PypeIt can account for flexure-spectral
and flexure-spatial
in the instrument. The former is applied by default while the latter requires extra care and expertise.
We discuss each in turn.
The code has a simple yet relatively robust method to cross-correlate the slits against any input image to determine a rigid, spatial offset. This algorithm is performed for any frame type by setting spat_flexure_correct = True
in the process
block of processimagespar
.
We have made our own determinations for which instruments to enable this as the default. Inspect the instr_par
list to see if your instrument is included (search for the value of spat_flexure_correct
).
Depending on what frame types you choose to correct, the code will behave somewhat differently. Here we describe the options in increasing complexity.
Most users may wish to only correct for flexure when processing standard and science frames. If you wish to turn on this correction add this to your PypeIt file:
[scienceframe]
[[process]]
spat_flexure_correct = True
[calibrations]
[[standardframe]]
[[[process]]]
spat_flexure_correct = True
This will:
- Calculate a spatial offset for each science/standard frame from the slits
- Apply this correction for the illumination flat
- Apply this correction prior to sky subtraction and extraction
To apply the correction only to your "tilts" image, you would instead add the following to your ../pypeit_file
:
[calibrations]
[[tiltframe]]
[[[process]]]
spat_flexure_correct = True
This will:
- Calculate a spatial offset between the trace flats and the tilt image
- Construct the tilt solution in that frame
- Apply an offset to generate tilts and wavelengths for the associated science/standard images
PypeIt calculates the spectral flexure correction, as a single pixel shift, by performing a cross-correlation between an extracted sky spectrum and an archived sky spectrum. This is then imposed on the wavelength solution with simple linear interpolation.
To enable this correction the parameter spec_method
in flexurepar
should be set to boxcar
or slitcen
. The default for most spectrographs is spec_method = skip
, i.e., no spectral flexure correction is performed. Inspect the instr_par
list to see if spectral flexure is preformed by default for your instrument (i.e., search for the value of spec_method
in the [flexure]
parameter block).
If spec_method = boxcar
(recommended) the observed sky spectrum flux is boxcar extracted, while the spectrum wavelength is taken from the extracted 1D object. If no objects have been extracted, set spec_method = slitcen
, which uses a spectrum extracted from the center of each slit.
For the archived sky spectrum, generally, the Paranal sky spectrum (paranal_sky.fits
) is used by default. However, this is different for Kast blue and LRIS blue where sky_kastb_600.fits
and sky_LRISb_600.fits
are respectively used (see Alternate sky models for all sky models).
Narrow sky emission lines dominate the analysis, but other features can affect the cross-correlation.
The maximum allowable spectral shift (in pixels) is set using the spec_maxshift
flexurepar
, where the default is 20 pixels. If a spectrum is measured to have a shift greater than this value, the parameter excessive_shift
determines how the code responds. The default value use_median
allows the code to use the median flexure shift among all the objects in the same slit (if more than one object is detected) or among all the other slits. If a median value is not available, the flexure correction will not be applied to this spectrum. Optionally, the user may specify excessive_shift = crash
to cause the code to stop execution with an error or excessive_shift = set_to_zero
to allow the code to continue executing while skipping flexure correction (for this object) by setting the shift to zero or excessive_shift = continue
to utilize the large shift value. This feature is included caveat emptor, and the user should carefully examine the flexure QA PNG images (QA/PNGs/<objname>_global_<DET>_<SLIT>_spec_flex_corr.png
and similar) to be sure excessive flexure shift is not a spurious result of low signal-to-noise in the sky background before using the continue
option.
The basic algorithm may be summarized as follows:
- Identify the overlapping wavelength range between data and archived sky.
- Rebin the archived sky spectrum onto the overlapping wavelength range.
- Smooth the sky spectrum to the resolution of the data, if the archive has higher spectral resolution (preferred).
- Normalize each spectrum to unit average sky counts
- Subtract a bspline continuum from each
- Perform a cross-correlation
- Fit the cross-correlation with a parabola to find center
- Apply shift
You may find that the default sky models are not the best suited for your data. If so, there is a script that allows the user to plot the extracted sky spectrum for their data against any of the sky models in the PypeIt archive.
The script usage can be displayed by calling the script with the -h
option:
As noted above, the Paranal sky model is the default reference. Presently, we are finding that the sky spectrum at Mauna Kea (measured with LRIS) is sufficiently variable and dark that a robust solution is challenging. Fair results are achieved by using the instrument-specific sky spectra in the LowRedux package. The best practice currently is to use the one that best matches as an optional parameter
The models supplied with PypeIt are (see here),
Filename | Description |
---|---|
paranal_sky.fits |
|
sky_LRISb_400.fits |
|
sky_LRISb_600.fits |
|
sky_kastb_600.fits |
|
sky_LRISr_600_7500_5460_7950.fits |
|
We have also implemented a method to calculate a flexure correction across multiple detectors, i.e. with an expanded wavelength coverage. In contrast to the standard approach that estimates and applies a single pixel shift for the entire spectrum, this technique fits for a linear correction with wavelength.
Thus far, it has only been developed and fine-tuned for the 1200 line grating of Keck/DEIMOS. It is unlikely to work very well for wavelengths much blueward of 6000 angstrom (where sky emission lines are sparse).
Briefly, this algorithm:
- Match slits across pairs of red/blue detectors
- Measure the centroids of select sky lines
- Fit the flexure solutions, slit by slit
- Fit a 2D solution to all of the slits
- Write output, including QA
- The user then needs to read in the output and apply it to their spectra with their own custom code.
Future work may combine this approach with the standard (e.g. implement cross-correlation with a stretch).
If you wish to adopt this approach (not recommended for most users), there are several key steps:
First, modify your ../pypeit_file
to turn off the standard flexure and to avoid the vacuum frame:
[flexure]
spec_method = skip
[calibrations]
[[wavelengths]]
refframe = observed
Second, generate a Flexure File as described below.
Last, run the pypeit_multislit_flexure
script. The script usage can be displayed by calling the script with the -h
option:
and a typical call looks like:
pypeit_multislit_flexure file.flex out_root
where out_root
is the prefix for the FITS file generated that contains the flexure solution for all of the slits.
After running PypeIt with the standard call, construct a simple Flexure File ,which is a type of input_files
. It has a (required) parameter_block
that must specify the spectrograph name and a (required) data_block
that provides the table of files to process.
Here is an example file:
# User-defined execution parameters
[rdx]
spectrograph = keck_deimos
flexure read
filename
Science/spec1d_DE.20100913.22358-CFHQS1_DEIMOS_20100913T061231.334.fits
flexure end
As desired, you can modify the flexurepar
in the top block.
The output file produced by pypeit_multislit_flexure is named ${outroot}${target}_${filename}.fits
, where
outroot
is the 2nd command-line argument (see above)target
is pulled from the header of the firstspec1d
file in theflexure_file
(the TARGET header keyword must exist)filename
is parsed from the FILENAME header keyword:filename = header['FILENAME'].split('.')[2]
The file has the following two extensions:
HDU Name | HDU Type | Data Type | Description |
---|---|---|---|
PRIMARY |
astropy.io.fits.PrimaryHDU | ... | Empty data HDU. Contains basic header information. |
FLEXURE |
astropy.io.fits.BinTableHDU | ... | All data from the ~pypeit.core.flexure.MultiSlitFlexure datamodel |