diff --git a/jwql/website/apps/jwql/data_containers.py b/jwql/website/apps/jwql/data_containers.py index e647cb0a0..479a4367a 100644 --- a/jwql/website/apps/jwql/data_containers.py +++ b/jwql/website/apps/jwql/data_containers.py @@ -13,6 +13,7 @@ - Teagan King - Bryan Hilbert - Maria Pena-Guerrero + - Rachel Cooper Use --- @@ -56,6 +57,7 @@ from jwql.utils.credentials import get_mast_token from jwql.utils.permissions import set_permissions from jwql.utils.utils import get_rootnames_for_instrument_proposal +from jwql.website.apps.jwql.models import RootFileInfo from .forms import InstrumentAnomalySubmitForm from astroquery.mast import Mast @@ -1571,7 +1573,7 @@ def thumbnails_ajax(inst, proposal, obs_num=None): obs_list = sorted(list(set(all_obs))) # Get the available files for the instrument - filenames, columns = get_filenames_by_instrument(inst, proposal, observation_id=obs_num, other_columns=['expstart', 'exp_type']) + filenames = get_filenames_by_instrument(inst, proposal, observation_id=obs_num) # Get set of unique rootnames rootnames = set(['_'.join(f.split('/')[-1].split('_')[:-1]) for f in filenames]) @@ -1584,7 +1586,6 @@ def thumbnails_ajax(inst, proposal, obs_num=None): # Gather data for each rootname, and construct a list of all observations # in the proposal for rootname in rootnames: - # Parse filename try: filename_dict = filename_parser(rootname) @@ -1611,19 +1612,20 @@ def thumbnails_ajax(inst, proposal, obs_num=None): # Get list of available filenames and exposure start times. All files with a given # rootname will have the same exposure start time, so just keep the first. available_files = [item for item in filenames if rootname in item] - exp_start = [expstart for fname, expstart in zip(filenames, columns['expstart']) if rootname in fname][0] - exp_type = [exp_type for fname, exp_type in zip(filenames, columns['exp_type']) if rootname in fname][0] - exp_types.append(exp_type) # Viewed is stored by rootname in the Model db. Save it with the data_dict # THUMBNAIL_FILTER_LOOK is boolean accessed according to a viewed flag try: root_file_info = RootFileInfo.objects.get(root_name=rootname) viewed = THUMBNAIL_FILTER_LOOK[root_file_info.viewed] - except RootFileInfo.DoesNotExist: - + except RootFileInfo.DoesNotExist as e: viewed = THUMBNAIL_FILTER_LOOK[0] + # All this will break if root_file_info doesn't exist (model not found) + exp_type = root_file_info.exp_type + exp_types.append(exp_type) + exp_start = root_file_info.expstart + # Add data to dictionary data_dict['file_data'][rootname] = {} data_dict['file_data'][rootname]['filename_dict'] = filename_dict @@ -1631,16 +1633,50 @@ def thumbnails_ajax(inst, proposal, obs_num=None): data_dict['file_data'][rootname]["viewed"] = viewed data_dict['file_data'][rootname]["exp_type"] = exp_type data_dict['file_data'][rootname]['thumbnail'] = get_thumbnail_by_rootname(rootname) + data_dict['file_data'][rootname]['obs_visit'] = filename_dict['observation']+'/'+filename_dict['visit'] + data_dict['file_data'][rootname]['exp_num'] = filename_dict['exposure_id'] try: data_dict['file_data'][rootname]['expstart'] = exp_start data_dict['file_data'][rootname]['expstart_iso'] = Time(exp_start, format='mjd').iso.split('.')[0] + # reformat time for display (omit seconds to fit on one line) + data_dict['file_data'][rootname]['expstart_str'] = Time(exp_start, format='mjd').strftime("%y-%m-%d %H:%M") + except (ValueError, TypeError) as e: logging.warning("Unable to populate exp_start info for {}".format(rootname)) logging.warning(e) except KeyError: print("KeyError with get_expstart for {}".format(rootname)) + # Read header from file to get keywords not in model + # get_header_info() dict structure overcomplicates things + if inst in ['MIRI','NIRSpec']: # only miri and nirspec need header keywords for now + filetype=available_files[0].split('_')[-1].replace('.fits','') + fits_filepath = filesystem_path(rootname, search=f'*_{filetype}.fits') + header = fits.getheader(fits_filepath) # primary header + + # Add instrument-specific info to data_dict for hover-over + # Combine optical elements keywords to save space + if inst == 'NIRCam': + filt_pup = root_file_info.filter + '/' + root_file_info.pupil + data_dict['file_data'][rootname]['filterpupil'] = filt_pup + if inst == 'NIRSpec': + filt_grat = root_file_info.filter+'/'+root_file_info.grating + data_dict['file_data'][rootname]['filtergrating'] = filt_grat + data_dict['file_data'][rootname]['patt_num'] = root_file_info.read_patt_num + data_dict['file_data'][rootname]['lamp'] = header['LAMP'] + data_dict['file_data'][rootname]['opmode'] = header['OPMODE'] + if inst == 'NIRISS': + filt_pup = root_file_info.filter + '/' + root_file_info.pupil + data_dict['file_data'][rootname]['filterpupil'] = filt_pup + if inst == 'MIRI': + if 'MRS' in exp_type: + channel, band = header['CHANNEL'], header['BAND'] + data_dict['file_data'][rootname]['channelband'] = channel+'/'+band + else: + data_dict['file_data'][rootname]['filter'] = root_file_info.filter + data_dict['file_data'][rootname]['ngrp_nint'] = str(header['NGROUPS']) + '/' + str(header['NINTS']) + # Extract information for sorting with dropdown menus # (Don't include the proposal as a sorting parameter if the proposal has already been specified) detectors, proposals = [], [] @@ -1668,7 +1704,6 @@ def thumbnails_ajax(inst, proposal, obs_num=None): # Order dictionary by descending expstart time. sorted_file_data = OrderedDict(sorted(data_dict['file_data'].items(), key=lambda x: getitem(x[1], 'expstart'), reverse=True)) - data_dict['file_data'] = sorted_file_data # Add list of observation numbers diff --git a/jwql/website/apps/jwql/static/css/jwql.css b/jwql/website/apps/jwql/static/css/jwql.css index eaa74e690..da26a4c74 100644 --- a/jwql/website/apps/jwql/static/css/jwql.css +++ b/jwql/website/apps/jwql/static/css/jwql.css @@ -485,9 +485,9 @@ .thumbnail-color-fill { display: none; width: 100%; - height: 100%; + height: 110%; background-color: #356198; - opacity: 0.3; + opacity: 0.5; position: absolute; top: 0%; left: 0%; @@ -526,7 +526,7 @@ text-align: left; color: white; z-index: 2; - font-size: 0.75rem; + font-size: 0.65rem; } .thumbnail-staff { @@ -537,6 +537,15 @@ display: inline-block; margin: 0.1rem; } + + .thumbinfo-key { + float: left; + font-weight: bolder; + } + + .thumbinfo-val { + float: right; + } /*Format the version identifier text in bottom corner*/ diff --git a/jwql/website/apps/jwql/static/js/jwql.js b/jwql/website/apps/jwql/static/js/jwql.js index b70544eb2..446ce0445 100644 --- a/jwql/website/apps/jwql/static/js/jwql.js +++ b/jwql/website/apps/jwql/static/js/jwql.js @@ -923,11 +923,37 @@ function update_thumbnail_array(data) { content += ''; content += '
'; content += '
'; - content += 'Proposal: ' + filename_dict.program_id + '
'; - content += 'Observation: ' + filename_dict.observation + '
'; - content += 'Visit: ' + filename_dict.visit + '
'; - content += 'Detector: ' + filename_dict.detector + '
'; - content += 'Exp_Start: ' + file.expstart_iso + '
'; + content += 'Proposal: ' + ''+ filename_dict.program_id + '
'; + content += 'Obs/Visit: ' + ''+ file.obs_visit + '
'; + content += 'Detector: ' + ''+ filename_dict.detector + '
'; + content += 'Start: ' + ''+ file.expstart_str + '
'; + content += 'Exp_Num: ' + ''+ file.exp_num + '
'; + + // Additional keywords to be displayed for each instrument + if (filename_dict.instrument=="nirspec"){ + content += 'Optics: ' + ''+ file.filtergrating+ '
'; + content += 'Patt_Num: ' + ''+ file.patt_num+ '
'; + if (file.lamp !== "NONE"){ + content += 'Lamp: ' + ''+ file.lamp+ '
'; + } + content += 'Opmode: ' + ''+ file.opmode+ '
'; + } + if (filename_dict.instrument=="nircam"){ + content += 'Optics: ' + ''+ file.filterpupil + '
'; + } + if (filename_dict.instrument=="niriss"){ + content += 'Optics: ' + ''+ file.filterpupil + '
'; + } + if (filename_dict.instrument=="miri"){ + if ('channelband' in file) { + content += 'Optics: '+ ''+ file.channelband + '
'; + } + else { + content += 'Filter: '+ ''+ file.filter + '
'; + } + content += 'Ngrp/Nint: '+ ''+ file.ngrp_nint + '
'; + } + content += '
'; // Add the content to the div