LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Public Member Functions | Public Attributes | Static Public Attributes | List of all members
lsst.pipe.tasks.calibrate.CalibrateTask Class Reference

Calibrate an exposure: measure sources and perform astrometric and photometric calibration. More...

Inheritance diagram for lsst.pipe.tasks.calibrate.CalibrateTask:

Public Member Functions

def __init__ (self, butler=None, astromRefObjLoader=None, photoRefObjLoader=None, icSourceSchema=None, initInputs=None, **kwargs)
 Construct a CalibrateTask. More...
 
def runDataRef (self, dataRef, exposure=None, background=None, icSourceCat=None, doUnpersist=True)
 Calibrate an exposure, optionally unpersisting inputs and persisting outputs. More...
 
def runQuantum (self, butlerQC, inputRefs, outputRefs)
 
def run (self, exposure, exposureIdInfo=None, background=None, icSourceCat=None)
 Calibrate an exposure (science image or coadd) More...
 
def writeOutputs (self, dataRef, exposure, background, sourceCat, astromMatches, matchMeta)
 
def getSchemaCatalogs (self)
 
def setMetadata (self, exposure, photoRes=None)
 Set task and exposure metadata. More...
 
def copyIcSourceFields (self, icSourceCat, sourceCat)
 Match sources in icSourceCat and sourceCat and copy the specified fields. More...
 

Public Attributes

 schemaMapper
 
 calibSourceKey
 
 schema
 
 algMetadata
 
 skySourceKey
 
 outputSchema
 

Static Public Attributes

 ConfigClass = CalibrateConfig
 
 RunnerClass = pipeBase.ButlerInitializedTaskRunner
 

Detailed Description

Calibrate an exposure: measure sources and perform astrometric and photometric calibration.

Contents

@section pipe_tasks_calibrate_Purpose  Description

Given an exposure with a good PSF model and aperture correction map
(e.g. as provided by @ref CharacterizeImageTask), perform the following
 operations:
- Run detection and measurement
- Run astrometry subtask to fit an improved WCS
- Run photoCal subtask to fit the exposure's photometric zero-point

@section pipe_tasks_calibrate_Initialize  Task initialisation

@copydoc \_\_init\_\_

@section pipe_tasks_calibrate_IO  Invoking the Task

If you want this task to unpersist inputs or persist outputs, then call
the `runDataRef` method (a wrapper around the `run` method).

If you already have the inputs unpersisted and do not want to persist the
output then it is more direct to call the `run` method:

@section pipe_tasks_calibrate_Config  Configuration parameters

See @ref CalibrateConfig

@section pipe_tasks_calibrate_Metadata  Quantities set in exposure Metadata

Exposure metadata
<dl>
    <dt>MAGZERO_RMS  <dd>MAGZERO's RMS == sigma reported by photoCal task
    <dt>MAGZERO_NOBJ <dd>Number of stars used == ngood reported by photoCal
                         task
    <dt>COLORTERM1   <dd>?? (always 0.0)
    <dt>COLORTERM2   <dd>?? (always 0.0)
    <dt>COLORTERM3   <dd>?? (always 0.0)
</dl>

@section pipe_tasks_calibrate_Debug  Debug variables

The @link lsst.pipe.base.cmdLineTask.CmdLineTask command line task@endlink
interface supports a flag
`--debug` to import `debug.py` from your `$PYTHONPATH`; see @ref baseDebug
for more about `debug.py`.

CalibrateTask has a debug dictionary containing one key:
<dl>
<dt>calibrate
<dd>frame (an int; <= 0 to not display) in which to display the exposure,
    sources and matches. See @ref lsst.meas.astrom.displayAstrometry for
    the meaning of the various symbols.
</dl>

For example, put something like:
@code{.py}
    import lsstDebug
    def DebugInfo(name):
        di = lsstDebug.getInfo(name)  # N.b. lsstDebug.Info(name) would
                                      # call us recursively
        if name == "lsst.pipe.tasks.calibrate":
            di.display = dict(
                calibrate = 1,
            )

        return di

    lsstDebug.Info = DebugInfo
@endcode
into your `debug.py` file and run `calibrateTask.py` with the `--debug`
flag.

Some subtasks may have their own debug variables; see individual Task
documentation.

