LSSTApplications  17.0+11,17.0+34,17.0+56,17.0+57,17.0+59,17.0+7,17.0-1-g377950a+33,17.0.1-1-g114240f+2,17.0.1-1-g4d4fbc4+28,17.0.1-1-g55520dc+49,17.0.1-1-g5f4ed7e+52,17.0.1-1-g6dd7d69+17,17.0.1-1-g8de6c91+11,17.0.1-1-gb9095d2+7,17.0.1-1-ge9fec5e+5,17.0.1-1-gf4e0155+55,17.0.1-1-gfc65f5f+50,17.0.1-1-gfc6fb1f+20,17.0.1-10-g87f9f3f+1,17.0.1-11-ge9de802+16,17.0.1-16-ga14f7d5c+4,17.0.1-17-gc79d625+1,17.0.1-17-gdae4c4a+8,17.0.1-2-g26618f5+29,17.0.1-2-g54f2ebc+9,17.0.1-2-gf403422+1,17.0.1-20-g2ca2f74+6,17.0.1-23-gf3eadeb7+1,17.0.1-3-g7e86b59+39,17.0.1-3-gb5ca14a,17.0.1-3-gd08d533+40,17.0.1-30-g596af8797,17.0.1-4-g59d126d+4,17.0.1-4-gc69c472+5,17.0.1-6-g5afd9b9+4,17.0.1-7-g35889ee+1,17.0.1-7-gc7c8782+18,17.0.1-9-gc4bbfb2+3,w.2019.22
LSSTDataManagementBasePackage
metrics.py
Go to the documentation of this file.
1 # This file is part of ip_diffim.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (http://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 <http://www.gnu.org/licenses/>.
21 #
22 
23 __all__ = [
24  "NumberSciSourcesMetricTask", "NumberSciSourcesMetricConfig",
25  "FractionDiaSourcesToSciSourcesMetricTask", "FractionDiaSourcesToSciSourcesMetricConfig",
26 ]
27 
28 
29 import astropy.units as u
30 
31 from lsst.pipe.base import Struct, InputDatasetField
32 from lsst.verify import Measurement
33 from lsst.verify.gen2tasks import MetricTask, register
34 from lsst.verify.tasks import MetricComputationError
35 
36 
37 class NumberSciSourcesMetricConfig(MetricTask.ConfigClass):
38  sources = InputDatasetField(
39  doc="The catalog of science sources.",
40  name="src",
41  storageClass="SourceCatalog",
42  dimensions={"Instrument", "Exposure", "Detector"},
43  )
44 
45 
46 @register("numSciSources")
47 class NumberSciSourcesMetricTask(MetricTask):
48  """Task that computes the number of cataloged science sources.
49  """
50  _DefaultName = "numSciSources"
51  ConfigClass = NumberSciSourcesMetricConfig
52 
53  def run(self, sources):
54  """Count the number of science sources.
55 
56  Parameters
57  ----------
58  sources : iterable of `lsst.afw.table.SourceCatalog`
59  A collection of science source catalogs, one for each unit of
60  processing to be incorporated into this metric. Its elements may
61  be `None` to represent missing data.
62 
63  Returns
64  -------
65  result : `lsst.pipe.base.Struct`
66  A `~lsst.pipe.base.Struct` containing the following component:
67 
68  ``measurement``
69  the total number of science sources (`lsst.verify.Measurement`
70  or `None`)
71  """
72  nSciSources = 0
73  inputData = False
74  for catalog in sources:
75  if catalog is not None:
76  nSciSources += len(catalog)
77  inputData = True
78 
79  if inputData:
80  meas = Measurement(self.getOutputMetricName(self.config), nSciSources * u.count)
81  else:
82  self.log.info("Nothing to do: no catalogs found.")
83  meas = None
84  return Struct(measurement=meas)
85 
86  @classmethod
87  def getOutputMetricName(cls, config):
88  return "ip_diffim.numSciSources"
89 
90 
91 class FractionDiaSourcesToSciSourcesMetricConfig(MetricTask.ConfigClass):
92  sciSources = InputDatasetField(
93  doc="The catalog of science sources.",
94  name="src",
95  storageClass="SourceCatalog",
96  dimensions={"Instrument", "Exposure", "Detector"},
97  )
98  diaSources = InputDatasetField(
99  doc="The catalog of DIASources.",
100  name="deepDiff_diaSrc",
101  nameTemplate="{coaddName}Diff_diaSrc",
102  storageClass="SourceCatalog",
103  dimensions={"Instrument", "Exposure", "Detector"},
104  )
105 
106 
107 @register("fracDiaSourcesToSciSources")
109  """Task that computes the ratio of difference image sources to science
110  sources in an image, visit, etc.
111  """
112  _DefaultName = "fracDiaSourcesToSciSources"
113  ConfigClass = FractionDiaSourcesToSciSourcesMetricConfig
114 
115  def run(self, sciSources, diaSources):
116  """Compute the ratio of DIASources to science sources.
117 
118  Parameters
119  ----------
120  sciSources : iterable of `lsst.afw.table.SourceCatalog`
121  A collection of science source catalogs, one for each unit of
122  processing to be incorporated into this metric. Its elements may
123  be `None` to represent missing data.
124  diaSources : iterable of `lsst.afw.table.SourceCatalog`
125  A collection of difference imaging catalogs similar to
126  ``sciSources``.
127 
128  Returns
129  -------
130  result : `lsst.pipe.base.Struct`
131  A `~lsst.pipe.base.Struct` containing the following component:
132 
133  ``measurement``
134  the ratio (`lsst.verify.Measurement` or `None`)
135  """
136  nSciSources = 0
137  nDiaSources = 0
138  inputData = False
139 
140  for sciCatalog, diaCatalog in zip(sciSources, diaSources):
141  if diaCatalog is not None and sciCatalog is not None:
142  nSciSources += len(sciCatalog)
143  nDiaSources += len(diaCatalog)
144  inputData = True
145 
146  if inputData:
147  metricName = self.getOutputMetricName(self.config)
148  if nSciSources <= 0.0:
149  raise MetricComputationError(
150  "No science sources found; ratio of DIASources to science sources ill-defined.")
151  meas = Measurement(metricName, 0.0 * u.dimensionless_unscaled)
152  else:
153  meas = Measurement(metricName, nDiaSources / nSciSources * u.dimensionless_unscaled)
154  else:
155  self.log.info("Nothing to do: no catalogs found.")
156  meas = None
157  return Struct(measurement=meas)
158 
159  @classmethod
160  def getOutputMetricName(cls, config):
161  return "ip_diffim.fracDiaSourcesToSciSources"