22__all__ = [
"CoaddInputRecorderTask"]
34 saveEmptyCcds = pexConfig.Field(
35 dtype=bool, default=
False, optional=
False,
36 doc=(
"Add records for CCDs we iterated over but did not add a coaddTempExp"
37 " due to a lack of unmasked pixels in the coadd footprint.")
39 saveErrorCcds = pexConfig.Field(
40 dtype=bool, default=
False, optional=
False,
41 doc=(
"Add records for CCDs we iterated over but did not add a coaddTempExp"
42 " due to an exception (often due to the calexp not being found on disk).")
44 saveVisitGoodPix = pexConfig.Field(
45 dtype=bool, default=
True, optional=
False,
46 doc=(
"Save the total number of good pixels in each coaddTempExp (redundant with a sum of"
47 " good pixels in associated CCDs)")
49 saveCcdWeights = pexConfig.Field(
50 dtype=bool, default=
True, optional=
False,
51 doc=(
"Save weights in the CCDs table as well as the visits table?"
52 " (This is necessary for easy construction of CoaddPsf, but otherwise duplicate information.)")
57 """A helper class for CoaddInputRecorderTask, managing the CoaddInputs object for that single
58 CoaddTempExp. This will contain a single 'visit' record
for the CoaddTempExp
and a number of
'ccd'
61 Should generally be created by calling CoaddInputRecorderTask.makeCoaddTempExp().
66 The CoaddInputRecorderTask that
is utilising us.
68 Identifier (integer)
for the visit.
70 Number of CCDs
for this visit that overlap this patch (
for reserving memory).
83 """Add a 'ccd' record for a calexp just added to the CoaddTempExp.
88 Calibrated exposure just added to the CoaddTempExp, or None in case of
89 failures that should nonetheless be tracked. Should be the original
90 calexp,
in that it should contain the original Psf
and Wcs,
not the
91 warped
and/
or matched ones.
93 A unique numeric ID
for the Exposure.
95 Number of good pixels this image will contribute to the CoaddTempExp.
96 If saveEmptyCcds
is not set
and this value
is zero, no record will be
99 if nGoodPix == 0
and not self.
task.config.saveEmptyCcds:
105 record.setI(self.
task.ccdCcdKey, calExp.getDetector().getId())
106 except Exception
as e:
107 self.
task.log.warning(
"Error getting detector serial number in visit %d; using -1; error=%s",
109 record.setI(self.
task.ccdCcdKey, -1)
110 record.setI(self.
task.ccdGoodPixKey, nGoodPix)
111 if calExp
is not None:
113 if self.
task.config.saveCcdWeights:
114 record.setD(self.
task.ccdWeightKey, 1.0)
115 record.set(self.
task.ccdFilterKey, calExp.getFilter().physicalLabel)
117 def finish(self, coaddTempExp, nGoodPix=None):
118 """Finish creating the CoaddInputs for a CoaddTempExp.
123 Exposure object from which to obtain the PSF, WCS,
and bounding
124 box
for the entry
in the
'visits' table. On
return, the completed
125 CoaddInputs object will be attached to it.
127 Total number of good pixels
in the CoaddTempExp; ignored unless
128 saveVisitGoodPix
is true.
131 if self.
task.config.saveVisitGoodPix:
133 coaddTempExp.getInfo().setCoaddInputs(self.
coaddInputs)
134 wcs = coaddTempExp.getWcs()
138 apCorrMap = makeCoaddApCorrMap(self.
coaddInputs.ccds, coaddTempExp.getBBox(afwImage.PARENT), wcs)
139 coaddTempExp.getInfo().setApCorrMap(apCorrMap)
142 """Set exposure info and bbox in an ExposureTable record.
146 exposure : `lsst.afw.image.ExposureF`
147 Exposure whose info is to be recorded.
149 Record of an ExposureTable to set.
151 info = exposure.getInfo()
152 record.setPsf(info.getPsf())
153 record.setWcs(info.getWcs())
154 record.setPhotoCalib(info.getPhotoCalib())
155 record.setApCorrMap(info.getApCorrMap())
156 record.setValidPolygon(info.getValidPolygon())
157 record.setVisitInfo(info.getVisitInfo())
158 record.setBBox(exposure.getBBox())
159 record.setTransmissionCurve(info.getTransmissionCurve())
163 """Subtask that handles filling a CoaddInputs object for a coadd exposure, tracking the CCDs and
164 visits that went into a coadd.
166 The interface here is a little messy, but I think this
is at least partly a product of a bit of
167 messiness
in the coadd code it
's plugged into. I hope #2590 might result in a better design.
170 ConfigClass = CoaddInputRecorderConfig
173 pipeBase.Task.__init__(self, *args, **kwargs)
175 if self.config.saveVisitGoodPix:
177 doc=
"Number of good pixels in the coaddTempExp")
179 doc=
"Weight for this visit in the coadd")
180 self.
ccdSchema = afwTable.ExposureTable.makeMinimalSchema()
181 self.
ccdCcdKey = self.
ccdSchema.addField(
"ccd", type=numpy.int32, doc=
"cameraGeom CCD serial number")
183 doc=
"Foreign key for the visits (coaddTempExp) catalog")
185 doc=
"Number of good pixels in this CCD")
186 if self.config.saveCcdWeights:
188 doc=
"Weight for this visit in the coadd")
190 doc=
"Physical filter associated with this visit.")
192 doc=
"Physical filter associated with this visit.")
195 """Return a CoaddTempExpInputRecorder instance to help with saving a CoaddTempExp's inputs.
200 num : `int`, optional
201 Number of CCDs for this visit that overlap this patch (
for reserving memory).
205 The visitId may be any number that
is unique
for each :that goes into a coadd,
206 but ideally should be something more meaningful that can be used to reconstruct a data ID.
211 """Create a CoaddInputs object with schemas defined by the task configuration."""
215 """Called by AssembleCoaddTask when adding (a subset of) a coaddTempExp to a coadd. The
216 base class impementation extracts the CoaddInputs from the coaddTempExp and appends
217 them to the given coaddInputs, filling
in the weight column(s).
221 coaddInputs : `lsst.afw.Image.CoaddInputs`
222 A record of the observations that are included
in the coadd.
224 Exposure object
from which to obtain the PSF, WCS,
and bounding
225 box
for the entry
in the
'visits' table. On
return, the completed
226 CoaddInputs object will be attached to it.
231 inputVisitRecord : `Unknown`
232 The record
for the visit to allow subclasses to fill
in additional fields
or
233 None if the inputRecorder catalogs
for the coaddTempExp are
not usable.
237 Note that the passed coaddTempExp may be a subimage, but that this method will only be
238 called
for the first subimage.
240 tempExpInputs = coaddTempExp.getInfo().getCoaddInputs()
241 if len(tempExpInputs.visits) != 1:
242 self.log.warning(
"CoaddInputs for coaddTempExp should have exactly one record in visits table "
243 "(found %d). CoaddInputs for this visit will not be saved.",
244 len(tempExpInputs.visits))
246 inputVisitRecord = tempExpInputs.visits[0]
247 outputVisitRecord = coaddInputs.visits.addNew()
248 outputVisitRecord.assign(inputVisitRecord)
250 outputVisitRecord.set(self.
visitFilterKey, coaddTempExp.getFilter().physicalLabel)
251 for inputCcdRecord
in tempExpInputs.ccds:
252 if inputCcdRecord.getL(self.
ccdVisitKey) != inputVisitRecord.getId():
253 self.log.warning(
"CoaddInputs for coaddTempExp with id %d contains CCDs with visit=%d. "
254 "CoaddInputs may be unreliable.",
255 inputVisitRecord.getId(), inputCcdRecord.getL(self.
ccdVisitKey))
256 outputCcdRecord = coaddInputs.ccds.addNew()
257 outputCcdRecord.assign(inputCcdRecord)
258 if self.config.saveCcdWeights:
260 outputCcdRecord.set(self.
ccdFilterKey, coaddTempExp.getFilter().physicalLabel)
261 return inputVisitRecord