Definition at line 337 of file calibrate.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.pipe.tasks.calibrate.CalibrateTask.__init__ (   self,
  butler = None,
  astromRefObjLoader = None,
  photoRefObjLoader = None,
  icSourceSchema = None,
  initInputs = None,
**  kwargs 
)

Construct a CalibrateTask.

    @param[in] butler  The butler is passed to the refObjLoader constructor
        in case it is needed.  Ignored if the refObjLoader argument
        provides a loader directly.
    @param[in] astromRefObjLoader  An instance of LoadReferenceObjectsTasks
        that supplies an external reference catalog for astrometric
        calibration.  May be None if the desired loader can be constructed
        from the butler argument or all steps requiring a reference catalog
        are disabled.
    @param[in] photoRefObjLoader  An instance of LoadReferenceObjectsTasks
        that supplies an external reference catalog for photometric
        calibration.  May be None if the desired loader can be constructed
        from the butler argument or all steps requiring a reference catalog
        are disabled.
    @param[in] icSourceSchema  schema for icSource catalog, or None.
        Schema values specified in config.icSourceFieldsToCopy will be
        taken from this schema. If set to None, no values will be
        propagated from the icSourceCatalog
    @param[in,out] kwargs  other keyword arguments for
        lsst.pipe.base.CmdLineTask

Definition at line 434 of file calibrate.py.

436  initInputs=None, **kwargs):
437  """!Construct a CalibrateTask
438 
439  @param[in] butler The butler is passed to the refObjLoader constructor
440  in case it is needed. Ignored if the refObjLoader argument
441  provides a loader directly.
442  @param[in] astromRefObjLoader An instance of LoadReferenceObjectsTasks
443  that supplies an external reference catalog for astrometric
444  calibration. May be None if the desired loader can be constructed
445  from the butler argument or all steps requiring a reference catalog
446  are disabled.
447  @param[in] photoRefObjLoader An instance of LoadReferenceObjectsTasks
448  that supplies an external reference catalog for photometric
449  calibration. May be None if the desired loader can be constructed
450  from the butler argument or all steps requiring a reference catalog
451  are disabled.
452  @param[in] icSourceSchema schema for icSource catalog, or None.
453  Schema values specified in config.icSourceFieldsToCopy will be
454  taken from this schema. If set to None, no values will be
455  propagated from the icSourceCatalog
456  @param[in,out] kwargs other keyword arguments for
457  lsst.pipe.base.CmdLineTask
458  """
459  super().__init__(**kwargs)
460 
461  if icSourceSchema is None and butler is not None:
462  # Use butler to read icSourceSchema from disk.
463  icSourceSchema = butler.get("icSrc_schema", immediate=True).schema
464 
465  if icSourceSchema is None and butler is None and initInputs is not None:
466  icSourceSchema = initInputs['icSourceSchema'].schema
467 
468  if icSourceSchema is not None:
469  # use a schema mapper to avoid copying each field separately
470  self.schemaMapper = afwTable.SchemaMapper(icSourceSchema)
471  minimumSchema = afwTable.SourceTable.makeMinimalSchema()
472  self.schemaMapper.addMinimalSchema(minimumSchema, False)
473 
474  # Add fields to copy from an icSource catalog
475  # and a field to indicate that the source matched a source in that
476  # catalog. If any fields are missing then raise an exception, but
477  # first find all missing fields in order to make the error message
478  # more useful.
479  self.calibSourceKey = self.schemaMapper.addOutputField(
480  afwTable.Field["Flag"]("calib_detected",
481  "Source was detected as an icSource"))
482  missingFieldNames = []
483  for fieldName in self.config.icSourceFieldsToCopy:
484  try:
485  schemaItem = icSourceSchema.find(fieldName)
486  except Exception:
487  missingFieldNames.append(fieldName)
488  else:
489  # field found; if addMapping fails then raise an exception
490  self.schemaMapper.addMapping(schemaItem.getKey())
491 
492  if missingFieldNames:
493  raise RuntimeError("isSourceCat is missing fields {} "
494  "specified in icSourceFieldsToCopy"
495  .format(missingFieldNames))
496 
497  # produce a temporary schema to pass to the subtasks; finalize it
498  # later
499  self.schema = self.schemaMapper.editOutputSchema()
500  else:
501  self.schemaMapper = None
502  self.schema = afwTable.SourceTable.makeMinimalSchema()
503  self.makeSubtask('detection', schema=self.schema)
504 
505  self.algMetadata = dafBase.PropertyList()
506 
507  # Only create a subtask for fakes if configuration option is set
508  # N.B. the config for fake object task must be retargeted to a child
509  # of BaseFakeSourcesTask
510  if self.config.doInsertFakes:
511  self.makeSubtask("insertFakes")
512 
513  if self.config.doDeblend:
514  self.makeSubtask("deblend", schema=self.schema)
515  if self.config.doSkySources:
516  self.makeSubtask("skySources")
517  self.skySourceKey = self.schema.addField("sky_source", type="Flag", doc="Sky objects.")
518  self.makeSubtask('measurement', schema=self.schema,
519  algMetadata=self.algMetadata)
520  self.makeSubtask("setPrimaryFlags", schema=self.schema, isSingleFrame=True)
521  if self.config.doApCorr:
522  self.makeSubtask('applyApCorr', schema=self.schema)
523  self.makeSubtask('catalogCalculation', schema=self.schema)
524 
525  if self.config.doAstrometry:
526  if astromRefObjLoader is None and butler is not None:
527  self.makeSubtask('astromRefObjLoader', butler=butler)
528  astromRefObjLoader = self.astromRefObjLoader
529  self.makeSubtask("astrometry", refObjLoader=astromRefObjLoader,
530  schema=self.schema)
531  if self.config.doPhotoCal:
532  if photoRefObjLoader is None and butler is not None:
533  self.makeSubtask('photoRefObjLoader', butler=butler)
534  photoRefObjLoader = self.photoRefObjLoader
535  self.makeSubtask("photoCal", refObjLoader=photoRefObjLoader,
536  schema=self.schema)
537  if self.config.doComputeSummaryStats:
538  self.makeSubtask('computeSummaryStats')
539 
540  if initInputs is not None and (astromRefObjLoader is not None or photoRefObjLoader is not None):
541  raise RuntimeError("PipelineTask form of this task should not be initialized with "
542  "reference object loaders.")
543 
544  if self.schemaMapper is not None:
545  # finalize the schema
546  self.schema = self.schemaMapper.getOutputSchema()
547  self.schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
548 
549  sourceCatSchema = afwTable.SourceCatalog(self.schema)
550  sourceCatSchema.getTable().setMetadata(self.algMetadata)
551  self.outputSchema = sourceCatSchema
552 
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:21
Class for storing ordered metadata with comments.
Definition: PropertyList.h:68
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A description of a field in a table.
Definition: Field.h:24

