Skip to content

Commit

Permalink
Merge pull request #1884 from pypeit/msc_ar_slits
Browse files Browse the repository at this point in the history
Fixes problem with definition of image locations in mosaics
  • Loading branch information
kbwestfall authored Feb 4, 2025
2 parents d5ab50f + 493dd06 commit 20a4260
Show file tree
Hide file tree
Showing 14 changed files with 604 additions and 224 deletions.
8 changes: 8 additions & 0 deletions doc/api/pypeit.scripts.run_to_calibstep.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pypeit.scripts.run\_to\_calibstep module
========================================

.. automodule:: pypeit.scripts.run_to_calibstep
:members:
:private-members:
:undoc-members:
:show-inheritance:
36 changes: 36 additions & 0 deletions doc/help/pypeit_run_to_calibstep.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.. code-block:: console
$ pypeit_run_to_calibstep -h
usage: pypeit_run_to_calibstep [-h] [--science_frame SCIENCE_FRAME]
[--calib_group CALIB_GROUP] [--det DET]
[-v VERBOSITY] [-r REDUX_PATH] [-s]
pypeit_file step
Run PypeIt to a single calibration step for an input frame
positional arguments:
pypeit_file PypeIt reduction file (must have .pypeit extension)
step Calibration step to perform. Valid steps are: align,
arc, bias, bpm, dark, flats, scattlight, slits, tiltimg,
tilts, wv_calib
options:
-h, --help show this help message and exit
--science_frame SCIENCE_FRAME
Raw science frame to reduce as listed in your PypeIt
file, e.g. b28.fits.gz. Either this or the calib_group
must be provided
--calib_group CALIB_GROUP
Calibration group ID to reduce. Either this or the frame
must be provided
--det DET Detector to reduce
-v VERBOSITY, --verbosity VERBOSITY
Verbosity level between 0 [none] and 2 [all]
-r REDUX_PATH, --redux_path REDUX_PATH
Path to directory for the reduction. Only advised for
testing
-s, --show Show reduction steps via plots (which will block further
execution until clicked on) and outputs to ginga.
Requires remote control ginga session via "ginga
--modules=RC,SlitWavelength &"
2 changes: 1 addition & 1 deletion doc/help/run_pypeit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
usage: run_pypeit [-h] [-v VERBOSITY] [-r REDUX_PATH] [-m] [-s] [-o] [-c]
pypeit_file
## [1;37;42mPypeIt : The Python Spectroscopic Data Reduction Pipeline v1.17.1.dev2+g6e8b74d14[0m
## [1;37;42mPypeIt : The Python Spectroscopic Data Reduction Pipeline v1.17.2.dev152+gd5ab50fca[0m
##
## Available spectrographs include:
## aat_uhrf, bok_bc, gemini_flamingos1, gemini_flamingos2,
Expand Down
150 changes: 75 additions & 75 deletions doc/pypeit_par.rst

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions doc/releases/1.17.2dev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ Bug Fixes
the spectrum is extracted even when `pixelflat_model` does not exist.
- The variance cube previously had a cubic term, and this has been changed
to a quadratic term. This has been cross-checked with simple subpixel calculations.
- Fixes bug associated with trying to remove or add slits for reductions that
mosaic multiple detectors.
- Fix Setup GUI sizing issues on MacOS.
- Fixed a bug with ``pypeit_identify`` when the number of echelle orders has
more than two digits.
131 changes: 131 additions & 0 deletions pypeit/core/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,134 @@ def str2list(inp, length=None):
indices += [int(grp)]
return np.unique(indices).tolist()


