예제 #1
0
 def _fiducialYPlane(self, root, iy):
     assert isinstance(
         iy, numbers.Integral) and iy >= 0 and iy <= self.resolution
     y = 2.0 * float(iy) / float(self.resolution) - 1.0
     c, b = self.center[root], self.y[root]
     v = (c[0] + y * b[0], c[1] + y * b[1], c[2] + y * b[2])
     return geom.normalize(self.yrot[root](v, 1.0, 0.0))
예제 #2
0
 def _fiducialXPlane(self, root, ix):
     assert isinstance(
         ix, numbers.Integral) and ix >= 0 and ix <= self.resolution
     x = 2.0 * float(ix) / float(self.resolution) - 1.0
     c, b = self.center[root], self.x[root]
     v = (c[0] + x * b[0], c[1] + x * b[1], c[2] + x * b[2])
     return geom.normalize(self.xrot[root](v, 1.0, 0.0))
예제 #3
0
 def getCenter(self, pixelId):
     """Returns the center of a sky-pixel as a unit cartesian 3-vector.
     """
     root, ix, iy = self.coords(pixelId)
     xc = 2.0 * (float(ix) + 0.5) / float(self.resolution) - 1.0
     yc = 2.0 * (float(iy) + 0.5) / float(self.resolution) - 1.0
     c, x, y = self.center[root], self.x[root], self.y[root]
     return geom.normalize(
         (c[0] + xc * x[0] + yc * y[0], c[1] + xc * x[1] + yc * y[1],
          c[2] + xc * x[2] + yc * y[2]))
예제 #4
0
 def getCenter(self, pixelId):
     """Returns the center of a sky-pixel as a unit cartesian 3-vector.
     """
     root, ix, iy = self.coords(pixelId)
     xc = 2.0 * (float(ix) + 0.5) / float(self.resolution) - 1.0
     yc = 2.0 * (float(iy) + 0.5) / float(self.resolution) - 1.0
     c, x, y = self.center[root], self.x[root], self.y[root]
     return geom.normalize((c[0] + xc * x[0] + yc * y[0],
                            c[1] + xc * x[1] + yc * y[1],
                            c[2] + xc * x[2] + yc * y[2]))
예제 #5
0
def buildPoints(refFile, posFile, radius):
    """Builds test data for point within circle matches.
    """
    assert radius > 0.0 and radius < 5.0

    # Divide unit sphere into latitude angle stripes
    phiMin = -90.0
    phiMax = 90.0
    i = 0
    deltaPhi = 4.0 * radius;
    phi = phiMin
    while phi < phiMax:
        centerPhi = geom.clampPhi(max(abs(phi), abs(phi + deltaPhi)))
        deltaTheta = geom.maxAlpha(4.0 * radius, centerPhi)
        theta = 0.0
        refOutput = []
        posOutput = []
        # Divide latitude angle stripes into boxes (by longitude angle)
        while theta < 360.0 - 2.0 * deltaTheta:
            # Create a random point inside a sub-region of each box
            # such that a circle of the given radius centered on that
            # point is guaranteed not to cross the box boundaries
            if theta == 0.0:
                # make sure longitude angle wrap-around is tested
                p = pointInBox(360.0 - 0.125 * deltaTheta,
                               0.125 * deltaTheta,
                               geom.clampPhi(phi + deltaPhi * 0.38),
                               geom.clampPhi(phi + deltaPhi * 0.62))
            else:
                p = pointInBox(theta + deltaTheta * 0.38,
                               theta + deltaTheta * 0.62,
                               geom.clampPhi(phi + deltaPhi * 0.38),
                               geom.clampPhi(phi + deltaPhi * 0.62))
            refId = i
            i += 1

            # Generate matches
            numMatches = random.randint(0, MAX_MATCHES)
            pIn = pointsOnCircle(p, radius - MATCH_ACCURACY, numMatches)
            pOut = pointsOnCircle(p, radius + MATCH_ACCURACY, numMatches)
            if len(pIn) > 1:
                # shift first point inwards towards p to make it the
                # closest match
                v1 = geom.cartesianUnitVector(p)
                v2 = geom.cartesianUnitVector(pIn[0])
                v3 = geom.normalize((v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]))
                pIn[0] = geom.sphericalCoords(v3)
            matches = ' '.join(map(str, xrange(i, i + len(pIn))))
            # Write out reference position
            refOutput.append(
                (p[1], "%d,%s,%s,%s\n" % (refId, repr(p[0]), repr(p[1]), matches)))
            # Write out matching positions
            for p in pIn:
                posOutput.append(
                    (p[1], "%d,%s,%s,%d\n" % (i, repr(p[0]), repr(p[1]), refId)))
                i += 1
            # Write out positions with no matches
            for p in pOut:
                posOutput.append(
                    (p[1], "%d,%s,%s,\n" % (i, repr(p[0]), repr(p[1]))))
                i += 1
            theta += deltaTheta
        posOutput.sort()
        refOutput.sort()
        for r in refOutput:
            refFile.write(r[1])
        for p in posOutput:
            posFile.write(p[1])
        phi += deltaPhi
    refFile.flush()
    posFile.flush()
예제 #6
0
def getAllSipWcs(cursor, qsp, kind):
    """Constructs a Wcs object from each entry in the Science_Ccd_Exposure
    table. SIP distortion parameters are read in from
    Science_Ccd_Exposure_Metadata. Returns a 3-tuple with the following
    contents:

    - a mapping from sky-tiles to a list of (WCS, filter) tuples for
      overlapping science CCDs
    - a list of all (WCS, filter) tuples read in
    - a bounding circle (lsst.geom.SphericalCircle) for all science CCDs.
    """
    wcsMap = {}
    wcsList = []
    offset = 0
    centers = []
    radius = 0.0
    n = 0
    blocksize = 1000
    # An alternative would be to create WCSes from FITS metadata or FITS
    # files themselves, but these aren't always available.
    while True:
        cursor.execute("""SELECT scienceCcdExposureId, filterId,
                      raDeSys, equinox, ctype1, ctype2,
                      crpix1, crpix2, crval1, crval2,
                      cd1_1, cd1_2, cd2_1, cd2_2
               FROM Science_Ccd_Exposure LIMIT %d, %d
            """ % (offset, blocksize))
        rows = cursor.fetchall()
        if len(rows) == 0:
            break
        # For each CCD in the results, build up a metadata PropertySet
        # including SIP distortion terms and use it to obtain a WCS.
        for row in rows:
            ps = dafBase.PropertySet()
            ps.setString("RADESYS", row[2])
            ps.setDouble("EQUINOX", row[3])
            ps.setString("CTYPE1", row[4])
            ps.setString("CTYPE2", row[5])
            ps.setString("CUNIT1", "deg")
            ps.setString("CUNIT2", "deg")
            ps.setDouble("CRPIX1", row[6])
            ps.setDouble("CRPIX2", row[7])
            ps.setDouble("CRVAL1", row[8])
            ps.setDouble("CRVAL2", row[9])
            ps.setDouble("CD1_1", row[10])
            ps.setDouble("CD1_2", row[11])
            ps.setDouble("CD2_1", row[12])
            ps.setDouble("CD2_2", row[13])
            if row[4].endswith("-SIP") and row[5].endswith("-SIP"):
                cursor.execute("""
                    SELECT metadataKey, intValue
                    FROM Science_Ccd_Exposure_Metadata
                    WHERE scienceCcdExposureId = %d AND
                          intValue IS NOT NULL AND
                          metadataKey RLIKE '^[AB]P?_ORDER$'
                    """ % row[0])
                for k, v in cursor.fetchall():
                    ps.setInt(k, v)
                cursor.execute("""
                    SELECT metadataKey, doubleValue
                    FROM Science_Ccd_Exposure_Metadata
                    WHERE scienceCcdExposureId = %d AND
                          doubleValue IS NOT NULL AND
                          metadataKey RLIKE '^[AB]P?_[0-9]+_[0-9]+$'
                    """ % row[0])
                for k, v in cursor.fetchall():
                    ps.setDouble(k, v)
            wcs = afwImage.makeWcs(ps)
            wcsList.append([wcs, row[1]])
            if kind == 'imsim':
                poly = qs.imageToPolygon(wcs, 4072.0, 4000.0, 0.0)
            else:
                poly = qs.imageToPolygon(wcs, 2048.0, 4610.0, 0.0)
            bc = poly.getBoundingCircle()
            radius = max(radius, bc.getRadius())
            centers.append(geom.cartesianUnitVector(bc.getCenter()))
            pix = qsp.intersect(poly)
            for skyTile in pix:
                if skyTile in wcsMap:
                    wcsMap[skyTile].append([wcs, row[1]])
                else:
                    wcsMap[skyTile] = [[wcs, row[1]]]
        n = offset + len(rows)
        print "... %d" % n
        offset += blocksize
    x, y, z = 0.0, 0.0, 0.0
    for v in centers:
        x += v[0]
        y += v[1]
        z += v[2]
    cen = geom.normalize((x, y, z))
    r = max(geom.cartesianAngularSep(cen, v) for v in centers) + 2.0 * radius
    return wcsMap, wcsList, geom.SphericalCircle(cen, r)
