Пример #1
0
    def fit_rotoff(self, x1, y1, x2, y2):
        """
        Fit rotation + offset (but not scale) for (x1,y1) -> (x2,y2)

        Args:
           x1,y1,x2,y2 : 1D np.arrays of coordinates in tangent plane
        """

        assert((x1.shape == y1.shape)&(x2.shape == y2.shape)&(x1.shape == x2.shape))
        n = len(x1)
        v = np.concatenate([x2, y2])
        A = np.zeros((2*n, 4))
        A[0:n, 0] = x1
        A[n:, 0]  = y1
        A[0:n, 1] = -y1
        A[n:, 1]  = x1
        A[0:n, 2] = 1
        A[n:, 2]  = 0
        A[0:n, 3] = 0
        A[n:, 3]  = 1

        ATv = A.T.dot(v)
        ATA = A.T.dot(A)
        p = np.linalg.solve(ATA, ATv)

        self.rot_deg = arctan2d(p[1], p[0])
        self.dx = p[2]
        self.dy = p[3]
        self.sxx = 1.
        self.syy = 1.
        self.sxy = 0.
Пример #2
0
def hadec2altaz(ha,dec) :
    """
     Convert HA,Dec to Altitude , Azimuth at Kitt Peak elevation

    Args:
        ha: float or 1D np.array hour angle in degrees
        dec: float or 1D np.array declination in degrees

    Returns: alt, az
        alt: float or 1D np.array altitude in degrees
        az: float or 1D np.array azimuth in degrees
    """
    sha,cha   = sincosd(ha)
    sdec,cdec = sincosd(dec)
    slat,clat = sincosd(LATITUDE)
    x = - cha * cdec * slat + sdec * clat
    y = - sha * cdec
    z = cha * cdec * clat + sdec * slat
    r = np.hypot(x, y)
    az  = arctan2d(y,x)
    alt = arctan2d(z,r)
    return alt,az
Пример #3
0
def altaz2hadec(alt,az) :
    """
     Convert Altitude, Azimuth to HA, Dec at Kitt Peak elevation

    Args:
        alt: float or 1D np.array altitude in degrees
        az: float or 1D np.array azimuth in degrees

    Returns: ha, dec
        ha: float or 1D np.array Hour Angle in degrees
        dec: float or 1D np.array Hour Angle in degrees
    """
    salt,calt = sincosd(alt)
    saz,caz   = sincosd(az)
    slat,clat = sincosd(LATITUDE)
    ha  = arctan2d( -saz*calt, -caz*slat*calt+salt*clat)
    dec = arcsind(slat*salt+clat*calt*caz)
    return ha,dec
Пример #4
0
def xy2qs(x, y):
    '''Focal tangent plane x,y -> angular q,s on curved focal surface

    Args:
        x, y: cartesian location on focal tangent plane in mm

    Returns (q, s) where q=angle in degrees; s=focal surface radial dist [mm]

    Notes: (x,y) are in the "CS5" DESI coordinate system tangent plane to
    the curved focal surface.  q is the radial angle measured counter-clockwise
    from the x-axis; s is the radial distance along the curved focal surface;
    it is *not* sqrt(x**2 + y**2).  (q,s) are the preferred coordinates for
    the DESI focal plane hardware engineering team.
    '''
    r = np.hypot(x, y)
    s = r2s(r)
    q = arctan2d(y, x)
    return q, s
Пример #5
0
    def fit(self, x1, y1, x2, y2, solid=False) :
        """
        Adjust tranformation from x1,y1 to x2,y2

        Args:
           x1,y1,x2,y2 : 1D np.arrays of coordinates in tangent plane

        Optional:
           if solid, scales are forced = 1

        Returns:
           None

        """

        if solid :
            return self.fit_rotoff(x1, y1, x2, y2)

        assert((x1.shape == y1.shape)&(x2.shape == y2.shape)&(x1.shape == x2.shape))

        # now fit simultaneously extra offset, rotation, scale
        self.nmatch=x1.size
        H=np.zeros((3,self.nmatch))
        H[0] = 1.
        H[1] = x1
        H[2] = y1
        A = H.dot(H.T)
        Ai = np.linalg.inv(A)
        ax = Ai.dot(np.sum(x2*H,axis=1))
        x2p = ax[0] + ax[1]*x1 + ax[2]*y1 # x2p = predicted x2 from x1 (=x1 after telescope pointing offset)
        ay = Ai.dot(np.sum(y2*H,axis=1))
        y2p = ay[0] + ay[1]*x1 + ay[2]*y1 # y2p = predicted y2 from y1

         # tangent plane coordinates are in radians
        self.rms = np.sqrt( np.mean( (x2-x2p)**2 + (y2-y2p)**2 ) )

        # pointing offset
        self.dx = ax[0]
        self.dy = ay[0]

        # dilatation and rotation
        # |ax1 ax2| |sxx sxy| |ca  -sa|
        # |ay1 ay2|=|syx syy|*|sa   ca|
        # ax1=sxx*ca+sxy*sa ; ax2=-sxx*sa+sxy*ca
        # ay1=syx*ca+syy*sa ; ay2=-syx*sa+syy*ca
        # ax1+ay2 = (sxx+syy)*ca
        # ay1-ax2 = (sxx+syy)*sa

        sxx_p_syy = np.hypot(ax[1]+ay[2], ay[1]-ax[2])
        sa=(ay[1]-ax[2])/sxx_p_syy
        ca=(ax[1]+ay[2])/sxx_p_syy

        if sa != 0 :
            self.rot_deg = arctan2d(sa,ca)

            sxy = sa*ax[1]+ca*ay[1] - sxx_p_syy*ca*sa
            sxx =(ax[1]-sxy*sa)/ca
            syy = (ay[1]-sxy*ca)/sa
        else :
            sxx = ax[1]
            syy = ay[2]
            sxy = ax[2]
        self.sxx = sxx
        self.syy = syy
        self.sxy = sxy
