30 __all__ = [
"CoaddInputRecorderTask"]
 
   34     """Config for CoaddInputRecorderTask 
   36     The inputRecorder section of the various coadd tasks' configs should generally agree, 
   37     or the schemas created by earlier tasks (like MakeCoaddTempExpTask) will not contain 
   38     the fields filled by later tasks (like AssembleCoaddTask). 
   41     saveEmptyCcds = pexConfig.Field(
 
   42         dtype=bool, default=
False, optional=
False,
 
   43         doc=(
"Add records for CCDs we iterated over but did not add a coaddTempExp" 
   44              " due to a lack of unmasked pixels in the coadd footprint.")
 
   46     saveErrorCcds = pexConfig.Field(
 
   47         dtype=bool, default=
False, optional=
False,
 
   48         doc=(
"Add records for CCDs we iterated over but did not add a coaddTempExp" 
   49              " due to an exception (often due to the calexp not being found on disk).")
 
   51     saveVisitGoodPix = pexConfig.Field(
 
   52         dtype=bool, default=
True, optional=
False,
 
   53         doc=(
"Save the total number of good pixels in each coaddTempExp (redundant with a sum of" 
   54              " good pixels in associated CCDs)")
 
   56     saveCcdWeights = pexConfig.Field(
 
   57         dtype=bool, default=
True, optional=
False,
 
   58         doc=(
"Save weights in the CCDs table as well as the visits table?" 
   59              " (This is necessary for easy construction of CoaddPsf, but otherwise duplicate information.)")
 
   64     """A helper class for CoaddInputRecorderTask, managing the CoaddInputs object for that single 
   65     CoaddTempExp.  This will contain a single 'visit' record for the CoaddTempExp and a number of 'ccd' 
   68     Should generally be created by calling CoaddInputRecorderTask.makeCoaddTempExp(). 
   74         @param task  The CoaddInputRecorderTask that is utilising us 
   75         @param visitId  Identifier (integer) for the visit 
   76         @param num  Number of CCDs for this visit that overlap this 
   77                         patch (for reserving memory) 
   88         """Add a 'ccd' record for a calexp just added to the CoaddTempExp 
   90         @param[in] calExp   Calibrated exposure just added to the CoaddTempExp, or None in case of 
   91                             failures that should nonetheless be tracked.  Should be the original 
   92                             calexp, in that it should contain the original Psf and Wcs, not the 
   93                             warped and/or matched ones. 
   94         @param[in] ccdId    A unique numeric ID for the Exposure. 
   95         @param[in] nGoodPix 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.
tasktask.config.saveEmptyCcds:
 
  103         record.setL(self.
tasktask.ccdVisitKey, self.
visitRecordvisitRecord.getId())
 
  105             record.setI(self.
tasktask.ccdCcdKey, calExp.getDetector().getId())
 
  106         except Exception 
as e:
 
  107             self.
tasktask.log.warning(
"Error getting detector serial number in visit %d; using -1; error=%s",
 
  109             record.setI(self.
tasktask.ccdCcdKey, -1)
 
  110         record.setI(self.
tasktask.ccdGoodPixKey, nGoodPix)
 
  111         if calExp 
is not None:
 
  113             if self.
tasktask.config.saveCcdWeights:
 
  114                 record.setD(self.
tasktask.ccdWeightKey, 1.0)  
 
  115             record.set(self.
tasktask.ccdFilterKey, calExp.getFilterLabel().physicalLabel)
 
  117     def finish(self, coaddTempExp, nGoodPix=None):
 
  118         """Finish creating the CoaddInputs for a CoaddTempExp. 
  120         @param[in,out] coaddTempExp   Exposure object from which to obtain the PSF, WCS, and bounding 
  121                                       box for the entry in the 'visits' table.  On return, the completed 
  122                                       CoaddInputs object will be attached to it. 
  123         @param[in]     nGoodPix       Total number of good pixels in the CoaddTempExp; ignored unless 
  124                                       saveVisitGoodPix is true. 
  127         if self.
tasktask.config.saveVisitGoodPix:
 
  128             self.
