Instruments¶
PyReduce supports many instruments out of the box. Custom instruments can be added by creating YAML configuration files.
Supported Instruments¶
ESO Instruments¶
HARPS - High Accuracy Radial velocity Planet Searcher
HARPS-N - HARPS-North at TNG
HARPSPOL - HARPS Polarimeter (dual-beam mode)
UVES - UV-Visual Echelle Spectrograph
XSHOOTER - Wide-band spectrograph (UVB/VIS/NIR)
CRIRES+ - Cryogenic IR Echelle Spectrograph
Space Telescopes¶
JWST NIRISS - Near Infrared Imager and Slitless Spectrograph
JWST MIRI - Mid-Infrared Instrument
Other Observatories¶
Keck NIRSPEC - Near-IR spectrograph
Lick APF - Automated Planet Finder
McDonald - McDonald Observatory spectrograph
NEID - NN-EXPLORE Exoplanet Investigations with Doppler spectroscopy
ELT Instruments (Simulated)¶
METIS - Mid-infrared ELT Imager and Spectrograph (LSS and IFU modes)
MICADO - Multi-AO Imaging Camera for Deep Observations
MOSAIC - Multi-Object Spectrograph for Astrophysics, Intergalactic-medium studies and Cosmology
ANDES_UBV - ArmazoNes high Dispersion Echelle Spectrograph (U/B/V channels)
ANDES_RIZ - ArmazoNes high Dispersion Echelle Spectrograph (R/IZ channels)
ANDES_YJH - ArmazoNes high Dispersion Echelle Spectrograph (Y/J/H channels)
NTE - New Technology Echelle spectrograph
Adding a Custom Instrument¶
Method 1: YAML Configuration¶
Create a YAML file defining your instrument:
# myinstrument.yaml
instrument: MyInstrument
telescope: MyTelescope
channels: [default]
# Detector
naxis: [2048, 2048]
orientation: 0
extension: 0
gain: 1.0
readnoise: 5.0
# Header keywords
date: DATE-OBS
target: OBJECT
exposure_time: EXPTIME
# File classification
kw_bias: IMAGETYP
id_bias: bias
kw_flat: IMAGETYP
id_flat: flat
kw_spec: IMAGETYP
id_spec: object
Load it directly:
from pyreduce.instruments import load_instrument
inst = load_instrument("/path/to/myinstrument.yaml")
Method 2: Python Class¶
For instruments needing custom logic, create a Python class:
from pyreduce.instruments.common import Instrument
class MyInstrument(Instrument):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Custom initialization
def add_header_info(self, header):
# Compute derived header values
header["MJD_MID"] = header["MJD_OBS"] + header["EXPTIME"] / 86400 / 2
return header
def get_wavecal_filename(self, header, channel, **kwargs):
# Return path to wavelength calibration file
return f"wavecal_{channel}.npz"
Place both files in pyreduce/instruments/{NAME}/ directory (YAML as config.yaml, Python as __init__.py).
Instrument Configuration Fields¶
Required Fields¶
Field |
Description |
|---|---|
|
Instrument name |
|
Telescope name |
|
List of instrument channels/modes |
|
Detector dimensions [x, y] |
Detector Properties¶
Field |
Description |
|---|---|
|
FITS extension (0 or name) |
|
Rotation/flip code (0-7) |
|
Detector gain (value or header keyword) |
|
Read noise (value or header keyword) |
|
Dark current (value or header keyword) |
|
Prescan region in x |
|
Overscan region in x |
Header Mappings¶
These map instrument-specific header keywords to internal names:
Field |
Description |
|---|---|
|
Observation date |
|
Target name |
|
Exposure time |
|
Coordinates |
|
Julian date |
|
Instrument mode |
File Classification¶
Field |
Description |
|---|---|
|
Bias file keyword and pattern |
|
Flat file keyword and pattern |
|
Wavelength calibration keyword and pattern |
|
Science file keyword and pattern |
See pyreduce/instruments/models.py for the complete schema.
Detector Orientation¶
The orientation field controls how the raw image is rotated/flipped before processing.
Values 0-7 correspond to different transformations:
Value |
Transformation |
|---|---|
0 |
No change |
1 |
Rotate 90 CCW |
2 |
Rotate 180 |
3 |
Rotate 90 CW |
4 |
Flip horizontal |
5 |
Flip horizontal + rotate 90 CCW |
6 |
Flip vertical |
7 |
Flip horizontal + rotate 90 CW |
The goal is to orient the image so that:
Dispersion direction is horizontal (wavelength increases left to right)
Cross-dispersion is vertical (orders are stacked vertically)
Reduction Settings¶
Each instrument has its own settings file at pyreduce/instruments/{INSTRUMENT}/settings.json.
This inherits from and overrides pyreduce/instruments/defaults/settings.json.
Per-channel overrides can be placed in settings_{channel}.json (e.g., settings_r.json),
which inherit from the instrument’s base settings.
See Configuration for details.
Multi-Fiber Instruments¶
Some instruments have multiple fibers per spectral order (e.g., IFU bundles, calibration fibers alongside science fibers). PyReduce supports these via the fibers configuration in config.yaml:
Fiber groups - Named collections of fibers (e.g., “science”, “cal”, “sky”)
Bundle patterns - Repeating groups of fibers (e.g., 7 fibers per IFU target)
Per-order grouping - For echelle instruments with multi-fiber orders
The fibers.use section specifies which traces each reduction step should use:
fibers:
groups:
A: { range: [1, 36], merge: average }
cal: { range: [37, 40], merge: average }
use:
science: [A]
wavecal: [cal]
norm_flat: all
See Fiber Bundle Tracing for the full configuration reference.