LSST Applications g00d0e8bbd7+edbf708997,g03191d30f7+9ce8016dbd,g1955dfad08+0bd186d245,g199a45376c+5137f08352,g1fd858c14a+a888a50aa2,g262e1987ae+45f9aba685,g29ae962dfc+1c7d47a24f,g2cef7863aa+73c82f25e4,g35bb328faa+edbf708997,g3fd5ace14f+eed17d2c67,g47891489e3+6dc8069a4c,g53246c7159+edbf708997,g64539dfbff+c4107e45b5,g67b6fd64d1+6dc8069a4c,g74acd417e5+f452e9c21a,g786e29fd12+af89c03590,g7ae74a0b1c+a25e60b391,g7aefaa3e3d+2025e9ce17,g7cc15d900a+2d158402f9,g87389fa792+a4172ec7da,g89139ef638+6dc8069a4c,g8d4809ba88+c4107e45b5,g8d7436a09f+e96c132b44,g8ea07a8fe4+db21c37724,g98df359435+aae6d409c1,ga2180abaac+edbf708997,gac66b60396+966efe6077,gb632fb1845+88945a90f8,gbaa8f7a6c5+38b34f4976,gbf99507273+edbf708997,gca7fc764a6+6dc8069a4c,gd7ef33dd92+6dc8069a4c,gda68eeecaf+7d1e613a8d,gdab6d2f7ff+f452e9c21a,gdbb4c4dda9+c4107e45b5,ge410e46f29+6dc8069a4c,ge41e95a9f2+c4107e45b5,geaed405ab2+e194be0d2b,w.2025.47
LSST Data Management Base Package
Loading...
Searching...
No Matches
lsst.pipe.tasks.multiBand Namespace Reference

Classes

class  DetectCoaddSourcesConnections
 
class  MeasureMergedCoaddSourcesConnections
 