Пример #6
0
    def fit(self, x1, y1, x2, y2):
        """
        Adjust tranformation from focal plane x1,y1 to x2,y2

        Args:
           x1,y1,x2,y2 : 1D np.arrays of coordinates in tangent plane

        Returns:
           None

        """

        assert ((x1.shape == y1.shape) & (x2.shape == y2.shape) &
                (x1.shape == x2.shape))

        # first ajust an offset using spherical coordinates
        # assume fiducial pointing of telescope to convert
        # tangent plane coords to angles
        self.dha = 0.
        self.ddec = 0.
        x1t = x1 + 0.
        y1t = y1 + 0.
        ha, dec = xy2hadec(x1, y1, 0, 0)
        for _ in range(4):
            x1t, y1t = hadec2xy(ha, dec, self.dha, self.ddec)
            dx = np.mean(x2 - x1t)
            dy = np.mean(y2 - y1t)
            self.dha -= np.rad2deg(dx)
            self.ddec -= np.rad2deg(dy)
        x1t, y1t = hadec2xy(ha, dec, self.dha, self.ddec)

        # now fit simultaneously extra offset, rotation, scale
        self.nstars = x1t.size
        H = np.zeros((3, self.nstars))
        H[0] = 1.
        H[1] = x1t
        H[2] = y1t
        A = H.dot(H.T)
        Ai = np.linalg.inv(A)
        ax = Ai.dot(np.sum(x2 * H, axis=1))
        x2p = ax[0] + ax[1] * x1t + ax[
            2] * y1t  # x2p = predicted x2 from x1t (=x1 after telescope pointing offset)
        ay = Ai.dot(np.sum(y2 * H, axis=1))
        y2p = ay[0] + ay[1] * x1t + ay[2] * y1t  # y2p = predicted y2 from y1t

        # tangent plane coordinates are in radians
        rms = np.sqrt(np.mean((x2 - x2p)**2 + (y2 - y2p)**2))
        self.rms_arcsec = np.rad2deg(rms) * 3600.

        # interpret this back into telescope pointing offset, field rotation, dilatation

        # pointing offset
        # increasing gaia stars x means telescope is more to the left so tel_ha should be decreased
        # increasing gaia stars y means telescope is more to the bottom so tel_dec should be decreased
        # tangent plane coordinates are in rad
        ddha = -np.rad2deg(ax[0])
        dddec = -np.rad2deg(ay[0])

        self.dha += ddha
        self.ddec += dddec

        # dilatation and rotation
        # |ax1 ax2| |sxx sxy| |ca  -sa|
        # |ay1 ay2|=|syx syy|*|sa   ca|
        # ax1=sxx*ca+sxy*sa ; ax2=-sxx*sa+sxy*ca
        # ay1=syx*ca+syy*sa ; ay2=-syx*sa+syy*ca
        # ax1+ay2 = (sxx+syy)*ca
        # ay1-ax2 = (sxx+syy)*sa

        sxx_p_syy = np.hypot(ax[1] + ay[2], ay[1] - ax[2])
        sa = (ay[1] - ax[2]) / sxx_p_syy
        ca = (ax[1] + ay[2]) / sxx_p_syy

        self.rot_deg = arctan2d(sa, ca)

        sxy = sa * ax[1] + ca * ay[1] - sxx_p_syy * ca * sa
        sxx = (ax[1] - sxy * sa) / ca
        syy = (ay[1] - sxy * ca) / sa

        self.sxx = sxx
        self.syy = syy
        self.sxy = sxy
Пример #7
0
def getLONLAT(xyz):
    """Convert xyz into its spherical angles"""
    xyz = getNormalized(xyz)  # usually unnecessary
    return  arctan2d(xyz[1],xyz[0]) , arcsind(xyz[2])  # degrees
Пример #8
0
def uv2xy(u, v):
    s = np.hypot(u, v)
    q = arctan2d(v, u)
    x, y = qs2xy(q, s)
    return x, y