LSST Applications g04e9c324dd+8c5ae1fdc5,g134cb467dc+b203dec576,g18429d2f64+358861cd2c,g199a45376c+0ba108daf9,g1fd858c14a+dd066899e3,g262e1987ae+ebfced1d55,g29ae962dfc+72fd90588e,g2cef7863aa+aef1011c0b,g35bb328faa+8c5ae1fdc5,g3fd5ace14f+b668f15bc5,g4595892280+3897dae354,g47891489e3+abcf9c3559,g4d44eb3520+fb4ddce128,g53246c7159+8c5ae1fdc5,g67b6fd64d1+abcf9c3559,g67fd3c3899+1f72b5a9f7,g74acd417e5+cb6b47f07b,g786e29fd12+668abc6043,g87389fa792+8856018cbb,g89139ef638+abcf9c3559,g8d7436a09f+bcf525d20c,g8ea07a8fe4+9f5ccc88ac,g90f42f885a+6054cc57f1,g97be763408+06f794da49,g9dd6db0277+1f72b5a9f7,ga681d05dcb+7e36ad54cd,gabf8522325+735880ea63,gac2eed3f23+abcf9c3559,gb89ab40317+abcf9c3559,gbf99507273+8c5ae1fdc5,gd8ff7fe66e+1f72b5a9f7,gdab6d2f7ff+cb6b47f07b,gdc713202bf+1f72b5a9f7,gdfd2d52018+8225f2b331,ge365c994fd+375fc21c71,ge410e46f29+abcf9c3559,geaed405ab2+562b3308c0,gf9a733ac38+8c5ae1fdc5,w.2025.35
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.