Wavelength Calibration Algorithm

class modules.wavelength_cal.src.alg.WaveCalibration(cal_type, clip_peaks_toggle, quicklook, min_order, max_order, save_diagnostics=None, config=None, logger=None)[source]

This module defines ‘WaveCalibration’ and methods to perform the wavelength calibration.

Wavelength calibration computation. Algorithm is called under _perform() in wavelength_cal.py. Algorithm itself iterates over orders.

calculate_gaussian(x, y, height, center, width)[source]

Fits a continous Gaussian in wavelength space for

Parameters:
  • x (np.array) – wavelength segment to fit

  • y (np.array) – Flux data to be fit

Returns:

Height of Gaussian Center of Gaussian Width of Gaussian

calculate_rv_precision(fitted_peak_pixels, wls, leg_out, rough_wls, our_wavelength_solution_for_order, rough_wls_order, print_update=True, plot_path=None)[source]

Calculates 1) RV precision from the difference between the known (from physics) wavelengths of pixels containing peak flux values and the fitted wavelengths of the same pixels, generated using a polynomial wavelength solution (“absolute RV precision”) and 2) RV precision from the difference between the “master” wavelength solution and our fitted wavelength solution (“relative RV precision”) :param fitted_peak_pixels: array of true detected peak locations as

determined by Gaussian fitting (already clipped)

Parameters:
  • wls (np.array of float) – precise wavelengths of fitted_peak_pixels, from fundamental physics or another wavelength solution.

  • leg_out (func) – a Python function that, given an array of pixel locations, returns the Legendre polynomial wavelength solutions

  • rough_wls (np.array of float) – rough wavelength values for each pixel in the order [Angstroms]

  • print_update (bool) – If true, prints standard error per order.

  • plot_path (str) – if defined, the path to the output directory for diagnostic plots. If None, plots are not made.

Returns:

float: absolute RV precision in cm/s float: relative RV precision in cm/s

Return type:

tuple of

clip_peaks(order_flux, fitted_peak_pixels, detected_peak_pixels, gauss_coeffs, detected_peak_heights, clip_below_median=True, print_update=True, plot_path=None)[source]

Clips peaks that have detected and Gaussian-fitted central pixels values more than 1 pixel apart. Also clip peaks that are immediately next to a flux value of 0 (this prevents peak detection near masked areas). There is also an option to clip detected peaks that are less than the median of the overall chip flux. :param order_flux: array of order_flux data :type order_flux: np.array :param fitted_peak_pixels: array of true peak locations as

determined by Gaussian fitting

Parameters:
  • detected_peak_pixels (np.array of float) – array of detected peak locations (pre-Gaussian fitting)

  • gauss_coeffs (np.array) – array of size (4, n_peaks) containing best-fit Gaussian parameters [a, mu, sigma**2, const] for each detected peak

  • detected_peak_heights (np.array) – array of detected peak heights (pre-Gaussian fitting)

  • clip_below_median (bool) – if True, clip all peaks below the overall chip median.

  • print_update (bool) – if True, print how many peaks were clipped

  • plot_path (str) – if defined, the path to the output directory for diagnostic plots. If None, plots are not made.

Returns:

indices of surviving peaks

Return type:

np.array

comb_gen(f0, f_rep)[source]

Computes wavelengths of LFC modes using the comb equation :param f0: initial comb frequency [Hz] :type f0: float :param f_rep: comb repitition frequency [Hz] :type f_rep: float

Returns:

array of comb lines [Angstroms]

Return type:

np.array

find_etalon_peaks(flux, wave, etalon_mask)[source]

Fit peaks of etalon calibration with a gaussian function :param Wavelengths of one order: :param Flux of one order: :param Full etalon mask from master file.:

Returns

Original an new etalon peak positions for one order

find_peaks(order_flux, peak_height_threshold=1.5)[source]
Finds all order_flux peaks in an array. This runs scipy.signal.find_peaks

twice: once to find the average distance between peaks, and once for real, disregarding close peaks.

Parameters:
  • order_flux (np.array) – flux values. Their indices correspond to their pixel numbers. Generally a subset of the full order.

  • peak_height_threshold (float) – only detect peaks above this num * sigma above the chip median.

Returns:

np.array: array of true peak locations as determined by Gaussian fitting np.array: array of detected peak locations (pre-Gaussian fitting) np.array: array of detected peak heights (pre-Gaussian fitting) np.array: array of size (4, n_peaks) containing best-fit Gaussian

parameters [a, mu, sigma**2, const] for each detected peak

Return type:

tuple of

find_peaks_in_order(order_flux, plot_path=None)[source]

Runs find_peaks on successive subsections of the order_flux lines and concatenates the output. The difference between adjacent peaks changes as a function of position on the detector, so this results in more accurate peak-finding. Based on pyreduce. :param order_flux: flux values. Their indices correspond to

their pixel numbers. Generally the entire order.

Parameters:

plot_path (str) – Path for diagnostic plots. If None, plots are not made.

Returns:

np.array: array of true peak locations as determined by Gaussian fitting np.array: array of detected peak locations (pre-Gaussian fitting) np.array: array of detected peak heights (pre-Gaussian fitting) np.array: array of size (4, n_peaks)

containing best-fit Gaussian parameters [a, mu, sigma**2, const] for each detected peak

dict: dictionary of information about each line in the order

Return type:

tuple of

fit_gaussian(x, y)[source]

Fits a continous Gaussian in wavelength space for an input flux

Parameters:
  • x (np.array) – wavelength segment to fit

  • y (np.array) – Flux data to be fit

Returns:

Height of Gaussian Center of Gaussian Width of Gaussian

fit_gaussian_integral(x, y)[source]

Fits a continuous Gaussian to a discrete set of x and y datapoints using scipy.curve_fit

Parameters:
  • x (np.array) – x data to be fit

  • y (np.array) – y data to be fit

Returns a tuple of:

list: best-fit parameters [a, mu, sigma**2, const] line_dict: dictionary of best-fit parameters, wav, flux, model, etc.

fit_many_orders(cal_flux, order_list, rough_wls=None, comb_lines_angstrom=None, expected_peak_locs=None, peak_wavelengths_ang=None, our_wavelength_solution_for_order=None, plt_path=None, print_update=False)[source]

Iteratively performs wavelength calibration for all orders. :param cal_flux: (n_orders x n_pixels) array of calibrator fluxes

for which to derive a wavelength solution

Parameters:
  • order_list (list of int) – list order to compute wls for

  • rough_wls (np.array) – (N_orders x N_pixels) array of wavelength values describing a “rough” wavelength solution. Always None for lamps. For LFC, this is generally a lamp-derived solution. For Etalon, this is generally an LFC-derived solution. Default None.

  • comb_lines_angstrom (np.array) – array of all allowed wavelengths for the LFC, computed using the order_flux equation. Should be None unless we are calibrating an LFC frame. Default None.

  • expected_peak_locs (dict) – dictionary of order number-dict pairs. See description in run_wavelength_cal().

  • plt_path (str) – if set, all diagnostic plots will be saved in this directory. If None, no plots will be made.

  • print_update (bool) – whether subfunctions should print updates.

Returns:

np.array of float: (N_orders x N_pixels) derived wavelength

solution for each pixel

dict: the peaks and wavelengths used for wavelength cal. Keys
are ints representing order numbers, values are 2-tuples of:
  • lists of wavelengths corresponding to peaks

  • the corresponding (fractional) pixels on which the peaks fall

dict: the orderlet dictionary, that is folded into wls_dict at a higher level

Return type:

tuple of

fit_polynomial(wls, rough_wls_order, peak_wavelengths_ang, order_list, n_pixels, fitted_peak_pixels, fit_iterations=5, sigma_clip=2.1, peak_heights=None, plot_path=None)[source]

Given precise wavelengths of detected LFC order_flux lines, fits a polynomial wavelength solution. :param wls: the known, precise wavelengths of the detected peaks,

either from fundamental physics or a previous wavelength solution.

Parameters:
  • n_pixels (int) – number of pixels in the order

  • fitted_peak_pixels (np.array) – array of true detected peak locations as determined by Gaussian fitting.

  • fit_iterations (int) – number of sigma-clipping iterations in the polynomial fit

  • sigma_clip (float) – clip outliers in fit with residuals greater than sigma_clip away from fit

  • peak_heights (np.array) – heights of peaks (either detected heights or fitted heights). We use this to weight the peaks in the polynomial fit, assuming Poisson errors.

  • plot_path (str) – if defined, the path to the output directory for diagnostic plots. If None, plots are not made.