Variables

 exposure = self._cropToExactBinning(exposure, patchInfo).clone()
 
 background = self.detection.background.run(exposure).background
 
 stats = bg.getStatsImage()
 
 schema : ``lsst.afw.table.Schema`, optional
 
 peakSchema : ``lsst.afw.table.Schema`, optional
 
 refObjLoader : `lsst.meas.algorithms.ReferenceObjectLoader`, optional
 
 initInputs : `dict`, optional
 
 sources : `lsst.afw.table.SourceCatalog`
 
 skyInfo : `lsst.pipe.base.Struct`
 
 exposureId : `int` or `bytes`
 
 ccdInputs : `lsst.afw.table.ExposureCatalog`, optional
 
 sourceTableHandleDict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`], optional
 
 finalizedSourceTableHandleDict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`], optional
 
 finalVisitSummaryHandleDict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`], optional
 
 apCorrMap : `lsst.afw.image.ApCorrMap`, optional
 
 results : `lsst.pipe.base.Struct`
 

Variable Documentation

◆ apCorrMap

lsst.pipe.tasks.multiBand.apCorrMap : `lsst.afw.image.ApCorrMap`, optional

Definition at line 929 of file multiBand.py.

◆ background

lsst.pipe.tasks.multiBand.background = self.detection.background.run(exposure).background

Definition at line 410 of file multiBand.py.

◆ ccdInputs

lsst.pipe.tasks.multiBand.ccdInputs : `lsst.afw.table.ExposureCatalog`, optional

Definition at line 917 of file multiBand.py.

◆ exposure

lsst.pipe.tasks.multiBand.exposure = self._cropToExactBinning(exposure, patchInfo).clone()
_DefaultName = "measureCoaddSources"
ConfigClass = MeasureMergedCoaddSourcesConfig

def __init__(self, schema=None, peakSchema=None, refObjLoader=None, initInputs=None,
             **kwargs):
    super().__init__(**kwargs)
    self.deblended = self.config.inputCatalog.startswith("deblended")
    self.inputCatalog = "Coadd_" + self.config.inputCatalog
    if initInputs is not None:
        schema = initInputs['inputSchema'].schema
    if schema is None:
        raise ValueError("Schema must be defined.")
    self.schemaMapper = afwTable.SchemaMapper(schema)
    self.schemaMapper.addMinimalSchema(schema)
    self.schema = self.schemaMapper.getOutputSchema()
    self.algMetadata = PropertyList()
    self.makeSubtask("measurement", schema=self.schema, algMetadata=self.algMetadata)
    self.makeSubtask("setPrimaryFlags", schema=self.schema)
    # TODO[DM-47797]: remove match subtask
    if self.config.doMatchSources:
        self.makeSubtask("match", refObjLoader=refObjLoader)
    if self.config.doPropagateFlags:
        self.makeSubtask("propagateFlags", schema=self.schema)
    self.schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
    if self.config.doApCorr:
        self.makeSubtask("applyApCorr", schema=self.schema)
    if self.config.doRunCatalogCalculation:
        self.makeSubtask("catalogCalculation", schema=self.schema)

    self.outputSchema = afwTable.SourceCatalog(self.schema)

def runQuantum(self, butlerQC, inputRefs, outputRefs):
    inputs = butlerQC.get(inputRefs)

    # TODO[DM-47797]: remove this block
    if self.config.doMatchSources:
        refObjLoader = ReferenceObjectLoader([ref.datasetRef.dataId for ref in inputRefs.refCat],
                                             inputs.pop('refCat'),
                                             name=self.config.connections.refCat,
                                             config=self.config.refObjLoader,
                                             log=self.log)
        self.match.setRefObjLoader(refObjLoader)

    if self.config.useCellCoadds:
        multiple_cell_coadd = inputs.pop("exposure_cells")
        stitched_coadd = multiple_cell_coadd.stitch()
        exposure = stitched_coadd.asExposure()
        background = inputs.pop("background")
        exposure.image -= background.getImage()

        ccdInputs = stitched_coadd.ccds
        apCorrMap = stitched_coadd.ap_corr_map
        band = inputRefs.exposure_cells.dataId["band"]
    else:
        exposure = inputs.pop("exposure")
        # Set psfcache
        # move this to run after gen2 deprecation
        exposure.getPsf().setCacheCapacity(self.config.psfCache)

        ccdInputs = exposure.getInfo().getCoaddInputs().ccds
        apCorrMap = exposure.getInfo().getApCorrMap()
        band = inputRefs.exposure.dataId["band"]

    # Get unique integer ID for IdFactory and RNG seeds; only the latter
    # should really be used as the IDs all come from the input catalog.
    idGenerator = self.config.idGenerator.apply(butlerQC.quantum.dataId)

    # Transform inputCatalog
    table = afwTable.SourceTable.make(self.schema, idGenerator.make_table_id_factory())
    sources = afwTable.SourceCatalog(table)
    # Load the correct input catalog
    if "scarletCatalog" in inputs:
        inputCatalog = inputs.pop("scarletCatalog")
        catalogRef = inputRefs.scarletCatalog
    else:
        inputCatalog = inputs.pop("inputCatalog")
        catalogRef = inputRefs.inputCatalog
    sources.extend(inputCatalog, self.schemaMapper)
    del inputCatalog
    # Add the HeavyFootprints to the deblended sources
    if self.config.doAddFootprints:
        modelData = inputs.pop('scarletModels')
        if self.config.doConserveFlux:
            imageForRedistribution = exposure
        else:
            imageForRedistribution = None
        updateCatalogFootprints(
            modelData=modelData,
            catalog=sources,
            band=band,
            imageForRedistribution=imageForRedistribution,
            removeScarletData=True,
            updateFluxColumns=True,
        )
    table = sources.getTable()
    table.setMetadata(self.algMetadata)  # Capture algorithm metadata to write out to the source catalog.

    skyMap = inputs.pop('skyMap')
    tractNumber = catalogRef.dataId['tract']
    tractInfo = skyMap[tractNumber]
    patchInfo = tractInfo.getPatchInfo(catalogRef.dataId['patch'])
    skyInfo = Struct(
        skyMap=skyMap,
        tractInfo=tractInfo,
        patchInfo=patchInfo,
        wcs=tractInfo.getWcs(),
        bbox=patchInfo.getOuterBBox()
    )

    if self.config.doPropagateFlags:
        if "sourceTableHandles" in inputs:
            sourceTableHandles = inputs.pop("sourceTableHandles")
            sourceTableHandleDict = {handle.dataId["visit"]: handle for handle in sourceTableHandles}
        else:
            sourceTableHandleDict = None
        if "finalizedSourceTableHandles" in inputs:
            finalizedSourceTableHandles = inputs.pop("finalizedSourceTableHandles")
            finalizedSourceTableHandleDict = {handle.dataId["visit"]: handle
                                              for handle in finalizedSourceTableHandles}
        else:
            finalizedSourceTableHandleDict = None
        if "finalVisitSummaryHandles" in inputs:
            finalVisitSummaryHandles = inputs.pop("finalVisitSummaryHandles")
            finalVisitSummaryHandleDict = {handle.dataId["visit"]: handle
                                           for handle in finalVisitSummaryHandles}
        else:
            finalVisitSummaryHandleDict = None

    assert not inputs, "runQuantum got more inputs than expected."
    outputs = self.run(
        exposure=exposure,
        sources=sources,
        skyInfo=skyInfo,
        exposureId=idGenerator.catalog_id,
        ccdInputs=ccdInputs,
        sourceTableHandleDict=sourceTableHandleDict,
        finalizedSourceTableHandleDict=finalizedSourceTableHandleDict,
        finalVisitSummaryHandleDict=finalVisitSummaryHandleDict,
        apCorrMap=apCorrMap,
    )
    # Strip HeavyFootprints to save space on disk
    if self.config.doStripFootprints:
        sources = outputs.outputSources
        for source in sources[sources["parent"] != 0]:
            source.setFootprint(None)
    butlerQC.put(outputs, outputRefs)

def run(self, exposure, sources, skyInfo, exposureId, ccdInputs=None,
        sourceTableHandleDict=None, finalizedSourceTableHandleDict=None, finalVisitSummaryHandleDict=None,
        apCorrMap=None):

Definition at line 407 of file multiBand.py.

◆ exposureId

lsst.pipe.tasks.multiBand.exposureId : `int` or `bytes`

Definition at line 915 of file multiBand.py.

◆ finalizedSourceTableHandleDict

lsst.pipe.tasks.multiBand.finalizedSourceTableHandleDict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`], optional