Member Function Documentation

◆ copyIcSourceFields()

def lsst.pipe.tasks.calibrate.CalibrateTask.copyIcSourceFields (   self,
  icSourceCat,
  sourceCat 
)

Match sources in icSourceCat and sourceCat and copy the specified fields.

    @param[in] icSourceCat  catalog from which to copy fields
    @param[in,out] sourceCat  catalog to which to copy fields

    The fields copied are those specified by `config.icSourceFieldsToCopy`
    that actually exist in the schema. This was set up by the constructor
    using self.schemaMapper.

Definition at line 888 of file calibrate.py.

888  def copyIcSourceFields(self, icSourceCat, sourceCat):
889  """!Match sources in icSourceCat and sourceCat and copy the specified fields
890 
891  @param[in] icSourceCat catalog from which to copy fields
892  @param[in,out] sourceCat catalog to which to copy fields
893 
894  The fields copied are those specified by `config.icSourceFieldsToCopy`
895  that actually exist in the schema. This was set up by the constructor
896  using self.schemaMapper.
897  """
898  if self.schemaMapper is None:
899  raise RuntimeError("To copy icSource fields you must specify "
900  "icSourceSchema nd icSourceKeys when "
901  "constructing this task")
902  if icSourceCat is None or sourceCat is None:
903  raise RuntimeError("icSourceCat and sourceCat must both be "
904  "specified")
905  if len(self.config.icSourceFieldsToCopy) == 0:
906  self.log.warning("copyIcSourceFields doing nothing because "
907  "icSourceFieldsToCopy is empty")
908  return
909 
910  mc = afwTable.MatchControl()
911  mc.findOnlyClosest = False # return all matched objects
912  matches = afwTable.matchXy(icSourceCat, sourceCat,
913  self.config.matchRadiusPix, mc)
914  if self.config.doDeblend:
915  deblendKey = sourceCat.schema["deblend_nChild"].asKey()
916  # if deblended, keep children
917  matches = [m for m in matches if m[1].get(deblendKey) == 0]
918 
919  # Because we had to allow multiple matches to handle parents, we now
920  # need to prune to the best matches
921  # closest matches as a dict of icSourceCat source ID:
922  # (icSourceCat source, sourceCat source, distance in pixels)
923  bestMatches = {}
924  for m0, m1, d in matches:
925  id0 = m0.getId()
926  match = bestMatches.get(id0)
927  if match is None or d <= match[2]:
928  bestMatches[id0] = (m0, m1, d)
929  matches = list(bestMatches.values())
930 
931  # Check that no sourceCat sources are listed twice (we already know
932  # that each match has a unique icSourceCat source ID, due to using
933  # that ID as the key in bestMatches)
934  numMatches = len(matches)
935  numUniqueSources = len(set(m[1].getId() for m in matches))
936  if numUniqueSources != numMatches:
937  self.log.warning("%d icSourceCat sources matched only %d sourceCat "
938  "sources", numMatches, numUniqueSources)
939 
940  self.log.info("Copying flags from icSourceCat to sourceCat for "
941  "%d sources", numMatches)
942 
943  # For each match: set the calibSourceKey flag and copy the desired
944  # fields
945  for icSrc, src, d in matches:
946  src.setFlag(self.calibSourceKey, True)
947  # src.assign copies the footprint from icSrc, which we don't want
948  # (DM-407)
949  # so set icSrc's footprint to src's footprint before src.assign,
950  # then restore it
951  icSrcFootprint = icSrc.getFootprint()
952  try:
953  icSrc.setFootprint(src.getFootprint())
954  src.assign(icSrc, self.schemaMapper)
955  finally:
956  icSrc.setFootprint(icSrcFootprint)
Pass parameters to algorithms that match list of sources.
Definition: Match.h:45
daf::base::PropertyList * list
Definition: fits.cc:913
daf::base::PropertySet * set
Definition: fits.cc:912
SourceMatchVector matchXy(SourceCatalog const &cat1, SourceCatalog const &cat2, double radius, MatchControl const &mc=MatchControl())
Compute all tuples (s1,s2,d) where s1 belings to cat1, s2 belongs to cat2 and d, the distance between...
Definition: Match.cc:305

◆ getSchemaCatalogs()

def lsst.pipe.tasks.calibrate.CalibrateTask.getSchemaCatalogs (   self)
Return a dict of empty catalogs for each catalog dataset produced
by this task.

Definition at line 847 of file calibrate.py.

847  def getSchemaCatalogs(self):
848  """Return a dict of empty catalogs for each catalog dataset produced
849  by this task.
850  """
851  sourceCat = afwTable.SourceCatalog(self.schema)
852  sourceCat.getTable().setMetadata(self.algMetadata)
853  return {"src": sourceCat}
854 

◆ run()

def lsst.pipe.tasks.calibrate.CalibrateTask.run (   self,
  exposure,
  exposureIdInfo = None,
  background = None,
  icSourceCat = None 
)

Calibrate an exposure (science image or coadd)

    @param[in,out] exposure  exposure to calibrate (an
        lsst.afw.image.ExposureF or similar);
        in:
        - MaskedImage
        - Psf
        out:
        - MaskedImage has background subtracted
        - Wcs is replaced
        - PhotoCalib is replaced
    @param[in] exposureIdInfo  ID info for exposure (an
        lsst.obs.base.ExposureIdInfo) If not provided, returned
        SourceCatalog IDs will not be globally unique.
    @param[in,out] background  background model already subtracted from
        exposure (an lsst.afw.math.BackgroundList). May be None if no
        background has been subtracted, though that is unusual for
        calibration. A refined background model is output.
    @param[in] icSourceCat  A SourceCatalog from CharacterizeImageTask
        from which we can copy some fields.

    @return pipe_base Struct containing these fields:
    - exposure  calibrate science exposure with refined WCS and PhotoCalib
    - background  model of background subtracted from exposure (an
      lsst.afw.math.BackgroundList)
    - sourceCat  catalog of measured sources
    - astromMatches  list of source/refObj matches from the astrometry
      solver

Definition at line 648 of file calibrate.py.

649  icSourceCat=None):
650  """!Calibrate an exposure (science image or coadd)
651 
652  @param[in,out] exposure exposure to calibrate (an
653  lsst.afw.image.ExposureF or similar);
654  in:
655  - MaskedImage
656  - Psf
657  out:
658  - MaskedImage has background subtracted
659  - Wcs is replaced
660  - PhotoCalib is replaced
661  @param[in] exposureIdInfo ID info for exposure (an
662  lsst.obs.base.ExposureIdInfo) If not provided, returned
663  SourceCatalog IDs will not be globally unique.
664  @param[in,out] background background model already subtracted from
665  exposure (an lsst.afw.math.BackgroundList). May be None if no
666  background has been subtracted, though that is unusual for
667  calibration. A refined background model is output.
668  @param[in] icSourceCat A SourceCatalog from CharacterizeImageTask
669  from which we can copy some fields.
670 
671  @return pipe_base Struct containing these fields:
672  - exposure calibrate science exposure with refined WCS and PhotoCalib
673  - background model of background subtracted from exposure (an
674  lsst.afw.math.BackgroundList)
675  - sourceCat catalog of measured sources
676  - astromMatches list of source/refObj matches from the astrometry
677  solver
678  """
679  # detect, deblend and measure sources
680  if exposureIdInfo is None:
681  exposureIdInfo = ExposureIdInfo()
682 
683  if background is None:
684  background = BackgroundList()
685  sourceIdFactory = exposureIdInfo.makeSourceIdFactory()
686  table = SourceTable.make(self.schema, sourceIdFactory)
687  table.setMetadata(self.algMetadata)
688 
689  detRes = self.detection.run(table=table, exposure=exposure,
690  doSmooth=True)
691  sourceCat = detRes.sources
692  if detRes.fpSets.background:
693  for bg in detRes.fpSets.background:
694  background.append(bg)
695  if self.config.doSkySources:
696  skySourceFootprints = self.skySources.run(mask=exposure.mask, seed=exposureIdInfo.expId)
697  if skySourceFootprints:
698  for foot in skySourceFootprints:
699  s = sourceCat.addNew()
700  s.setFootprint(foot)
701  s.set(self.skySourceKey, True)
702  if self.config.doDeblend:
703  self.deblend.run(exposure=exposure, sources=sourceCat)
704  self.measurement.run(
705  measCat=sourceCat,
706  exposure=exposure,
707  exposureId=exposureIdInfo.expId
708  )
709  if self.config.doApCorr:
710  self.applyApCorr.run(
711  catalog=sourceCat,
712  apCorrMap=exposure.getInfo().getApCorrMap()
713  )
714  self.catalogCalculation.run(sourceCat)
715 
716  self.setPrimaryFlags.run(sourceCat)
717 
718  if icSourceCat is not None and \
719  len(self.config.icSourceFieldsToCopy) > 0:
720  self.copyIcSourceFields(icSourceCat=icSourceCat,
721  sourceCat=sourceCat)
722 
723  # TODO DM-11568: this contiguous check-and-copy could go away if we
724  # reserve enough space during SourceDetection and/or SourceDeblend.
725  # NOTE: sourceSelectors require contiguous catalogs, so ensure
726  # contiguity now, so views are preserved from here on.
727  if not sourceCat.isContiguous():
728  sourceCat = sourceCat.copy(deep=True)
729 
730  # perform astrometry calibration:
731  # fit an improved WCS and update the exposure's WCS in place
732  astromMatches = None
733  matchMeta = None
734  if self.config.doAstrometry:
735  try:
736  astromRes = self.astrometry.run(
737  exposure=exposure,
738  sourceCat=sourceCat,
739  )
740  astromMatches = astromRes.matches
741  matchMeta = astromRes.matchMeta
742  except Exception as e:
743  if self.config.requireAstrometry:
744  raise
745  self.log.warning("Unable to perform astrometric calibration "
746  "(%s): attempting to proceed", e)
747 
748  # compute photometric calibration
749  if self.config.doPhotoCal:
750  try:
751  photoRes = self.photoCal.run(exposure, sourceCat=sourceCat, expId=exposureIdInfo.expId)
752  exposure.setPhotoCalib(photoRes.photoCalib)
753  # TODO: reword this to phrase it in terms of the calibration factor?
754  self.log.info("Photometric zero-point: %f",
755  photoRes.photoCalib.instFluxToMagnitude(1.0))
756  self.setMetadata(exposure=exposure, photoRes=photoRes)
757  except Exception as e:
758  if self.config.requirePhotoCal:
759  raise
760  self.log.warning("Unable to perform photometric calibration "
761  "(%s): attempting to proceed", e)
762  self.setMetadata(exposure=exposure, photoRes=None)
763 
764  if self.config.doInsertFakes:
765  self.insertFakes.run(exposure, background=background)
766 
767  table = SourceTable.make(self.schema, sourceIdFactory)
768  table.setMetadata(self.algMetadata)
769 
770  detRes = self.detection.run(table=table, exposure=exposure,
771  doSmooth=True)
772  sourceCat = detRes.sources
773  if detRes.fpSets.background:
774  for bg in detRes.fpSets.background:
775  background.append(bg)
776  if self.config.doDeblend:
777  self.deblend.run(exposure=exposure, sources=sourceCat)
778  self.measurement.run(
779  measCat=sourceCat,
780  exposure=exposure,
781  exposureId=exposureIdInfo.expId
782  )
783  if self.config.doApCorr:
784  self.applyApCorr.run(
785  catalog=sourceCat,
786  apCorrMap=exposure.getInfo().getApCorrMap()
787  )
788  self.catalogCalculation.run(sourceCat)
789 
790  if icSourceCat is not None and len(self.config.icSourceFieldsToCopy) > 0:
791  self.copyIcSourceFields(icSourceCat=icSourceCat,
792  sourceCat=sourceCat)
793 
794  if self.config.doComputeSummaryStats:
795  summary = self.computeSummaryStats.run(exposure=exposure,
796  sources=sourceCat,
797  background=background)
798  exposure.getInfo().setSummaryStats(summary)
799 
800  frame = getDebugFrame(self._display, "calibrate")
801  if frame:
803  sourceCat=sourceCat,
804  exposure=exposure,
805  matches=astromMatches,
806  frame=frame,
807  pause=False,
808  )
809 
810  return pipeBase.Struct(
811  exposure=exposure,
812  background=background,
813  sourceCat=sourceCat,
814  astromMatches=astromMatches,
815  matchMeta=matchMeta,
816  # These are duplicate entries with different names for use with
817  # gen3 middleware
818  outputExposure=exposure,
819  outputCat=sourceCat,
820  outputBackground=background,
821  )
822 
def run(self, coaddExposures, bbox, wcs)
Definition: getTemplate.py:603
def displayAstrometry(refCat=None, sourceCat=None, distortedCentroidKey=None, bbox=None, exposure=None, matches=None, frame=1, title="", pause=True)
Definition: display.py:34
def getDebugFrame(debugDisplay, name)
Definition: lsstDebug.py:95

◆ runDataRef()

def lsst.pipe.tasks.calibrate.CalibrateTask.runDataRef (   self,
  dataRef,
  exposure = None,
  background = None,
  icSourceCat = None,
  doUnpersist = True 
)

Calibrate an exposure, optionally unpersisting inputs and persisting outputs.

This is a wrapper around the run method that unpersists inputs (if doUnpersist true) and persists outputs (if config.doWrite true)

Parameters
[in]dataRefbutler data reference corresponding to a science image
[in,out]exposurecharacterized exposure (an lsst.afw.image.ExposureF or similar), or None to unpersist existing icExp and icBackground. See run method for details of what is read and written.
[in,out]backgroundinitial model of background already subtracted from exposure (an lsst.afw.math.BackgroundList). May be None if no background has been subtracted, though that is unusual for calibration. A refined background model is output. Ignored if exposure is None.
[in]icSourceCatcatalog from which to copy the fields specified by icSourceKeys, or None;
[in]doUnpersistunpersist data:
  • if True, exposure, background and icSourceCat are read from dataRef and those three arguments must all be None;
  • if False the exposure must be provided; background and icSourceCat are optional. True is intended for running as a command-line task, False for running as a subtask
Returns
same data as the calibrate method

Definition at line 554 of file calibrate.py.

