def points(self,npoints): """ compute arrays of npoints equally spaced intermediate points along the great circle. input parameter npoints is the number of points to compute. Returns lons, lats (lists with longitudes and latitudes of intermediate points in degrees). For example npoints=10 will return arrays lons,lats of 10 equally spaced points along the great circle. """ # can't do it if endpoints of great circle are antipodal, since # route is undefined. if self.antipodal: raise ValueError,'cannot compute intermediate points on a great circle whose endpoints are antipodal' d = self.distance delta = 1.0/(npoints-1) f = delta*N.arange(npoints) lat1 = self.lat1 lat2 = self.lat2 lon1 = self.lon1 lon2 = self.lon2 A = N.sin((1-f)*d)/math.sin(d) B = N.sin(f*d)/math.sin(d) x = A*math.cos(lat1)*math.cos(lon1)+B*math.cos(lat2)*math.cos(lon2) y = A*math.cos(lat1)*math.sin(lon1)+B*math.cos(lat2)*math.sin(lon2) z = A*math.sin(lat1) +B*math.sin(lat2) lats=N.arctan2(z,N.sqrt(x**2+y**2)) lons=N.arctan2(y,x) lons = map(math.degrees,lons.tolist()) lats = map(math.degrees,lats.tolist()) return lons,lats
def points(self,npoints): """ compute arrays of npoints equally spaced intermediate points along the great circle. input parameter npoints is the number of points to compute. Returns lons, lats (lists with longitudes and latitudes of intermediate points in degrees). For example npoints=10 will return arrays lons,lats of 10 equally spaced points along the great circle. """ # must ask for at least 2 points. if npoints <= 1: raise ValueError,'npoints must be greater than 1' elif npoints == 2: return [math.degrees(self.lon1),math.degrees(self.lon2)],[math.degrees(self.lat1),math.degrees(self.lat2)] # can't do it if endpoints are antipodal, since # route is undefined. if self.antipodal: raise ValueError,'cannot compute intermediate points on a great circle whose endpoints are antipodal' d = self.gcarclen delta = 1.0/(npoints-1) f = delta*N.arange(npoints) # f=0 is point 1, f=1 is point 2. incdist = self.distance/(npoints-1) lat1 = self.lat1 lat2 = self.lat2 lon1 = self.lon1 lon2 = self.lon2 # perfect sphere, use great circle formula if self.f == 0.: A = N.sin((1-f)*d)/math.sin(d) B = N.sin(f*d)/math.sin(d) x = A*math.cos(lat1)*math.cos(lon1)+B*math.cos(lat2)*math.cos(lon2) y = A*math.cos(lat1)*math.sin(lon1)+B*math.cos(lat2)*math.sin(lon2) z = A*math.sin(lat1) +B*math.sin(lat2) lats=N.arctan2(z,N.sqrt(x**2+y**2)) lons=N.arctan2(y,x) lons = map(math.degrees,lons.tolist()) lats = map(math.degrees,lats.tolist()) # use ellipsoid formulas else: latpt = self.lat1 lonpt = self.lon1 azimuth = self.azimuth12 lons = [math.degrees(lonpt)] lats = [math.degrees(latpt)] for n in range(npoints-2): latptnew,lonptnew,alpha21=vinc_pt(self.f,self.a,latpt,lonpt,azimuth,incdist) d,azimuth,a21=vinc_dist(self.f,self.a,latptnew,lonptnew,lat2,lon2) lats.append(math.degrees(latptnew)) lons.append(math.degrees(lonptnew)) latpt = latptnew; lonpt = lonptnew lons.append(math.degrees(self.lon2)) lats.append(math.degrees(self.lat2)) return lons,lats
def phaselag(spectrum, coherence, numinbin): """Compute phase lags from a cross spectrum. lag, error = phaselag(spectrum, coherence, numinbin) Inputs: spectrum: The cross spectrum. A complex array. coherence: The uncorrected coherence. numinbin: The number of raw estimates that went into each frequency bin. Outputs: lag: The phase of the input spectrum. In radians. error: The standard deviation of the lag. Also in radians. Calculated from eq. (9.52) in Bendat & Piersol 2000.""" lag = num.arctan2(spectrum.imag, spectrum.real) # eq. (9.52) in Bendat & Piersol 2000 error = num.sqrt((1 - coherence) / (2 * numinbin * coherence)) return lag, error
def xy2rd(filename, x,y,hdu = -1, hms = 0, verbose = 0): from numarray import sin,cos,arctan2,sqrt def degtorad(num): return num/180.0*numarray.pi def radtodeg(num): return num/numarray.pi * 180.0 def degtoHMS(num): mmm = int((num-int(num))*60.0) sss = ((num-int(num))*60.0-mmm)*60.0 num = `int(num)`+":"+ `mmm`+":"+`sss` return num keys = ["CRPIX1","CRPIX2","CRVAL1","CRVAL2","CD1_1","CD1_2","CD2_1","CD2_2"] CD = read_keys(filename,keys,hdu) crpix = numarray.zeros((2),numarray.Float) cd = numarray.zeros((2,2),numarray.Float) crpix[0] = CD['CRPIX1'][0] crpix[1] = CD['CRPIX2'][0] ra0 = CD['CRVAL1'][0] dec0 = CD['CRVAL2'][0] cd[0,0] = CD['CD1_1'][0] cd[0,1] = CD['CD1_2'][0] cd[1,0] = CD['CD2_1'][0] cd[1,1] = CD['CD2_2'][0] xi = cd[0, 0] * (x - crpix[0]) + cd[0, 1] * (y - crpix[1]) eta = cd[1, 0] * (x - crpix[0]) + cd[1, 1] * (y - crpix[1]) xi = degtorad(xi) eta = degtorad(eta) ra0 = degtorad(ra0) dec0 = degtorad(dec0) ra = arctan2(xi,cos(dec0)-eta*sin(dec0)) + ra0 dec = arctan2(eta*cos(dec0)+sin(dec0),sqrt((cos(dec0)-eta*sin(dec0))**2 + xi**2)) ra = radtodeg(ra)# % 360.0 # if ra < 0: ra = ra + 360.0 dec = radtodeg(dec) if (hms): return degtoHMS(ra/15.0),degtoHMS(dec) else: return ra,dec
def points(self, npoints): """ compute arrays of npoints equally spaced intermediate points along the great circle. input parameter npoints is the number of points to compute. Returns lons, lats (lists with longitudes and latitudes of intermediate points in degrees). For example npoints=10 will return arrays lons,lats of 10 equally spaced points along the great circle. """ # can't do it if endpoints of great circle are antipodal, since # route is undefined. if self.antipodal: raise ValueError, 'cannot compute intermediate points on a great circle whose endpoints are antipodal' d = self.distance delta = 1.0 / (npoints - 1) f = delta * N.arange(npoints) lat1 = self.lat1 lat2 = self.lat2 lon1 = self.lon1 lon2 = self.lon2 A = N.sin((1 - f) * d) / math.sin(d) B = N.sin(f * d) / math.sin(d) x = A * math.cos(lat1) * math.cos(lon1) + B * math.cos( lat2) * math.cos(lon2) y = A * math.cos(lat1) * math.sin(lon1) + B * math.cos( lat2) * math.sin(lon2) z = A * math.sin(lat1) + B * math.sin(lat2) lats = N.arctan2(z, N.sqrt(x**2 + y**2)) lons = N.arctan2(y, x) lons = map(math.degrees, lons.tolist()) lats = map(math.degrees, lats.tolist()) return lons, lats
def points(self, npoints): """ compute arrays of npoints equally spaced intermediate points along the great circle. input parameter npoints is the number of points to compute. Returns lons, lats (lists with longitudes and latitudes of intermediate points in degrees). For example npoints=10 will return arrays lons,lats of 10 equally spaced points along the great circle. """ # must ask for at least 2 points. if npoints <= 1: raise ValueError, 'npoints must be greater than 1' elif npoints == 2: return [math.degrees(self.lon1), math.degrees(self.lon2) ], [math.degrees(self.lat1), math.degrees(self.lat2)] # can't do it if endpoints are antipodal, since # route is undefined. if self.antipodal: raise ValueError, 'cannot compute intermediate points on a great circle whose endpoints are antipodal' d = self.gcarclen delta = 1.0 / (npoints - 1) f = delta * N.arange(npoints) # f=0 is point 1, f=1 is point 2. incdist = self.distance / (npoints - 1) lat1 = self.lat1 lat2 = self.lat2 lon1 = self.lon1 lon2 = self.lon2 # perfect sphere, use great circle formula if self.f == 0.: A = N.sin((1 - f) * d) / math.sin(d) B = N.sin(f * d) / math.sin(d) x = A * math.cos(lat1) * math.cos(lon1) + B * math.cos( lat2) * math.cos(lon2) y = A * math.cos(lat1) * math.sin(lon1) + B * math.cos( lat2) * math.sin(lon2) z = A * math.sin(lat1) + B * math.sin(lat2) lats = N.arctan2(z, N.sqrt(x**2 + y**2)) lons = N.arctan2(y, x) lons = map(math.degrees, lons.tolist()) lats = map(math.degrees, lats.tolist()) # use ellipsoid formulas else: latpt = self.lat1 lonpt = self.lon1 azimuth = self.azimuth12 lons = [math.degrees(lonpt)] lats = [math.degrees(latpt)] for n in range(npoints - 2): latptnew, lonptnew, alpha21 = vinc_pt(self.f, self.a, latpt, lonpt, azimuth, incdist) d, azimuth, a21 = vinc_dist(self.f, self.a, latptnew, lonptnew, lat2, lon2) lats.append(math.degrees(latptnew)) lons.append(math.degrees(lonptnew)) latpt = latptnew lonpt = lonptnew lons.append(math.degrees(self.lon2)) lats.append(math.degrees(self.lat2)) return lons, lats
def matchum(file1, file2, tol=10, perr=4, aerr=1.0, nmax=40, im_masks1=[], im_masks2=[], debug=0, domags=0, xrange=None, yrange=None, sigma=4, aoffset=0): '''Take the output of two sextractor runs and match up the objects with each other (find out which objects in the first file match up with objects in the second file. The routine considers a 'match' to be any two objects that are closer than tol pixels (after applying the shift). Returns a 6-tuple: (x1,y1,x2,y2,o1,o2). o1 and o2 are the ojbects numbers such that o1[i] in file 1 corresponds to o2[i] in file 2.''' NA = num.NewAxis sexdata1 = readsex(file1) sexdata2 = readsex(file2) # Use the readsex data to get arrays of the (x,y) positions x1 = num.asarray(sexdata1[0]['X_IMAGE']) y1 = num.asarray(sexdata1[0]['Y_IMAGE']) x2 = num.asarray(sexdata2[0]['X_IMAGE']) y2 = num.asarray(sexdata2[0]['Y_IMAGE']) m1 = num.asarray(sexdata1[0]['MAG_BEST']) m2 = num.asarray(sexdata2[0]['MAG_BEST']) o1 = num.asarray(sexdata1[0]['NUMBER']) o2 = num.asarray(sexdata2[0]['NUMBER']) f1 = num.asarray(sexdata1[0]['FLAGS']) f2 = num.asarray(sexdata2[0]['FLAGS']) # First, make a cut on the flags: gids = num.where(f1 < 4) x1 = x1[gids] y1 = y1[gids] m1 = m1[gids] o1 = o1[gids] gids = num.where(f2 < 4) x2 = x2[gids] y2 = y2[gids] m2 = m2[gids] o2 = o2[gids] # next, if there is a range to use: if xrange is not None and yrange is not None: cond = num.greater(x1, xrange[0])*num.less(x1,xrange[1])*\ num.greater(y1, yrange[0])*num.less(y1,yrange[1]) gids = num.where(cond) x1 = x1[gids] y1 = y1[gids] m1 = m1[gids] o1 = o1[gids] cond = num.greater(x2, xrange[0])*num.less(x2,xrange[1])*\ num.greater(y2, yrange[0])*num.less(y2,yrange[1]) gids = num.where(cond) x2 = x2[gids] y2 = y2[gids] m2 = m2[gids] o2 = o2[gids] # Use the user masks for m in im_masks1: print "applying mask (%d,%d,%d,%d)" % tuple(m) condx = num.less(x1, m[0]) + num.greater(x1, m[1]) condy = num.less(y1, m[2]) + num.greater(y1, m[3]) gids = num.where(condx + condy) x1 = x1[gids] y1 = y1[gids] m1 = m1[gids] o1 = o1[gids] for m in im_masks2: print "applying mask (%d,%d,%d,%d)" % tuple(m) condx = num.less(x2, m[0]) + num.greater(x2, m[1]) condy = num.less(y2, m[2]) + num.greater(y2, m[3]) gids = num.where(condx + condy) x2 = x2[gids] y2 = y2[gids] m2 = m2[gids] o2 = o2[gids] if nmax: if len(x1) > nmax: ids = num.argsort(m1)[0:nmax] x1 = x1[ids] y1 = y1[ids] m1 = m1[ids] o1 = o1[ids] if len(x2) > nmax: ids = num.argsort(m2)[0:nmax] x2 = x2[ids] y2 = y2[ids] m2 = m2[ids] o2 = o2[ids] if debug: print "objects in frame 1:" print o1 print "objects in frame 2:" print o2 mp = pygplot.MPlot(2, 1, device='/XWIN') p = pygplot.Plot() p.point(x1, y1) [p.label(x1[i], y1[i], "%d" % o1[i]) for i in range(len(x1))] mp.add(p) p = pygplot.Plot() p.point(x2, y2) [p.label(x2[i], y2[i], "%d" % o2[i]) for i in range(len(x2))] mp.add(p) mp.plot() mp.close() # Now, we make 2-D arrays of all the differences in x and y between each pair # of objects. e.g., dx1[n,m] is the delta-x between object n and m in file 1 and # dy2[n,m] is the y-distance between object n and m in file 2. dx1 = x1[NA, :] - x1[:, NA] dx2 = x2[NA, :] - x2[:, NA] dy1 = y1[NA, :] - y1[:, NA] dy2 = y2[NA, :] - y2[:, NA] # Same, but with angles da1 = num.arctan2(dy1, dx1) * 180 / num.pi da2 = num.arctan2(dy2, dx2) * 180 / num.pi # Same, but with absolute distances ds1 = num.sqrt(num.power(dx1, 2) + num.power(dy1, 2)) ds2 = num.sqrt(num.power(dx2, 2) + num.power(dy2, 2)) # Here's the real magic: this is a matrix of matrices (4-D). Consider 4 objects: # objects i and j in file 1 and objects m and n in file 2. dx[i,j,m,n] is the # difference between delta-xs for objects i,j in file 1 and m,n in file 2. If object # i corresponds to object m and object j corresponds to object n, this should be a small # number, irregardless of an overall shift in coordinate systems between file 1 and 2. dx = dx1[::, ::, NA, NA] - dx2[NA, NA, ::, ::] dy = dy1[::, ::, NA, NA] - dy2[NA, NA, ::, ::] da = da1[::, ::, NA, NA] - da2[NA, NA, ::, ::] + aoffset ds = ds1[::, ::, NA, NA] - ds2[NA, NA, ::, ::] # pick out close pairs. #use = num.less(dy,perr)*num.less(dx,perr)*num.less(num.abs(da),aerr) use = num.less(ds, perr) * num.less(num.abs(da), aerr) use = use.astype(num.Int32) #use = num.less(num.abs(da),perr) suse = num.add.reduce(num.add.reduce(use, 3), 1) print suse[0] guse = num.greater(suse, suse.flat.max() / 2) i = [j for j in range(x1.shape[0]) if num.sum(guse[j])] m = [num.argmax(guse[j]) for j in range(x1.shape[0]) if num.sum(guse[j])] xx0, yy0, oo0, mm0 = num.take([x1, y1, o1, m1], i, 1) xx1, yy1, oo1, mm1 = num.take([x2, y2, o2, m2], m, 1) if debug: mp = pygplot.MPlot(2, 1, device='/XWIN') p = pygplot.Plot() p.point(xx0, yy0) [p.label(xx0[i], yy0[i], "%d" % oo0[i]) for i in range(len(xx0))] mp.add(p) p = pygplot.Plot() p.point(xx1, yy1) [p.label(xx1[i], yy1[i], "%d" % oo1[i]) for i in range(len(xx1))] mp.add(p) mp.plot() mp.close() xshift, xscat = stats.bwt(xx0 - xx1) xscat = max([1.0, xscat]) yshift, yscat = stats.bwt(yy0 - yy1) yscat = max([1.0, yscat]) mshift, mscat = stats.bwt(mm0 - mm1) print "xscat = ", xscat print "yscat = ", yscat print "xshift = ", xshift print "yshift = ", yshift print "mshift = ", mshift print "mscat = ", mscat keep = num.less(num.abs(xx0-xx1-xshift),sigma*xscat)*\ num.less(num.abs(yy0-yy1-yshift),sigma*yscat) # This is a list of x,y,object# in each file. xx0, yy0, oo0, xx1, yy1, oo1 = num.compress(keep, [xx0, yy0, oo0, xx1, yy1, oo1], 1) if debug: print file1, oo0 print file2, oo1 mp = pygplot.MPlot(2, 1, device='temp.ps/CPS') p1 = pygplot.Plot() p1.point(xx0, yy0, symbol=25, color='red') for i in range(len(xx0)): p1.label(xx0[i], yy0[i], " %d" % oo0[i], color='red') mp.add(p1) p2 = pygplot.Plot() p2.point(xx1, yy1, symbol=25, color='green') for i in range(len(xx1)): p2.label(xx1[i], yy1[i], " %d" % oo1[i], color='green') mp.add(p2) mp.plot() mp.close() if domags: return (xx0, yy0, mm0, xx1, yy1, mm1, mshift, mscat, oo0, oo1) else: return (xx0, yy0, xx1, yy1, oo0, oo1)
def recenter(self): """ Reset the reference position values to correspond to the center of the reference frame. Algorithm used here developed by Colin Cox - 27-Jan-2004. """ if self.ctype1.find('TAN') < 0 or self.ctype2.find('TAN') < 0: print 'WCS.recenter() only supported for TAN projections.' raise TypeError # Check to see if WCS is already centered... if self.crpix1 == self.naxis1 / 2. and self.crpix2 == self.naxis2 / 2.: # No recentering necessary... return without changing WCS. return # This offset aligns the WCS to the center of the pixel, in accordance # with the 'align=center' option used by 'drizzle'. #_drz_off = -0.5 _drz_off = 0. _cen = (self.naxis1 / 2. + _drz_off, self.naxis2 / 2. + _drz_off) # Compute the RA and Dec for center pixel _cenrd = self.xy2rd(_cen) _cd = N.array([[self.cd11, self.cd12], [self.cd21, self.cd22]], type=N.Float64) _ra0 = DEGTORAD(self.crval1) _dec0 = DEGTORAD(self.crval2) _ra = DEGTORAD(_cenrd[0]) _dec = DEGTORAD(_cenrd[1]) # Set up some terms for use in the final result _dx = self.naxis1 / 2. - self.crpix1 _dy = self.naxis2 / 2. - self.crpix2 _dE, _dN = DEGTORAD(N.dot(_cd, (_dx, _dy))) _dE_dN = 1 + N.power(_dE, 2) + N.power(_dN, 2) _cosdec = N.cos(_dec) _sindec = N.sin(_dec) _cosdec0 = N.cos(_dec0) _sindec0 = N.sin(_dec0) _n1 = N.power(_cosdec, 2) + _dE * _dE + _dN * _dN * N.power(_sindec, 2) _dra_dE = (_cosdec0 - _dN * _sindec0) / _n1 _dra_dN = _dE * _sindec0 / _n1 _ddec_dE = -_dE * N.tan(_dec) / _dE_dN _ddec_dN = (1 / _cosdec) * ((_cosdec0 / N.sqrt(_dE_dN)) - (_dN * N.sin(_dec) / _dE_dN)) # Compute new CD matrix values now... _cd11n = _cosdec * (self.cd11 * _dra_dE + self.cd21 * _dra_dN) _cd12n = _cosdec * (self.cd12 * _dra_dE + self.cd22 * _dra_dN) _cd21n = self.cd11 * _ddec_dE + self.cd21 * _ddec_dN _cd22n = self.cd12 * _ddec_dE + self.cd22 * _ddec_dN _new_orient = RADTODEG(N.arctan2(_cd12n, _cd22n)) # Update the values now... self.crpix1 = _cen[0] self.crpix2 = _cen[1] self.crval1 = RADTODEG(_ra) self.crval2 = RADTODEG(_dec) # Keep the same plate scale, only change the orientation self.rotateCD(_new_orient) # These would update the CD matrix with the new rotation # ALONG with the new plate scale which we do not want. self.cd11 = _cd11n self.cd12 = _cd12n self.cd21 = _cd21n self.cd22 = _cd22n
def run(): # Assume circular orbits with isotropic normal vectors on circular # orbits with circular orbital velocity of 500 km/s. ntrials = 10000 nstars = int((1.0 / 3.0) * 100) gens = aorb.create_generators(7, ntrials*10) velTot = 500.0 # km/s -- velocity amplitude radTot = 2.04 # arcsec def fitfunc(p, fjac=None, vx=None, vy=None, vz=None, vxerr=None, vyerr=None, vzerr=None): irad = math.radians(p[0]) orad = math.radians(p[1]) nx = math.sin(irad) * math.cos(orad) ny = -math.sin(irad) * math.sin(orad) nz = -math.cos(irad) top = (nx*vx + ny*vy + nz*vz)**2 bot = (nx*vxerr + ny*vyerr + nz*vzerr)**2 devs = (1.0 / (len(vx) - 1.0)) * top / bot status = 0 return [status, devs.flat] # Keep track from every trial the incl, omeg, chi2, number of stars incl = na.zeros(ntrials, type=na.Float) omeg = na.zeros(ntrials, type=na.Float) chi2 = na.zeros(ntrials, type=na.Float) niter = na.zeros(ntrials) stars = na.zeros(ntrials) # Keep track of same stuff for spatial test inclPos = na.zeros(ntrials, type=na.Float) omegPos = na.zeros(ntrials, type=na.Float) chi2Pos = na.zeros(ntrials, type=na.Float) niterPos = na.zeros(ntrials) angleAvg = na.zeros(ntrials, type=na.Float) angleStd = na.zeros(ntrials, type=na.Float) for trial in range(ntrials): if ((trial % 100) == 0): print 'Trial %d' % trial x = na.zeros(nstars, type=na.Float) y = na.zeros(nstars, type=na.Float) z = na.zeros(nstars, type=na.Float) vx = na.zeros(nstars, type=na.Float) vy = na.zeros(nstars, type=na.Float) vz = na.zeros(nstars, type=na.Float) rmag = na.zeros(nstars, type=na.Float) vmag = na.zeros(nstars, type=na.Float) nx = na.zeros(nstars, type=na.Float) ny = na.zeros(nstars, type=na.Float) nz = na.zeros(nstars, type=na.Float) for ss in range(nstars): vx[ss] = gens[0].uniform(-velTot, velTot) vyTot = math.sqrt(velTot**2 - vx[ss]**2) vy[ss] = gens[1].uniform(-vyTot, vyTot) vz[ss] = math.sqrt(velTot**2 - vx[ss]**2 - vy[ss]**2) vz[ss] *= gens[2].choice([-1.0, 1.0]) x[ss] = gens[3].uniform(-radTot, radTot) yTot = math.sqrt(radTot**2 - x[ss]**2) y[ss] = gens[4].uniform(-yTot, yTot) z[ss] = math.sqrt(radTot**2 - x[ss]**2 - y[ss]**2) z[ss] *= gens[5].choice([-1.0, 1.0]) rmag[ss] = math.sqrt(x[ss]**2 + y[ss]**2 + z[ss]**2) vmag[ss] = math.sqrt(vx[ss]**2 + vy[ss]**2 + vz[ss]**2) rvec = [x[ss], y[ss], z[ss]] vvec = [vx[ss], vy[ss], vz[ss]] tmp = util.cross_product(rvec, vvec) tmp /= rmag[ss] * vmag[ss] nx[ss] = tmp[0] ny[ss] = tmp[1] nz[ss] = tmp[2] r2d = na.hypot(x, y) v2d = na.hypot(vx, vy) top = (x * vy - y * vx) jz = (x * vy - y * vx) / (r2d * v2d) djzdx = (vy * r2d * v2d - (top * v2d * x / r2d)) / (r2d * v2d)**2 djzdy = (-vx * r2d * v2d - (top * v2d * y / r2d)) / (r2d * v2d)**2 djzdvx = (-y * r2d * v2d - (top * r2d * vx / v2d)) / (r2d * v2d)**2 djzdvy = (x * r2d * v2d - (top * r2d * vy / v2d)) / (r2d * v2d)**2 xerr = na.zeros(nstars, type=na.Float) + 0.001 # arcsec yerr = na.zeros(nstars, type=na.Float) + 0.001 vxerr = na.zeros(nstars, type=na.Float) + 10.0 # km/s vyerr = na.zeros(nstars, type=na.Float) + 10.0 vzerr = na.zeros(nstars, type=na.Float) + 30.0 # km/s jzerr = na.sqrt((djzdx*xerr)**2 + (djzdy*yerr)**2 + (djzdvx*vxerr)**2 + (djzdvy*vyerr)**2) # Eliminate all stars with jz > 0 and jz/jzerr < 2 # I think these are they cuts they are doing idx = (na.where((jz < 0) & (na.abs(jz/jzerr) > 2)))[0] #idx = (na.where(jz < 0))[0] #idx = range(len(jz)) cotTheta = vz / na.sqrt(vx**2 + vy**2) phi = na.arctan2(vy, vx) # Initial guess: p0 = na.zeros(2, type=na.Float) p0[0] = gens[5].uniform(0.1, 90) # deg -- inclination p0[1] = gens[6].uniform(0.1, 360) # deg -- omega # Setup properties of each free parameter. parinfo = {'relStep':10.0, 'step':10.0, 'fixed':0, 'limits':[0.0,360.0], 'limited':[1,1], 'mpside':1} pinfo = [parinfo.copy() for i in range(len(p0))] pinfo[0]['limits'] = [0.0, 180.0] pinfo[1]['limits'] = [0.0, 360.0] # Stuff to pass into the fit function functargs = {'vx': vx[idx], 'vy': vy[idx], 'vz': vz[idx], 'vxerr':vxerr[idx], 'vyerr':vyerr[idx], 'vzerr':vzerr[idx]} m = mpfit.mpfit(fitfunc, p0, functkw=functargs, parinfo=pinfo, quiet=1) if (m.status <= 0): print 'error message = ', m.errmsg p = m.params incl[trial] = p[0] omeg[trial] = p[1] stars[trial] = len(idx) chi2[trial] = m.fnorm / (stars[trial] - len(p0)) niter[trial] = m.niter n = [math.sin(p[0]) * math.cos(p[1]), -math.sin(p[0]) * math.sin(p[1]), -math.cos(p[0])] # Now look at the angle between the best fit normal vector # from the velocity data and the true r cross v normal vector. # Take the dot product between n and nreal. angle = na.arccos(n[0]*nx + n[1]*ny + n[2]*nz) angle *= (180.0 / math.pi) # What is the average angle and std angle angleAvg[trial] = angle.mean() angleStd[trial] = angle.stddev() # print chi2[trial], chi2Pos[trial], incl[trial], inclPos[trial], \ # omeg[trial], omegPos[trial], niter[trial], niterPos[trial] # print angleAvg[trial], angleStd[trial] # Plot up chi2 for v-fit vs. chi2 for x-fit pylab.clf() pylab.semilogx(chi2, angleAvg, 'k.') pylab.errorbar(chi2, angleAvg, fmt='k.', yerr=angleStd) pylab.xlabel('Chi^2') pylab.ylabel('Angle w.r.t. Best Fit') foo = raw_input('Contine?') # Probability of encountering solution with chi^2 < 2 idx = (na.where(chi2 < 2.0))[0] print 'Prob(chi^2 < 2) = %5.3f ' % (len(idx) / float(ntrials)) # Probability of encountering solution with chi^2 < 2 AND # inclination = 20 - 30 and Omega = 160 - 170 foo = (na.where((chi2 < 2.0) & (incl > 20) & (incl < 40)))[0] print 'Prob of chi2 and incl = %5.3f' % (len(foo) / float(ntrials)) pylab.clf() pylab.subplot(2, 2, 1) pylab.hist(chi2, bins=na.arange(0, 10, 0.5)) pylab.xlabel('Log Chi^2') pylab.subplot(2, 2, 2) pylab.hist(incl[idx]) pylab.xlabel('Inclination for Chi^2 < 2') rng = pylab.axis() pylab.axis([0, 180, rng[2], rng[3]]) pylab.subplot(2, 2, 3) pylab.hist(omeg[idx]) pylab.xlabel('Omega for Chi^2 < 2') rng = pylab.axis() pylab.axis([0, 360, rng[2], rng[3]]) pylab.subplot(2, 2, 4) pylab.hist(stars[idx]) pylab.xlabel('Nstars for Chi^2 < 2') rng = pylab.axis() pylab.axis([0, 33, rng[2], rng[3]]) pylab.savefig('diskTest.png') # Pickle everything foo = {'incl': incl, 'omeg': omeg, 'star': stars, 'chi2': chi2, 'niter': niter} pickle.dump(foo, open('diskTestSave.pick', 'w'))
def recenter(self): """ Reset the reference position values to correspond to the center of the reference frame. Algorithm used here developed by Colin Cox - 27-Jan-2004. """ if self.ctype1.find('TAN') < 0 or self.ctype2.find('TAN') < 0: print 'WCS.recenter() only supported for TAN projections.' raise TypeError # Check to see if WCS is already centered... if self.crpix1 == self.naxis1/2. and self.crpix2 == self.naxis2/2.: # No recentering necessary... return without changing WCS. return # This offset aligns the WCS to the center of the pixel, in accordance # with the 'align=center' option used by 'drizzle'. #_drz_off = -0.5 _drz_off = 0. _cen = (self.naxis1/2.+ _drz_off,self.naxis2/2. + _drz_off) # Compute the RA and Dec for center pixel _cenrd = self.xy2rd(_cen) _cd = N.array([[self.cd11,self.cd12],[self.cd21,self.cd22]],type=N.Float64) _ra0 = DEGTORAD(self.crval1) _dec0 = DEGTORAD(self.crval2) _ra = DEGTORAD(_cenrd[0]) _dec = DEGTORAD(_cenrd[1]) # Set up some terms for use in the final result _dx = self.naxis1/2. - self.crpix1 _dy = self.naxis2/2. - self.crpix2 _dE,_dN = DEGTORAD(N.dot(_cd,(_dx,_dy))) _dE_dN = 1 + N.power(_dE,2) + N.power(_dN,2) _cosdec = N.cos(_dec) _sindec = N.sin(_dec) _cosdec0 = N.cos(_dec0) _sindec0 = N.sin(_dec0) _n1 = N.power(_cosdec,2) + _dE*_dE + _dN*_dN*N.power(_sindec,2) _dra_dE = (_cosdec0 - _dN*_sindec0)/_n1 _dra_dN = _dE*_sindec0 /_n1 _ddec_dE = -_dE*N.tan(_dec) / _dE_dN _ddec_dN = (1/_cosdec) * ((_cosdec0 / N.sqrt(_dE_dN)) - (_dN*N.sin(_dec) / _dE_dN)) # Compute new CD matrix values now... _cd11n = _cosdec * (self.cd11*_dra_dE + self.cd21 * _dra_dN) _cd12n = _cosdec * (self.cd12*_dra_dE + self.cd22 * _dra_dN) _cd21n = self.cd11 * _ddec_dE + self.cd21 * _ddec_dN _cd22n = self.cd12 * _ddec_dE + self.cd22 * _ddec_dN _new_orient = RADTODEG(N.arctan2(_cd12n,_cd22n)) # Update the values now... self.crpix1 = _cen[0] self.crpix2 = _cen[1] self.crval1 = RADTODEG(_ra) self.crval2 = RADTODEG(_dec) # Keep the same plate scale, only change the orientation self.rotateCD(_new_orient) # These would update the CD matrix with the new rotation # ALONG with the new plate scale which we do not want. self.cd11 = _cd11n self.cd12 = _cd12n self.cd21 = _cd21n self.cd22 = _cd22n
def run(): # Assume circular orbits with isotropic normal vectors on circular # orbits with circular orbital velocity of 500 km/s. ntrials = 10000 nstars = int((1.0 / 3.0) * 100) gens = aorb.create_generators(7, ntrials*10) velTot = 500.0 # km/s -- velocity amplitude radTot = 2.04 # arcsec def fitfunc(p, fjac=None, vx=None, vy=None, vz=None, vxerr=None, vyerr=None, vzerr=None): irad = math.radians(p[0]) orad = math.radians(p[1]) nx = math.sin(irad) * math.cos(orad) ny = -math.sin(irad) * math.sin(orad) nz = -math.cos(irad) top = (nx*vx + ny*vy + nz*vz)**2 bot = (nx*vxerr + ny*vyerr + nz*vzerr)**2 devs = (1.0 / (len(vx) - 1.0)) * top / bot status = 0 return [status, devs.flat] # Keep track from every trial the incl, omeg, chi2, number of stars incl = na.zeros(ntrials, type=na.Float) omeg = na.zeros(ntrials, type=na.Float) chi2 = na.zeros(ntrials, type=na.Float) niter = na.zeros(ntrials) stars = na.zeros(ntrials) # Keep track of same stuff for spatial test inclPos = na.zeros(ntrials, type=na.Float) omegPos = na.zeros(ntrials, type=na.Float) chi2Pos = na.zeros(ntrials, type=na.Float) niterPos = na.zeros(ntrials) angleAvg = na.zeros(ntrials, type=na.Float) angleStd = na.zeros(ntrials, type=na.Float) for trial in range(ntrials): if ((trial % 100) == 0): print('Trial %d' % trial) x = na.zeros(nstars, type=na.Float) y = na.zeros(nstars, type=na.Float) z = na.zeros(nstars, type=na.Float) vx = na.zeros(nstars, type=na.Float) vy = na.zeros(nstars, type=na.Float) vz = na.zeros(nstars, type=na.Float) rmag = na.zeros(nstars, type=na.Float) vmag = na.zeros(nstars, type=na.Float) nx = na.zeros(nstars, type=na.Float) ny = na.zeros(nstars, type=na.Float) nz = na.zeros(nstars, type=na.Float) for ss in range(nstars): vx[ss] = gens[0].uniform(-velTot, velTot) vyTot = math.sqrt(velTot**2 - vx[ss]**2) vy[ss] = gens[1].uniform(-vyTot, vyTot) vz[ss] = math.sqrt(velTot**2 - vx[ss]**2 - vy[ss]**2) vz[ss] *= gens[2].choice([-1.0, 1.0]) x[ss] = gens[3].uniform(-radTot, radTot) yTot = math.sqrt(radTot**2 - x[ss]**2) y[ss] = gens[4].uniform(-yTot, yTot) z[ss] = math.sqrt(radTot**2 - x[ss]**2 - y[ss]**2) z[ss] *= gens[5].choice([-1.0, 1.0]) rmag[ss] = math.sqrt(x[ss]**2 + y[ss]**2 + z[ss]**2) vmag[ss] = math.sqrt(vx[ss]**2 + vy[ss]**2 + vz[ss]**2) rvec = [x[ss], y[ss], z[ss]] vvec = [vx[ss], vy[ss], vz[ss]] tmp = util.cross_product(rvec, vvec) tmp /= rmag[ss] * vmag[ss] nx[ss] = tmp[0] ny[ss] = tmp[1] nz[ss] = tmp[2] r2d = na.hypot(x, y) v2d = na.hypot(vx, vy) top = (x * vy - y * vx) jz = (x * vy - y * vx) / (r2d * v2d) djzdx = (vy * r2d * v2d - (top * v2d * x / r2d)) / (r2d * v2d)**2 djzdy = (-vx * r2d * v2d - (top * v2d * y / r2d)) / (r2d * v2d)**2 djzdvx = (-y * r2d * v2d - (top * r2d * vx / v2d)) / (r2d * v2d)**2 djzdvy = (x * r2d * v2d - (top * r2d * vy / v2d)) / (r2d * v2d)**2 xerr = na.zeros(nstars, type=na.Float) + 0.001 # arcsec yerr = na.zeros(nstars, type=na.Float) + 0.001 vxerr = na.zeros(nstars, type=na.Float) + 10.0 # km/s vyerr = na.zeros(nstars, type=na.Float) + 10.0 vzerr = na.zeros(nstars, type=na.Float) + 30.0 # km/s jzerr = na.sqrt((djzdx*xerr)**2 + (djzdy*yerr)**2 + (djzdvx*vxerr)**2 + (djzdvy*vyerr)**2) # Eliminate all stars with jz > 0 and jz/jzerr < 2 # I think these are they cuts they are doing idx = (na.where((jz < 0) & (na.abs(jz/jzerr) > 2)))[0] #idx = (na.where(jz < 0))[0] #idx = range(len(jz)) cotTheta = vz / na.sqrt(vx**2 + vy**2) phi = na.arctan2(vy, vx) # Initial guess: p0 = na.zeros(2, type=na.Float) p0[0] = gens[5].uniform(0.1, 90) # deg -- inclination p0[1] = gens[6].uniform(0.1, 360) # deg -- omega # Setup properties of each free parameter. parinfo = {'relStep':10.0, 'step':10.0, 'fixed':0, 'limits':[0.0,360.0], 'limited':[1,1], 'mpside':1} pinfo = [parinfo.copy() for i in range(len(p0))] pinfo[0]['limits'] = [0.0, 180.0] pinfo[1]['limits'] = [0.0, 360.0] # Stuff to pass into the fit function functargs = {'vx': vx[idx], 'vy': vy[idx], 'vz': vz[idx], 'vxerr':vxerr[idx], 'vyerr':vyerr[idx], 'vzerr':vzerr[idx]} m = mpfit.mpfit(fitfunc, p0, functkw=functargs, parinfo=pinfo, quiet=1) if (m.status <= 0): print('error message = ', m.errmsg) p = m.params incl[trial] = p[0] omeg[trial] = p[1] stars[trial] = len(idx) chi2[trial] = m.fnorm / (stars[trial] - len(p0)) niter[trial] = m.niter n = [math.sin(p[0]) * math.cos(p[1]), -math.sin(p[0]) * math.sin(p[1]), -math.cos(p[0])] # Now look at the angle between the best fit normal vector # from the velocity data and the true r cross v normal vector. # Take the dot product between n and nreal. angle = na.arccos(n[0]*nx + n[1]*ny + n[2]*nz) angle *= (180.0 / math.pi) # What is the average angle and std angle angleAvg[trial] = angle.mean() angleStd[trial] = angle.stddev() # print chi2[trial], chi2Pos[trial], incl[trial], inclPos[trial], \ # omeg[trial], omegPos[trial], niter[trial], niterPos[trial] # print angleAvg[trial], angleStd[trial] # Plot up chi2 for v-fit vs. chi2 for x-fit pylab.clf() pylab.semilogx(chi2, angleAvg, 'k.') pylab.errorbar(chi2, angleAvg, fmt='k.', yerr=angleStd) pylab.xlabel('Chi^2') pylab.ylabel('Angle w.r.t. Best Fit') foo = input('Contine?') # Probability of encountering solution with chi^2 < 2 idx = (na.where(chi2 < 2.0))[0] print('Prob(chi^2 < 2) = %5.3f ' % (len(idx) / float(ntrials))) # Probability of encountering solution with chi^2 < 2 AND # inclination = 20 - 30 and Omega = 160 - 170 foo = (na.where((chi2 < 2.0) & (incl > 20) & (incl < 40)))[0] print('Prob of chi2 and incl = %5.3f' % (len(foo) / float(ntrials))) pylab.clf() pylab.subplot(2, 2, 1) pylab.hist(chi2, bins=na.arange(0, 10, 0.5)) pylab.xlabel('Log Chi^2') pylab.subplot(2, 2, 2) pylab.hist(incl[idx]) pylab.xlabel('Inclination for Chi^2 < 2') rng = pylab.axis() pylab.axis([0, 180, rng[2], rng[3]]) pylab.subplot(2, 2, 3) pylab.hist(omeg[idx]) pylab.xlabel('Omega for Chi^2 < 2') rng = pylab.axis() pylab.axis([0, 360, rng[2], rng[3]]) pylab.subplot(2, 2, 4) pylab.hist(stars[idx]) pylab.xlabel('Nstars for Chi^2 < 2') rng = pylab.axis() pylab.axis([0, 33, rng[2], rng[3]]) pylab.savefig('diskTest.png') # Pickle everything foo = {'incl': incl, 'omeg': omeg, 'star': stars, 'chi2': chi2, 'niter': niter} pickle.dump(foo, open('diskTestSave.pick', 'w'))