def resample1d(data,coeffs,axis,const=0.0,offset=0.): """ resample1d(data,coeffs,axis,const=0.0,offset=0.) Resamples 2d spectra in x or y direction. Inputs: data - input data array coeffs - polynomial that describes output axis - axis to resample ("x" or "y") const - padding constant for the interpolation offset - amount by which to offset the coefficient solution Output: resampled data """ from special_functions import genfunc coords = array_coords(data.shape) y = coords[0].flatten() x = coords[1].flatten() if axis=="Y" or axis=="y" or axis==1: y += offset coords[0] = genfunc(x,y,coeffs).reshape(data.shape)-offset else: x += offset coords[1] = genfunc(x,y,coeffs).reshape(data.shape)-offset del x,y return scipy.ndimage.map_coordinates(data,coords,cval=const,output=scipy.float64,order=5)
def getYsoln(star, nstars, low, high): # Find solution as function of y position if there are enough star traces print "" print "Finding y solution" star = star.repeat(2, 0).repeat(2, 1) star = rotate2(star) starTMP = star[low * 2:high * 2].copy() if nstars > 3: ytrue2, ymap2 = ycorrect.ycorrect(starTMP, False, order=2) coords = numpy.indices(starTMP.shape).astype(numpy.float32) x = coords[1].flatten() y = coords[0].flatten() del coords yforw2 = sf.genfunc(x, y, ytrue2).reshape(starTMP.shape) yback2 = sf.genfunc(x, y, ymap2).reshape(starTMP.shape) # Not enough star traces; assume the distortion is constant over y else: yforw2, yback2 = ycor(starTMP) # Repeat for non-oversampled case star = iT.resamp(star, 2)[low:high] if nstars > 3: ytrue, ymap = ycorrect.ycorrect(star, False, order=2) coords = numpy.indices(star.shape).astype(numpy.float32) x = coords[1].flatten() y = coords[0].flatten() del coords yforw = sf.genfunc(x, y, ytrue).reshape(star.shape) yback = sf.genfunc(x, y, ymap).reshape(star.shape) else: yforw, yback = ycor(star) return yforw, yback, yforw2, yback2 #,ytrue2,ymap2
def dofit(self): print("Press Enter to input order") order = raw_input("Order: ") order = int(order) lines = scipy.empty(len(self.lines)) wave = scipy.empty(len(self.ids)) for i in range(lines.size): lines[i] = self.lines[i] wave[i] = self.ids[i] fit = scipy.empty((lines.size, 2)) fit[:, 0] = lines.copy() fit[:, 1] = wave.copy() self.solution = sf.lsqfit(fit, 'chebyshev', order) fit[:, 0] = wave.copy() fit[:, 1] = lines.copy() self.inverse = sf.lsqfit(fit, 'chebyshev', order) self.wave = sf.genfunc(self.points, 0., self.solution) pylab.close() self.__call__() for i in self.markers: wave = sf.genfunc(i, 0., self.solution) verts = self.markers[i].get_verts() bottom = verts[0][1] top = verts[1][1] wave = wave[0] mark = mpl.patches.Polygon([(wave, bottom), (wave, top)]) self.markers[wave] = mark self.ax.add_patch(mark) del self.markers[i] pylab.draw()
def matchlines(peaks, solution, linefile, tol=30., order=3, offset=False): wave = special_functions.genfunc(peaks, 0., solution) try: lines = getlines(linefile) except: lines = linefile gooddata = [] goodlines = [] for i in range(wave.size): delta = 1e9 match = None for j in lines: if abs(j - wave[i]) < delta: delta = abs(j - wave[i]) match = j else: break if delta < tol: gooddata.append(peaks[i]) goodlines.append(match) fitdata = scipy.empty((len(gooddata), 2)) fitdata[:, 0] = scipy.asarray(gooddata) fitdata[:, 1] = scipy.asarray(goodlines) if offset: a = special_functions.genfunc(fitdata[:, 0], 0., solution) return fitdata[:, 1] - a return special_functions.lsqfit(fitdata, 'chebyshev', order)
def fullSolution(shape,ysoln,orders,wideorders,wsoln): import indexTricks as iT coords = iT.coords(shape) y = coords[0].copy() x = coords[1].copy() soln = [] if shape[1]>3000: disp = 1.65e-5 else: disp = 2*1.65e-5 owave = numpy.arange(3.585,4.038,disp) for i in range(len(ysoln)): low,high = orders[i] wlow,whigh = wideorders[i] ytrue,ymap = ysoln[i] win,wout = wsoln[i] tmpw = genfunc(x[0],0.,win) ow = owave[(owave>=tmpw[0])&(owave<=tmpw[-1])].copy() if ow.size>x.shape[1]: diff = ow.size-x.shape[1] if diff%2==0: ow = ow[int(diff/2):int(diff/-2)] else: ow = ow[int(diff/2):int((diff+1)/-2)] xc = genfunc(ow,0.,wout) xc = xc.repeat(high-low).reshape((xc.size,high-low)).T yc = genfunc(xc.ravel(),y[low:high,:xc.shape[1]].ravel(),ytrue) yc = yc.reshape((high-low,xc.shape[1]))-wlow corr = numpy.linspace(-0.2,0.2,high-low) xc = (xc.T+corr).T #xc = xc.repeat(high-low).reshape(yc.shape[::-1]).T soln.append([numpy.array([yc,xc]),ow[0],ow[-1],disp]) return soln
def combine_xyw(coords, xsoln, ysoln, wsoln, xord, yord): x = coords[1].flatten() y = coords[0].flatten() newy = ysoln.flatten() from scipy import random k = random.random(x.size) args = k.argsort() x = x[args[:y.size / 10]] newy = newy[args[:y.size / 10]] y = y[args[:y.size / 10]] newx = sf.genfunc(x, y, xsoln['back']) wave = sf.genfunc(newx, 0., wsoln) data = scipy.empty((x.size, 3)) data[:, 0] = wave.copy() data[:, 1] = y.copy() data[:, 2] = x.copy() output_to_ccdx = sf.lsqfit(data, 'chebyshev', xord, yord) data[:, 2] = newy.copy() output_to_ccdy = sf.lsqfit(data, 'chebyshev', xord, yord) data[:, 0] = x.copy() data[:, 1] = y.copy() data[:, 2] = wave.copy() ccdx_ycor_to_wave = sf.lsqfit(data, 'chebyshev', xord, yord) return { 'sky2x': output_to_ccdx, 'sky2y': output_to_ccdy, 'ccd2wave': ccdx_ycor_to_wave }
def doublematch(peaks, w, linefile, skyin, tol=30., order=3, shift=0., logfile=None): lines = scipy.asarray(skyin) lines.sort() p = peaks[0] wave = special_functions.genfunc(p, 0., w) goodmatches = [] for i in range(wave.size): delta = 1e9 match = None for j in lines: if abs(j - wave[i]) < delta: delta = abs(j - wave[i] + shift) match = j else: break if delta < tol: goodmatches.append([p[i], match]) p = peaks[1] wave = special_functions.genfunc(p, 0., w) lines = scipy.asarray(linefile) # lines = getlines(linefile) lines.sort() for i in range(wave.size): delta = 1e9 match = None for arc in lines: if abs(arc - wave[i]) < delta: delta = abs(arc - wave[i] + shift) match = arc else: break if delta < tol: goodmatches.append([p[i], match]) fitdata = scipy.asarray(goodmatches) fit = special_functions.lsqfit(fitdata, 'chebyshev', order) match = special_functions.genfunc(fitdata[:, 0], 0., fit) diff = match - fitdata[:, 1] error = stats.stats.std(diff) if logfile is not None: logentry = "\tWavelength solution error: %5.3f angstroms from %d lines\n" % ( error, diff.size) for i in range(diff.size): logentry += "\t\t%7.2f %7.2f %5.2f\n" % (fitdata[i, 1], match[i], diff[i]) keeplog(logfile, logentry) return fit, error
def getWsoln(sky, x, wsolution, wmodel): def refine(p, x, d, sky, model): pars = {'coeff': numpy.atleast_2d(p).T, 'type': 'polynomial'} w = sf.genfunc(x, 0., pars) c = (w > wmodel['blue']) & (w < wmodel['red']) mod = interpolate.splev(w[c], model) mod /= mod.mean() return (d[c] - mod) / abs(sky[c] + mod)**0.5 # For `by hand' fitting if wsolution is None: import id_spec wsolution = id_spec.id_spec(sky, wmodel) x0 = numpy.arange(sky.size) w = sf.genfunc(x0, 0., wsolution) wsolution = sf.lsqfit(numpy.array([x, w]).T, 'polynomial', 3) else: import pylab tmpD = sky.copy() tmpD /= sky.mean() sky /= sky.mean()**2 T = FFTFilter(tmpD, 100) Dlines = spf.get_lines(x, T, nstd=7.) Dwlines = sf.genfunc(Dlines, 0., wsolution) w = sf.genfunc(x, 0., wsolution) c = (w > wmodel['blue']) & (w < wmodel['red']) mod = interpolate.splev(w[c], wmodel['model']) Slines = spf.get_lines(w[c], mod, nstd=7.) matches = [] for j in range(Dwlines.size): diff = abs(Dwlines[j] - Slines) if diff.min() < 5. * wmodel['scale']: matches.append([Dlines[j], Slines[diff.argmin()]]) wsolution = sf.lsqfit(numpy.asarray(matches), 'polynomial', 3) start = wsolution['coeff'].flatten() coeff, ier = optimize.leastsq(refine, start, (x, tmpD, sky, wmodel['model']), epsfcn=1e-5, maxfev=10000, ftol=1e-13, xtol=1e-13) wsolution = {'coeff': numpy.atleast_2d(coeff).T, 'type': 'polynomial'} w = sf.genfunc(x, 0., wsolution) c = (w > wmodel['blue']) & (w < wmodel['red']) mod = interpolate.splev(w[c], wmodel['model']) mod /= mod.mean() pylab.plot(w[c], mod) pylab.plot(w[c], tmpD[c]) pylab.show() w = sf.genfunc(x, 0., wsolution) rwsoln = sf.lsqfit(numpy.array([w, x]).T, 'polynomial', 3) return wsolution, rwsoln
def wave_arclines(arc, arcmodel, sky, solution): from scipy import interpolate STD_LINES = scipy.sort(arcmodel['lines']) SKYLINES = [5577.338, 6300.304, 6363.78, 6553.617] #,6912.62] x = scipy.arange(arc.size).astype(scipy.float32) lines = get_lines(x, arc) skycoords = get_lines(x, sky) arccoords = lines.copy() scale = arcmodel['scale'] if scale > 1.5: SKYLINES.insert(1, 5891.) order = solution['coeff'].size - 1 fit = solution w = sf.genfunc(lines, 0., fit) matches = [] for line in STD_LINES: diff = abs(w - line) if diff.min() < 5. * scale: pos = diff.argmin() matches.append([lines[pos], line]) print matches, order fit = sf.lsqfit(scipy.asarray(matches), 'polynomial', order) order = 1 for i in range(7): matched = [m for m in matches] if skycoords.size == 0: offset = 0. break skyline = sf.genfunc(skycoords, 0., fit) offsets = [] for line in SKYLINES[:i * 2 + 2]: diff = abs(line - skyline) if diff.min() < 5. * scale: offsets.append(line - skyline[diff.argmin()]) if len(offsets) == 0: offset = 0. break offset = scipy.median(scipy.asarray(offsets)) for line in SKYLINES[:i * 2 + 2]: diff = abs(line - skyline) if diff.min() < 5. * scale: pos = diff.argmin() matched.append([skycoords[pos], line - offset]) fit = sf.lsqfit(scipy.asarray(matched), 'polynomial', order) fit['coeff'][0] += offset return fit
def resample1d(data,coeffs,axis,const=0.0,offset=0.): from special_functions import genfunc coords = array_coords(data.shape) y = coords[0].flatten() x = coords[1].flatten() if axis=="Y" or axis=="y" or axis==1: y += offset coords[0] = genfunc(x,y,coeffs).reshape(data.shape)-offset else: x += offset coords[1] = genfunc(x,y,coeffs).reshape(data.shape)-offset del x,y return scipy.ndimage.map_coordinates(data,coords,cval=const,output=scipy.float64,order=5)
def skyfit(p, x, data, model, tmp): par = special_functions.build_coeff(p[:-2], tmp) """ Test for increasing function... """ tmp = special_functions.genfunc(x, 0., par).astype(scipy.float32) diff = signal.convolve(tmp, [1., -1.], mode='same')[10:-10].copy() if diff[diff < 0].size > 0: return scipy.ones(x.size) * 1.e9 data = data.astype(scipy.float64) z = special_functions.genfunc(x, 0, par).astype(scipy.float64) sky = interpolate.splev(z, model).astype(scipy.float64) sky *= p[-2] return (sky - data) / scipy.sqrt(abs(sky))
def refine(p, x, d, sky, model): pars = {'coeff': numpy.atleast_2d(p).T, 'type': 'polynomial'} w = sf.genfunc(x, 0., pars) c = (w > wmodel['blue']) & (w < wmodel['red']) mod = interpolate.splev(w[c], model) mod /= mod.mean() return (d[c] - mod) / abs(sky[c] + mod)**0.5
def arcfit(p, x, arc, mod): fit = {'coeff': scipy.atleast_2d(p).T, 'type': 'polynomial'} w = sf.genfunc(x, 0., fit) cond = (w > bcutoff) & (w < rcutoff) m = interpolate.splev(w[cond], mod) chi = (m - arc[cond]) / abs(arc[cond])**0.5 return chi
def resampley(data,ycoords,yoffset=0.,cval=0.,mode="constant",slice=None): """ resampley(data,ycoords,yoffset=0.,cval=0.,mode="constant",slice=None) Resamples 2d spectra in the spatial direction to remove the grating smile. Allows a coordinate array or polynomial to be passed. Inputs: data - data to be resampled ycoords - output y-coordinates or a polynomial to describe output yoffset - optional offset wrt the polynomial or coordinate array cval - interpolation boundary constant mode - method for interpolating boundaries slice - sub-slice to resample to (ie if the output shape is not the same as the input shape) """ from scipy import ndimage try: coords = array_coords(ycoords.shape) except: from special_functions import genfunc coords = array_coords(data.shape) x = coords[1].flatten() y = coords[0].flatten()+yoffset ycoords = genfunc(x,y,ycoords).reshape(coords[0].shape) if slice is not None: ycoords = ycoords[slice].copy() coords = array_coords(ycoords.shape) del x,y coords[0] = ycoords.astype(scipy.float64)-yoffset return ndimage.map_coordinates(data,coords,output=scipy.float64,mode=mode,cval=cval,order=5)
def resampleData(data, owgrid, low, high, ysoln, xsoln, rwsoln): dy = (high - low) * 2 ygrid = iT.coords((dy, owgrid.size))[0] xgrid = sf.genfunc(owgrid, 0., rwsoln).repeat(dy) xgrid = xgrid.reshape((owgrid.size, dy)).T xgrid = sf.genfunc(xgrid.flatten(), ygrid.flatten(), xsoln['forw']) xgrid = xgrid.reshape(ygrid.shape) c = numpy.array([ygrid, xgrid]) ygrid = ndimage.map_coordinates(ysoln[2], c) c = numpy.array([ygrid + low * 2, xgrid]) X = ndimage.map_coordinates(rotcoords2[1], c) Y = ndimage.map_coordinates(rotcoords2[0], c) c = numpy.array([Y, X]) d = data.repeat(2, 0).repeat(2, 1) img = ndimage.map_coordinates(d, c, order=5) return iT.resamp(img, 2)
def findoffset(p, x, data, model, coeff): xvals = x + p[0] w = special_functions.genfunc(xvals, 0., coeff) mod = interpolate.splev(w, model) mod = mod * data.max() / mod.max() diff = (mod - data) / scipy.sqrt(abs(mod)) return diff
def debug(wave,fitdata,finemodel,skycoeff=None): if skycoeff is not None: wave = special_functions.genfunc(wave,0.,skycoeff) mod = interpolate.splev(wave,finemodel) import pylab pylab.plot(wave,fitdata) pylab.plot(wave,mod*fitdata.max()/mod.max()) pylab.show()
def opt(p): p = numpy.array(p) n = p[-1] coeff = numpy.atleast_2d(p[:-1]).T m = {'coeff': coeff, 'type': 'polynomial'} w = sf.genfunc(xvals, 0., m) mod = n * interpolate.splev(w, skymodel) return (data - mod) / abs(data)**0.5
def doarcfitfunc(p,xdata,ydata,scidata,model,coeff): par = special_functions.build_coeff(p,coeff) scidata = scidata.astype(scipy.float64) z = special_functions.genfunc(xdata,ydata,par).astype(scipy.float64) z = z.reshape((1,scidata.size)) resample = ndimage.map_coordinates(model,z,output=scipy.float64,cval=-1) diff = (scidata - resample)/scipy.sqrt(abs(resample)) return diff
def update_xsoln(data, soln, xord=3, yord=3, skip=False): data = data.copy() height, width = data.shape if skip: slice = data.mean(1) indx = slice.argsort()[slice.size / 4] mid = data[indx] badrow = scipy.where(slice > slice[indx] + 5. * (slice[indx])**0.5)[0] if badrow.size == 0: badrow = scipy.array([-1]) else: indx = height / 2 mid = data[indx] badrow = scipy.array([-1]) xvals = scipy.arange(mid.size) middle_lines = get_lines(xvals, mid, False) straight = sf.genfunc(middle_lines, indx, soln['back']) ref = [] lines = [] for row in range(height): if abs(row - badrow).min() == 0: continue current = get_lines(xvals, data[row], False) if current.size == 0: continue guess = sf.genfunc(current, row, soln['back']) for l in straight: diff = abs(l - guess) if diff.min() < 2: pos = diff.argmin() lines.append([current[pos], row, l]) lines = scipy.asarray(lines) newsoln = sf.lsqfit(lines, 'chebyshev', xord, yord) tmp = lines[:, 0].copy() lines[:, 0] = lines[:, 2].copy() lines[:, 2] = tmp.copy() del tmp newsoln2 = sf.lsqfit(lines, 'chebyshev', xord, yord) return {'back': newsoln, 'forw': newsoln2}
def arcfitfunc(p, x, data, model, tmp, model2=None, mask=None): par = special_functions.build_coeff(p, tmp) """ Test for increasing function... """ tmp = special_functions.genfunc(x, 0., par).astype(scipy.float32) diff = signal.convolve(tmp, [1., -1.], mode='same')[10:-10].copy() if diff[diff < 0].size > 0: return scipy.ones(x.size) * 1.e9 data = data.astype(scipy.float64) z = special_functions.genfunc(x, 0, par).astype(scipy.float64) mod = interpolate.splev(z, model).astype(scipy.float64) if model2 is not None: mod += interpolate.splev(z, model2).astype(scipy.float64) mod = mod * data.max() / mod.max() + scipy.median(data) diff = (data - mod) / scipy.sqrt(abs(mod)) return diff
def wave_skylines(sky, solution): STD_LINES = [ 5197.928, 5200.286, 5202.977, 5460.735, 5577.345, 5867.5522, 5915.308, 5932.864, 6257.970, 6300.320, 6363.810, 6533.040, 6553.610, 6863.971, 6912.620, 6923.210, 6939.520, 7303.716, 7329.148, 7340.885, 7358.659, 7392.198, 7586.093, 7808.467, 7821.510, 7841.266, 7993.332, 8310.719, 8344.613, 8399.160, 8415.231, 8430.170, 8791.186, 8885.830, 8943.395, 8988.384, 9038.059, 9337.854, 9375.977, 9419.746, 9439.670, 9458.524 ] x = scipy.arange(sky.size).astype(scipy.float32) lines = get_lines(x, sky) scale = solution['coeff'][1] order = solution['coeff'].size - 1 if scale > 1.5: STD_LINES.insert(6, 5891.) w = sf.genfunc(lines, 0., solution) matches = [] for i in range(w.size): diff = abs(w[i] - STD_LINES) if diff.min() < 5. * scale: matches.append([lines[i], STD_LINES[diff.argmin()]]) fit = sf.lsqfit(scipy.asarray(matches), 'polynomial', order) w = sf.genfunc(lines, 0., fit) matches = [] for i in range(w.size): diff = abs(w[i] - STD_LINES) if diff.min() < 5. * scale: matches.append([lines[i], STD_LINES[diff.argmin()]]) fit = sf.lsqfit(scipy.asarray(matches), 'polynomial', order) lines = get_lines(x, sky, nstd=7.) w = sf.genfunc(lines, 0., fit) matches = [] for i in range(w.size): diff = abs(w[i] - STD_LINES) if diff.min() < 3. * scale: matches.append([lines[i], STD_LINES[diff.argmin()]]) fit = sf.lsqfit(scipy.asarray(matches), 'polynomial', order) return fit
def combine_xw(coords, xsoln, wsoln, xord, yord): x = coords[1].flatten() y = coords[0].flatten() newx = sf.genfunc(x, y, xsoln['back']) wave = sf.genfunc(newx, 0., wsoln) data = scipy.empty((x.size, 3)) data[:, 0] = x.copy() data[:, 1] = y.copy() data[:, 2] = wave.copy() soln = sf.lsqfit(data, 'chebyshev', xord, yord) tmp = data[:, 0].copy() data[:, 0] = data[:, 2].copy() data[:, 2] = tmp.copy() soln2 = sf.lsqfit(data, 'chebyshev', xord, yord) return {'back': soln, 'forw': soln2}
def skycorrect(p, arc, sky, arcmodel, skymodel): fit = {'coeff': scipy.atleast_2d(p[:-1]).T, 'type': 'polynomial'} w = sf.genfunc(x, 0., fit) arcm = interpolate.splev(w + p[-1], arcmodel) chi_arc = (arcm - arc) s = sky[w > 5100.] skym = interpolate.splev(w[w > 5100.], skymodel) skym *= scipy.median(s / skym) chi_sky = 5. * (skym - s) #/abs(m)**0.5 chi = scipy.concatenate((chi_arc, chi_sky)) return chi
def fitline(self, xpos): # Find local maximum to start fitting if self.solution == None: point = round(xpos) else: point = sf.genfunc(xpos, 0., self.inverse) point = point[0].round() print(point) center = self.data[point - 5:point + 6].argmax() + point - 5 print(self.data[point - 5:point + 6]) print(self.data[point - 5:point + 6].argmax()) max = self.data[center] fit = scipy.empty(4) fit[0] = 0. fit[1] = max fit[2] = 7. fit[3] = 2. fit, chi = sf.ngaussfit(self.data[center - 7:center + 8], fit) centroid = fit[2] + center - 7 print("Press enter to input wavelength") wave = float(input("Wavelength: ")) max = self.data[centroid - 2:centroid + 3].max() try: indx = self.lines.index(centroid) self.ids[indx] = wave except: self.lines.append(centroid) self.ids.append(wave) axis = self.ax.axis() fudge = 0.05 * (axis[3] - axis[2]) if self.solution == None: wave = centroid else: wave = sf.genfunc(centroid, 0., self.solution) mark = mpl.patches.Polygon([(wave, max + fudge), (wave, max + 2 * fudge)]) self.ax.add_patch(mark) self.markers[centroid] = mark pylab.draw()
def optFunc(p, x, spec, mod): if (numpy.isnan(p)).any() or p[0] < 0.5 or p[1] < 0.8 or p[1] > 1.2: return spec coeff = numpy.atleast_2d(numpy.array(p) * rescale).T fit = {'coeff': coeff, 'type': 'polynomial'} w = sf.genfunc(x, 0., fit) m = interpolate.splev(w, mod) cond = (w < 9800.) m = m[cond] m /= m.mean() resid = (spec[cond] - m) / abs(spec[cond] + m)**0.5 return resid / resid.size
def dofit(p, x, data, model): if scipy.isnan(p).any(): return x * 0. + 1e7 fit = {'coeff': scipy.atleast_2d(p[1:]).T, 'type': 'polynomial'} w = sf.genfunc(x, 0., fit) m = interpolate.splev(w, model) m *= p[0] chi = (m - data) / abs(data)**0.5 cond = ~scipy.isnan(chi) cond = cond & scipy.isfinite(chi) cond = cond & (w > cutoff) & (w < 10400.) return chi[cond] / chi[cond].size
def optfunc(pars, x, d, mod, sig): if numpy.isnan(pars).any(): return -1e200 coeff = numpy.atleast_2d(numpy.array(pars)).T fit = {'coeff': coeff, 'type': 'polynomial'} x0 = sf.genfunc(x, 0., fit) try: model = interpolate.splev(x0, mod) except: return -1e200 model /= model.mean() resid = (model - d) / sig return -0.5 * (resid**2).sum()
def id_spec(spec, model): fig = plt.figure() ax = fig.add_subplot(111) ax.fmt_xdata = plt.FormatStrFormatter('%4.2f') ax.fmt_ydata = plt.FormatStrFormatter('%4.2f') from scipy import ndimage, interpolate skymodel = model['model'] data = spec.copy() blue, red, scale = model['blue'], model['red'], model['scale'] while (red - blue) / scale < data.size: red += scale blue -= scale wave = scipy.arange(blue, red, scale) blue, red = model['blue'], model['red'] sky = interpolate.splev(wave, skymodel) sky /= sky.mean() / data.mean() plt.plot(wave, sky, c='gray') from scipy import optimize, signal corr = signal.correlate(sky, data, mode='valid') w0 = wave[corr.argmax()] p = [w0, scale, 0., 0., 1.] xvals = numpy.arange(data.size).astype(numpy.float32) def opt(p): p = numpy.array(p) n = p[-1] coeff = numpy.atleast_2d(p[:-1]).T m = {'coeff': coeff, 'type': 'polynomial'} w = sf.genfunc(xvals, 0., m) mod = n * interpolate.splev(w, skymodel) return (data - mod) / abs(data)**0.5 #coeff,ier = optimize.leastsq(opt,p,maxfev=10000,epsfcn=1e-5) #fit = {'coeff':numpy.atleast_2d(coeff[:-1]).T,'type':'polynomial'} #dwave = sf.genfunc(xvals,0.,fit) dwave = numpy.linspace(blue, red, data.size) dr = IDSpectrum(data, sky, dwave, wave, skymodel) print "dr.keyid:", dr.keyid print "dr.soln:", dr.soln x = numpy.arange(sky.size) w = sf.genfunc(x, 0., dr.soln) if dr.soln is None: dr.do_fit() xdata = dr.data.get_xdata() ydata = dr.data.get_ydata() return dr.soln
def skyopt(p, x, data, model): par = special_functions.unpack_coeff(p).tolist() wave = special_functions.genfunc(x, 0, p).astype(scipy.float64) sky = interpolate.splev(wave, model).astype(scipy.float64) ratio = scipy.median(data) / scipy.median(sky) offset = 0. par.append(ratio) par.append(offset) coeff, ier = optimize.leastsq(skyfit, par, (x, data, model, p), maxfev=100000) return special_functions.build_coeff(coeff, p), coeff[-2], coeff[-1]