예제 #7
0
def buildPoints(refFile, posFile, radius):
    """Builds test data for point within circle matches.
    """
    assert radius > 0.0 and radius < 5.0

    # Divide unit sphere into latitude angle stripes
    phiMin = -90.0
    phiMax = 90.0
    i = 0
    deltaPhi = 4.0 * radius
    phi = phiMin
    while phi < phiMax:
        centerPhi = geom.clampPhi(max(abs(phi), abs(phi + deltaPhi)))
        deltaTheta = geom.maxAlpha(4.0 * radius, centerPhi)
        theta = 0.0
        refOutput = []
        posOutput = []
        # Divide latitude angle stripes into boxes (by longitude angle)
        while theta < 360.0 - 2.0 * deltaTheta:
            # Create a random point inside a sub-region of each box
            # such that a circle of the given radius centered on that
            # point is guaranteed not to cross the box boundaries
            if theta == 0.0:
                # make sure longitude angle wrap-around is tested
                p = pointInBox(360.0 - 0.125 * deltaTheta, 0.125 * deltaTheta,
                               geom.clampPhi(phi + deltaPhi * 0.38),
                               geom.clampPhi(phi + deltaPhi * 0.62))
            else:
                p = pointInBox(theta + deltaTheta * 0.38,
                               theta + deltaTheta * 0.62,
                               geom.clampPhi(phi + deltaPhi * 0.38),
                               geom.clampPhi(phi + deltaPhi * 0.62))
            refId = i
            i += 1

            # Generate matches
            numMatches = random.randint(0, MAX_MATCHES)
            pIn = pointsOnCircle(p, radius - MATCH_ACCURACY, numMatches)
            pOut = pointsOnCircle(p, radius + MATCH_ACCURACY, numMatches)
            if len(pIn) > 1:
                # shift first point inwards towards p to make it the
                # closest match
                v1 = geom.cartesianUnitVector(p)
                v2 = geom.cartesianUnitVector(pIn[0])
                v3 = geom.normalize(
                    (v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]))
                pIn[0] = geom.sphericalCoords(v3)
            matches = ' '.join(map(str, xrange(i, i + len(pIn))))
            # Write out reference position
            refOutput.append(
                (p[1],
                 "%d,%s,%s,%s\n" % (refId, repr(p[0]), repr(p[1]), matches)))
            # Write out matching positions
            for p in pIn:
                posOutput.append(
                    (p[1],
                     "%d,%s,%s,%d\n" % (i, repr(p[0]), repr(p[1]), refId)))
                i += 1
            # Write out positions with no matches
            for p in pOut:
                posOutput.append(
                    (p[1], "%d,%s,%s,\n" % (i, repr(p[0]), repr(p[1]))))
                i += 1
            theta += deltaTheta
        posOutput.sort()
        refOutput.sort()
        for r in refOutput:
            refFile.write(r[1])
        for p in posOutput:
            posFile.write(p[1])
        phi += deltaPhi
    refFile.flush()
    posFile.flush()
예제 #8
0
 def _fiducialYPlane(self, root, iy):
     assert isinstance(iy, (int,long)) and iy >= 0 and iy <= self.resolution
     y = 2.0 * float(iy) / float(self.resolution) - 1.0
     c, b = self.center[root], self.y[root]
     v = (c[0] + y * b[0], c[1] + y * b[1], c[2] + y * b[2])
     return geom.normalize(self.yrot[root](v, 1.0, 0.0))
예제 #9
0
 def _fiducialXPlane(self, root, ix):
     assert isinstance(ix, (int,long)) and ix >= 0 and ix <= self.resolution
     x = 2.0 * float(ix) / float(self.resolution) - 1.0
     c, b = self.center[root], self.x[root]
     v = (c[0] + x * b[0], c[1] + x * b[1], c[2] + x * b[2])
     return geom.normalize(self.xrot[root](v, 1.0, 0.0))
