detect_order_edges¶
The detect_order_edges utility uses a fully-illuminated slit flat-lamp frame to detect and fit the edges of each echelle order across the detector plane.
Fig. 65 This algorithm detects and fits the edges of the echelle orders across the detector plane.¶
The utility takes as input a fully illuminated slit image (flat-field frame). The second input is the order table generated by the soxs_order_centres recipe, which provides a trace of the centre of each order along the dispersion axis.
An array of central pixel positions is generated using the order table for each order. At each pixel position in these arrays, an N-pixel long (slice-length-for-edge-detection), M-pixel wide (slice-width-for-edge-detection) image slice in the cross-dispersion direction is cut from the flat-frame. Each 2D slice is collapsed to a 1D array by taking the median value across its width (ignoring masked pixels).
The minimum and maximum fluxes are calculated from the central 1D slice in each order to give a flux range. The absolute minimum and maximum flux thresholds are determined from the percentage thresholds given as recipe parameters (min-percentage-threshold-for-edge-detection and max-percentage-threshold-for-edge-detection). If the minimum threshold were set at 25%, then the absolute flux would be:
If the minimum flux is not recorded at any point along the order edge, the threshold slowly increments to the maximum flux until the threshold is registered. Slices where both edges are undetected before the maximum flux threshold is reached are rejected.
For each slice along each order, we measure the flux at the centre of the order and record a minimum and maximum percentage of this central flux (minimum and maximum percentages are set in the settings file). Then, we smooth the flux with a rolling-median filter for each cross-dispersion slice. Finally, we start at the minimum flux threshold to try and find both order edges simultaneously. If an edge can’t be found at this threshold, we incrementally increase the threshold until we find the edges or reach the maximum threshold. If found, the pixel-locations xmin (lower edge) and xmax (upper edge) where the flux reaches this minimum flux threshold are recorded (see red circles in Fig. 66). If, however, the maximum threshold is reached, then the slice will be discarded.
Fig. 66 A single slice cut across the cross-dispersion axis of an echelle order. The grey dots represent the median flux from the width-collapsed 1D slice. The red dots show where a pre-determined flux threshold is reached, and the pixel positions at these locations are registered as the lower and upper edges of the order as measured in this slice.¶
For each order, a median order height (\(xmax-xmin\)) is determined, and \(xmin\) and \(xmax\) are adjusted for each slice, so each order now has the same pixel height across the order. This helps fit the order edges at the extremes of the detector plane where flux from the flat lamp can be reduced.
Finally, for each order, the arrays of \(xmin\) and \(xmax\) pixel-positions are iteratively fitted with low order polynomials:
where \(X\) and \(Y\) are the pixel positions and \(n\) is the echelle order number. \(i\) and \(j\) are the polynomial degree orders for the echelle order (order-deg) and \(Y\) pixel position (disp-axis-deg) respectively. \(c_{ij}\) are the polynomial coefficients to be fitted. The polynomial is iteratively fitted while sigma-clipping pixel-positions with outlying residuals (see Fig. 67). The new order location table is written to file and now includes the upper and lower-edge locations alongside the central location for each order.
Fig. 67 The top panel shows the upper and lower-order edge detections registered in the individual cross-dispersion slices in an Xshooter VIS flat frame. The bottom panel shows the global polynomial fits to the upper and lower-order edges, with the area between the fits filled with different colours to reveal the unique echelle orders across the detector plane.¶
Utility API¶
- class detect_order_edges(log, flatFrame, orderCentreTable, settings=False, recipeSettings=False, recipeName='soxs-mflat', verbose=False, qcTable=False, productsTable=False, tag='', sofName=False, binx=1, biny=1, extendToEdges=True, lampTag=False, startNightDate='', debug=False)[source]¶
Bases:
soxspipe.commonutils._base_detectusing a fully-illuminated slit flat frame detect and record the order-edges
Key Arguments:
log– loggersettings– the settings dictionaryrecipeSettings– the recipe specific settingsflatFrame– the flat frame to detect the order edges onorderCentreTable– the order centre tablerecipeName– name of the recipe as it appears in the settings dictionaryverbose– verbose. True or False. Default FalseqcTable– the data frame to collect measured QC metricsproductsTable– the data frame to collect output productstag– e.g. ‘_DLAMP’ to differentiate between UV-VIS lampssofName– name of the originating SOF filebinx– binning in x-axisbiny– binning in y-axisextendToEdges– if true, extend the order edge tracing to the edges of the frame (Default True)lampTag– add this tag to the end of the product filename (Default False)startNightDate– YYYY-MM-DD date of the observation night. Default “”
Usage:
from soxspipe.commonutils import detect_order_edges edges = detect_order_edges( log=log, flatFrame=flatFrame, orderCentreTable=orderCentreTable, settings=settings, recipeSettings=recipeSettings, recipeName="soxs-mflat", verbose=False, qcTable=False, productsTable=False, extendToEdges=True, lampTag=False ) productsTable, qcTable, orderDetectionCounts = edges.get()
Initialization
- calculate_residuals(orderPixelTable, coeff, axisACol, axisBCol, orderCol=False, writeQCs=False)[source]¶
- determine_lower_upper_edge_pixel_positions(orderData)[source]¶
from a pixel postion somewhere on the trace of the order centre, return the lower and upper edges of the order
Key Arguments:
orderData– one row in the orderTable
Return:
orderData– orderData with upper and lower edge xcoord arrays added
- determine_order_flux_threshold(orderData, orderPixelTable)[source]¶
determine the flux threshold at the central column of each order
Key Arguments:
orderData– one row in the orderTableorderPixelTablethe order table containing pixel arrays
Return:
orderData– orderData with min and max flux thresholds added
- fit_global_polynomial(pixelList, axisACol='cont_x', axisBCol='cont_y', orderCol='order', exponentsIncluded=False, writeQCs=False)[source]¶
- fit_order_polynomial(pixelList, order, axisBDeg, axisACol, axisBCol, exponentsIncluded=False)[source]¶
- get()[source]¶
get the detect_order_edges object
Return:
orderTablePath– path to the new order table
- plot_results(orderPixelTableUpper, orderPixelTableLower, orderPolyTable, orderMetaTable, clippedDataUpper, clippedDataLower)[source]¶
generate a plot of the polynomial fits and residuals
Key Arguments:
orderPixelTableUpper– the pixel table with residuals of fits for the upper edgesorderPixelTableLower– the pixel table with residuals of fits for the lower edgesorderPolyTable– data-frame of order-location polynomial coefforderMetaTable– data-frame containing the limits of the fitclippedDataUpper– the sigma-clipped data from upper edgeclippedDataLower– the sigma-clipped data from lower edge
Return:
filePath– path to the plot pdf