Coverage for python/lsst/obs/subaru/filterFraction.py : 17%

Hot-keys 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#
2# LSST Data Management System
3# Copyright 2017 LSST/AURA.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <http://www.lsstcorp.org/LegalNotices/>.
21#
22import lsst.meas.base
24__all__ = ["FilterFractionPlugin"]
27class FilterFractionPluginConfig(lsst.meas.base.SingleFramePluginConfig):
28 pass
31@lsst.meas.base.register("subaru_FilterFraction")
32class FilterFractionPlugin(lsst.meas.base.SingleFramePlugin):
34 ConfigClass = FilterFractionPluginConfig
36 @classmethod
37 def getExecutionOrder(cls):
38 return cls.FLUX_ORDER
40 def __init__(self, config, name, schema, metadata):
41 lsst.meas.base.SingleFramePlugin.__init__(self, config, name, schema, metadata)
42 self.unweightedKey = schema.addField(
43 schema.join(name, "unweighted"), type=float,
44 doc=("Fraction of observations taken with the preferred version of this filter. "
45 "For filters with a single version, this will always be 1; for HSC i or r, "
46 "the preferred filter is the replacement filter (i2 or r2)."),
47 doReplace=True
48 )
49 self.weightedKey = schema.addField(
50 schema.join(name, "weighted"), type=float,
51 doc=("Contribution-weighted fraction of observations taken with the preferred "
52 "version of this filter. "
53 "For filters with a single version, this will always be 1; for HSC i or r, "
54 "the preferred filter is the replacement filter (i2 or r2)."),
55 doReplace=True
56 )
58 def measure(self, measRecord, exposure):
59 try:
60 ccds = exposure.getInfo().getCoaddInputs().ccds
61 except AttributeError:
62 raise lsst.meas.base.FatalAlgorithmError("FilterFraction can only be run on coadds.")
63 overlapping = ccds.subsetContaining(measRecord.getCentroid(), exposure.getWcs(),
64 includeValidPolygon=True)
65 if not overlapping:
66 measRecord.set(self.key, float("NaN")) # no inputs in any filter
67 return
68 counts = {}
69 weights = {}
70 filterKey = overlapping.schema.find("filter").key
71 try:
72 weightKey = overlapping.schema.find("weight").key
73 except KeyError:
74 weightKey = None
75 for ccd in overlapping:
76 filterName = ccd.get(filterKey)
77 counts[filterName] = counts.get(filterName, 0) + 1
78 if weightKey is not None:
79 weight = ccd.get(weightKey)
80 weights[filterName] = weights.get(filterName, 0.0) + weight
81 if "i" in counts:
82 weird = set(counts.keys()) - set(["i", "i2"])
83 if weird:
84 raise lsst.meas.base.FatalAlgorithmError(
85 "Unexpected filter combination found in coadd: %s" % counts.keys()
86 )
87 measRecord.set(self.unweightedKey, counts.get("i2", 0.0)/len(overlapping))
88 if weightKey is not None:
89 measRecord.set(self.weightedKey, weights.get("i2", 0.0)/sum(weights.values()))
90 elif "r" in counts:
91 weird = set(counts.keys()) - set(["r", "r2"])
92 if weird:
93 raise lsst.meas.base.FatalAlgorithmError(
94 "Unexpected filter combination found in coadd: %s" % counts.keys()
95 )
96 measRecord.set(self.unweightedKey, counts.get("r2", 0.0)/len(overlapping))
97 if weightKey is not None:
98 measRecord.set(self.weightedKey, weights.get("r2", 0.0)/sum(weights.values()))
99 elif len(counts) > 1:
100 raise lsst.meas.base.FatalAlgorithmError(
101 "Unexpected filter combination found in coadd: %s" % counts.keys()
102 )
103 else:
104 measRecord.set(self.unweightedKey, 1.0)
105 if weightKey is not None:
106 measRecord.set(self.weightedKey, 1.0)
108 def fail(self, measRecord, error=None):
109 # this plugin can only raise fatal exceptions
110 pass