lsst.fgcmcal g9c3108eb99+601a40e866
fgcmCalibrateTractBase.py
Go to the documentation of this file.
1# This file is part of fgcmcal.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21"""Base class for running fgcmcal on a single tract using src tables
22or sourceTable_visit tables.
23"""
24
25import sys
26import traceback
27import abc
28
29import numpy as np
30
31import lsst.daf.persistence as dafPersist
32import lsst.pex.config as pexConfig
33import lsst.pipe.base as pipeBase
34
35from .fgcmBuildStars import FgcmBuildStarsTask, FgcmBuildStarsConfig
36from .fgcmFitCycle import FgcmFitCycleConfig
37from .fgcmOutputProducts import FgcmOutputProductsTask
38from .utilities import makeConfigDict, translateFgcmLut, translateVisitCatalog
39from .utilities import computeCcdOffsets, computeApertureRadiusFromDataRef, extractReferenceMags
40from .utilities import makeZptSchema, makeZptCat
41from .utilities import makeAtmSchema, makeAtmCat
42from .utilities import makeStdSchema, makeStdCat
43
44import fgcm
45
46__all__ = ['FgcmCalibrateTractConfigBase', 'FgcmCalibrateTractBaseTask', 'FgcmCalibrateTractRunner']
47
48
49class FgcmCalibrateTractConfigBase(pexConfig.Config):
50 """Config for FgcmCalibrateTract"""
51
52 fgcmBuildStars = pexConfig.ConfigurableField(
53 target=FgcmBuildStarsTask,
54 doc="Task to load and match stars for fgcm",
55 )
56 fgcmFitCycle = pexConfig.ConfigField(
57 dtype=FgcmFitCycleConfig,
58 doc="Config to run a single fgcm fit cycle",
59 )
60 fgcmOutputProducts = pexConfig.ConfigurableField(
61 target=FgcmOutputProductsTask,
62 doc="Task to output fgcm products",
63 )
64 convergenceTolerance = pexConfig.Field(
65 doc="Tolerance on repeatability convergence (per band)",
66 dtype=float,
67 default=0.005,
68 )
69 maxFitCycles = pexConfig.Field(
70 doc="Maximum number of fit cycles",
71 dtype=int,
72 default=5,
73 )
74 doDebuggingPlots = pexConfig.Field(
75 doc="Make plots for debugging purposes?",
76 dtype=bool,
77 default=False,
78 )
79
80 def setDefaults(self):
81 pexConfig.Config.setDefaults(self)
82
83 self.fgcmFitCyclefgcmFitCycle.quietMode = True
84 self.fgcmFitCyclefgcmFitCycle.doPlots = False
85 self.fgcmOutputProductsfgcmOutputProducts.doReferenceCalibration = False
86 self.fgcmOutputProductsfgcmOutputProducts.doRefcatOutput = False
87 self.fgcmOutputProductsfgcmOutputProducts.cycleNumber = 0
88 self.fgcmOutputProductsfgcmOutputProducts.photoCal.applyColorTerms = False
89
90 def validate(self):
91 super().validate()
92
93 for band in self.fgcmFitCyclefgcmFitCycle.bands:
94 if not self.fgcmFitCyclefgcmFitCycle.useRepeatabilityForExpGrayCutsDict[band]:
95 msg = 'Must set useRepeatabilityForExpGrayCutsDict[band]=True for all bands'
96 raise pexConfig.FieldValidationError(FgcmFitCycleConfig.useRepeatabilityForExpGrayCutsDict,
97 self, msg)
98
99
100class FgcmCalibrateTractRunner(pipeBase.ButlerInitializedTaskRunner):
101 """Subclass of TaskRunner for FgcmCalibrateTractTask
102
103 fgcmCalibrateTractTask.run() takes a number of arguments, one of which is
104 the butler (for persistence and mapper data), and a list of dataRefs
105 extracted from the command line. This task runs on a constrained set
106 of dataRefs, typically a single tract.
107 This class transforms the process arguments generated by the ArgumentParser
108 into the arguments expected by FgcmCalibrateTractTask.run().
109 This runner does not use any parallelization.
110 """
111
112 @staticmethod
113 def getTargetList(parsedCmd):
114 """
115 Return a list with one element: a tuple with the butler and
116 list of dataRefs.
117 """
118 return [(parsedCmd.butler, parsedCmd.id.refList)]
119
120 def __call__(self, args):
121 """
122 Parameters
123 ----------
124 args: `tuple` with (butler, dataRefList)
125
126 Returns
127 -------
128 exitStatus: `list` with `lsst.pipe.base.Struct`
129 exitStatus (0: success; 1: failure)
130 May also contain results if `self.doReturnResults` is `True`.
131 """
132 butler, dataRefList = args
133
134 task = self.TaskClass(config=self.config, log=self.log)
135
136 exitStatus = 0
137 if self.doRaise:
138 results = task.runDataRef(butler, dataRefList)
139 else:
140 try:
141 results = task.runDataRef(butler, dataRefList)
142 except Exception as e:
143 exitStatus = 1
144 task.log.fatal("Failed: %s" % e)
145 if not isinstance(e, pipeBase.TaskError):
146 traceback.print_exc(file=sys.stderr)
147
148 task.writeMetadata(butler)
149
150 if self.doReturnResults:
151 return [pipeBase.Struct(exitStatus=exitStatus,
152 results=results)]
153 else:
154 return [pipeBase.Struct(exitStatus=exitStatus)]
155
156 def run(self, parsedCmd):
157 """
158 Run the task, with no multiprocessing
159
160 Parameters
161 ----------
162 parsedCmd: `lsst.pipe.base.ArgumentParser` parsed command line
163 """
164
165 resultList = []
166
167 if self.precall(parsedCmd):
168 targetList = self.getTargetListgetTargetList(parsedCmd)
169 resultList = self(targetList[0])
170
171 return resultList
172
173
174class FgcmCalibrateTractBaseTask(pipeBase.PipelineTask, pipeBase.CmdLineTask, abc.ABC):
175 """Base class to calibrate a single tract using fgcmcal
176 """
177 def __init__(self, initInputs=None, butler=None, **kwargs):
178 """
179 Instantiate an `FgcmCalibrateTractTask`.
180
181 Parameters
182 ----------
183 butler : `lsst.daf.persistence.Butler`, optional
184 """
185 super().__init__(**kwargs)
186 self.makeSubtask("fgcmBuildStars", initInputs=initInputs, butler=butler)
187 self.makeSubtask("fgcmOutputProducts", butler=butler)
188
189 # no saving of metadata for now
190 def _getMetadataName(self):
191 return None
192
193 @pipeBase.timeMethod
194 def runDataRef(self, butler, dataRefs):
195 """
196 Run full FGCM calibration on a single tract, including building star list,
197 fitting multiple cycles, and making outputs.
198
199 Parameters
200 ----------
201 butler: `lsst.daf.persistence.Butler`
202 dataRefs: `list` of `lsst.daf.persistence.ButlerDataRef`
203 Data references for the input visits.
204 These may be either per-ccd "src" or per-visit"sourceTable_visit"
205 references.
206
207 Raises
208 ------
209 RuntimeError: Raised if `config.fgcmBuildStars.doReferenceMatches` is
210 not True, or if fgcmLookUpTable is not available, or if
211 doSubtractLocalBackground is True and aperture radius cannot be
212 determined.
213 """
214 datasetType = dataRefs[0].butlerSubset.datasetType
215 self.log.info("Running with %d %s dataRefs" % (len(dataRefs), datasetType))
216
217 if not butler.datasetExists('fgcmLookUpTable'):
218 raise RuntimeError("Must run FgcmCalibrateTract with an fgcmLookUpTable")
219
220 if not self.config.fgcmBuildStars.doReferenceMatches:
221 raise RuntimeError("Must run FgcmCalibrateTract with fgcmBuildStars.doReferenceMatches")
222 if isinstance(self.config.fgcmBuildStars, FgcmBuildStarsConfig):
223 if self.config.fgcmBuildStars.checkAllCcds:
224 raise RuntimeError("Cannot run FgcmCalibrateTract with "
225 "fgcmBuildStars.checkAllCcds set to True")
226
227 tract = int(dataRefs[0].dataId['tract'])
228 camera = butler.get('camera')
229
230 dataRefDict = {}
231 dataRefDict['camera'] = camera
232 dataRefDict['source_catalogs'] = dataRefs
233 dataRefDict['sourceSchema'] = butler.get('src_schema', immediate=True).schema
234 dataRefDict['fgcmLookUpTable'] = butler.dataRef('fgcmLookUpTable')
235
236 struct = self.runrun(dataRefDict, tract, butler=butler, returnCatalogs=False)
237
238 visitDataRefName = self.config.fgcmBuildStars.visitDataRefName
239 ccdDataRefName = self.config.fgcmBuildStars.ccdDataRefName
240
241 if struct.photoCalibs is not None:
242 self.log.info("Outputting photoCalib files.")
243
244 for visit, detector, physicalFilter, photoCalib in struct.photoCalibs:
245 butler.put(photoCalib, 'fgcm_tract_photoCalib',
246 dataId={visitDataRefName: visit,
247 ccdDataRefName: detector,
248 'filter': physicalFilter,
249 'tract': tract})
250
251 self.log.info("Done outputting photoCalib files.")
252
253 if struct.atmospheres is not None:
254 self.log.info("Outputting atmosphere files.")
255 for visit, atm in struct.atmospheres:
256 butler.put(atm, "transmission_atmosphere_fgcm_tract",
257 dataId={visitDataRefName: visit,
258 'tract': tract})
259 self.log.info("Done outputting atmosphere transmissions.")
260
261 return pipeBase.Struct(repeatability=struct.repeatability)
262
263 def run(self, dataRefDict, tract,
264 buildStarsRefObjLoader=None, returnCatalogs=True, butler=None):
265 """Run the calibrations for a single tract with fgcm.
266
267 Parameters
268 ----------
269 dataRefDict : `dict`
270 All dataRefs are `lsst.daf.persistence.ButlerDataRef` (gen2) or
271 `lsst.daf.butler.DeferredDatasetHandle` (gen3)
272 dataRef dictionary with the following keys. Note that all
273 keys need not be set based on config parameters.
274
275 ``"camera"``
276 Camera object (`lsst.afw.cameraGeom.Camera`)
277 ``"source_catalogs"``
278 `list` of dataRefs for input source catalogs.
279 ``"sourceSchema"``
280 Schema for the source catalogs.
281 ``"fgcmLookUpTable"``
282 dataRef for the FGCM look-up table.
283 ``"calexps"``
284 `list` of dataRefs for the input calexps (Gen3 only)
285 ``"fgcmPhotoCalibs"``
286 `dict` of output photoCalib dataRefs. Key is
287 (tract, visit, detector). (Gen3 only)
288 Present if doZeropointOutput is True.
289 ``"fgcmTransmissionAtmospheres"``
290 `dict` of output atmosphere transmission dataRefs.
291 Key is (tract, visit). (Gen3 only)
292 Present if doAtmosphereOutput is True.
293 tract : `int`
294 Tract number
295 buildStarsRefObjLoader : `lsst.meas.algorithms.ReferenceObjectLoader`, optional
296 Reference object loader object for fgcmBuildStars.
297 returnCatalogs : `bool`, optional
298 Return photoCalibs as per-visit exposure catalogs.
299 butler : `lsst.daf.persistence.Butler`, optional
300 Gen2 butler used for reference star outputs
301
302 Returns
303 -------
304 outstruct : `lsst.pipe.base.Struct`
305 Output structure with keys:
306
307 offsets : `np.ndarray`
308 Final reference offsets, per band.
309 repeatability : `np.ndarray`
310 Raw fgcm repeatability for bright stars, per band.
311 atmospheres : `generator` [(`int`, `lsst.afw.image.TransmissionCurve`)]
312 Generator that returns (visit, transmissionCurve) tuples.
313 photoCalibs : `generator` [(`int`, `int`, `str`, `lsst.afw.image.PhotoCalib`)]
314 Generator that returns (visit, ccd, filtername, photoCalib) tuples.
315 (returned if returnCatalogs is False).
316 photoCalibCatalogs : `generator` [(`int`, `lsst.afw.table.ExposureCatalog`)]
317 Generator that returns (visit, exposureCatalog) tuples.
318 (returned if returnCatalogs is True).
319 """
320 self.log.info("Running on tract %d", (tract))
321
322 # Compute the aperture radius if necessary. This is useful to do now before
323 # any heavy lifting has happened (fail early).
324 calibFluxApertureRadius = None
325 if self.config.fgcmBuildStars.doSubtractLocalBackground:
326 try:
327 field = self.config.fgcmBuildStars.instFluxField
328 calibFluxApertureRadius = computeApertureRadiusFromDataRef(dataRefDict['source_catalogs'][0],
329 field)
330 except RuntimeError:
331 raise RuntimeError("Could not determine aperture radius from %s. "
332 "Cannot use doSubtractLocalBackground." %
333 (field))
334
335 # Run the build stars tasks
336
337 # Note that we will need visitCat at the end of the procedure for the outputs
338 if isinstance(butler, dafPersist.Butler):
339 # Gen2
340 groupedDataRefs = self.fgcmBuildStars._findAndGroupDataRefsGen2(butler, dataRefDict['camera'],
341 dataRefDict['source_catalogs'])
342 else:
343 # Gen3
344 groupedDataRefs = self.fgcmBuildStars._groupDataRefs(dataRefDict['sourceTableDataRefDict'],
345 dataRefDict['visitSummaryDataRefDict'])
346 visitCat = self.fgcmBuildStars.fgcmMakeVisitCatalog(dataRefDict['camera'], groupedDataRefs)
347 rad = calibFluxApertureRadius
348 fgcmStarObservationCat = self.fgcmBuildStars.fgcmMakeAllStarObservations(groupedDataRefs,
349 visitCat,
350 dataRefDict['sourceSchema'],
351 dataRefDict['camera'],
352 calibFluxApertureRadius=rad)
353
354 if self.fgcmBuildStars.config.doReferenceMatches:
355 lutDataRef = dataRefDict['fgcmLookUpTable']
356 if buildStarsRefObjLoader is not None:
357 self.fgcmBuildStars.makeSubtask("fgcmLoadReferenceCatalog",
358 refObjLoader=buildStarsRefObjLoader)
359 else:
360 self.fgcmBuildStars.makeSubtask("fgcmLoadReferenceCatalog", butler=butler)
361 else:
362 lutDataRef = None
363
364 fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat = \
365 self.fgcmBuildStars.fgcmMatchStars(visitCat,
366 fgcmStarObservationCat,
367 lutDataRef=lutDataRef)
368
369 # Load the LUT
370 lutCat = dataRefDict['fgcmLookUpTable'].get()
371 fgcmLut, lutIndexVals, lutStd = translateFgcmLut(lutCat,
372 dict(self.config.fgcmFitCycle.physicalFilterMap))
373 del lutCat
374
375 # Translate the visit catalog into fgcm format
376 fgcmExpInfo = translateVisitCatalog(visitCat)
377
378 configDict = makeConfigDict(self.config.fgcmFitCycle, self.log, dataRefDict['camera'],
379 self.config.fgcmFitCycle.maxIterBeforeFinalCycle,
380 True, False, lutIndexVals[0]['FILTERNAMES'],
381 tract=tract)
382
383 # Use the first orientation.
384 # TODO: DM-21215 will generalize to arbitrary camera orientations
385 ccdOffsets = computeCcdOffsets(dataRefDict['camera'], fgcmExpInfo['TELROT'][0])
386
387 # Set up the fit cycle task
388
389 noFitsDict = {'lutIndex': lutIndexVals,
390 'lutStd': lutStd,
391 'expInfo': fgcmExpInfo,
392 'ccdOffsets': ccdOffsets}
393
394 fgcmFitCycle = fgcm.FgcmFitCycle(configDict, useFits=False,
395 noFitsDict=noFitsDict, noOutput=True)
396
397 # We determine the conversion from the native units (typically radians) to
398 # degrees for the first star. This allows us to treat coord_ra/coord_dec as
399 # numpy arrays rather than Angles, which would we approximately 600x slower.
400 conv = fgcmStarObservationCat[0]['ra'].asDegrees() / float(fgcmStarObservationCat[0]['ra'])
401
402 # To load the stars, we need an initial parameter object
403 fgcmPars = fgcm.FgcmParameters.newParsWithArrays(fgcmFitCycle.fgcmConfig,
404 fgcmLut,
405 fgcmExpInfo)
406
407 # Match star observations to visits
408 # Only those star observations that match visits from fgcmExpInfo['VISIT'] will
409 # actually be transferred into fgcm using the indexing below.
410
411 obsIndex = fgcmStarIndicesCat['obsIndex']
412 visitIndex = np.searchsorted(fgcmExpInfo['VISIT'],
413 fgcmStarObservationCat['visit'][obsIndex])
414
415 refMag, refMagErr = extractReferenceMags(fgcmRefCat,
416 self.config.fgcmFitCycle.bands,
417 self.config.fgcmFitCycle.physicalFilterMap)
418 refId = fgcmRefCat['fgcm_id'][:]
419
420 fgcmStars = fgcm.FgcmStars(fgcmFitCycle.fgcmConfig)
421 fgcmStars.loadStars(fgcmPars,
422 fgcmStarObservationCat['visit'][obsIndex],
423 fgcmStarObservationCat['ccd'][obsIndex],
424 fgcmStarObservationCat['ra'][obsIndex] * conv,
425 fgcmStarObservationCat['dec'][obsIndex] * conv,
426 fgcmStarObservationCat['instMag'][obsIndex],
427 fgcmStarObservationCat['instMagErr'][obsIndex],
428 fgcmExpInfo['FILTERNAME'][visitIndex],
429 fgcmStarIdCat['fgcm_id'][:],
430 fgcmStarIdCat['ra'][:],
431 fgcmStarIdCat['dec'][:],
432 fgcmStarIdCat['obsArrIndex'][:],
433 fgcmStarIdCat['nObs'][:],
434 obsX=fgcmStarObservationCat['x'][obsIndex],
435 obsY=fgcmStarObservationCat['y'][obsIndex],
436 obsDeltaMagBkg=fgcmStarObservationCat['deltaMagBkg'][obsIndex],
437 psfCandidate=fgcmStarObservationCat['psf_candidate'][obsIndex],
438 refID=refId,
439 refMag=refMag,
440 refMagErr=refMagErr,
441 flagID=None,
442 flagFlag=None,
443 computeNobs=True)
444
445 # Clear out some memory
446 del fgcmStarIdCat
447 del fgcmStarIndicesCat
448 del fgcmRefCat
449
450 fgcmFitCycle.setLUT(fgcmLut)
451 fgcmFitCycle.setStars(fgcmStars, fgcmPars)
452
453 converged = False
454 cycleNumber = 0
455
456 previousReservedRawRepeatability = np.zeros(fgcmPars.nBands) + 1000.0
457 previousParInfo = None
458 previousParams = None
459 previousSuperStar = None
460
461 while (not converged and cycleNumber < self.config.maxFitCycles):
462
463 fgcmFitCycle.fgcmConfig.updateCycleNumber(cycleNumber)
464
465 if cycleNumber > 0:
466 # Use parameters from previous cycle
467 fgcmPars = fgcm.FgcmParameters.loadParsWithArrays(fgcmFitCycle.fgcmConfig,
468 fgcmExpInfo,
469 previousParInfo,
470 previousParams,
471 previousSuperStar)
472 # We need to reset the star magnitudes and errors for the next
473 # cycle
474 fgcmFitCycle.fgcmStars.reloadStarMagnitudes(fgcmStarObservationCat['instMag'][obsIndex],
475 fgcmStarObservationCat['instMagErr'][obsIndex])
476 fgcmFitCycle.initialCycle = False
477
478 fgcmFitCycle.setPars(fgcmPars)
479 fgcmFitCycle.finishSetup()
480
481 fgcmFitCycle.run()
482
483 # Grab the parameters for the next cycle
484 previousParInfo, previousParams = fgcmFitCycle.fgcmPars.parsToArrays()
485 previousSuperStar = fgcmFitCycle.fgcmPars.parSuperStarFlat.copy()
486
487 self.log.info("Raw repeatability after cycle number %d is:" % (cycleNumber))
488 for i, band in enumerate(fgcmFitCycle.fgcmPars.bands):
489 if not fgcmFitCycle.fgcmPars.hasExposuresInBand[i]:
490 continue
491 rep = fgcmFitCycle.fgcmPars.compReservedRawRepeatability[i] * 1000.0
492 self.log.info(" Band %s, repeatability: %.2f mmag" % (band, rep))
493
494 # Check for convergence
495 if np.alltrue((previousReservedRawRepeatability
496 - fgcmFitCycle.fgcmPars.compReservedRawRepeatability)
497 < self.config.convergenceTolerance):
498 self.log.info("Raw repeatability has converged after cycle number %d." % (cycleNumber))
499 converged = True
500 else:
501 fgcmFitCycle.fgcmConfig.expGrayPhotometricCut[:] = fgcmFitCycle.updatedPhotometricCut
502 fgcmFitCycle.fgcmConfig.expGrayHighCut[:] = fgcmFitCycle.updatedHighCut
503 fgcmFitCycle.fgcmConfig.precomputeSuperStarInitialCycle = False
504 fgcmFitCycle.fgcmConfig.freezeStdAtmosphere = False
505 previousReservedRawRepeatability[:] = fgcmFitCycle.fgcmPars.compReservedRawRepeatability
506 self.log.info("Setting exposure gray photometricity cuts to:")
507 for i, band in enumerate(fgcmFitCycle.fgcmPars.bands):
508 if not fgcmFitCycle.fgcmPars.hasExposuresInBand[i]:
509 continue
510 cut = fgcmFitCycle.updatedPhotometricCut[i] * 1000.0
511 self.log.info(" Band %s, photometricity cut: %.2f mmag" % (band, cut))
512
513 cycleNumber += 1
514
515 # Log warning if not converged
516 if not converged:
517 self.log.warning("Maximum number of fit cycles exceeded (%d) without convergence.", cycleNumber)
518
519 # Do final clean-up iteration
520 fgcmFitCycle.fgcmConfig.freezeStdAtmosphere = False
521 fgcmFitCycle.fgcmConfig.resetParameters = False
522 fgcmFitCycle.fgcmConfig.maxIter = 0
523 fgcmFitCycle.fgcmConfig.outputZeropoints = True
524 fgcmFitCycle.fgcmConfig.outputStandards = True
525 fgcmFitCycle.fgcmConfig.doPlots = self.config.doDebuggingPlots
526 fgcmFitCycle.fgcmConfig.updateCycleNumber(cycleNumber)
527 fgcmFitCycle.initialCycle = False
528
529 fgcmPars = fgcm.FgcmParameters.loadParsWithArrays(fgcmFitCycle.fgcmConfig,
530 fgcmExpInfo,
531 previousParInfo,
532 previousParams,
533 previousSuperStar)
534 fgcmFitCycle.fgcmStars.reloadStarMagnitudes(fgcmStarObservationCat['instMag'][obsIndex],
535 fgcmStarObservationCat['instMagErr'][obsIndex])
536 fgcmFitCycle.setPars(fgcmPars)
537 fgcmFitCycle.finishSetup()
538
539 self.log.info("Running final clean-up fit cycle...")
540 fgcmFitCycle.run()
541
542 self.log.info("Raw repeatability after clean-up cycle is:")
543 for i, band in enumerate(fgcmFitCycle.fgcmPars.bands):
544 if not fgcmFitCycle.fgcmPars.hasExposuresInBand[i]:
545 continue
546 rep = fgcmFitCycle.fgcmPars.compReservedRawRepeatability[i] * 1000.0
547 self.log.info(" Band %s, repeatability: %.2f mmag" % (band, rep))
548
549 # Do the outputs. Need to keep track of tract.
550
551 superStarChebSize = fgcmFitCycle.fgcmZpts.zpStruct['FGCM_FZPT_SSTAR_CHEB'].shape[1]
552 zptChebSize = fgcmFitCycle.fgcmZpts.zpStruct['FGCM_FZPT_CHEB'].shape[1]
553
554 zptSchema = makeZptSchema(superStarChebSize, zptChebSize)
555 zptCat = makeZptCat(zptSchema, fgcmFitCycle.fgcmZpts.zpStruct)
556
557 atmSchema = makeAtmSchema()
558 atmCat = makeAtmCat(atmSchema, fgcmFitCycle.fgcmZpts.atmStruct)
559
560 stdStruct, goodBands = fgcmFitCycle.fgcmStars.retrieveStdStarCatalog(fgcmFitCycle.fgcmPars)
561 stdSchema = makeStdSchema(len(goodBands))
562 stdCat = makeStdCat(stdSchema, stdStruct, goodBands)
563
564 outStruct = self.fgcmOutputProducts.generateTractOutputProducts(dataRefDict,
565 tract,
566 visitCat,
567 zptCat, atmCat, stdCat,
568 self.config.fgcmBuildStars,
569 returnCatalogs=returnCatalogs,
570 butler=butler)
571
572 outStruct.repeatability = fgcmFitCycle.fgcmPars.compReservedRawRepeatability
573
574 fgcmFitCycle.freeSharedMemory()
575
576 return outStruct
def __init__(self, initInputs=None, butler=None, **kwargs)
def run(self, dataRefDict, tract, buildStarsRefObjLoader=None, returnCatalogs=True, butler=None)
def extractReferenceMags(refStars, bands, filterMap)
Definition: utilities.py:883
def computeApertureRadiusFromDataRef(dataRef, fluxField)
Definition: utilities.py:808
def makeStdSchema(nBands)
Definition: utilities.py:738
def makeAtmCat(atmSchema, atmStruct)
Definition: utilities.py:705
def makeConfigDict(config, log, camera, maxIter, resetFitParameters, outputZeropoints, lutFilterNames, tract=None)
Definition: utilities.py:51
def translateFgcmLut(lutCat, physicalFilterMap)
Definition: utilities.py:218
def makeZptCat(zptSchema, zpStruct)
Definition: utilities.py:626
def makeStdCat(stdSchema, stdStruct, goodBands)
Definition: utilities.py:770
def makeZptSchema(superStarChebyshevSize, zptChebyshevSize)
Definition: utilities.py:540
def computeCcdOffsets(camera, defaultOrientation)
Definition: utilities.py:399
def translateVisitCatalog(visitCat)
Definition: utilities.py:348