30 from .apCorrRegistry
import getApCorrNameSet
36 UseNaiveFluxErr =
True 38 __all__ = (
"ApplyApCorrConfig",
"ApplyApCorrTask")
42 """!Catalog field names and keys needed to aperture correct a particular instrument flux 46 """!Construct an ApCorrInfo and add fields to the schema 48 The aperture correction can be derived from the meaasurements in the 49 column being aperture-corrected or from measurements in a different 50 column (a "proxy"). In the first case, we will add columns to contain 51 the aperture correction values; in the second case (using a proxy), 52 we will add an alias to the proxy's aperture correction values. In 53 all cases, we add a flag. 55 @param[in,out] schema source catalog schema; 56 three fields are used to generate keys: 60 three fields are added: 61 - {name}_apCorr (only if not already added by proxy) 62 - {name}_apCorrErr (only if not already added by proxy) 64 @param[in] model field name prefix for instFlux with aperture correction model, e.g. "base_PsfFlux" 65 @param[in] name field name prefix for instFlux needing aperture correction; may be None if it's the 66 same as for the 'model' parameter 68 ApCorrInfo has the following attributes: 69 - name: field name prefix for instFlux needing aperture correction 70 - modelName: field name for aperture correction model for instFlux 71 - modelSigmaName: field name for aperture correction model for instFluxErr 72 - doApCorrColumn: should we write the aperture correction values? (not if they're already being 74 - instFluxName: name of instFlux field 75 - instFluxErrName: name of instFlux sigma field 76 - instFluxKey: key to instFlux field 77 - instFluxErrKey: key to instFlux sigma field 78 - fluxFlagKey: key to flux flag field 79 - apCorrKey: key to new aperture correction field 80 - apCorrErrKey: key to new aperture correction sigma field 81 - apCorrFlagKey: key to new aperture correction flag field 99 doc=
"aperture correction applied to %s" % (name,),
104 doc=
"standard deviation of aperture correction applied to %s" % (name,),
108 aliases = schema.getAliasMap()
109 aliases.set(name +
"_apCorr", model +
"_apCorr")
110 aliases.set(name +
"_apCorrErr", model +
"_apCorrErr")
111 self.
apCorrKey = schema.find(name +
"_apCorr").key
112 self.
apCorrErrKey = schema.find(name +
"_apCorrErr").key
115 name +
"_flag_apCorr",
116 doc=
"set if unable to aperture correct %s" % (name,),
122 ignoreList = lsst.pex.config.ListField(
123 doc=
"flux measurement algorithms in getApCorrNameSet() to ignore; " 124 "if a name is listed that does not appear in getApCorrNameSet() then a warning is logged",
129 doFlagApCorrFailures = lsst.pex.config.Field(
130 doc=
"set the general failure flag for a flux when it cannot be aperture-corrected?",
134 proxies = lsst.pex.config.DictField(
135 doc=
"flux measurement algorithms to be aperture-corrected by reference to another algorithm; " 136 "this is a mapping alg1:alg2, where 'alg1' is the algorithm being corrected, and 'alg2' " 137 "is the algorithm supplying the corrections",
145 """!Apply aperture corrections 147 ConfigClass = ApplyApCorrConfig
148 _DefaultName =
"applyApCorr" 151 """Construct an instance of this task 153 lsst.pipe.base.Task.__init__(self, **kwds)
157 ignoreSet = set(self.config.ignoreList)
158 missingNameSet = ignoreSet - set(apCorrNameSet)
160 self.log.warn(
"Fields in ignoreList that are not in fluxCorrectList: %s",
161 sorted(list(missingNameSet)))
162 for name
in sorted(list(apCorrNameSet - ignoreSet)):
163 if name +
"_instFlux" not in schema:
168 for name, model
in self.config.proxies.items():
169 if name
in apCorrNameSet:
172 if name +
"_instFlux" not in schema:
177 def run(self, catalog, apCorrMap):
178 """Apply aperture corrections to a catalog of sources 180 @param[in,out] catalog catalog of sources 181 @param[in] apCorrMap aperture correction map (an lsst.afw.image.ApCorrMap) 183 If you show debug-level log messages then you will see statistics for the effects of 186 self.log.info(
"Applying aperture corrections to %d instFlux fields", len(self.
apCorrInfoDict))
188 self.log.debug(
"Use naive instFlux sigma computation")
190 self.log.debug(
"Use complex instFlux sigma computation that double-counts photon noise " 191 "and thus over-estimates instFlux uncertainty")
193 apCorrModel = apCorrMap.get(apCorrInfo.modelName)
194 apCorrErrModel = apCorrMap.get(apCorrInfo.modelSigmaName)
195 if None in (apCorrModel, apCorrErrModel):
196 missingNames = [(apCorrInfo.modelName, apCorrInfo.modelSigmaName)[i]
197 for i, model
in enumerate((apCorrModel, apCorrErrModel))
if model
is None]
198 self.log.warn(
"Cannot aperture correct %s because could not find %s in apCorrMap" %
199 (apCorrInfo.name,
" or ".join(missingNames),))
200 for source
in catalog:
201 source.set(apCorrInfo.apCorrFlagKey,
True)
204 for source
in catalog:
205 center = source.getCentroid()
207 source.set(apCorrInfo.apCorrFlagKey,
True)
208 oldFluxFlagState =
False 209 if self.config.doFlagApCorrFailures:
210 oldFluxFlagState = source.get(apCorrInfo.fluxFlagKey)
211 source.set(apCorrInfo.fluxFlagKey,
True)
216 apCorr = apCorrModel.evaluate(center)
217 if not UseNaiveFluxErr:
218 apCorrErr = apCorrErrModel.evaluate(center)
222 if apCorrInfo.doApCorrColumn:
223 source.set(apCorrInfo.apCorrKey, apCorr)
224 source.set(apCorrInfo.apCorrErrKey, apCorrErr)
226 if apCorr <= 0.0
or apCorrErr < 0.0:
229 instFlux = source.get(apCorrInfo.instFluxKey)
230 instFluxErr = source.get(apCorrInfo.instFluxErrKey)
231 source.set(apCorrInfo.instFluxKey, instFlux*apCorr)
233 source.set(apCorrInfo.instFluxErrKey, instFluxErr*apCorr)
235 a = instFluxErr/instFlux
237 source.set(apCorrInfo.instFluxErrKey, abs(instFlux*apCorr)*math.sqrt(a*a + b*b))
238 source.set(apCorrInfo.apCorrFlagKey,
False)
239 if self.config.doFlagApCorrFailures:
240 source.set(apCorrInfo.fluxFlagKey, oldFluxFlagState)
242 if self.log.getLevel() <= self.log.DEBUG:
244 apCorrArr = np.array([s.get(apCorrInfo.apCorrKey)
for s
in catalog])
245 apCorrErrArr = np.array([s.get(apCorrInfo.apCorrErrKey)
for s
in catalog])
246 self.log.debug(
"For instFlux field %r: mean apCorr=%s, stdDev apCorr=%s, " 247 "mean apCorrErr=%s, stdDev apCorrErr=%s for %s sources",
248 apCorrInfo.name, apCorrArr.mean(), apCorrArr.std(),
249 apCorrErrArr.mean(), apCorrErrArr.std(), len(catalog))
Apply aperture corrections.
def __init__(self, schema, kwds)
def getApCorrNameSet()
Return a copy of the set of field name prefixes for instrument flux that should be aperture corrected...
def __init__(self, schema, model, name=None)
Construct an ApCorrInfo and add fields to the schema.
Catalog field names and keys needed to aperture correct a particular instrument flux.
def run(self, catalog, apCorrMap)