555  doUnpersist=True):
556  """!Calibrate an exposure, optionally unpersisting inputs and
557  persisting outputs.
558 
559  This is a wrapper around the `run` method that unpersists inputs
560  (if `doUnpersist` true) and persists outputs (if `config.doWrite` true)
561 
562  @param[in] dataRef butler data reference corresponding to a science
563  image
564  @param[in,out] exposure characterized exposure (an
565  lsst.afw.image.ExposureF or similar), or None to unpersist existing
566  icExp and icBackground. See `run` method for details of what is
567  read and written.
568  @param[in,out] background initial model of background already
569  subtracted from exposure (an lsst.afw.math.BackgroundList). May be
570  None if no background has been subtracted, though that is unusual
571  for calibration. A refined background model is output. Ignored if
572  exposure is None.
573  @param[in] icSourceCat catalog from which to copy the fields specified
574  by icSourceKeys, or None;
575  @param[in] doUnpersist unpersist data:
576  - if True, exposure, background and icSourceCat are read from
577  dataRef and those three arguments must all be None;
578  - if False the exposure must be provided; background and
579  icSourceCat are optional. True is intended for running as a
580  command-line task, False for running as a subtask
581  @return same data as the calibrate method
582  """
583  self.log.info("Processing %s", dataRef.dataId)
584 
585  if doUnpersist:
586  if any(item is not None for item in (exposure, background,
587  icSourceCat)):
588  raise RuntimeError("doUnpersist true; exposure, background "
589  "and icSourceCat must all be None")
590  exposure = dataRef.get("icExp", immediate=True)
591  background = dataRef.get("icExpBackground", immediate=True)
592  icSourceCat = dataRef.get("icSrc", immediate=True)
593  elif exposure is None:
594  raise RuntimeError("doUnpersist false; exposure must be provided")
595 
596  exposureIdInfo = dataRef.get("expIdInfo")
597 
598  calRes = self.run(
599  exposure=exposure,
600  exposureIdInfo=exposureIdInfo,
601  background=background,
602  icSourceCat=icSourceCat,
603  )
604 
605  if self.config.doWrite:
606  self.writeOutputs(
607  dataRef=dataRef,
608  exposure=calRes.exposure,
609  background=calRes.background,
610  sourceCat=calRes.sourceCat,
611  astromMatches=calRes.astromMatches,
612  matchMeta=calRes.matchMeta,
613  )
614 
615  return calRes
616 
bool any(CoordinateExpr< N > const &expr) noexcept
Return true if any elements are true.

◆ runQuantum()

def lsst.pipe.tasks.calibrate.CalibrateTask.runQuantum (   self,
  butlerQC,
  inputRefs,
  outputRefs 
)

Definition at line 617 of file calibrate.py.

617  def runQuantum(self, butlerQC, inputRefs, outputRefs):
618  inputs = butlerQC.get(inputRefs)
619  inputs['exposureIdInfo'] = ExposureIdInfo.fromDataId(butlerQC.quantum.dataId, "visit_detector")
620 
621  if self.config.doAstrometry:
622  refObjLoader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
623  for ref in inputRefs.astromRefCat],
624  refCats=inputs.pop('astromRefCat'),
625  config=self.config.astromRefObjLoader, log=self.log)
626  self.astrometry.setRefObjLoader(refObjLoader)
627 
628  if self.config.doPhotoCal:
629  photoRefObjLoader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
630  for ref in inputRefs.photoRefCat],
631  refCats=inputs.pop('photoRefCat'),
632  config=self.config.photoRefObjLoader,
633  log=self.log)
634  self.photoCal.match.setRefObjLoader(photoRefObjLoader)
635 
636  outputs = self.run(**inputs)
637 
638  if self.config.doWriteMatches and self.config.doAstrometry:
639  normalizedMatches = afwTable.packMatches(outputs.astromMatches)
640  normalizedMatches.table.setMetadata(outputs.matchMeta)
641  if self.config.doWriteMatchesDenormalized:
642  denormMatches = denormalizeMatches(outputs.astromMatches, outputs.matchMeta)
643  outputs.matchesDenormalized = denormMatches
644  outputs.matches = normalizedMatches
645  butlerQC.put(outputs, outputRefs)
646 
BaseCatalog packMatches(std::vector< Match< Record1, Record2 > > const &matches)
Return a table representation of a MatchVector that can be used to persist it.
Definition: Match.cc:432
def denormalizeMatches(matches, matchMeta=None)

◆ setMetadata()

def lsst.pipe.tasks.calibrate.CalibrateTask.setMetadata (   self,
  exposure,
  photoRes = None 
)

Set task and exposure metadata.

    Logs a warning and continues if needed data is missing.

    @param[in,out] exposure  exposure whose metadata is to be set
    @param[in]  photoRes  results of running photoCal; if None then it was
        not run

