From 25c7e35ad84d480420dd21b6ea3b62d09c583483 Mon Sep 17 00:00:00 2001 From: Kyle Westfall Date: Wed, 28 Aug 2024 17:42:31 -0700 Subject: [PATCH 1/3] mv flexure_diagnostics into each relevant class --- pypeit/core/flexure.py | 160 +++++++++++++++++----------------- pypeit/scripts/chk_flexure.py | 33 +++---- pypeit/spec2dobj.py | 41 +++++++++ pypeit/specobjs.py | 23 +++++ 4 files changed, 162 insertions(+), 95 deletions(-) diff --git a/pypeit/core/flexure.py b/pypeit/core/flexure.py index 7fda7bf2b4..e22a84cdff 100644 --- a/pypeit/core/flexure.py +++ b/pypeit/core/flexure.py @@ -37,7 +37,7 @@ from pypeit.datamodel import DataContainer from pypeit.images.detector_container import DetectorContainer from pypeit.images.mosaic import Mosaic -from pypeit import specobj, specobjs, spec2dobj +from pypeit import specobj, specobjs #, spec2dobj from pypeit import wavemodel from IPython import embed @@ -1395,85 +1395,85 @@ def sky_em_residuals(wave:np.ndarray, flux:np.ndarray, return dwave[m], diff[m], diff_err[m], los[m], los_err[m] -def flexure_diagnostic(file, file_type='spec2d', flexure_type='spec', chk_version=False): - """ - Print the spectral or spatial flexure of a spec2d or spec1d file. - - Args: - file (:obj:`str`, `Path`_): - Filename of the spec2d or spec1d file to check - file_type (:obj:`str`, optional): - Type of the file to check. Options are 'spec2d' or 'spec1d'. Default is 'spec2d'. - flexure_type (:obj:`str`, optional): - Type of flexure to check. Options are 'spec' or 'spat'. Default is 'spec'. - chk_version (:obj:`bool`, optional): - If True, raise an error if the datamodel version or type check failed. - If False, throw a warning only. Default is False. - - Returns: - :obj:`astropy.table.Table`, :obj:`float`: Type depends on the keyword - arguments: - - - If file_type is 'spec2d' and flexure_type is 'spec', return a - table with the spectral flexure - - - If file_type is 'spec2d' and flexure_type is 'spat', return the - spatial flexure - - - If file_type is 'spec1d', return a table with the spectral flexure - - """ - - # value to return - return_flex = None - - if file_type == 'spec2d': - # load the spec2d file - allspec2D = spec2dobj.AllSpec2DObj.from_fits(file, chk_version=chk_version) - # Loop on Detectors - for det in allspec2D.detectors: - print('') - print('=' * 50 + f'{det:^7}' + '=' * 51) - # get and print the spectral flexure - if flexure_type == 'spec': - spec_flex = allspec2D[det].sci_spec_flexure - spec_flex.rename_column('sci_spec_flexure', 'global_spec_shift') - if np.all(spec_flex['global_spec_shift'] != None): - spec_flex['global_spec_shift'].format = '0.3f' - # print the table - spec_flex.pprint_all() - # return the table - return_flex = spec_flex - # get and print the spatial flexure - if flexure_type == 'spat': - spat_flex = allspec2D[det].sci_spat_flexure - # print the value - print(f'Spat shift: {spat_flex}') - # return the value - return_flex = spat_flex - elif file_type == 'spec1d': - # no spat flexure in spec1d file - if flexure_type == 'spat': - msgs.error("Spat flexure not available in the spec1d file, try with a spec2d file") - # load the spec1d file - sobjs = specobjs.SpecObjs.from_fitsfile(file, chk_version=chk_version) - spec_flex = Table() - spec_flex['NAME'] = sobjs.NAME - spec_flex['global_spec_shift'] = sobjs.FLEX_SHIFT_GLOBAL - if np.all(spec_flex['global_spec_shift'] != None): - spec_flex['global_spec_shift'].format = '0.3f' - spec_flex['local_spec_shift'] = sobjs.FLEX_SHIFT_LOCAL - if np.all(spec_flex['local_spec_shift'] != None): - spec_flex['local_spec_shift'].format = '0.3f' - spec_flex['total_spec_shift'] = sobjs.FLEX_SHIFT_TOTAL - if np.all(spec_flex['total_spec_shift'] != None): - spec_flex['total_spec_shift'].format = '0.3f' - # print the table - spec_flex.pprint_all() - # return the table - return_flex = spec_flex - - return return_flex +#def flexure_diagnostic(file, file_type='spec2d', flexure_type='spec', chk_version=False): +# """ +# Print the spectral or spatial flexure of a spec2d or spec1d file. +# +# Args: +# file (:obj:`str`, `Path`_): +# Filename of the spec2d or spec1d file to check +# file_type (:obj:`str`, optional): +# Type of the file to check. Options are 'spec2d' or 'spec1d'. Default is 'spec2d'. +# flexure_type (:obj:`str`, optional): +# Type of flexure to check. Options are 'spec' or 'spat'. Default is 'spec'. +# chk_version (:obj:`bool`, optional): +# If True, raise an error if the datamodel version or type check failed. +# If False, throw a warning only. Default is False. +# +# Returns: +# :obj:`astropy.table.Table`, :obj:`float`: Type depends on the keyword +# arguments: +# +# - If file_type is 'spec2d' and flexure_type is 'spec', return a +# table with the spectral flexure +# +# - If file_type is 'spec2d' and flexure_type is 'spat', return the +# spatial flexure +# +# - If file_type is 'spec1d', return a table with the spectral flexure +# +# """ +# +# # value to return +# return_flex = None +# +# if file_type == 'spec2d': +# # load the spec2d file +# allspec2D = spec2dobj.AllSpec2DObj.from_fits(file, chk_version=chk_version) +# # Loop on Detectors +# for det in allspec2D.detectors: +# print('') +# print('=' * 50 + f'{det:^7}' + '=' * 51) +# # get and print the spectral flexure +# if flexure_type == 'spec': +# spec_flex = allspec2D[det].sci_spec_flexure +# spec_flex.rename_column('sci_spec_flexure', 'global_spec_shift') +# if np.all(spec_flex['global_spec_shift'] != None): +# spec_flex['global_spec_shift'].format = '0.3f' +# # print the table +# spec_flex.pprint_all() +# # return the table +# return_flex = spec_flex +# # get and print the spatial flexure +# if flexure_type == 'spat': +# spat_flex = allspec2D[det].sci_spat_flexure +# # print the value +# print(f'Spat shift: {spat_flex}') +# # return the value +# return_flex = spat_flex +# elif file_type == 'spec1d': +# # no spat flexure in spec1d file +# if flexure_type == 'spat': +# msgs.error("Spat flexure not available in the spec1d file, try with a spec2d file") +# # load the spec1d file +# sobjs = specobjs.SpecObjs.from_fitsfile(file, chk_version=chk_version) +# spec_flex = Table() +# spec_flex['NAME'] = sobjs.NAME +# spec_flex['global_spec_shift'] = sobjs.FLEX_SHIFT_GLOBAL +# if np.all(spec_flex['global_spec_shift'] != None): +# spec_flex['global_spec_shift'].format = '0.3f' +# spec_flex['local_spec_shift'] = sobjs.FLEX_SHIFT_LOCAL +# if np.all(spec_flex['local_spec_shift'] != None): +# spec_flex['local_spec_shift'].format = '0.3f' +# spec_flex['total_spec_shift'] = sobjs.FLEX_SHIFT_TOTAL +# if np.all(spec_flex['total_spec_shift'] != None): +# spec_flex['total_spec_shift'].format = '0.3f' +# # print the table +# spec_flex.pprint_all() +# # return the table +# return_flex = spec_flex +# +# return return_flex # TODO -- Consider separating the methods from the DataContainer as per calibrations diff --git a/pypeit/scripts/chk_flexure.py b/pypeit/scripts/chk_flexure.py index d384dc8e29..3be590ef2d 100644 --- a/pypeit/scripts/chk_flexure.py +++ b/pypeit/scripts/chk_flexure.py @@ -15,10 +15,13 @@ def get_parser(cls, width=None): parser = super().get_parser(description='Print QA on flexure to the screen', width=width) - parser.add_argument('input_file', type=str, nargs='+', help='One or more PypeIt spec2d or spec1d file') + parser.add_argument('input_file', type=str, nargs='+', + help='One or more PypeIt spec2d or spec1d file') inp = parser.add_mutually_exclusive_group(required=True) - inp.add_argument('--spec', default=False, action='store_true', help='Check the spectral flexure') - inp.add_argument('--spat', default=False, action='store_true', help='Check the spatial flexure') + inp.add_argument('--spec', default=False, action='store_true', + help='Check the spectral flexure') + inp.add_argument('--spat', default=False, action='store_true', + help='Check the spatial flexure') parser.add_argument('--try_old', default=False, action='store_true', help='Attempt to load old datamodel versions. A crash may ensue..') return parser @@ -29,9 +32,11 @@ def main(args): from IPython import embed from astropy.io import fits from pypeit import msgs - from pypeit.core import flexure + from pypeit import specobjs + from pypeit import spec2dobj chk_version = not args.try_old + flexure_type = 'spat' if args.spat else 'spec' # Loop over the input files for in_file in args.input_file: @@ -43,21 +48,19 @@ def main(args): head0 = hdul[0].header file_type = None if 'PYP_CLS' in head0.keys() and head0['PYP_CLS'].strip() == 'AllSpec2DObj': - file_type = 'spec2d' + # load the spec2d file + allspec2D = spec2dobj.AllSpec2DObj.from_fits(file, chk_version=chk_version) + allspec2D.flexure_diagnostics(flexure_type=flexure_type) elif 'DMODCLS' in head0.keys() and head0['DMODCLS'].strip() == 'SpecObjs': - file_type = 'spec1d' + if flexure_type == 'spat': + msgs.error("Spat flexure not available in the spec1d file, try with a " + "spec2d file") + # load the spec1d file + sobjs = specobjs.SpecObjs.from_fitsfile(file, chk_version=chk_version) + sobjs.flexure_diagnostics() else: msgs.error("Bad file type input!") - # Check the flexure - flexure.flexure_diagnostic(in_file, file_type=file_type, flexure_type='spat' if args.spat else 'spec', - chk_version=chk_version) - # space between files for clarity print('') - - - - - diff --git a/pypeit/spec2dobj.py b/pypeit/spec2dobj.py index 6aaae67396..9628f34df1 100644 --- a/pypeit/spec2dobj.py +++ b/pypeit/spec2dobj.py @@ -728,3 +728,44 @@ def __repr__(self): txt += ') >' return txt + def flexure_diagnostics(self, flexure_type='spat'): + """ + Print the spectral or spatial flexure of a spec2d or spec1d file. + + Args: + flexure_type (:obj:`str`, optional): + Type of flexure to check. Options are 'spec' or 'spat'. Default + is 'spec'. + + Returns: + :obj:`astropy.table.Table`, :obj:`float`: If flexure_type is + 'spec', return a table with the spectral flexure. If flexure_type is + 'spat', return the spatial flexure + """ + if flexure_type not in ['spat', 'spec']: + msgs.error(f'flexure_type must be spat or spec, not {flexure_type}') + # Loop on Detectors + for det in self.detectors: + print('') + print('=' * 50 + f'{det:^7}' + '=' * 51) + # get and print the spectral flexure + if flexure_type == 'spec': + spec_flex = self[det].sci_spec_flexure + spec_flex.rename_column('sci_spec_flexure', 'global_spec_shift') + if np.all(spec_flex['global_spec_shift'] != None): + spec_flex['global_spec_shift'].format = '0.3f' + # print the table + spec_flex.pprint_all() + # return the table + return_flex = spec_flex + # get and print the spatial flexure + if flexure_type == 'spat': + spat_flex = self[det].sci_spat_flexure + # print the value + print(f'Spat shift: {spat_flex}') + # return the value + return_flex = spat_flex + + # TODO: Was this supposed to be a list for all detectors, or just the last detector? + return return_flex + diff --git a/pypeit/specobjs.py b/pypeit/specobjs.py index 4b6da7ef36..16bf272cdc 100644 --- a/pypeit/specobjs.py +++ b/pypeit/specobjs.py @@ -1027,6 +1027,29 @@ def get_extraction_groups(self, model_full_slit=False) -> List[List[int]]: return groups + def flexure_diagnostics(self): + """ + Print the spectral or spatial flexure of a spec2d or spec1d file. + + Returns: + :obj:`astropy.table.Table`: Table with the spectral flexure. + """ + spec_flex = Table() + spec_flex['NAME'] = self.NAME + spec_flex['global_spec_shift'] = self.FLEX_SHIFT_GLOBAL + if np.all(spec_flex['global_spec_shift'] != None): + spec_flex['global_spec_shift'].format = '0.3f' + spec_flex['local_spec_shift'] = self.FLEX_SHIFT_LOCAL + if np.all(spec_flex['local_spec_shift'] != None): + spec_flex['local_spec_shift'].format = '0.3f' + spec_flex['total_spec_shift'] = self.FLEX_SHIFT_TOTAL + if np.all(spec_flex['total_spec_shift'] != None): + spec_flex['total_spec_shift'].format = '0.3f' + # print the table + spec_flex.pprint_all() + # return the table + return spec_flex + #TODO Should this be a classmethod on specobjs?? def get_std_trace(detname, std_outfile, chk_version=True): From 97c59505e1c221f153b8c612787b2baedb587da8 Mon Sep 17 00:00:00 2001 From: Debora Pelliccia Date: Wed, 28 Aug 2024 16:55:02 -1000 Subject: [PATCH 2/3] small fixes --- pypeit/scripts/chk_flexure.py | 6 +++--- pypeit/spec2dobj.py | 15 ++++++++------- pypeit/specobjs.py | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/pypeit/scripts/chk_flexure.py b/pypeit/scripts/chk_flexure.py index 3be590ef2d..74faf77b01 100644 --- a/pypeit/scripts/chk_flexure.py +++ b/pypeit/scripts/chk_flexure.py @@ -46,17 +46,17 @@ def main(args): # What kind of file are we?? hdul = fits.open(in_file) head0 = hdul[0].header - file_type = None + if 'PYP_CLS' in head0.keys() and head0['PYP_CLS'].strip() == 'AllSpec2DObj': # load the spec2d file - allspec2D = spec2dobj.AllSpec2DObj.from_fits(file, chk_version=chk_version) + allspec2D = spec2dobj.AllSpec2DObj.from_fits(in_file, chk_version=chk_version) allspec2D.flexure_diagnostics(flexure_type=flexure_type) elif 'DMODCLS' in head0.keys() and head0['DMODCLS'].strip() == 'SpecObjs': if flexure_type == 'spat': msgs.error("Spat flexure not available in the spec1d file, try with a " "spec2d file") # load the spec1d file - sobjs = specobjs.SpecObjs.from_fitsfile(file, chk_version=chk_version) + sobjs = specobjs.SpecObjs.from_fitsfile(in_file, chk_version=chk_version) sobjs.flexure_diagnostics() else: msgs.error("Bad file type input!") diff --git a/pypeit/spec2dobj.py b/pypeit/spec2dobj.py index 9628f34df1..5e693e44c0 100644 --- a/pypeit/spec2dobj.py +++ b/pypeit/spec2dobj.py @@ -730,7 +730,7 @@ def __repr__(self): def flexure_diagnostics(self, flexure_type='spat'): """ - Print the spectral or spatial flexure of a spec2d or spec1d file. + Print and return the spectral or spatial flexure of a spec2d file. Args: flexure_type (:obj:`str`, optional): @@ -738,12 +738,14 @@ def flexure_diagnostics(self, flexure_type='spat'): is 'spec'. Returns: - :obj:`astropy.table.Table`, :obj:`float`: If flexure_type is - 'spec', return a table with the spectral flexure. If flexure_type is - 'spat', return the spatial flexure + :obj:`dict`: Dictionary with the flexure values for each detector. If + flexure_type is 'spec', the spectral flexure is stored in an astropy table. + If flexure_type is 'spat', the spatial flexure is stored in a float. + """ if flexure_type not in ['spat', 'spec']: msgs.error(f'flexure_type must be spat or spec, not {flexure_type}') + return_flex = {} # Loop on Detectors for det in self.detectors: print('') @@ -757,15 +759,14 @@ def flexure_diagnostics(self, flexure_type='spat'): # print the table spec_flex.pprint_all() # return the table - return_flex = spec_flex + return_flex[det] = spec_flex # get and print the spatial flexure if flexure_type == 'spat': spat_flex = self[det].sci_spat_flexure # print the value print(f'Spat shift: {spat_flex}') # return the value - return_flex = spat_flex + return_flex[det] = spat_flex - # TODO: Was this supposed to be a list for all detectors, or just the last detector? return return_flex diff --git a/pypeit/specobjs.py b/pypeit/specobjs.py index 16bf272cdc..a5a51411e7 100644 --- a/pypeit/specobjs.py +++ b/pypeit/specobjs.py @@ -1029,7 +1029,7 @@ def get_extraction_groups(self, model_full_slit=False) -> List[List[int]]: def flexure_diagnostics(self): """ - Print the spectral or spatial flexure of a spec2d or spec1d file. + Print and return the spectral flexure of a spec1d file. Returns: :obj:`astropy.table.Table`: Table with the spectral flexure. From 449d5ded2d522186db2df10dafb1775e300ff87e Mon Sep 17 00:00:00 2001 From: Kyle Westfall Date: Thu, 29 Aug 2024 07:37:50 -0700 Subject: [PATCH 3/3] rm commented code --- pypeit/core/flexure.py | 83 +----------------------------------------- 1 file changed, 1 insertion(+), 82 deletions(-) diff --git a/pypeit/core/flexure.py b/pypeit/core/flexure.py index e22a84cdff..487dd504bf 100644 --- a/pypeit/core/flexure.py +++ b/pypeit/core/flexure.py @@ -37,7 +37,7 @@ from pypeit.datamodel import DataContainer from pypeit.images.detector_container import DetectorContainer from pypeit.images.mosaic import Mosaic -from pypeit import specobj, specobjs #, spec2dobj +from pypeit import specobj, specobjs from pypeit import wavemodel from IPython import embed @@ -1395,87 +1395,6 @@ def sky_em_residuals(wave:np.ndarray, flux:np.ndarray, return dwave[m], diff[m], diff_err[m], los[m], los_err[m] -#def flexure_diagnostic(file, file_type='spec2d', flexure_type='spec', chk_version=False): -# """ -# Print the spectral or spatial flexure of a spec2d or spec1d file. -# -# Args: -# file (:obj:`str`, `Path`_): -# Filename of the spec2d or spec1d file to check -# file_type (:obj:`str`, optional): -# Type of the file to check. Options are 'spec2d' or 'spec1d'. Default is 'spec2d'. -# flexure_type (:obj:`str`, optional): -# Type of flexure to check. Options are 'spec' or 'spat'. Default is 'spec'. -# chk_version (:obj:`bool`, optional): -# If True, raise an error if the datamodel version or type check failed. -# If False, throw a warning only. Default is False. -# -# Returns: -# :obj:`astropy.table.Table`, :obj:`float`: Type depends on the keyword -# arguments: -# -# - If file_type is 'spec2d' and flexure_type is 'spec', return a -# table with the spectral flexure -# -# - If file_type is 'spec2d' and flexure_type is 'spat', return the -# spatial flexure -# -# - If file_type is 'spec1d', return a table with the spectral flexure -# -# """ -# -# # value to return -# return_flex = None -# -# if file_type == 'spec2d': -# # load the spec2d file -# allspec2D = spec2dobj.AllSpec2DObj.from_fits(file, chk_version=chk_version) -# # Loop on Detectors -# for det in allspec2D.detectors: -# print('') -# print('=' * 50 + f'{det:^7}' + '=' * 51) -# # get and print the spectral flexure -# if flexure_type == 'spec': -# spec_flex = allspec2D[det].sci_spec_flexure -# spec_flex.rename_column('sci_spec_flexure', 'global_spec_shift') -# if np.all(spec_flex['global_spec_shift'] != None): -# spec_flex['global_spec_shift'].format = '0.3f' -# # print the table -# spec_flex.pprint_all() -# # return the table -# return_flex = spec_flex -# # get and print the spatial flexure -# if flexure_type == 'spat': -# spat_flex = allspec2D[det].sci_spat_flexure -# # print the value -# print(f'Spat shift: {spat_flex}') -# # return the value -# return_flex = spat_flex -# elif file_type == 'spec1d': -# # no spat flexure in spec1d file -# if flexure_type == 'spat': -# msgs.error("Spat flexure not available in the spec1d file, try with a spec2d file") -# # load the spec1d file -# sobjs = specobjs.SpecObjs.from_fitsfile(file, chk_version=chk_version) -# spec_flex = Table() -# spec_flex['NAME'] = sobjs.NAME -# spec_flex['global_spec_shift'] = sobjs.FLEX_SHIFT_GLOBAL -# if np.all(spec_flex['global_spec_shift'] != None): -# spec_flex['global_spec_shift'].format = '0.3f' -# spec_flex['local_spec_shift'] = sobjs.FLEX_SHIFT_LOCAL -# if np.all(spec_flex['local_spec_shift'] != None): -# spec_flex['local_spec_shift'].format = '0.3f' -# spec_flex['total_spec_shift'] = sobjs.FLEX_SHIFT_TOTAL -# if np.all(spec_flex['total_spec_shift'] != None): -# spec_flex['total_spec_shift'].format = '0.3f' -# # print the table -# spec_flex.pprint_all() -# # return the table -# return_flex = spec_flex -# -# return return_flex - - # TODO -- Consider separating the methods from the DataContainer as per calibrations class MultiSlitFlexure(DataContainer): """