Coverage for python/lsst/faro/base/CatalogMeasurementBase.py: 48%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of faro.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21from astropy.table import Table, hstack
22import astropy.units as u
24import lsst.pipe.base as pipeBase
25import lsst.pex.config as pexConfig
26from lsst.verify.tasks import MetricTask, MetricConfig, MetricConnections
27from lsst.pipe.tasks.loadReferenceCatalog import LoadReferenceCatalogTask
28import lsst.geom
30from .BaseSubTasks import NumSourcesTask
32__all__ = (
33 "CatalogMeasurementBaseConnections",
34 "CatalogMeasurementBaseConfig",
35 "CatalogMeasurementBaseTask",
36)
39class CatalogMeasurementBaseConnections(
40 MetricConnections, defaultTemplates={"refDataset": ""}
41):
43 refCat = pipeBase.connectionTypes.PrerequisiteInput(
44 doc="Reference catalog",
45 name="{refDataset}",
46 storageClass="SimpleCatalog",
47 dimensions=("skypix",),
48 deferLoad=True,
49 multiple=True,
50 )
52 def __init__(self, *, config=None):
53 super().__init__(config=config)
54 if config.connections.refDataset == "":
55 self.prerequisiteInputs.remove("refCat")
58class CatalogMeasurementBaseConfig(
59 MetricConfig, pipelineConnections=CatalogMeasurementBaseConnections
60):
61 """Configuration for CatalogMeasurementBaseTask."""
63 measure = pexConfig.ConfigurableField(
64 # This task is meant to make measurements of various types.
65 # The default task is, therefore, a bit of a place holder.
66 # It is expected that this will be overridden in the pipeline
67 # definition in most cases.
68 target=NumSourcesTask,
69 doc="Measure task",
70 )
72 referenceCatalogLoader = pexConfig.ConfigurableField(
73 target=LoadReferenceCatalogTask, doc="Reference catalog loader",
74 )
76 def setDefaults(self):
77 self.referenceCatalogLoader.refObjLoader.ref_dataset_name = ""
78 self.referenceCatalogLoader.doApplyColorTerms = False
80 def validate(self):
81 super().validate()
82 if (
83 self.connections.refDataset
84 != self.referenceCatalogLoader.refObjLoader.ref_dataset_name
85 ):
86 msg = "The reference datasets specified in connections and reference catalog loader must match."
87 raise pexConfig.FieldValidationError(
88 CatalogMeasurementBaseConfig.referenceCatalogLoader, self, msg
89 )
92class CatalogMeasurementBaseTask(MetricTask):
93 """Base class for science performance metrics measured from source/object catalogs."""
95 ConfigClass = CatalogMeasurementBaseConfig
96 _DefaultName = "catalogMeasurementBaseTask"
98 def __init__(self, config, *args, **kwargs):
99 super().__init__(*args, config=config, **kwargs)
100 self.makeSubtask("measure")
102 def run(self, **kwargs):
103 return self.measure.run(self.config.connections.metric, **kwargs)
105 def _getReferenceCatalog(self, butlerQC, dataIds, refCats, filterList, epoch=None):
106 """Load reference catalog in sky region of interest and optionally applies proper
107 motion correction and color terms.
109 Loads the `lsst.afw.table.SimpleCatalog` reference catalog, computes ra and dec
110 (optionally) applying a proper motion correction. Also, color terms
111 are (optionally) applied to the reference magnitudes in order to transform
112 them to the data's photometric system.
114 returns a refCat with both the original loaded reference catalog and
115 the coorected coordinates (ra,dec) and transformed reference magnitudes
116 (refMag-/refMagErr-)
118 Parameters
119 ----------
120 butlerQC : `lsst.pipe.base.butlerQuantumContext.ButlerQuantumContext`
121 Butler quantum context for a Gen3 repository.
122 dataIds: interable of `lsst.daf.butler.dataId`
123 An iterable object of dataIds that point to reference catalogs
124 in a Gen3 repository.
125 refCats : iterable of `lsst.daf.butler.DeferredDatasetHandle`
126 An iterable object of dataset refs for reference catalogs in
127 a Gen3 repository.
128 filterList : `list` [`str`]
129 List of camera physicalFilter names to apply color terms.
130 epoch : `astropy.time.Time`, optional
131 Epoch to which to correct proper motion and parallax
132 (if available), or `None` to not apply such corrections.
134 Returns
135 -------
136 refCat: pandas.dataframe
137 a reference catalog with original columns and corrected
138 coordinates (ra,dec) and reference magnitudes (refMag-/refMagErr-)
139 """
140 center = lsst.geom.SpherePoint(
141 butlerQC.quantum.dataId.region.getBoundingCircle().getCenter()
142 )
143 radius = butlerQC.quantum.dataId.region.getBoundingCircle().getOpeningAngle()
145 loaderTask = LoadReferenceCatalogTask(
146 config=self.config.referenceCatalogLoader, dataIds=dataIds, refCats=refCats
147 )
149 # Get catalog with proper motion and color terms applied
150 refCatCorrected = loaderTask.getSkyCircleCatalog(
151 center, radius, filterList, epoch=epoch
152 )
154 # Get unformatted catalog w/ all columns
155 skyCircle = loaderTask.refObjLoader.loadSkyCircle(
156 center, radius, loaderTask._referenceFilter, epoch=epoch
157 )
158 refCat = skyCircle.refCat
160 refCatTable = Table()
161 refCatTable['ra'] = refCatCorrected['ra']*u.deg
162 refCatTable['dec'] = refCatCorrected['ra']*u.deg
163 for n, filterName in enumerate(filterList):
164 refCatTable['refMag-' + filterName] = refCatCorrected["refMag"][:, n]*u.ABmag
165 refCatTable['refMagErr-' + filterName] = refCatCorrected["refMagErr"][:, n]*u.ABmag
166 refCatFrame = hstack([refCatTable, refCat.asAstropy()]).to_pandas()
168 return refCatFrame