visitRecordvisitRecord.setI(self.
tasktask.visitGoodPixKey, nGoodPix)
 
  129         coaddTempExp.getInfo().setCoaddInputs(self.
coaddInputscoaddInputs)
 
  130         wcs = coaddTempExp.getWcs()
 
  135         coaddTempExp.getInfo().setApCorrMap(apCorrMap)
 
  137     def _setExposureInfoInRecord(self, exposure, record):
 
  138         """Set exposure info and bbox in an ExposureTable record 
  140         @param[in] exposure  exposure whose info is to be recorded 
  141         @param[in,out] record  record of an ExposureTable to set 
  143         info = exposure.getInfo()
 
  144         record.setPsf(info.getPsf())
 
  145         record.setWcs(info.getWcs())
 
  146         record.setPhotoCalib(info.getPhotoCalib())
 
  147         record.setApCorrMap(info.getApCorrMap())
 
  148         record.setValidPolygon(info.getValidPolygon())
 
  149         record.setVisitInfo(info.getVisitInfo())
 
  150         record.setBBox(exposure.getBBox())
 
  151         record.setTransmissionCurve(info.getTransmissionCurve())
 
  155     """Subtask that handles filling a CoaddInputs object for a coadd exposure, tracking the CCDs and 
  156     visits that went into a coadd. 
  158     The interface here is a little messy, but I think this is at least partly a product of a bit of 
  159     messiness in the coadd code it's plugged into.  I hope #2590 might result in a better design. 
  162     ConfigClass = CoaddInputRecorderConfig
 
  165         pipeBase.Task.__init__(self, *args, **kwargs)
 
  166         self.
visitSchemavisitSchema = afwTable.ExposureTable.makeMinimalSchema()
 
  167         if self.config.saveVisitGoodPix:
 
  169                                                              doc=
"Number of good pixels in the coaddTempExp")
 
  171                                                         doc=
"Weight for this visit in the coadd")
 
  172         self.
ccdSchemaccdSchema = afwTable.ExposureTable.makeMinimalSchema()
 
  173         self.
ccdCcdKeyccdCcdKey = self.
ccdSchemaccdSchema.addField(
"ccd", type=numpy.int32, doc=
"cameraGeom CCD serial number")
 
  175                                                    doc=
"Foreign key for the visits (coaddTempExp) catalog")
 
  177                                                      doc=
"Number of good pixels in this CCD")
 
  178         if self.config.saveCcdWeights:
 
  180                                                         doc=
"Weight for this visit in the coadd")
 
  182                                                         doc=
"Physical filter associated with this visit.")
 
  184                                                     doc=
"Physical filter associated with this visit.")
 
  187         """Return a CoaddTempExpInputRecorder instance to help with saving a CoaddTempExp's inputs. 
  189         The visitId may be any number that is unique for each CoaddTempExp that goes into a coadd, 
  190         but ideally should be something more meaningful that can be used to reconstruct a data ID. 
  195         """Create a CoaddInputs object with schemas defined by the task configuration""" 
  199         """Called by AssembleCoaddTask when adding (a subset of) a coaddTempExp to a coadd.  The 
  200         base class impementation extracts the CoaddInputs from the coaddTempExp and appends 
  201         them to the given coaddInputs, filling in the weight column(s). 
  203         Note that the passed coaddTempExp may be a subimage, but that this method will only be 
  204         called for the first subimage 
  206         Returns the record for the visit to allow subclasses to fill in additional fields. 
  207         Warns and returns None if the inputRecorder catalogs for the coaddTempExp are not usable. 
  209         tempExpInputs = coaddTempExp.getInfo().getCoaddInputs()
 
  210         if len(tempExpInputs.visits) != 1:
 
  211             self.log.
warning(
"CoaddInputs for coaddTempExp should have exactly one record in visits table " 
  212                              "(found %d).  CoaddInputs for this visit will not be saved.",
 
  213                              len(tempExpInputs.visits))
 
  215         inputVisitRecord = tempExpInputs.visits[0]
 
  216         outputVisitRecord = coaddInputs.visits.addNew()
 
  217         outputVisitRecord.assign(inputVisitRecord)
 
  219         outputVisitRecord.set(self.
visitFilterKeyvisitFilterKey, coaddTempExp.getFilterLabel().physicalLabel)
 
  220         for inputCcdRecord 
in tempExpInputs.ccds:
 
  221             if inputCcdRecord.getL(self.
ccdVisitKeyccdVisitKey) != inputVisitRecord.getId():
 
  222                 self.log.
warning(
"CoaddInputs for coaddTempExp with id %d contains CCDs with visit=%d. " 
  223                                  "CoaddInputs may be unreliable.",
 
  224                                  inputVisitRecord.getId(), inputCcdRecord.getL(self.
ccdVisitKeyccdVisitKey))
 
  225             outputCcdRecord = coaddInputs.ccds.addNew()
 
  226             outputCcdRecord.assign(inputCcdRecord)
 
  227             if self.config.saveCcdWeights:
 
  228                 outputCcdRecord.setD(self.
ccdWeightKeyccdWeightKey, weight)
 
  229             outputCcdRecord.set(self.
ccdFilterKeyccdFilterKey, coaddTempExp.getFilterLabel().physicalLabel)
 
  230         return inputVisitRecord
 
CoaddPsf is the Psf derived to be used for non-PSF-matched Coadd images.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
def makeCoaddApCorrMap(catalog, coaddBox, coaddWcs, weightFieldName="weight")
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations.