2 __all__ = [
"DirectMatchConfig",
"DirectMatchTask",
"DirectMatchConfigWithoutLoader"]
5 from lsst.pipe.base
import Task, Struct
6 from lsst.meas.algorithms
import (LoadIndexedReferenceObjectsTask, ScienceSourceSelectorTask,
7 ReferenceSourceSelectorTask)
13 """Configuration for DirectMatchTask when an already-initialized 14 refObjLoader will be passed to this task.""" 15 matchRadius = Field(dtype=float, default=0.25, doc=
"Matching radius, arcsec")
16 sourceSelection = ConfigurableField(target=ScienceSourceSelectorTask,
17 doc=
"Selection of science sources")
18 referenceSelection = ConfigurableField(target=ReferenceSourceSelectorTask,
19 doc=
"Selection of reference sources")
23 """Configuration for DirectMatchTask""" 24 refObjLoader = ConfigurableField(target=LoadIndexedReferenceObjectsTask, doc=
"Load reference objects")
28 """Simple, brute force matching of a source catalog to a reference catalog. 32 butler : `lsst.daf.persistence.Butler` 33 Data butler containing the relevant reference catalog data. 34 refObjLoader : `lsst.meas.algorithms.LoadReferenceObjectsTask` or `None` 35 For loading reference objects 37 Other keyword arguments required for instantiating a Task (e.g., 'config') 39 ConfigClass = DirectMatchConfig
40 _DefaultName =
"directMatch" 42 def __init__(self, butler=None, refObjLoader=None, **kwargs):
43 Task.__init__(self, **kwargs)
45 if not isinstance(self.config, DirectMatchConfig):
46 raise RuntimeError(
"DirectMatchTask must be initialized with DirectMatchConfig " 47 "if a refObjLoader is not supplied at initialization")
48 self.makeSubtask(
"refObjLoader", butler=butler)
51 self.makeSubtask(
"sourceSelection")
52 self.makeSubtask(
"referenceSelection")
54 def run(self, catalog, filterName=None, epoch=None):
55 """Load reference objects and match to them. 59 catalog : `lsst.afw.table.SourceCatalog` 62 Name of filter loading fluxes 63 epoch : `astropy.time.Time` or `None` 64 Epoch to which to correct proper motion and parallax, 65 or `None` to not apply such corrections. 69 result : `lsst.pipe.base.Struct` 70 Result struct with components: 72 - matches : Matched sources with associated reference 73 (`lsst.afw.table.SourceMatchVector`) 74 - matchMeta : Match metadata (`lsst.meas.astrom.MatchMetadata`) 77 matchMeta = self.
refObjLoader.getMetadataCircle(circle.center, circle.radius, filterName, epoch=epoch)
78 emptyResult = Struct(matches=[], matchMeta=matchMeta)
79 sourceSelection = self.sourceSelection.
run(catalog)
80 if len(sourceSelection.sourceCat) == 0:
81 self.log.warn(
"No objects selected from %d objects in source catalog", len(catalog))
83 refData = self.
refObjLoader.loadSkyCircle(circle.center, circle.radius, filterName, epoch=epoch)
84 refCat = refData.refCat
85 refSelection = self.referenceSelection.
run(refCat)
86 if len(refSelection.sourceCat) == 0:
87 self.log.warn(
"No objects selected from %d objects in reference catalog", len(refCat))
90 self.config.matchRadius*arcseconds)
91 self.log.info(
"Matched %d from %d/%d input and %d/%d reference sources" %
92 (len(matches), len(sourceSelection.sourceCat), len(catalog),
93 len(refSelection.sourceCat), len(refCat)))
94 return Struct(matches=matches, matchMeta=matchMeta, refCat=refCat, sourceSelection=sourceSelection,
95 refSelection=refSelection)
98 """Calculate a circle enclosing the catalog 102 catalog : `lsst.afw.table.SourceCatalog` 107 result : `lsst.pipe.base.Struct` 108 Result struct with components: 110 - center : ICRS center coordinate (`lsst.afw.geom.SpherePoint`) 111 - radius : Radius of the circle (`lsst.geom.Angle`) 113 coordList = [src.getCoord()
for src
in catalog]
114 center = averageSpherePoint(coordList)
115 radius = max(center.separation(coord)
for coord
in coordList)
116 return Struct(center=center, radius=radius + self.config.matchRadius*arcseconds)
def run(self, catalog, filterName=None, epoch=None)
template SourceMatchVector matchRaDec(SourceCatalog const &, lsst::geom::Angle, MatchControl const &)
def calculateCircle(self, catalog)
def __init__(self, butler=None, refObjLoader=None, kwargs)