LSSTApplications  16.0-10-g1758552+4,16.0-10-g4f78f78+4,16.0-10-gc1446dd+30,16.0-11-g39ac3c7+2,16.0-13-g066a532+3,16.0-14-g6c7ed55+4,16.0-14-gd373004+3,16.0-15-g072d20e+4,16.0-15-gb461e1a+2,16.0-16-g48c959a+3,16.0-16-g89065d4+2,16.0-16-gd8e3590+4,16.0-19-gb830ed4e+4,16.0-2-g0febb12+20,16.0-2-g9d5294e+53,16.0-2-ga8830df+3,16.0-20-g17d57d5+2,16.0-22-gf7a7fdf+3,16.0-27-g78173a71+3,16.0-3-g324faa9+3,16.0-3-gcfd6c53+51,16.0-3-ge00e371+9,16.0-4-g03cf288+42,16.0-4-g5f3a788+19,16.0-4-ga3eb747+9,16.0-4-gabf74b7+4,16.0-4-gb13d127+3,16.0-5-g6a53317+9,16.0-5-gb3f8a4b+62,16.0-5-gef99c9f+4,16.0-57-g90e7ba260+2,16.0-6-g0838257+3,16.0-6-g9321be7+3,16.0-6-gcbc7b31+3,16.0-6-gf49912c+4,16.0-7-gd2eeba5+12,16.0-8-g21fd5fe+4,16.0-8-g3a9f023+4,16.0-9-g85d1a16+4,master-g7b902255af+4,w.2018.43
LSSTDataManagementBasePackage
Public Member Functions | Public Attributes | Static Public Attributes | List of all members
lsst.pipe.tasks.multiBand.MergeDetectionsTask Class Reference

Merge coadd detections from multiple bands. More...

Inheritance diagram for lsst.pipe.tasks.multiBand.MergeDetectionsTask:
lsst.pipe.tasks.multiBand.MergeSourcesTask lsst.pipe.tasks.dcrMultiBand.MergeDcrDetectionsTask

Public Member Functions

def __init__ (self, butler=None, schema=None, kwargs)
 Initialize the merge detections task. More...
 
def run (self, catalogs, patchRef)
 Merge multiple catalogs. More...
 
def cullPeaks (self, catalog)
 Attempt to remove garbage peaks (mostly on the outskirts of large blends). More...
 
def getSchemaCatalogs (self)
 Return a dict of empty catalogs for each catalog dataset produced by this task. More...
 
def getSkySourceFootprints (self, mergedList, skyInfo, seed)
 Return a list of Footprints of sky objects which don't overlap with anything in mergedList. More...
 
def getInputSchema (self, butler=None, schema=None)
 Obtain the input schema either directly or froma butler reference. More...
 
def runDataRef (self, patchRefList)
 Merge coadd sources from multiple bands. More...
 
def readCatalog (self, patchRef)
 Read input catalog. More...
 
def write (self, patchRef, catalog)
 Write the output. More...
 
def writeMetadata (self, dataRefList)
 No metadata to write, and not sure how to write it for a list of dataRefs. More...
 

Public Attributes

 schema
 
 merged
 

Static Public Attributes

 ConfigClass = MergeDetectionsConfig
 
string inputDataset = "det"
 
string outputDataset = "mergeDet"
 
 makeIdFactory = _makeMakeIdFactory("MergedCoaddId")
 
 RunnerClass = MergeSourcesRunner
 
 getSchemaCatalogs = None
 

Detailed Description

Merge coadd detections from multiple bands.

Contents

Description

Command-line task that merges sources detected in coadds of exposures obtained with different filters.

To perform photometry consistently across coadds in multiple filter bands, we create a master catalog of sources from all bands by merging the sources (peaks & footprints) detected in each coadd, while keeping track of which band each source originates in.

The catalog merge is performed by getMergedSourceCatalog. Spurious peaks detected around bright objects are culled as described in CullPeaksConfig_.

Inputs:
deepCoadd_det{tract,patch,filter}: SourceCatalog (only parent Footprints)
Outputs:
deepCoadd_mergeDet{tract,patch}: SourceCatalog (only parent Footprints)
Data Unit:
tract, patch

MergeDetectionsTask subclasses MergeSourcesTask.

Task initialisation

Initialize the merge detections task. A FootprintMergeList will be used to merge the source catalogs.