Returns:

np.array: calculated wavelength solution for the order (i.e.

wavelength value for each pixel in the order)

func: a Python function that, given an array of pixel locations,

returns the Legendre polynomial wavelength solutions

Return type:

tuple of

integrate_gaussian(x, a, mu, sig, const, int_width=0.5)[source]

Returns the integral of a Gaussian over a specified symmetric range. Gaussian given by: g(x) = a * exp(-(x - mu)**2 / (2 * sig**2)) + const :param x: the central value over which the integral will be calculated :type x: float :param a: the amplitude of the Gaussian :type a: float :param mu: the mean of the Gaussian :type mu: float :param sig: the standard deviation of the Gaussian :type sig: float :param const: the Gaussian’s offset from zero (i.e. the value of

the Gaussian at infinity).

Parameters:

int_width (float) – the width of the range over which the integral will be calculated (i.e. if I want to calculate from 0.5 to 1, I’d set x = 0.75 and int_width = 0.25).

Returns:

the integrated value

Return type:

float

line_match(flux, linelist, line_pixels_expected, plot_toggle, savefig, gaussian_fit_width=10)[source]

Given a linelist of known wavelengths of peaks and expected pixel locations (from a previous wavelength solution), returns precise, updated pixel locations for each known peak wavelength. :param flux: flux of order :type flux: np.array :param linelist: wavelengths of lines to be fit (Angstroms) :type linelist: np.array of float :param line_pixels_expected: expected pixels for each wavelength

(Angstroms); must be same length as linelist

Parameters:
  • plot_toggle (bool) – if True, make and save plots.

  • savefig (str) – path to directory where plots will be saved

  • gaussian_fit_width (int) – pixel +/- range to use for Gaussian fitting

Retuns:
tuple of:

np.array: same input linelist, with unfit lines removed np.array: array of size (4, n_peaks) containing best-fit

Gaussian parameters [a, mu, sigma**2, const] for each detected peak

dictionary: a dictionary of information about the lines fit within this order

mask_array_neid(calflux, n_orders)[source]

Creates ad-hoc mask to remove bad pixel regions specific to order. For NEID testing. :param calflux: (N_orders x N_pixels) flux array to be masked :type calflux: np.array :param n_orders: number of orders to be masked :type n_orders: np.array

Returns:

masked flux array

Return type:

np.array

mode_match(order_flux, fitted_peak_pixels, good_peak_idx, rough_wls_order, comb_lines_angstrom, print_update=False, plot_path=None, start_check=True)[source]

Matches detected order_flux peaks to the theoretical locations of LFC wavelengths and returns the derived wavelength solution. Given detected peak locations in data, a preexisting coarse wavelength solution (e.g. from ThAr), and theoretical line wavelengths from physics, returns precise wavelengths for peaks. :param order_flux: flux values for an order. Their indices

correspond to their pixel numbers.

Parameters:
  • fitted_peak_pixels (np.array) – array of true peak locations as determined by Gaussian fitting.

  • good_peak_idx (np.array) – indices (of new_peaks) of detected and unclipped peaks

  • rough_wls_order (np.array) – a rough (generally ThAr-based) wavelength solution. Each entry in the array is the wavelength (in Angstroms) corresponding to a pixel (indicated by its index)

  • comb_lines_angstrom (np.array) – theoretical LFC wavelengths as computed by fundamental physics (in Angstroms)

  • print_update (bool) – if True, print total number of LFC modes in the order that were not detected (n_clipped + n_never_detected)

  • plot_path (str) – if defined, the path to the output directory for diagnostic plots. If None, plots are not made.

Returns:

np.array: the precise wavelengths of detected order_flux peaks. Each

entry in the array is the wavelength (in Angstroms) corresponding to a pixel (indicated by its index)

np.array: the mode numbers of the LFC modes to be used for

wavelength calibration

Return type:

tuple of

remove_orders(step=1)[source]

Removes bad orders from order list if between min and max orders to test. :param step: Interval at which to test orders. Used to skip orders

for QLP. Defaults to 1, which means every order will be tested on and none will be removed.

Returns:

List of orders to run wavelength calibration on.

Return type:

list

