Skip to content

Commit

Permalink
improve gmu.return_requested_units() to allow any input units
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-simpson committed Jan 10, 2025
1 parent 19485aa commit 44bde99
Show file tree
Hide file tree
Showing 16 changed files with 103 additions and 72 deletions.
8 changes: 4 additions & 4 deletions gemini_instruments/bhros/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
4 changes: 2 additions & 2 deletions gemini_instruments/f2/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
11 changes: 8 additions & 3 deletions gemini_instruments/f2/tests/test_f2.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
import gemini_instruments
from gemini_instruments.f2 import AstroDataF2

import numpy as np


FLOAT_TYPES = (float, np.float32, np.float64)

test_files = [
"S20131121S0094.fits",
"S20131126S1111.fits",
Expand All @@ -16,9 +21,9 @@
]

F2_DESCRIPTORS_TYPES = [
('detector_x_offset', float),
('detector_y_offset', float),
('pixel_scale', float),
('detector_x_offset', FLOAT_TYPES),
('detector_y_offset', FLOAT_TYPES),
('pixel_scale', FLOAT_TYPES),
]


Expand Down
6 changes: 3 additions & 3 deletions gemini_instruments/flamingos/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
13 changes: 7 additions & 6 deletions gemini_instruments/gemini/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,23 +610,23 @@ 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')
wave_in_microns = float(self.phu.get(keyword, -1))

if wave_in_microns < 0:
return None
return 1000 * wave_in_microns
return wave_in_microns

@astro_data_descriptor
def coadds(self):
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -892,7 +893,7 @@ def dispersion(self):
else:
return None

return 1e-9 * dispersion
return dispersion

@astro_data_descriptor
def dispersion_axis(self):
Expand Down
2 changes: 1 addition & 1 deletion gemini_instruments/ghost/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions gemini_instruments/gmos/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions gemini_instruments/gmos/tests/test_gmos.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
import astrodata.testing
import gemini_instruments

import numpy as np


FLOAT_TYPES = (float, np.float32, np.float64)

GMOS_DESCRIPTORS_TYPES = [
('detector_x_offset', float),
('detector_y_offset', float),
('detector_x_offset', FLOAT_TYPES),
('detector_y_offset', FLOAT_TYPES),
('nod_count', tuple),
('nod_offsets', tuple),
('pixel_scale', float),
Expand Down
61 changes: 33 additions & 28 deletions gemini_instruments/gmu.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -106,38 +108,41 @@ 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
parameter, but time is limited.
Returns as np.float32 values to avoid excessive precision
"""
@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)
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):
Expand Down
4 changes: 2 additions & 2 deletions gemini_instruments/gnirs/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 8 additions & 3 deletions gemini_instruments/gnirs/tests/test_gnirs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
import gemini_instruments
from gemini_instruments.gnirs import AstroDataGnirs

import numpy as np


FLOAT_TYPES = (float, np.float32, np.float64)

test_files = [
"N20190206S0279.fits",
"N20190214S0058.fits",
Expand All @@ -15,9 +20,9 @@


GNIRS_DESCRIPTORS_TYPES = [
('detector_x_offset', float),
('detector_y_offset', float),
('pixel_scale', float),
('detector_x_offset', FLOAT_TYPES),
('detector_y_offset', FLOAT_TYPES),
('pixel_scale', FLOAT_TYPES),
]


Expand Down
4 changes: 2 additions & 2 deletions gemini_instruments/graces/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------
Expand Down
8 changes: 4 additions & 4 deletions gemini_instruments/gsaoi/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions gemini_instruments/niri/adclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 13 additions & 3 deletions gemini_instruments/test/test_astrodata_descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
import gemini_instruments
import os

import numpy as np


FLOAT_TYPES = (float, np.float32, np.float64)

THIS_DIR = os.path.dirname(__file__)

from .lut_descriptors import fixture_data as descriptors_fixture_data
Expand Down Expand Up @@ -40,7 +45,12 @@ def test_descriptor(instr, filename, descriptor, value):
assert method() is None
else:
mvalue = method()
if float in (type(value), type(mvalue)):
if type(value) in FLOAT_TYPES or type(mvalue) in FLOAT_TYPES:
assert abs(mvalue - value) < 0.0001
else:
assert value == mvalue
elif isinstance(value, list):
assert len(value) == len(mvalue)
for v, mv in zip(value, mvalue):
if type(v) in FLOAT_TYPES or type(mv) in FLOAT_TYPES:
assert abs(mv - v) < 0.0001
else:
assert v == mv
Loading

0 comments on commit 44bde99

Please sign in to comment.