Skip to content

Commit

Permalink
Mostly GUI Bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
MJWeberg committed Nov 19, 2024
1 parent a97d9b4 commit 7bac64f
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 36 deletions.
87 changes: 80 additions & 7 deletions eispac/core/read_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from eispac.core.read_wininfo import read_wininfo
from eispac.instr.calc_read_noise import calc_read_noise

def read_cube(filename=None, window=0, apply_radcal=True, radcal=None,
def read_cube(filename=None, window=0, exp_set='sum', apply_radcal=True, radcal=None,
abs_errs=True, count_offset=None, debug=False):
"""Load a single window of EIS data from an HDF5 file into an EISCube object
Expand All @@ -25,6 +25,11 @@ def read_cube(filename=None, window=0, apply_radcal=True, radcal=None,
window : int, float, or str, optional
Requested spectral window number or the value of any wavelength within
the requested window. Default is '0'
exp_set : int or str, optional
Index number of the exposure set to load from the file. Only used in the
rare case of scanning observations with multiple exposures per raster
position. Can also set to a value of "sum" to add together all exposures
and simulate a longer exposure image. Default is "sum".
apply_radcal : bool, optional
If set to True, will apply the pre-flight radiometric calibration curve
found in the HDF5 header file and set units to erg/(cm^2 s sr). If set
Expand Down Expand Up @@ -179,13 +184,15 @@ def read_cube(filename=None, window=0, apply_radcal=True, radcal=None,
meta['date_obs'] = np.array(f_head['times/date_obs']).astype(np.str_)
meta['date_obs_format'] = np.array(f_head['times/time_format']).astype(np.str_)[0]
except KeyError:
# Estimate missing or broken timestamps (ideally, never used)
print('WARNING: the header file has missing or incomplete date_obs'
+' for each raster step! Filling with estimated timestamps.')
total_time = np.datetime64(index['date_end']) - np.datetime64(index['date_obs'])
total_time = total_time / np.timedelta64(1, 's') # ensure [s] units
est_cad = total_time / index['nexp']
n_xsteps = index['nexp'] / index['nexp_prp']
est_cad = total_time / n_xsteps
est_date_obs = np.datetime64(index['date_obs']) \
+ np.arange(index['nexp']) \
+ np.arange(n_xsteps) \
* np.timedelta64(int(est_cad*1000), 'ms')
if index['nraster'] == 1:
# Sit-and-stare timestamps inc left to right
Expand Down Expand Up @@ -221,6 +228,73 @@ def read_cube(filename=None, window=0, apply_radcal=True, radcal=None,
else:
radcal_array = None

############################################################################
### Check for multiple exposure sets and select one (very rarely used)
############################################################################
if len(lv_1_counts.shape) == 4:
nexp_per_pos = lv_1_counts.shape[0] # Num exposures per slit position

if not isinstance(exp_set, (str, int)):
print(f"ERROR: invalid 'raster' keyword data type. Please input a"
+f" string of 'sum' or an integer.", file=sys.stderr)
return None
elif isinstance(exp_set, str):
if exp_set.isdigit():
# convert string containing an integer
exp_set = int(exp_set)
elif exp_set.lower() != 'sum':
print(f"ERROR: invalid raster string of '{exp_set}'. Please"
+f" input either 'sum' or an integer between 0 and"
+f" {nexp_per_pos-1}.", file=sys.stderr)
return None

if isinstance(exp_set, int):
if (exp_set >= nexp_per_pos) or (exp_set < -1*nexp_per_pos):
# Check for out-of-bound indices
oob_exp_set = exp_set
if exp_set < 0:
exp_set = 0
else:
exp_set = nexp_per_pos-1
print(f"WARNING: exp_set {oob_exp_set} is out of bounds."
+f" Loading the nearest valid exp_set ({exp_set}) instead.",
file=sys.stderr)
elif exp_set < 0:
# convert negative indices to positive
exp_set = nexp_per_pos - exp_set

# Extract the correct subarrays
if str(exp_set).lower() == 'sum':
print(f'Summing all {nexp_per_pos} sets exposures per slit position')
lv_1_counts = np.nansum(lv_1_counts, axis=0)
meta['date_obs'] = meta['date_obs'][0, :]
meta['duration'] = np.nansum(meta['duration'], axis=0)
meta['wave_corr'] = np.nanmean(meta['wave_corr'], axis=0)
meta['wave_corr_t'] = np.nanmean(meta['wave_corr_t'], axis=0)
meta['pointing']['solar_x'] = meta['pointing']['solar_x'][0, :]
else:
print(f'Loading exposure set {exp_set} ({exp_set+1} of {nexp_per_pos})')
lv_1_counts = lv_1_counts[exp_set,:,:,:]
meta['date_obs'] = meta['date_obs'][exp_set, :]
meta['duration'] = meta['duration'][exp_set, :]
meta['wave_corr'] = meta['wave_corr'][exp_set, :, :]
meta['wave_corr_t'] = meta['wave_corr_t'][exp_set, :]
meta['pointing']['solar_x'] = meta['pointing']['solar_x'][exp_set, :]
elif len(lv_1_counts.shape) > 4:
print(f"ERROR: cannot read input file with data array shape of"
+f" {lv_1_counts.shape}.", file=sys.stderr)
return None

############################################################################
### Determine observation type
############################################################################
if index['nraster'] == 1:
obs_type = 'sit-and-stare'
elif index['nexp_prp'] >= 2:
obs_type = 'multi_scan'
else:
obs_type = 'scan'

############################################################################
### Apply pointing corrections and create output EISCube
############################################################################
Expand All @@ -240,10 +314,6 @@ def read_cube(filename=None, window=0, apply_radcal=True, radcal=None,

### (3) Apply wave correction and get median base wavelength value and delta
counts_shape = lv_1_counts.shape
if len(counts_shape) > 3:
print('ERROR: EIS observations with multiple rasters in a single file'
+' are not currently supported.', file=sys.stderr)
return None
ny_pxls = counts_shape[0] # num pixels along the slit (y-axis)
nx_steps = counts_shape[1] # num raster steps (x-axis)
n_wave = counts_shape[2] # num wavelength values (i.e. EIS window width)
Expand Down Expand Up @@ -297,7 +367,10 @@ def read_cube(filename=None, window=0, apply_radcal=True, radcal=None,
output_hdr['bunit'] = 'unknown' # units of primary observable
output_hdr['slit_id'] = index['slit_id']
output_hdr['slit_ind'] = index['slit_ind']
output_hdr['obs_type'] = obs_type
output_hdr['nraster'] = index['nraster'] # 1 for sit-and-stare
output_hdr['nexp'] = index['nexp'] # total num exposures
output_hdr['nexp_prp'] = index['nexp_prp'] # num exposures per slit position
output_hdr['tr_mode'] = index['tr_mode'] # tracking mode. "FIX" for no tracking
output_hdr['saa'] = index['saa'] # IN / OUT South Atlantic Anomaly (SAA)
output_hdr['hlz'] = index['hlz'] # IN / OUT High-Latitude Zone (HLZ)
Expand Down
1 change: 1 addition & 0 deletions eispac/data/ref/eis_chianti_lookup_table.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
255.684 Fe VIII
171.073 Fe IX
177.592 Fe IX
188.493 Fe IX
174.531 Fe X
175.263 Fe X
175.475 Fe X
Expand Down
37 changes: 31 additions & 6 deletions eispac/download/eis_obs_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ def __init__(self, dbfile):
# Create placeholders
self.eis_str = []
self.skipped_obs = []
self.unknown_main_row = {'stud_acr':'unknown', 'study_id':-999, 'jop_id':-999,
'obstitle':'NO STUDY INFO FOUND! ',
'obs_dec':'No study info with same tl_id found within +-12 hrs ',
'sci_obj':'?? ', 'target':'unknown'}
self.unknown_exp_row = {'filename':' ', 'date_obs':1, 'date_end':2,
'xcen':-90000, 'ycen':-90000, 'fovx':0.0, 'fovy':0.0,
'tl_id':0, 'rast_acr':'unknown', 'rast_id':1}

def load_ll(self):
"""Load useful info from line linelist db."""
Expand Down Expand Up @@ -169,12 +176,21 @@ def mk_obs_list(self):
for loop_m_row in main_rows:
if primary_db.lower().startswith('main'):
# Search the EXPERIMENT DB for info
t_start = loop_m_row['date_obs'] - 43200 # 12 hr BEFORE
t_end = loop_m_row['date_end'] + 43200 # 12 hr AFTER
exp_string = ('filename, date_obs, date_end, xcen, ycen,'
+' fovx, fovy, tl_id, rast_acr, rast_id')
self.cur.execute('SELECT '+exp_string+' FROM'
+' eis_experiment WHERE tl_id==?',
(loop_m_row['tl_id'],))
+' eis_experiment WHERE tl_id==?'
+' AND date_obs BETWEEN ? and ?',
(loop_m_row['tl_id'], t_start, t_end))
exp_rows = self.cur.fetchall()
if len(exp_rows) <= 0:
empty_e_row = self.unknown_exp_row
empty_e_row['tl_id'] = loop_m_row['tl_id']
empty_e_row['date_obs'] = loop_m_row['date_obs']
empty_e_row['date_end'] = loop_m_row['date_end']
exp_rows = [empty_e_row]

for e_row in exp_rows:
# Validate rast ID
Expand Down Expand Up @@ -243,11 +259,20 @@ def mk_obs_list(self):
m_row = loop_m_row
elif primary_db.lower().startswith('exp'):
# Search the MAIN DB for information
t_start = e_row['date_obs'] - 43200 # 12 hr BEFORE
t_end = e_row['date_end'] + 43200 # 12 hr AFTER
main_string = ('stud_acr, study_id, jop_id, obstitle,'
+' obs_dec, sci_obj, target')
self.cur.execute('SELECT '+main_string+ ' FROM eis_main'
+' WHERE tl_id = ?', (e_row['tl_id'],))
m_row, = self.cur.fetchall()
+' WHERE tl_id = ?'
+' AND date_obs BETWEEN ? and ?',
(e_row['tl_id'], t_start, t_end))
study_rows = self.cur.fetchall()
if len(study_rows) <= 0:
# No matching row found in eis_main!
m_row = self.unknown_main_row
else:
m_row = study_rows[0]

# Extract, merge, and append the obs info from all rows
self.eis_str.append(EIS_Struct(e_row, ll_row, rast_row, m_row))
Expand Down Expand Up @@ -276,8 +301,8 @@ def search(self, quiet=False, print_sqlite=False, **kwargs):
text_cols = ['rast_acr', 'll_acr']
valid_cols = self.exp_cols
elif primary_db.lower().startswith('eis_main'):
select_cols = ('tl_id, stud_acr, study_id, jop_id, obstitle,'
+' obs_dec, sci_obj, target')
select_cols = ('tl_id, date_obs, date_end, stud_acr, study_id,'
+' jop_id, obstitle, obs_dec, sci_obj, target')
text_cols = ['stud_acr', 'obstitle', 'obs_dec', 'target', 'sci_obj',
'join_sb', 'solb_sci', 'eis_sc',
'st_auth', 'observer', 'planner', 'tohbans']
Expand Down
23 changes: 11 additions & 12 deletions scripts/eis_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def top_menu(self):
self.download_db.clicked.connect(self.event_download_db)

self.db_source_box = QtWidgets.QComboBox()
self.db_source_box.addItems(['NASA (source)', 'NRL (mirror)'])
self.db_source_box.addItems(['NRL (source)', 'NASA (mirror)'])
self.db_source_box.setFixedWidth(self.default_button_width) # or 150
self.db_source_box.setFont(self.default_font)

Expand Down Expand Up @@ -198,7 +198,7 @@ def event_download_db(self):
info = (f'Downloading eis_cat.sqlite.\n'
f' Remote: {db_remote_text}\n'
f' Local: {os.path.abspath(self.dbfile)}\n\n'
f'Please wait...')
f'Please wait (see console for download progress)...')
self.info_detail.append(info)
QtWidgets.QApplication.processEvents() # update gui while user waits
if self.db_loaded:
Expand Down Expand Up @@ -432,9 +432,9 @@ def set_filters(self):
def event_search(self):
"""Validate and process search request."""
self.tabs.setCurrentIndex(0) #switch to details tab
self.info_detail.clear()
self.search_info.setText('Found ?? search results')
self.filter_info.setText('Showing ?? filter matches')
self.info_detail.clear()
if self.db_loaded == False:
self.info_detail.append('No EIS As-Run Catalog found!\n\n'
+'Please use the "Update Database" '
Expand Down Expand Up @@ -622,10 +622,8 @@ def fill_info(self, file):
info.append(f"{'fovx':<20} {row.fovx}")
info.append(f"{'fovy':<20} {row.fovy}")
info.append(f"{'tl_id':<20} {row.tl_id}")
info.append(f"{'study_id':<20} {row.study_id}")
info.append(f"{'stud_acr':<20} {row.stud_acr}")
info.append(f"{'rast_acr':<20} {row.rast_acr}")
info.append(f"{'rast_id':<20} {row.rast_id}")
info.append(f"{'study_id, stud_acr':<20} {row.study_id}, {row.stud_acr}")
info.append(f"{'rast_id, rast_acr':<20} {row.rast_id}, {row.rast_acr}")
info.append(f"{'jop_id':<20} {row.jop_id}")
info.append(f"{'obstitle':<20} {row.obstitle}")
info.append(f"{'obs_dec':<20} {row.obs_dec}")
Expand All @@ -638,7 +636,8 @@ def fill_info(self, file):
info.append(f"{'nexp':<20} {row.nexp}")
info.append(f"{'exptime':<20} {row.exptime}")

info.append(f"\n\n{'----- Line List -----':^55}")
line_list_title = f"----- Line List (ll_id: {row.ll_id}) -----"
info.append(f"\n\n{line_list_title:^55}")
info.append(f"{'window':<8} {'title':<20} "
+f"{'wavemin':<9} {'wavemax':<9} {'width':<5}")
for i in range(0,len(row.ll_title)):
Expand Down Expand Up @@ -683,13 +682,13 @@ def on_finished(self, reply):

def event_update_context_image(self, tab_index):
"""Download context image into memory and update the image tab"""
clean_filename = self.selected_file.replace('.gz', '')
remote_dir = get_remote_image_dir(clean_filename)
context_img_name = 'XRT_'+clean_filename+'.gif'
self.context_url = remote_dir+context_img_name

if self.tabs.currentIndex() == 1:
try:
clean_filename = self.selected_file.replace('.gz', '')
remote_dir = get_remote_image_dir(clean_filename)
context_img_name = 'XRT_'+clean_filename+'.gif'
self.context_url = remote_dir+context_img_name
self.get_image()
except:
print(' ERROR: context images or server are unavailable.')
Expand Down
Loading

0 comments on commit 7bac64f

Please sign in to comment.