pypeit.spectrographs.ramp_spectrograph module
Mixin adding up-the-ramp fitting to a spectrograph.
Detectors read out non-destructively “up the ramp” record a series of reads of
the accumulating charge rather than a single integration. A spectrograph read
out this way mixes in RampSpectrograph alongside
Spectrograph:
class MyRampSpectrograph(RampSpectrograph, Spectrograph):
...
and implements the two instrument hooks RampSpectrograph._load_ramp() and
RampSpectrograph._count_reads(); the mixin then provides the generic
orchestration (noise calibration, count-rate fit, sidecar caching), delegating
the instrument-independent numerics to pypeit.core.ramp. MMT/MMIRS
(pypeit.spectrographs.mmt_mmirs) is the first such instrument.
The base Spectrograph carries
is_up_the_ramp = False and a preprocess_ramp_file() stub that raises;
mixing in this class flips is_up_the_ramp to True and supplies the working
implementation, so pypeit_fit_ramp and the reduction detect ramp support by
the is_up_the_ramp flag alone – there is no registry to keep in sync.
- class pypeit.spectrographs.ramp_spectrograph.RampSpectrograph[source]
Bases:
objectMixin providing up-the-ramp fitting to a
Spectrograph.Not a spectrograph itself (it is not a
Spectrographsubclass, so it is never discovered as one); it must be combined withSpectrographand relies on the host fornameandget_detector_par. Subclasses must implement_load_ramp()and_count_reads().- _count_reads(hdu)[source]
Count the non-destructive reads in a raw up-the-ramp cube.
Instrument-specific hook; subclasses must implement it.
- Parameters:
hdu (astropy.io.fits.HDUList) – Opened raw up-the-ramp cube.
- Returns:
Number of reads in the ramp.
- Return type:
- _load_ramp(hdu, detector_par)[source]
Load the non-destructive reads of a raw up-the-ramp cube.
Instrument-specific hook backing the ramp orchestration (
_ramp_fit_image(),_ramp_dark_sigmas()); subclasses must implement it. Implementations read the raw cube into the reads (in electrons, so any gain and reference-pixel correction is applied here), build the covariance from the read times, and return the header carrying the frame metadata (EXPTIME,RDNOISE, …).- Parameters:
hdu (astropy.io.fits.HDUList) – Opened raw up-the-ramp cube.
detector_par (
DetectorContainer) – Detector parameters (e.g. the gain applied to convert the reads to electrons).
- Returns:
The reads in electrons (numpy.ndarray, shape
(ngroups, ny, nx)), the matchingCovar, and the metadata astropy.io.fits.Header.- Return type:
- _ramp_dark_sigmas(exptime=None)[source]
Calibrate the single-read noise and its uncertainty from every recorded dark frame that matches the science ramp depth.
The darks are the
darkframes of the cached metadata table (viafind_frame_files()); each with at leastramp_min_cal_groupsreads is fit independently. Whenexptimeis provided, only darks whose ownEXPTIMEmatches it (withinrtol=1e-3) are used, because the calibrated noise is the effective per-read noise – instantaneous read noise plus accumulated dark-current/flux shot noise – which grows with ramp length, so it must be measured at the science exposure time. Darks that cannot be opened, or that yield a non-finite noise or a non-positive uncertainty, are skipped.
- _ramp_fit_image(hdu, detector_par)[source]
Perform up-the-ramp fitting of a multi-read frame.
Instrument-independent orchestration: the instrument hook
_load_ramp()provides the reads (in electrons), the covariance, and the metadata header; the count rate, single-read noise, and effective read noise are then computed withpypeit.core.ramp.- Parameters:
hdu (astropy.io.fits.HDUList) – Opened raw cube with at least
ramp_min_readsnon-destructive reads.detector_par (
DetectorContainer) – Detector parameters, passed through to_load_ramp().
- Returns:
The fitted count-rate image in e-/s (numpy.ndarray, shape of the trimmed data section), the single-read noise in electrons (
float), and the effective read noise in electrons (float).- Return type:
- _ramp_fitstbl = None
- _ramp_output_dir = None
- _ramp_sigma = None
- _ramp_sigma_cache = None
- _rampfit_dir = 'RampFit'
Name of the subdirectory (relative to the reduction directory) where preprocessed up-the-ramp count-rate images are written and reused. The default is overridden from the
[rdx] rampfit_dirparameter incache_metadata().- Type:
- cache_metadata(fitstbl)[source]
Record the reduction directory and dark frames for later ramp fitting.
Overrides the base
cache_metadata()no-op. The reduction directory determines where preprocessed ramp images are written (its[rdx] rampfit_dirsubdirectory). The metadata table is kept so the dark frames used to calibrate the single-read noise can be looked up lazily by_ramp_dark_sigmas()(viafind_frame_files()) once frame types are assigned – they are not yet set when this hook runs duringPypeItMetaDataconstruction. Cheap and idempotent, as required of the hook.- Parameters:
fitstbl (
PypeItMetaData) – The class holding the metadata for all the frames.
- get_ramp_sigma(diffs, covar, exptime=None, ron_floor=None)[source]
Determine the single-read noise for up-the-ramp fitting.
Preferentially calibrates the noise from the dark frames recorded by
cache_metadata()that match the science ramp depth: every dark with the sameEXPTIMEas the science frame (seeexptime) and at leastramp_min_cal_groupsreads is calibrated independently and the results are combined as an inverse-variance weighted mean, weighting each dark by the (bootstrap) uncertainty on its own calibrated noise (the result is cached for the rest of the run). Matching the exposure time matters because the calibrated value is the effective per-read noise, which includes accumulated dark-current/flux shot noise and so grows with ramp length. If no matching dark is available and the frame has at leastramp_min_cal_groupsreads, self-calibrates from the provided ramp differences (not cached); with fewer reads the fit is too poorly constrained, so the published guess (ramp_sig_guess) is used.A calibrated result is clamped to
ramp_sig_range, with the lower bound raised toron_floor(the headerRDNOISE, the instantaneous read noise) when provided: a derived noise below the instantaneous read noise is unphysical, so such values are floored.- Parameters:
diffs (numpy.ndarray) – Scaled resultant differences of the frame being processed, shape
(ndiffs, ny, nx), in electrons.covar (
Covar) – Covariance object matchingdiffs.exptime (
float, optional) – Science-frame exposure time in seconds, used to select darks of the same ramp depth. IfNone, darks are not filtered by exposure time.ron_floor (
float, optional) – Instantaneous read noise in electrons (headerRDNOISE) used as the physical lower bound on the derived noise. IfNone, the lower bound oframp_sig_rangeis used.
- Returns:
Single-read noise in electrons.
- Return type:
- is_up_the_ramp = True
Flags a spectrograph read out up-the-ramp; see
is_up_the_ramp().
- preprocess_ramp_file(raw_file, redux_path, rampfit_dir='RampFit', force=False)[source]
Fit one raw up-the-ramp cube and cache its 2D count-rate image.
Overrides the base
preprocess_ramp_file()stub. Backs thepypeit_fit_rampscript and mirrors the fit thatget_rawimageperforms during a reduction, writing the preprocessed image where the reduction will find and reuse it. Frames that are already up to date, already preprocessed, or too short to fit are skipped. The orchestration is instrument-independent; the raw cube is read through the_load_ramp()/_count_reads()hooks.- Parameters:
raw_file (
str, Path) – Path to the raw up-the-ramp cube to fit.redux_path (
str, Path) – The reduction directory holding the ramp-fit subdirectory.rampfit_dir (
str, optional) – Name of the ramp-fit subdirectory, relative toredux_path(the[rdx] rampfit_dirparameter).force (
bool, optional) – Re-fit and overwrite an existing, up-to-date preprocessed image instead of skipping it.
- Returns:
The path to the preprocessed image, or None if the frame was skipped (already up to date, already preprocessed, or too few reads).
- Return type:
- ramp_fit_chunk_rows = 16
Number of detector rows fit per
fit_ramps()call. Small chunks keep each thread’s working set cache-resident; 16 was the empirical sweet spot.
- ramp_fit_workers = None
Number of worker threads for up-the-ramp fitting.
Noneselectsmin(6, os.cpu_count()). This is set from the general[rdx] ncpuparameter incache_metadata()(ncpu <= 1keeps this parallel default;ncpu > 1is used as given). The per-pixel fit is memory-bandwidth bound, so throughput plateaus at roughly 6 threads (measured ~3x over the serial fit on a 10-core machine).
- ramp_min_cal_groups = 10
Minimum number of reads for a frame (dark or science) to calibrate the single-read noise. A dark with fewer reads is not used; a science frame with fewer reads falls back to the published guess (
ramp_sig_guess) instead of self-calibrating.
- ramp_min_reads = 5
Minimum number of reads for up-the-ramp fitting. Frames with fewer reads do not sample the ramp well enough to fit reliably and fall back to correlated double sampling.
- ramp_sig_guess = 9.0
Initial guess for the effective single-read noise in electrons (the instantaneous read noise plus accumulated dark-current/flux shot noise), used to seed the chi-square rescaling and as the fallback when a frame has too few reads to calibrate. Refined from darks or self-calibrated per frame; the header
RDNOISEis used as a physical floor (seeget_ramp_sigma()).
- ramp_sig_range = (3.0, 50.0)
Absolute sanity range for the calibrated single-read noise (electrons). The lower bound is raised to the header
RDNOISEwhen available, since a derived noise below the instantaneous read noise is unphysical.
- rampfit_path(raw_file)[source]
Path to the cached ramp-fit image for a raw cube during a reduction.
Resolves the
[rdx] rampfit_dirsubdirectory of the reduction directory recorded bycache_metadata(). When that hook never fired (e.g. direct API use ofget_rawimage()outside a reduction), the current working directory is used instead. This is the reduction-time counterpart ofpreprocess_ramp_file(), which takes the reduction directory explicitly from thepypeit_fit_rampscript.