Definition at line 855 of file calibrate.py.

855  def setMetadata(self, exposure, photoRes=None):
856  """!Set task and exposure metadata
857 
858  Logs a warning and continues if needed data is missing.
859 
860  @param[in,out] exposure exposure whose metadata is to be set
861  @param[in] photoRes results of running photoCal; if None then it was
862  not run
863  """
864  if photoRes is None:
865  return
866 
867  metadata = exposure.getMetadata()
868 
869  # convert zero-point to (mag/sec/adu) for task MAGZERO metadata
870  try:
871  exposureTime = exposure.getInfo().getVisitInfo().getExposureTime()
872  magZero = photoRes.zp - 2.5*math.log10(exposureTime)
873  except Exception:
874  self.log.warning("Could not set normalized MAGZERO in header: no "
875  "exposure time")
876  magZero = math.nan
877 
878  try:
879  metadata.set('MAGZERO', magZero)
880  metadata.set('MAGZERO_RMS', photoRes.sigma)
881  metadata.set('MAGZERO_NOBJ', photoRes.ngood)
882  metadata.set('COLORTERM1', 0.0)
883  metadata.set('COLORTERM2', 0.0)
884  metadata.set('COLORTERM3', 0.0)
885  except Exception as e:
886  self.log.warning("Could not set exposure metadata: %s", e)
887 

◆ writeOutputs()

def lsst.pipe.tasks.calibrate.CalibrateTask.writeOutputs (   self,
  dataRef,
  exposure,
  background,
  sourceCat,
  astromMatches,
  matchMeta 
)
Write output data to the output repository

@param[in] dataRef  butler data reference corresponding to a science
    image
@param[in] exposure  exposure to write
@param[in] background  background model for exposure
@param[in] sourceCat  catalog of measured sources
@param[in] astromMatches  list of source/refObj matches from the
    astrometry solver

Definition at line 823 of file calibrate.py.

824  astromMatches, matchMeta):
825  """Write output data to the output repository
826 
827  @param[in] dataRef butler data reference corresponding to a science
828  image
829  @param[in] exposure exposure to write
830  @param[in] background background model for exposure
831  @param[in] sourceCat catalog of measured sources
832  @param[in] astromMatches list of source/refObj matches from the
833  astrometry solver
834  """
835  dataRef.put(sourceCat, "src")
836  if self.config.doWriteMatches and astromMatches is not None:
837  normalizedMatches = afwTable.packMatches(astromMatches)
838  normalizedMatches.table.setMetadata(matchMeta)
839  dataRef.put(normalizedMatches, "srcMatch")
840  if self.config.doWriteMatchesDenormalized:
841  denormMatches = denormalizeMatches(astromMatches, matchMeta)
842  dataRef.put(denormMatches, "srcMatchFull")
843  if self.config.doWriteExposure:
844  dataRef.put(exposure, "calexp")
845  dataRef.put(background, "calexpBackground")
846 

Member Data Documentation

◆ algMetadata

lsst.pipe.tasks.calibrate.CalibrateTask.algMetadata

Definition at line 505 of file calibrate.py.

◆ calibSourceKey

lsst.pipe.tasks.calibrate.CalibrateTask.calibSourceKey

Definition at line 479 of file calibrate.py.

◆ ConfigClass

lsst.pipe.tasks.calibrate.CalibrateTask.ConfigClass = CalibrateConfig
static

Definition at line 430 of file calibrate.py.

◆ outputSchema

lsst.pipe.tasks.calibrate.CalibrateTask.outputSchema

Definition at line 551 of file calibrate.py.

◆ RunnerClass

lsst.pipe.tasks.calibrate.CalibrateTask.RunnerClass = pipeBase.ButlerInitializedTaskRunner
static

Definition at line 432 of file calibrate.py.

◆ schema

lsst.pipe.tasks.calibrate.CalibrateTask.schema

Definition at line 499 of file calibrate.py.

◆ schemaMapper

lsst.pipe.tasks.calibrate.CalibrateTask.schemaMapper

Definition at line 470 of file calibrate.py.

◆ skySourceKey

lsst.pipe.tasks.calibrate.CalibrateTask.skySourceKey

Definition at line 517 of file calibrate.py.


The documentation for this class was generated from the following file: