def dofit(xs, slambdas, alpha, sinbeta, gamma, delta, band, y): xs = np.array(xs) ok = np.isfinite(slambdas) lsf = Fit.do_fit_wavelengths(xs[ok], lines[ok], alpha, sinbeta, gamma, delta, band, y, error=slambdas[ok]) (order, pixel_y, alpha, sinbeta, gamma, delta) = lsf.params print "order alpha sinbeta gamma delta" print "%1.0i %5.7f %3.5f %3.2e %5.2f" % (order, alpha, sinbeta, gamma, delta) ll = Fit.wavelength_model(lsf.params, pix) if DRAW: pl.figure(3) pl.clf() pl.plot(ll, spec) pl.title("Pixel %4.4f" % pos) for lam in lines: pl.axvline(lam, color='r') pl.draw() return [np.abs(( Fit.wavelength_model(lsf.params, xs[ok]) - lines[ok]))*1e4, lsf.params]
def fit_line_with_sigclip(xs, data, i=0): ps = Fit.do_fit_edge(xs, data) pf = lambda x: Fit.fit_bar_edge(ps, x) residual = np.abs(pf(xs) - data) sd = np.std(residual) ok = np.where(residual < 2.5 * sd)[0] if len(ok) == 0: return [lambda x: NaN, []] ps = Fit.do_fit_edge(xs[ok], data[ok]) pf = lambda x: Fit.fit_bar_edge(ps, x) return [pf, ok]
def fit_spec(data, pos, alpha, sinbeta, gamma, delta, band): global DRAW ar_h_lines = np.array([1.465435, 1.474317, 1.505062, 1.517684, 1.530607, 1.533334, 1.540685, 1.590403, 1.599386, 1.618444, 1.644107, 1.674465, 1.744967, 1.791961]) Ar_K_lines = np.array([1.982291, 1.997118, 2.032256, 2.057443, 2.062186, 2.099184, 2.133871, 2.15409, 2.204558, 2.208321, 2.313952, 2.385154]) lines = ar_h_lines bmap = {"Y": 6, "J": 5, "H": 4, "K": 3} order = bmap[band] d = 1e3/110.5 pix = np.arange(2048) ll = Fit.wavelength_model([order, alpha, sinbeta, gamma, delta], pix) spec = np.median(data[pos-3:pos+3, :], axis=0) [xs, sxs, sigmas] = find_peaks(ll, spec, lines) slambdas = d/order * np.array(sxs) [deltas, params] = dofit(xs, slambdas, lines, alpha, sinbeta, gamma, delta, band) return (params[1], params[2], params[3], params[4], np.median(deltas), np.std(deltas), pixel, sigmas)
def dofit(xs, slambdas, lines, alpha, sinbeta, gamma, delta, band): xs = np.array(xs) ok = np.isfinite(slambdas) lsf = Fit.do_fit_wavelengths(xs[ok], lines[ok], alpha, sinbeta, gamma, delta, band, error=slambdas[ok]) (order, alpha, sinbeta, gamma, delta) = lsf.params print "order alpha sinbeta gamma delta" print "%1.0i %5.7f %3.5f %3.2e %5.2f" % (order, alpha, sinbeta, gamma, delta) pix = np.arange(2048.) ll = Fit.wavelength_model(lsf.params, pix) return [np.abs(( Fit.wavelength_model(lsf.params, xs[ok]) - lines[ok]))*1e4, lsf.params]
def fit_edge_poly(xposs, xposs_missing, yposs, order): ''' fit_edge_poly fits a polynomial to the measured slit edges. This polynomial is used to extract spectra. fit_edge_poly computes a parabola, and fills in missing data with a parabola input- xposs, yposs [N]: The x and y positions of the slit edge [pix] order: the polynomial order ''' # First fit low order polynomial to fill in missing data fun = np.poly1d(Fit.polyfit_clip(xposs, yposs, 2)) xposs = np.append(xposs, xposs_missing) yposs = np.append(yposs, fun(xposs_missing)) # Remove any fits that deviate wildly from the 2nd order polynomial ok = np.abs(yposs - fun(xposs)) < 1 if not ok.any(): error("Flat is not well illuminated? Cannot find edges") raise Exception("Flat is not well illuminated? Cannot find edges") # Now refit to user requested order fun = np.poly1d(Fit.polyfit_clip(xposs[ok], yposs[ok], order)) yposs_ok = yposs[ok] res = fun(xposs[ok]) - yposs[ok] sd = np.std(res) ok = np.abs(res) < 2*sd # Check to see if the slit edge funciton is sane, # if it's not, then we fix it. pix = np.arange(2048) V = fun(pix) if np.abs(V.max() - V.min()) > 10: info ("Forcing a horizontal slit edge") print("Forcing a horizontal slit edge") tmp = yposs_ok[ok] fun = np.poly1d(np.median(tmp)) #fun = np.poly1d(np.median(yposs[ok])) return (fun, res, sd, ok)
def find_peaks(ll, spec, lines): xs = [] sxs = [] sigmas = [] pix = np.arange(2048.) for lam in lines: f = 0.9985 roi = (f*lam < ll) & (ll < lam/f) if not roi.any(): xs.append(0.0) sxs.append(np.inf) sigmas.append(0.0) continue lsf = Fit.mpfitpeak(pix[roi], spec[roi], error=np.sqrt(np.abs(spec[roi]))) if lsf.perror is None: xs.append(0.0) sxs.append(np.inf) sigmas.append(0.0) continue if lsf.status < 0: xs.append(0.0) sxs.append(np.inf) sigmas.append(0.0) continue mnpix = np.min(pix[roi]) mxpix = np.max(pix[roi]) if (mnpix + 4) > lsf.params[1] < (mxpix-4): xs.append(0.0) sxs.append(np.inf) sigmas.append(0.0) continue if mnpix < 7: xs.append(0.0) sxs.append(np.inf) sigmas.append(0.0) continue if mxpix > 2040: xs.append(0.) sxs.append(np.inf) sigmas.append(0.0) continue xs.append(lsf.params[1]) sxs.append(lsf.perror[1]) sigmas.append(lsf.params[2]) return [xs, sxs, sigmas]
def fit_edge_poly(xposs, xposs_missing, yposs, order): ''' fit_edge_poly fits a polynomial to the measured slit edges. This polynomial is used to extract spectra. fit_edge_poly computes a parabola, and fills in missing data with a parabola input- xposs, yposs [N]: The x and y positions of the slit edge [pix] order: the polynomial order ''' # First fit low order polynomial to fill in missing data fun = np.poly1d(Fit.polyfit_clip(xposs, yposs, 2)) xposs = np.append(xposs, xposs_missing) yposs = np.append(yposs, fun(xposs_missing)) # Remove any fits that deviate wildly from the 2nd order polynomial ok = np.abs(yposs - fun(xposs)) < 1 if not ok.any(): error("Flat is not well illuminated? Cannot find edges") raise Exception("Flat is not well illuminated? Cannot find edges") # Now refit to user requested order fun = np.poly1d(Fit.polyfit_clip(xposs[ok], yposs[ok], order)) yposs_ok = yposs[ok] res = fun(xposs[ok]) - yposs[ok] sd = np.std(res) ok = np.abs(res) < 2 * sd # Check to see if the slit edge funciton is sane, # if it's not, then we fix it. pix = np.arange(2048) V = fun(pix) if np.abs(V.max() - V.min()) > 10: info("Forcing a horizontal slit edge") print("Forcing a horizontal slit edge") tmp = yposs_ok[ok] fun = np.poly1d(np.median(tmp)) #fun = np.poly1d(np.median(yposs[ok])) return (fun, res, sd, ok)
def plot_linefits(y, ff): global plot_arr pl.figure(3) pl.subplot(*plot_arr) ps = Fit.do_fit(y, Fit.residual_single)[0] xx = np.arange(len(y)) xxx = np.arange(0,len(y)-1,.1) fun = Fit.fit_single(ps,xxx) pl.plot(xx,y, '*') pl.plot(xxx, fun) x0 = ff(0) x1 = ff(0) + ps[4] pl.plot([x0, x0], [0, Fit.fit_single(ps, x0)]) pl.plot([x1, x1], [0, Fit.fit_single(ps, x1)]) pl.figure(4) pl.subplot(*plot_arr) fun = Fit.fit_single(ps,xx) r = (y - fun)/np.sqrt(np.abs(fun)) pl.plot(xx, r, '*') pl.ylim([-5,5])
def dofit(xs, sxs, alpha, beta, band): xs = np.array(xs) sxs = np.array(sxs)/1000. lsf = Fit.do_fit_wavelengths(xs, lines, alpha, beta, band, error=sxs) (order, alpha, beta, gamma, delta) = lsf.params print "alpha beta gamma delta" print "%5.7f %3.5f %3.2e %5.2f" % (alpha, beta, gamma, delta) ll = Fit.wavelength_model(lsf.params, pix) if False: pl.figure(3) pl.clf() pl.plot(ll, spec) pl.title("Pixel %4.4f" % pos) for lam in lines: pl.axvline(lam, color='r') pl.draw() return [np.abs((Fit.wavelength_model(lsf.params, xs) - lines))/lines, lsf.params]
def do_fits(params, pos, dy): (alpha, sinbeta, gamma, delta) = params[1:] thispos = pos - dy yposs.append(thispos) spec = np.median(data[thispos-3:thispos+3, :], axis=0) ll = Fit.wavelength_model(params, pix) [xs, sxs, sigmas] = find_peaks(ll, spec, lines) slambdas = d/order * np.array(sxs) [deltas, params] = dofit(xs, slambdas, lines, alpha, sinbeta, gamma, delta, band) results.append(np.array(params)) resdelt.append(deltas)
def fit_spec(data, pos, alpha, beta): global DRAW lines = np.array([1.49339, 1.49904, 1.51442, 1.51950, 1.52349, 1.53524, 1.54118, 1.6027, 1.62728, 1.64097, 1.71666]) order = 4 d = 1e3/110.5 pix = np.arange(2048.) ll = alpha * d/order * (np.sin(18./(250e3) * pix) + np.radians(beta)) spec = np.median(data[pos-3:pos+3, :], axis=0) if DRAW: pl.figure(2) pl.clf() pl.figure(3) pl.clf() pl.figure(1) pl.clf() pl.plot(ll, spec, '-+') for lam in lines: pl.axvline(lam, color='r') pl.title("Pixel pos: %i"% pos) pl.figure(2) pl.clf() xs = [] sxs = [] pks = [] rats = [] for lam in lines: roi = ((lam-.002) < ll) & (ll < (lam+0.002)) if not roi.any(): xs.append(0.0) sxs.append(np.inf) continue lsf = Fit.mpfitpeak(pix[roi], spec[roi], error=np.sqrt(np.abs(spec[roi]))) if lsf.perror is None: xs.append(0.0) sxs.append(np.inf) continue if lsf.status < 0: xs.append(0.0) sxs.append(np.inf) continue #if DRAW: if False: pl.plot(pix[roi], spec[roi]) pl.plot(pix[roi], spec[roi], 'o') pl.plot(pix[roi], Fit.gaussian(lsf.params, pix[roi]), 'r--') xs.append(lsf.params[1]) sxs.append(lsf.perror[1]) if False: pl.axvline(lsf.params[1]) if DRAW: pl.draw() def dofit(xs, sxs, alpha, beta, band): xs = np.array(xs) sxs = np.array(sxs)/1000. lsf = Fit.do_fit_wavelengths(xs, lines, alpha, beta, band, error=sxs) (order, alpha, beta, gamma, delta) = lsf.params print "alpha beta gamma delta" print "%5.7f %3.5f %3.2e %5.2f" % (alpha, beta, gamma, delta) ll = Fit.wavelength_model(lsf.params, pix) if False: pl.figure(3) pl.clf() pl.plot(ll, spec) pl.title("Pixel %4.4f" % pos) for lam in lines: pl.axvline(lam, color='r') pl.draw() return [np.abs((Fit.wavelength_model(lsf.params, xs) - lines))/lines, lsf.params] [delta, params] = dofit(xs, sxs, alpha, beta, 'H') return (params[1], params[2], np.median(delta), np.std(delta), pixel)
def fit_spec(data, pos, alpha, sinbeta, gamma, delta, band): global DRAW ar_h_lines = np.array([1.465435, 1.474317, 1.505062, 1.517684, 1.530607, 1.533334, 1.540685, 1.590403, 1.599386, 1.618444, 1.644107, 1.674465, 1.744967, 1.791961]) Ar_K_lines = np.array([1.982291, 1.997118, 2.032256, 2.057443, 2.062186, 2.099184, 2.133871, 2.15409, 2.204558, 2.208321, 2.313952, 2.385154]) Ne_J_lines = np.array([1.149125, 1.16719, 1.17227, 1.194655, 1.202994, 1.211564, 1.214306, 1.234677, 1.240622, 1.244273, 1.249108, 1.27369, 1.280624, 1.296021, 1.301182, 1.321761, 1.327627, 1.331685, 1.337077, 1.341026, 1.350788, 1.362638]) Ne_J_lines = np.array([1.149125, 1.16719, 1.117227]) AR_Y_lines = np.array([0.966043, 0.978718, 1.005481, 1.04809, 1.067649, 1.07039, 1.088394, 1.110819]) # NeAr H (1961, 1949) lines = np.array([1.465435, 1.474317, 1.505062, 1.517684, 1.530607, 1.533334, 1.540685, 1.590403, 1.599386, 1.618444, 1.644107, 1.674465, 1.744967, 1.791961, \ 1.493386, 1.499041, 1.523487, 1.5352384, 1.5411803, 1.5608478, 1.6027147, 1.6272797, 1.6409737, 1.6479254, 1.6793378, 1.7166622]) lines = np.array([ 1.540685, 1.5411803]) lines.sort() bmap = {"Y": 6, "J": 5, "H": 4, "K": 3} order = bmap[band] d = 1e3/110.5 pix = np.arange(2048.) ll = Fit.wavelength_model([order, pos, alpha, sinbeta, gamma, delta], pix) spec = np.median(data[pos-1:pos+1, :], axis=0) if DRAW: pl.figure(2) pl.clf() pl.figure(3) pl.clf() pl.figure(1) pl.clf() pl.plot(ll, spec, '-+') for lam in lines: pl.axvline(lam, color='r') pl.title("Pixel pos: %i"% pos) pl.figure(2) pl.clf() xs = [] sxs = [] pks = [] rats = [] for lam in lines: f = 0.9985 roi = (f*lam < ll) & (ll < lam/f) if not roi.any(): xs.append(0.0) sxs.append(np.inf) continue #lsf = Fit.mpfitpeak(pix[roi], spec[roi], # error=np.sqrt(np.abs(spec[roi]))) lsf = Fit.mpfitpeak(pix[roi], spec[roi], error=np.sqrt(np.abs(spec[roi]))) print lsf.params[2], lsf.params[1] print "LSF" pl.figure(6) pl.clf() pl.scatter(pix[roi], spec[roi]) pl.plot(pix[roi], Fit.gaussian(lsf.params, pix[roi])) lsf = Fit.mpfitpeaks(pix[roi], spec[roi], 2, error=np.sqrt(np.abs(spec[roi]))) print lsf.params[2], lsf.params[6], lsf.params[8] print "LSF" pl.figure(5) pl.clf() pl.scatter(pix[roi], spec[roi]) pl.plot(pix[roi], Fit.multi_gaussian(lsf.params, pix[roi])) if lsf.perror is None: xs.append(0.0) sxs.append(np.inf) continue if lsf.status < 0: xs.append(0.0) sxs.append(np.inf) continue mnpix = np.min(pix[roi]) mxpix = np.max(pix[roi]) if (mnpix + 4) > lsf.params[1] < (mxpix-4): xs.append(0.0) sxs.append(np.inf) continue if mnpix < 7: xs.append(0.0) sxs.append(np.inf) continue if mxpix > 2040: xs.append(0.) sxs.append(np.inf) continue #if DRAW: if DRAW: pl.plot(pix[roi], spec[roi]) pl.plot(pix[roi], spec[roi], 'o') pl.plot(pix[roi], Fit.gaussian(lsf.params, pix[roi]), 'r--') xval = lsf.params[1] xvals = lsf.perror[1] xs.append(xval) sxs.append(xvals) if DRAW: if np.isfinite(xvals): pl.axvline(xval) if DRAW: pl.draw() def dofit(xs, slambdas, alpha, sinbeta, gamma, delta, band, y): xs = np.array(xs) ok = np.isfinite(slambdas) lsf = Fit.do_fit_wavelengths(xs[ok], lines[ok], alpha, sinbeta, gamma, delta, band, y, error=slambdas[ok]) (order, pixel_y, alpha, sinbeta, gamma, delta) = lsf.params print "order alpha sinbeta gamma delta" print "%1.0i %5.7f %3.5f %3.2e %5.2f" % (order, alpha, sinbeta, gamma, delta) ll = Fit.wavelength_model(lsf.params, pix) if DRAW: pl.figure(3) pl.clf() pl.plot(ll, spec) pl.title("Pixel %4.4f" % pos) for lam in lines: pl.axvline(lam, color='r') pl.draw() return [np.abs(( Fit.wavelength_model(lsf.params, xs[ok]) - lines[ok]))*1e4, lsf.params] slambdas = d/order * np.array(sxs) [deltas, params] = dofit(xs, slambdas, alpha, sinbeta, gamma, delta, band) if 0.4 < np.median(deltas) < 0.8: prev = np.median(deltas) [deltas, params] = dofit(xs, slambdas, params[1], params[2], params[3], params[4], band) print "Previous MAD: %f is now %f" % (prev, np.median(deltas)) return (params[1], params[2], params[3], params[4], np.median(deltas), np.std(deltas), pixel)
print "-------------==========================------------------" print "Finding Slit Edges for %s starting at %4.0i" % (ssl[target]["Target_Name"], y) tock = time.clock() yposs = [] widths = [] xposs = [] x = 936 for i in range(-49, 50): delt = 1900/100. xp = x+delt*i v = data[y-roi_width:y+roi_width, xp-2:xp+2] v = np.median(v, axis=1) ff = Fit.do_fit(v, residual_fun=Fit.residual_disjoint_pair) if (0 < ff[4] < 4): xposs.append(x+delt*i) xs = np.arange(len(v)) yposs.append(ff[0][1] - roi_width) widths.append(ff[0][5]) else: print "Skipping: %i" % (x+delt*i) (xposs, yposs, widths) = map(np.array, (xposs, yposs, widths)) fun = np.poly1d(Fit.polyfit_clip(xposs, yposs, 3)) wfun = np.poly1d(Fit.polyfit_clip(xposs, widths, 3)) res = fun(xposs) - yposs sd = np.std(res)
pars = [1500, 20, 100000, 10000] pars.extend(np.zeros(len(pixs))) pars = np.array(pars) parinfo = [] for par in pars: parinfo.append({"fixed": 0, "value": par}) pl.ion() y = Wavelength.beta_model(pars, pixs) parinfo[0]["fixed"] = 1 parinfo[1]["fixed"] = 1 parinfo[2]["fixed"] = 1 parinfo[3]["fixed"] = 1 merit_fun = Fit.mpfit_residuals(Wavelength.beta_model) lsf = Fit.mpfit_do(merit_fun, pixs, all_betas, parinfo) parinfo = [] for param in lsf.params: parinfo.append({"fixed": 0, "value": param}) lsf = Fit.mpfit_do(merit_fun, pixs, all_betas, parinfo) print lsf pl.figure(2) pl.clf() pl.plot(all_pixs, all_betas, '.') y = Wavelength.beta_model(lsf.params, pixs) d = np.abs(np.diff(y)) rois = np.where(d>0.01)[0] prev = 0
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))
[[xslice, yslice], extent] = make_slice(pos, 6, 25) if extent[0] == extent[1]: cnt += 1 continue if extent[2] == extent[3]: cnt += 1 continue cnt += 1 fits = [] xs = np.arange(-10, 10) for i in xs: tofit = data[pos[1] - i, xslice] y = median_tails(tofit) ps = Fit.do_fit(y, Fit.residual_pair) fits.append(ps[0]) fits = np.array(fits) m = [np.mean(fits[:, i]) for i in range(5)] s = [np.std(fits[:, i]) for i in range(5)] means.append(m) sds.append(s) [ff, ok] = fit_line_with_sigclip(xs, fits[:, 1]) pl.figure(5) pl.subplot(7, 7, cntfit) pl.plot(xs, fits[:, 1] - ff(xs), '*-') pl.plot(xs[ok], fits[ok, 1] - ff(xs[ok]), 'or-')
[[xslice, yslice],extent] = make_slice(pos, 6,25) if extent[0] == extent[1]: cnt += 1 continue if extent[2] == extent[3]: cnt += 1 continue cnt+=1 fits = [] xs = np.arange(-10,10) for i in xs: tofit = data[pos[1]-i, xslice] y = median_tails(tofit) ps = Fit.do_fit(y, Fit.residual_pair) fits.append(ps[0]) fits = np.array(fits) m = [np.mean(fits[:,i]) for i in range(5)] s = [np.std(fits[:,i]) for i in range(5)] means.append(m) sds.append(s) [ff, ok] = fit_line_with_sigclip(xs, fits[:,1]) pl.figure(5) pl.subplot(7,7,cntfit) pl.plot(xs, fits[:,1] - ff(xs), '*-') pl.plot(xs[ok], fits[ok,1] - ff(xs[ok]), 'or-')
def go(fname): global plot_arr print fname (header, data) = IO.readfits(fname) bs = CSU.Barset() bs.set_header(header) bars = [] means = [] sds = [] deltas = [] deltas_mm = [] poss = [] poss_mm = [] poss_y = [] request = [] qs = [] bars = range(1, 93) fit_fun = Fit.residual_single for bar in bars: pos = bs.get_bar_pix(bar) if bar % 8 == 0: print "%2.0i: (%7.2f, %7.2f)" % (bar, pos[0], pos[1]) if is_odd(bar): if (bs.pos[bar] - bs.pos[bar-1]) < 2.7: fit_fun = Fit.residual_pair else: fit_fun = Fit.residual_single width = 19 [[xslice, yslice],extent,ystart] = make_slice(pos,0,width,30) if not is_in_bounds(extent): fits = [0,0,0,0,0] [ff,ok] = [np.poly1d(0,0), []] means.append(fits) sds.append(fits) drop_this = True else: drop_this = False fits = [] ys = np.arange(-10,10, dtype=np.float32) for i in ys: tofit = data[ystart-i, xslice] y = median_tails(tofit) ps = Fit.do_fit(y, fit_fun) fits.append(ps[0]) fits = np.array(fits) fits[:,1] += 1 # fit to the ridgeline [ff, ok] = fit_line_with_sigclip(ys, fits[:,1]) m = [np.mean(fits[:,i]) for i in range(5)] s = [np.std(fits[:,i]) for i in range(5)] means.append(m) sds.append(s) slit_center_offset = pos[1] - ystart fc = ff(slit_center_offset) slit_center_pos = np.float(extent[0] + fc ) if drop_this: poss.append(NaN) poss_y.append(NaN) poss_mm.append(NaN) else: poss.append(slit_center_pos) poss_y.append(ystart) poss_mm.append(CSU.csu_pix_to_mm_poly(slit_center_pos, ystart)[0]) delta = np.float(slit_center_pos - pos[0]) if drop_this: deltas.append(NaN) deltas_mm.append(NaN) else: deltas.append(delta) b = CSU.csu_pix_to_mm_poly(slit_center_pos + delta, ystart)[0] deltas_mm.append(b - poss_mm[-1]) q = np.float(np.degrees(np.tan(ff(1)-ff(0)))) if drop_this: qs.append(NaN) qs.append(q) means = np.array(means) f = lambda x: np.array(x).ravel() sds = f(sds) deltas = f(deltas) poss = f(poss) poss_y = f(poss_y) poss_mm = f(poss_mm) deltas_mm = f(deltas_mm) qs = f(qs) bars = f(bars) fout = "/users/npk/dropbox/mosfire/cooldown 9/csu_meas/" + fname.split("/")[-1] + ".sav" print "saving" tosav = {"bars": bars, "request": bs.pos, "deltas_mm": deltas_mm, "poss": poss, "poss_mm": poss_mm, "deltas": deltas, "means": means, "qs": qs} scipy.io.savemat(fout, tosav) save_region(bs, "/users/npk/dropbox/mosfire/cooldown 9/csu_meas/" + fname.split("/")[-1] + ".reg") print "saved" regout = "/users/npk/dropbox/mosfire/cooldown 9/csu_meas/" + fname.split("/")[-1] + ".meas.reg" pairs = np.array([poss,poss_y]).transpose() s = CSU.to_ds9_region(pairs, dash=0, color="blue", label=False) try: f = open(regout, "w") f.writelines(s) f.close() except: print "Couldn't write: %s" % regout return [tosav, bs]
def go(fname): global plot_arr print fname (header, data) = IO.readfits(fname) bs = CSU.Barset() bs.set_header(header) cntfit = 1 for i in range(1,8): continue pl.figure(i) pl.clf() first_time = True bars = [] means = [] sds = [] deltas = [] deltas_mm = [] poss = [] poss_mm = [] poss_y = [] request = [] qs = [] bars = range(1, 93) for bar in bars: pos = bs.get_bar_pix(bar) if bar % 8 == 0: print "%2.0i: (%7.2f, %7.2f)" % (bar, pos[0], pos[1]) width = 19 [[xslice, yslice],extent,ystart] = make_slice(pos,0,width,30) if not is_in_bounds(extent): fits = [0,0,0,0,0] [ff,ok] = [np.poly1d(0,0), []] means.append(fits) sds.append(fits) drop_this = True else: drop_this = False fits = [] ys = np.arange(-10,10, dtype=np.float32) for i in ys: tofit = data[ystart-i, xslice] y = median_tails(tofit) ps = Fit.do_fit(y, Fit.residual_single) fits.append(ps[0]) fits = np.array(fits) fits[:,1] += 1 # fit to the ridgeline [ff, ok] = fit_line_with_sigclip(ys, fits[:,1]) m = [np.mean(fits[:,i]) for i in range(5)] s = [np.std(fits[:,i]) for i in range(5)] means.append(m) sds.append(s) #if bar == 44: start_shell() #if bar == 43: start_shell() # End of measurement logic, PLOTS plot_arr = [12, 8, cntfit] cntfit += 1 if False: plot_stamps(data[yslice, xslice], ps[0]) y0 = median_tails(data[ystart, xslice]) plot_linefits(y0, ff) plot_ridgeline(fits, ok, ys, ff, bar) plot_widths(fits, ok, ys) # End of plots, BOOKEEPING slit_center_offset = pos[1] - ystart fc = ff(slit_center_offset) slit_center_pos = np.float(extent[0] + fc ) if drop_this: poss.append(NaN) poss_y.append(NaN) poss_mm.append(NaN) else: poss.append(slit_center_pos) poss_y.append(ystart) poss_mm.append(CSU.csu_pix_to_mm_poly(slit_center_pos, ystart)[0]) delta = np.float(slit_center_pos - pos[0]) if drop_this: deltas.append(NaN) deltas_mm.append(NaN) else: deltas.append(delta) b = CSU.csu_pix_to_mm_poly(slit_center_pos + delta, ystart)[0] deltas_mm.append(b - poss_mm[-1]) q = np.float(np.degrees(np.tan(ff(1)-ff(0)))) if drop_this: qs.append(NaN) qs.append(q) if False: #is_in_bounds(extent): pl.figure(2) pl.text(pos[0], pos[1], 'b%2.0i: w=%3.2f p=%5.2f q=%3.2f d=%1.3f' % (bar, np.mean(fits[:,4]), extent[0]+ff(0), q, delta), fontsize=11, family='monospace', horizontalalignment='center') means = np.array(means) f = lambda x: np.array(x).ravel() sds = f(sds) deltas = f(deltas) poss = f(poss) poss_y = f(poss_y) poss_mm = f(poss_mm) deltas_mm = f(deltas_mm) qs = f(qs) bars = f(bars) pl.draw() if False: [pf, ok] = fit_line_with_sigclip(bars, deltas) print "** Residual: %4.3f [pix]" % np.std(deltas[ok]-pf(bars[ok])) evens = range(0,92,2) odds = range(1,92,2) pl.plot(bars[evens], deltas[evens],'r*-') pl.plot(bars[odds], deltas[odds],'b*-') pl.title("Red: even, blue: odd") pl.xlabel("Bar #") pl.ylabel("Delta pixel (Measured - Predicted)") pl.plot(bars, pf(bars)) fout = "/users/npk/dropbox/mosfire/cooldown 9/csu_meas/" + fname.split("/")[-1] + ".sav" print "saving" tosav = {"bars": bars, "request": bs.pos, "deltas_mm": deltas_mm, "poss": poss, "poss_mm": poss_mm, "deltas": deltas, "means": means, "qs": qs} scipy.io.savemat(fout, tosav) save_region(bs, "/users/npk/dropbox/mosfire/cooldown 9/csu_meas/" + fname.split("/")[-1] + ".reg") print "saved" regout = "/users/npk/dropbox/mosfire/cooldown 9/csu_meas/" + fname.split("/")[-1] + ".meas.reg" pairs = np.array([poss,poss_y]).transpose() s = CSU.to_ds9_region(pairs, dash=0, color="blue", label=False) try: f = open(regout, "w") f.writelines(s) f.close() except: print "Couldn't write: %s" % regout return [tosav, bs]
print "Skipping: %i" % (x+delt*i) return map(np.array, (xposs, yposs, widths)) def fit_edge_poly(xposs, yposs, widths, order): ''' fit_edge_poly fits a polynomial to the measured slit edges. This polynomial is used to extract spectra. input- xposs, yposs [N]: The x and y positions of the slit edge [pix] widths [N]: the offset from end of one slit to beginning of another [pix] order: the polynomial order ''' fun = np.poly1d(Fit.polyfit_clip(xposs, yposs, order)) wfun = np.poly1d(Fit.polyfit_clip(xposs, widths, order)) res = fun(xposs) - yposs sd = np.std(res) ok = np.abs(res) < 2*sd return (fun, wfun, res, sd, ok) def data_quality_plots(results): y = 2028 toc = 0 slits = []
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))
spec = slitlet[mid-3:mid+3, :] spec = np.median(spec, axis=0) continuum = median_filter(spec, 250) if fiducial_spec.shape == (0,): fiducial_spec = spec fiducial_spec /= continuum fiducial_spec /= fiducial_spec.max() soc = spec/continuum soc /= soc.max() as_per_pix = .18/1.4 shift = -np.median(loc)/as_per_pix lags = np.arange(shift-300,shift+300,dtype=np.int) xc = Fit.xcor(soc[800:1300], fiducial_spec[800:1300], lags) #start_shell() shift = lags[np.argmax(xc)] center = width/2 - shift print center, write_pos xs = np.arange(len(spec)) pl.plot(xs - shift, spec/continuum) try: out[(write_pos - dy):write_pos, center-1024:center+1024] = slitlet if minl > center-1024: minl = center-1024 if maxl < center+1024: maxl = center+1024