예제 #10
0
def getAllSipWcs(cursor, qsp, kind):
    """Constructs a Wcs object from each entry in the Science_Ccd_Exposure
    table. SIP distortion parameters are read in from
    Science_Ccd_Exposure_Metadata. Returns a 3-tuple with the following
    contents:

    - a mapping from sky-tiles to a list of (WCS, filter) tuples for
      overlapping science CCDs
    - a list of all (WCS, filter) tuples read in
    - a bounding circle (lsst.geom.SphericalCircle) for all science CCDs.
    """
    wcsMap = {}
    wcsList = []
    offset = 0
    centers = []
    radius = 0.0
    n = 0
    blocksize = 1000
    # An alternative would be to create WCSes from FITS metadata or FITS
    # files themselves, but these aren't always available.
    while True:
        cursor.execute(
            """SELECT scienceCcdExposureId, filterId,
                      raDeSys, equinox, ctype1, ctype2,
                      crpix1, crpix2, crval1, crval2,
                      cd1_1, cd1_2, cd2_1, cd2_2
               FROM Science_Ccd_Exposure LIMIT %d, %d
            """ % (offset, blocksize))
        rows = cursor.fetchall()
        if len(rows) == 0:
            break
        # For each CCD in the results, build up a metadata PropertySet
        # including SIP distortion terms and use it to obtain a WCS.
        for row in rows:
            ps = dafBase.PropertySet()
            ps.setString("RADESYS", row[2])
            ps.setDouble("EQUINOX", row[3])
            ps.setString("CTYPE1", row[4])
            ps.setString("CTYPE2", row[5])
            ps.setString("CUNIT1", "deg")
            ps.setString("CUNIT2", "deg")
            ps.setDouble("CRPIX1", row[6])
            ps.setDouble("CRPIX2", row[7])
            ps.setDouble("CRVAL1", row[8])
            ps.setDouble("CRVAL2", row[9])
            ps.setDouble("CD1_1", row[10])
            ps.setDouble("CD1_2", row[11])
            ps.setDouble("CD2_1", row[12])
            ps.setDouble("CD2_2", row[13])
            if row[4].endswith("-SIP") and row[5].endswith("-SIP"):
                cursor.execute("""
                    SELECT metadataKey, intValue
                    FROM Science_Ccd_Exposure_Metadata
                    WHERE scienceCcdExposureId = %d AND
                          intValue IS NOT NULL AND
                          metadataKey RLIKE '^[AB]P?_ORDER$'
                    """ % row[0])
                for k, v in cursor.fetchall():
                    ps.setInt(k, v)
                cursor.execute("""
                    SELECT metadataKey, doubleValue
                    FROM Science_Ccd_Exposure_Metadata
                    WHERE scienceCcdExposureId = %d AND
                          doubleValue IS NOT NULL AND
                          metadataKey RLIKE '^[AB]P?_[0-9]+_[0-9]+$'
                    """ % row[0])
                for k, v in cursor.fetchall():
                    ps.setDouble(k, v)
            wcs = afwImage.makeWcs(ps)
            wcsList.append([wcs, row[1]])
            if kind == 'imsim':
                poly = qs.imageToPolygon(wcs, 4072.0, 4000.0, 0.0)
            else:
                poly = qs.imageToPolygon(wcs, 2048.0, 4610.0, 0.0)
            bc = poly.getBoundingCircle()
            radius = max(radius, bc.getRadius())
            centers.append(geom.cartesianUnitVector(bc.getCenter()))
            pix = qsp.intersect(poly)
            for skyTile in pix:
                if skyTile in wcsMap:
                    wcsMap[skyTile].append([wcs, row[1]])
                else:
                    wcsMap[skyTile] = [[wcs, row[1]]]
        n = offset + len(rows)
        print "... %d" % n
        offset += blocksize
    x, y, z = 0.0, 0.0, 0.0
    for v in centers:
        x += v[0]; y += v[1]; z += v[2]
    cen = geom.normalize((x, y, z))
    r = max(geom.cartesianAngularSep(cen, v) for v in centers) + 2.0*radius
    return wcsMap, wcsList, geom.SphericalCircle(cen, r)