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.matchDiffimSourceInjected Namespace Reference

Classes

class  MatchInjectedToDiaSourceConnections
 

Variables

 injectedCat : `astropy.table.table.Table`
 
 diffIm : `lsst.afw.image.Exposure`
 
 diaSources : `afw.table.SourceCatalog`
 
 result : `lsst.pipe.base.Struct`
 
 associatedDiaSources : `pandas.DataFrame`
 
 ras : `numpy.ndarray`, (N,)
 
 decs : `numpy.ndarray`, (N,)
 
 vectors : `numpy.ndarray`, (N, 3)
 
 fakeCat : `astropy.table.table.Table`
 
 image : `lsst.afw.image.exposure.exposure.ExposureF`
 
 matchDiaSources : `pandas.DataFrame`
 
 assocDiaSources : `pandas.DataFrame`
 

Variable Documentation

◆ assocDiaSources

lsst.pipe.tasks.matchDiffimSourceInjected.assocDiaSources : `pandas.DataFrame`

Definition at line 406 of file matchDiffimSourceInjected.py.

◆ associatedDiaSources

lsst.pipe.tasks.matchDiffimSourceInjected.associatedDiaSources : `pandas.DataFrame`

Definition at line 229 of file matchDiffimSourceInjected.py.

◆ decs

lsst.pipe.tasks.matchDiffimSourceInjected.decs : `numpy.ndarray`, (N,)

Definition at line 273 of file matchDiffimSourceInjected.py.

◆ diaSources

lsst.pipe.tasks.matchDiffimSourceInjected.diaSources : `afw.table.SourceCatalog`

Definition at line 123 of file matchDiffimSourceInjected.py.

◆ diffIm

lsst.pipe.tasks.matchDiffimSourceInjected.diffIm : `lsst.afw.image.Exposure`

Definition at line 121 of file matchDiffimSourceInjected.py.

◆ fakeCat

lsst.pipe.tasks.matchDiffimSourceInjected.fakeCat : `astropy.table.table.Table`
vectors = np.empty((len(ras), 3))

vectors[:, 2] = np.sin(decs)
vectors[:, 0] = np.cos(decs) * np.cos(ras)
vectors[:, 1] = np.cos(decs) * np.sin(ras)

return vectors

def _addPixCoords(self, fakeCat, image):
wcs = image.getWcs()

# Get x/y pixel coordinates for injected sources.
xs, ys = wcs.skyToPixelArray(
    fakeCat["ra"],
    fakeCat["dec"],
    degrees=True
)
fakeCat["x"] = xs
fakeCat["y"] = ys

return fakeCat

def _trimFakeCat(self, fakeCat, image):

Definition at line 294 of file matchDiffimSourceInjected.py.

◆ image

lsst.pipe.tasks.matchDiffimSourceInjected.image : `lsst.afw.image.exposure.exposure.ExposureF`

Definition at line 296 of file matchDiffimSourceInjected.py.

◆ injectedCat

lsst.pipe.tasks.matchDiffimSourceInjected.injectedCat : `astropy.table.table.Table`
matchDistanceArcseconds = pexConfig.RangeField(
    doc="Distance in arcseconds to match within.",
    dtype=float,
    default=0.5,
    min=0,
    max=10,
)
doMatchVisit = pexConfig.Field(
    dtype=bool,
    default=True,
    doc="Match visit to trim the fakeCat"
)
trimBuffer = pexConfig.Field(
    doc="Size of the pixel buffer surrounding the image."
        "Only those fake sources with a centroid"
        "falling within the image+buffer region will be considered matches.",
    dtype=int,
    default=50,
)
doForcedMeasurement = pexConfig.Field(
    dtype=bool,
    default=True,
    doc="Force measurement of the fakes at the injection locations."
)
forcedMeasurement = pexConfig.ConfigurableField(
    target=ForcedMeasurementTask,
    doc="Task to force photometer difference image at injection locations.",
)


class MatchInjectedToDiaSourceTask(PipelineTask):

_DefaultName = "matchInjectedToDiaSource"
ConfigClass = MatchInjectedToDiaSourceConfig