Additional keyword arguments (forwarded to MergeSourcesTask.__init__):

Parameters
[in]schemathe schema of the detection catalogs used as input to this one
[in]butlera butler used to read the input schema from disk, if schema is None
[in]**kwargskeyword arguments to be passed to MergeSourcesTask.__init__

The task will set its own self.schema attribute to the schema of the output merged catalog.

Invoking the Task

Merge multiple catalogs. After ordering the catalogs and filters in priority order, getMergedSourceCatalog of the FootprintMergeList created by __init__ is used to perform the actual merging. Finally, cullPeaks is used to remove garbage peaks detected around bright objects.

Parameters
[in]catalogs
[in]patchRef
[out]mergedList

Configuration parameters

See MergeDetectionsConfig_

Debug variables

The command line task interface supports a flag -d to import debug.py from your PYTHONPATH; see Using lsstDebug to control debugging output for more about debug.py files.

MergeDetectionsTask has no debug variables.

A complete example of using MergeDetectionsTask

MergeDetectionsTask is meant to be run after detecting sources in coadds generated for the chosen subset of the available bands. The purpose of the task is to merge sources (peaks & footprints) detected in the coadds generated from the chosen subset of filters. Subsequent tasks in the multi-band processing procedure will deblend the generated master list of sources and, eventually, perform forced photometry. Command-line usage of MergeDetectionsTask expects data references for all the coadds to be processed. A list of the available optional arguments can be obtained by calling mergeCoaddDetections.py with the --help command line argument:

mergeCoaddDetections.py --help

To demonstrate usage of the DetectCoaddSourcesTask in the larger context of multi-band processing, we will process HSC data in the ci_hsc package. Assuming one has finished step 5 at pipeTasks_multiBand, one may merge the catalogs of sources from each coadd as follows:

mergeCoaddDetections.py $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-I^HSC-R

This will merge the HSC-I & -R band parent source catalogs and write the results to $CI_HSC_DIR/DATA/deepCoadd-results/merged/0/5,4/mergeDet-0-5,4.fits.

The next step in the multi-band processing procedure is MeasureMergedCoaddSourcesTask

Definition at line 691 of file multiBand.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.pipe.tasks.multiBand.MergeDetectionsTask.__init__ (   self,
  butler = None,
  schema = None,
  kwargs 
)

Initialize the merge detections task.

A FootprintMergeList will be used to merge the source catalogs.

Additional keyword arguments (forwarded to MergeSourcesTask.__init__):

Parameters
[in]schemathe schema of the detection catalogs used as input to this one
[in]butlera butler used to read the input schema from disk, if schema is None
[in]**kwargskeyword arguments to be passed to MergeSourcesTask.__init__

The task will set its own self.schema attribute to the schema of the output merged catalog.

Definition at line 778 of file multiBand.py.

778  def __init__(self, butler=None, schema=None, **kwargs):
779  """!
780  @brief Initialize the merge detections task.
781 
782  A @ref FootprintMergeList_ "FootprintMergeList" will be used to
783  merge the source catalogs.
784 
785  Additional keyword arguments (forwarded to MergeSourcesTask.__init__):
786  @param[in] schema the schema of the detection catalogs used as input to this one
787  @param[in] butler a butler used to read the input schema from disk, if schema is None
788  @param[in] **kwargs keyword arguments to be passed to MergeSourcesTask.__init__
789 
790  The task will set its own self.schema attribute to the schema of the output merged catalog.
791  """
792  MergeSourcesTask.__init__(self, butler=butler, schema=schema, **kwargs)
793  self.makeSubtask("skyObjects")
794  self.schema = self.getInputSchema(butler=butler, schema=schema)
795 
796  filterNames = [getShortFilterName(name) for name in self.config.priorityList]
797  filterNames += [self.config.skyFilterName]
798  self.merged = afwDetect.FootprintMergeList(self.schema, filterNames)
799 
def getShortFilterName(name)
Definition: multiBand.py:98
def __init__(self, minimum, dataRange, Q)

Member Function Documentation

◆ cullPeaks()

def lsst.pipe.tasks.multiBand.MergeDetectionsTask.cullPeaks (   self,
  catalog 
)

Attempt to remove garbage peaks (mostly on the outskirts of large blends).

Parameters
[in]catalogSource catalog

Definition at line 849 of file multiBand.py.

849  def cullPeaks(self, catalog):
850  """!
851  @brief Attempt to remove garbage peaks (mostly on the outskirts of large blends).
852 
853  @param[in] catalog Source catalog
854  """
855  keys = [item.key for item in self.merged.getPeakSchema().extract("merge_peak_*").values()]
856  assert len(keys) > 0, "Error finding flags that associate peaks with their detection bands."
857  totalPeaks = 0
858  culledPeaks = 0
859  for parentSource in catalog:
860  # Make a list copy so we can clear the attached PeakCatalog and append the ones we're keeping
861  # to it (which is easier than deleting as we iterate).
862  keptPeaks = parentSource.getFootprint().getPeaks()
863  oldPeaks = list(keptPeaks)
864  keptPeaks.clear()
865  familySize = len(oldPeaks)
866  totalPeaks += familySize
867  for rank, peak in enumerate(oldPeaks):
868  if ((rank < self.config.cullPeaks.rankSufficient) or
869  (sum([peak.get(k) for k in keys]) >= self.config.cullPeaks.nBandsSufficient) or
870  (rank < self.config.cullPeaks.rankConsidered and
871  rank < self.config.cullPeaks.rankNormalizedConsidered * familySize)):
872  keptPeaks.append(peak)
873  else:
874  culledPeaks += 1
875  self.log.info("Culled %d of %d peaks" % (culledPeaks, totalPeaks))
876 
daf::base::PropertyList * list
Definition: fits.cc:833

◆ getInputSchema()

def lsst.pipe.tasks.multiBand.MergeSourcesTask.getInputSchema (   self,
  butler = None,
  schema = None 
)
inherited

Obtain the input schema either directly or froma butler reference.

Parameters
[in]butlerbutler reference to obtain the input schema from
[in]schemathe input schema

Definition at line 537 of file multiBand.py.

537  def getInputSchema(self, butler=None, schema=None):
538  """!
539  @brief Obtain the input schema either directly or froma butler reference.
540 
541  @param[in] butler butler reference to obtain the input schema from
542  @param[in] schema the input schema
543  """
544  if schema is None:
545  assert butler is not None, "Neither butler nor schema specified"
546  schema = butler.get(self.config.coaddName + "Coadd_" + self.inputDataset + "_schema",
547  immediate=True).schema
548  return schema
549 

◆ getSchemaCatalogs()

def lsst.pipe.tasks.multiBand.MergeDetectionsTask.getSchemaCatalogs (   self)

Return a dict of empty catalogs for each catalog dataset produced by this task.

Parameters
[out]dictionaryof empty catalogs

Definition at line 877 of file multiBand.py.

877  def getSchemaCatalogs(self):
878  """!
879  Return a dict of empty catalogs for each catalog dataset produced by this task.
880 
881  @param[out] dictionary of empty catalogs
882  """
883  mergeDet = afwTable.SourceCatalog(self.schema)
884  peak = afwDetect.PeakCatalog(self.merged.getPeakSchema())
885  return {self.config.coaddName + "Coadd_mergeDet": mergeDet,
886  self.config.coaddName + "Coadd_peak": peak}
887 

◆ getSkySourceFootprints()

def lsst.pipe.tasks.multiBand.MergeDetectionsTask.getSkySourceFootprints (   self,
  mergedList,
  skyInfo,
  seed 
)

Return a list of Footprints of sky objects which don't overlap with anything in mergedList.

Parameters
mergedListThe merged Footprints from all the input bands
skyInfoA description of the patch
seedSeed for the random number generator

Definition at line 888 of file multiBand.py.

