23Insert fake sources into calexps
25from astropy.table
import Table
32from .insertFakes
import InsertFakesTask
36from lsst.pipe.base import PipelineTask, PipelineTaskConfig, CmdLineTask, PipelineTaskConnections
37import lsst.pipe.base.connectionTypes
as cT
42__all__ = [
"ProcessCcdWithFakesConfig",
"ProcessCcdWithFakesTask",
43 "ProcessCcdWithVariableFakesConfig",
"ProcessCcdWithVariableFakesTask"]
47 dimensions=(
"instrument",
"visit",
"detector"),
48 defaultTemplates={
"coaddName":
"deep",
49 "wcsName":
"jointcal",
50 "photoCalibName":
"jointcal",
51 "fakesType":
"fakes_"}):
53 doc=
"Input definition of geometry/bbox and projection/wcs for "
54 "template exposures. Needed to test which tract to generate ",
55 name=BaseSkyMap.SKYMAP_DATASET_TYPE_NAME,
56 dimensions=(
"skymap",),
57 storageClass=
"SkyMap",
61 doc=
"Exposure into which fakes are to be added.",
63 storageClass=
"ExposureF",
64 dimensions=(
"instrument",
"visit",
"detector")
68 doc=
"Set of catalogs of fake sources to draw inputs from. We "
69 "concatenate the tract catalogs for detectorVisits that cover "
71 name=
"{fakesType}fakeSourceCat",
72 storageClass=
"DataFrame",
73 dimensions=(
"tract",
"skymap"),
78 externalSkyWcsTractCatalog = cT.Input(
79 doc=(
"Per-tract, per-visit wcs calibrations. These catalogs use the detector "
80 "id for the catalog id, sorted on id for fast lookup."),
81 name=
"{wcsName}SkyWcsCatalog",
82 storageClass=
"ExposureCatalog",
83 dimensions=(
"instrument",
"visit",
"tract",
"skymap"),
88 externalSkyWcsGlobalCatalog = cT.Input(
89 doc=(
"Per-visit wcs calibrations computed globally (with no tract information). "
90 "These catalogs use the detector id for the catalog id, sorted on id for "
92 name=
"{wcsName}SkyWcsCatalog",
93 storageClass=
"ExposureCatalog",
94 dimensions=(
"instrument",
"visit"),
97 externalPhotoCalibTractCatalog = cT.Input(
98 doc=(
"Per-tract, per-visit photometric calibrations. These catalogs use the "
99 "detector id for the catalog id, sorted on id for fast lookup."),
100 name=
"{photoCalibName}PhotoCalibCatalog",
101 storageClass=
"ExposureCatalog",
102 dimensions=(
"instrument",
"visit",
"tract"),
107 externalPhotoCalibGlobalCatalog = cT.Input(
108 doc=(
"Per-visit photometric calibrations. These catalogs use the "
109 "detector id for the catalog id, sorted on id for fast lookup."),
110 name=
"{photoCalibName}PhotoCalibCatalog",
111 storageClass=
"ExposureCatalog",
112 dimensions=(
"instrument",
"visit"),
115 icSourceCat = cT.Input(
116 doc=
"Catalog of calibration sources",
118 storageClass=
"SourceCatalog",
119 dimensions=(
"instrument",
"visit",
"detector")
122 sfdSourceCat = cT.Input(
123 doc=
"Catalog of calibration sources",
125 storageClass=
"SourceCatalog",
126 dimensions=(
"instrument",
"visit",
"detector")
129 outputExposure = cT.Output(
130 doc=
"Exposure with fake sources added.",
131 name=
"{fakesType}calexp",
132 storageClass=
"ExposureF",
133 dimensions=(
"instrument",
"visit",
"detector")
136 outputCat = cT.Output(
137 doc=
"Source catalog produced in calibrate task with fakes also measured.",
138 name=
"{fakesType}src",
139 storageClass=
"SourceCatalog",
140 dimensions=(
"instrument",
"visit",
"detector"),
143 def __init__(self, *, config=None):
144 super().__init__(config=config)
146 if not config.doApplyExternalGlobalPhotoCalib:
147 self.inputs.remove(
"externalPhotoCalibGlobalCatalog")
148 if not config.doApplyExternalTractPhotoCalib:
149 self.inputs.remove(
"externalPhotoCalibTractCatalog")
151 if not config.doApplyExternalGlobalSkyWcs:
152 self.inputs.remove(
"externalSkyWcsGlobalCatalog")
153 if not config.doApplyExternalTractSkyWcs:
154 self.inputs.remove(
"externalSkyWcsTractCatalog")
157class ProcessCcdWithFakesConfig(PipelineTaskConfig,
158 pipelineConnections=ProcessCcdWithFakesConnections):
159 """Config for inserting fake sources
163 The default column names are those from the UW sims database.
166 doApplyExternalGlobalPhotoCalib = pexConfig.Field(
169 doc=
"Whether to apply an external photometric calibration via an "
170 "`lsst.afw.image.PhotoCalib` object. Uses the "
171 "`externalPhotoCalibName` config option to determine which "
172 "calibration to use. Uses a global calibration."
175 doApplyExternalTractPhotoCalib = pexConfig.Field(
178 doc=
"Whether to apply an external photometric calibration via an "
179 "`lsst.afw.image.PhotoCalib` object. Uses the "
180 "`externalPhotoCalibName` config option to determine which "
181 "calibration to use. Uses a per tract calibration."
184 externalPhotoCalibName = pexConfig.ChoiceField(
185 doc=
"What type of external photo calib to use.",
188 allowed={
"jointcal":
"Use jointcal_photoCalib",
189 "fgcm":
"Use fgcm_photoCalib",
190 "fgcm_tract":
"Use fgcm_tract_photoCalib"}
193 doApplyExternalGlobalSkyWcs = pexConfig.Field(
196 doc=
"Whether to apply an external astrometric calibration via an "
197 "`lsst.afw.geom.SkyWcs` object. Uses the "
198 "`externalSkyWcsName` config option to determine which "
199 "calibration to use. Uses a global calibration."
202 doApplyExternalTractSkyWcs = pexConfig.Field(
205 doc=
"Whether to apply an external astrometric calibration via an "
206 "`lsst.afw.geom.SkyWcs` object. Uses the "
207 "`externalSkyWcsName` config option to determine which "
208 "calibration to use. Uses a per tract calibration."
211 externalSkyWcsName = pexConfig.ChoiceField(
212 doc=
"What type of updated WCS calib to use.",
215 allowed={
"jointcal":
"Use jointcal_wcs"}
218 coaddName = pexConfig.Field(
219 doc=
"The name of the type of coadd used",
224 srcFieldsToCopy = pexConfig.ListField(
226 default=(
"calib_photometry_reserved",
"calib_photometry_used",
"calib_astrometry_used",
227 "calib_psf_candidate",
"calib_psf_used",
"calib_psf_reserved"),
228 doc=(
"Fields to copy from the `src` catalog to the output catalog "
229 "for matching sources Any missing fields will trigger a "
230 "RuntimeError exception.")
233 matchRadiusPix = pexConfig.Field(
236 doc=(
"Match radius for matching icSourceCat objects to sourceCat objects (pixels)"),
239 doMatchVisit = pexConfig.Field(
242 doc=
"Match visit to trim the fakeCat"
245 calibrate = pexConfig.ConfigurableField(target=CalibrateTask,
246 doc=
"The calibration task to use.")
248 insertFakes = pexConfig.ConfigurableField(target=InsertFakesTask,
249 doc=
"Configuration for the fake sources")
253 self.calibrate.measurement.plugins[
"base_PixelFlags"].masksFpAnywhere.append(
"FAKE")
254 self.calibrate.measurement.plugins[
"base_PixelFlags"].masksFpCenter.append(
"FAKE")
255 self.calibrate.doAstrometry =
False
256 self.calibrate.doWriteMatches =
False
257 self.calibrate.doPhotoCal =
False
258 self.calibrate.detection.reEstimateBackground =
False
261class ProcessCcdWithFakesTask(PipelineTask, CmdLineTask):
262 """Insert fake objects into calexps.
264 Add fake stars and galaxies to the given calexp, specified
in the dataRef. Galaxy parameters are read
in
265 from the specified file
and then modelled using galsim. Re-runs characterize image
and calibrate image to
266 give a new background estimation
and measurement of the calexp.
268 `ProcessFakeSourcesTask` inherits six functions
from insertFakesTask that make images of the fake
269 sources
and then add them to the calexp.
272 Use the WCS information to add the pixel coordinates of each source
273 Adds an ``x``
and ``y`` column to the catalog of fake sources.
275 Trim the fake cat to about the size of the input image.
276 `mkFakeGalsimGalaxies`
277 Use Galsim to make fake double sersic galaxies
for each set of galaxy parameters
in the input file.
279 Use the PSF information
from the calexp to make a fake star using the magnitude information
from the
282 Remove rows of the input fake catalog which have half light radius, of either the bulge
or the disk,
285 Add the fake sources to the calexp.
289 The ``calexp``
with fake souces added to it
is written out
as the datatype ``calexp_fakes``.
292 _DefaultName = "processCcdWithFakes"
293 ConfigClass = ProcessCcdWithFakesConfig
295 def __init__(self, schema=None, butler=None, **kwargs):
296 """Initalize things! This should go above in the class docstring
299 super().__init__(**kwargs)
302 schema = SourceTable.makeMinimalSchema()
304 self.makeSubtask(
"insertFakes")
305 self.makeSubtask(
"calibrate")
307 def runDataRef(self, dataRef):
308 """Read in/write out the required data products and add fake sources to the calexp.
313 Data reference defining the ccd to have fakes added to it.
314 Used to access the following data products:
321 Uses the calibration and WCS information attached to the calexp
for the posistioning
and calibration
322 of the sources unless the config option config.externalPhotoCalibName
or config.externalSkyWcsName
323 are set then it uses the specified outputs. The config defualts
for the column names
in the catalog
324 of fakes are taken
from the University of Washington simulations database.
325 Operates on one ccd at a time.
327 exposureIdInfo = dataRef.get("expIdInfo")
329 if self.config.insertFakes.fakeType ==
"snapshot":
330 fakeCat = dataRef.get(
"fakeSourceCat").toDataFrame()
331 elif self.config.insertFakes.fakeType ==
"static":
332 fakeCat = dataRef.get(
"deepCoadd_fakeSourceCat").toDataFrame()
334 fakeCat = Table.read(self.config.insertFakes.fakeType).to_pandas()
336 calexp = dataRef.get(
"calexp")
337 if self.config.doApplyExternalGlobalSkyWcs
or self.config.doApplyExternalTractSkyWcs:
338 self.log.
info(
"Using external wcs from %s", self.config.externalSkyWcsName)
339 wcs = dataRef.get(self.config.externalSkyWcsName +
"_wcs")
341 wcs = calexp.getWcs()
343 if self.config.doApplyExternalGlobalPhotoCalib
or self.config.doApplyExternalTractPhotoCalib:
344 self.log.
info(
"Using external photocalib from %s", self.config.externalPhotoCalibName)
345 photoCalib = dataRef.get(self.config.externalPhotoCalibName +
"_photoCalib")
347 photoCalib = calexp.getPhotoCalib()
349 icSourceCat = dataRef.get(
"icSrc", immediate=
True)
350 sfdSourceCat = dataRef.get(
"src", immediate=
True)
352 resultStruct = self.run(fakeCat, calexp, wcs=wcs, photoCalib=photoCalib,
353 exposureIdInfo=exposureIdInfo, icSourceCat=icSourceCat,
354 sfdSourceCat=sfdSourceCat)
356 dataRef.put(resultStruct.outputExposure,
"fakes_calexp")
357 dataRef.put(resultStruct.outputCat,
"fakes_src")
360 def runQuantum(self, butlerQC, inputRefs, outputRefs):
361 inputs = butlerQC.get(inputRefs)
362 detectorId = inputs[
"exposure"].
getInfo().getDetector().getId()
364 if 'exposureIdInfo' not in inputs.keys():
365 expId, expBits = butlerQC.quantum.dataId.pack(
"visit_detector", returnMaxBits=
True)
366 inputs[
'exposureIdInfo'] = ExposureIdInfo(expId, expBits)
368 expWcs = inputs[
"exposure"].getWcs()
369 tractId = inputs[
"skyMap"].findTract(
370 expWcs.pixelToSky(inputs[
"exposure"].getBBox().getCenter())).tract_id
371 if not self.config.doApplyExternalGlobalSkyWcs
and not self.config.doApplyExternalTractSkyWcs:
372 inputs[
"wcs"] = expWcs
373 elif self.config.doApplyExternalGlobalSkyWcs:
374 externalSkyWcsCatalog = inputs[
"externalSkyWcsGlobalCatalog"]
375 row = externalSkyWcsCatalog.find(detectorId)
376 inputs[
"wcs"] = row.getWcs()
377 elif self.config.doApplyExternalTractSkyWcs:
378 externalSkyWcsCatalogList = inputs[
"externalSkyWcsTractCatalog"]
379 externalSkyWcsCatalog =
None
380 for externalSkyWcsCatalogRef
in externalSkyWcsCatalogList:
381 if externalSkyWcsCatalogRef.dataId[
"tract"] == tractId:
382 externalSkyWcsCatalog = externalSkyWcsCatalogRef.get(
383 datasetType=self.config.connections.externalSkyWcsTractCatalog)
385 if externalSkyWcsCatalog
is None:
386 usedTract = externalSkyWcsCatalogList[-1].dataId[
"tract"]
388 f
"Warning, external SkyWcs for tract {tractId} not found. Using tract {usedTract} "
390 externalSkyWcsCatalog = externalSkyWcsCatalogList[-1].get(
391 datasetType=self.config.connections.externalSkyWcsTractCatalog)
392 row = externalSkyWcsCatalog.find(detectorId)
393 inputs[
"wcs"] = row.getWcs()
395 if not self.config.doApplyExternalGlobalPhotoCalib
and not self.config.doApplyExternalTractPhotoCalib:
396 inputs[
"photoCalib"] = inputs[
"exposure"].getPhotoCalib()
397 elif self.config.doApplyExternalGlobalPhotoCalib:
398 externalPhotoCalibCatalog = inputs[
"externalPhotoCalibGlobalCatalog"]
399 row = externalPhotoCalibCatalog.find(detectorId)
400 inputs[
"photoCalib"] = row.getPhotoCalib()
401 elif self.config.doApplyExternalTractPhotoCalib:
402 externalPhotoCalibCatalogList = inputs[
"externalPhotoCalibTractCatalog"]
403 externalPhotoCalibCatalog =
None
404 for externalPhotoCalibCatalogRef
in externalPhotoCalibCatalogList:
405 if externalPhotoCalibCatalogRef.dataId[
"tract"] == tractId:
406 externalPhotoCalibCatalog = externalPhotoCalibCatalogRef.get(
407 datasetType=self.config.connections.externalPhotoCalibTractCatalog)
409 if externalPhotoCalibCatalog
is None:
410 usedTract = externalPhotoCalibCatalogList[-1].dataId[
"tract"]
412 f
"Warning, external PhotoCalib for tract {tractId} not found. Using tract {usedTract} "
414 externalPhotoCalibCatalog = externalPhotoCalibCatalogList[-1].get(
415 datasetType=self.config.connections.externalPhotoCalibTractCatalog)
416 row = externalPhotoCalibCatalog.find(detectorId)
417 inputs[
"photoCalib"] = row.getPhotoCalib()
419 outputs = self.run(**inputs)
420 butlerQC.put(outputs, outputRefs)
423 def _makeArgumentParser(cls):
424 parser = pipeBase.ArgumentParser(name=cls._DefaultName)
425 parser.add_id_argument(
"--id",
"fakes_calexp", help=
"data ID with raw CCD keys [+ tract optionally], "
426 "e.g. --id visit=12345 ccd=1,2 [tract=0]",
427 ContainerClass=PerTractCcdDataIdContainer)
430 def run(self, fakeCats, exposure, skyMap, wcs=None, photoCalib=None, exposureIdInfo=None,
431 icSourceCat=None, sfdSourceCat=None, externalSkyWcsGlobalCatalog=None,
432 externalSkyWcsTractCatalog=None, externalPhotoCalibGlobalCatalog=None,
433 externalPhotoCalibTractCatalog=None):
434 """Add fake sources to a calexp and then run detection, deblending and measurement.
438 fakeCats : `list` of `lsst.daf.butler.DeferredDatasetHandle`
439 Set of tract level fake catalogs that potentially cover
441 exposure : `lsst.afw.image.exposure.exposure.ExposureF`
442 The exposure to add the fake sources to
443 skyMap : `lsst.skymap.SkyMap`
444 SkyMap defining the tracts and patches the fakes are stored over.
446 WCS to use to add fake sources
447 photoCalib : `lsst.afw.image.photoCalib.PhotoCalib`
448 Photometric calibration to be used to calibrate the fake sources
449 exposureIdInfo : `lsst.obs.base.ExposureIdInfo`
452 Catalog to take the information about which sources were used
for calibration
from.
455 Catalog produced by singleFrameDriver, needed to copy some calibration flags
from.
459 resultStruct : `lsst.pipe.base.struct.Struct`
460 contains : outputExposure : `lsst.afw.image.exposure.exposure.ExposureF`
461 outputCat : `lsst.afw.table.source.source.SourceCatalog`
465 Adds pixel coordinates
for each source to the fakeCat
and removes objects
with bulge
or disk half
466 light radius = 0 (
if ``config.cleanCat =
True``). These columns are called ``x``
and ``y``
and are
in
469 Adds the ``Fake`` mask plane to the exposure which
is then set by `addFakeSources` to mark where fake
470 sources have been added. Uses the information
in the ``fakeCat`` to make fake galaxies (using galsim)
471 and fake stars, using the PSF models
from the PSF information
for the calexp. These are then added to
472 the calexp
and the calexp
with fakes included returned.
474 The galsim galaxies are made using a double sersic profile, one
for the bulge
and one
for the disk,
475 this
is then convolved
with the PSF at that point.
477 If exposureIdInfo
is not provided then the SourceCatalog IDs will
not be globally unique.
479 fakeCat = self.composeFakeCat(fakeCats, skyMap)
482 wcs = exposure.getWcs()
484 if photoCalib
is None:
485 photoCalib = exposure.getPhotoCalib()
487 if self.config.doMatchVisit:
488 fakeCat = self.getVisitMatchedFakeCat(fakeCat, exposure)
490 self.insertFakes.
run(fakeCat, exposure, wcs, photoCalib)
493 if exposureIdInfo
is None:
494 exposureIdInfo = ExposureIdInfo()
495 returnedStruct = self.calibrate.
run(exposure, exposureIdInfo=exposureIdInfo)
496 sourceCat = returnedStruct.sourceCat
498 sourceCat = self.copyCalibrationFields(sfdSourceCat, sourceCat, self.config.srcFieldsToCopy)
500 resultStruct = pipeBase.Struct(outputExposure=exposure, outputCat=sourceCat)
503 def composeFakeCat(self, fakeCats, skyMap):
504 """Concatenate the fakeCats from tracts that may cover the exposure.
508 fakeCats : `list` of `lst.daf.butler.DeferredDatasetHandle`
509 Set of fake cats to concatenate.
510 skyMap : `lsst.skymap.SkyMap`
511 SkyMap defining the geometry of the tracts and patches.
515 combinedFakeCat : `pandas.DataFrame`
516 All fakes that cover the inner polygon of the tracts
in this
519 if len(fakeCats) == 1:
520 return fakeCats[0].get(
521 datasetType=self.config.connections.fakeCats)
523 for fakeCatRef
in fakeCats:
524 cat = fakeCatRef.get(
525 datasetType=self.config.connections.fakeCats)
526 tractId = fakeCatRef.dataId[
"tract"]
528 outputCat.append(cat[
529 skyMap.findTractIdArray(cat[self.config.insertFakes.ra_col],
530 cat[self.config.insertFakes.dec_col],
534 return pd.concat(outputCat)
536 def getVisitMatchedFakeCat(self, fakeCat, exposure):
537 """Trim the fakeCat to select particular visit
541 fakeCat : `pandas.core.frame.DataFrame`
542 The catalog of fake sources to add to the exposure
543 exposure : `lsst.afw.image.exposure.exposure.ExposureF`
544 The exposure to add the fake sources to
548 movingFakeCat : `pandas.DataFrame`
549 All fakes that belong to the visit
551 selected = exposure.getInfo().getVisitInfo().getId() == fakeCat["visit"]
553 return fakeCat[selected]
555 def copyCalibrationFields(self, calibCat, sourceCat, fieldsToCopy):
556 """Match sources in calibCat and sourceCat and copy the specified fields
561 Catalog from which to copy fields.
563 Catalog to which to copy fields.
565 Fields to copy
from calibCat to SoourceCat.
570 Catalog which includes the copied fields.
572 The fields copied are those specified by `fieldsToCopy` that actually exist
573 in the schema of `calibCat`.
575 This version was based on
and adapted
from the one
in calibrateTask.
580 sourceSchemaMapper.addMinimalSchema(sourceCat.schema,
True)
585 missingFieldNames = []
586 for fieldName
in fieldsToCopy:
587 if fieldName
in calibCat.schema:
588 schemaItem = calibCat.schema.find(fieldName)
589 calibSchemaMapper.editOutputSchema().addField(schemaItem.getField())
590 schema = calibSchemaMapper.editOutputSchema()
591 calibSchemaMapper.addMapping(schemaItem.getKey(), schema.find(fieldName).getField())
593 missingFieldNames.append(fieldName)
594 if missingFieldNames:
595 raise RuntimeError(f
"calibCat is missing fields {missingFieldNames} specified in "
598 if "calib_detected" not in calibSchemaMapper.getOutputSchema():
599 self.calibSourceKey = calibSchemaMapper.addOutputField(
afwTable.Field[
"Flag"](
"calib_detected",
600 "Source was detected as an icSource"))
602 self.calibSourceKey =
None
604 schema = calibSchemaMapper.getOutputSchema()
606 newCat.reserve(len(sourceCat))
607 newCat.extend(sourceCat, sourceSchemaMapper)
610 for k, v
in sourceCat.schema.getAliasMap().
items():
611 newCat.schema.getAliasMap().
set(k, v)
613 select = newCat[
"deblend_nChild"] == 0
614 matches =
afwTable.matchXy(newCat[select], calibCat, self.config.matchRadiusPix)
618 numMatches = len(matches)
619 numUniqueSources = len(
set(m[1].getId()
for m
in matches))
620 if numUniqueSources != numMatches:
621 self.log.
warning(
"%d calibCat sources matched only %d sourceCat sources", numMatches,
624 self.log.
info(
"Copying flags from calibCat to sourceCat for %s sources", numMatches)
628 for src, calibSrc, d
in matches:
629 if self.calibSourceKey:
630 src.setFlag(self.calibSourceKey,
True)
635 calibSrcFootprint = calibSrc.getFootprint()
637 calibSrc.setFootprint(src.getFootprint())
638 src.assign(calibSrc, calibSchemaMapper)
640 calibSrc.setFootprint(calibSrcFootprint)
646 ccdVisitFakeMagnitudes = cT.Output(
647 doc=
"Catalog of fakes with magnitudes scattered for this ccdVisit.",
648 name=
"{fakesType}ccdVisitFakeMagnitudes",
649 storageClass=
"DataFrame",
650 dimensions=(
"instrument",
"visit",
"detector"),
654class ProcessCcdWithVariableFakesConfig(ProcessCcdWithFakesConfig,
655 pipelineConnections=ProcessCcdWithVariableFakesConnections):
656 scatterSize = pexConfig.RangeField(
661 doc=
"Amount of scatter to add to the visit magnitude for variable "
666class ProcessCcdWithVariableFakesTask(ProcessCcdWithFakesTask):
667 """As ProcessCcdWithFakes except add variablity to the fakes catalog
668 magnitude in the observed band
for this ccdVisit.
670 Additionally, write out the modified magnitudes to the Butler.
673 _DefaultName = "processCcdWithVariableFakes"
674 ConfigClass = ProcessCcdWithVariableFakesConfig
676 def run(self, fakeCats, exposure, skyMap, wcs=None, photoCalib=None, exposureIdInfo=None,
677 icSourceCat=None, sfdSourceCat=None):
678 """Add fake sources to a calexp and then run detection, deblending and measurement.
682 fakeCat : `pandas.core.frame.DataFrame`
683 The catalog of fake sources to add to the exposure
684 exposure : `lsst.afw.image.exposure.exposure.ExposureF`
685 The exposure to add the fake sources to
686 skyMap : `lsst.skymap.SkyMap`
687 SkyMap defining the tracts and patches the fakes are stored over.
689 WCS to use to add fake sources
690 photoCalib : `lsst.afw.image.photoCalib.PhotoCalib`
691 Photometric calibration to be used to calibrate the fake sources
692 exposureIdInfo : `lsst.obs.base.ExposureIdInfo`
695 Catalog to take the information about which sources were used
for calibration
from.
698 Catalog produced by singleFrameDriver, needed to copy some calibration flags
from.
702 resultStruct : `lsst.pipe.base.struct.Struct`
703 Results Strcut containing:
705 - outputExposure : Exposure
with added fakes
706 (`lsst.afw.image.exposure.exposure.ExposureF`)
707 - outputCat : Catalog
with detected fakes
708 (`lsst.afw.table.source.source.SourceCatalog`)
709 - ccdVisitFakeMagnitudes : Magnitudes that these fakes were
710 inserted
with after being scattered (`pandas.DataFrame`)
714 Adds pixel coordinates
for each source to the fakeCat
and removes objects
with bulge
or disk half
715 light radius = 0 (
if ``config.cleanCat =
True``). These columns are called ``x``
and ``y``
and are
in
718 Adds the ``Fake`` mask plane to the exposure which
is then set by `addFakeSources` to mark where fake
719 sources have been added. Uses the information
in the ``fakeCat`` to make fake galaxies (using galsim)
720 and fake stars, using the PSF models
from the PSF information
for the calexp. These are then added to
721 the calexp
and the calexp
with fakes included returned.
723 The galsim galaxies are made using a double sersic profile, one
for the bulge
and one
for the disk,
724 this
is then convolved
with the PSF at that point.
726 If exposureIdInfo
is not provided then the SourceCatalog IDs will
not be globally unique.
728 fakeCat = self.composeFakeCat(fakeCats, skyMap)
731 wcs = exposure.getWcs()
733 if photoCalib
is None:
734 photoCalib = exposure.getPhotoCalib()
736 if exposureIdInfo
is None:
737 exposureIdInfo = ExposureIdInfo()
739 band = exposure.getFilter().bandLabel
740 ccdVisitMagnitudes = self.addVariablity(fakeCat, band, exposure, photoCalib, exposureIdInfo)
742 self.insertFakes.
run(fakeCat, exposure, wcs, photoCalib)
745 returnedStruct = self.calibrate.
run(exposure, exposureIdInfo=exposureIdInfo)
746 sourceCat = returnedStruct.sourceCat
748 sourceCat = self.copyCalibrationFields(sfdSourceCat, sourceCat, self.config.srcFieldsToCopy)
750 resultStruct = pipeBase.Struct(outputExposure=exposure,
752 ccdVisitFakeMagnitudes=ccdVisitMagnitudes)
755 def addVariablity(self, fakeCat, band, exposure, photoCalib, exposureIdInfo):
756 """Add scatter to the fake catalog visit magnitudes.
758 Currently just adds a simple Gaussian scatter around the static fake
759 magnitude. This function could be modified to return any number of
764 fakeCat : `pandas.DataFrame`
765 Catalog of fakes to modify magnitudes of.
767 Current observing band to modify.
768 exposure : `lsst.afw.image.ExposureF`
769 Exposure fakes will be added to.
771 Photometric calibration object of ``exposure``.
772 exposureIdInfo : `lsst.obs.base.ExposureIdInfo`
773 Exposure id information
and metadata.
777 dataFrame : `pandas.DataFrame`
778 DataFrame containing the values of the magnitudes to that will
779 be inserted into this ccdVisit.
781 expId = exposureIdInfo.expId
782 rng = np.random.default_rng(expId)
783 magScatter = rng.normal(loc=0,
784 scale=self.config.scatterSize,
786 visitMagnitudes = fakeCat[self.insertFakes.config.mag_col % band] + magScatter
787 fakeCat.loc[:, self.insertFakes.config.mag_col % band] = visitMagnitudes
788 return pd.DataFrame(data={
"variableMag": visitMagnitudes})
std::vector< SchemaItem< Flag > > * items
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
The photometric calibration of an exposure.
A mapping between the keys of two Schemas, used to copy data between them.
daf::base::PropertySet * set
SourceMatchVector matchXy(SourceCatalog const &cat1, SourceCatalog const &cat2, double radius, MatchControl const &mc=MatchControl())
Compute all tuples (s1,s2,d) where s1 belings to cat1, s2 belongs to cat2 and d, the distance between...
def run(self, coaddExposures, bbox, wcs, dataIds, **kwargs)
A description of a field in a table.