Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/releases/2.1.0dev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ Instrument-specific Updates
(orders 7--3, ~0.8--2.47 microns). Wavelength calibration uses OH sky lines
from the science frames and a new native ``soar_triplespec.fits`` reid
archive.
- MMT/Binospec: ``pypeit_setup`` now splits setups by slit mask in addition to
grating (``decker`` added to ``configuration_keys``), so frames taken with
different masks no longer share calibrations.

Script Changes
--------------
Expand All @@ -71,6 +74,8 @@ Testing

- Add new tests for :mod:`~pypeit.core.pydl`
- Added new tests for :class:`~pypeit.inputfiles.InputFile` objects.
- Added tests for MMT/Binospec setup grouping and INCAN-based flat/trace frame
typing.

Under-the-hood Improvements
---------------------------
Expand Down Expand Up @@ -110,3 +115,6 @@ Bug Fixes
mode to the :ref:`known_issues_coadd2d` documentation for 2D coaddition.
- Fixes a bug in :class:`~pypeit.bspline.bspline.bspline` which was not
correctly setting ``xmin`` and ``xmax`` when using the ``x2`` option.
- MMT/Binospec: flat/trace/illumflat frame typing now requires the
incandescent lamp to be on (``INCAN`` = ``on``), preventing dark/noisy
``INCAN`` = ``off`` exposures from being combined into pixel and trace flats.
16 changes: 16 additions & 0 deletions doc/spectrographs/mmt_binospec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ Overview
This file summarizes several instrument specific
items for the MMTO's Binospec spectrograph.

Setups and Frame Typing
+++++++++++++++++++++++

Unique configurations (setups) are defined by both the grating
(``dispname``, FITS ``DISPERS1``) and the slit mask (``decker``, FITS
``MASK``). Frames taken with different masks therefore end up in separate
setups (separate ``.pypeit`` files and calibration groups), so that slit
traces, pixel flats, and wavelength solutions are never mixed across
distinct slit-mask geometries.

Pixel flats, trace flats, and illumination flats require the incandescent
flat lamp to be on (FITS ``INCAN`` = ``on``), in addition to the arc lamp
being off (``HENEAR`` = ``off``) and the screen deployed (``SCRN`` =
``deployed``). Exposures taken with ``INCAN`` = ``off`` are dark/noisy and
are not auto-typed as flats.

Wavelength Calibration
++++++++++++++++++++++

Expand Down
11 changes: 8 additions & 3 deletions pypeit/spectrographs/mmt_binospec.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ def init_meta(self):
self.meta['lampstat01'] = dict(ext=1, card='HENEAR')
# used for flatlamp, SCRN is actually telescope status
self.meta['lampstat02'] = dict(ext=1, card='SCRN')
# incandescent (flat-field) lamp; required to be 'on' for flat/trace frames
self.meta['lampstat03'] = dict(ext=1, card='INCAN')
self.meta['instrument'] = dict(ext=1, card='INSTRUME')

def compound_meta(self, headarr, meta_key):
Expand Down Expand Up @@ -173,7 +175,7 @@ def configuration_keys(self):
and used to constuct the :class:`~pypeit.metadata.PypeItMetaData`
object.
"""
return ['dispname']
return ['dispname', 'decker']

def raw_header_cards(self):
"""
Expand All @@ -193,7 +195,7 @@ def raw_header_cards(self):
:obj:`list`: List of keywords from the raw data files that should
be propagated in output files.
"""
return ['DISPERS1']
return ['DISPERS1', 'MASK']

@classmethod
def default_pypeit_par(cls):
Expand Down Expand Up @@ -406,7 +408,10 @@ def check_frame_type(self, ftype, fitstbl, exprng=None):
if ftype in ['arc', 'tilt']:
return good_exp & (fitstbl['lampstat01'] == 'on')
if ftype in ['pixelflat', 'trace', 'illumflat']:
return good_exp & (fitstbl['lampstat01'] == 'off') & (fitstbl['lampstat02'] == 'deployed')
# Require the incandescent (flat) lamp to be on; INCAN=off frames
# are dark/noisy exposures and must not be combined into flats.
return good_exp & (fitstbl['lampstat01'] == 'off') \
& (fitstbl['lampstat02'] == 'deployed') & (fitstbl['lampstat03'] == 'on')

log.debug('Cannot determine if frames are of type {0}.'.format(ftype))
return np.zeros(len(fitstbl), dtype=bool)
Expand Down
49 changes: 49 additions & 0 deletions pypeit/tests/test_binospec_setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
Tests for Binospec setup grouping (configuration_keys) and frame typing
(check_frame_type), addressing GitHub issue #2137.
"""
import numpy as np
from astropy.table import Table

from pypeit.spectrographs.mmt_binospec import MMTBINOSPECSpectrograph


def test_configuration_keys_includes_decker():
"""Setups must be split by slit mask (decker), not just grating."""
spec = MMTBINOSPECSpectrograph()
keys = spec.configuration_keys()
assert 'dispname' in keys
assert 'decker' in keys, \
"decker (MASK) must be a configuration key so different slit masks " \
"get separate setups"


def _frame_table(**columns):
"""Build a minimal metadata table for frame-typing tests.

Every column is broadcast to the same length.
"""
n = max(len(np.atleast_1d(v)) for v in columns.values())
data = {k: np.broadcast_to(np.atleast_1d(v), n).copy()
for k, v in columns.items()}
return Table(data)


def test_incan_on_is_flat():
"""INCAN=on with screen deployed and arc lamp off is a flat/trace."""
spec = MMTBINOSPECSpectrograph()
fitstbl = _frame_table(exptime=10.0, lampstat01='off',
lampstat02='deployed', lampstat03='on')
for ftype in ['pixelflat', 'trace', 'illumflat']:
assert spec.check_frame_type(ftype, fitstbl)[0], \
f"INCAN=on frame should be typed as {ftype}"


def test_incan_off_is_not_flat():
"""INCAN=off must NOT be typed as a flat/trace even if screen deployed."""
spec = MMTBINOSPECSpectrograph()
fitstbl = _frame_table(exptime=10.0, lampstat01='off',
lampstat02='deployed', lampstat03='off')
for ftype in ['pixelflat', 'trace', 'illumflat']:
assert not spec.check_frame_type(ftype, fitstbl)[0], \
f"INCAN=off frame must not be typed as {ftype}"
Loading