def run(self, injectedCat, diffIm, diaSources):
if self.config.doMatchVisit:
    fakeCat = self._trimFakeCat(injectedCat, diffIm)
else:
    fakeCat = injectedCat
if self.config.doForcedMeasurement:
    self._estimateFakesSNR(fakeCat, diffIm)

return self._processFakes(fakeCat, diaSources)

def _estimateFakesSNR(self, injectedCat, diffIm):
# Create a schema for the forced measurement task
schema = afwTable.SourceTable.makeMinimalSchema()
schema.addField("x", "D", "x position in image.", units="pixel")
schema.addField("y", "D", "y position in image.", units="pixel")
schema.addField("deblend_nChild", "I", "Need for minimal forced phot schema")

pluginList = [
    "base_PixelFlags",
    "base_SdssCentroid",
    "base_CircularApertureFlux",
    "base_PsfFlux",
    "base_LocalBackground"
]
forcedMeasConfig = ForcedMeasurementConfig(plugins=pluginList)
forcedMeasConfig.slots.centroid = 'base_SdssCentroid'
forcedMeasConfig.slots.shape = None

# Create the forced measurement task
forcedMeas = ForcedMeasurementTask(schema, config=forcedMeasConfig)

# Specify the columns to copy from the input catalog to the output catalog
forcedMeas.copyColumns = {"coord_ra": "ra", "coord_dec": "dec"}

# Create an afw table from the input catalog
outputCatalog = afwTable.SourceCatalog(schema)
outputCatalog.reserve(len(injectedCat))
for row in injectedCat:
    outputRecord = outputCatalog.addNew()
    outputRecord.setId(row['injection_id'])
    outputRecord.setCoord(lsstGeom.SpherePoint(row["ra"], row["dec"], lsstGeom.degrees))
    outputRecord.set("x", row["x"])
    outputRecord.set("y", row["y"])

# Generate the forced measurement catalog
forcedSources = forcedMeas.generateMeasCat(diffIm, outputCatalog, diffIm.getWcs())
# Attach the PSF shape footprints to the forced measurement catalog
forcedMeas.attachPsfShapeFootprints(forcedSources, diffIm)

# Copy the x and y positions from the forced measurement catalog back
# to the input catalog
for src, tgt in zip(forcedSources, outputCatalog):
    src.set('base_SdssCentroid_x', tgt['x'])
    src.set('base_SdssCentroid_y', tgt['y'])

# Define the centroid for the forced measurement catalog
forcedSources.defineCentroid('base_SdssCentroid')
# Run the forced measurement task
forcedMeas.run(forcedSources, diffIm, outputCatalog, diffIm.getWcs())
# Convert the forced measurement catalog to an astropy table
forcedSources_table = forcedSources.asAstropy()

# Add the forced measurement columns to the input catalog
for column in forcedSources_table.columns:
    if "Flux" in column or "flag" in column:
        injectedCat["forced_"+column] = forcedSources_table[column]

# Add the SNR columns to the input catalog
for column in injectedCat.colnames:
    if column.endswith("instFlux"):
        flux = injectedCat[column]
        fluxErr = injectedCat[column+"Err"].copy()
        fluxErr = np.where(
            (fluxErr <= 0) | (np.isnan(fluxErr)), np.nanmax(fluxErr), fluxErr)

        injectedCat[column+"_SNR"] = flux / fluxErr

def _processFakes(self, injectedCat, diaSources):

Definition at line 119 of file matchDiffimSourceInjected.py.

◆ matchDiaSources

lsst.pipe.tasks.matchDiffimSourceInjected.matchDiaSources : `pandas.DataFrame`
# fakeCat must be processed with _addPixCoords before trimming
fakeCat = self._addPixCoords(fakeCat, image)

# Prefilter in ra/dec to avoid cases where the wcs incorrectly maps
# input fakes which are really off the chip onto it.
ras = fakeCat["ra"] * u.deg
decs = fakeCat["dec"] * u.deg

isContainedRaDec = image.containsSkyCoords(ras, decs, padding=0)

