23"""Class for running fgcmcal on a single tract using sourceTable_visit tables.
27import lsst.pipe.base
as pipeBase
28from lsst.pipe.base
import connectionTypes
29from lsst.meas.algorithms
import ReferenceObjectLoader
30import lsst.afw.table
as afwTable
32from .dataIds
import TractCheckDataIdContainer
33from .fgcmBuildStarsTable
import FgcmBuildStarsTableTask
34from .fgcmCalibrateTractBase
import (FgcmCalibrateTractConfigBase, FgcmCalibrateTractRunner,
35 FgcmCalibrateTractBaseTask)
36from .utilities
import lookupStaticCalibrations
38__all__ = [
'FgcmCalibrateTractTableConfig',
'FgcmCalibrateTractTableTask']
42 dimensions=(
"instrument",
44 camera = connectionTypes.PrerequisiteInput(
45 doc=
"Camera instrument",
47 storageClass=
"Camera",
48 dimensions=(
"instrument",),
49 lookupFunction=lookupStaticCalibrations,
53 fgcmLookUpTable = connectionTypes.PrerequisiteInput(
54 doc=(
"Atmosphere + instrument look-up-table for FGCM throughput and "
55 "chromatic corrections."),
56 name=
"fgcmLookUpTable",
57 storageClass=
"Catalog",
58 dimensions=(
"instrument",),
62 sourceSchema = connectionTypes.InitInput(
63 doc=
"Schema for source catalogs",
65 storageClass=
"SourceCatalog",
68 refCat = connectionTypes.PrerequisiteInput(
69 doc=
"Reference catalog to use for photometric calibration",
71 storageClass=
"SimpleCatalog",
72 dimensions=(
"skypix",),
77 source_catalogs = connectionTypes.Input(
78 doc=
"Source table in parquet format, per visit",
79 name=
"sourceTable_visit",
80 storageClass=
"DataFrame",
81 dimensions=(
"instrument",
"visit"),
86 visitSummary = connectionTypes.Input(
87 doc=
"Per-visit summary statistics table",
89 storageClass=
"ExposureCatalog",
90 dimensions=(
"instrument",
"visit"),
95 background = connectionTypes.Input(
96 doc=
"Calexp background model",
97 name=
"calexpBackground",
98 storageClass=
"Background",
99 dimensions=(
"instrument",
"visit",
"detector"),
104 fgcmPhotoCalib = connectionTypes.Output(
105 doc=
"Per-tract, per-visit photoCalib exposure catalogs produced from fgcm calibration",
106 name=
"fgcmPhotoCalibTractCatalog",
107 storageClass=
"ExposureCatalog",
108 dimensions=(
"instrument",
"tract",
"visit",),
112 fgcmTransmissionAtmosphere = connectionTypes.Output(
113 doc=
"Per-visit atmosphere transmission files produced from fgcm calibration",
114 name=
"transmission_atmosphere_fgcm_tract",
115 storageClass=
"TransmissionCurve",
116 dimensions=(
"instrument",
"tract",
"visit",),
120 fgcmRepeatability = connectionTypes.Output(
121 doc=
"Per-band raw repeatability numbers in the fgcm tract calibration",
122 name=
"fgcmRawRepeatability",
123 storageClass=
"Catalog",
124 dimensions=(
"instrument",
"tract",),
132 loaderName = config.fgcmBuildStars.fgcmLoadReferenceCatalog.refObjLoader.ref_dataset_name
133 if config.connections.refCat != loaderName:
134 raise ValueError(
"connections.refCat must be the same as "
135 "config.fgcmBuildStars.fgcmLoadReferenceCatalog.refObjLoader.ref_dataset_name")
136 if config.fgcmOutputProducts.doReferenceCalibration:
137 loaderName = config.fgcmOutputProducts.refObjLoader.ref_dataset_name
138 if config.connections.refCat != loaderName:
139 raise ValueError(
"connections.refCat must be the same as "
140 "config.fgcmOutputProducts.refObjLoader.ref_dataset_name")
142 if not config.fgcmBuildStars.doModelErrorsWithBackground:
143 self.inputs.remove(
"background")
145 if config.fgcmOutputProducts.doRefcatOutput:
146 raise ValueError(
"FgcmCalibrateTractTableTask (Gen3) does not support doRefcatOutput")
147 if not config.fgcmOutputProducts.doAtmosphereOutput:
148 self.prerequisiteInputs.remove(
"fgcmAtmosphereParameters")
149 if not config.fgcmOutputProducts.doZeropointOutput:
150 self.prerequisiteInputs.remove(
"fgcmZeropoints")
154 pipelineConnections=FgcmCalibrateTractTableConnections):
155 """Config for FgcmCalibrateTractTable task"""
161 self.
fgcmBuildStarsfgcmBuildStars.retarget(FgcmBuildStarsTableTask)
168 Calibrate a single tract using fgcmcal, using sourceTable_visit (parquet)
171 ConfigClass = FgcmCalibrateTractTableConfig
172 RunnerClass = FgcmCalibrateTractRunner
173 _DefaultName = "fgcmCalibrateTractTable"
175 canMultiprocess =
False
178 super().
__init__(initInputs=initInputs, **kwargs)
179 if initInputs
is not None:
183 dataRefDict = butlerQC.get(inputRefs)
185 self.log.info(
"Running with %d sourceTable_visit dataRefs", (len(dataRefDict[
'source_catalogs'])))
188 tract = butlerQC.quantum.dataId[
'tract']
190 dataRefDict[
'sourceSchema'] = self.
sourceSchemasourceSchema
192 sourceTableRefs = dataRefDict[
'source_catalogs']
193 sourceTableDataRefDict = {sourceTableRef.dataId[
'visit']: sourceTableRef
for
194 sourceTableRef
in sourceTableRefs}
196 visitSummaryRefs = dataRefDict[
'visitSummary']
197 visitSummaryDataRefDict = {visitSummaryRef.dataId[
'visit']: visitSummaryRef
for
198 visitSummaryRef
in visitSummaryRefs}
200 dataRefDict[
'sourceTableDataRefDict'] = sourceTableDataRefDict
201 dataRefDict[
'visitSummaryDataRefDict'] = visitSummaryDataRefDict
204 if self.config.fgcmOutputProducts.doZeropointOutput:
205 photoCalibRefDict = {photoCalibRef.dataId.byName()[
'visit']:
206 photoCalibRef
for photoCalibRef
in outputRefs.fgcmPhotoCalib}
207 dataRefDict[
'fgcmPhotoCalibs'] = photoCalibRefDict
209 if self.config.fgcmOutputProducts.doAtmosphereOutput:
210 atmRefDict = {atmRef.dataId.byName()[
'visit']: atmRef
for
211 atmRef
in outputRefs.fgcmTransmissionAtmosphere}
212 dataRefDict[
'fgcmTransmissionAtmospheres'] = atmRefDict
214 if self.config.fgcmBuildStars.doReferenceMatches:
215 refConfig = self.config.fgcmBuildStars.fgcmLoadReferenceCatalog.refObjLoader
216 loader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
217 for ref
in inputRefs.refCat],
218 refCats=butlerQC.get(inputRefs.refCat),
221 buildStarsRefObjLoader = loader
223 buildStarsRefObjLoader =
None
225 if self.config.fgcmOutputProducts.doReferenceCalibration:
226 refConfig = self.config.fgcmOutputProducts.refObjLoader
227 loader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
228 for ref
in inputRefs.refCat],
229 refCats=butlerQC.get(inputRefs.refCat),
232 self.fgcmOutputProducts.refObjLoader = loader
234 struct = self.
runrun(dataRefDict, tract,
235 buildStarsRefObjLoader=buildStarsRefObjLoader)
237 if struct.photoCalibCatalogs
is not None:
238 self.log.info(
"Outputting photoCalib catalogs.")
239 for visit, expCatalog
in struct.photoCalibCatalogs:
240 butlerQC.put(expCatalog, photoCalibRefDict[visit])
241 self.log.info(
"Done outputting photoCalib catalogs.")
243 if struct.atmospheres
is not None:
244 self.log.info(
"Outputting atmosphere transmission files.")
245 for visit, atm
in struct.atmospheres:
246 butlerQC.put(atm, atmRefDict[visit])
247 self.log.info(
"Done outputting atmosphere files.")
250 schema = afwTable.Schema()
251 schema.addField(
'rawRepeatability', type=np.float64,
252 doc=
"Per-band raw repeatability in FGCM calibration.")
253 repeatabilityCat = afwTable.BaseCatalog(schema)
254 repeatabilityCat.resize(len(struct.repeatability))
255 repeatabilityCat[
'rawRepeatability'][:] = struct.repeatability
257 butlerQC.put(repeatabilityCat, outputRefs.fgcmRepeatability)
262 def _makeArgumentParser(cls):
263 parser = pipeBase.ArgumentParser(name=cls.
_DefaultName_DefaultName)
264 parser.add_id_argument(
"--id",
"sourceTable_visit",
265 help=
"Data ID, e.g. --id visit=6789 tract=9617",
266 ContainerClass=TractCheckDataIdContainer)
def run(self, dataRefDict, tract, buildStarsRefObjLoader=None, returnCatalogs=True, butler=None)
def __init__(self, *config=None)
def __init__(self, initInputs=None, **kwargs)
def runQuantum(self, butlerQC, inputRefs, outputRefs)