def _testFluxSlot(self, slotName): """Demonstrate that we can create & use the named Flux slot.""" schema = lsst.afw.table.SourceTable.makeMinimalSchema() baseName = "afw_Test" fluxKey = schema.addField("%s_flux" % (baseName,), type=float, doc="flux") errKey = schema.addField("%s_fluxSigma" % (baseName,), type=float, doc="flux uncertainty") flagKey = schema.addField("%s_flag" % (baseName,), type="Flag", doc="flux flag") table = lsst.afw.table.SourceTable.make(schema) # Initially, the slot is undefined. self.assertRaises(lsst.pex.exceptions.NotFoundError, getattr(table, "get%sDefinition" % (slotName,))) # After definition, it maps to the keys defined above. getattr(table, "define%s" % (slotName,))(baseName) self.assertEqual(getattr(table, "get%sDefinition" % (slotName,))(), baseName) self.assertEqual(getattr(table, "get%sKey" % (slotName,))(), fluxKey) self.assertEqual(getattr(table, "get%sErrKey" % (slotName,))(), errKey) self.assertEqual(getattr(table, "get%sFlagKey" % (slotName,))(), flagKey) # We should be able to retrieve arbitrary values set in records. record = table.makeRecord() flux, err, flag = 10.0, 1.0, False record.set(fluxKey, flux) record.set(errKey, err) record.set(flagKey, flag) self.assertEqual(getattr(record, "get%s" % (slotName,))(), flux) self.assertEqual(getattr(record, "get%sErr" % (slotName,))(), err) self.assertEqual(getattr(record, "get%sFlag" % (slotName,))(), flag) # And we should be able to delete the slot, breaking the mapping. table.schema.getAliasMap().erase("slot_%s" % (slotName,)) self.assertNotEqual(getattr(table, "get%sKey" % (slotName,))(), fluxKey) self.assertNotEqual(getattr(table, "get%sErrKey" % (slotName,))(), errKey) self.assertNotEqual(getattr(table, "get%sFlagKey" % (slotName,))(), flagKey)
def testEllipseKey(self): schema = lsst.afw.table.Schema() fKey0 = lsst.afw.table.EllipseKey.addFields( schema, "a", "ellipse", "pixel") qKey = lsst.afw.table.QuadrupoleKey(schema["a"]) pKey = lsst.afw.table.Point2DKey(schema["a"]) # we create two more equivalent functor keys, using the two different # constructors fKey1 = lsst.afw.table.EllipseKey(qKey, pKey) fKey2 = lsst.afw.table.EllipseKey(schema["a"]) # test that they're equivalent, and tha=t their constituent keys are # what we expect self.assertEqual(fKey0.getCore(), qKey) self.assertEqual(fKey1.getCore(), qKey) self.assertEqual(fKey2.getCore(), qKey) self.assertEqual(fKey0.getCenter(), pKey) self.assertEqual(fKey1.getCenter(), pKey) self.assertEqual(fKey2.getCenter(), pKey) self.assertEqual(fKey0, fKey1) self.assertEqual(fKey1, fKey2) self.assertTrue(fKey0.isValid()) self.assertTrue(fKey1.isValid()) self.assertTrue(fKey2.isValid()) # check that a default-constructed functor key is invalid fKey3 = lsst.afw.table.EllipseKey() self.assertNotEqual(fKey3, fKey1) self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the # constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(qKey, lsst.afw.geom.Quadrupole(4, 3, 1)) record.set(pKey, lsst.geom.Point2D(5, 6)) # test that the return type and value is correct self.assertIsInstance(record.get(fKey1), lsst.afw.geom.Ellipse) self.assertFloatsAlmostEqual(record.get(fKey1).getCore().getIxx(), record.get(qKey).getIxx(), rtol=1E-14) self.assertFloatsAlmostEqual(record.get(fKey1).getCore().getIyy(), record.get(qKey).getIyy(), rtol=1E-14) self.assertFloatsAlmostEqual(record.get(fKey1).getCore().getIxy(), record.get(qKey).getIxy(), rtol=1E-14) self.assertEqual(record.get(fKey1).getCenter().getX(), record.get(pKey).getX()) self.assertEqual(record.get(fKey1).getCenter().getX(), record.get(pKey).getX()) # test that we can set using the functor key e = lsst.afw.geom.Ellipse(lsst.afw.geom.Quadrupole(8, 16, 4), lsst.geom.Point2D(5, 6)) record.set(fKey1, e) self.assertFloatsAlmostEqual(record.get(fKey1).getCore().getIxx(), e.getCore().getIxx(), rtol=1E-14) self.assertFloatsAlmostEqual(record.get(fKey1).getCore().getIyy(), e.getCore().getIyy(), rtol=1E-14) self.assertFloatsAlmostEqual(record.get(fKey1).getCore().getIxy(), e.getCore().getIxy(), rtol=1E-14) self.assertEqual(record.get(fKey1).getCenter().getX(), e.getCenter().getX()) self.assertEqual(record.get(fKey1).getCenter().getX(), e.getCenter().getX())
def doTestCovarianceMatrixKeyAddFields(self, fieldType, varianceOnly, dynamicSize): names = ["x", "y"] schema = lsst.afw.table.Schema() if dynamicSize: FunctorKeyType = getattr( lsst.afw.table, "CovarianceMatrix2%sKey" % fieldType.lower()) else: FunctorKeyType = getattr( lsst.afw.table, "CovarianceMatrixX%sKey" % fieldType.lower()) fKey1 = FunctorKeyType.addFields(schema, "a", names, ["m", "s"], varianceOnly) fKey2 = FunctorKeyType.addFields(schema, "b", names, "kg", varianceOnly) self.assertEqual(schema.find("a_xSigma").field.getUnits(), "m") self.assertEqual(schema.find("a_ySigma").field.getUnits(), "s") self.assertEqual(schema.find("b_xSigma").field.getUnits(), "kg") self.assertEqual(schema.find("b_ySigma").field.getUnits(), "kg") dtype = numpy.float64 if fieldType == "D" else numpy.float32 if varianceOnly: m = numpy.diagflat(numpy.random.randn(2)**2).astype(dtype) else: self.assertEqual(schema.find("a_x_y_Cov").field.getUnits(), "m s") self.assertEqual( schema.find("b_x_y_Cov").field.getUnits(), "kg kg") v = numpy.random.randn(2, 2).astype(dtype) m = numpy.dot(v.transpose(), v) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(fKey1, m) self.assertFloatsAlmostEqual(record.get(fKey1), m, rtol=1E-6) record.set(fKey2, m * 2) self.assertFloatsAlmostEqual(record.get(fKey2), m * 2, rtol=1E-6)
def doTestCovarianceMatrixKeyAddFields(self, fieldType, varianceOnly, dynamicSize): names = ["x", "y"] schema = lsst.afw.table.Schema() if dynamicSize: FunctorKeyType = getattr( lsst.afw.table, "CovarianceMatrix2%sKey" % fieldType.lower()) else: FunctorKeyType = getattr( lsst.afw.table, "CovarianceMatrixX%sKey" % fieldType.lower()) fKey1 = FunctorKeyType.addFields( schema, "a", names, ["m", "s"], varianceOnly) fKey2 = FunctorKeyType.addFields( schema, "b", names, "kg", varianceOnly) self.assertEqual(schema.find("a_xErr").field.getUnits(), "m") self.assertEqual(schema.find("a_yErr").field.getUnits(), "s") self.assertEqual(schema.find("b_xErr").field.getUnits(), "kg") self.assertEqual(schema.find("b_yErr").field.getUnits(), "kg") dtype = numpy.float64 if fieldType == "D" else numpy.float32 if varianceOnly: m = numpy.diagflat(numpy.random.randn(2)**2).astype(dtype) else: self.assertEqual(schema.find("a_x_y_Cov").field.getUnits(), "m s") self.assertEqual(schema.find("b_x_y_Cov").field.getUnits(), "kg kg") v = numpy.random.randn(2, 2).astype(dtype) m = numpy.dot(v.transpose(), v) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(fKey1, m) self.assertFloatsAlmostEqual(record.get(fKey1), m, rtol=1E-6) record.set(fKey2, m*2) self.assertFloatsAlmostEqual(record.get(fKey2), m*2, rtol=1E-6)
def testRecordAccess(self): schema = lsst.afw.table.Schema() kB = schema.addField("fB", type="B") kU = schema.addField("fU", type="U") kI = schema.addField("fI", type="I") kL = schema.addField("fL", type="L") kF = schema.addField("fF", type="F") kD = schema.addField("fD", type="D") kAngle = schema.addField("fAngle", type="Angle") kString = schema.addField("fString", type="String", size=4) kArrayB = schema.addField("fArrayB", type="ArrayB", size=6) kArrayU = schema.addField("fArrayU", type="ArrayU", size=2) kArrayI = schema.addField("fArrayI", type="ArrayI", size=3) kArrayF = schema.addField("fArrayF", type="ArrayF", size=4) kArrayD = schema.addField("fArrayD", type="ArrayD", size=5) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() self.assertEqual(record[kB], 0) self.assertEqual(record[kU], 0) self.assertEqual(record[kI], 0) self.assertEqual(record[kL], 0) self.assertTrue(np.isnan(record[kF])) self.assertTrue(np.isnan(record[kD])) self.checkScalarAccessors(record, kB, "fB", 4, 5) self.checkScalarAccessors(record, kU, "fU", 5, 6) self.checkScalarAccessors(record, kI, "fI", 2, 3) self.checkScalarAccessors(record, kL, "fL", 2, 3) self.checkScalarAccessors(record, kF, "fF", 2.5, 3.5) self.checkScalarAccessors(record, kD, "fD", 2.5, 3.5) self.checkScalarAccessors(record, kAngle, "fAngle", 5.1*lsst.geom.degrees, -4.1*lsst.geom.degrees) self.checkScalarAccessors(record, kString, "fString", "ab", "abcd") self.checkArrayAccessors(record, kArrayB, "fArrayB", makeArray(kArrayB.getSize(), dtype=np.uint8)) self.checkArrayAccessors(record, kArrayU, "fArrayU", makeArray(kArrayU.getSize(), dtype=np.uint16)) self.checkArrayAccessors(record, kArrayI, "fArrayI", makeArray(kArrayI.getSize(), dtype=np.int32)) self.checkArrayAccessors(record, kArrayF, "fArrayF", makeArray(kArrayF.getSize(), dtype=np.float32)) self.checkArrayAccessors(record, kArrayD, "fArrayD", makeArray(kArrayD.getSize(), dtype=np.float64)) for k in (kArrayF, kArrayD): self.assertEqual(k.subfields, tuple(range(k.getSize()))) sub1 = kArrayD.slice(1, 3) sub2 = kArrayD[0:2] self.assertFloatsAlmostEqual(record.get(sub1), record.get(kArrayD)[1:3], rtol=0, atol=0) self.assertFloatsAlmostEqual(record.get(sub2), record.get(kArrayD)[0:2], rtol=0, atol=0) self.assertEqual(sub1[0], sub2[1]) self.assertIsNone(kAngle.subfields) k0a = lsst.afw.table.Key["D"]() k0b = lsst.afw.table.Key["Flag"]() with self.assertRaises(lsst.pex.exceptions.LogicError): record.get(k0a) with self.assertRaises(lsst.pex.exceptions.LogicError): record.get(k0b)
def _testFluxSlot(self, slotName): """Demonstrate that we can create & use the named Flux slot.""" schema = lsst.afw.table.SourceTable.makeMinimalSchema() baseName = "afw_Test" instFluxKey = schema.addField("%s_instFlux" % (baseName, ), type=np.float64, doc="flux") errKey = schema.addField("%s_instFluxErr" % (baseName, ), type=np.float64, doc="flux uncertainty") flagKey = schema.addField("%s_flag" % (baseName, ), type="Flag", doc="flux flag") table = lsst.afw.table.SourceTable.make(schema) # Initially, the slot is undefined. self.assertFalse( getattr(table, "get%sSlot" % (slotName, ))().isValid()) # After definition, it maps to the keys defined above. getattr(table, "define%s" % (slotName, ))(baseName) self.assertTrue(getattr(table, "get%sSlot" % (slotName, ))().isValid()) self.assertEqual( getattr(table, "get%sSlot" % (slotName, ))().getMeasKey(), instFluxKey) self.assertEqual( getattr(table, "get%sSlot" % (slotName, ))().getErrKey(), errKey) self.assertEqual( getattr(table, "get%sSlot" % (slotName, ))().getFlagKey(), flagKey) # We should be able to retrieve arbitrary values set in records. record = table.makeRecord() instFlux, err, flag = 10.0, 1.0, False record.set(instFluxKey, instFlux) record.set(errKey, err) record.set(flagKey, flag) instFluxName = slotName.replace("Flux", "InstFlux") self.assertEqual( getattr(record, "get%s" % (instFluxName, ))(), instFlux) self.assertEqual(getattr(record, "get%sErr" % (instFluxName, ))(), err) self.assertEqual(getattr(record, "get%sFlag" % (slotName, ))(), flag) # And we should be able to delete the slot, breaking the mapping. table.schema.getAliasMap().erase("slot_%s" % (slotName, )) self.assertFalse( getattr(table, "get%sSlot" % (slotName, ))().isValid()) self.assertNotEqual( getattr(table, "get%sSlot" % (slotName, ))().getMeasKey(), instFluxKey) self.assertNotEqual( getattr(table, "get%sSlot" % (slotName, ))().getErrKey(), errKey) self.assertNotEqual( getattr(table, "get%sSlot" % (slotName, ))().getFlagKey(), flagKey)
def doTestBoxKey(self, pointFieldType, functorKeyType, valueType): """Run type-parameterized tests on a Box FunctorKey. Parameters ---------- pointFieldType : `type` A FunctorKey class for the Point type of this box; one of Point2IKey or Point2DKey. functorKeyType : `type` The Box FunctorKey class to test; one of Box2IKey or Box2DKey. valueType : `type` The Box type to test; one of Box2I or Box2D. """ schema = lsst.afw.table.Schema() fKey0 = functorKeyType.addFields(schema, "a", "box", "pixel") minKey = pointFieldType(schema["a_min"]) maxKey = pointFieldType(schema["a_max"]) # we create two equivalent functor keys, using the two different constructors fKey1 = functorKeyType(minKey, maxKey) fKey2 = functorKeyType(schema["a"]) # test that they're equivalent, and that their constituent keys are what we expect self.assertEqual(fKey0.getMin(), minKey) self.assertEqual(fKey0.getMax(), maxKey) self.assertEqual(fKey1.getMin(), minKey) self.assertEqual(fKey2.getMin(), minKey) self.assertEqual(fKey1.getMax(), maxKey) self.assertEqual(fKey2.getMax(), maxKey) self.assertEqual(fKey0, fKey1) self.assertEqual(fKey1, fKey2) self.assertTrue(fKey0.isValid()) self.assertTrue(fKey1.isValid()) self.assertTrue(fKey2.isValid()) # check that a default-constructed functor key is invalid fKey3 = functorKeyType() self.assertNotEqual(fKey3, fKey1) self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(minKey, valueType.Point(2, 4)) record.set(maxKey, valueType.Point(5, 8)) # test that the return type and value is correct self.assertIsInstance(record.get(fKey1), valueType) self.assertEqual(record.get(fKey1).getMin(), record.get(minKey)) self.assertEqual(record.get(fKey1).getMax(), record.get(maxKey)) # test that we can set using the functor key b = valueType(valueType.Point(8, 16), valueType.Point(11, 20)) record.set(fKey1, b) self.assertEqual(record.get(minKey), b.getMin()) self.assertEqual(record.get(maxKey), b.getMax())
def doTestArrayKey(self, fieldType, numpyType): FunctorKeyType = getattr(lsst.afw.table, "Array%sKey" % fieldType) self.assertFalse(FunctorKeyType().isValid()) schema = lsst.afw.table.Schema() a0 = schema.addField("a_0", type=fieldType, doc="valid array element") a1 = schema.addField("a_1", type=fieldType, doc="valid array element") a2 = schema.addField("a_2", type=fieldType, doc="valid array element") b0 = schema.addField("b_0", type=fieldType, doc="invalid out-of-order array element") b2 = schema.addField("b_2", type=fieldType, doc="invalid out-of-order array element") b1 = schema.addField("b_1", type=fieldType, doc="invalid out-of-order array element") c = schema.addField("c", type="Array%s" % fieldType, doc="old-style array", size=4) k1 = FunctorKeyType([a0, a1, a2]) # construct from a vector of keys k2 = FunctorKeyType(schema["a"]) # construct from SubSchema k3 = FunctorKeyType(c) # construct from old-style Key<Array<T>> k4 = FunctorKeyType.addFields(schema, "d", "doc for d", "camels", 4) k5 = FunctorKeyType.addFields(schema, "e", "doc for e %3.1f", "camels", [2.1, 2.2]) self.assertTrue(k1.isValid()) self.assertTrue(k2.isValid()) self.assertTrue(k3.isValid()) self.assertTrue(k4.isValid()) self.assertTrue(k5.isValid()) self.assertEqual(k1, k2) # k1 and k2 point to the same underlying fields self.assertEqual(k1[2], a2) # test that we can extract an element self.assertEqual(k1[1:3], FunctorKeyType([a1, a2])) # test that we can slice ArrayKeys self.assertEqual(k1.getSize(), 3) self.assertEqual(k2.getSize(), 3) self.assertEqual(k3.getSize(), 4) self.assertEqual(k4.getSize(), 4) self.assertEqual(k5.getSize(), 2) self.assertNotEqual(k1, k3) # none of these point to the same underlying fields; self.assertNotEqual(k1, k4) # they should all be unequal self.assertNotEqual(k1, k5) self.assertEqual(schema.find(k5[0]).field.getDoc(), "doc for e 2.1") # test that the fields we added self.assertEqual(schema.find(k5[1]).field.getDoc(), "doc for e 2.2") # got the right docs self.assertRaises(IndexError, lambda k: k[1:3:2], k1) # test that invalid slices raise exceptions # test that trying to construct from a SubSchema with badly ordered fields doesn't work self.assertRaises(lsst.pex.exceptions.InvalidParameterError, FunctorKeyType, schema["b"]) # test that trying to construct from a list of keys that are not ordered doesn't work self.assertRaises(lsst.pex.exceptions.InvalidParameterError, FunctorKeyType, [b0, b1, b2]) self.assertEqual(k4, FunctorKeyType(schema["d"])) self.assertEqual(k5, FunctorKeyType(schema["e"])) # finally, we create a record, fill it with random data, and verify that get/set/__getitem__ work table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() array = numpy.random.randn(3).astype(numpyType) record.set(k1, array) self.assertClose(record.get(k1), array) self.assertClose(record.get(k2), array) self.assertClose(record[k1], array) self.assertEqual(record.get(k1).dtype, numpy.dtype(numpyType))
def testRecordAccess(self): schema = lsst.afw.table.Schema() k0 = schema.addField("f0", type="U") k1 = schema.addField("f1", type="I") k2 = schema.addField("f2", type="L") k3 = schema.addField("f3", type="F") k4 = schema.addField("f4", type="D") k10b = schema.addField("f10b", type="ArrayU", size=2) k10a = schema.addField("f10a", type="ArrayI", size=3) k10 = schema.addField("f10", type="ArrayF", size=4) k11 = schema.addField("f11", type="ArrayD", size=5) k18 = schema.addField("f18", type="Angle") schema.addField("f20", type="String", size=4) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() self.assertEqual(record[k1], 0) self.assertEqual(record[k2], 0) self.assert_(numpy.isnan(record[k3])) self.assert_(numpy.isnan(record[k4])) self.checkScalarAccessors(record, k0, "f0", 5, 6) self.checkScalarAccessors(record, k1, "f1", 2, 3) self.checkScalarAccessors(record, k2, "f2", 2, 3) self.checkScalarAccessors(record, k3, "f3", 2.5, 3.5) self.checkScalarAccessors(record, k4, "f4", 2.5, 3.5) self.checkArrayAccessors(record, k10b, "f10b", makeArray(k10b.getSize(), dtype=numpy.uint16)) self.checkArrayAccessors(record, k10a, "f10a", makeArray(k10a.getSize(), dtype=numpy.int32)) self.checkArrayAccessors(record, k10, "f10", makeArray(k10.getSize(), dtype=numpy.float32)) self.checkArrayAccessors(record, k11, "f11", makeArray(k11.getSize(), dtype=numpy.float64)) for k in (k10, k11): self.assertEqual(k.subfields, tuple(range(k.getSize()))) sub1 = k11.slice(1, 3) sub2 = k11[0:2] self.assertClose(record.get(sub1), record.get(k11)[1:3], rtol=0, atol=0) self.assertClose(record.get(sub2), record.get(k11)[0:2], rtol=0, atol=0) self.assertEqual(sub1[0], sub2[1]) self.assert_(k18.subfields is None) k0a = lsst.afw.table.Key["D"]() k0b = lsst.afw.table.Key["Flag"]() self.assertRaises(lsst.pex.exceptions.LogicError, record.get, k0a) self.assertRaises(lsst.pex.exceptions.LogicError, record.get, k0b)
def doTestArrayKey(self, fieldType, numpyType): FunctorKeyType = getattr(lsst.afw.table, "Array%sKey" % fieldType) self.assertFalse(FunctorKeyType().isValid()) schema = lsst.afw.table.Schema() a0 = schema.addField("a_0", type=fieldType, doc="valid array element") a1 = schema.addField("a_1", type=fieldType, doc="valid array element") a2 = schema.addField("a_2", type=fieldType, doc="valid array element") b0 = schema.addField("b_0", type=fieldType, doc="invalid out-of-order array element") b2 = schema.addField("b_2", type=fieldType, doc="invalid out-of-order array element") b1 = schema.addField("b_1", type=fieldType, doc="invalid out-of-order array element") c = schema.addField("c", type="Array%s" % fieldType, doc="old-style array", size=4) k1 = FunctorKeyType([a0, a1, a2]) # construct from a vector of keys k2 = FunctorKeyType(schema["a"]) # construct from SubSchema k3 = FunctorKeyType(c) # construct from old-style Key<Array<T>> k4 = FunctorKeyType.addFields(schema, "d", "doc for d", "barn", 4) k5 = FunctorKeyType.addFields(schema, "e", "doc for e %3.1f", "barn", [2.1, 2.2]) self.assertTrue(k1.isValid()) self.assertTrue(k2.isValid()) self.assertTrue(k3.isValid()) self.assertTrue(k4.isValid()) self.assertTrue(k5.isValid()) self.assertEqual(k1, k2) # k1 and k2 point to the same underlying fields self.assertEqual(k1[2], a2) # test that we can extract an element self.assertEqual(k1[1:3], FunctorKeyType([a1, a2])) # test that we can slice ArrayKeys self.assertEqual(k1.getSize(), 3) self.assertEqual(k2.getSize(), 3) self.assertEqual(k3.getSize(), 4) self.assertEqual(k4.getSize(), 4) self.assertEqual(k5.getSize(), 2) self.assertNotEqual(k1, k3) # none of these point to the same underlying fields; self.assertNotEqual(k1, k4) # they should all be unequal self.assertNotEqual(k1, k5) self.assertEqual(schema.find(k5[0]).field.getDoc(), "doc for e 2.1") # test that the fields we added self.assertEqual(schema.find(k5[1]).field.getDoc(), "doc for e 2.2") # got the right docs self.assertRaises(IndexError, lambda k: k[1:3:2], k1) # test that invalid slices raise exceptions # test that trying to construct from a SubSchema with badly ordered fields doesn't work self.assertRaises(lsst.pex.exceptions.InvalidParameterError, FunctorKeyType, schema["b"]) # test that trying to construct from a list of keys that are not ordered doesn't work self.assertRaises(lsst.pex.exceptions.InvalidParameterError, FunctorKeyType, [b0, b1, b2]) self.assertEqual(k4, FunctorKeyType(schema["d"])) self.assertEqual(k5, FunctorKeyType(schema["e"])) # finally, we create a record, fill it with random data, and verify that get/set/__getitem__ work table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() array = numpy.random.randn(3).astype(numpyType) record.set(k1, array) self.assertClose(record.get(k1), array) self.assertClose(record.get(k2), array) self.assertClose(record[k1], array) self.assertEqual(record.get(k1).dtype, numpy.dtype(numpyType))
def testQuadrupoleKey(self): schema = lsst.afw.table.Schema() fKey0 = lsst.afw.table.QuadrupoleKey.addFields( schema, "a", "moments", lsst.afw.table.CoordinateType.PIXEL) xxKey = schema.find("a_xx").key yyKey = schema.find("a_yy").key xyKey = schema.find("a_xy").key # we create two equivalent functor keys, using the two different # constructors fKey1 = lsst.afw.table.QuadrupoleKey(xxKey, yyKey, xyKey) fKey2 = lsst.afw.table.QuadrupoleKey(schema["a"]) # test that they're equivalent, and tha=t their constituent keys are # what we expect self.assertEqual(fKey0.getIxx(), xxKey) self.assertEqual(fKey1.getIxx(), xxKey) self.assertEqual(fKey2.getIxx(), xxKey) self.assertEqual(fKey0.getIyy(), yyKey) self.assertEqual(fKey1.getIyy(), yyKey) self.assertEqual(fKey2.getIyy(), yyKey) self.assertEqual(fKey0.getIxy(), xyKey) self.assertEqual(fKey1.getIxy(), xyKey) self.assertEqual(fKey2.getIxy(), xyKey) self.assertEqual(fKey0, fKey1) self.assertEqual(fKey1, fKey2) self.assertTrue(fKey0.isValid()) self.assertTrue(fKey1.isValid()) self.assertTrue(fKey2.isValid()) # check that a default-constructed functor key is invalid fKey3 = lsst.afw.table.QuadrupoleKey() self.assertNotEqual(fKey3, fKey1) self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the # constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(xxKey, 4) record.set(yyKey, 2) record.set(xyKey, 2) # test that the return type and value is correct self.assertIsInstance(record.get(fKey1), lsst.afw.geom.Quadrupole) self.assertEqual(record.get(fKey1).getIxx(), record.get(xxKey)) self.assertEqual(record.get(fKey1).getIyy(), record.get(yyKey)) self.assertEqual(record.get(fKey1).getIxy(), record.get(xyKey)) # test that we can set using the functor key p = lsst.afw.geom.Quadrupole(8, 16, 4) record.set(fKey1, p) self.assertEqual(record.get(xxKey), p.getIxx()) self.assertEqual(record.get(yyKey), p.getIyy()) self.assertEqual(record.get(xyKey), p.getIxy())
def _testFluxSlot(self, slotName): """Demonstrate that we can create & use the named Flux slot.""" schema = lsst.afw.table.SourceTable.makeMinimalSchema() baseName = "afw_Test" fluxKey = schema.addField("%s_flux" % (baseName, ), type=np.float64, doc="flux") errKey = schema.addField("%s_fluxSigma" % (baseName, ), type=np.float64, doc="flux uncertainty") flagKey = schema.addField("%s_flag" % (baseName, ), type="Flag", doc="flux flag") table = lsst.afw.table.SourceTable.make(schema) # Initially, the slot is undefined. # For some reason this doesn't work with a context manager for assertRaises self.assertRaises(lsst.pex.exceptions.NotFoundError, getattr(table, "get%sDefinition" % (slotName, ))) # After definition, it maps to the keys defined above. getattr(table, "define%s" % (slotName, ))(baseName) self.assertEqual( getattr(table, "get%sDefinition" % (slotName, ))(), baseName) self.assertEqual(getattr(table, "get%sKey" % (slotName, ))(), fluxKey) self.assertEqual( getattr(table, "get%sErrKey" % (slotName, ))(), errKey) self.assertEqual( getattr(table, "get%sFlagKey" % (slotName, ))(), flagKey) # We should be able to retrieve arbitrary values set in records. record = table.makeRecord() flux, err, flag = 10.0, 1.0, False record.set(fluxKey, flux) record.set(errKey, err) record.set(flagKey, flag) self.assertEqual(getattr(record, "get%s" % (slotName, ))(), flux) self.assertEqual(getattr(record, "get%sErr" % (slotName, ))(), err) self.assertEqual(getattr(record, "get%sFlag" % (slotName, ))(), flag) # And we should be able to delete the slot, breaking the mapping. table.schema.getAliasMap().erase("slot_%s" % (slotName, )) self.assertNotEqual( getattr(table, "get%sKey" % (slotName, ))(), fluxKey) self.assertNotEqual( getattr(table, "get%sErrKey" % (slotName, ))(), errKey) self.assertNotEqual( getattr(table, "get%sFlagKey" % (slotName, ))(), flagKey)
def testCoordKey(self): schema = lsst.afw.table.Schema() fKey0 = lsst.afw.table.CoordKey.addFields(schema, "a", "position") longKey = schema.find("a_ra").key latKey = schema.find("a_dec").key # create two equivalent functor keys using the two different # constructors fKey1 = lsst.afw.table.CoordKey(longKey, latKey) fKey2 = lsst.afw.table.CoordKey(schema["a"]) # test that they are equivalent self.assertEqual(fKey0.getRa(), longKey) self.assertEqual(fKey0.getRa(), fKey1.getRa()) self.assertEqual(fKey0.getRa(), fKey2.getRa()) self.assertEqual(fKey0.getDec(), latKey) self.assertEqual(fKey0.getDec(), fKey1.getDec()) self.assertEqual(fKey0.getDec(), fKey2.getDec()) self.assertEqual(fKey0, fKey1) self.assertEqual(fKey0, fKey2) self.assertEqual(fKey1, fKey2) # a default-constructed key is invalid fKey3 = lsst.afw.table.CoordKey() self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the # constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(longKey, lsst.afw.geom.Angle(0)) record.set(latKey, lsst.afw.geom.Angle(1)) self.assertIsInstance(record.get(fKey1), lsst.afw.coord.IcrsCoord) self.assertEqual(record.get(fKey1).getRa(), record.get(longKey)) self.assertEqual(record.get(fKey1).getDec(), record.get(latKey)) # Test that we can set using the functor key coord = lsst.afw.coord.IcrsCoord( lsst.afw.geom.Angle(0), lsst.afw.geom.Angle(1)) record.set(fKey1, coord) self.assertEqual(record.get(longKey), coord.getRa()) self.assertEqual(record.get(latKey), coord.getDec()) # Check for inequality with a different key fKey3 = lsst.afw.table.CoordKey.addFields(schema, "b", "position") self.assertNotEqual(fKey0, fKey3) # test that we can assign a non-ICRS coordinate coord = lsst.afw.coord.Coord("11:11:11", "22:22:22", 1950) record.set(fKey0, coord) self.assertNotEqual(coord.getLongitude(), record.get(fKey0).getRa()) self.assertEqual(coord.toIcrs().getRa(), record.get(fKey0).getRa()) self.assertNotEqual(coord.getLatitude(), record.get(fKey0).getDec()) self.assertEqual(coord.toIcrs().getDec(), record.get(fKey0).getDec())
def testCoordKey(self): schema = lsst.afw.table.Schema() fKey0 = lsst.afw.table.CoordKey.addFields(schema, "a", "position") longKey = schema.find("a_ra").key latKey = schema.find("a_dec").key # create two equivalent functor keys using the two different constructors fKey1 = lsst.afw.table.CoordKey(longKey, latKey) fKey2 = lsst.afw.table.CoordKey(schema["a"]) # test that they are equivalent self.assertEqual(fKey0.getRa(), longKey) self.assertEqual(fKey0.getRa(), fKey1.getRa()) self.assertEqual(fKey0.getRa(), fKey2.getRa()) self.assertEqual(fKey0.getDec(), latKey) self.assertEqual(fKey0.getDec(), fKey1.getDec()) self.assertEqual(fKey0.getDec(), fKey2.getDec()) self.assertEqual(fKey0, fKey1) self.assertEqual(fKey0, fKey2) self.assertEqual(fKey1, fKey2) # a default-constructed key is invalid fKey3 = lsst.afw.table.CoordKey() self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(longKey, lsst.afw.geom.Angle(0)) record.set(latKey, lsst.afw.geom.Angle(1)) self.assertIsInstance(record.get(fKey1), lsst.afw.coord.IcrsCoord) self.assertEqual(record.get(fKey1).getRa(), record.get(longKey)) self.assertEqual(record.get(fKey1).getDec(), record.get(latKey)) # Test that we can set using the functor key coord = lsst.afw.coord.IcrsCoord(lsst.afw.geom.Angle(0), lsst.afw.geom.Angle(1)) record.set(fKey1, coord) self.assertEqual(record.get(longKey), coord.getRa()) self.assertEqual(record.get(latKey), coord.getDec()) # Check for inequality with a different key fKey3 = lsst.afw.table.CoordKey.addFields(schema, "b", "position") self.assertNotEqual(fKey0, fKey3) # test that we can assign a non-ICRS coordinate coord = lsst.afw.coord.Coord("11:11:11", "22:22:22", 1950) record.set(fKey0, coord) self.assertNotEqual(coord.getLongitude(), record.get(fKey0).getRa()) self.assertEqual(coord.toIcrs().getRa(), record.get(fKey0).getRa()) self.assertNotEqual(coord.getLatitude(), record.get(fKey0).getDec()) self.assertEqual(coord.toIcrs().getDec(), record.get(fKey0).getDec())
def testShapeletFunctionKey(self): schema = lsst.afw.table.Schema() order = 4 k0 = lsst.shapelet.ShapeletFunctionKey.addFields(schema, "s", "shapelet function", "pixel", "count", order) k1 = lsst.shapelet.ShapeletFunctionKey(k0.getEllipse(), k0.getCoefficients()) k2 = lsst.shapelet.ShapeletFunctionKey(schema["s"]) self.assertEqual(k0, k1) self.assertEqual(k1, k2) self.assertTrue(k0.isValid()) self.assertEqual(k0.getEllipse(), lsst.afw.table.EllipseKey(schema["s"])) self.assertEqual(k0.getCoefficients(), lsst.afw.table.ArrayDKey(schema["s"])) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() s0 = self.makeRandomShapeletFunction(order=order) record.set(k0, s0) s1 = record.get(k0) self.compareShapeletFunctions(s0, s1) self.assertRaises(lsst.pex.exceptions.InvalidParameterError, record.set, k0, self.makeRandomShapeletFunction(order=3))
def testShapeletFunctionKey(self): schema = lsst.afw.table.Schema() order = 4 k0 = lsst.shapelet.ShapeletFunctionKey.addFields(schema, "s", "shapelet function", "pixels", "dn", order) k1 = lsst.shapelet.ShapeletFunctionKey(k0.getEllipse(), k0.getCoefficients()) k2 = lsst.shapelet.ShapeletFunctionKey(schema["s"]) self.assertEqual(k0, k1) self.assertEqual(k1, k2) self.assertTrue(k0.isValid()) self.assertEqual(k0.getEllipse(), lsst.afw.table.EllipseKey(schema["s"])) self.assertEqual(k0.getCoefficients(), lsst.afw.table.ArrayDKey(schema["s"])) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() s0 = self.makeRandomShapeletFunction(order=order) record.set(k0, s0) s1 = record.get(k0) self.compareShapeletFunctions(s0, s1) self.assertRaises(lsst.pex.exceptions.InvalidParameterError, record.set, k0, self.makeRandomShapeletFunction(order=3))
def doTestPointKey(self, fieldType, functorKeyType, valueType): schema = lsst.afw.table.Schema() fKey0 = functorKeyType.addFields(schema, "a", "x or y", "pixel") xKey = schema.find("a_x").key yKey = schema.find("a_y").key # we create two equivalent functor keys, using the two different # constructors fKey1 = functorKeyType(xKey, yKey) fKey2 = functorKeyType(schema["a"]) # test that they're equivalent, and that their constituent keys are # what we expect self.assertEqual(fKey0.getX(), xKey) self.assertEqual(fKey0.getY(), yKey) self.assertEqual(fKey1.getX(), xKey) self.assertEqual(fKey2.getX(), xKey) self.assertEqual(fKey1.getY(), yKey) self.assertEqual(fKey2.getY(), yKey) self.assertEqual(fKey0, fKey1) self.assertEqual(fKey1, fKey2) self.assertTrue(fKey0.isValid()) self.assertTrue(fKey1.isValid()) self.assertTrue(fKey2.isValid()) # check that a default-constructed functor key is invalid fKey3 = functorKeyType() self.assertNotEqual(fKey3, fKey1) self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the # constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(xKey, 4) record.set(yKey, 2) # test that the return type and value is correct self.assertIsInstance(record.get(fKey1), valueType) self.assertEqual(record.get(fKey1).getX(), record.get(xKey)) self.assertEqual(record.get(fKey1).getY(), record.get(yKey)) # test that we can set using the functor key p = valueType(8, 16) record.set(fKey1, p) self.assertEqual(record.get(xKey), p.getX()) self.assertEqual(record.get(yKey), p.getY())
def testMultiShapeletFunctionKey(self): schema = lsst.afw.table.Schema() msf0 = self.makeRandomMultiShapeletFunction(nComponents=3) orders = [s.getOrder() for s in msf0.getComponents()] k0 = lsst.shapelet.MultiShapeletFunctionKey.addFields(schema, "s", "shapelet function", "pixels", "dn", orders) k1 = lsst.shapelet.MultiShapeletFunctionKey([k0[i] for i in range(len(orders))]) k2 = lsst.shapelet.MultiShapeletFunctionKey(schema["s"]) self.assertEqual(k0, k1) self.assertEqual(k1, k2) self.assertTrue(k0.isValid()) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(k0, msf0) msf1 = record.get(k0) self.compareMultiShapeletFunctions(msf0, msf1) self.assertRaises(lsst.pex.exceptions.InvalidParameterError, record.set, k0, self.makeRandomMultiShapeletFunction(nComponents=4)) self.assertRaises(lsst.pex.exceptions.NotFoundError, lsst.shapelet.MultiShapeletFunctionKey, schema["a"])
def testMultiShapeletFunctionKey(self): schema = lsst.afw.table.Schema() msf0 = self.makeRandomMultiShapeletFunction(nComponents=3) orders = [s.getOrder() for s in msf0.getComponents()] k0 = lsst.shapelet.MultiShapeletFunctionKey.addFields(schema, "s", "shapelet function", "pixel", "count", orders) k1 = lsst.shapelet.MultiShapeletFunctionKey([k0[i] for i in range(len(orders))]) k2 = lsst.shapelet.MultiShapeletFunctionKey(schema["s"]) self.assertEqual(k0, k1) self.assertEqual(k1, k2) self.assertTrue(k0.isValid()) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() record.set(k0, msf0) msf1 = record.get(k0) self.compareMultiShapeletFunctions(msf0, msf1) self.assertRaises(lsst.pex.exceptions.InvalidParameterError, record.set, k0, self.makeRandomMultiShapeletFunction(nComponents=4)) self.assertRaises(lsst.pex.exceptions.NotFoundError, lsst.shapelet.MultiShapeletFunctionKey, schema["a"])
def test(self): """Test a measurement algorithm by running it on an elliptical Gaussian convolved with a circular Gaussian PSF. """ # Setup test data bbox = lsst.afw.geom.Box2I(lsst.afw.geom.Point2I(-30, -30), lsst.afw.geom.Point2I(30, 30)) exposure = lsst.afw.image.ExposureF(bbox) exposure.setPsf(lsst.afw.detection.GaussianPsf(17, 17, 1.0)) # width, height, sigma radius = 7 ellipticity = (0.3, 0.51961524227066314) # a:b = 2:1, angle = 30deg self.fillTestExposure(exposure, radius, ellipticity, noiseSigma=0.0) # we'll use a square region that covers the full postage stamp for the Footprint footprint = lsst.afw.detection.Footprint(bbox) footprint.getPeaks().push_back(lsst.afw.detection.Peak(0, 0)) # Prepare measurement machinery config = lsst.meas.algorithms.SourceMeasurementConfig() config.algorithms.names = ["shape.z08"] schema = lsst.afw.table.SourceTable.makeMinimalSchema() ms = config.makeMeasureSources(schema) table = lsst.afw.table.SourceTable.make(schema) # Measure the object record = table.makeRecord() record.setFootprint(footprint) ms.applyWithPeak(record, exposure) e1 = record.get("shape.z08.num1") / record.get("shape.z08.denom") e2 = record.get("shape.z08.num2") / record.get("shape.z08.denom") print e1, e2 # Test that the results are what we expect (should update expected values when algorithm is ready) #self.assertFalse(record.get("shape.z08.flags")) # check that failure flag is not set self.assertClose(e1, ellipticity[0]) self.assertClose(e2, ellipticity[1])
def doTestCovarianceMatrixKey(self, fieldType, parameterNames, varianceOnly, dynamicSize): schema = lsst.afw.table.Schema() sigmaKeys = [] covKeys = [] # we generate a schema with a complete set of fields for the diagonal and some (but not all) # of the covariance elements for i, pi in enumerate(parameterNames): sigmaKeys.append( schema.addField("a_%sSigma" % pi, type=fieldType, doc="uncertainty on %s" % pi)) if varianceOnly: continue # in this case we have fields for only the diagonal for pj in parameterNames[:i]: # intentionally be inconsistent about whether we store the lower or upper triangle, # and occasionally don't store anything at all; this tests that the # CovarianceMatrixKey constructor can handle all those # possibilities. r = numpy.random.rand() if r < 0.3: k = schema.addField("a_%s_%s_Cov" % (pi, pj), type=fieldType, doc="%s,%s covariance" % (pi, pj)) elif r < 0.6: k = schema.addField("a_%s_%s_Cov" % (pj, pi), type=fieldType, doc="%s,%s covariance" % (pj, pi)) else: k = lsst.afw.table.Key[fieldType]() covKeys.append(k) if dynamicSize: FunctorKeyType = getattr( lsst.afw.table, "CovarianceMatrix%d%sKey" % (len(parameterNames), fieldType.lower())) else: FunctorKeyType = getattr( lsst.afw.table, "CovarianceMatrixX%sKey" % fieldType.lower()) # construct two equivalent functor keys using the different # constructors fKey1 = FunctorKeyType(sigmaKeys, covKeys) fKey2 = FunctorKeyType(schema["a"], parameterNames) self.assertTrue(fKey1.isValid()) self.assertTrue(fKey2.isValid()) self.assertEqual(fKey1, fKey2) # verify that a default-constructed functor key is invalid fKey3 = FunctorKeyType() self.assertNotEqual(fKey3, fKey1) self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the # constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() k = 0 # we set each matrix element a two-digit number where the first digit is the row # index and the second digit is the column index. for i in range(len(parameterNames)): record.set(sigmaKeys[i], ((i + 1) * 10 + (i + 1))**0.5) if varianceOnly: continue for j in range(i): if covKeys[k].isValid(): record.set(covKeys[k], (i + 1) * 10 + (j + 1)) k += 1 # test that the return type and value is correct matrix1 = record.get(fKey1) matrix2 = record.get(fKey2) # we use assertFloatsAlmostEqual because it can handle matrices, and because square root # in Python might not be exactly reversible with squaring in C++ (with possibly # different precision). self.assertFloatsAlmostEqual(matrix1, matrix2) k = 0 for i in range(len(parameterNames)): self.assertFloatsAlmostEqual(matrix1[i, i], (i + 1) * 10 + (i + 1), rtol=1E-7) if varianceOnly: continue for j in range(i): if covKeys[k].isValid(): self.assertFloatsAlmostEqual(matrix1[i, j], (i + 1) * 10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual(matrix2[i, j], (i + 1) * 10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual(matrix1[j, i], (i + 1) * 10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual(matrix2[j, i], (i + 1) * 10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual(fKey1.getElement( record, i, j), (i + 1) * 10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual(fKey2.getElement( record, i, j), (i + 1) * 10 + (j + 1), rtol=1E-7) v = numpy.random.randn() fKey1.setElement(record, i, j, v) self.assertFloatsAlmostEqual(fKey2.getElement( record, i, j), v, rtol=1E-7) fKey2.setElement(record, i, j, (i + 1) * 10 + (j + 1)) else: with self.assertRaises(lsst.pex.exceptions.LogicError): fKey1.setElement(record, i, j, 0.0) k += 1
def testRecordAccess(self): schema = lsst.afw.table.Schema() k0 = schema.addField("f0", type="U") k1 = schema.addField("f1", type="I") k2 = schema.addField("f2", type="L") k3 = schema.addField("f3", type="F") k4 = schema.addField("f4", type="D") k5 = schema.addField("f5", type="PointI") k7 = schema.addField("f7", type="PointD") k9 = schema.addField("f9", type="MomentsD") k10b = schema.addField("f10b", type="ArrayU", size=2) k10a = schema.addField("f10a", type="ArrayI", size=3) k10 = schema.addField("f10", type="ArrayF", size=4) k11 = schema.addField("f11", type="ArrayD", size=5) k12 = schema.addField("f12", type="CovF", size=3) k14 = schema.addField("f14", type="CovPointF") k16 = schema.addField("f16", type="CovMomentsF") k18 = schema.addField("f18", type="Angle") k19 = schema.addField("f19", type="Coord") k20 = schema.addField("f20", type="String", size=4) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() self.assertEqual(record[k1], 0) self.assertEqual(record[k2], 0) self.assert_(numpy.isnan(record[k3])) self.assert_(numpy.isnan(record[k4])) self.assertEqual(record.get(k5), lsst.afw.geom.Point2I()) self.assert_(numpy.isnan(record[k7.getX()])) self.assert_(numpy.isnan(record[k7.getY()])) self.checkScalarAccessors(record, k0, "f0", 5, 6) self.checkScalarAccessors(record, k1, "f1", 2, 3) self.checkScalarAccessors(record, k2, "f2", 2, 3) self.checkScalarAccessors(record, k3, "f3", 2.5, 3.5) self.checkScalarAccessors(record, k4, "f4", 2.5, 3.5) self.checkGeomAccessors(record, k5, "f5", lsst.afw.geom.Point2I(5, 3)) self.checkGeomAccessors(record, k7, "f7", lsst.afw.geom.Point2D(5.5, 3.5)) for k in (k5, k7): self.assertEqual(k.subfields, ("x", "y")) self.checkGeomAccessors(record, k9, "f9", lsst.afw.geom.ellipses.Quadrupole(5.5, 3.5, -1.0)) self.assertEqual(k9.subfields, ("xx", "yy", "xy")) self.checkArrayAccessors(record, k10b, "f10b", makeArray(k10b.getSize(), dtype=numpy.uint16)) self.checkArrayAccessors(record, k10a, "f10a", makeArray(k10a.getSize(), dtype=numpy.int32)) self.checkArrayAccessors(record, k10, "f10", makeArray(k10.getSize(), dtype=numpy.float32)) self.checkArrayAccessors(record, k11, "f11", makeArray(k11.getSize(), dtype=numpy.float64)) for k in (k10, k11): self.assertEqual(k.subfields, tuple(range(k.getSize()))) self.checkArrayAccessors(record, k12, "f12", makeCov(k12.getSize(), dtype=numpy.float32)) self.checkArrayAccessors(record, k14, "f14", makeCov(k14.getSize(), dtype=numpy.float32)) self.checkArrayAccessors(record, k16, "f16", makeCov(k16.getSize(), dtype=numpy.float32)) sub1 = k11.slice(1, 3) sub2 = k11[0:2] self.assert_((record.get(sub1) == record.get(k11)[1:3]).all()) self.assert_((record.get(sub2) == record.get(k11)[0:2]).all()) self.assertEqual(sub1[0], sub2[1]) for k in (k12, k14, k16): n = 0 for idx, subkey in zip(k.subfields, k.subkeys): self.assertEqual(k[idx], subkey) n += 1 self.assertEqual(n, k.getElementCount()) self.checkGeomAccessors(record, k18, "f18", lsst.afw.geom.Angle(1.2)) self.assert_(k18.subfields is None) self.checkGeomAccessors( record, k19, "f19", lsst.afw.coord.IcrsCoord(lsst.afw.geom.Angle(1.3), lsst.afw.geom.Angle(0.5)) ) self.assertEqual(k19.subfields, ("ra", "dec")) self.checkScalarAccessors(record, k20, "f20", "foo", "bar") k0a = lsst.afw.table.Key["D"]() k0b = lsst.afw.table.Key["Flag"]() lsst.utils.tests.assertRaisesLsstCpp(self, lsst.pex.exceptions.LogicErrorException, record.get, k0a) lsst.utils.tests.assertRaisesLsstCpp(self, lsst.pex.exceptions.LogicErrorException, record.get, k0b)
def testRecordAccess(self): schema = lsst.afw.table.Schema() kB = schema.addField("fB", type="B") kU = schema.addField("fU", type="U") kI = schema.addField("fI", type="I") kL = schema.addField("fL", type="L") kF = schema.addField("fF", type="F") kD = schema.addField("fD", type="D") kAngle = schema.addField("fAngle", type="Angle") kString = schema.addField("fString", type="String", size=4) kArrayB = schema.addField("fArrayB", type="ArrayB", size=6) kArrayU = schema.addField("fArrayU", type="ArrayU", size=2) kArrayI = schema.addField("fArrayI", type="ArrayI", size=3) kArrayF = schema.addField("fArrayF", type="ArrayF", size=4) kArrayD = schema.addField("fArrayD", type="ArrayD", size=5) table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() self.assertEqual(record[kB], 0) self.assertEqual(record[kU], 0) self.assertEqual(record[kI], 0) self.assertEqual(record[kL], 0) self.assertTrue(np.isnan(record[kF])) self.assertTrue(np.isnan(record[kD])) self.checkScalarAccessors(record, kB, "fB", 4, 5) self.checkScalarAccessors(record, kU, "fU", 5, 6) self.checkScalarAccessors(record, kI, "fI", 2, 3) self.checkScalarAccessors(record, kL, "fL", 2, 3) self.checkScalarAccessors(record, kF, "fF", 2.5, 3.5) self.checkScalarAccessors(record, kD, "fD", 2.5, 3.5) self.checkScalarAccessors(record, kAngle, "fAngle", 5.1 * lsst.geom.degrees, -4.1 * lsst.geom.degrees) self.checkScalarAccessors(record, kString, "fString", "ab", "abcd") self.checkArrayAccessors(record, kArrayB, "fArrayB", makeArray(kArrayB.getSize(), dtype=np.uint8)) self.checkArrayAccessors(record, kArrayU, "fArrayU", makeArray(kArrayU.getSize(), dtype=np.uint16)) self.checkArrayAccessors(record, kArrayI, "fArrayI", makeArray(kArrayI.getSize(), dtype=np.int32)) self.checkArrayAccessors( record, kArrayF, "fArrayF", makeArray(kArrayF.getSize(), dtype=np.float32)) self.checkArrayAccessors( record, kArrayD, "fArrayD", makeArray(kArrayD.getSize(), dtype=np.float64)) for k in (kArrayF, kArrayD): self.assertEqual(k.subfields, tuple(range(k.getSize()))) sub1 = kArrayD.slice(1, 3) sub2 = kArrayD[0:2] self.assertFloatsAlmostEqual(record.get(sub1), record.get(kArrayD)[1:3], rtol=0, atol=0) self.assertFloatsAlmostEqual(record.get(sub2), record.get(kArrayD)[0:2], rtol=0, atol=0) self.assertEqual(sub1[0], sub2[1]) self.assertIsNone(kAngle.subfields) k0a = lsst.afw.table.Key["D"]() k0b = lsst.afw.table.Key["Flag"]() with self.assertRaises(lsst.pex.exceptions.LogicError): record.get(k0a) with self.assertRaises(lsst.pex.exceptions.LogicError): record.get(k0b)
def doTestCovarianceMatrixKey(self, fieldType, parameterNames, varianceOnly, dynamicSize): schema = lsst.afw.table.Schema() sigmaKeys = [] covKeys = [] # we generate a schema with a complete set of fields for the diagonal and some (but not all) # of the covariance elements for i, pi in enumerate(parameterNames): sigmaKeys.append(schema.addField("a_%sErr" % pi, type=fieldType, doc="uncertainty on %s" % pi)) if varianceOnly: continue # in this case we have fields for only the diagonal for pj in parameterNames[:i]: # intentionally be inconsistent about whether we store the lower or upper triangle, # and occasionally don't store anything at all; this tests that the # CovarianceMatrixKey constructor can handle all those # possibilities. r = numpy.random.rand() if r < 0.3: k = schema.addField("a_%s_%s_Cov" % (pi, pj), type=fieldType, doc="%s,%s covariance" % (pi, pj)) elif r < 0.6: k = schema.addField("a_%s_%s_Cov" % (pj, pi), type=fieldType, doc="%s,%s covariance" % (pj, pi)) else: k = lsst.afw.table.Key[fieldType]() covKeys.append(k) if dynamicSize: FunctorKeyType = getattr(lsst.afw.table, "CovarianceMatrix%d%sKey" % (len(parameterNames), fieldType.lower())) else: FunctorKeyType = getattr(lsst.afw.table, "CovarianceMatrixX%sKey" % fieldType.lower()) # construct two equivalent functor keys using the different # constructors fKey1 = FunctorKeyType(sigmaKeys, covKeys) fKey2 = FunctorKeyType(schema["a"], parameterNames) self.assertTrue(fKey1.isValid()) self.assertTrue(fKey2.isValid()) self.assertEqual(fKey1, fKey2) # verify that a default-constructed functor key is invalid fKey3 = FunctorKeyType() self.assertNotEqual(fKey3, fKey1) self.assertFalse(fKey3.isValid()) # create a record from the test schema, and fill it using the # constituent keys table = lsst.afw.table.BaseTable.make(schema) record = table.makeRecord() k = 0 # we set each matrix element a two-digit number where the first digit is the row # index and the second digit is the column index. for i in range(len(parameterNames)): record.set(sigmaKeys[i], ((i + 1)*10 + (i + 1))**0.5) if varianceOnly: continue for j in range(i): if covKeys[k].isValid(): record.set(covKeys[k], (i + 1)*10 + (j + 1)) k += 1 # test that the return type and value is correct matrix1 = record.get(fKey1) matrix2 = record.get(fKey2) # we use assertFloatsAlmostEqual because it can handle matrices, and because square root # in Python might not be exactly reversible with squaring in C++ (with possibly # different precision). self.assertFloatsAlmostEqual(matrix1, matrix2) k = 0 for i in range(len(parameterNames)): self.assertFloatsAlmostEqual( matrix1[i, i], (i + 1)*10 + (i + 1), rtol=1E-7) if varianceOnly: continue for j in range(i): if covKeys[k].isValid(): self.assertFloatsAlmostEqual( matrix1[i, j], (i + 1)*10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual( matrix2[i, j], (i + 1)*10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual( matrix1[j, i], (i + 1)*10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual( matrix2[j, i], (i + 1)*10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual( fKey1.getElement(record, i, j), (i + 1)*10 + (j + 1), rtol=1E-7) self.assertFloatsAlmostEqual( fKey2.getElement(record, i, j), (i + 1)*10 + (j + 1), rtol=1E-7) v = numpy.random.randn() fKey1.setElement(record, i, j, v) self.assertFloatsAlmostEqual( fKey2.getElement(record, i, j), v, rtol=1E-7) fKey2.setElement(record, i, j, (i + 1)*10 + (j + 1)) else: with self.assertRaises(lsst.pex.exceptions.LogicError): fKey1.setElement(record, i, j, 0.0) k += 1