# now use the exact pixel BBox to filter to only fakes that were inserted
xs = fakeCat["x"]
ys = fakeCat["y"]

bbox = lsstGeom.Box2D(image.getBBox())
isContainedXy = xs - self.config.trimBuffer >= bbox.minX
isContainedXy &= xs + self.config.trimBuffer <= bbox.maxX
isContainedXy &= ys - self.config.trimBuffer >= bbox.minY
isContainedXy &= ys + self.config.trimBuffer <= bbox.maxY

return fakeCat[isContainedRaDec & isContainedXy]


class MatchInjectedToAssocDiaSourceConnections(
PipelineTaskConnections,
defaultTemplates={"coaddName": "deep",
              "fakesType": "fakes_"},
dimensions=("instrument",
        "visit",
        "detector")):

assocDiaSources = connTypes.Input(
doc="An assocDiaSource catalog to match against fakeCat from the"
    "diaPipe run. Assumed to be SDMified.",
name="{fakesType}{coaddName}Diff_assocDiaSrc",
storageClass="DataFrame",
dimensions=("instrument", "visit", "detector"),
)
matchDiaSources = connTypes.Input(
doc="A catalog of those fakeCat sources that have a match in "
    "diaSrc. The schema is the union of the schemas for "
    "``fakeCat`` and ``diaSrc``.",
name="{fakesType}{coaddName}Diff_matchDiaSrc",
storageClass="DataFrame",
dimensions=("instrument", "visit", "detector"),
)
matchAssocDiaSources = connTypes.Output(
doc="A catalog of those fakeCat sources that have a match in "
    "associatedDiaSources. The schema is the union of the schemas for "
    "``fakeCat`` and ``associatedDiaSources``.",
name="{fakesType}{coaddName}Diff_matchAssocDiaSrc",
storageClass="DataFrame",
dimensions=("instrument", "visit", "detector"),
)


class MatchInjectedToAssocDiaSourceConfig(
PipelineTaskConfig,
pipelineConnections=MatchInjectedToAssocDiaSourceConnections):
class MatchInjectedToAssocDiaSourceTask(PipelineTask):

_DefaultName = "matchInjectedToAssocDiaSource"
ConfigClass = MatchInjectedToAssocDiaSourceConfig

def run(self, assocDiaSources, matchDiaSources):

Definition at line 404 of file matchDiffimSourceInjected.py.

◆ ras

lsst.pipe.tasks.matchDiffimSourceInjected.ras : `numpy.ndarray`, (N,)
# First match the diaSrc to the injected fakes
injectedCat = injectedCat.to_pandas()
nPossibleFakes = len(injectedCat)

fakeVects = self._getVectors(
    np.radians(injectedCat.ra),
    np.radians(injectedCat.dec))
diaSrcVects = self._getVectors(
    diaSources['coord_ra'],
    diaSources['coord_dec'])

diaSrcTree = cKDTree(diaSrcVects)
dist, idxs = diaSrcTree.query(
    fakeVects,
    distance_upper_bound=np.radians(self.config.matchDistanceArcseconds / 3600))
nFakesFound = np.isfinite(dist).sum()

self.log.info("Found %d out of %d possible in diaSources.", nFakesFound, nPossibleFakes)

# assign diaSourceId to the matched fakes
diaSrcIds = diaSources['id'][np.where(np.isfinite(dist), idxs, 0)]
matchedFakes = injectedCat.assign(diaSourceId=np.where(np.isfinite(dist), diaSrcIds, 0))
matchedFakes['dist_diaSrc'] = np.where(np.isfinite(dist), 3600*np.rad2deg(dist), -1)

return Struct(matchDiaSources=matchedFakes)

def _getVectors(self, ras, decs):

Definition at line 271 of file matchDiffimSourceInjected.py.

◆ result

lsst.pipe.tasks.matchDiffimSourceInjected.result : `lsst.pipe.base.Struct`

Definition at line 127 of file matchDiffimSourceInjected.py.

◆ vectors

lsst.pipe.tasks.matchDiffimSourceInjected.vectors : `numpy.ndarray`, (N, 3)

Definition at line 278 of file matchDiffimSourceInjected.py.