def __init__(self, x, y, xref, yref, degree, init_gx=None,init_gy=None, weights=None): ''' defines a 2d polnyomial tranformation fomr x,y -> xref,yref using Legnedre polynomials as the basis transforms are independent for x and y, of the form x' = c0_0 + c1_0 * L_1(x) + c0_1*L_1(y) + .... y' = d0_0 + d1_0 * L_1(x) + d0_1*L_1(y) + .... Note that all input coorindates will be renomalized to be on the interval of [-1:1] for fitting The evaulate function will use the same renomralization procedure ''' init_gx = check_initial_guess(init_gx) init_gy = check_initial_guess(init_gy) self.x_nc , x_norm= self.norm0(x) self.x_ncr, x_norm_ref = self.norm0(xref) self.y_nc , y_norm = self.norm0(y) self.y_ncr , y_norm_ref = self.norm0(yref) self.degree = degree p_init_x = models.Legendre2D(degree, degree,**init_gx) p_init_y = models.Legendre2D(degree, degree, **init_gy) fit_p = fitting.LinearLSQFitter() self.px = fit_p(p_init_x, x_norm, y_norm, x_norm_ref, weights=weights) self.py = fit_p(p_init_y, x_norm, y_norm, y_norm_ref, weights=weights)
def model(xdat, ydat, *args, num_sec=9, order=4): ''' does the modeling for polynomials uses the length of the arguements to decide what order of polynomials this is xdat/ydat are list of lists of positions for each mask location [[xpos1, ypos1, xerr1, yerr1], [xpos2, ypos2, xerr2, yerr2], ...] ''' arg_dict = {1:6, 2:12, 3:20, 4:30, 5:42} #check that we put in the right number of arguements assert len(args) == num_sec * 4 + arg_dict[order] #first creaate xn = [] yn = [] #now that we have corrected the individual positions for 4 parameters apply the distortion solution tdist = models.Legendre2D(order, order) tdistX.parameters = args[4*(len(xdat)-1)+5:arg_dict[order]+4*(len(xdat)-1)+5] tdistY.parameters = args[4*(len(xdat)-1)+5+arg_dict[order]:] #applies both the distortion map and the 4 parameter tranformation for i in range(len(xdat)): xn.append(args[4*i]*(np.cos(args[1+4*i])*xdat[i] - np.sin(args[1+4*i])*ydat[i]) + args[2+4*i] + tdistX.evaluate(xdat[i], ydat[i]) ) yn.append(args[4*i]*(np.sin(args[1+4*i])*xdat[i] + np.cos(args[1+4*i])*ydat[i]) + args[3+4*i] + tdistY.evaluate(xdat[i], ydat[i]) ) return xn, yn
def fit_poly_surface_2D(x_norm, y_norm, z, weights=None, polytype='chebyshev', poly_deg=5, timit=False, debug_level=0): """ Calculate 2D polynomial fit to normalized x and y values. Wrapper function for using the astropy fitting library. INPUT: 'x_norm' : x-values (pixels) of all the lines, re-normalized to [-1,+1] 'm_norm' : order numbers of all the lines, re-normalized to [-1,+1] 'z' : the 2-dim array of 'observed' values 'weights' : weights to use in the fitting 'polytype' : types of polynomials to use (either '(p)olynomial' (default), '(l)egendre', or '(c)hebyshev' are accepted) 'poly_deg' : degree of the polynomials 'timit' : boolean - do you want to measure execution run time? 'debug_level' : for debugging... OUTPUT: 'p' : coefficients of the best-fit polynomials """ if timit: start_time = time.time() if polytype.lower() in ['p', 'polynomial']: p_init = models.Polynomial2D(poly_deg) if debug_level > 0: print('OK, using standard polynomials...') elif polytype.lower() in ['c', 'chebyshev']: p_init = models.Chebyshev2D(poly_deg, poly_deg) if debug_level > 0: print('OK, using Chebyshev polynomials...') elif polytype.lower() in ['l', 'legendre']: p_init = models.Legendre2D(poly_deg, poly_deg) if debug_level > 0: print('OK, using Legendre polynomials...') else: print( "ERROR: polytype not recognised ['(P)olynomial' / '(C)hebyshev' / '(L)egendre']" ) return fit_p = fitting.LevMarLSQFitter() with warnings.catch_warnings(): # Ignore model linearity warning from the fitter warnings.simplefilter('ignore') p = fit_p(p_init, x_norm, y_norm, z, weights=weights) if timit: print('Time elapsed: ' + np.round(time.time() - start_time, 2).astype(str) + ' seconds...') return p
def generate2DLegendreModel(xo, yo, xlen, ylen, coeffs=None): ''' ''' x, y = meshgrid(linspace(-1, 1, xlen), linspace(-1, 1, ylen)) g = models.Legendre2D(xo, yo) if (coeffs is not None) & (len(g.__dict__['_parameters']) == len(coeffs)): try: g.__dict__['_parameters'] = coeffs except: pdb.set_trace() return g(x, y)
def restorefn(savfile): f = np.load(savfile) names = f.f.names pars = f.f.pars xord = f.f.xord #[0] # arrays to ints yord = f.f.yord #[0] print yord.shape d = {} for k, v in zip(names, pars): d[k] = v f = models.Legendre2D(xord, yord, **d) return f
def legendre2d(d, xo=2, yo=2, xl=None, yl=None): """ Fit a set of 2d Legendre polynomials to a 2D array. The aperture is assumed to be +-1 over each dimension. NaNs are automatically excluded from the analysis. x0 = 2 fits up to quadratic in row axis y0 = 3 fits up to cubic in column axis If xl and yl are specified, only the polynomials with orders xl[i],yl[i] are fitted, this allows for fitting only specific polynomial orders. """ #Define fitting algorithm fit_p = fitting.LinearLSQFitter() #Handle xl,yl if xl is not None and yl is not None: xo, yo = max(xl), max(yl) p_init = models.Legendre2D(xo, yo) #Set all variables to fixed for l in range(xo + 1): for m in range(yo + 1): key = 'c' + str(l) + '_' + str(m) p_init.fixed[key] = True #p_init.fixed = dict.fromkeys(p_init.fixed.iterkeys(),True) #Allow specific orders to vary for i in range(len(xl)): key = 'c' + str(xl[i]) + '_' + str(yl[i]) p_init.fixed[key] = False else: p_init = models.Legendre2D(xo, yo) sh = np.shape(d) x,y = np.meshgrid(np.linspace(-1,1,sh[1]),\ np.linspace(-1,1,sh[0])) index = ~np.isnan(d) p = fit_p(p_init, x[index], y[index], d[index]) return p(x, y), p.parameters.reshape((yo + 1, xo + 1))
m1 = p1 & p2 m2 = p3 & p4 m1.inverse = m2 return m1 test_models = [ astmodels.Identity(2), astmodels.Polynomial1D(2, c0=1, c1=2, c2=3), astmodels.Polynomial2D(1, c0_0=1, c0_1=2, c1_0=3), astmodels.Shift(2.), astmodels.Hermite1D(2, c0=2, c1=3, c2=0.5), astmodels.Legendre1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Legendre2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Hermite2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Scale(3.4), astmodels.RotateNative2Celestial(5.63, -72.5, 180), astmodels.Multiply(3), astmodels.Multiply(10 * u.m), astmodels.RotateCelestial2Native(5.63, -72.5, 180), astmodels.EulerAngleRotation(23, 14, 2.3, axes_order='xzx'), astmodels.Mapping((0, 1), n_inputs=3), astmodels.Shift(2. * u.deg), astmodels.Scale(3.4 * u.deg), astmodels.RotateNative2Celestial(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg), astmodels.RotateCelestial2Native(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg), astmodels.RotationSequence3D([1.2, 2.3, 3.4, .3], 'xyzx'), astmodels.SphericalRotationSequence([1.2, 2.3, 3.4, .3], 'xyzy'), custom_and_analytical_inverse(),
m = astmodels.Gaussian2D() m.inputs = ('a', 'b') m.outputs = ('c', ) return m test_models = [ astmodels.Identity(2), astmodels.Polynomial1D(2, c0=1, c1=2, c2=3), astmodels.Polynomial2D(1, c0_0=1, c0_1=2, c1_0=3), astmodels.Shift(2.), astmodels.Hermite1D(2, c0=2, c1=3, c2=0.5), astmodels.Legendre1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Legendre2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Hermite2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Scale(3.4), astmodels.RotateNative2Celestial(5.63, -72.5, 180), astmodels.Multiply(3), astmodels.Multiply(10 * u.m), astmodels.RotateCelestial2Native(5.63, -72.5, 180), astmodels.EulerAngleRotation(23, 14, 2.3, axes_order='xzx'), astmodels.Mapping((0, 1), n_inputs=3), astmodels.Shift(2. * u.deg), astmodels.Scale(3.4 * u.deg), astmodels.RotateNative2Celestial(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg), astmodels.RotateCelestial2Native(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg), astmodels.RotationSequence3D([1.2, 2.3, 3.4, .3], 'xyzx'), astmodels.SphericalRotationSequence([1.2, 2.3, 3.4, .3], 'xyzy'), astmodels.AiryDisk2D(amplitude=10., x_0=0.5, y_0=1.5),
p4 = astmodels.Polynomial1D(1) m1 = p1 & p2 m2 = p3 & p4 m1.inverse = m2 return m1 test_models = [ astmodels.Identity(2), astmodels.Polynomial1D(2, c0=1, c1=2, c2=3), astmodels.Polynomial2D(1, c0_0=1, c0_1=2, c1_0=3), astmodels.Shift(2.), astmodels.Hermite1D(2, c0=2, c1=3, c2=0.5), astmodels.Legendre1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Legendre2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Hermite2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Scale(3.4), astmodels.RotateNative2Celestial(5.63, -72.5, 180), astmodels.Multiply(3), astmodels.Multiply(10*u.m), astmodels.RotateCelestial2Native(5.63, -72.5, 180), astmodels.EulerAngleRotation(23, 14, 2.3, axes_order='xzx'), astmodels.Mapping((0, 1), n_inputs=3), astmodels.Shift(2.*u.deg), astmodels.Scale(3.4*u.deg), astmodels.RotateNative2Celestial(5.63*u.deg, -72.5*u.deg, 180*u.deg), astmodels.RotateCelestial2Native(5.63*u.deg, -72.5*u.deg, 180*u.deg), astmodels.RotationSequence3D([1.2, 2.3, 3.4, .3], 'xyzx'), astmodels.SphericalRotationSequence([1.2, 2.3, 3.4, .3], 'xyzy'), astmodels.AiryDisk2D(amplitude=10., x_0=0.5, y_0=1.5), astmodels.Box1D(amplitude=10., x_0=0.5, width=5.), astmodels.Box2D(amplitude=10., x_0=0.5, x_width=5., y_0=1.5, y_width=7.),
xpix = np.append(xpix,xx) order=np.append(order,np.repeat(angle,len(x))) plt.legend() plt.show() z = lam x = xpix y = order xord = 3; yord = 3 # Fit the data using astropy.modeling p_init = models.Legendre2D(x_degree=xord,y_degree=yord) fit_p = fitting.LevMarLSQFitter() with warnings.catch_warnings(): # Ignore model linearity warning from the fitter warnings.simplefilter('ignore') #*** need to define correct equation here: #p = fit_p(p_init, x, y, z) p = fit_p(p_init, x, y, z)#*y) yy = np.arange(order.min(),order.max(),0.2) nord = len(yy) xx = np.arange(0,2000,100) nx = len(xx) yyy = np.repeat(yy,nx) xxx = np.tile(xx,nord)
assert a.bounds == b.bounds assert_models_equal(a._user_inverse, b._user_inverse) MODEL_WITH_BOUNDING_BOX = astropy_models.Shift(10) MODEL_WITH_BOUNDING_BOX.bounding_box = ((1, 7), ) MODEL_WITH_USER_INVERSE = astropy_models.Shift(10) MODEL_WITH_USER_INVERSE.inverse = astropy_models.Shift(-7) MODEL_WITH_CONSTRAINTS = astropy_models.Legendre2D(x_degree=1, y_degree=1, c0_0=1, c0_1=2, c1_0=3, fixed={ "c1_0": True, "c0_1": True }, bounds={"c0_0": (-10, 10)}) SINGLE_MODELS = [ # Generic model features astropy_models.Shift(10, name="some model name"), MODEL_WITH_BOUNDING_BOX, MODEL_WITH_USER_INVERSE, MODEL_WITH_CONSTRAINTS, # astropy.modeling.functional_models astropy_models.AiryDisk2D(amplitude=10., x_0=0.5, y_0=1.5), astropy_models.Box1D(amplitude=10., x_0=0.5, width=5.),
def python_geoxytran(x_kfp, y_kfp, direction="forward"): if direction=="backward": px_backward = models.Legendre2D(6, 6, c0_0=-1.359159118077272, c1_0=0.12849509682026816, c2_0=0.00017587310282272408, c3_0=-8.214009406649863e-06, c4_0=2.0206624190921399e-07, c5_0=-2.225331028379213e-09, c6_0=1.8201097072390407e-14, c0_1=-0.0008865780983085235, c1_1=0.0002837258293901996, c2_1=-1.3953479926814954e-05, c3_1=2.6865725414225316e-07, c4_1=3.7333388292351965e-10, c5_1=8.662694037494459e-13, c6_1=-7.6802320344598e-15, c0_2=9.616027720780746e-05, c1_2=-1.5463196269995818e-05, c2_2=4.615248418093103e-07, c3_2=-9.938940430240368e-09, c4_2=7.538338883385691e-12, c5_2=-1.8016883087953452e-13, c6_2=1.6284543459178821e-15, c0_3=-2.7112157097925163e-06, c1_3=3.63691974893539e-07, c2_3=6.326334170834919e-10, c3_3=1.2045620539279474e-11, c4_3=-6.281301326529564e-13, c5_3=1.5395969945758583e-14, c6_3=-1.4203191615580046e-16, c0_4=2.487234831550635e-08, c1_4=-5.3202681529753e-09, c2_4=3.813876920246599e-12, c3_4=-4.578771786695712e-13, c4_4=2.4833675429790513e-14, c5_4=-6.278532214053127e-16, c6_4=5.932362209122972e-18, c0_5=2.6533817724685113e-10, c1_5=6.362774492493808e-14, c2_5=-5.695287662674329e-14, c3_5=7.648943667217284e-15, c4_5=-4.4244874441233506e-16, c5_5=1.1718033882619874e-17, c6_5=-1.1450561454795142e-19, c0_6=-5.252495563272626e-15, c1_6=6.498737275590606e-16, c2_6=2.2221508682832634e-16, c3_6=-4.096197448486931e-17, c4_6=2.7086424901520096e-18, c5_6=-7.787892566015997e-20, c6_6=8.028451974197805e-22) py_backward = models.Legendre2D(6, 6, c0_0=-1.3408760539296245, c1_0=-0.0014681933080717899, c2_0=6.252434078059442e-05, c3_0=-1.7794023960848901e-06, c4_0=2.0505693079301286e-08, c5_0=1.3303121908968087e-10, c6_0=4.036925907590215e-14, c0_1=0.1287659978047137, c1_1=0.0002187658143857909, c2_1=-1.1414122040749694e-05, c3_1=2.514881941931133e-07, c4_1=-4.014646650126551e-09, c5_1=4.6361664655461665e-12, c6_1=-4.2907954493018394e-14, c0_2=0.00017210509816287917, c1_2=-1.1517572721650909e-05, c2_2=4.070900780580943e-07, c3_2=-2.924032092730881e-10, c4_2=4.3651272195759074e-11, c5_2=-1.0942185864222553e-12, c6_2=1.0124374619198603e-14, c0_3=-8.927312822514692e-06, c1_3=2.178919731355544e-07, c2_3=-9.309247977587529e-09, c3_3=7.587241655284752e-11, c4_3=-4.20296301764774e-12, c5_3=1.0534116340750084e-13, c6_3=-9.745842383678927e-16, c0_4=2.3500427475161216e-07, c1_4=5.797618861500032e-10, c2_4=2.787756737792332e-11, c3_4=-3.471711550473785e-12, c4_4=1.9236825440442053e-13, c5_4=-4.82226129561789e-15, c6_4=4.4622762166743036e-17, c0_5=-2.631606790683655e-09, c1_5=1.8088697785601813e-12, c2_5=-6.029913349859671e-13, c3_5=7.51954755289406e-14, c4_5=-4.1690939247203245e-15, c5_5=1.0455627246423308e-16, c6_5=-9.679289662228309e-19, c0_6=1.1235020215574227e-14, c1_6=-1.481115941278654e-14, c2_6=4.964545148330356e-15, c3_6=-6.201605688722248e-16, c4_6=3.441248923238193e-17, c5_6=-8.635683356739731e-19, c6_6=7.999236760366155e-21) x = px_backward(x_kfp/100.0,y_kfp/100.0)*100.0 y = py_backward(x_kfp/100.0,y_kfp/100.0)*100.0 if direction=="forward": px_forward = models.Legendre2D(6, 6, c0_0=10.429995608040636, c1_0=7.669072866696911, c2_0=-0.0005171642200091058, c3_0=0.0010640118370285666, c4_0=6.591355825164487e-05, c5_0=0.0004579785406086718, c6_0=-3.381749890396372e-07, c0_1=-0.029899970699651657, c1_1=-1.0370107736602057e-05, c2_1=0.00012355149488906862, c3_1=0.0001681000870132385, c4_1=-8.915078035548195e-05, c5_1=1.0828480948981245e-06, c6_1=-3.0604028638458465e-07, c0_2=-0.0005617773576709009, c1_2=0.0021497066157591966, c2_2=0.0003159972245946561, c3_2=0.001999515078707485, c4_2=9.953809608627005e-07, c5_2=8.667245967324062e-06, c6_2=2.8043195865254592e-08, c0_3=0.0001440482443085916, c1_3=-3.4260998883389794e-05, c2_3=-0.00016054621466681272, c3_3=9.517312759587115e-07, c4_3=-4.1446577769773705e-07, c5_3=3.6262929000660604e-07, c6_3=-1.4504338440561597e-07, c0_4=0.00015388407922332725, c1_4=0.0010841802946648064, c2_4=5.000639720902258e-07, c3_4=5.927690431156899e-06, c4_4=5.991902315389979e-07, c5_4=1.7610373474546858e-06, c6_4=3.6698527469006115e-09, c0_5=-5.883225927240384e-05, c1_5=3.472735736376934e-07, c2_5=-1.0563775236811306e-06, c3_5=2.2897505242989876e-07, c4_5=-2.389407023502443e-07, c5_5=-2.7244280935829703e-09, c6_5=-2.0771844124138064e-08, c0_6=2.8762976671867224e-07, c1_6=3.2864844277261225e-06, c2_6=3.881850299314179e-07, c3_6=1.3047967293000456e-06, c4_6=1.0513711949538813e-08, c5_6=8.671289818897808e-09, c6_6=-1.760160785036003e-09) py_forward = models.Legendre2D(6, 6, c0_0=10.35865352089189, c1_0=0.029868752847050786, c2_0=-5.181441268292675e-05, c3_0=9.57356706812987e-05, c4_0=0.00017241278829382978, c5_0=-2.4675256900133155e-05, c6_0=3.95235509529886e-07, c0_1=7.66897227133641, c1_1=0.00034364965616906756, c2_1=0.0027356854767171535, c3_1=0.00042743941177974913, c4_1=0.0007837226536120123, c5_1=9.874568475762985e-07, c6_1=2.3707441689970604e-06, c0_2=0.0003489725952788292, c1_2=0.0002812999003417556, c2_2=0.0006371193460650293, c3_2=-8.6155293329177e-05, c4_2=1.6936419268906433e-06, c5_2=-3.490309288135124e-07, c6_2=4.3797605194396266e-07, c0_3=0.0007884544919103953, c1_3=0.00021149527310720538, c2_3=0.0017752319143687079, c3_3=1.4502993553656453e-06, c4_3=5.374215134624355e-06, c5_3=4.6355913497424066e-07, c6_3=9.418886502384274e-07, c0_4=9.01336941821207e-05, c1_4=-0.0001230909091922516, c2_4=2.2577487548726405e-06, c3_4=8.480105722621575e-08, c4_4=6.821359101651797e-07, c5_4=-2.7924348331191066e-07, c6_4=1.195944732829135e-08, c0_5=0.0005414644597315499, c1_5=1.1375883331712563e-06, c2_5=8.954534272097303e-06, c3_5=5.176871464493416e-07, c4_5=1.5475712624698004e-06, c5_5=1.0885690389676392e-08, c6_5=1.1381062005799344e-08, c0_6=1.4659708681089706e-07, c1_6=-6.338488221563267e-07, c2_6=2.1673413055835894e-07, c3_6=-2.8336747286630153e-07, c4_6=1.6623075723212755e-08, c5_6=1.7700444635232546e-08, c6_6=-1.7039889450896992e-09) x = px_forward(x_kfp/100.0,y_kfp/100.0)*100.0 y = py_forward(x_kfp/100.0,y_kfp/100.0)*100.0 return (x,y)