예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
파일: fitsio.py 프로젝트: fxia22/ASM_xf
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
예제 #6
0
    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
예제 #7
0
    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
예제 #8
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)
예제 #9
0
파일: wcsutil.py 프로젝트: stephengwyn/MOP
    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
예제 #10
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'))
예제 #11
0
파일: wcsutil.py 프로젝트: OSSOS/MOP
    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
예제 #12
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 = 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'))