run_wavelength_cal(calflux, rough_wls=None, our_wavelength_solution_for_order=None, peak_wavelengths_ang=None, lfc_allowed_wls=None, input_filename=None)[source]

Runs all wavelength calibration algorithm steps in order. :param calflux: (N_orders x N_pixels) array of L1 flux data of a

calibration source

Parameters:
  • rough_wls (np.array) – (N_orders x N_pixels) array of wavelength values describing a “rough” wavelength solution. Always None for lamps. For LFC, this is generally a lamp-derived solution. For Etalon, this is generally an LFC-derived solution. Default None.

  • peak_wavelengths_ang (dict of dicts) –

    dictionary of order number-dict pairs. Each order number corresponds to a dict containing an array of expected line positions (pixel values) under the key “line_positions” and an array of corresponding wavelengths in Angstroms under the key “known_wavelengths_vac”. This value must be set for lamps. Can be set or not set for LFC and Etalon. If set to None, then peak finding is not run. Defaults to None. Ex:

    {51: {

    “line_positions” : array([500.2, … 8000.3]), “known_wavelengths_vac” : array([3633.1, … 3570.1])

    }

    }

  • lfc_allowed_wls (np.array) – array of all allowed wavelengths for the LFC, computed using the order_flux equation. Should be None unless we are calibrating an LFC frame. Defaults to None.

Examples

1: Calibrating an LFC frame using a rough ThAr solution,
with no previous LFC frames to inform this one:

rough_wls -> ThAr-derived wavelength solution lfc_allowed_wls -> wavelengths computed from comb eq

2: Calibrating an LFC frame using a rough ThAr solution,
given information about expected mode position:

rough_wls -> ThAr-derived wavelength solution lfc_allowed_wls -> wavelengths computed from comb eq peak_wavelengths_ang -> LFC mode wavelengths and their

expected pixel locations

3: Calibrating a lamp frame:
peak_wavelengths_ang -> lamp line wavelengths in vacuum and their

expected rough pixel locations

4: Calibrating an Etalon frame using an LFC-derived solution, with
no previous Etalon frames to inform this one:

rough_wls -> LFC-derived wavelength solution

5: Calibrating an Etalon frame using an LFC-derived solution and
at least one other Etalon frame to inform this one:

rough_wls -> LFC-derived wavelength solution peak_wavelengths_ang -> Etalon peak wavelengths and their

expected pixel locations

Returns:

np.array: Calculated polynomial solution np.array: (N_orders x N_pixels) array of the computed wavelength

for each pixel.

dictionary: information about the fits for each line and order (orderlet_dict)

Return type:

tuple of

save_etalon_mask_update(file_name, wave_pxl_data)[source]

Saves nightly etalon mask

Parameters:
  • file_name (str) – Filename including date and time from original science file

  • new_mask (np.array) – Wavlengths of updated etalon mask function ‘run_wavelength_cal’.

Returns:

Updated mask in two column, csv file

Return type:

str

save_lfc_mask(file_name, comb_lines_ang)[source]

Save the LFC mask produced from f0 and frep.

Parameters:
  • file_name (str) – Where to write the mask.

  • comb_lines_ang ((N,) ndarray) – Wavelengths (Å) of all allowed comb modes.

save_wl_pixel_info(file_name, wave_pxl_data)[source]

Saves wavelength pixel reference file.

Parameters:
  • file_name (str) – Filename including date and time from original science file

  • wave_pxl_data (np.array) – Wavelength per pixel reference information output by function ‘run_wavelength_cal’.

Returns:

Full wavelength pixel reference filename

Return type:

str

class modules.wavelength_cal.src.alg.WaveInterpolation(l1_timestamp, wls_timestamps, wls1_arrays, wls2_arrays, config=None, logger=None)[source]

This module defines ‘WaveInterpolation’ and methods to perform interpolation between different wavelength solutions.

Wavelength interpolation computation. Algorithm is called under _perform() in wavelength_cal.py. Algorithm itself iterates over orders.

modules.wavelength_cal.src.alg.plot_drift(wlpixelfile1, wlpixelfile2, figsave_name)[source]

Overall RV of cal data vs time for array of input files. :param wlpixelfile1: Path to first wavelength solution file :type wlpixelfile1: str :param wlpixelfile2: Path to second wavelength solution file :type wlpixelfile2: str