Definition at line 923 of file multiBand.py.

◆ finalVisitSummaryHandleDict

lsst.pipe.tasks.multiBand.finalVisitSummaryHandleDict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`], optional

Definition at line 926 of file multiBand.py.

◆ initInputs

lsst.pipe.tasks.multiBand.initInputs : `dict`, optional

Definition at line 745 of file multiBand.py.

◆ peakSchema

lsst.pipe.tasks.multiBand.peakSchema : ``lsst.afw.table.Schema`, optional

Definition at line 739 of file multiBand.py.

◆ refObjLoader

lsst.pipe.tasks.multiBand.refObjLoader : `lsst.meas.algorithms.ReferenceObjectLoader`, optional

Definition at line 741 of file multiBand.py.

◆ results

lsst.pipe.tasks.multiBand.results : `lsst.pipe.base.Struct`

Definition at line 935 of file multiBand.py.

◆ schema

lsst.pipe.tasks.multiBand.schema : ``lsst.afw.table.Schema`, optional
inputCatalog = ChoiceField(
    dtype=str,
    default="deblendedCatalog",
    allowed={
        "deblendedCatalog": "Output catalog from ScarletDeblendTask",
        "deblendedFlux": "Output catalog from SourceDeblendTask",
        "mergeDet": "The merged detections before deblending."
    },
    doc="The name of the input catalog.",
    # TODO[DM-47797]: remove this config option and anything using it.
    deprecated="Support for old deblender outputs will be removed after v29.",
)
doAddFootprints = Field(dtype=bool,
                        default=True,
                        doc="Whether or not to add footprints to the input catalog from scarlet models. "
                            "This should be true whenever using the multi-band deblender, "
                            "otherwise this should be False.")
doConserveFlux = Field(dtype=bool, default=True,
                       doc="Whether to use the deblender models as templates to re-distribute the flux "
                           "from the 'exposure' (True), or to perform measurements on the deblender "
                           "model footprints.")
doStripFootprints = Field(dtype=bool, default=True,
                          doc="Whether to strip footprints from the output catalog before "
                              "saving to disk. "
                              "This is usually done when using scarlet models to save disk space.")
useCellCoadds = Field(dtype=bool, default=False, doc="Whether to use cell coadds?")
measurement = ConfigurableField(target=SingleFrameMeasurementTask, doc="Source measurement")
setPrimaryFlags = ConfigurableField(target=SetPrimaryFlagsTask, doc="Set flags for primary tract/patch")
doPropagateFlags = Field(
    dtype=bool, default=True,
    doc="Whether to match sources to CCD catalogs to propagate flags (to e.g. identify PSF stars)"
)
propagateFlags = ConfigurableField(target=PropagateSourceFlagsTask, doc="Propagate source flags to coadd")
doMatchSources = Field(
    dtype=bool,
    default=False,
    doc="Match sources to reference catalog?",
    deprecated="Reference matching in measureCoaddSources will be removed after v29.",
)
match = ConfigurableField(
    target=DirectMatchTask,
    doc="Matching to reference catalog",
    deprecated="Reference matching in measureCoaddSources will be removed after v29.",
)
doWriteMatchesDenormalized = Field(
    dtype=bool,
    default=False,
    doc=("Write reference matches in denormalized format? "
         "This format uses more disk space, but is more convenient to read."),
    deprecated="Reference matching in measureCoaddSources will be removed after v29.",
)
coaddName = Field(dtype=str, default="deep", doc="Name of coadd")
psfCache = Field(dtype=int, default=100, doc="Size of psfCache")
checkUnitsParseStrict = Field(
    doc="Strictness of Astropy unit compatibility check, can be 'raise', 'warn' or 'silent'",
    dtype=str,
    default="raise",
)
doApCorr = Field(
    dtype=bool,
    default=True,
    doc="Apply aperture corrections"
)
applyApCorr = ConfigurableField(
    target=ApplyApCorrTask,
    doc="Subtask to apply aperture corrections"
)
doRunCatalogCalculation = Field(
    dtype=bool,
    default=True,
    doc='Run catalogCalculation task'
)
catalogCalculation = ConfigurableField(
    target=CatalogCalculationTask,
    doc="Subtask to run catalogCalculation plugins on catalog"
)

hasFakes = Field(
    dtype=bool,
    default=False,
    doc="Should be set to True if fake sources have been inserted into the input data."
)
idGenerator = SkyMapIdGeneratorConfig.make_field()

@property
def refObjLoader(self):
    return self.match.refObjLoader

def setDefaults(self):
    super().setDefaults()
    self.measurement.plugins.names |= ['base_InputCount',
                                       'base_Variance',
                                       'base_LocalPhotoCalib',
                                       'base_LocalWcs']

    # TODO: Remove STREAK in DM-44658, streak masking to happen only in
    # ip_diffim; if we can propagate the streak mask from diffim, we can
    # still set flags with it here.
    self.measurement.plugins['base_PixelFlags'].masksFpAnywhere = ['CLIPPED', 'SENSOR_EDGE',
                                                                   'INEXACT_PSF']
    self.measurement.plugins['base_PixelFlags'].masksFpCenter = ['CLIPPED', 'SENSOR_EDGE',
                                                                 'INEXACT_PSF']

def validate(self):
    super().validate()

    if not self.doMatchSources and self.doWriteMatchesDenormalized:
        raise ValueError("Cannot set doWriteMatchesDenormalized if doMatchSources is False.")


class MeasureMergedCoaddSourcesTask(PipelineTask):

Definition at line 737 of file multiBand.py.

◆ skyInfo

lsst.pipe.tasks.multiBand.skyInfo : `lsst.pipe.base.Struct`

Definition at line 912 of file multiBand.py.

◆ sources

lsst.pipe.tasks.multiBand.sources : `lsst.afw.table.SourceCatalog`

Definition at line 909 of file multiBand.py.

◆ sourceTableHandleDict

lsst.pipe.tasks.multiBand.sourceTableHandleDict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`], optional

Definition at line 920 of file multiBand.py.

◆ stats

lsst.pipe.tasks.multiBand.stats = bg.getStatsImage()

Definition at line 412 of file multiBand.py.