def LUdecomp(a, tol=1.0e-9): n = len(a) seq = array(range(n)) # Set up scale factors s = zeros((n), type=Float64) for i in range(n): s[i] = max(abs(a[i, :])) for k in range(0, n - 1): # Row interchange, if needed p = int(argmax(abs(a[k:n, k]) / s[k:n])) + k if abs(a[p, k]) < tol: error.err("Matrix is singular") if p != k: swap.swapRows(s, k, p) swap.swapRows(a, k, p) swap.swapRows(seq, k, p) # Elimination for i in range(k + 1, n): if a[i, k] != 0.0: lam = a[i, k] / a[k, k] a[i, k + 1 : n] = a[i, k + 1 : n] - lam * a[k, k + 1 : n] a[i, k] = lam return a, seq
def gaussJordanPivot(a, tol=1.0e-9): n = len(a) seq = array(range(n)) # Set up scale factors s = zeros((n), type=Float64) for i in range(n): s[i] = max(abs(a[i, :])) for i in range(n): # Row interchange, if needed p = int(argmax(abs(a[i:n, i]) / s[i:n])) + i if abs(a[p, i]) < tol: error.err('Matrix is singular') if p != i: swap.swapRows(s, i, p) swap.swapRows(a, i, p) swap.swapRows(seq, i, p) # Elimination phase temp = a[i, i] a[i, i] = 1.0 a[i, 0:n] = a[i, 0:n] / temp for k in range(n): if k != i: temp = a[k, i] a[k, i] = 0.0 a[k, 0:n] = a[k, 0:n] - a[i, 0:n] * temp # Rearrange columns in the right sequence for i in range(n): swap.swapCols(a, i, seq[i]) swap.swapRows(seq, i, seq[i]) return a
def ddtohms(xsky, ysky, verbose=no): """ Convert sky position(s) from decimal degrees to HMS format.""" xskyh = xsky / 15. xskym = (xskyh - N.floor(xskyh)) * 60. xskys = (xskym - N.floor(xskym)) * 60. yskym = (N.abs(ysky) - N.floor(N.abs(ysky))) * 60. yskys = (yskym - N.floor(yskym)) * 60. if isinstance(xskyh, N.NumArray): rah, dech = [], [] for i in xrange(len(xskyh)): rastr = repr(int(xskyh[i])) + ':' + repr(int( xskym[i])) + ':' + repr(xskys[i]) decstr = repr(int(ysky[i])) + ':' + repr(int( yskym[i])) + ':' + repr(yskys[i]) rah.append(rastr) dech.append(decstr) if verbose: print 'RA = ', rastr, ', Dec = ', decstr else: rastr = repr(int(xskyh)) + ':' + repr(int(xskym)) + ':' + repr(xskys) decstr = repr(int(ysky)) + ':' + repr(int(yskym)) + ':' + repr(yskys) rah = rastr dech = decstr if verbose: print 'RA = ', rastr, ', Dec = ', decstr return rah, dech
def gaussJordanPivot(a,tol=1.0e-9): n = len(a) seq = array(range(n)) # Set up scale factors s = zeros((n),type=Float64) for i in range(n): s[i] = max(abs(a[i,:])) for i in range(n): # Row interchange, if needed p = int(argmax(abs(a[i:n,i])/s[i:n])) + i if abs(a[p,i]) < tol: error.err('Matrix is singular') if p != i: swap.swapRows(s,i,p) swap.swapRows(a,i,p) swap.swapRows(seq,i,p) # Elimination phase temp = a[i,i] a[i,i] = 1.0 a[i,0:n] = a[i,0:n]/temp for k in range(n): if k != i: temp = a[k,i] a[k,i] = 0.0 a[k,0:n] = a[k,0:n] - a[i,0:n]*temp # Rearrange columns in the right sequence for i in range(n): swap.swapCols(a,i,seq[i]) swap.swapRows(seq,i,seq[i]) return a
def ddtohms(xsky,ysky,verbose=no): """ Convert sky position(s) from decimal degrees to HMS format.""" xskyh = xsky /15. xskym = (xskyh - N.floor(xskyh)) * 60. xskys = (xskym - N.floor(xskym)) * 60. yskym = (N.abs(ysky) - N.floor(N.abs(ysky))) * 60. yskys = (yskym - N.floor(yskym)) * 60. if isinstance(xskyh,N.NumArray): rah,dech = [],[] for i in xrange(len(xskyh)): rastr = repr(int(xskyh[i]))+':'+repr(int(xskym[i]))+':'+repr(xskys[i]) decstr = repr(int(ysky[i]))+':'+repr(int(yskym[i]))+':'+repr(yskys[i]) rah.append(rastr) dech.append(decstr) if verbose: print 'RA = ',rastr,', Dec = ',decstr else: rastr = repr(int(xskyh))+':'+repr(int(xskym))+':'+repr(xskys) decstr = repr(int(ysky))+':'+repr(int(yskym))+':'+repr(yskys) rah = rastr dech = decstr if verbose: print 'RA = ',rastr,', Dec = ',decstr return rah,dech
def LUdecomp(a,tol=1.0e-9): n = len(a) seq = array(range(n)) # Set up scale factors s = zeros((n),type=Float64) for i in range(n): s[i] = max(abs(a[i,:])) for k in range(0,n-1): # Row interchange, if needed p = int(argmax(abs(a[k:n,k])/s[k:n])) + k if abs(a[p,k]) < tol: error.err('Matrix is singular') if p != k: swap.swapRows(s,k,p) swap.swapRows(a,k,p) swap.swapRows(seq,k,p) # Elimination for i in range(k+1,n): if a[i,k] != 0.0: lam = a[i,k]/a[k,k] a[i,k+1:n] = a[i,k+1:n] - lam*a[k,k+1:n] a[i,k] = lam return a,seq
def sharpenImage(self, image, alpha): # FIXME: support RGB images rep = image.representations()[0] height = rep.pixelsHigh() width = rep.pixelsWide() samplesPerPixel = rep.samplesPerPixel() bytesPerRow = rep.bytesPerRow() bitmapData = rep.bitmapData() # Convert the image to a numarray array size = (width, height) imgData = numarray.fromstring(datastring=bitmapData, type=numarray.UInt8, shape=size) # Convert to double and do a FFT2D G = numarray.fft.fft2d(imgData.astype(numarray.Float64)) # Compute the power spectrum SG = (numarray.abs(G)**2.) / (width * height) # KD = 0.14711 D1 = (numarray.abs(SG)**(alpha / 2.)) # Find the normalization constant KD by requiring ||D1|| <= 1 firstPass = numarray.add.reduce(D1**2) norm = math.sqrt(numarray.add.reduce(firstPass)) KD = 1. / norm D1 *= KD # Divide the fft by its power spectrum and go back to real space. F1 = G / D1 f2 = numarray.fft.inverse_fft2d(F1).real # Bring f2 into the [0, 255] range min = f2.min() if (min != 0): f2 -= min max = f2.max() if (max != 0): f2 /= max f2 *= 255. return(f2.astype(numarray.UInt8))
def find(P, p): ''' In the 2D neighbourhood P, find the point closest to p. The approach is based on the selection of a trial value Pt, from P, and discarding all values further than Pt from p. To avoid repeated sqrt calculations the discard is based on an enclosing square. ''' global lengthRemaining, trial lengthRemaining+= [[P.shape[0]]] Pz= P - p # zero based neighbourhood while len(Pz): Pt= Pz[0] # trial value Pta= N.abs(Pt) Pz= Pz[1:] pd= math.sqrt(N.dot(Pta, Pta)) # distance of p from the trial
def plot_rspgenIntegral(self, energy, inclination, phi=0, nsamp=2000): rmin = 1e-2 rmax = 30. npts = 20 rstep = num.log(rmax / rmin) / (npts - 1) radii = rmin * num.exp(rstep * num.arange(npts)) self._setPsf(energy, inclination, phi) seps = [] srcDir = SkyDir(180, 0) for i in range(nsamp): appDir = self.psf.appDir(energy, srcDir, self.scZAxis, self.scXAxis) seps.append(appDir.difference(srcDir) * 180. / num.pi) seps.sort() fraction = num.arange(nsamp, type=num.Float) / nsamp disp = plot.scatter(seps, fraction, xlog=1, xname='ROI radius', yname='enclosed Psf fraction', pointRep='Line', color='red') disp.setTitle("%s: %i MeV, %.1f deg" % (self.irfs, energy, inclination)) npred = [] resids = [] for radius in radii: npred.append( self.psf.angularIntegral(energy, inclination, phi, radius)) resids.append( num.abs( (self._interpolate(seps, fraction, radius) - npred[-1]) / npred[-1])) plot.scatter(radii, npred, pointRep='Line', oplot=1) residplot = plot.scatter(radii, resids, 'ROI radius', yname='abs(sim - npred)/npred', xlog=1, ylog=1) # Npred = Interpolator(radii, npred) ks_prob = ks2(npred, seps) plot.hline(0) residplot.setTitle("%s: %i MeV, %.1f deg\n ks prob=%.2e" % (self.irfs, energy, inclination, ks_prob[1])) return energy, inclination, ks_prob[1]
def generate_binary_structure(rank, connectivity): """Generate a binary structure for binary morphological operations. The inputs are the rank of the array to which the structure will be applied and the square of the connectivity of the structure. """ if connectivity < 1: connectivity = 1 if rank < 1: if connectivity < 1: return numarray.array(0, type = numarray.Bool) else: return numarray.array(1, type = numarray.Bool) output = numarray.zeros([3] * rank, numarray.Bool) output = numarray.abs(numarray.indices([3] * rank) - 1) output = numarray.add.reduce(output, 0) return numarray.asarray(output <= connectivity, type = numarray.Bool)
def generate_binary_structure(rank, connectivity): """Generate a binary structure for binary morphological operations. The inputs are the rank of the array to which the structure will be applied and the square of the connectivity of the structure. """ if connectivity < 1: connectivity = 1 if rank < 1: if connectivity < 1: return numarray.array(0, type=numarray.Bool) else: return numarray.array(1, type=numarray.Bool) output = numarray.zeros([3] * rank, numarray.Bool) output = numarray.abs(numarray.indices([3] * rank) - 1) output = numarray.add.reduce(output, 0) return numarray.asarray(output <= connectivity, type=numarray.Bool)
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 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 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'))