def find_edge_pair(data, y, roi_width, edgeThreshold=450): ''' find_edge_pair finds the edge of a slit pair in a flat data[2048x2048]: a well illuminated flat field [DN] y: guess of slit edge position [pix] Keywords: edgeThreshold: the pixel value below which we should ignore using to calculate edges. Moves along the edge of a slit image - At each location along the slit edge, determines the position of the demarcations between two slits Outputs: xposs []: Array of x positions along the slit edge [pix] yposs []: The fitted y positions of the "top" edge of the slit [pix] widths []: The fitted delta from the top edge of the bottom [pix] scatters []: The amount of light between slits The procedure is as follows 1: starting from a guess spatial position (parameter y), march along the spectral direction in some chunk of pixels 2: At each spectral location, construct a cross cut across the spatial direction; select_roi is used for this. 3: Fit a two-sided error function Fit.residual_disjoint_pair on the vertical cross cut derived in step 2. 4: If the fit fails, store it in the missing list - else if the top fit is good, store the top values in top vector - else if the bottom fit is good, store the bottom values in bottom vector. 5: In the vertical cross-cut, there is a minimum value. This minimum value is stored as a measure of scattered light. Another procedure is used to fit polynomials to these fitted values. ''' def select_roi(data, roi_width): v = data[y - roi_width:y + roi_width, xp - 2:xp + 2] v = np.median(v, axis=1) # Axis = 1 is spatial direction return v xposs_top = [] yposs_top = [] xposs_top_missing = [] xposs_bot = [] yposs_bot = [] xposs_bot_missing = [] yposs_bot_scatters = [] #1 rng = np.linspace(10, 2040, 50).astype(np.int) for i in rng: xp = i #2 v = select_roi(data, roi_width) xs = np.arange(len(v)) # Modified from 450 as the hard coded threshold to one that # can be controlled by a keyword if (np.median(v) < edgeThreshold): xposs_top_missing.append(xp) xposs_bot_missing.append(xp) continue #3 ff = Fit.do_fit(v, residual_fun=Fit.residual_disjoint_pair) fit_ok = 0 < ff[4] < 4 if fit_ok: (sigma, offset, mult1, mult2, add, width) = ff[0] xposs_top.append(xp) yposs_top.append(y - roi_width + offset + width) xposs_bot.append(xp) yposs_bot.append(y - roi_width + offset) between = offset + width / 2 if 0 < between < len(v) - 1: start = np.max([0, between - 2]) stop = np.min([len(v), between + 2]) yposs_bot_scatters.append(np.min(v[start:stop])) # 5 if False: pl.figure(2) pl.clf() tmppix = np.arange(y - roi_width, y + roi_width) tmpx = np.arange(len(v)) pl.axvline(y - roi_width + offset + width, color='red') pl.axvline(y - roi_width + offset, color='red') pl.scatter(tmppix, v) pl.plot(tmppix, Fit.fit_disjoint_pair(ff[0], tmpx)) pl.axhline(yposs_bot_scatters[-1]) pl.draw() else: yposs_bot_scatters.append(np.nan) else: xposs_bot_missing.append(xp) xposs_top_missing.append(xp) info("Skipping wavelength pixel): %i" % (xp)) return map(np.array, (xposs_bot, xposs_bot_missing, yposs_bot, xposs_top, xposs_top_missing, yposs_top, yposs_bot_scatters))
def find_edge_pair(data, y, roi_width, edgeThreshold=450): ''' find_edge_pair finds the edge of a slit pair in a flat data[2048x2048]: a well illuminated flat field [DN] y: guess of slit edge position [pix] Keywords: edgeThreshold: the pixel value below which we should ignore using to calculate edges. Moves along the edge of a slit image - At each location along the slit edge, determines the position of the demarcations between two slits Outputs: xposs []: Array of x positions along the slit edge [pix] yposs []: The fitted y positions of the "top" edge of the slit [pix] widths []: The fitted delta from the top edge of the bottom [pix] scatters []: The amount of light between slits The procedure is as follows 1: starting from a guess spatial position (parameter y), march along the spectral direction in some chunk of pixels 2: At each spectral location, construct a cross cut across the spatial direction; select_roi is used for this. 3: Fit a two-sided error function Fit.residual_disjoint_pair on the vertical cross cut derived in step 2. 4: If the fit fails, store it in the missing list - else if the top fit is good, store the top values in top vector - else if the bottom fit is good, store the bottom values in bottom vector. 5: In the vertical cross-cut, there is a minimum value. This minimum value is stored as a measure of scattered light. Another procedure is used to fit polynomials to these fitted values. ''' def select_roi(data, roi_width): v = data[y-roi_width:y+roi_width, xp-2:xp+2] v = np.median(v, axis=1) # Axis = 1 is spatial direction return v xposs_top = [] yposs_top = [] xposs_top_missing = [] xposs_bot = [] yposs_bot = [] xposs_bot_missing = [] yposs_bot_scatters = [] #1 rng = np.linspace(10, 2040, 50).astype(np.int) for i in rng: xp = i #2 v = select_roi(data, roi_width) xs = np.arange(len(v)) # Modified from 450 as the hard coded threshold to one that # can be controlled by a keyword if (np.median(v) < edgeThreshold): xposs_top_missing.append(xp) xposs_bot_missing.append(xp) continue #3 ff = Fit.do_fit(v, residual_fun=Fit.residual_disjoint_pair) fit_ok = 0 < ff[4] < 4 if fit_ok: (sigma, offset, mult1, mult2, add, width) = ff[0] xposs_top.append(xp) yposs_top.append(y - roi_width + offset + width) xposs_bot.append(xp) yposs_bot.append(y - roi_width + offset) between = offset + width/2 if 0 < between < len(v)-1: start = np.max([0, between-2]) stop = np.min([len(v),between+2]) yposs_bot_scatters.append(np.min(v[start:stop])) # 5 if False: pl.figure(2) pl.clf() tmppix = np.arange(y-roi_width, y+roi_width) tmpx = np.arange(len(v)) pl.axvline(y - roi_width + offset + width, color='red') pl.axvline(y - roi_width + offset, color='red') pl.scatter(tmppix, v) pl.plot(tmppix, Fit.fit_disjoint_pair(ff[0], tmpx)) pl.axhline(yposs_bot_scatters[-1]) pl.draw() else: yposs_bot_scatters.append(np.nan) else: xposs_bot_missing.append(xp) xposs_top_missing.append(xp) info("Skipping wavelength pixel): %i" % (xp)) return map(np.array, (xposs_bot, xposs_bot_missing, yposs_bot, xposs_top, xposs_top_missing, yposs_top, yposs_bot_scatters))