Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
File: wcsutil.py Progetto: OSSOS/MOP
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
Esempio n. 6
0
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))
Esempio n. 8
0
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 
Esempio n. 9
0
 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]
Esempio n. 10
0
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)
Esempio n. 11
0
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)
Esempio n. 12
0
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)
Esempio n. 13
0
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'))