24 Definitions and registration of pure-Python plugins with trivial implementations,
25 and automatic plugin-from-algorithm calls for those implemented in C++.
34 from .baseLib
import *
36 from .forcedMeasurement
import *
37 from .wrappers
import *
38 from .transforms
import *
43 TransformClass=PsfFluxTransform, executionOrder=2.0)
45 TransformClass=PeakLikelihoodFluxTransform, executionOrder=2.0)
47 TransformClass=GaussianFluxTransform, executionOrder=2.0)
49 TransformClass=GaussianCentroidTransform, executionOrder=0.0)
51 TransformClass=NaiveCentroidTransform, executionOrder=0.0)
53 TransformClass=SdssCentroidTransform, executionOrder=0.0)
56 TransformClass=SdssShapeTransform, executionOrder=1.0)
58 wrapSimpleAlgorithm(CircularApertureFluxAlgorithm, needsMetadata=
True, Control=ApertureFluxControl,
59 TransformClass=ApertureFluxTransform, executionOrder=2.0)
69 A centroid algorithm that simply uses the first (i.e. highest) Peak in the Source's
70 Footprint as the centroid. This is of course a relatively poor measure of the true
71 centroid of the object; this algorithm is provided mostly for testing and debugging.
74 ConfigClass = SingleFramePeakCentroidConfig
80 def __init__(self, config, name, schema, metadata):
81 SingleFramePlugin.__init__(self, config, name, schema, metadata)
82 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixels")
83 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixels")
86 peak = measRecord.getFootprint().getPeaks()[0]
87 measRecord.set(self.
keyX, peak.getFx())
88 measRecord.set(self.
keyY, peak.getFy())
92 return SimpleCentroidTransform
100 A measurement plugin that sets the "coord" field (part of the Source minimal schema)
101 using the slot centroid and the Wcs attached to the Exposure.
104 ConfigClass = SingleFrameSkyCoordConfig
113 if not exposure.hasWcs():
114 raise Exception(
"Wcs not attached to exposure. Required for " + self.name +
" algorithm")
115 measRecord.updateCoord(exposure.getWcs())
117 def fail(self, measRecord, error=None):
124 class SingleFrameClassificationConfig(SingleFramePluginConfig):
126 fluxRatio = lsst.pex.config.Field(dtype=float, default=.925, optional=
True,
127 doc=
"critical ratio of model to psf flux")
128 modelErrFactor = lsst.pex.config.Field(dtype=float, default=0.0, optional=
True,
129 doc=
"correction factor for modelFlux error")
130 psfErrFactor = lsst.pex.config.Field(dtype=float, default=0.0, optional=
True,
131 doc=
"correction factor for psfFlux error")
133 @
register(
"base_ClassificationExtendedness")
136 A binary measure of the extendedness of a source, based a simple cut on the ratio of the
137 PSF flux to the model flux.
139 Because the fluxes on which this algorithm is based are slot measurements, they can be provided
140 by different algorithms, and the "fluxRatio" threshold used by this algorithm should generally
141 be set differently for different algorithms. To do this, plot the difference between the PSF
142 magnitude and the model magnitude vs. the PSF magnitude, and look for where the cloud of galaxies
146 ConfigClass = SingleFrameClassificationConfig
152 def __init__(self, config, name, schema, metadata):
153 SingleFramePlugin.__init__(self, config, name, schema, metadata)
155 doc=
"Set to 1 for extended sources, 0 for point sources.")
156 self.
keyFlag = schema.addField(name +
"_flag", type=
"Flag", doc=
"Set to 1 for any fatal failure.")
159 modelFlux = measRecord.getModelFlux()
160 psfFlux = measRecord.getPsfFlux()
161 modelFluxFlag = (measRecord.getModelFluxFlag()
162 if measRecord.table.getModelFluxFlagKey().isValid()
164 psfFluxFlag = (measRecord.getPsfFluxFlag()
165 if measRecord.table.getPsfFluxFlagKey().isValid()
167 flux1 = self.config.fluxRatio*modelFlux
168 if not self.config.modelErrFactor == 0:
169 flux1 += self.config.modelErrFactor*measRecord.getModelFluxErr()
171 if not self.config.psfErrFactor == 0:
172 flux2 += self.config.psfErrFactor*measRecord.getPsfFluxErr()
178 if numpy.isnan(flux1)
or numpy.isnan(flux2)
or modelFluxFlag
or psfFluxFlag:
179 self.
fail(measRecord)
186 def fail(self, measRecord, error=None):
189 measRecord.set(self.
keyFlag,
True)
200 The forced peak centroid is like the SFM peak centroid plugin, except that it must transform
201 the peak coordinate from the original (reference) coordinate system to the coordinate system
202 of the exposure being measured.
205 ConfigClass = ForcedPeakCentroidConfig
211 def __init__(self, config, name, schemaMapper, metadata):
212 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
213 schema = schemaMapper.editOutputSchema()
214 self.
keyX = schema.addField(name +
"_x", type=
"D", doc=
"peak centroid", units=
"pixels")
215 self.
keyY = schema.addField(name +
"_y", type=
"D", doc=
"peak centroid", units=
"pixels")
217 def measure(self, measRecord, exposure, refRecord, refWcs):
218 targetWcs = exposure.getWcs()
219 peak = refRecord.getFootprint().getPeaks()[0]
221 if not refWcs == targetWcs:
222 result = targetWcs.skyToPixel(refWcs.pixelToSky(result))
223 measRecord.set(self.
keyX, result.getX())
224 measRecord.set(self.
keyY, result.getY())
228 return SimpleCentroidTransform
233 @
register(
"base_TransformedCentroid")
235 """A centroid pseudo-algorithm for forced measurement that simply transforms the centroid
236 from the reference catalog to the measurement coordinate system. This is used as
237 the slot centroid by default in forced measurement, allowing subsequent measurements
238 to simply refer to the slot value just as they would in single-frame measurement.
241 ConfigClass = ForcedTransformedCentroidConfig
247 def __init__(self, config, name, schemaMapper, metadata):
248 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
249 schema = schemaMapper.editOutputSchema()
251 xKey = schema.addField(name +
"_x", type=
"D", doc=
"transformed reference centroid column",
253 yKey = schema.addField(name +
"_y", type=
"D", doc=
"transformed reference centroid row",
259 if "slot_Centroid_flag" in schemaMapper.getInputSchema():
260 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
261 doc=
"whether the reference centroid is marked as bad")
265 def measure(self, measRecord, exposure, refRecord, refWcs):
266 targetWcs = exposure.getWcs()
267 if not refWcs == targetWcs:
268 targetPos = targetWcs.skyToPixel(refWcs.pixelToSky(refRecord.getCentroid()))
271 measRecord.set(self.
centroidKey, refRecord.getCentroid())
273 measRecord.set(self.
flagKey, refRecord.getCentroidFlag())
281 """A shape pseudo-algorithm for forced measurement that simply transforms the shape
282 from the reference catalog to the measurement coordinate system. This is used as
283 the slot shape by default in forced measurement, allowing subsequent measurements
284 to simply refer to the slot value just as they would in single-frame measurement.
287 ConfigClass = ForcedTransformedShapeConfig
293 def __init__(self, config, name, schemaMapper, metadata):
294 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata)
295 schema = schemaMapper.editOutputSchema()
297 xxKey = schema.addField(name +
"_xx", type=
"D", doc=
"transformed reference shape x^2 moment",
299 yyKey = schema.addField(name +
"_yy", type=
"D", doc=
"transformed reference shape y^2 moment",
301 xyKey = schema.addField(name +
"_xy", type=
"D", doc=
"transformed reference shape xy moment",
307 if "slot_Shape_flag" in schemaMapper.getInputSchema():
308 self.
flagKey = schema.addField(name +
"_flag", type=
"Flag",
309 doc=
"whether the reference shape is marked as bad")
313 def measure(self, measRecord, exposure, refRecord, refWcs):
314 targetWcs = exposure.getWcs()
315 if not refWcs == targetWcs:
317 localTransform = fullTransform.linearizeForwardTransform(refRecord.getCentroid())
318 measRecord.set(self.
shapeKey, refRecord.getShape().transform(localTransform.getLinear()))
320 measRecord.set(self.
shapeKey, refRecord.getShape())
322 measRecord.set(self.
flagKey, refRecord.getShapeFlag())
def wrapSimpleAlgorithm
Wrap a C++ SimpleAlgorithm class into both a Python SingleFramePlugin and ForcedPlugin classes...
A FunctorKey used to get or set a geom::ellipses::Quadrupole from a tuple of constituent Keys...