888  def getSkySourceFootprints(self, mergedList, skyInfo, seed):
889  """!
890  @brief Return a list of Footprints of sky objects which don't overlap with anything in mergedList
891 
892  @param mergedList The merged Footprints from all the input bands
893  @param skyInfo A description of the patch
894  @param seed Seed for the random number generator
895  """
896  mask = afwImage.Mask(skyInfo.patchInfo.getOuterBBox())
897  detected = mask.getPlaneBitMask("DETECTED")
898  for s in mergedList:
899  s.getFootprint().spans.setMask(mask, detected)
900 
901  footprints = self.skyObjects.run(mask, seed)
902  if not footprints:
903  return footprints
904 
905  # Need to convert the peak catalog's schema so we can set the "merge_peak_<skyFilterName>" flags
906  schema = self.merged.getPeakSchema()
907  mergeKey = schema.find("merge_peak_%s" % self.config.skyFilterName).key
908  converted = []
909  for oldFoot in footprints:
910  assert len(oldFoot.getPeaks()) == 1, "Should be a single peak only"
911  peak = oldFoot.getPeaks()[0]
912  newFoot = afwDetect.Footprint(oldFoot.spans, schema)
913  newFoot.addPeak(peak.getFx(), peak.getFy(), peak.getPeakValue())
914  newFoot.getPeaks()[0].set(mergeKey, True)
915  converted.append(newFoot)
916 
917  return converted
918 
919 
daf::base::PropertySet * set
Definition: fits.cc:832
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:78
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:62

◆ readCatalog()

def lsst.pipe.tasks.multiBand.MergeSourcesTask.readCatalog (   self,
  patchRef 
)
inherited

Read input catalog.

We read the input dataset provided by the 'inputDataset' class variable.

Parameters
[in]patchRefdata reference for patch
Returns
tuple consisting of the filter name and the catalog

Definition at line 574 of file multiBand.py.

574  def readCatalog(self, patchRef):
575  """!
576  @brief Read input catalog.
577 
578  We read the input dataset provided by the 'inputDataset'
579  class variable.
580 
581  @param[in] patchRef data reference for patch
582  @return tuple consisting of the filter name and the catalog
583  """
584  filterName = patchRef.dataId["filter"]
585  catalog = patchRef.get(self.config.coaddName + "Coadd_" + self.inputDataset, immediate=True)
586  self.log.info("Read %d sources for filter %s: %s" % (len(catalog), filterName, patchRef.dataId))
587  return filterName, catalog
588 

◆ run()

def lsst.pipe.tasks.multiBand.MergeDetectionsTask.run (   self,
  catalogs,
  patchRef 
)

Merge multiple catalogs.

After ordering the catalogs and filters in priority order, getMergedSourceCatalog of the FootprintMergeList created by __init__ is used to perform the actual merging. Finally, cullPeaks is used to remove garbage peaks detected around bright objects.

Parameters
[in]catalogs
[in]patchRef
[out]mergedList

Definition at line 800 of file multiBand.py.

800  def run(self, catalogs, patchRef):
801  r"""!
802  @brief Merge multiple catalogs.
803 
804  After ordering the catalogs and filters in priority order,
805  @ref getMergedSourceCatalog of the @ref FootprintMergeList_ "FootprintMergeList" created by
806  @ref \_\_init\_\_ is used to perform the actual merging. Finally, @ref cullPeaks is used to remove
807  garbage peaks detected around bright objects.
808 
809  @param[in] catalogs
810  @param[in] patchRef
811  @param[out] mergedList
812  """
813 
814  # Convert distance to tract coordinate
815  skyInfo = getSkyInfo(coaddName=self.config.coaddName, patchRef=patchRef)
816  tractWcs = skyInfo.wcs
817  peakDistance = self.config.minNewPeak / tractWcs.getPixelScale().asArcseconds()
818  samePeakDistance = self.config.maxSamePeak / tractWcs.getPixelScale().asArcseconds()
819 
820  # Put catalogs, filters in priority order
821  orderedCatalogs = [catalogs[band] for band in self.config.priorityList if band in catalogs.keys()]
822  orderedBands = [getShortFilterName(band) for band in self.config.priorityList
823  if band in catalogs.keys()]
824 
825  mergedList = self.merged.getMergedSourceCatalog(orderedCatalogs, orderedBands, peakDistance,
826  self.schema, self.makeIdFactory(patchRef),
827  samePeakDistance)
828 
829  #
830  # Add extra sources that correspond to blank sky
831  #
832  skySeed = patchRef.get(self.config.coaddName + "MergedCoaddId")
833  skySourceFootprints = self.getSkySourceFootprints(mergedList, skyInfo, skySeed)
834  if skySourceFootprints:
835  key = mergedList.schema.find("merge_footprint_%s" % self.config.skyFilterName).key
836  for foot in skySourceFootprints:
837  s = mergedList.addNew()
838  s.setFootprint(foot)
839  s.set(key, True)
840 
841  # Sort Peaks from brightest to faintest
842  for record in mergedList:
843  record.getFootprint().sortPeaks()
844  self.log.info("Merged to %d sources" % len(mergedList))
845  # Attempt to remove garbage peaks
846  self.cullPeaks(mergedList)
847  return mergedList
848 
def getShortFilterName(name)
Definition: multiBand.py:98
def getSkyInfo(coaddName, patchRef)
Return the SkyMap, tract and patch information, wcs, and outer bbox of the patch to be coadded...
Definition: coaddBase.py:253

