Response

This section deals with the HDRL module estimating the spectroscopic response of the instrument (including telescope and detector) as a 1D function of wavelength. Wavelengths are in nm. Observations should be taken in photometric conditions and in the same optical setup as the science data. The observed and reference fluxes must be expressed in the same units.

In PyHDRL this is hdrl.func.Response. Input spectra are hdrl.core.Spectrum1D objects; constructors require strictly increasing wavelengths.

Algorithm

The algorithm is divided in two parts: telluric correction and response calculation. Telluric correction is optional and can be disabled.

Telluric correction tries to find the best telluric model among the ones provided and uses it to correct the observed spectrum. For each model the observed spectrum is cross-correlated with the telluric model (typically on a water-vapour feature) to measure the wavelength shift and the difference in resolution. The model is shifted, convolved with a Gaussian of the measured FWHM, resampled onto the observed wavelengths, and divided into the observation. A quality indicator \(q = |m_r - 1|\) is computed, where \(m_r\) is the mean of the continuum-normalised corrected spectrum. The model having the lowest \(q\) is used. If telluric correction is disabled, the unmodified observed spectrum is used.

A logarithmic wavelength scale should be used for the cross-correlation when \(\lambda\)/FWHM is constant; the sampling of that scale must be fine enough. If the reference spectrum already contains telluric lines, telluric correction of the observation should be skipped and the response interpolated across those regions.

Velocity compensation (optional) determines the radial velocity of the observed spectrum by fitting a Gaussian to a known stellar line and applies it to the stellar model as \(\lambda = \lambda_0 (1 + RV/c)\). This also covers a slit-positioning offset that shifts the observed wavelength scale.

The remaining steps calculate the raw response, take the median flux in a window of half-width wrange around each continuum wavelength in fit_points (avoiding high-absorption regions and stellar line cores), apply a median filter of radius radius to the raw response, and fit a spline through those median points.

The response is calculated according to

\[R(\lambda)= \frac{I_{std-ref}^{(r)}(\lambda) \cdot 10^{[ 0.4(A_p- A_m)E_x^{(r)}(\lambda)] } \cdot G \cdot T_{ex}}{I_{std}(\lambda)}\]

where:

  • \(I_{std}(\lambda)\) is the observed 1D spectrum [ADU]

  • \(I_{std-ref}^{(r)}(\lambda)\) is the resampled reference standard-star spectrum

  • \(E_x^{(r)}(\lambda)\) is the resampled atmospheric extinction [mag/airmass]

  • \(A_m\) is the airmass of the observed standard-star spectrum

  • \(A_p\) is the airmass at which the response is computed (0 for above the atmosphere, or typically the tabulated airmass of the reference spectrum)

  • \(G\) is the detector gain [ADU/e]

  • \(T_{ex}\) is the exposure time [s]

\(E_x(\lambda)\) and \(I_{std-ref}(\lambda)\) are resampled with Akima interpolation onto the observed wavelength grid. The response is defined only where those inputs overlap.

Compute

Parameter objects:

  • hdrl.func.Response.telluric_evaluation_parameter_create / hdrl.func.ResponseTelluricParameter

  • hdrl.func.Response.velocity_parameter_create / hdrl.func.ResponseVelocityParameter

  • hdrl.func.Response.calc_parameter_create / hdrl.func.ResponseCalcParameter

  • hdrl.func.Response.fit_parameter_create / hdrl.func.ResponseFitParameter

Pass a default-constructed ResponseTelluricParameter() or ResponseVelocityParameter() to skip telluric correction or velocity compensation.

These constructors follow the HDRL C checks:

  • Ap=0 is valid (response above the atmosphere).

  • high_abs_regions is a tuple of two arrays, or defaults to None (C NULL): no regions are skipped. An empty tuple is not a substitute for None.

  • fit_points is a NumPy array and may be empty. radius and wrange must still be greater than zero.

  • velocity_parameter_create stores the given wavelength ranges and fit_half_win without extra Python checks. fit_half_win is an integer (C size_t).

compute() takes three hdrl.core.Spectrum1D objects (observed spectrum, reference spectrum, atmospheric extinction) and the parameter objects. It returns a hdrl.func.ResponseResult. Accessors include get_final_response(), get_selected_response(), get_raw_response(), get_corrected_obs_spectrum(), get_best_telluric_model_idx(), get_avg_diff_from_1(), get_stddev(), get_telluric_shift() and get_doppler_shift(). The response accessors return hdrl.core.Spectrum1D. get_corrected_obs_spectrum() is undefined if telluric correction was skipped. The raw response is the reference standard-star spectrum divided by the observed spectrum, corrected for gain, exposure time and atmospheric extinction.

evaluate_telluric_models() evaluates all telluric models and picks the best model.

calc_par = hdrl.func.Response.calc_parameter_create(Ap=0.0, Am=0.5, G=0.1, Tex=5000.0)
vel_par = hdrl.func.Response.velocity_parameter_create(
    wguess=7.0, range_wmin=3.0, range_wmax=11.0,
    fit_wmin=6.0, fit_wmax=8.0, fit_half_win=1,
)
fit_par = hdrl.func.Response.fit_parameter_create(
    radius=11,
    fit_points=fit_points,
    wrange=1.0,
)
result = hdrl.func.Response.compute(
    obs_s, ref_s, E_x,
    hdrl.func.ResponseTelluricParameter(),
    vel_par, calc_par, fit_par,
)
final = result.get_final_response()