From fe71e4a56e80c09b4d72d68c2ac5497d7f02923e Mon Sep 17 00:00:00 2001 From: chris-simpson Date: Thu, 9 Jan 2025 13:49:04 -1000 Subject: [PATCH] improve gmu.return_requested_units() to allow any input units --- gemini_instruments/bhros/adclass.py | 8 +-- gemini_instruments/f2/adclass.py | 4 +- gemini_instruments/flamingos/adclass.py | 6 +-- gemini_instruments/gemini/adclass.py | 13 ++--- gemini_instruments/ghost/adclass.py | 2 +- gemini_instruments/gmos/adclass.py | 6 +-- gemini_instruments/gmu.py | 58 ++++++++++++---------- gemini_instruments/gnirs/adclass.py | 4 +- gemini_instruments/graces/adclass.py | 4 +- gemini_instruments/gsaoi/adclass.py | 8 +-- gemini_instruments/niri/adclass.py | 4 +- gemini_instruments/test/lut_descriptors.py | 2 +- gemini_instruments/trecs/adclass.py | 8 +-- 13 files changed, 66 insertions(+), 61 deletions(-) diff --git a/gemini_instruments/bhros/adclass.py b/gemini_instruments/bhros/adclass.py index 04ae795ff..e50d4d0d6 100644 --- a/gemini_instruments/bhros/adclass.py +++ b/gemini_instruments/bhros/adclass.py @@ -17,22 +17,22 @@ def _tag_instrument(self): return TagSet({'BHROS', 'SPECT'}, ()) @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units(input_units="AA") def central_wavelength(self): """ - Returns the central wavelength in nm + Returns the central wavelength Returns ------- float - The central wavelength setting in nm + The central wavelength setting """ # The central_wavelength keyword is in Angstroms keyword = self._keyword_for('central_wavelength') wave_in_angstroms = self.phu.get(keyword, -1) if wave_in_angstroms < 0: return None - return wave_in_angstroms * 0.1 + return wave_in_angstroms @astro_data_descriptor def dec(self): diff --git a/gemini_instruments/f2/adclass.py b/gemini_instruments/f2/adclass.py index 26b569049..0c8148615 100644 --- a/gemini_instruments/f2/adclass.py +++ b/gemini_instruments/f2/adclass.py @@ -164,7 +164,7 @@ def camera(self, stripID=False, pretty=False): return self._may_remove_component(camera, stripID, pretty) @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def central_wavelength(self): """ Returns the central wavelength in nm @@ -302,7 +302,7 @@ def detector_y_offset(self): return -offset if self.phu.get('INPORT') == 1 else offset @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def dispersion(self): """ Returns the dispersion in nm per pixel as a list (one value per diff --git a/gemini_instruments/flamingos/adclass.py b/gemini_instruments/flamingos/adclass.py index f2fed217d..289c2c7fe 100644 --- a/gemini_instruments/flamingos/adclass.py +++ b/gemini_instruments/flamingos/adclass.py @@ -41,15 +41,15 @@ def _tag_dark(self): return TagSet(['DARK', 'CAL']) @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def central_wavelength(self): """ - Returns the central wavelength in nm + Returns the central wavelength Returns ------- float - The central wavelength setting in nm + The central wavelength setting """ return 1500.0 diff --git a/gemini_instruments/gemini/adclass.py b/gemini_instruments/gemini/adclass.py index 779da397c..6870acd7f 100644 --- a/gemini_instruments/gemini/adclass.py +++ b/gemini_instruments/gemini/adclass.py @@ -610,15 +610,15 @@ def cass_rotator_pa(self): return crpa if abs(crpa) <= 360 else None @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units(input_units="um") def central_wavelength(self): """ - Returns the central wavelength in nm or the specified units + Returns the central wavelength Returns ------- float - The central wavelength setting in nm + The central wavelength setting """ # We assume that the central_wavelength keyword is in microns keyword = self._keyword_for('central_wavelength') @@ -626,7 +626,7 @@ def central_wavelength(self): if wave_in_microns < 0: return None - return 1000 * wave_in_microns + return wave_in_microns @astro_data_descriptor def coadds(self): @@ -870,7 +870,7 @@ def disperser(self, stripID=False, pretty=False): stripID, pretty) @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units(input_units="m") def dispersion(self): """ Returns the dispersion in nm per pixel as a list (one value per @@ -883,6 +883,7 @@ def dispersion(self): The dispersion(s) in nm """ keyword = self._keyword_for('dispersion') + print(keyword) if keyword in self.hdr: dispersion = self.hdr[keyword] elif self._keyword_for('dispersion') in self.phu: @@ -892,7 +893,7 @@ def dispersion(self): else: return None - return 1e-9 * dispersion + return dispersion @astro_data_descriptor def dispersion_axis(self): diff --git a/gemini_instruments/ghost/adclass.py b/gemini_instruments/ghost/adclass.py index 615a0ac2f..13476a5b6 100644 --- a/gemini_instruments/ghost/adclass.py +++ b/gemini_instruments/ghost/adclass.py @@ -395,7 +395,7 @@ def calibration_key(self): # FIXME Remove once headers corrected @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def central_wavelength(self): # pragma: no cover """ Dummy to work around current Gemini cal_mgr diff --git a/gemini_instruments/gmos/adclass.py b/gemini_instruments/gmos/adclass.py index 2675b972e..2321e9636 100644 --- a/gemini_instruments/gmos/adclass.py +++ b/gemini_instruments/gmos/adclass.py @@ -207,7 +207,7 @@ def array_name(self): return self.hdr.get('AMPNAME') @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def central_wavelength(self, pretty=False): """ Returns the central wavelength in nm @@ -430,7 +430,7 @@ def disperser(self, stripID=False, pretty=False): return disperser @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def dispersion(self): """ Returns the dispersion in nm per binned pixel as a list (one value per @@ -474,7 +474,7 @@ def dispersion(self): if dispersion is not None: grating_order = self.phu.get('GRORDER', 1) - dispersion = 1e-9 * dispersion / grating_order + dispersion = 1e9 * dispersion / grating_order if not self.is_single: dispersion = [dispersion] * len(self) diff --git a/gemini_instruments/gmu.py b/gemini_instruments/gmu.py index 8b42f4517..3be8ef96a 100644 --- a/gemini_instruments/gmu.py +++ b/gemini_instruments/gmu.py @@ -4,6 +4,8 @@ import re from functools import wraps +import numpy as np + from astropy import coordinates, units as u # The unitDict dictionary defines the factors for the function @@ -106,38 +108,40 @@ def convert_units(input_units, input_value, output_units): return input_value * factor -def return_requested_units(fn): +def return_requested_units(input_units='nm'): """ Decorator that replaces the repeated code for asMicrometers, asNanometers, asAngstroms. Should be replaced by a "units='nm'" parameter, but time is limited. Keeping current coding to avoid """ - @wraps(fn) - def gn(instance, asMicrometers=False, asNanometers=False, asAngstroms=False, - **kwargs): - unit_arg_list = [asMicrometers, asNanometers, asAngstroms] - output_units = u.m # By default - if unit_arg_list.count(True) == 1: - # Just one of the unit arguments was set to True. Return the - # central wavelength in these units - if asMicrometers: - output_units = u.um - elif asNanometers: - output_units = u.nm - else: - output_units = u.AA - - # Ensure we return a list, not an array - # nm are the "standard" DRAGONS wavelength unit - retval = fn(instance, **kwargs) - if retval is None: - return retval - if isinstance(retval, list): - return [None if v is None else (v * u.nm).to(output_units).value - for v in retval] - return (fn(instance) * u.nm).to(output_units).value - - return gn + def inner_decorator(fn): + @wraps(fn) + def gn(instance, asMicrometers=False, asNanometers=False, asAngstroms=False, + **kwargs): + unit_arg_list = [asMicrometers, asNanometers, asAngstroms] + output_units = u.m # By default + if unit_arg_list.count(True) == 1: + # Just one of the unit arguments was set to True. Return the + # central wavelength in these units + if asMicrometers: + output_units = u.um + elif asNanometers: + output_units = u.nm + else: + output_units = u.AA + + # Ensure we return a list, not an array + # nm are the "standard" DRAGONS wavelength unit + retval = fn(instance, **kwargs) + print("RETVAL", retval) + if retval is None: + return retval + if isinstance(retval, list): + return [None if v is None else np.float32((v * u.Unit(input_units)).to(output_units).value) + for v in retval] + return np.float32((retval * u.Unit(input_units)).to(output_units).value) + return gn + return inner_decorator def toicrs(frame, ra, dec, equinox=2000.0, ut_datetime=None): diff --git a/gemini_instruments/gnirs/adclass.py b/gemini_instruments/gnirs/adclass.py index 9c5948a44..29cc58eeb 100644 --- a/gemini_instruments/gnirs/adclass.py +++ b/gemini_instruments/gnirs/adclass.py @@ -91,8 +91,8 @@ def array_name(self): return self.phu.get(self._keyword_for('array_name')) @astro_data_descriptor - @gmu.return_requested_units - def dispersion(self,): + @gmu.return_requested_units() + def dispersion(self): """ Returns the dispersion in nm per pixel as a list (one value per extension) or a float if used on a single-extension slice. It is diff --git a/gemini_instruments/graces/adclass.py b/gemini_instruments/graces/adclass.py index 1e34c7514..6e7171ab6 100644 --- a/gemini_instruments/graces/adclass.py +++ b/gemini_instruments/graces/adclass.py @@ -35,10 +35,10 @@ def _tag_bias(self): return TagSet(['BIAS', 'CAL']) @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def central_wavelength(self): """ - Returns the central wavelength in nm + Returns the central wavelength Returns ------- diff --git a/gemini_instruments/gsaoi/adclass.py b/gemini_instruments/gsaoi/adclass.py index 85aac5544..eb784285c 100644 --- a/gemini_instruments/gsaoi/adclass.py +++ b/gemini_instruments/gsaoi/adclass.py @@ -67,21 +67,21 @@ def array_name(self): return self.phu.get('DETECTOR') @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units(input_units="AA") def central_wavelength(self): """ - Returns the central wavelength in nm + Returns the central wavelength Returns ------- float - The central wavelength setting in nm + The central wavelength setting """ central_wavelength = self.phu.get('WAVELENG', -1) # in Angstroms if central_wavelength < 0.0: return None - return 0.1 * central_wavelength + return central_wavelength @returns_list @use_keyword_if_prepared diff --git a/gemini_instruments/niri/adclass.py b/gemini_instruments/niri/adclass.py index 3594d31ec..e699d4b8b 100644 --- a/gemini_instruments/niri/adclass.py +++ b/gemini_instruments/niri/adclass.py @@ -78,7 +78,7 @@ def array_section(self, pretty=False): return build_ir_section(self, pretty) @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def central_wavelength(self): """ Returns the central wavelength in nm @@ -251,7 +251,7 @@ def disperser(self, stripID=False, pretty=False): return 'MIRROR' @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units() def dispersion(self): """ Returns the dispersion in nm per pixel as a list (one value per diff --git a/gemini_instruments/test/lut_descriptors.py b/gemini_instruments/test/lut_descriptors.py index 4dbf765a3..07b2eba1f 100644 --- a/gemini_instruments/test/lut_descriptors.py +++ b/gemini_instruments/test/lut_descriptors.py @@ -510,7 +510,7 @@ ('detector_x_bin', 1), ('detector_y_bin', 1), ('disperser', 'MIRROR'), - ('dispersion', [-3.88e-10]), + ('dispersion', [-3.8800000000000006e-10]), ('dispersion_axis', [2]), ('effective_wavelength', 1.25e-06), ('elevation', 60.1851833333), diff --git a/gemini_instruments/trecs/adclass.py b/gemini_instruments/trecs/adclass.py index 003adf680..1a0111f1e 100644 --- a/gemini_instruments/trecs/adclass.py +++ b/gemini_instruments/trecs/adclass.py @@ -28,7 +28,7 @@ def _type_mode(self): return TagSet(['SPECT']) @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units(input_units="um") def central_wavelength(self): """ Returns the central wavelength in microns @@ -49,7 +49,7 @@ def central_wavelength(self): wave_in_microns = self.phu.get('HRCENWL') else: return None - return wave_in_microns * 1000 + return wave_in_microns @astro_data_descriptor def detector_x_offset(self): @@ -84,7 +84,7 @@ def detector_y_offset(self): return None @astro_data_descriptor - @gmu.return_requested_units + @gmu.return_requested_units(input_units="um") def dispersion(self): """ Returns the dispersion in microns per pixel as a list (one value per @@ -105,7 +105,7 @@ def dispersion(self): dispersion = 0.0019 else: return None - return dispersion * 1000 + return dispersion @returns_list @astro_data_descriptor