◆ runDataRef()

def lsst.pipe.tasks.multiBand.MergeSourcesTask.runDataRef (   self,
  patchRefList 
)
inherited

Merge coadd sources from multiple bands.

Calls run which must be defined in subclasses that inherit from MergeSourcesTask.

Parameters
[in]patchRefListlist of data references for each filter

Definition at line 563 of file multiBand.py.

563  def runDataRef(self, patchRefList):
564  """!
565  @brief Merge coadd sources from multiple bands. Calls @ref `run` which must be defined in
566  subclasses that inherit from MergeSourcesTask.
567 
568  @param[in] patchRefList list of data references for each filter
569  """
570  catalogs = dict(self.readCatalog(patchRef) for patchRef in patchRefList)
571  mergedCatalog = self.run(catalogs, patchRefList[0])
572  self.write(patchRefList[0], mergedCatalog)
573 

◆ write()

def lsst.pipe.tasks.multiBand.MergeSourcesTask.write (   self,
  patchRef,
  catalog 
)
inherited

Write the output.

Parameters
[in]patchRefdata reference for patch
[in]catalogcatalog

We write as the dataset provided by the 'outputDataset' class variable.

Definition at line 600 of file multiBand.py.

600  def write(self, patchRef, catalog):
601  """!
602  @brief Write the output.
603 
604  @param[in] patchRef data reference for patch
605  @param[in] catalog catalog
606 
607  We write as the dataset provided by the 'outputDataset'
608  class variable.
609  """
610  patchRef.put(catalog, self.config.coaddName + "Coadd_" + self.outputDataset)
611  # since the filter isn't actually part of the data ID for the dataset we're saving,
612  # it's confusing to see it in the log message, even if the butler simply ignores it.
613  mergeDataId = patchRef.dataId.copy()
614  del mergeDataId["filter"]
615  self.log.info("Wrote merged catalog: %s" % (mergeDataId,))
616 

◆ writeMetadata()

def lsst.pipe.tasks.multiBand.MergeSourcesTask.writeMetadata (   self,
  dataRefList 
)
inherited

No metadata to write, and not sure how to write it for a list of dataRefs.

Definition at line 617 of file multiBand.py.

617  def writeMetadata(self, dataRefList):
618  """!
619  @brief No metadata to write, and not sure how to write it for a list of dataRefs.
620  """
621  pass
622 
623 

Member Data Documentation

◆ ConfigClass

lsst.pipe.tasks.multiBand.MergeDetectionsTask.ConfigClass = MergeDetectionsConfig
static

Definition at line 772 of file multiBand.py.

◆ getSchemaCatalogs

lsst.pipe.tasks.multiBand.MergeSourcesTask.getSchemaCatalogs = None
staticinherited

Definition at line 520 of file multiBand.py.

◆ inputDataset

string lsst.pipe.tasks.multiBand.MergeDetectionsTask.inputDataset = "det"
static

Definition at line 774 of file multiBand.py.

◆ makeIdFactory

lsst.pipe.tasks.multiBand.MergeDetectionsTask.makeIdFactory = _makeMakeIdFactory("MergedCoaddId")
static

Definition at line 776 of file multiBand.py.

◆ merged

lsst.pipe.tasks.multiBand.MergeDetectionsTask.merged

Definition at line 798 of file multiBand.py.

◆ outputDataset

string lsst.pipe.tasks.multiBand.MergeDetectionsTask.outputDataset = "mergeDet"
static

Definition at line 775 of file multiBand.py.

◆ RunnerClass

lsst.pipe.tasks.multiBand.MergeSourcesTask.RunnerClass = MergeSourcesRunner
staticinherited

Definition at line 517 of file multiBand.py.

◆ schema

lsst.pipe.tasks.multiBand.MergeDetectionsTask.schema

Definition at line 794 of file multiBand.py.


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