def parse_image_location(inp, spec):
"""
Parse a colon-separated string with a detector/mosaic identifier and a
series of floats.
This function should be used to parse a *single* image location. Multiple
image locations are generally separated by semi-colons; the ``inp`` string
provided *must not* contain semi-colons.
This is primarily used for two purposes: setting locations in a
PypeIt-reduced image (e.g., adding or removing slits) or to define a manual
extraction aperture (see :ref:`manual`).
Parameters
----------
inp : :obj:`str`
Colon-separated string with a detector identifier and 2 to 3 numbers.
**Must not contain semi-colons.**
spec : :class:`~pypeit.spectrographs.spectrograph.Spectrograph`
Spectrograph class used to interpret the detector/mosaic identifier.
Returns
-------
:obj:`tuple`
Flag that detector integer as negative, the detector identifier returned
as a string (e.g., DET01, MSC01), and the set of floats.
Raises
------
PypeItError
Raised if the ``inp`` string contains a semi-colon, if a mosaic is
identified that is not valid for the provided spectrograph, or if there
is an issue constructing the detector/mosaic identifier.
Examples
--------
Setup, where ``keck_nires`` is just used as an example of a single detector
spectrograph.
>>> from pypeit.spectrographs.util import load_spectrograph
>>> from pypeit.core import parse
>>> spec = load_spectrograph('keck_nires')
The detector can be negative:
>>> parse.parse_image_location('-1:34.5:400.1:4', spec)
(True, 'DET01', 34.5, 400.1, 4.0)
or positive:
>>> parse.parse_image_location('1:34.5:400.1:4', spec)
(False, 'DET01', 34.5, 400.1, 4.0)
This will fail because ``(1,2,3)`` is not an allowed mosaic for ``keck_nires``.
>>> try:
... parse.parse_image_location('(1,2,3):34.5:400.1:4', spec)
... except:
... print('failed')
[ERROR] :: (1, 2, 3) is not a valid mosaic for keck_nires.
failed
Now for a mosaic:
>>> spec = load_spectrograph('gemini_gmos_south_ham')
>>> parse.parse_image_location('(1,2,3):34.5:400.1:4', spec)
(False, 'MSC01', 34.5, 400.1, 4.0)
>>> parse.parse_image_location('(-1,-2,-3):34.5:400.1:4', spec)
(True, 'MSC01', 34.5, 400.1, 4.0)
>>> parse.parse_image_location('2:34.5:400.1', spec)
(False, 'DET02', 34.5, 400.1)
"""
if ';' in inp:
msgs.error(f'Image location string provided ({inp}) includes a semi-colon!')
# Split the components of the string
_inp = inp.split(':')

# Get the detector integer(s); det will be a list of a single number (no
# mosaic) or >= 2 numbers (mosaic)
det = tuple(int(d) for d in _inp[0].strip('()').split(','))

# check if the detector integers are negative
neg = np.all([d < 0 for d in det])
if neg:
det = tuple(-d for d in det)

if len(det) > 1 and det not in spec.allowed_mosaics:
msgs.error(f'{det} is not a valid mosaic for {spec.name}.')
elif len(det) > 1 and det in spec.allowed_mosaics:
# we use detname, which is a string (e.g., 'DET01', 'MSC01')
detname = spec.get_det_name(det)
elif len(det) == 1:
detname = spec.get_det_name(det[0])
else:
msgs.error(f'Unable to parse detector identifier in: {inp}')

return (neg, detname) + tuple(float(p) for p in _inp[1:])


def fix_config_par_image_location(par):
"""
Fix mosaic image locations as parsed by `configobj`_.
When, e.g., defining a slit to remove, the user sets:
.. code-block:: ini
rm_slits = (1,2,3):1500:331; (1,2,3):1500:635
The `configobj`_ parser turns this into ``['(1', '2', '3):1500:331; (1',
'2', '3):1500:635']``. This function converts this back to the expected
format: ``['(1,2,3):1500:331', '(1,2,3):1500:635']``.
Parameters
----------
par : :obj:`str`, :obj:`list`
List of strings parsed by `configobj`_.
Returns
-------
:obj:`list`
The corrected image-location definitions.
"""
# Ensure list type; avoid running ','.join(par) on a string!
_par = [par] if isinstance(par, str) else par
# Simply join all the entries with a comma (removed by the configobj parser)
# and instead split at the semi-colon and remove leading/trailing whitespace:
return list(map(str.strip, (','.join(_par)).split(';')))

4 changes: 3 additions & 1 deletion pypeit/core/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
from pypeit import msgs
from pypeit import utils
from pypeit import sampling
from pypeit.core import moment, pydl, arc
from pypeit.core import arc
from pypeit.core import moment
from pypeit.core import pydl

# TODO: Some of these functions could probably just live in pypeit.edges

Expand Down
Loading

0 comments on commit 20a4260

Please sign in to comment.