24 from lsstDebug
import getDebugFrame
25 import lsst.pex.config
as pexConfig
29 from lsst.meas.astrom import AstrometryTask, displayAstrometry, denormalizeMatches
38 CatalogCalculationTask,
39 EvaluateLocalCalibrationTask)
41 from .fakes
import BaseFakeSourcesTask
42 from .photoCal
import PhotoCalTask
44 __all__ = [
"CalibrateConfig",
"CalibrateTask"]
50 icSourceSchema = cT.InitInput(
51 doc=
"Schema produced by characterize image task, used to initialize this task",
53 storageClass=
"SourceCatalog",
57 outputSchema = cT.InitOutput(
58 doc=
"Schema after CalibrateTask has been initialized",
60 storageClass=
"SourceCatalog",
65 doc=
"Input image to calibrate",
67 storageClass=
"ExposureF",
68 dimensions=(
"instrument",
"visit",
"detector"),
71 background = cT.Input(
72 doc=
"Backgrounds determined by characterize task",
73 name=
"icExpBackground",
74 storageClass=
"Background",
75 dimensions=(
"instrument",
"visit",
"detector"),
78 icSourceCat = cT.Input(
79 doc=
"Source catalog created by characterize task",
81 storageClass=
"SourceCatalog",
82 dimensions=(
"instrument",
"visit",
"detector"),
85 astromRefCat = cT.PrerequisiteInput(
86 doc=
"Reference catalog to use for astrometry",
88 storageClass=
"SimpleCatalog",
89 dimensions=(
"skypix",),
94 photoRefCat = cT.PrerequisiteInput(
95 doc=
"Reference catalog to use for photometric calibration",
97 storageClass=
"SimpleCatalog",
98 dimensions=(
"skypix",),
103 outputExposure = cT.Output(
104 doc=
"Exposure after running calibration task",
106 storageClass=
"ExposureF",
107 dimensions=(
"instrument",
"visit",
"detector"),
110 outputCat = cT.Output(
111 doc=
"Source catalog produced in calibrate task",
113 storageClass=
"SourceCatalog",
114 dimensions=(
"instrument",
"visit",
"detector"),
117 outputBackground = cT.Output(
118 doc=
"Background models estimated in calibration task",
119 name=
"calexpBackground",
120 storageClass=
"Background",
121 dimensions=(
"instrument",
"visit",
"detector"),
125 doc=
"Source/refObj matches from the astrometry solver",
127 storageClass=
"Catalog",
128 dimensions=(
"instrument",
"visit",
"detector"),
131 matchesDenormalized = cT.Output(
132 doc=
"Denormalized matches from astrometry solver",
134 storageClass=
"Catalog",
135 dimensions=(
"instrument",
"visit",
"detector"),
140 if config.doWriteMatches
is False:
141 self.outputs.remove(
"matches")
142 if config.doWriteMatchesDenormalized
is False:
143 self.outputs.remove(
"matchesDenormalized")
146 class CalibrateConfig(pipeBase.PipelineTaskConfig, pipelineConnections=CalibrateConnections):
147 """Config for CalibrateTask""" 148 doWrite = pexConfig.Field(
151 doc=
"Save calibration results?",
153 doWriteHeavyFootprintsInSources = pexConfig.Field(
156 doc=
"Include HeavyFootprint data in source table? If false then heavy " 157 "footprints are saved as normal footprints, which saves some space" 159 doWriteMatches = pexConfig.Field(
162 doc=
"Write reference matches (ignored if doWrite false)?",
164 doWriteMatchesDenormalized = pexConfig.Field(
167 doc=(
"Write reference matches in denormalized format? " 168 "This format uses more disk space, but is more convenient to " 169 "read. Ignored if doWriteMatches=False or doWrite=False."),
171 doAstrometry = pexConfig.Field(
174 doc=
"Perform astrometric calibration?",
176 astromRefObjLoader = pexConfig.ConfigurableField(
177 target=LoadIndexedReferenceObjectsTask,
178 doc=
"reference object loader for astrometric calibration",
180 photoRefObjLoader = pexConfig.ConfigurableField(
181 target=LoadIndexedReferenceObjectsTask,
182 doc=
"reference object loader for photometric calibration",
184 astrometry = pexConfig.ConfigurableField(
185 target=AstrometryTask,
186 doc=
"Perform astrometric calibration to refine the WCS",
188 requireAstrometry = pexConfig.Field(
191 doc=(
"Raise an exception if astrometry fails? Ignored if doAstrometry " 194 doPhotoCal = pexConfig.Field(
197 doc=
"Perform phometric calibration?",
199 requirePhotoCal = pexConfig.Field(
202 doc=(
"Raise an exception if photoCal fails? Ignored if doPhotoCal " 205 photoCal = pexConfig.ConfigurableField(
207 doc=
"Perform photometric calibration",
209 doEvalLocCalibration = pexConfig.Field(
212 doc=
"Store calibration products (local wcs and PhotoCalib) in output " 215 evalLocCalib = pexConfig.ConfigurableField(
216 target=EvaluateLocalCalibrationTask,
217 doc=
"Task to strip calibrations from an exposure and store their " 218 "local values in the output source catalog." 220 icSourceFieldsToCopy = pexConfig.ListField(
222 default=(
"calib_psf_candidate",
"calib_psf_used",
"calib_psf_reserved"),
223 doc=(
"Fields to copy from the icSource catalog to the output catalog " 224 "for matching sources Any missing fields will trigger a " 225 "RuntimeError exception. Ignored if icSourceCat is not provided.")
227 matchRadiusPix = pexConfig.Field(
230 doc=(
"Match radius for matching icSourceCat objects to sourceCat " 233 checkUnitsParseStrict = pexConfig.Field(
234 doc=(
"Strictness of Astropy unit compatibility check, can be 'raise', " 235 "'warn' or 'silent'"),
239 detection = pexConfig.ConfigurableField(
240 target=SourceDetectionTask,
243 doDeblend = pexConfig.Field(
246 doc=
"Run deblender input exposure" 248 deblend = pexConfig.ConfigurableField(
249 target=SourceDeblendTask,
250 doc=
"Split blended sources into their components" 252 measurement = pexConfig.ConfigurableField(
253 target=SingleFrameMeasurementTask,
254 doc=
"Measure sources" 256 doApCorr = pexConfig.Field(
259 doc=
"Run subtask to apply aperture correction" 261 applyApCorr = pexConfig.ConfigurableField(
262 target=ApplyApCorrTask,
263 doc=
"Subtask to apply aperture corrections" 268 catalogCalculation = pexConfig.ConfigurableField(
269 target=CatalogCalculationTask,
270 doc=
"Subtask to run catalogCalculation plugins on catalog" 272 doInsertFakes = pexConfig.Field(
275 doc=
"Run fake sources injection task" 277 insertFakes = pexConfig.ConfigurableField(
278 target=BaseFakeSourcesTask,
279 doc=
"Injection of fake sources for testing purposes (must be " 282 doWriteExposure = pexConfig.Field(
285 doc=
"Write the calexp? If fakes have been added then we do not want to write out the calexp as a " 286 "normal calexp but as a fakes_calexp." 291 self.
detection.doTempLocalBackground =
False 292 self.
deblend.maxFootprintSize = 2000
297 if astromRefCatGen2
is not None and astromRefCatGen2 != self.connections.astromRefCat:
299 f
"Gen2 ({astromRefCatGen2}) and Gen3 ({self.connections.astromRefCat}) astrometry reference " 300 f
"catalogs are different. These options must be kept in sync until Gen2 is retired." 303 if photoRefCatGen2
is not None and photoRefCatGen2 != self.connections.photoRefCat:
305 f
"Gen2 ({photoRefCatGen2}) and Gen3 ({self.connections.photoRefCat}) photometry reference " 306 f
"catalogs are different. These options must be kept in sync until Gen2 is retired." 318 r"""!Calibrate an exposure: measure sources and perform astrometric and 319 photometric calibration 321 @anchor CalibrateTask_ 323 @section pipe_tasks_calibrate_Contents Contents 325 - @ref pipe_tasks_calibrate_Purpose 326 - @ref pipe_tasks_calibrate_Initialize 327 - @ref pipe_tasks_calibrate_IO 328 - @ref pipe_tasks_calibrate_Config 329 - @ref pipe_tasks_calibrate_Metadata 330 - @ref pipe_tasks_calibrate_Debug 333 @section pipe_tasks_calibrate_Purpose Description 335 Given an exposure with a good PSF model and aperture correction map 336 (e.g. as provided by @ref CharacterizeImageTask), perform the following 338 - Run detection and measurement 339 - Run astrometry subtask to fit an improved WCS 340 - Run photoCal subtask to fit the exposure's photometric zero-point 342 @section pipe_tasks_calibrate_Initialize Task initialisation 344 @copydoc \_\_init\_\_ 346 @section pipe_tasks_calibrate_IO Invoking the Task 348 If you want this task to unpersist inputs or persist outputs, then call 349 the `runDataRef` method (a wrapper around the `run` method). 351 If you already have the inputs unpersisted and do not want to persist the 352 output then it is more direct to call the `run` method: 354 @section pipe_tasks_calibrate_Config Configuration parameters 356 See @ref CalibrateConfig 358 @section pipe_tasks_calibrate_Metadata Quantities set in exposure Metadata 362 <dt>MAGZERO_RMS <dd>MAGZERO's RMS == sigma reported by photoCal task 363 <dt>MAGZERO_NOBJ <dd>Number of stars used == ngood reported by photoCal 365 <dt>COLORTERM1 <dd>?? (always 0.0) 366 <dt>COLORTERM2 <dd>?? (always 0.0) 367 <dt>COLORTERM3 <dd>?? (always 0.0) 370 @section pipe_tasks_calibrate_Debug Debug variables 372 The @link lsst.pipe.base.cmdLineTask.CmdLineTask command line task@endlink 373 interface supports a flag 374 `--debug` to import `debug.py` from your `$PYTHONPATH`; see @ref baseDebug 375 for more about `debug.py`. 377 CalibrateTask has a debug dictionary containing one key: 380 <dd>frame (an int; <= 0 to not display) in which to display the exposure, 381 sources and matches. See @ref lsst.meas.astrom.displayAstrometry for 382 the meaning of the various symbols. 385 For example, put something like: 389 di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would 390 # call us recursively 391 if name == "lsst.pipe.tasks.calibrate": 398 lsstDebug.Info = DebugInfo 400 into your `debug.py` file and run `calibrateTask.py` with the `--debug` 403 Some subtasks may have their own debug variables; see individual Task 410 ConfigClass = CalibrateConfig
411 _DefaultName =
"calibrate" 412 RunnerClass = pipeBase.ButlerInitializedTaskRunner
414 def __init__(self, butler=None, astromRefObjLoader=None,
415 photoRefObjLoader=None, icSourceSchema=None,
416 initInputs=None, **kwargs):
417 """!Construct a CalibrateTask 419 @param[in] butler The butler is passed to the refObjLoader constructor 420 in case it is needed. Ignored if the refObjLoader argument 421 provides a loader directly. 422 @param[in] astromRefObjLoader An instance of LoadReferenceObjectsTasks 423 that supplies an external reference catalog for astrometric 424 calibration. May be None if the desired loader can be constructed 425 from the butler argument or all steps requiring a reference catalog 427 @param[in] photoRefObjLoader An instance of LoadReferenceObjectsTasks 428 that supplies an external reference catalog for photometric 429 calibration. May be None if the desired loader can be constructed 430 from the butler argument or all steps requiring a reference catalog 432 @param[in] icSourceSchema schema for icSource catalog, or None. 433 Schema values specified in config.icSourceFieldsToCopy will be 434 taken from this schema. If set to None, no values will be 435 propagated from the icSourceCatalog 436 @param[in,out] kwargs other keyword arguments for 437 lsst.pipe.base.CmdLineTask 441 if icSourceSchema
is None and butler
is not None:
443 icSourceSchema = butler.get(
"icSrc_schema", immediate=
True).schema
445 if icSourceSchema
is None and butler
is None and initInputs
is not None:
446 icSourceSchema = initInputs[
'icSourceSchema'].schema
448 if icSourceSchema
is not None:
451 minimumSchema = afwTable.SourceTable.makeMinimalSchema()
452 self.
schemaMapper.addMinimalSchema(minimumSchema,
False)
461 "Source was detected as an icSource"))
462 missingFieldNames = []
463 for fieldName
in self.config.icSourceFieldsToCopy:
465 schemaItem = icSourceSchema.find(fieldName)
467 missingFieldNames.append(fieldName)
472 if missingFieldNames:
473 raise RuntimeError(
"isSourceCat is missing fields {} " 474 "specified in icSourceFieldsToCopy" 475 .
format(missingFieldNames))
482 self.
schema = afwTable.SourceTable.makeMinimalSchema()
483 self.makeSubtask(
'detection', schema=self.
schema)
490 if self.config.doInsertFakes:
491 self.makeSubtask(
"insertFakes")
493 if self.config.doDeblend:
494 self.makeSubtask(
"deblend", schema=self.
schema)
495 self.makeSubtask(
'measurement', schema=self.
schema,
497 if self.config.doApCorr:
498 self.makeSubtask(
'applyApCorr', schema=self.
schema)
499 self.makeSubtask(
'catalogCalculation', schema=self.
schema)
501 if self.config.doAstrometry:
502 if astromRefObjLoader
is None and butler
is not None:
503 self.makeSubtask(
'astromRefObjLoader', butler=butler)
504 astromRefObjLoader = self.astromRefObjLoader
506 self.makeSubtask(
"astrometry", refObjLoader=astromRefObjLoader,
508 if self.config.doPhotoCal:
509 if photoRefObjLoader
is None and butler
is not None:
510 self.makeSubtask(
'photoRefObjLoader', butler=butler)
511 photoRefObjLoader = self.photoRefObjLoader
512 self.
pixelMargin = photoRefObjLoader.config.pixelMargin
513 self.makeSubtask(
"photoCal", refObjLoader=photoRefObjLoader,
516 if self.config.doEvalLocCalibration
and self.config.doAstrometry
and self.config.doPhotoCal:
517 self.makeSubtask(
"evalLocCalib", schema=self.
schema)
519 if initInputs
is not None and (astromRefObjLoader
is not None or photoRefObjLoader
is not None):
520 raise RuntimeError(
"PipelineTask form of this task should not be initialized with " 521 "reference object loaders.")
526 self.
schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
533 def runDataRef(self, dataRef, exposure=None, background=None, icSourceCat=None,
535 """!Calibrate an exposure, optionally unpersisting inputs and 538 This is a wrapper around the `run` method that unpersists inputs 539 (if `doUnpersist` true) and persists outputs (if `config.doWrite` true) 541 @param[in] dataRef butler data reference corresponding to a science 543 @param[in,out] exposure characterized exposure (an 544 lsst.afw.image.ExposureF or similar), or None to unpersist existing 545 icExp and icBackground. See `run` method for details of what is 547 @param[in,out] background initial model of background already 548 subtracted from exposure (an lsst.afw.math.BackgroundList). May be 549 None if no background has been subtracted, though that is unusual 550 for calibration. A refined background model is output. Ignored if 552 @param[in] icSourceCat catalog from which to copy the fields specified 553 by icSourceKeys, or None; 554 @param[in] doUnpersist unpersist data: 555 - if True, exposure, background and icSourceCat are read from 556 dataRef and those three arguments must all be None; 557 - if False the exposure must be provided; background and 558 icSourceCat are optional. True is intended for running as a 559 command-line task, False for running as a subtask 560 @return same data as the calibrate method 562 self.log.
info(
"Processing %s" % (dataRef.dataId))
565 if any(item
is not None for item
in (exposure, background,
567 raise RuntimeError(
"doUnpersist true; exposure, background " 568 "and icSourceCat must all be None")
569 exposure = dataRef.get(
"icExp", immediate=
True)
570 background = dataRef.get(
"icExpBackground", immediate=
True)
571 icSourceCat = dataRef.get(
"icSrc", immediate=
True)
572 elif exposure
is None:
573 raise RuntimeError(
"doUnpersist false; exposure must be provided")
575 exposureIdInfo = dataRef.get(
"expIdInfo")
579 exposureIdInfo=exposureIdInfo,
580 background=background,
581 icSourceCat=icSourceCat,
584 if self.config.doWrite:
587 exposure=calRes.exposure,
588 background=calRes.background,
589 sourceCat=calRes.sourceCat,
590 astromMatches=calRes.astromMatches,
591 matchMeta=calRes.matchMeta,
597 inputs = butlerQC.get(inputRefs)
598 expId, expBits = butlerQC.quantum.dataId.pack(
"visit_detector",
602 if self.config.doAstrometry:
604 for ref
in inputRefs.astromRefCat],
605 refCats=inputs.pop(
'astromRefCat'),
606 config=self.config.astromRefObjLoader, log=self.log)
608 self.astrometry.setRefObjLoader(refObjLoader)
610 if self.config.doPhotoCal:
612 for ref
in inputRefs.photoRefCat],
613 refCats=inputs.pop(
'photoRefCat'),
614 config=self.config.photoRefObjLoader,
616 self.
pixelMargin = photoRefObjLoader.config.pixelMargin
617 self.photoCal.match.setRefObjLoader(photoRefObjLoader)
619 outputs = self.
run(**inputs)
621 if self.config.doWriteMatches:
623 normalizedMatches.table.setMetadata(outputs.matchMeta)
624 if self.config.doWriteMatchesDenormalized:
626 outputs.matchesDenormalized = denormMatches
627 outputs.matches = normalizedMatches
628 butlerQC.put(outputs, outputRefs)
630 def run(self, exposure, exposureIdInfo=None, background=None,
632 """!Calibrate an exposure (science image or coadd) 634 @param[in,out] exposure exposure to calibrate (an 635 lsst.afw.image.ExposureF or similar); 640 - MaskedImage has background subtracted 642 - PhotoCalib is replaced 643 @param[in] exposureIdInfo ID info for exposure (an 644 lsst.obs.base.ExposureIdInfo) If not provided, returned 645 SourceCatalog IDs will not be globally unique. 646 @param[in,out] background background model already subtracted from 647 exposure (an lsst.afw.math.BackgroundList). May be None if no 648 background has been subtracted, though that is unusual for 649 calibration. A refined background model is output. 650 @param[in] icSourceCat A SourceCatalog from CharacterizeImageTask 651 from which we can copy some fields. 653 @return pipe_base Struct containing these fields: 654 - exposure calibrate science exposure with refined WCS and PhotoCalib 655 - background model of background subtracted from exposure (an 656 lsst.afw.math.BackgroundList) 657 - sourceCat catalog of measured sources 658 - astromMatches list of source/refObj matches from the astrometry 662 if exposureIdInfo
is None:
665 if background
is None:
667 sourceIdFactory = IdFactory.makeSource(exposureIdInfo.expId,
668 exposureIdInfo.unusedBits)
669 table = SourceTable.make(self.
schema, sourceIdFactory)
672 detRes = self.detection.
run(table=table, exposure=exposure,
674 sourceCat = detRes.sources
675 if detRes.fpSets.background:
676 for bg
in detRes.fpSets.background:
677 background.append(bg)
678 if self.config.doDeblend:
679 self.deblend.
run(exposure=exposure, sources=sourceCat)
680 self.measurement.
run(
683 exposureId=exposureIdInfo.expId
685 if self.config.doApCorr:
686 self.applyApCorr.
run(
688 apCorrMap=exposure.getInfo().getApCorrMap()
690 self.catalogCalculation.
run(sourceCat)
692 if icSourceCat
is not None and \
693 len(self.config.icSourceFieldsToCopy) > 0:
701 if not sourceCat.isContiguous():
702 sourceCat = sourceCat.copy(deep=
True)
708 if self.config.doAstrometry:
710 astromRes = self.astrometry.
run(
714 astromMatches = astromRes.matches
715 matchMeta = astromRes.matchMeta
716 except Exception
as e:
717 if self.config.requireAstrometry:
719 self.log.
warn(
"Unable to perform astrometric calibration " 720 "(%s): attempting to proceed" % e)
723 if self.config.doPhotoCal:
725 photoRes = self.photoCal.
run(exposure, sourceCat=sourceCat, expId=exposureIdInfo.expId)
726 exposure.setPhotoCalib(photoRes.photoCalib)
728 self.log.
info(
"Photometric zero-point: %f" %
729 photoRes.photoCalib.instFluxToMagnitude(1.0))
730 self.
setMetadata(exposure=exposure, photoRes=photoRes)
731 except Exception
as e:
732 if self.config.requirePhotoCal:
734 self.log.
warn(
"Unable to perform photometric calibration " 735 "(%s): attempting to proceed" % e)
738 if self.config.doEvalLocCalibration
and self.config.doAstrometry
and self.config.doPhotoCal:
739 self.evalLocCalib.
run(sourceCat, exposure)
741 if self.config.doInsertFakes:
742 self.insertFakes.
run(exposure, background=background)
744 table = SourceTable.make(self.
schema, sourceIdFactory)
747 detRes = self.detection.
run(table=table, exposure=exposure,
749 sourceCat = detRes.sources
750 if detRes.fpSets.background:
751 for bg
in detRes.fpSets.background:
752 background.append(bg)
753 if self.config.doDeblend:
754 self.deblend.
run(exposure=exposure, sources=sourceCat)
755 self.measurement.
run(
758 exposureId=exposureIdInfo.expId
760 if self.config.doApCorr:
761 self.applyApCorr.
run(
763 apCorrMap=exposure.getInfo().getApCorrMap()
765 self.catalogCalculation.
run(sourceCat)
767 if icSourceCat
is not None and len(self.config.icSourceFieldsToCopy) > 0:
776 matches=astromMatches,
781 return pipeBase.Struct(
783 background=background,
785 astromMatches=astromMatches,
789 outputExposure=exposure,
791 outputBackground=background,
794 def writeOutputs(self, dataRef, exposure, background, sourceCat,
795 astromMatches, matchMeta):
796 """Write output data to the output repository 798 @param[in] dataRef butler data reference corresponding to a science 800 @param[in] exposure exposure to write 801 @param[in] background background model for exposure 802 @param[in] sourceCat catalog of measured sources 803 @param[in] astromMatches list of source/refObj matches from the 806 dataRef.put(sourceCat,
"src")
807 if self.config.doWriteMatches
and astromMatches
is not None:
809 normalizedMatches.table.setMetadata(matchMeta)
810 dataRef.put(normalizedMatches,
"srcMatch")
811 if self.config.doWriteMatchesDenormalized:
813 dataRef.put(denormMatches,
"srcMatchFull")
814 if self.config.doWriteExposure:
815 dataRef.put(exposure,
"calexp")
816 dataRef.put(background,
"calexpBackground")
819 """Return a dict of empty catalogs for each catalog dataset produced 824 return {
"src": sourceCat}
827 """!Set task and exposure metadata 829 Logs a warning and continues if needed data is missing. 831 @param[in,out] exposure exposure whose metadata is to be set 832 @param[in] photoRes results of running photoCal; if None then it was 840 exposureTime = exposure.getInfo().getVisitInfo().getExposureTime()
841 magZero = photoRes.zp - 2.5*math.log10(exposureTime)
842 self.metadata.
set(
'MAGZERO', magZero)
844 self.log.
warn(
"Could not set normalized MAGZERO in header: no " 848 metadata = exposure.getMetadata()
849 metadata.set(
'MAGZERO_RMS', photoRes.sigma)
850 metadata.set(
'MAGZERO_NOBJ', photoRes.ngood)
851 metadata.set(
'COLORTERM1', 0.0)
852 metadata.set(
'COLORTERM2', 0.0)
853 metadata.set(
'COLORTERM3', 0.0)
854 except Exception
as e:
855 self.log.
warn(
"Could not set exposure metadata: %s" % (e,))
858 """!Match sources in icSourceCat and sourceCat and copy the specified fields 860 @param[in] icSourceCat catalog from which to copy fields 861 @param[in,out] sourceCat catalog to which to copy fields 863 The fields copied are those specified by `config.icSourceFieldsToCopy` 864 that actually exist in the schema. This was set up by the constructor 865 using self.schemaMapper. 868 raise RuntimeError(
"To copy icSource fields you must specify " 869 "icSourceSchema nd icSourceKeys when " 870 "constructing this task")
871 if icSourceCat
is None or sourceCat
is None:
872 raise RuntimeError(
"icSourceCat and sourceCat must both be " 874 if len(self.config.icSourceFieldsToCopy) == 0:
875 self.log.
warn(
"copyIcSourceFields doing nothing because " 876 "icSourceFieldsToCopy is empty")
880 mc.findOnlyClosest =
False 882 self.config.matchRadiusPix, mc)
883 if self.config.doDeblend:
884 deblendKey = sourceCat.schema[
"deblend_nChild"].asKey()
886 matches = [m
for m
in matches
if m[1].get(deblendKey) == 0]
893 for m0, m1, d
in matches:
895 match = bestMatches.get(id0)
896 if match
is None or d <= match[2]:
897 bestMatches[id0] = (m0, m1, d)
898 matches =
list(bestMatches.values())
903 numMatches = len(matches)
904 numUniqueSources = len(
set(m[1].getId()
for m
in matches))
905 if numUniqueSources != numMatches:
906 self.log.
warn(
"{} icSourceCat sources matched only {} sourceCat " 907 "sources".
format(numMatches, numUniqueSources))
909 self.log.
info(
"Copying flags from icSourceCat to sourceCat for " 910 "%s sources" % (numMatches,))
914 for icSrc, src, d
in matches:
920 icSrcFootprint = icSrc.getFootprint()
922 icSrc.setFootprint(src.getFootprint())
925 icSrc.setFootprint(icSrcFootprint)
def copyIcSourceFields(self, icSourceCat, sourceCat)
Match sources in icSourceCat and sourceCat and copy the specified fields.
def __init__(self, butler=None, astromRefObjLoader=None, photoRefObjLoader=None, icSourceSchema=None, initInputs=None, kwargs)
Construct a CalibrateTask.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
def run(self, exposure, exposureIdInfo=None, background=None, icSourceCat=None)
Calibrate an exposure (science image or coadd)
Class for storing ordered metadata with comments.
A mapping between the keys of two Schemas, used to copy data between them.
def denormalizeMatches(matches, matchMeta=None)
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations...
daf::base::PropertySet * set
def writeOutputs(self, dataRef, exposure, background, sourceCat, astromMatches, matchMeta)
bool any(CoordinateExpr< N > const &expr) noexcept
Return true if any elements are true.
Pass parameters to algorithms that match list of sources.
afw::table::PointKey< int > dimensions
def __init__(self, config=None)
template BaseCatalog packMatches(SourceMatchVector const &)
A description of a field in a table.
def setMetadata(self, exposure, photoRes=None)
Set task and exposure metadata.
def displayAstrometry(refCat=None, sourceCat=None, distortedCentroidKey=None, bbox=None, exposure=None, matches=None, frame=1, title="", pause=True)
def getDebugFrame(debugDisplay, name)
def getSchemaCatalogs(self)
SourceMatchVector matchXy(SourceCatalog const &cat, double radius, bool symmetric)
Compute all tuples (s1,s2,d) where s1 != s2, s1 and s2 both belong to cat, and d, the distance betwee...
def runDataRef(self, dataRef, exposure=None, background=None, icSourceCat=None, doUnpersist=True)
Calibrate an exposure, optionally unpersisting inputs and persisting outputs.
daf::base::PropertyList * list
Calibrate an exposure: measure sources and perform astrometric and photometric calibration.
def runQuantum(self, butlerQC, inputRefs, outputRefs)