Object (Science) Reduction Planning Document#
Status: P0 complete — pipeline runs end-to-end; P1 core (flatfield, throughput, sky, RWSS) implemented; P2+ in progress. Last updated: 2026-02-19
0. Scope#
Complete the reduce_object pipeline so that a raw science frame can be
reduced end-to-end to a wavelength-calibrated, flat-fielded,
sky-subtracted, flux-calibrated RED file. This document covers every
placeholder function in reduce_object.py and related gaps in
make_ex.py and make_red.py.
What already works#
Component |
Module |
Status |
|---|---|---|
Preprocessing (IM creation) |
|
~90% |
Tramline map generation |
|
~90% |
SUM extraction |
|
Done |
Arc wavelength calibration |
|
~90% |
Scrunching (standalone) |
|
Done |
Fiber flat reduction |
|
~50% |
Object core (flatfield, throughput, sky, RWSS) |
|
P1 core implemented |
Flux calibration |
|
Done |
What is missing#
The P1 core of reduce_object() (flat-fielding, fiber-throughput
correction, RWSS snapshot, and basic sky subtraction) is now implemented
in reduce_object.py. Remaining gaps are the P2/P3 features
(skylines_recalibration, skycalib_test, super_skysub,
telcor, velcor_update_fibre_table, skysubpca,
correct_frame_by_assoc_transfer_function, propagate_badthput,
de_wiggle) which are still no-ops guarded by flags. The current
commissioning workflow can now produce wavelength-calibrated,
flat-fielded, sky-subtracted, flux-calibrated RED files; what remains is
to add the advanced corrections and diagnostics.
1. Architecture Overview#
Raw science frame
│
▼
make_im ──► IM file (bias/dark/flat corrected image + variance)
│
▼
make_ex ──► EX file (extracted 1D spectra per fiber + variance)
│
▼
reduce_object ──► RED file (calibrated, sky-subtracted spectra)
│
├─ skylines_recalibration [P3] fine-tune wavelength via sky lines
├─ copy EX → RED
├─ skycalib_test [P3] QC check on skyline wavelengths
├─ cmfspec_flatfield [P1] divide by fiber flat response
├─ scrunch_object_frame [P0] rebin to linear wavelength grid
├─ tdfio_nod_shuffle [P0] trivial flag check
├─ cmfspec_ftpcal [P1] fiber throughput correction
├─ make_rwss [P3] snapshot before sky subtraction
├─ skysub [P1] median sky subtraction
├─ super_skysub [P2] super-sampled sky subtraction
├─ tdfio_pixcal_delete [P3] housekeeping
├─ telcor [P2] telluric absorption correction
├─ velcor_update_fibre_table [P2] heliocentric velocity correction
├─ skysubpca [P2] PCA sky subtraction (alternative)
├─ _apply_fluxcal [Done] flux calibration
├─ correct_frame_by_assoc_transfer_function [P3]
├─ propagate_badthput [P3] flag bad-throughput fibers
├─ de_wiggle [P3] remove sinusoidal artifacts
├─ tdfio_sds_write [P3] write args to FITS header
├─ tdfio_setred [P3] set REDUCED status flag
└─ stamp_2dfdrver [P3] write pipeline version
2. Priority Definitions#
Priority |
Meaning |
Goal |
|---|---|---|
P0 |
Critical — pipeline cannot produce useful output without this |
First usable end-to-end reduction |
P1 |
High — needed for science-quality reductions |
Commissioning-grade spectra |
P2 |
Medium — improves accuracy and enables advanced use cases |
Publication-quality spectra |
P3 |
Low — housekeeping, diagnostics, edge cases |
Polish and completeness |
3. Implementation Plan#
Phase 0 — Minimum Viable Pipeline#
Goal: run reduce_object end-to-end on commissioning data without errors
and produce wavelength-calibrated extracted spectra.
P0-1. tdfio_nod_shuffle — Nod & Shuffle flag check#
Effort: trivial (< 10 lines)
Action: return
0for standard (non-N&S) mode. ReadUTNODSFLheader keyword if present; otherwise assume standard mode.Why P0: this function gates access to
cmfspec_ftpcal,skysub, andskysubpca— without it, the pipeline crashes immediately.
P0-2. scrunch_object_frame — Wavelength rebinning#
Effort: small (~30 lines, wiring)
Action: wrap the existing
scrunch_from_arc_idfromwavecal/scrunch.py. ReadWAVEL_FILENAMEfromargs, callscrunch_from_arc_id(red_filename, arc_filename, args).Depends on: the arc RED file existing with a calibrated
WAVELAextension.Why P0: without scrunching, spectra remain on pixel coordinates — flat-fielding, sky subtraction, and flux calibration all assume a common wavelength grid.
P0-3. I/O utilities — tdfio_sds_write, tdfio_setred, stamp_2dfdrver, tdfio_pixcal_delete#
Effort: small (~50 lines total)
Action:
tdfio_sds_write: write selectedargskeys as FITS header cards (e.g.,HIERARCH KSPECDR_<KEY> = <VALUE>), or as aDRARGSBinTableHDU.tdfio_setred: setDRSTATUS = 'REDUCED'header keyword.stamp_2dfdrver: setDRPIPVER = kspecdr.__version__header keyword.tdfio_pixcal_delete: deletePIXCALHDU if present (try/except).
Why P0: these are required for the function to complete without raising
NotImplementedError, even though their scientific impact is minimal.
P0-4. Remaining stubs — make non-critical functions conditional no-ops#
Effort: trivial
Action: for functions not yet implemented that are behind
args.get(FLAG, False)guards (e.g.,skylines_recalibration,skycalib_test,super_skysub,telcor,velcor_update_fibre_table,skysubpca,correct_frame_by_assoc_transfer_function,propagate_badthput,de_wiggle), changeraise NotImplementedErrortologger.warning("... not implemented, skipping")and return early. This allows the pipeline to run when these features are not requested.For functions that are unconditionally called (
skylines_recalibration,propagate_badthput,de_wiggle), add a check for an enable flag or make them no-ops with a warning.Why P0: the pipeline must not crash on any code path during normal operation.
P0 deliverable: reduce_object runs end-to-end on commissioning
data and produces a scrunched RED file. No flat-fielding or sky
subtraction yet, but the spectra are wavelength-calibrated and
inspectable.
Phase 1 — Science-Quality Core#
Goal: produce flat-fielded, sky-subtracted, wavelength-calibrated spectra suitable for commissioning analysis.
P1-1. cmfspec_flatfield — Fiber flat-field division#
Effort: medium (~70 lines)
Called at: after EX→RED copy, before scrunching (pixel space)
Action:
Check
args.get('USEFFLAT', True). IfFalse, write history'Not divided by fibre flat field'and return immediately.Read
FFLAT_FILENAMEfromargs. If missing or empty, raise (or log error and return); 2dfdr sets statusDRS__NOFFLAT.Open the FFLAT RED FITS file and read the primary image array
FLTIMG (NPIX, NFIB)and variance arrayFLTVAR (NPIX, NFIB).Read the science RED primary image
OBJIMGand varianceOBJVAR. AssertOBJIMG.shape == FLTIMG.shape; raise a clear error if dimensions do not match (this is the most common failure mode).Check for optional truncation: if
TRUNCFLATisTrue, readUSEFLATSTART(default 1) andUSEFLATEND(default 2048) and setFLTIMG[:USEFLATSTART-1, :] = 1.0,FLTVAR[:USEFLATSTART-1, :] = 0.0(likewise for pixels beyondUSEFLATEND) so those regions are divided by unity (no correction applied outside the trusted range).Division (element-wise, handling bad pixels / zeros):
good = (FLTIMG != 0) & np.isfinite(FLTIMG) & np.isfinite(OBJIMG) OBJIMG_out = np.where(good, OBJIMG / FLTIMG, np.nan)
Full variance propagation (Taylor expansion, both terms):
Var_out = (1/flat)^2 * Var_obj + (obj/flat^2)^2 * Var_flat
Set
OBJVAR_out = np.nanwhereverOBJIMG_outis NaN.Write updated image and variance back to the RED file.
Write FITS history:
f'Divided by fibre flat field {FFLAT_FILENAME}'. IfTRUNCFLAT, append a second history record noting the pixel range used.
What the FFLAT RED file contains:
reduce_fflatproduces a pixel-space (un-scrunched) flat where each fiber spectrum is normalized to ≈1.0 (the per-fiber median is used for normalization, then the global averaged flat is removed). Values should be close to 1.0 ± a few per cent. No explicitTHPUTextension is present — that is the job ofcmfspec_ftpcal.Confirmed: flat-fielding happens in pixel space, before scrunching.
reduce_fflatscrunch→average→unscrunch→extrapolate→ normalize so the output is always pixel-space. This matches the 2dfdr call order inreduce_object.F95(line 183, beforeSCRUNCH_OBJECT_FRAMEat line 190).
P1-2. cmfspec_ftpcal — Fiber throughput correction#
Effort: medium (~90 lines)
Called at: after scrunching, before sky subtraction; skipped entirely if
TDFIO_NOD_SHUFFLEreturns non-zero (Nod & Shuffle mode)Action:
Check
args.get('THRUPUT', True). IfFalse, write history'No throughput calibration performed'and return.Check
args.get('USETHPTFILE', False). IfTrueand aTHROUGHPUT.fitsfile exists in the working directory, read itsTHPUTextension (1-D vector of length NFIB) and use those values directly (skipping all calculation below).Otherwise, select the calculation method from
args.get('TPMETH', 'OFFSKY'):'OFFSKY'(default): readTHPUT_FILENAMEfrom args; open that file and read itsTHPUTextension. If filename is empty, log a warning'No throughput map available — continuing'and return without modifying data.'SKYLINE(KGB)': Karl Glazebrook’s sky-line algorithm — (a) callumfspec_ftpc(mean-per-fiber, median-normalized) for a first-pass estimate; (b) build a median sky spectrum from sky fibers (TYPE='S') normalized by that estimate; (c) subtract continuum via a ±100-pixel median filter; (d) for each P/S fiber, do a robust linear fit (slope B) of the continuum-subtracted fiber spectrum against the median sky spectrum; (e)thput = Bif0.01 < B < 100, elseNaN; (f) normalize the whole vector by its median.'SKYFLUX(COR)'/'SKYFLUX(MED)': sky-line flux integration methods — readskylines.datfor line positions, integrate continuum-subtracted flux in ±2×FWHM-pixel windows, normalize per line and across lines. These are more robust when many sky lines are present but require askylines.datdata file.Recommendation for KSPEC commissioning: start with
'SKYLINE(KGB)'(self-contained, no external file); fall back to'OFFSKY'if a dedicated sky frame is available.
thput_vecis a 1-D float array of length NFIB. Sanity bounds: values outside(0.01, 100.0)are set toNaN.Divide each fiber’s spectrum and variance by its throughput:
scale = np.where(np.isfinite(thput_vec) & (thput_vec > 0), 1.0 / thput_vec, 0.0) spec[:, i] *= scale[i] var[:, i] *= scale[i]**2
(2dfdr sets scale=0 for bad fibers so that their spectra become identically zero, not NaN — this is intentional to prevent sky contamination.)
Write the throughput vector to a
THPUTextension in the RED file (1-D BinTable or ImageHDU of length NFIB). Replace any remaining NaN values with 0.0 before writing (per 2dfdr convention).Write FITS history noting the method used.
Note:
THPUTis written as a file extension, not as a column in theFIBREStable. TheFIBREStableTHPUTcolumn is a separate (optional) annotation.
P1-3. skysub — Sky subtraction#
Effort: large (~100 lines)
Called at: after throughput correction, before telluric; skipped for Nod & Shuffle data
Action:
Check
args.get('SKYSUB', True). IfFalse, write history'No sky subtraction performed'and return.Identify sky fibers via
getskyfibres():Read
FIBREStableTYPEcolumn; collect indices whereTYPE == 'S'.Fallback if no FIBRES table: read from a
skyfibres.datASCII file (one fiber index per line).If no sky fibers are identified at all, log a warning
'No sky fibers found'and skip sky subtraction (do not crash).(
AUTO_SKYFIBRE_DECLARATIONin 2dfdr handles instrument-specific auto-assignment of sky fibers when the table has none; for KSPEC this path should not be needed if the assign file correctly populates the FIBRES table.)
Reject bad sky fibers: a sky fiber is bad if more than 1/8 of its pixels are
NaN/bad (theFCHECKcriterion from 2dfdr). Keep a list of good sky fibers.Combine sky fibers into a single sky spectrum and sky variance:
Method selected by
args.get('SKYCOMBINE', 'MEAN'); supported values:'MEAN'or'MEDIAN'.For MEAN:
sky = np.nanmean(spectra[:, good_sky_fibs], axis=1). Variance:sky_var = np.nansum(var[:, good_sky_fibs], axis=1) / N_good^2(error propagation for mean of N independent spectra).For MEDIAN: use
np.nanmedian; sky variance estimate should use theπ/2 · MEAN_VAR / Nscaling factor or fall back to the mean variance.
Normal sky subtraction (default,
ITERSKY = False):for fib in range(NFIB): good = ~(np.isnan(spec[:,fib]) | np.isnan(sky)) spec[good, fib] -= sky[good] var[good, fib] += sky_var[good] spec[~good, fib] = np.nan var[~good, fib] = np.nan
The variance addition
Var_fib += Var_skyis the correct propagation (notVar_sky / N_sky— the division by N_sky is already baked into the sky variance from step 4).Iterative sky subtraction (optional,
ITERSKY = True): not required for P1; add aNotImplementedError-as-warning stub.Write sky-subtracted spectra and updated variances back to the RED file’s PRIMARY and
VARIANCEextensions.Write the combined sky spectrum to a
SKYextension (1-D ImageHDU, NPIX elements). Replace bad pixels with 0.0 before writing (2dfdr usesCMFSPEC_COPYfor this).Write FITS history:
f'Sky subtracted using {N_good} sky fibers'.
Design notes for ISOPLANE (~2 sky fibers):
With only 2 sky fibers, MEAN and MEDIAN produce the same result; use MEAN as the default.
Sky subtraction quality will be limited by small-number statistics and spatial sky gradients across the field; document this.
Consider exposing
SKYCOMBINEin the commissioning notebook args so it can be toggled easily.
P1-4. make_rwss — Pre-sky-subtraction snapshot (optional)#
Effort: small (~15 lines)
Called at: after
cmfspec_ftpcal, immediately beforeskysubAction: if
args.get('INC_RWSS', False), copy the current PRIMARY image array to a newRWSSImageHDU in the RED file. No header modification needed beyond the extension name.Why P1: the RWSS (“Reduced Without Sky Subtraction”) HDU lets the commissioning analyst compare pre/post sky-subtraction spectra in the same file. Also required by the planned
MEASURE_SKY_RESIDUALSdiagnostic (P3).Note:
INC_RWSSdefaults toFalsein 2dfdr (reduce_object.F95line 211); we should follow this default.
P1 deliverable: reduce_object produces flat-fielded,
sky-subtracted, wavelength-calibrated spectra. Combined with the
already-implemented flux calibration, this is a complete basic science
reduction.
Phase 2 — Advanced Corrections#
Goal: publication-quality spectra with atmospheric, velocity, and advanced sky corrections.
P2-1. telcor — Telluric absorption correction#
Effort: medium (~80 lines)
Design options (decide before implementing):
Option A: Empirical — use a hot star (TYPE=’C’ or dedicated telluric standard) observed at similar airmass. Divide science by the (continuum-normalized) telluric star spectrum. Simplest; requires a suitable star on the plate.
Option B: Model-based — use a pre-computed atmospheric transmission model (e.g., Molecfit output or a lookup table by airmass + PWV). More general but requires external data.
Option C: Combined — use the telluric mask regions from
data/masks/telluric_default.datto flag (not correct) affected wavelengths. Quickest to implement as a first pass.
Recommendation: implement Option C first (flag-only), then Option A for correction.
Depends on: scrunched data on a common wavelength grid.
P2-2. velcor_update_fibre_table — Velocity corrections#
Effort: medium (~60 lines)
Action:
Compute heliocentric/barycentric velocity correction from the observation date, RA/Dec, and observatory coordinates using
astropy.coordinates.SkyCoord.radial_velocity_correction.Store
VHELIO(km/s) in theFIBREStable.Optionally store
VLSR(Local Standard of Rest).Do NOT apply the correction to the wavelength grid (let the user decide); only store the values.
Depends on:
astropy.coordinates, validRA,DEC,DATE-OBS,OBSERVAT(orLONG-OBS,LAT-OBS,ALT-OBS) header keywords.
P2-3. super_skysub — Super-sampled sky subtraction#
Effort: large (~150 lines)
Action: uses the original EX file (pixel-space) and the RED file (scrunched) to perform sky subtraction at higher spectral resolution than the output grid. Primarily relevant when the number of sky fibers is large enough to build a spatially-varying sky model. Low priority for ISOPLANE (14 fibers).
Note: can be deferred until full KSPEC is operational.
P2-4. skysubpca — PCA sky subtraction#
Effort: large (~150 lines)
Action: PCA decomposition of sky-fiber spectra to build an eigenspectrum basis, then project and subtract from all fibers. More robust for structured sky residuals (e.g., OH line variation across the field).
Note: most valuable for the full KSPEC instrument with many sky fibers. Defer for ISOPLANE commissioning.
P2-5. skylines_recalibration — Wavelength fine-tuning from sky lines#
Effort: medium (~80 lines)
Action:
After extraction (on the EX file), identify known sky emission lines (e.g., OI 5577, OI 6300, OH lines).
Measure centroids in each fiber.
Compute per-fiber wavelength offsets/shifts.
Apply as corrections to the
WAVELAextension before scrunching.
Why P2: the arc calibration is usually sufficient for commissioning, but sky-line recalibration corrects for flexure between arc and science exposures.
P2 deliverable: telluric-corrected, velocity-annotated spectra with optional advanced sky subtraction.
Phase 3 — Polish and Completeness#
Goal: complete feature parity with the 2dfdr REDUCE_OBJECT flow and
production-ready diagnostics.
P3-1. skycalib_test#
Test function that verifies the skyline recalibration worked correctly. Log statistics (mean offset, scatter) and optionally raise a warning if residuals exceed a threshold.
P3-2. correct_frame_by_assoc_transfer_function#
Apply a transfer function from an associated observation (e.g., a spectrophotometric standard at different airmass). Primarily relevant for multi-visit survey operations.
P3-3. propagate_badthput#
If a fiber’s throughput was flagged as bad during
cmfspec_ftpcal, propagate NaN to all wavelength pixels for that fiber so downstream analysis doesn’t use unreliable data.
P3-4. de_wiggle#
Remove sinusoidal fringing artifacts. Implementation depends on characterizing the KSPEC detector’s fringe pattern. Requires commissioning data showing the artifact.
P3-5. clean_im — Double-pass cosmic ray rejection#
Use the residual map from optimal extraction to identify cosmic rays in the IM frame, clean them, then re-extract. Only meaningful once optimal extraction is implemented.
4. Extraction Improvements (Parallel Track)#
These are independent of reduce_object but improve the EX files it
consumes.
Item |
Effort |
Priority |
Notes |
|---|---|---|---|
GAUSS extraction |
Large |
P2 |
Gaussian profile fit per fiber per column |
Optimal extraction (OPTEX) |
Large |
P2 |
Horne (1986) variance-weighted extraction; maximizes S/N |
Scattered light subtraction |
Medium |
P2 |
Fit and subtract inter-fiber background before extraction |
5. Fiber Flat Completion (Dependency)#
reduce_fflat.py is at ~50% completion. For cmfspec_flatfield (P1-1)
to work, the following must be verified:
reduce_fflatproduces a valid master flat RED file with correct array dimensions matching science EX files (NPIX × NFIB).The flat is in pixel space (not scrunched):
reduce_fflatscrunch→averages→unscrunch→extrapolate→normalize, so the output RED flat is always in pixel space with values ≈ 1.0. This is confirmed bySCRUNCH_FLAT_FRAMEinreduce_fflat.F95.Fiber types (
P,S) in the flat FIBRES table must be populated to correctly exclude non-illuminated fibers (U,N,G, etc.) from the averaging step.CMFFF_EXTRAPperforms a linear least-squares extrapolation into the first/last 5 pixels of each fiber spectrum to fill edge bad pixels created by scrunching; verify that the Python equivalent does the same (or replaces it with a constant edge-fill).Optional B-spline post-smoothing (
BSSMOOTHflag) is available in 2dfdr but not required for P1.
Action: test reduce_fflat on commissioning flat data, inspect
the output (values near 1.0, no NaN-dominated fibers), and confirm
shape matches science EX files before implementing cmfspec_flatfield.
6. Implementation Order Summary#
Phase 0 (MVP — pipeline runs without crashing)
├── P0-1 tdfio_nod_shuffle trivial
├── P0-2 scrunch_object_frame small (wire existing code)
├── P0-3 I/O utilities small (FITS header writes)
└── P0-4 Remaining stubs → no-ops trivial
Phase 1 (Science-quality core)
├── P1-1 cmfspec_flatfield medium (~70 lines; pixel-space division, full Var propagation)
├── P1-2 cmfspec_ftpcal medium (~90 lines; OFFSKY default, KGB optional)
├── P1-3 skysub large (~100 lines; MEAN/MEDIAN combine, bad-fib filter)
└── P1-4 make_rwss small (~15 lines; copy PRIMARY → RWSS HDU)
Phase 2 (Advanced corrections)
├── P2-1 telcor medium
├── P2-2 velcor_update_fibre_table medium
├── P2-3 super_skysub large (defer for ISOPLANE)
├── P2-4 skysubpca large (defer for ISOPLANE)
└── P2-5 skylines_recalibration medium
Phase 3 (Polish)
├── P3-1 skycalib_test small
├── P3-2 transfer function medium
├── P3-3 propagate_badthput small
├── P3-4 de_wiggle unknown
└── P3-5 clean_im medium (needs OPTEX first)
7. Testing Strategy#
Unit tests#
Each implemented function should have a corresponding test in
tests/test_reduce_object.py covering:
Normal operation with valid input.
Graceful handling of missing optional files (e.g., no flat → skip).
Edge cases: all-NaN spectra, single-fiber data, zero sky fibers.
Integration test#
A notebook-based end-to-end test using commissioning data
(20260129 dataset):
Convert raw files (bias, flat, arc, science).
Build master bias.
Preprocess flat → TLM → extract flat →
reduce_fflat.Preprocess arc → extract →
reduce_arc.Preprocess science → extract →
reduce_object(full pipeline).Inspect output: plot wavelength-calibrated, sky-subtracted spectra.
Regression test#
Compare output RED files against a reference set (to be generated once Phase 1 is complete) to catch accidental changes.
8. Open Questions#
Flat-field order: confirmed — 2dfdr applies flat-fielding before scrunching (
reduce_object.F95lines 183→190). The FFLAT RED file is in pixel space by design. No change needed.Sky fibers in ISOPLANE: with only ~2 sky fibers out of 14, MEAN and MEDIAN sky combination are equivalent. Simple subtraction is the only practical option; iterative sky subtraction (
ITERSKY) requires more sky fibers and can be deferred. Document the limitation in the commissioning notebook.Throughput method for KSPEC:
'OFFSKY'requires a dedicated sky frame with a pre-computedTHPUTextension.'SKYLINE(KGB)'computes throughput from the science frame itself using sky fibers, making it the most self-contained option for commissioning. Decide which method to use based on whether an offset sky frame is available. Note thatSKYFLUX(*)methods requireskylines.dat.THPUTextension vs.FIBREStable column: 2dfdr writes throughputs as a standaloneTHPUTImageHDU (1-D, NFIB elements), not as a column inFIBRES. Our Python implementation should follow this. TheFIBRES.THPUTcolumn is a separate annotation written byvelcor_update_fibre_table.Bad sky fiber handling:
FCHECK(< 1/8 bad pixels) is defined inskysub.F95but is not called in theSKYSUBflow visible in the source — bad pixel masking is delegated toCOMBINE_STACK. In Python, explicitly filter sky fibers with a NaN-fraction check before combining.Telluric standard: is a dedicated telluric standard observed during commissioning, or should we rely on flux calibration stars (
TYPE='C')?Velocity correction source: do science targets have RA/Dec stored in the
FIBREStable, or only in the assign file? Need to decide wherevelcor_update_fibre_tablereads coordinates from.TDFIO_WAVE_DELETE: 2dfdr deletes theWAVELAextension from the RED file after scrunching (line 201 ofreduce_object.F95). Verify whetherkspecdrneeds to do the same, or whether keepingWAVELAfor diagnostics is preferable.
9. Dependencies and Blockers#
Blocker |
Affects |
Resolution |
|---|---|---|
|
P1-1 |
Run |
Assign file → FIBRES table integration |
P1-3 |
Verify |
Observatory coordinates in headers |
P2-2 |
Check if LONG-OBS/LAT-OBS/ALT-OBS are set during conversion |
Telluric standard identification |
P2-1 |
Determine if TYPE=’C’ stars can serve as telluric standards |