Skip to content

Commit

Permalink
review comments addressed
Browse files Browse the repository at this point in the history
  • Loading branch information
rcooke-ast committed Oct 2, 2024
1 parent 4f5fa09 commit 7755dee
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 37 deletions.
2 changes: 1 addition & 1 deletion deprecated/flat.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def fit_flat(flat, tilts_dict, tslits_dict_in, slit, inmask = None,
slitmask_pad = pixels.tslits2mask(tslits_dict_in, pad = pad)
thismask = (slitmask_pad == slit) # mask enclosing the wider slit bounadries
# Create a tilts image using this padded thismask, rather than using the original thismask_in slit pixels
tilts = tracewave.fit2tilts(shape, tilts_dict['coeffs'], tilts_dict['func2d'])
tilts = tracewave.fit2tilts(tilts_dict['coeffs'], tilts_dict['func2d'], shape=shape)
piximg = tilts * (nspec-1)
pixvec = np.arange(nspec)

Expand Down
2 changes: 1 addition & 1 deletion pypeit/calibrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ def get_tilts(self):
return self.wavetilts

# Get flexure
_spat_flexure = self.mstilt.spat_flexure if self.par['tiltframe']['process']['spat_flexure_correct'] != "none" \
_spat_flexure = self.mstilt.spat_flexure if self.par['tiltframe']['process']['spat_flexure_method'] != "skip" \
else None

# Build
Expand Down
18 changes: 14 additions & 4 deletions pypeit/core/tracewave.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,18 +900,20 @@ def fit2tilts_prepareSlit(slit_left, slit_right, thismask_science, spat_flexure=
return _spec_eval, _spat_eval


def fit2tilts(shape, coeff2, func2d, spec_eval=None, spat_eval=None):
def fit2tilts(coeff2, func2d, shape=None, spec_eval=None, spat_eval=None):
"""
Evaluate the wavelength tilt model over the full image.
Evaluate the wavelength tilt model over the full image. Note that this function
requires either shape or both spec_eval and spat_eval to be provided. If all three
are provided, spec_eval and spat_eval will be used.
Parameters
----------
shape : tuple of ints,
shape of image
coeff2 : `numpy.ndarray`_, float
result of griddata tilt fit
func2d : str
the 2d function used to fit the tilts
shape : tuple of ints, optional
Shape of image. Only used if spat_eval and spec_eval are not provided.
spat_eval : `numpy.ndarray`_, optional
1D array indicating how spatial pixel locations move across the
image. If spat_eval is provided, spec_eval must also be provided.
Expand All @@ -937,6 +939,14 @@ def fit2tilts(shape, coeff2, func2d, spec_eval=None, spat_eval=None):
if (spec_eval is None and spat_eval is not None) or (spec_eval is not None and spat_eval is None):
msgs.warn('Both spec_eval and spat_eval must be provided.' + msgs.newline() +
'Only one variable provided, so a new (full) grid will be generated.')
# Print a warning if neither are provided
if spec_eval is None and spat_eval is None:
msgs.warn('No spatial and spectral coordinates provided.' + msgs.newline() +
'A new (full) grid will be generated.')
# Print a warning is shape is not provided
if shape is None:
msgs.error('No shape provided for the image.' + msgs.newline() +
'You must provide either `shape` or both `spat_eval` and `spec_eval`.')
msgs.warn("Assuming no spatial flexure.")
_spat_shift = 0.0
# Setup the evaluation grid
Expand Down
7 changes: 4 additions & 3 deletions pypeit/flatfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ def build_waveimg(self):
msgs.error("Wavelength calib or tilts are not available. Cannot generate wavelength image.")
else:
spat_flexure = self.wavetilts.spat_flexure
left, right, msk = self.slits.select_edges(spat_flexure=spat_flexure)
left, right, msk = self.slits.select_edges(initial=True, spat_flexure=spat_flexure)
slitmask = self.slits.slit_img(initial=True, spat_flexure=spat_flexure)
tilts = self.wavetilts.fit2tiltimg(slitmask, left, right, spat_flexure=spat_flexure)
# Save to class attribute for inclusion in the Flat calibration frame
Expand Down Expand Up @@ -1004,8 +1004,9 @@ def fit(self, spat_illum_only=False, doqa=True, debug=False):
self.slits.right_init[:, slit_idx],
onslit_init, _flexure)
tilts = np.zeros(rawflat.shape, dtype=float)
tilts[onslit_init] = tracewave.fit2tilts(rawflat.shape, self.wavetilts['coeffs'][:,:,slit_idx],
self.wavetilts['func2d'], spec_eval=_spec_eval, spat_eval=_spat_eval)
tilts[onslit_init] = tracewave.fit2tilts(self.wavetilts['coeffs'][:,:,slit_idx],
self.wavetilts['func2d'],
spec_eval=_spec_eval, spat_eval=_spat_eval)
# Convert the tilt image to an image with the spectral pixel index
spec_coo = tilts * (nspec-1)

Expand Down
12 changes: 9 additions & 3 deletions pypeit/images/pypeitimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,10 +785,16 @@ def sub(self, other):
# Spatial flexure
spat_flexure = self.spat_flexure
if other.spat_flexure is not None and spat_flexure is not None \
and np.array_equal(other.spat_flexure, spat_flexure):
msgs.warn(f'Spatial flexure different for images being subtracted. Adopting ' \
and not np.array_equal(other.spat_flexure, spat_flexure):
msgs.warn(f'Spatial flexure different for images being subtracted. Adopting '
f'the maximum spatial flexure of each individual edge.')
spat_flexure = np.maximum(spat_flexure, other.spat_flexure)
# Loop through all slit edges and find the largest flexure
for ii in range(spat_flexure.shape[0]):
# Assign the largest flexure (irrespective of sign) for each edge
if np.abs(other.spat_flexure[ii,0]) > np.abs(spat_flexure[ii,0]):
spat_flexure[ii,0] = other.spat_flexure[ii,0]
if np.abs(other.spat_flexure[ii,1]) > np.abs(spat_flexure[ii,1]):
spat_flexure[ii,1] = other.spat_flexure[ii,1]

# Create a copy of the detector, if it is defined, to be used when
# creating the new pypeit image below
Expand Down
10 changes: 5 additions & 5 deletions pypeit/images/rawimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def use_slits(self):
"""
if self.par is None:
return False
return (self.par['spat_flexure_correct'] != "none") or (self.use_flat and self.par['use_illumflat'])
return (self.par['spat_flexure_method'] != "skip") or (self.use_flat and self.par['use_illumflat'])

def apply_gain(self, force=False):
"""
Expand Down Expand Up @@ -506,7 +506,7 @@ def process(self, par, bpm=None, scattlight=None, flatimages=None, bias=None, sl
Bias image for bias subtraction.
slits (:class:`~pypeit.slittrace.SlitTraceSet`, optional):
Used to calculate spatial flexure between the image and the
slits, if requested via the ``spat_flexure_correct`` parameter
slits, if requested via the ``spat_flexure_method`` parameter
in :attr:`par`; see
:func:`~pypeit.core.flexure.spat_flexure_shift`. Also used to
construct the slit illumination profile, if requested via the
Expand Down Expand Up @@ -546,7 +546,7 @@ def process(self, par, bpm=None, scattlight=None, flatimages=None, bias=None, sl
msgs.error('No dark available for dark subtraction!')
if self.par['subtract_scattlight'] and scattlight is None:
msgs.error('Scattered light subtraction requested, but scattered light model not provided.')
if (self.par['spat_flexure_correct'] != "none") and slits is None:
if (self.par['spat_flexure_method'] != "skip") and slits is None:
msgs.error('Spatial flexure correction requested but no slits provided.')
if self.use_flat and flatimages is None:
msgs.error('Flat-field corrections requested but no flat-field images generated '
Expand Down Expand Up @@ -671,9 +671,9 @@ def process(self, par, bpm=None, scattlight=None, flatimages=None, bias=None, sl
# bias and dark subtraction) and before field flattening. Also the
# function checks that the slits exist if running the spatial flexure
# correction, so no need to do it again here.
self.spat_flexure_shift = self.spatial_flexure_shift(slits, method=self.par['spat_flexure_correct'],
self.spat_flexure_shift = self.spatial_flexure_shift(slits, method=self.par['spat_flexure_method'],
maxlag=self.par['spat_flexure_maxlag']) \
if self.par['spat_flexure_correct'] != "none" else None
if self.par['spat_flexure_method'] != "skip" else None

# - Subtract scattered light... this needs to be done before flatfielding.
if self.par['subtract_scattlight']:
Expand Down
18 changes: 9 additions & 9 deletions pypeit/par/pypeitpar.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def __init__(self, trim=None, apply_gain=None, orient=None,
empirical_rn=None, shot_noise=None, noise_floor=None,
use_pixelflat=None, use_illumflat=None, use_specillum=None,
use_pattern=None, subtract_scattlight=None, scattlight=None, subtract_continuum=None,
spat_flexure_correct=None, spat_flexure_maxlag=None):
spat_flexure_method=None, spat_flexure_maxlag=None):

# Grab the parameter names and values from the function
# arguments
Expand Down Expand Up @@ -356,12 +356,12 @@ def __init__(self, trim=None, apply_gain=None, orient=None,
'``slit_illum_relative=True`` in the ``flatfield`` parameter set!'

# Flexure
defaults['spat_flexure_correct'] = 'none'
options['spat_flexure_correct'] = ProcessImagesPar.valid_spatial_flexure()
dtypes['spat_flexure_correct'] = str
descr['spat_flexure_correct'] = 'Correct slits, illumination flat, etc. for spatial flexure. ' \
'Options are: {0}'.format(', '.join(options['spat_flexure_correct'])) + \
'"none" means no correction is performed. ' \
defaults['spat_flexure_method'] = 'skip'
options['spat_flexure_method'] = ProcessImagesPar.valid_spatial_flexure()
dtypes['spat_flexure_method'] = str
descr['spat_flexure_method'] = 'Correct slits, illumination flat, etc. for spatial flexure. ' \
'Options are: {0}'.format(', '.join(options['spat_flexure_method'])) + \
'"skip" means no correction is performed. ' \
'"detector" means that a single shift is applied to all slits. ' \
'"slit" means that each slit is shifted independently.' \
'"edge" means that each slit edge is shifted independently.'
Expand Down Expand Up @@ -467,7 +467,7 @@ def from_dict(cls, cfg):
parkeys = ['trim', 'apply_gain', 'orient', 'use_biasimage', 'subtract_continuum',
'subtract_scattlight', 'scattlight', 'use_pattern', 'use_overscan',
'overscan_method', 'overscan_par', 'use_darkimage', 'dark_expscale',
'spat_flexure_correct', 'spat_flexure_maxlag', 'use_illumflat', 'use_specillum',
'spat_flexure_method', 'spat_flexure_maxlag', 'use_illumflat', 'use_specillum',
'empirical_rn', 'shot_noise', 'noise_floor', 'use_pixelflat', 'combine',
'scale_to_mean', 'correct_nonlinear', 'satpix', #'calib_setup_and_bit',
'n_lohi', 'mask_cr', 'lamaxiter', 'grow', 'clip', 'comb_sigrej', 'rmcompact',
Expand Down Expand Up @@ -504,7 +504,7 @@ def valid_spatial_flexure():
"""
Return the valid methods for combining frames.
"""
return ['none', 'detector', 'slit', 'edge']
return ['skip', 'detector', 'slit', 'edge']

@staticmethod
def valid_saturation_handling():
Expand Down
6 changes: 3 additions & 3 deletions pypeit/pypeit.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,11 +814,11 @@ def objfind_one(self, frames, det, bg_frames=None, std_outfile=None):
spat_flexure = np.zeros((self.caliBrate.slits.nslits, 2)) # No spatial flexure, unless we find it below
# use the flexure correction in the "shift" column
manual_flexure = self.fitstbl[frames[0]]['shift']
if (self.objtype == 'science' and self.par['scienceframe']['process']['spat_flexure_correct'] != "none") or \
(self.objtype == 'standard' and self.par['calibrations']['standardframe']['process']['spat_flexure_correct'] != "none") or \
if (self.objtype == 'science' and self.par['scienceframe']['process']['spat_flexure_method'] != "skip") or \
(self.objtype == 'standard' and self.par['calibrations']['standardframe']['process']['spat_flexure_method'] != "skip") or \
manual_flexure:
if (manual_flexure != self.fitstbl.MASKED_VALUE) and np.issubdtype(self.fitstbl[frames[0]]["shift"], np.integer):
msgs.info(f'Implementing manual spatial flexure of {manual_flexure}')
msgs.info(f'Implementing manual spatial flexure of {manual_flexure} pixels')
spat_flexure = np.full((self.caliBrate.slits.nslits, 2), np.float64(manual_flexure))
sciImg.spat_flexure = spat_flexure
else:
Expand Down
2 changes: 1 addition & 1 deletion pypeit/spectrographs/gemini_gnirs.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ def default_pypeit_par(cls):
par['scienceframe']['process']['objlim'] = 1.5
par['scienceframe']['process']['use_illumflat'] = False # illumflat is applied when building the relative scale image in reduce.py, so should be applied to scienceframe too.
par['scienceframe']['process']['use_specillum'] = False # apply relative spectral illumination
par['scienceframe']['process']['spat_flexure_correct'] = "none" # don't correct for spatial flexure - varying spatial illumination profile could throw this correction off. Also, there's no way to do astrometric correction if we can't correct for spatial flexure of the contbars frames
par['scienceframe']['process']['spat_flexure_method'] = "skip" # don't correct for spatial flexure - varying spatial illumination profile could throw this correction off. Also, there's no way to do astrometric correction if we can't correct for spatial flexure of the contbars frames
par['scienceframe']['process']['use_biasimage'] = False
par['scienceframe']['process']['use_darkimage'] = False
par['calibrations']['flatfield']['slit_illum_finecorr'] = False
Expand Down
2 changes: 1 addition & 1 deletion pypeit/spectrographs/gtc_osiris.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ def default_pypeit_par(cls):
par['scienceframe']['process']['objlim'] = 1.5
par['scienceframe']['process']['use_illumflat'] = False # illumflat is applied when building the relative scale image in reduce.py, so should be applied to scienceframe too.
par['scienceframe']['process']['use_specillum'] = False # apply relative spectral illumination
par['scienceframe']['process']['spat_flexure_correct'] = "none" # don't correct for spatial flexure - varying spatial illumination profile could throw this correction off. Also, there's no way to do astrometric correction if we can't correct for spatial flexure of the contbars frames
par['scienceframe']['process']['spat_flexure_method'] = "skip" # don't correct for spatial flexure - varying spatial illumination profile could throw this correction off. Also, there's no way to do astrometric correction if we can't correct for spatial flexure of the contbars frames
par['scienceframe']['process']['use_biasimage'] = False
par['scienceframe']['process']['use_darkimage'] = False
par['calibrations']['flatfield']['slit_illum_finecorr'] = False
Expand Down
2 changes: 1 addition & 1 deletion pypeit/spectrographs/keck_kcwi.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def default_pypeit_par(cls):
# Illumination corrections
par['scienceframe']['process']['use_illumflat'] = True # illumflat is applied when building the relative scale image in reduce.py, so should be applied to scienceframe too.
par['scienceframe']['process']['use_specillum'] = True # apply relative spectral illumination
par['scienceframe']['process']['spat_flexure_correct'] = "none" # don't correct for spatial flexure - varying spatial illumination profile could throw this correction off. Also, there's no way to do astrometric correction if we can't correct for spatial flexure of the contbars frames
par['scienceframe']['process']['spat_flexure_method'] = "skip" # don't correct for spatial flexure - varying spatial illumination profile could throw this correction off. Also, there's no way to do astrometric correction if we can't correct for spatial flexure of the contbars frames
par['scienceframe']['process']['use_biasimage'] = True # Need to use bias frames for KCWI, because the bias level varies monotonically with spatial and spectral direction
par['scienceframe']['process']['use_darkimage'] = False

Expand Down
4 changes: 2 additions & 2 deletions pypeit/spectrographs/keck_lris.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ def default_pypeit_par(cls):
# Always correct for spatial flexure on science images
# TODO -- Decide whether to make the following defaults
# May not want to do them for LongSlit
par['scienceframe']['process']['spat_flexure_correct'] = "detector"
par['calibrations']['standardframe']['process']['spat_flexure_correct'] = "detector"
par['scienceframe']['process']['spat_flexure_method'] = "detector"
par['calibrations']['standardframe']['process']['spat_flexure_method'] = "detector"

par['scienceframe']['exprng'] = [61, None]

Expand Down
6 changes: 3 additions & 3 deletions pypeit/wavetilts.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def fit2tiltimg(self, slitmask, slits_left, slits_right, spat_flexure=None):
_spec_eval, _spat_eval = tracewave.fit2tilts_prepareSlit(slits_left[:, slit_idx], slits_right[:, slit_idx],
thismask_science, _spat_flexure[slit_idx, :])
# Calculate the tilts
final_tilts[thismask_science] = tracewave.fit2tilts(final_tilts.shape, coeff_out, self.func2d,
final_tilts[thismask_science] = tracewave.fit2tilts(coeff_out, self.func2d,
spec_eval=_spec_eval, spat_eval=_spat_eval)
# Return
return final_tilts
Expand Down Expand Up @@ -797,8 +797,8 @@ def run(self, doqa=True, debug=False, show=False):
thismask_science = self.slitmask_science == slit_spat
_spec_eval, _spat_eval = tracewave.fit2tilts_prepareSlit(slits_left[:, slit_idx], slits_right[:, slit_idx],
thismask_science, self.spat_flexure[slit_idx, :])
self.final_tilts[thismask_science] = tracewave.fit2tilts(self.slitmask_science.shape, coeff_out, self.par['func2d'],
spec_eval=_spec_eval, spat_eval=_spat_eval)
self.final_tilts[thismask_science] = tracewave.fit2tilts(coeff_out, self.par['func2d'],
spec_eval=_spec_eval, spat_eval=_spat_eval)

if show:
viewer, ch = display.show_image(self.mstilt.image * (self.slitmask > -1), chname='tilts')
Expand Down

0 comments on commit 7755dee

Please sign in to comment.