23 from __future__
import absolute_import, division, print_function
24 from builtins
import zip
25 from builtins
import range
29 from lsst.pipe.base import CmdLineTask, Struct, TaskRunner, ArgumentParser, ButlerInitializedTaskRunner
30 from lsst.pex.config import Config, Field, ListField, ConfigurableField, RangeField, ConfigField
32 from lsst.meas.base import SingleFrameMeasurementTask, ApplyApCorrTask, CatalogCalculationTask
48 * deepCoadd_det: detections from what used to be processCoadd (tract, patch, filter) 49 * deepCoadd_mergeDet: merged detections (tract, patch) 50 * deepCoadd_meas: measurements of merged detections (tract, patch, filter) 51 * deepCoadd_ref: reference sources (tract, patch) 52 All of these have associated *_schema catalogs that require no data ID and hold no records. 54 In addition, we have a schema-only dataset, which saves the schema for the PeakRecords in 55 the mergeDet, meas, and ref dataset Footprints: 56 * deepCoadd_peak_schema 60 def _makeGetSchemaCatalogs(datasetSuffix):
61 """Construct a getSchemaCatalogs instance method 63 These are identical for most of the classes here, so we'll consolidate 66 datasetSuffix: Suffix of dataset name, e.g., "src" for "deepCoadd_src" 69 def getSchemaCatalogs(self):
70 """Return a dict of empty catalogs for each catalog dataset produced by this task.""" 71 src = afwTable.SourceCatalog(self.schema)
72 if hasattr(self,
"algMetadata"):
73 src.getTable().setMetadata(self.algMetadata)
74 return {self.config.coaddName +
"Coadd_" + datasetSuffix: src}
75 return getSchemaCatalogs
78 def _makeMakeIdFactory(datasetName):
79 """Construct a makeIdFactory instance method 81 These are identical for all the classes here, so this consolidates 84 datasetName: Dataset name without the coadd name prefix, e.g., "CoaddId" for "deepCoaddId" 87 def makeIdFactory(self, dataRef):
88 """Return an IdFactory for setting the detection identifiers 90 The actual parameters used in the IdFactory are provided by 91 the butler (through the provided data reference. 93 expBits = dataRef.get(self.config.coaddName + datasetName +
"_bits")
94 expId = int(dataRef.get(self.config.coaddName + datasetName))
95 return afwTable.IdFactory.makeSource(expId, 64 - expBits)
100 """Given a longer, camera-specific filter name (e.g. "HSC-I") return its shorthand name ("i"). 104 return afwImage.Filter(name).getFilterProperty().getName()
111 \anchor DetectCoaddSourcesConfig_ 113 \brief Configuration parameters for the DetectCoaddSourcesTask 115 doScaleVariance = Field(dtype=bool, default=
True, doc=
"Scale variance plane using empirical noise?")
116 detection = ConfigurableField(target=DynamicDetectionTask, doc=
"Source detection")
117 coaddName = Field(dtype=str, default=
"deep", doc=
"Name of coadd")
118 mask = ListField(dtype=str, default=[
"DETECTED",
"BAD",
"SAT",
"NO_DATA",
"INTRP"],
119 doc=
"Mask planes for pixels to ignore when scaling variance")
120 doInsertFakes = Field(dtype=bool, default=
False,
121 doc=
"Run fake sources injection task")
122 insertFakes = ConfigurableField(target=BaseFakeSourcesTask,
123 doc=
"Injection of fake sources for testing " 124 "purposes (must be retargeted)")
127 Config.setDefaults(self)
128 self.
detection.thresholdType =
"pixel_stdev" 131 self.
detection.reEstimateBackground =
False 132 self.
detection.background.useApprox =
False 134 self.
detection.background.undersampleStyle =
'REDUCE_INTERP_ORDER' 146 \anchor DetectCoaddSourcesTask_ 148 \brief Detect sources on a coadd 150 \section pipe_tasks_multiBand_Contents Contents 152 - \ref pipe_tasks_multiBand_DetectCoaddSourcesTask_Purpose 153 - \ref pipe_tasks_multiBand_DetectCoaddSourcesTask_Initialize 154 - \ref pipe_tasks_multiBand_DetectCoaddSourcesTask_Run 155 - \ref pipe_tasks_multiBand_DetectCoaddSourcesTask_Config 156 - \ref pipe_tasks_multiBand_DetectCoaddSourcesTask_Debug 157 - \ref pipe_tasks_multiband_DetectCoaddSourcesTask_Example 159 \section pipe_tasks_multiBand_DetectCoaddSourcesTask_Purpose Description 161 Command-line task that detects sources on a coadd of exposures obtained with a single filter. 163 Coadding individual visits requires each exposure to be warped. This introduces covariance in the noise 164 properties across pixels. Before detection, we correct the coadd variance by scaling the variance plane 165 in the coadd to match the observed variance. This is an approximate approach -- strictly, we should 166 propagate the full covariance matrix -- but it is simple and works well in practice. 168 After scaling the variance plane, we detect sources and generate footprints by delegating to the \ref 169 SourceDetectionTask_ "detection" subtask. 172 deepCoadd{tract,patch,filter}: ExposureF 174 deepCoadd_det{tract,patch,filter}: SourceCatalog (only parent Footprints) 175 \n deepCoadd_calexp{tract,patch,filter}: Variance scaled, background-subtracted input 177 \n deepCoadd_calexp_background{tract,patch,filter}: BackgroundList 181 DetectCoaddSourcesTask delegates most of its work to the \ref SourceDetectionTask_ "detection" subtask. 182 You can retarget this subtask if you wish. 184 \section pipe_tasks_multiBand_DetectCoaddSourcesTask_Initialize Task initialization 186 \copydoc \_\_init\_\_ 188 \section pipe_tasks_multiBand_DetectCoaddSourcesTask_Run Invoking the Task 192 \section pipe_tasks_multiBand_DetectCoaddSourcesTask_Config Configuration parameters 194 See \ref DetectCoaddSourcesConfig_ "DetectSourcesConfig" 196 \section pipe_tasks_multiBand_DetectCoaddSourcesTask_Debug Debug variables 198 The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a 199 flag \c -d to import \b debug.py from your \c PYTHONPATH; see \ref baseDebug for more about \b debug.py 202 DetectCoaddSourcesTask has no debug variables of its own because it relegates all the work to 203 \ref SourceDetectionTask_ "SourceDetectionTask"; see the documetation for 204 \ref SourceDetectionTask_ "SourceDetectionTask" for further information. 206 \section pipe_tasks_multiband_DetectCoaddSourcesTask_Example A complete example of using DetectCoaddSourcesTask 208 DetectCoaddSourcesTask is meant to be run after assembling a coadded image in a given band. The purpose of 209 the task is to update the background, detect all sources in a single band and generate a set of parent 210 footprints. Subsequent tasks in the multi-band processing procedure will merge sources across bands and, 211 eventually, perform forced photometry. Command-line usage of DetectCoaddSourcesTask expects a data 212 reference to the coadd to be processed. A list of the available optional arguments can be obtained by 213 calling detectCoaddSources.py with the `--help` command line argument: 215 detectCoaddSources.py --help 218 To demonstrate usage of the DetectCoaddSourcesTask in the larger context of multi-band processing, we 219 will process HSC data in the [ci_hsc](https://github.com/lsst/ci_hsc) package. Assuming one has followed 220 steps 1 - 4 at \ref pipeTasks_multiBand, one may detect all the sources in each coadd as follows: 222 detectCoaddSources.py $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-I 224 that will process the HSC-I band data. The results are written to 225 `$CI_HSC_DIR/DATA/deepCoadd-results/HSC-I`. 227 It is also necessary to run: 229 detectCoaddSources.py $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-R 231 to generate the sources catalogs for the HSC-R band required by the next step in the multi-band 232 processing procedure: \ref MergeDetectionsTask_ "MergeDetectionsTask". 234 _DefaultName =
"detectCoaddSources" 235 ConfigClass = DetectCoaddSourcesConfig
236 getSchemaCatalogs = _makeGetSchemaCatalogs(
"det")
237 makeIdFactory = _makeMakeIdFactory(
"CoaddId")
240 def _makeArgumentParser(cls):
242 parser.add_id_argument(
"--id",
"deepCoadd", help=
"data ID, e.g. --id tract=12345 patch=1,2 filter=r",
243 ContainerClass=ExistingCoaddDataIdContainer)
248 \brief Initialize the task. Create the \ref SourceDetectionTask_ "detection" subtask. 250 Keyword arguments (in addition to those forwarded to CmdLineTask.__init__): 252 \param[in] schema: initial schema for the output catalog, modified-in place to include all 253 fields set by this task. If None, the source minimal schema will be used. 254 \param[in] **kwargs: keyword arguments to be passed to lsst.pipe.base.task.Task.__init__ 256 CmdLineTask.__init__(self, **kwargs)
258 schema = afwTable.SourceTable.makeMinimalSchema()
259 if self.config.doInsertFakes:
260 self.makeSubtask(
"insertFakes")
262 self.makeSubtask(
"detection", schema=self.
schema)
266 \brief Run detection on a coadd. 268 Invokes \ref runDetection and then uses \ref write to output the 271 \param[in] patchRef: data reference for patch 273 exposure = patchRef.get(self.config.coaddName +
"Coadd", immediate=
True)
274 expId = int(patchRef.get(self.config.coaddName +
"CoaddId"))
276 self.
write(exposure, results, patchRef)
281 \brief Run detection on an exposure. 283 First scale the variance plane to match the observed variance 284 using \ref scaleVariance. Then invoke the \ref SourceDetectionTask_ "detection" subtask to 287 \param[in,out] exposure: Exposure on which to detect (may be backround-subtracted and scaled, 288 depending on configuration). 289 \param[in] idFactory: IdFactory to set source identifiers 290 \param[in] expId: Exposure identifier (integer) for RNG seed 292 \return a pipe.base.Struct with fields 293 - sources: catalog of detections 294 - backgrounds: list of backgrounds 296 if self.config.doScaleVariance:
297 varScale =
scaleVariance(exposure.getMaskedImage(), self.config.mask, log=self.log)
298 exposure.getMetadata().add(
"variance_scale", varScale)
299 backgrounds = afwMath.BackgroundList()
300 if self.config.doInsertFakes:
301 self.insertFakes.
run(exposure, background=backgrounds)
302 table = afwTable.SourceTable.make(self.
schema, idFactory)
303 detections = self.detection.makeSourceCatalog(table, exposure, expId=expId)
304 sources = detections.sources
305 fpSets = detections.fpSets
306 if hasattr(fpSets,
"background")
and fpSets.background:
307 backgrounds.append(fpSets.background)
308 return Struct(sources=sources, backgrounds=backgrounds)
310 def write(self, exposure, results, patchRef):
312 \brief Write out results from runDetection. 314 \param[in] exposure: Exposure to write out 315 \param[in] results: Struct returned from runDetection 316 \param[in] patchRef: data reference for patch 318 coaddName = self.config.coaddName +
"Coadd" 319 patchRef.put(results.backgrounds, coaddName +
"_calexp_background")
320 patchRef.put(results.sources, coaddName +
"_det")
321 patchRef.put(exposure, coaddName +
"_calexp")
328 \anchor MergeSourcesRunner_ 330 \brief Task runner for the \ref MergeSourcesTask_ "MergeSourcesTask". Required because the run method 331 requires a list of dataRefs rather than a single dataRef. 336 \brief Provide a butler to the Task constructor. 338 \param[in] parsedCmd the parsed command 339 \param[in] args tuple of a list of data references and kwargs (un-used) 340 \throws RuntimeError if both parsedCmd & args are None 342 if parsedCmd
is not None:
343 butler = parsedCmd.butler
344 elif args
is not None:
345 dataRefList, kwargs = args
346 butler = dataRefList[0].getButler()
348 raise RuntimeError(
"Neither parsedCmd or args specified")
349 return self.TaskClass(config=self.config, log=self.log, butler=butler)
354 \brief Provide a list of patch references for each patch. 356 The patch references within the list will have different filters. 358 \param[in] parsedCmd the parsed command 359 \param **kwargs key word arguments (unused) 360 \throws RuntimeError if multiple references are provided for the same combination of tract, patch and 364 for ref
in parsedCmd.id.refList:
365 tract = ref.dataId[
"tract"]
366 patch = ref.dataId[
"patch"]
367 filter = ref.dataId[
"filter"]
368 if not tract
in refList:
370 if not patch
in refList[tract]:
371 refList[tract][patch] = {}
372 if filter
in refList[tract][patch]:
373 raise RuntimeError(
"Multiple versions of %s" % (ref.dataId,))
374 refList[tract][patch][filter] = ref
375 return [(list(p.values()), kwargs)
for t
in refList.values()
for p
in t.values()]
380 \anchor MergeSourcesConfig_ 382 \brief Configuration for merging sources. 384 priorityList = ListField(dtype=str, default=[],
385 doc=
"Priority-ordered list of bands for the merge.")
386 coaddName = Field(dtype=str, default=
"deep", doc=
"Name of coadd")
389 Config.validate(self)
391 raise RuntimeError(
"No priority list provided")
396 \anchor MergeSourcesTask_ 398 \brief A base class for merging source catalogs. 400 Merging detections (MergeDetectionsTask) and merging measurements (MergeMeasurementsTask) are 401 so similar that it makes sense to re-use the code, in the form of this abstract base class. 403 NB: Do not use this class directly. Instead use one of the child classes that inherit from 404 MergeSourcesTask such as \ref MergeDetectionsTask_ "MergeDetectionsTask" or \ref MergeMeasurementsTask_ 405 "MergeMeasurementsTask" 407 Sub-classes should set the following class variables: 408 * `_DefaultName`: name of Task 409 * `inputDataset`: name of dataset to read 410 * `outputDataset`: name of dataset to write 411 * `getSchemaCatalogs` to the result of `_makeGetSchemaCatalogs(outputDataset)` 413 In addition, sub-classes must implement the mergeCatalogs method. 416 ConfigClass = MergeSourcesConfig
417 RunnerClass = MergeSourcesRunner
420 getSchemaCatalogs =
None 423 def _makeArgumentParser(cls):
425 \brief Create a suitable ArgumentParser. 427 We will use the ArgumentParser to get a provide a list of data 428 references for patches; the RunnerClass will sort them into lists 429 of data references for the same patch 432 parser.add_id_argument(
"--id",
"deepCoadd_" + cls.
inputDataset,
433 ContainerClass=ExistingCoaddDataIdContainer,
434 help=
"data ID, e.g. --id tract=12345 patch=1,2 filter=g^r^i")
439 \brief Obtain the input schema either directly or froma butler reference. 441 \param[in] butler butler reference to obtain the input schema from 442 \param[in] schema the input schema 445 assert butler
is not None,
"Neither butler nor schema specified" 446 schema = butler.get(self.config.coaddName +
"Coadd_" + self.
inputDataset +
"_schema",
447 immediate=
True).schema
450 def __init__(self, butler=None, schema=None, **kwargs):
452 \brief Initialize the task. 454 Keyword arguments (in addition to those forwarded to CmdLineTask.__init__): 455 \param[in] schema the schema of the detection catalogs used as input to this one 456 \param[in] butler a butler used to read the input schema from disk, if schema is None 458 Derived classes should use the getInputSchema() method to handle the additional 459 arguments and retreive the actual input schema. 461 CmdLineTask.__init__(self, **kwargs)
463 def run(self, patchRefList):
465 \brief Merge coadd sources from multiple bands. Calls \ref mergeCatalogs which must be defined in 466 subclasses that inherit from MergeSourcesTask. 468 \param[in] patchRefList list of data references for each filter 470 catalogs = dict(self.
readCatalog(patchRef)
for patchRef
in patchRefList)
471 mergedCatalog = self.
mergeCatalogs(catalogs, patchRefList[0])
472 self.
write(patchRefList[0], mergedCatalog)
476 \brief Read input catalog. 478 We read the input dataset provided by the 'inputDataset' 481 \param[in] patchRef data reference for patch 482 \return tuple consisting of the filter name and the catalog 484 filterName = patchRef.dataId[
"filter"]
485 catalog = patchRef.get(self.config.coaddName +
"Coadd_" + self.
inputDataset, immediate=
True)
486 self.log.info(
"Read %d sources for filter %s: %s" % (len(catalog), filterName, patchRef.dataId))
487 return filterName, catalog
491 \brief Merge multiple catalogs. This function must be defined in all subclasses that inherit from 494 \param[in] catalogs dict mapping filter name to source catalog 496 \return merged catalog 498 raise NotImplementedError()
502 \brief Write the output. 504 \param[in] patchRef data reference for patch 505 \param[in] catalog catalog 507 We write as the dataset provided by the 'outputDataset' 510 patchRef.put(catalog, self.config.coaddName +
"Coadd_" + self.
outputDataset)
513 mergeDataId = patchRef.dataId.copy()
514 del mergeDataId[
"filter"]
515 self.log.info(
"Wrote merged catalog: %s" % (mergeDataId,))
519 \brief No metadata to write, and not sure how to write it for a list of dataRefs. 524 class CullPeaksConfig(Config):
526 \anchor CullPeaksConfig_ 528 \brief Configuration for culling garbage peaks after merging footprints. 530 Peaks may also be culled after detection or during deblending; this configuration object 531 only deals with culling after merging Footprints. 533 These cuts are based on three quantities: 534 - nBands: the number of bands in which the peak was detected 535 - peakRank: the position of the peak within its family, sorted from brightest to faintest. 536 - peakRankNormalized: the peak rank divided by the total number of peaks in the family. 538 The formula that identifie peaks to cull is: 540 nBands < nBandsSufficient 541 AND (rank >= rankSufficient) 542 AND (rank >= rankConsider OR rank >= rankNormalizedConsider) 544 To disable peak culling, simply set nBandsSufficient=1. 547 nBandsSufficient = RangeField(dtype=int, default=2, min=1,
548 doc=
"Always keep peaks detected in this many bands")
549 rankSufficient = RangeField(dtype=int, default=20, min=1,
550 doc=
"Always keep this many peaks in each family")
551 rankConsidered = RangeField(dtype=int, default=30, min=1,
552 doc=(
"Keep peaks with less than this rank that also match the " 553 "rankNormalizedConsidered condition."))
554 rankNormalizedConsidered = RangeField(dtype=float, default=0.7, min=0.0,
555 doc=(
"Keep peaks with less than this normalized rank that" 556 " also match the rankConsidered condition."))
561 \anchor MergeDetectionsConfig_ 563 \brief Configuration parameters for the MergeDetectionsTask. 565 minNewPeak = Field(dtype=float, default=1,
566 doc=
"Minimum distance from closest peak to create a new one (in arcsec).")
568 maxSamePeak = Field(dtype=float, default=0.3,
569 doc=
"When adding new catalogs to the merge, all peaks less than this distance " 570 " (in arcsec) to an existing peak will be flagged as detected in that catalog.")
571 cullPeaks = ConfigField(dtype=CullPeaksConfig, doc=
"Configuration for how to cull peaks.")
573 skyFilterName = Field(dtype=str, default=
"sky",
574 doc=
"Name of `filter' used to label sky objects (e.g. flag merge_peak_sky is set)\n" 575 "(N.b. should be in MergeMeasurementsConfig.pseudoFilterList)")
576 skyObjects = ConfigurableField(target=SkyObjectsTask, doc=
"Generate sky objects")
579 MergeSourcesConfig.setDefaults(self)
593 \anchor MergeDetectionsTask_ 595 \brief Merge coadd detections from multiple bands. 597 \section pipe_tasks_multiBand_Contents Contents 599 - \ref pipe_tasks_multiBand_MergeDetectionsTask_Purpose 600 - \ref pipe_tasks_multiBand_MergeDetectionsTask_Init 601 - \ref pipe_tasks_multiBand_MergeDetectionsTask_Run 602 - \ref pipe_tasks_multiBand_MergeDetectionsTask_Config 603 - \ref pipe_tasks_multiBand_MergeDetectionsTask_Debug 604 - \ref pipe_tasks_multiband_MergeDetectionsTask_Example 606 \section pipe_tasks_multiBand_MergeDetectionsTask_Purpose Description 608 Command-line task that merges sources detected in coadds of exposures obtained with different filters. 610 To perform photometry consistently across coadds in multiple filter bands, we create a master catalog of 611 sources from all bands by merging the sources (peaks & footprints) detected in each coadd, while keeping 612 track of which band each source originates in. 614 The catalog merge is performed by \ref getMergedSourceCatalog. Spurious peaks detected around bright 615 objects are culled as described in \ref CullPeaksConfig_. 618 deepCoadd_det{tract,patch,filter}: SourceCatalog (only parent Footprints) 620 deepCoadd_mergeDet{tract,patch}: SourceCatalog (only parent Footprints) 624 MergeDetectionsTask subclasses \ref MergeSourcesTask_ "MergeSourcesTask". 626 \section pipe_tasks_multiBand_MergeDetectionsTask_Init Task initialisation 628 \copydoc \_\_init\_\_ 630 \section pipe_tasks_multiBand_MergeDetectionsTask_Run Invoking the Task 634 \section pipe_tasks_multiBand_MergeDetectionsTask_Config Configuration parameters 636 See \ref MergeDetectionsConfig_ 638 \section pipe_tasks_multiBand_MergeDetectionsTask_Debug Debug variables 640 The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a flag \c -d 641 to import \b debug.py from your \c PYTHONPATH; see \ref baseDebug for more about \b debug.py files. 643 MergeDetectionsTask has no debug variables. 645 \section pipe_tasks_multiband_MergeDetectionsTask_Example A complete example of using MergeDetectionsTask 647 MergeDetectionsTask is meant to be run after detecting sources in coadds generated for the chosen subset 648 of the available bands. 649 The purpose of the task is to merge sources (peaks & footprints) detected in the coadds generated from the 650 chosen subset of filters. 651 Subsequent tasks in the multi-band processing procedure will deblend the generated master list of sources 652 and, eventually, perform forced photometry. 653 Command-line usage of MergeDetectionsTask expects data references for all the coadds to be processed. 654 A list of the available optional arguments can be obtained by calling mergeCoaddDetections.py with the 655 `--help` command line argument: 657 mergeCoaddDetections.py --help 660 To demonstrate usage of the DetectCoaddSourcesTask in the larger context of multi-band processing, we 661 will process HSC data in the [ci_hsc](https://github.com/lsst/ci_hsc) package. Assuming one has finished 662 step 5 at \ref pipeTasks_multiBand, one may merge the catalogs of sources from each coadd as follows: 664 mergeCoaddDetections.py $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-I^HSC-R 666 This will merge the HSC-I & -R band parent source catalogs and write the results to 667 `$CI_HSC_DIR/DATA/deepCoadd-results/merged/0/5,4/mergeDet-0-5,4.fits`. 669 The next step in the multi-band processing procedure is 670 \ref MeasureMergedCoaddSourcesTask_ "MeasureMergedCoaddSourcesTask" 672 ConfigClass = MergeDetectionsConfig
673 _DefaultName =
"mergeCoaddDetections" 675 outputDataset =
"mergeDet" 676 makeIdFactory = _makeMakeIdFactory(
"MergedCoaddId")
678 def __init__(self, butler=None, schema=None, **kwargs):
680 \brief Initialize the merge detections task. 682 A \ref FootprintMergeList_ "FootprintMergeList" will be used to 683 merge the source catalogs. 685 Additional keyword arguments (forwarded to MergeSourcesTask.__init__): 686 \param[in] schema the schema of the detection catalogs used as input to this one 687 \param[in] butler a butler used to read the input schema from disk, if schema is None 688 \param[in] **kwargs keyword arguments to be passed to MergeSourcesTask.__init__ 690 The task will set its own self.schema attribute to the schema of the output merged catalog. 692 MergeSourcesTask.__init__(self, butler=butler, schema=schema, **kwargs)
693 self.makeSubtask(
"skyObjects")
697 filterNames += [self.config.skyFilterName]
702 \brief Merge multiple catalogs. 704 After ordering the catalogs and filters in priority order, 705 \ref getMergedSourceCatalog of the \ref FootprintMergeList_ "FootprintMergeList" created by 706 \ref \_\_init\_\_ is used to perform the actual merging. Finally, \ref cullPeaks is used to remove 707 garbage peaks detected around bright objects. 711 \param[out] mergedList 715 skyInfo =
getSkyInfo(coaddName=self.config.coaddName, patchRef=patchRef)
716 tractWcs = skyInfo.wcs
717 peakDistance = self.config.minNewPeak / tractWcs.pixelScale().asArcseconds()
718 samePeakDistance = self.config.maxSamePeak / tractWcs.pixelScale().asArcseconds()
721 orderedCatalogs = [catalogs[band]
for band
in self.config.priorityList
if band
in catalogs.keys()]
723 if band
in catalogs.keys()]
725 mergedList = self.
merged.getMergedSourceCatalog(orderedCatalogs, orderedBands, peakDistance,
732 skySeed = patchRef.get(self.config.coaddName +
"MergedCoaddId")
734 if skySourceFootprints:
735 key = mergedList.schema.find(
"merge_footprint_%s" % self.config.skyFilterName).key
736 for foot
in skySourceFootprints:
737 s = mergedList.addNew()
742 for record
in mergedList:
743 record.getFootprint().sortPeaks()
744 self.log.info(
"Merged to %d sources" % len(mergedList))
751 \brief Attempt to remove garbage peaks (mostly on the outskirts of large blends). 753 \param[in] catalog Source catalog 755 keys = [item.key
for item
in self.
merged.getPeakSchema().extract(
"merge_peak_*").values()]
756 assert len(keys) > 0,
"Error finding flags that associate peaks with their detection bands." 759 for parentSource
in catalog:
762 keptPeaks = parentSource.getFootprint().getPeaks()
763 oldPeaks = list(keptPeaks)
765 familySize = len(oldPeaks)
766 totalPeaks += familySize
767 for rank, peak
in enumerate(oldPeaks):
768 if ((rank < self.config.cullPeaks.rankSufficient)
or 769 (sum([peak.get(k)
for k
in keys]) >= self.config.cullPeaks.nBandsSufficient)
or 770 (rank < self.config.cullPeaks.rankConsidered
and 771 rank < self.config.cullPeaks.rankNormalizedConsidered * familySize)):
772 keptPeaks.append(peak)
775 self.log.info(
"Culled %d of %d peaks" % (culledPeaks, totalPeaks))
779 Return a dict of empty catalogs for each catalog dataset produced by this task. 781 \param[out] dictionary of empty catalogs 783 mergeDet = afwTable.SourceCatalog(self.
schema)
784 peak = afwDetect.PeakCatalog(self.
merged.getPeakSchema())
785 return {self.config.coaddName +
"Coadd_mergeDet": mergeDet,
786 self.config.coaddName +
"Coadd_peak": peak}
790 \brief Return a list of Footprints of sky objects which don't overlap with anything in mergedList 792 \param mergedList The merged Footprints from all the input bands 793 \param skyInfo A description of the patch 794 \param seed Seed for the random number generator 796 mask = afwImage.Mask(skyInfo.patchInfo.getOuterBBox())
797 detected = mask.getPlaneBitMask(
"DETECTED")
799 s.getFootprint().spans.setMask(mask, detected)
801 footprints = self.skyObjects.
run(mask, seed)
806 schema = self.
merged.getPeakSchema()
807 mergeKey = schema.find(
"merge_peak_%s" % self.config.skyFilterName).key
809 for oldFoot
in footprints:
810 assert len(oldFoot.getPeaks()) == 1,
"Should be a single peak only" 811 peak = oldFoot.getPeaks()[0]
812 newFoot = afwDetect.Footprint(oldFoot.spans, schema)
813 newFoot.addPeak(peak.getFx(), peak.getFy(), peak.getPeakValue())
814 newFoot.getPeaks()[0].set(mergeKey,
True)
815 converted.append(newFoot)
822 \anchor MeasureMergedCoaddSourcesConfig_ 824 \brief Configuration parameters for the MeasureMergedCoaddSourcesTask 826 doDeblend = Field(dtype=bool, default=
True, doc=
"Deblend sources?")
827 deblend = ConfigurableField(target=SourceDeblendTask, doc=
"Deblend sources")
828 measurement = ConfigurableField(target=SingleFrameMeasurementTask, doc=
"Source measurement")
829 setPrimaryFlags = ConfigurableField(target=SetPrimaryFlagsTask, doc=
"Set flags for primary tract/patch")
830 doPropagateFlags = Field(
831 dtype=bool, default=
True,
832 doc=
"Whether to match sources to CCD catalogs to propagate flags (to e.g. identify PSF stars)" 834 propagateFlags = ConfigurableField(target=PropagateVisitFlagsTask, doc=
"Propagate visit flags to coadd")
835 doMatchSources = Field(dtype=bool, default=
True, doc=
"Match sources to reference catalog?")
836 match = ConfigurableField(target=DirectMatchTask, doc=
"Matching to reference catalog")
837 doWriteMatchesDenormalized = Field(
840 doc=(
"Write reference matches in denormalized format? " 841 "This format uses more disk space, but is more convenient to read."),
843 coaddName = Field(dtype=str, default=
"deep", doc=
"Name of coadd")
844 checkUnitsParseStrict = Field(
845 doc=
"Strictness of Astropy unit compatibility check, can be 'raise', 'warn' or 'silent'",
852 doc=
"Apply aperture corrections" 854 applyApCorr = ConfigurableField(
855 target=ApplyApCorrTask,
856 doc=
"Subtask to apply aperture corrections" 858 doRunCatalogCalculation = Field(
861 doc=
'Run catalogCalculation task' 863 catalogCalculation = ConfigurableField(
864 target=CatalogCalculationTask,
865 doc=
"Subtask to run catalogCalculation plugins on catalog" 869 Config.setDefaults(self)
870 self.
deblend.propagateAllPeaks =
True 871 self.
measurement.plugins.names |= [
'base_InputCount',
'base_Variance']
872 self.
measurement.plugins[
'base_PixelFlags'].masksFpAnywhere = [
'CLIPPED',
'SENSOR_EDGE',
874 self.
measurement.plugins[
'base_PixelFlags'].masksFpCenter = [
'CLIPPED',
'SENSOR_EDGE',
887 \anchor MeasureMergedCoaddSourcesTask_ 889 \brief Deblend sources from master catalog in each coadd seperately and measure. 891 \section pipe_tasks_multiBand_Contents Contents 893 - \ref pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Purpose 894 - \ref pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Initialize 895 - \ref pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Run 896 - \ref pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Config 897 - \ref pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Debug 898 - \ref pipe_tasks_multiband_MeasureMergedCoaddSourcesTask_Example 900 \section pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Purpose Description 902 Command-line task that uses peaks and footprints from a master catalog to perform deblending and 903 measurement in each coadd. 905 Given a master input catalog of sources (peaks and footprints), deblend and measure each source on the 906 coadd. Repeating this procedure with the same master catalog across multiple coadds will generate a 907 consistent set of child sources. 909 The deblender retains all peaks and deblends any missing peaks (dropouts in that band) as PSFs. Source 910 properties are measured and the \c is-primary flag (indicating sources with no children) is set. Visit 911 flags are propagated to the coadd sources. 913 Optionally, we can match the coadd sources to an external reference catalog. 916 deepCoadd_mergeDet{tract,patch}: SourceCatalog 917 \n deepCoadd_calexp{tract,patch,filter}: ExposureF 919 deepCoadd_meas{tract,patch,filter}: SourceCatalog 923 MeasureMergedCoaddSourcesTask delegates most of its work to a set of sub-tasks: 926 <DT> \ref SourceDeblendTask_ "deblend" 927 <DD> Deblend all the sources from the master catalog.</DD> 928 <DT> \ref SingleFrameMeasurementTask_ "measurement" 929 <DD> Measure source properties of deblended sources.</DD> 930 <DT> \ref SetPrimaryFlagsTask_ "setPrimaryFlags" 931 <DD> Set flag 'is-primary' as well as related flags on sources. 'is-primary' is set for sources that are 932 not at the edge of the field and that have either not been deblended or are the children of deblended 934 <DT> \ref PropagateVisitFlagsTask_ "propagateFlags" 935 <DD> Propagate flags set in individual visits to the coadd.</DD> 936 <DT> \ref DirectMatchTask_ "match" 937 <DD> Match input sources to a reference catalog (optional). 940 These subtasks may be retargeted as required. 942 \section pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Initialize Task initialization 944 \copydoc \_\_init\_\_ 946 \section pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Run Invoking the Task 950 \section pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Config Configuration parameters 952 See \ref MeasureMergedCoaddSourcesConfig_ 954 \section pipe_tasks_multiBand_MeasureMergedCoaddSourcesTask_Debug Debug variables 956 The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a 957 flag \c -d to import \b debug.py from your \c PYTHONPATH; see \ref baseDebug for more about \b debug.py 960 MeasureMergedCoaddSourcesTask has no debug variables of its own because it delegates all the work to 961 the various sub-tasks. See the documetation for individual sub-tasks for more information. 963 \section pipe_tasks_multiband_MeasureMergedCoaddSourcesTask_Example A complete example of using MeasureMergedCoaddSourcesTask 965 After MeasureMergedCoaddSourcesTask has been run on multiple coadds, we have a set of per-band catalogs. 966 The next stage in the multi-band processing procedure will merge these measurements into a suitable 967 catalog for driving forced photometry. 969 Command-line usage of MeasureMergedCoaddSourcesTask expects a data reference to the coadds to be processed. 970 A list of the available optional arguments can be obtained by calling measureCoaddSources.py with the 971 `--help` command line argument: 973 measureCoaddSources.py --help 976 To demonstrate usage of the DetectCoaddSourcesTask in the larger context of multi-band processing, we 977 will process HSC data in the [ci_hsc](https://github.com/lsst/ci_hsc) package. Assuming one has finished 978 step 6 at \ref pipeTasks_multiBand, one may perform deblending and measure sources in the HSC-I band 981 measureCoaddSources.py $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-I 983 This will process the HSC-I band data. The results are written in 984 `$CI_HSC_DIR/DATA/deepCoadd-results/HSC-I/0/5,4/meas-HSC-I-0-5,4.fits 986 It is also necessary to run 988 measureCoaddSources.py $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-R 990 to generate the sources catalogs for the HSC-R band required by the next step in the multi-band 991 procedure: \ref MergeMeasurementsTask_ "MergeMeasurementsTask". 993 _DefaultName =
"measureCoaddSources" 994 ConfigClass = MeasureMergedCoaddSourcesConfig
995 RunnerClass = ButlerInitializedTaskRunner
996 getSchemaCatalogs = _makeGetSchemaCatalogs(
"meas")
997 makeIdFactory = _makeMakeIdFactory(
"MergedCoaddId")
1000 def _makeArgumentParser(cls):
1002 parser.add_id_argument(
"--id",
"deepCoadd_calexp",
1003 help=
"data ID, e.g. --id tract=12345 patch=1,2 filter=r",
1004 ContainerClass=ExistingCoaddDataIdContainer)
1007 def __init__(self, butler=None, schema=None, peakSchema=None, refObjLoader=None, **kwargs):
1009 \brief Initialize the task. 1011 Keyword arguments (in addition to those forwarded to CmdLineTask.__init__): 1012 \param[in] schema: the schema of the merged detection catalog used as input to this one 1013 \param[in] peakSchema: the schema of the PeakRecords in the Footprints in the merged detection catalog 1014 \param[in] refObjLoader: an instance of LoadReferenceObjectsTasks that supplies an external reference 1015 catalog. May be None if the loader can be constructed from the butler argument or all steps 1016 requiring a reference catalog are disabled. 1017 \param[in] butler: a butler used to read the input schemas from disk or construct the reference 1018 catalog loader, if schema or peakSchema or refObjLoader is None 1020 The task will set its own self.schema attribute to the schema of the output measurement catalog. 1021 This will include all fields from the input schema, as well as additional fields for all the 1024 CmdLineTask.__init__(self, **kwargs)
1026 assert butler
is not None,
"Neither butler nor schema is defined" 1027 schema = butler.get(self.config.coaddName +
"Coadd_mergeDet_schema", immediate=
True).schema
1032 if self.config.doDeblend:
1033 if peakSchema
is None:
1034 assert butler
is not None,
"Neither butler nor peakSchema is defined" 1035 peakSchema = butler.get(self.config.coaddName +
"Coadd_peak_schema", immediate=
True).schema
1036 self.makeSubtask(
"deblend", schema=self.
schema, peakSchema=peakSchema)
1037 self.makeSubtask(
"measurement", schema=self.
schema, algMetadata=self.
algMetadata)
1038 self.makeSubtask(
"setPrimaryFlags", schema=self.
schema)
1039 if self.config.doMatchSources:
1040 if refObjLoader
is None:
1041 assert butler
is not None,
"Neither butler nor refObjLoader is defined" 1042 self.makeSubtask(
"match", butler=butler, refObjLoader=refObjLoader)
1043 if self.config.doPropagateFlags:
1044 self.makeSubtask(
"propagateFlags", schema=self.
schema)
1045 self.
schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
1046 if self.config.doApCorr:
1047 self.makeSubtask(
"applyApCorr", schema=self.
schema)
1048 if self.config.doRunCatalogCalculation:
1049 self.makeSubtask(
"catalogCalculation", schema=self.
schema)
1053 \brief Deblend and measure. 1055 \param[in] patchRef: Patch reference. 1057 Deblend each source in every coadd and measure. Set 'is-primary' and related flags. Propagate flags 1058 from individual visits. Optionally match the sources to a reference catalog and write the matches. 1059 Finally, write the deblended sources and measurements out. 1061 exposure = patchRef.get(self.config.coaddName +
"Coadd_calexp", immediate=
True)
1063 if self.config.doDeblend:
1064 self.deblend.
run(exposure, sources)
1066 bigKey = sources.schema[
"deblend_parentTooBig"].asKey()
1068 numBig = sum((s.get(bigKey)
for s
in sources))
1070 self.log.warn(
"Patch %s contains %d large footprints that were not deblended" %
1071 (patchRef.dataId, numBig))
1073 table = sources.getTable()
1076 self.measurement.
run(sources, exposure, exposureId=self.
getExposureId(patchRef))
1078 if self.config.doApCorr:
1079 self.applyApCorr.
run(
1081 apCorrMap=exposure.getInfo().getApCorrMap()
1084 if self.config.doRunCatalogCalculation:
1085 self.catalogCalculation.
run(sources)
1087 skyInfo =
getSkyInfo(coaddName=self.config.coaddName, patchRef=patchRef)
1088 self.setPrimaryFlags.
run(sources, skyInfo.skyMap, skyInfo.tractInfo, skyInfo.patchInfo,
1089 includeDeblend=self.config.doDeblend)
1090 if self.config.doPropagateFlags:
1091 self.propagateFlags.
run(patchRef.getButler(), sources, self.propagateFlags.getCcdInputs(exposure),
1093 if self.config.doMatchSources:
1095 self.
write(patchRef, sources)
1099 \brief Read input sources. 1101 \param[in] dataRef: Data reference for catalog of merged detections 1102 \return List of sources in merged catalog 1104 We also need to add columns to hold the measurements we're about to make 1105 so we can measure in-place. 1107 merged = dataRef.get(self.config.coaddName +
"Coadd_mergeDet", immediate=
True)
1108 self.log.info(
"Read %d detections: %s" % (len(merged), dataRef.dataId))
1111 idFactory.notify(s.getId())
1112 table = afwTable.SourceTable.make(self.
schema, idFactory)
1113 sources = afwTable.SourceCatalog(table)
1119 \brief Write matches of the sources to the astrometric reference catalog. 1121 We use the Wcs in the exposure to match sources. 1123 \param[in] dataRef: data reference 1124 \param[in] exposure: exposure with Wcs 1125 \param[in] sources: source catalog 1127 result = self.match.
run(sources, exposure.getInfo().getFilter().getName())
1129 matches = afwTable.packMatches(result.matches)
1130 matches.table.setMetadata(result.matchMeta)
1131 dataRef.put(matches, self.config.coaddName +
"Coadd_measMatch")
1132 if self.config.doWriteMatchesDenormalized:
1133 denormMatches = denormalizeMatches(result.matches, result.matchMeta)
1134 dataRef.put(denormMatches, self.config.coaddName +
"Coadd_measMatchFull")
1139 \brief Write the source catalog. 1141 \param[in] dataRef: data reference 1142 \param[in] sources: source catalog 1144 dataRef.put(sources, self.config.coaddName +
"Coadd_meas")
1145 self.log.info(
"Wrote %d sources: %s" % (len(sources), dataRef.dataId))
1148 return int(dataRef.get(self.config.coaddName +
"CoaddId"))
1155 \anchor MergeMeasurementsConfig_ 1157 \brief Configuration parameters for the MergeMeasurementsTask 1159 pseudoFilterList = ListField(dtype=str, default=[
"sky"],
1160 doc=
"Names of filters which may have no associated detection\n" 1161 "(N.b. should include MergeDetectionsConfig.skyFilterName)")
1162 snName = Field(dtype=str, default=
"base_PsfFlux",
1163 doc=
"Name of flux measurement for calculating the S/N when choosing the reference band.")
1164 minSN = Field(dtype=float, default=10.,
1165 doc=
"If the S/N from the priority band is below this value (and the S/N " 1166 "is larger than minSNDiff compared to the priority band), use the band with " 1167 "the largest S/N as the reference band.")
1168 minSNDiff = Field(dtype=float, default=3.,
1169 doc=
"If the difference in S/N between another band and the priority band is larger " 1170 "than this value (and the S/N in the priority band is less than minSN) " 1171 "use the band with the largest S/N as the reference band")
1172 flags = ListField(dtype=str, doc=
"Require that these flags, if available, are not set",
1173 default=[
"base_PixelFlags_flag_interpolatedCenter",
"base_PsfFlux_flag",
1174 "ext_photometryKron_KronFlux_flag",
"modelfit_CModel_flag", ])
1186 \anchor MergeMeasurementsTask_ 1188 \brief Merge measurements from multiple bands 1190 \section pipe_tasks_multiBand_Contents Contents 1192 - \ref pipe_tasks_multiBand_MergeMeasurementsTask_Purpose 1193 - \ref pipe_tasks_multiBand_MergeMeasurementsTask_Initialize 1194 - \ref pipe_tasks_multiBand_MergeMeasurementsTask_Run 1195 - \ref pipe_tasks_multiBand_MergeMeasurementsTask_Config 1196 - \ref pipe_tasks_multiBand_MergeMeasurementsTask_Debug 1197 - \ref pipe_tasks_multiband_MergeMeasurementsTask_Example 1199 \section pipe_tasks_multiBand_MergeMeasurementsTask_Purpose Description 1201 Command-line task that merges measurements from multiple bands. 1203 Combines consistent (i.e. with the same peaks and footprints) catalogs of sources from multiple filter 1204 bands to construct a unified catalog that is suitable for driving forced photometry. Every source is 1205 required to have centroid, shape and flux measurements in each band. 1208 deepCoadd_meas{tract,patch,filter}: SourceCatalog 1210 deepCoadd_ref{tract,patch}: SourceCatalog 1214 MergeMeasurementsTask subclasses \ref MergeSourcesTask_ "MergeSourcesTask". 1216 \section pipe_tasks_multiBand_MergeMeasurementsTask_Initialize Task initialization 1218 \copydoc \_\_init\_\_ 1220 \section pipe_tasks_multiBand_MergeMeasurementsTask_Run Invoking the Task 1224 \section pipe_tasks_multiBand_MergeMeasurementsTask_Config Configuration parameters 1226 See \ref MergeMeasurementsConfig_ 1228 \section pipe_tasks_multiBand_MergeMeasurementsTask_Debug Debug variables 1230 The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a 1231 flag \c -d to import \b debug.py from your \c PYTHONPATH; see \ref baseDebug for more about \b debug.py 1234 MergeMeasurementsTask has no debug variables. 1236 \section pipe_tasks_multiband_MergeMeasurementsTask_Example A complete example of using MergeMeasurementsTask 1238 MergeMeasurementsTask is meant to be run after deblending & measuring sources in every band. 1239 The purpose of the task is to generate a catalog of sources suitable for driving forced photometry in 1240 coadds and individual exposures. 1241 Command-line usage of MergeMeasurementsTask expects a data reference to the coadds to be processed. A list 1242 of the available optional arguments can be obtained by calling mergeCoaddMeasurements.py with the `--help` 1243 command line argument: 1245 mergeCoaddMeasurements.py --help 1248 To demonstrate usage of the DetectCoaddSourcesTask in the larger context of multi-band processing, we 1249 will process HSC data in the [ci_hsc](https://github.com/lsst/ci_hsc) package. Assuming one has finished 1250 step 7 at \ref pipeTasks_multiBand, one may merge the catalogs generated after deblending and measuring 1253 mergeCoaddMeasurements.py $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-I^HSC-R 1255 This will merge the HSC-I & HSC-R band catalogs. The results are written in 1256 `$CI_HSC_DIR/DATA/deepCoadd-results/`. 1258 _DefaultName =
"mergeCoaddMeasurements" 1259 ConfigClass = MergeMeasurementsConfig
1260 inputDataset =
"meas" 1261 outputDataset =
"ref" 1262 getSchemaCatalogs = _makeGetSchemaCatalogs(
"ref")
1264 def __init__(self, butler=None, schema=None, **kwargs):
1266 Initialize the task. 1268 Additional keyword arguments (forwarded to MergeSourcesTask.__init__): 1269 \param[in] schema: the schema of the detection catalogs used as input to this one 1270 \param[in] butler: a butler used to read the input schema from disk, if schema is None 1272 The task will set its own self.schema attribute to the schema of the output merged catalog. 1274 MergeSourcesTask.__init__(self, butler=butler, schema=schema, **kwargs)
1278 self.
fluxKey = inputSchema.find(self.config.snName +
"_flux").getKey()
1279 self.
fluxErrKey = inputSchema.find(self.config.snName +
"_fluxSigma").getKey()
1280 self.
fluxFlagKey = inputSchema.find(self.config.snName +
"_flag").getKey()
1283 for band
in self.config.priorityList:
1285 outputKey = self.
schemaMapper.editOutputSchema().addField(
1286 "merge_measurement_%s" % short,
1288 doc=
"Flag field set if the measurements here are from the %s filter" % band
1290 peakKey = inputSchema.find(
"merge_peak_%s" % short).key
1291 footprintKey = inputSchema.find(
"merge_footprint_%s" % short).key
1292 self.
flagKeys[band] = Struct(peak=peakKey, footprint=footprintKey, output=outputKey)
1296 for filt
in self.config.pseudoFilterList:
1300 self.log.warn(
"merge_peak is not set for pseudo-filter %s" % filt)
1303 for flag
in self.config.flags:
1306 except KeyError
as exc:
1307 self.log.warn(
"Can't find flag %s in schema: %s" % (flag, exc,))
1311 Merge measurement catalogs to create a single reference catalog for forced photometry 1313 \param[in] catalogs: the catalogs to be merged 1314 \param[in] patchRef: patch reference for data 1316 For parent sources, we choose the first band in config.priorityList for which the 1317 merge_footprint flag for that band is is True. 1319 For child sources, the logic is the same, except that we use the merge_peak flags. 1322 orderedCatalogs = [catalogs[band]
for band
in self.config.priorityList
if band
in catalogs.keys()]
1323 orderedKeys = [self.
flagKeys[band]
for band
in self.config.priorityList
if band
in catalogs.keys()]
1325 mergedCatalog = afwTable.SourceCatalog(self.
schema)
1326 mergedCatalog.reserve(len(orderedCatalogs[0]))
1328 idKey = orderedCatalogs[0].table.getIdKey()
1329 for catalog
in orderedCatalogs[1:]:
1330 if numpy.any(orderedCatalogs[0].get(idKey) != catalog.get(idKey)):
1331 raise ValueError(
"Error in inputs to MergeCoaddMeasurements: source IDs do not match")
1335 for orderedRecords
in zip(*orderedCatalogs):
1338 maxSNFlagKeys =
None 1340 priorityRecord =
None 1341 priorityFlagKeys =
None 1343 hasPseudoFilter =
False 1347 for inputRecord, flagKeys
in zip(orderedRecords, orderedKeys):
1348 parent = (inputRecord.getParent() == 0
and inputRecord.get(flagKeys.footprint))
1349 child = (inputRecord.getParent() != 0
and inputRecord.get(flagKeys.peak))
1351 if not (parent
or child):
1353 if inputRecord.get(pseudoFilterKey):
1354 hasPseudoFilter =
True 1355 priorityRecord = inputRecord
1356 priorityFlagKeys = flagKeys
1361 isBad = any(inputRecord.get(flag)
for flag
in self.
badFlags)
1366 if numpy.isnan(sn)
or sn < 0.:
1368 if (parent
or child)
and priorityRecord
is None:
1369 priorityRecord = inputRecord
1370 priorityFlagKeys = flagKeys
1373 maxSNRecord = inputRecord
1374 maxSNFlagKeys = flagKeys
1387 bestRecord = priorityRecord
1388 bestFlagKeys = priorityFlagKeys
1389 elif (prioritySN < self.config.minSN
and (maxSN - prioritySN) > self.config.minSNDiff
and 1390 maxSNRecord
is not None):
1391 bestRecord = maxSNRecord
1392 bestFlagKeys = maxSNFlagKeys
1393 elif priorityRecord
is not None:
1394 bestRecord = priorityRecord
1395 bestFlagKeys = priorityFlagKeys
1397 if bestRecord
is not None and bestFlagKeys
is not None:
1398 outputRecord = mergedCatalog.addNew()
1400 outputRecord.set(bestFlagKeys.output,
True)
1402 raise ValueError(
"Error in inputs to MergeCoaddMeasurements: no valid reference for %s" %
1403 inputRecord.getId())
1406 for inputCatalog
in orderedCatalogs:
1407 if len(mergedCatalog) != len(inputCatalog):
1408 raise ValueError(
"Mismatch between catalog sizes: %s != %s" %
1409 (len(mergedCatalog), len(orderedCatalogs)))
1411 return mergedCatalog
def getSkySourceFootprints(self, mergedList, skyInfo, seed)
Return a list of Footprints of sky objects which don't overlap with anything in mergedList.
Merge coadd detections from multiple bands.
def makeTask(self, parsedCmd=None, args=None)
Provide a butler to the Task constructor.
def getInputSchema(self, butler=None, schema=None)
Obtain the input schema either directly or froma butler reference.
def getSchemaCatalogs(self)
Return a dict of empty catalogs for each catalog dataset produced by this task.
def runDetection(self, exposure, idFactory, expId)
Run detection on an exposure.
def cullPeaks(self, catalog)
Attempt to remove garbage peaks (mostly on the outskirts of large blends).
def run(self, patchRef)
Deblend and measure.
Task runner for the MergeSourcesTask. Required because the run method requires a list of dataRefs rat...
def write(self, exposure, results, patchRef)
Write out results from runDetection.
def __init__(self, butler=None, schema=None, kwargs)
Initialize the task.
def __init__(self, butler=None, schema=None, kwargs)
Initialize the task.
Configuration parameters for the DetectCoaddSourcesTask.
def __init__(self, schema=None, kwargs)
Initialize the task.
Merge measurements from multiple bands.
def run(self, patchRefList)
Merge coadd sources from multiple bands.
Deblend sources from master catalog in each coadd seperately and measure.
def writeMatches(self, dataRef, exposure, sources)
Write matches of the sources to the astrometric reference catalog.
def getShortFilterName(name)
def run(self, patchRef)
Run detection on a coadd.
def mergeCatalogs(self, catalogs, patchRef)
Merge measurement catalogs to create a single reference catalog for forced photometry.
def mergeCatalogs(self, catalogs, patchRef)
Merge multiple catalogs.
Configuration parameters for the MergeMeasurementsTask.
def readSources(self, dataRef)
Read input sources.
def getExposureId(self, dataRef)
Configuration parameters for the MergeDetectionsTask.
Configuration for merging sources.
def write(self, patchRef, catalog)
Write the output.
def mergeCatalogs(self, catalogs, patchRef)
Merge multiple catalogs.
A base class for merging source catalogs.
def write(self, dataRef, sources)
Write the source catalog.
def readCatalog(self, patchRef)
Read input catalog.
def scaleVariance(maskedImage, maskPlanes, log=None)
Scale the variance in a maskedImage.
Configuration parameters for the MeasureMergedCoaddSourcesTask.
def getSkyInfo(coaddName, patchRef)
Return the SkyMap, tract and patch information, wcs, and outer bbox of the patch to be coadded...
def writeMetadata(self, dataRefList)
No metadata to write, and not sure how to write it for a list of dataRefs.
def __init__(self, butler=None, schema=None, peakSchema=None, refObjLoader=None, kwargs)
Initialize the task.
Detect sources on a coadd.
def __init__(self, butler=None, schema=None, kwargs)
Initialize the merge detections task.
def getTargetList(parsedCmd, kwargs)
Provide a list of patch references for each patch.