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