LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Public Member Functions | Static Public Attributes | List of all members
lsst.fgcmcal.fgcmBuildStars.FgcmBuildStarsTask Class Reference
Inheritance diagram for lsst.fgcmcal.fgcmBuildStars.FgcmBuildStarsTask:
lsst.fgcmcal.fgcmBuildStarsBase.FgcmBuildStarsBaseTask

Public Member Functions

def fgcmMakeAllStarObservations (self, groupedDataRefs, visitCat, sourceSchema, camera, calibFluxApertureRadius=None, visitCatDataRef=None, starObsDataRef=None, inStarObsCat=None)
 
def runDataRef (self, butler, dataRefs)
 
def fgcmMakeVisitCatalog (self, camera, groupedDataRefs, bkgDataRefDict=None, visitCatDataRef=None, inVisitCat=None)
 
def fgcmMatchStars (self, visitCat, obsCat, lutDataRef=None)
 

Static Public Attributes

 ConfigClass = FgcmBuildStarsConfig
 
 RunnerClass = FgcmBuildStarsRunner
 

Detailed Description

Build stars for the FGCM global calibration, using src catalogs.

Definition at line 91 of file fgcmBuildStars.py.

Member Function Documentation

◆ fgcmMakeAllStarObservations()

def lsst.fgcmcal.fgcmBuildStars.FgcmBuildStarsTask.fgcmMakeAllStarObservations (   self,
  groupedDataRefs,
  visitCat,
  sourceSchema,
  camera,
  calibFluxApertureRadius = None,
  visitCatDataRef = None,
  starObsDataRef = None,
  inStarObsCat = None 
)
Compile all good star observations from visits in visitCat.  Checkpoint files
will be stored if both visitCatDataRef and starObsDataRef are not None.

Parameters
----------
groupedDataRefs : `dict` of `list`s
    Lists of `~lsst.daf.persistence.ButlerDataRef` or
    `~lsst.daf.butler.DeferredDatasetHandle`, grouped by visit.
visitCat : `~afw.table.BaseCatalog`
    Catalog with visit data for FGCM
sourceSchema : `~lsst.afw.table.Schema`
    Schema for the input src catalogs.
camera : `~lsst.afw.cameraGeom.Camera`
calibFluxApertureRadius : `float`, optional
    Aperture radius for calibration flux.
visitCatDataRef : `~lsst.daf.persistence.ButlerDataRef`, optional
    Dataref to write visitCat for checkpoints
starObsDataRef : `~lsst.daf.persistence.ButlerDataRef`, optional
    Dataref to write the star observation catalog for checkpoints.
inStarObsCat : `~afw.table.BaseCatalog`
    Input observation catalog.  If this is incomplete, observations
    will be appended from when it was cut off.

Returns
-------
fgcmStarObservations : `afw.table.BaseCatalog`
    Full catalog of good observations.

Raises
------
RuntimeError: Raised if doSubtractLocalBackground is True and
   calibFluxApertureRadius is not set.

Reimplemented from lsst.fgcmcal.fgcmBuildStarsBase.FgcmBuildStarsBaseTask.

Definition at line 180 of file fgcmBuildStars.py.

186  inStarObsCat=None):
187  startTime = time.time()
188 
189  # If both dataRefs are None, then we assume the caller does not
190  # want to store checkpoint files. If both are set, we will
191  # do checkpoint files. And if only one is set, this is potentially
192  # unintentional and we will warn.
193  if (visitCatDataRef is not None and starObsDataRef is None
194  or visitCatDataRef is None and starObsDataRef is not None):
195  self.log.warning("Only one of visitCatDataRef and starObsDataRef are set, so "
196  "no checkpoint files will be persisted.")
197 
198  if self.config.doSubtractLocalBackground and calibFluxApertureRadius is None:
199  raise RuntimeError("Must set calibFluxApertureRadius if doSubtractLocalBackground is True.")
200 
201  # create our source schema. Use the first valid dataRef
202  dataRef = groupedDataRefs[list(groupedDataRefs.keys())[0]][0]
203 
204  # Construct a mapping from ccd number to index
205  ccdMapping = {}
206  for ccdIndex, detector in enumerate(camera):
207  ccdMapping[detector.getId()] = ccdIndex
208 
209  approxPixelAreaFields = computeApproxPixelAreaFields(camera)
210 
211  sourceMapper = self._makeSourceMapper(sourceSchema)
212 
213  # We also have a temporary catalog that will accumulate aperture measurements
214  aperMapper = self._makeAperMapper(sourceSchema)
215 
216  outputSchema = sourceMapper.getOutputSchema()
217 
218  if inStarObsCat is not None:
219  fullCatalog = inStarObsCat
220  comp1 = fullCatalog.schema.compare(outputSchema, outputSchema.EQUAL_KEYS)
221  comp2 = fullCatalog.schema.compare(outputSchema, outputSchema.EQUAL_NAMES)
222  if not comp1 or not comp2:
223  raise RuntimeError("Existing fgcmStarObservations file found with mismatched schema.")
224  else:
225  fullCatalog = afwTable.BaseCatalog(outputSchema)
226 
227  # FGCM will provide relative calibration for the flux in config.instFluxField
228 
229  instFluxKey = sourceSchema[self.config.instFluxField].asKey()
230  instFluxErrKey = sourceSchema[self.config.instFluxField + 'Err'].asKey()
231  visitKey = outputSchema['visit'].asKey()
232  ccdKey = outputSchema['ccd'].asKey()
233  instMagKey = outputSchema['instMag'].asKey()
234  instMagErrKey = outputSchema['instMagErr'].asKey()
235  deltaMagBkgKey = outputSchema['deltaMagBkg'].asKey()
236 
237  # Prepare local background if desired
238  if self.config.doSubtractLocalBackground:
239  localBackgroundFluxKey = sourceSchema[self.config.localBackgroundFluxField].asKey()
240  localBackgroundArea = np.pi*calibFluxApertureRadius**2.
241 
242  aperOutputSchema = aperMapper.getOutputSchema()
243 
244  instFluxAperInKey = sourceSchema[self.config.apertureInnerInstFluxField].asKey()
245  instFluxErrAperInKey = sourceSchema[self.config.apertureInnerInstFluxField + 'Err'].asKey()
246  instFluxAperOutKey = sourceSchema[self.config.apertureOuterInstFluxField].asKey()
247  instFluxErrAperOutKey = sourceSchema[self.config.apertureOuterInstFluxField + 'Err'].asKey()
248  instMagInKey = aperOutputSchema['instMag_aper_inner'].asKey()
249  instMagErrInKey = aperOutputSchema['instMagErr_aper_inner'].asKey()
250  instMagOutKey = aperOutputSchema['instMag_aper_outer'].asKey()
251  instMagErrOutKey = aperOutputSchema['instMagErr_aper_outer'].asKey()
252 
253  k = 2.5/np.log(10.)
254 
255  # loop over visits
256  for ctr, visit in enumerate(visitCat):
257  if visit['sources_read']:
258  continue
259 
260  expTime = visit['exptime']
261 
262  nStarInVisit = 0
263 
264  # Reset the aperture catalog (per visit)
265  aperVisitCatalog = afwTable.BaseCatalog(aperOutputSchema)
266 
267  for dataRef in groupedDataRefs[visit['visit']]:
268 
269  ccdId = dataRef.dataId[self.config.ccdDataRefName]
270 
271  sources = dataRef.get(datasetType='src', flags=afwTable.SOURCE_IO_NO_FOOTPRINTS)
272  goodSrc = self.sourceSelector.selectSources(sources)
273 
274  # Need to add a selection based on the local background correction
275  # if necessary
276  if self.config.doSubtractLocalBackground:
277  localBackground = localBackgroundArea*sources[localBackgroundFluxKey]
278 
279  bad, = np.where((sources[instFluxKey] - localBackground) <= 0.0)
280  goodSrc.selected[bad] = False
281 
282  tempCat = afwTable.BaseCatalog(fullCatalog.schema)
283  tempCat.reserve(goodSrc.selected.sum())
284  tempCat.extend(sources[goodSrc.selected], mapper=sourceMapper)
285  tempCat[visitKey][:] = visit['visit']
286  tempCat[ccdKey][:] = ccdId
287 
288  # Compute "instrumental magnitude" by scaling flux with exposure time.
289  scaledInstFlux = (sources[instFluxKey][goodSrc.selected]
290  * visit['scaling'][ccdMapping[ccdId]])
291  tempCat[instMagKey][:] = (-2.5*np.log10(scaledInstFlux) + 2.5*np.log10(expTime))
292 
293  # Compute the change in magnitude from the background offset
294  if self.config.doSubtractLocalBackground:
295  # At the moment we only adjust the flux and not the flux
296  # error by the background because the error on
297  # base_LocalBackground_instFlux is the rms error in the
298  # background annulus, not the error on the mean in the
299  # background estimate (which is much smaller, by sqrt(n)
300  # pixels used to estimate the background, which we do not
301  # have access to in this task). In the default settings,
302  # the annulus is sufficiently large such that these
303  # additional errors are are negligibly small (much less
304  # than a mmag in quadrature).
305 
306  # This is the difference between the mag with background correction
307  # and the mag without background correction.
308  tempCat[deltaMagBkgKey][:] = (-2.5*np.log10(sources[instFluxKey][goodSrc.selected]
309  - localBackground[goodSrc.selected]) -
310  -2.5*np.log10(sources[instFluxKey][goodSrc.selected]))
311  else:
312  tempCat[deltaMagBkgKey][:] = 0.0
313 
314  # Compute instMagErr from instFluxErr/instFlux, any scaling
315  # will cancel out.
316 
317  tempCat[instMagErrKey][:] = k*(sources[instFluxErrKey][goodSrc.selected]
318  / sources[instFluxKey][goodSrc.selected])
319 
320  # Compute the jacobian from an approximate PixelAreaBoundedField
321  tempCat['jacobian'] = approxPixelAreaFields[ccdId].evaluate(tempCat['x'],
322  tempCat['y'])
323 
324  # Apply the jacobian if configured
325  if self.config.doApplyWcsJacobian:
326  tempCat[instMagKey][:] -= 2.5*np.log10(tempCat['jacobian'][:])
327 
328  fullCatalog.extend(tempCat)
329 
330  # And the aperture information
331  # This does not need the jacobian because it is all locally relative
332  tempAperCat = afwTable.BaseCatalog(aperVisitCatalog.schema)
333  tempAperCat.reserve(goodSrc.selected.sum())
334  tempAperCat.extend(sources[goodSrc.selected], mapper=aperMapper)
335 
336  with np.warnings.catch_warnings():
337  # Ignore warnings, we will filter infinities and
338  # nans below.
339  np.warnings.simplefilter("ignore")
340 
341  tempAperCat[instMagInKey][:] = -2.5*np.log10(
342  sources[instFluxAperInKey][goodSrc.selected])
343  tempAperCat[instMagErrInKey][:] = k*(
344  sources[instFluxErrAperInKey][goodSrc.selected]
345  / sources[instFluxAperInKey][goodSrc.selected])
346  tempAperCat[instMagOutKey][:] = -2.5*np.log10(
347  sources[instFluxAperOutKey][goodSrc.selected])
348  tempAperCat[instMagErrOutKey][:] = k*(
349  sources[instFluxErrAperOutKey][goodSrc.selected]
350  / sources[instFluxAperOutKey][goodSrc.selected])
351 
352  aperVisitCatalog.extend(tempAperCat)
353 
354  nStarInVisit += len(tempCat)
355 
356  # Compute the median delta-aper
357  if not aperVisitCatalog.isContiguous():
358  aperVisitCatalog = aperVisitCatalog.copy(deep=True)
359 
360  instMagIn = aperVisitCatalog[instMagInKey]
361  instMagErrIn = aperVisitCatalog[instMagErrInKey]
362  instMagOut = aperVisitCatalog[instMagOutKey]
363  instMagErrOut = aperVisitCatalog[instMagErrOutKey]
364 
365  ok = (np.isfinite(instMagIn) & np.isfinite(instMagErrIn)
366  & np.isfinite(instMagOut) & np.isfinite(instMagErrOut))
367 
368  visit['deltaAper'] = np.median(instMagIn[ok] - instMagOut[ok])
369  visit['sources_read'] = True
370 
371  self.log.info(" Found %d good stars in visit %d (deltaAper = %.3f)" %
372  (nStarInVisit, visit['visit'], visit['deltaAper']))
373 
374  if ((ctr % self.config.nVisitsPerCheckpoint) == 0
375  and starObsDataRef is not None and visitCatDataRef is not None):
376  # We need to persist both the stars and the visit catalog which gets
377  # additional metadata from each visit.
378  starObsDataRef.put(fullCatalog)
379  visitCatDataRef.put(visitCat)
380 
381  self.log.info("Found all good star observations in %.2f s" %
382  (time.time() - startTime))
383 
384  return fullCatalog
385 
daf::base::PropertyList * list
Definition: fits.cc:913
def computeApproxPixelAreaFields(camera)
Definition: utilities.py:499

◆ fgcmMakeVisitCatalog()

def lsst.fgcmcal.fgcmBuildStarsBase.FgcmBuildStarsBaseTask.fgcmMakeVisitCatalog (   self,
  camera,
  groupedDataRefs,
  bkgDataRefDict = None,
  visitCatDataRef = None,
  inVisitCat = None 
)
inherited
Make a visit catalog with all the keys from each visit

Parameters
----------
camera: `lsst.afw.cameraGeom.Camera`
   Camera from the butler
groupedDataRefs: `dict`
   Dictionary with visit keys, and `list`s of
   `lsst.daf.persistence.ButlerDataRef`
bkgDataRefDict: `dict`, optional
   Dictionary of gen3 dataRefHandles for background info.
visitCatDataRef: `lsst.daf.persistence.ButlerDataRef`, optional
   Dataref to write visitCat for checkpoints
inVisitCat: `afw.table.BaseCatalog`, optional
   Input (possibly incomplete) visit catalog

Returns
-------
visitCat: `afw.table.BaseCatalog`

Definition at line 460 of file fgcmBuildStarsBase.py.

461  visitCatDataRef=None, inVisitCat=None):
462  """
463  Make a visit catalog with all the keys from each visit
464 
465  Parameters
466  ----------
467  camera: `lsst.afw.cameraGeom.Camera`
468  Camera from the butler
469  groupedDataRefs: `dict`
470  Dictionary with visit keys, and `list`s of
471  `lsst.daf.persistence.ButlerDataRef`
472  bkgDataRefDict: `dict`, optional
473  Dictionary of gen3 dataRefHandles for background info.
474  visitCatDataRef: `lsst.daf.persistence.ButlerDataRef`, optional
475  Dataref to write visitCat for checkpoints
476  inVisitCat: `afw.table.BaseCatalog`, optional
477  Input (possibly incomplete) visit catalog
478 
479  Returns
480  -------
481  visitCat: `afw.table.BaseCatalog`
482  """
483 
484  self.log.info("Assembling visitCatalog from %d %ss" %
485  (len(groupedDataRefs), self.config.visitDataRefName))
486 
487  nCcd = len(camera)
488 
489  if inVisitCat is None:
490  schema = self._makeFgcmVisitSchema(nCcd)
491 
492  visitCat = afwTable.BaseCatalog(schema)
493  visitCat.reserve(len(groupedDataRefs))
494  visitCat.resize(len(groupedDataRefs))
495 
496  visitCat['visit'] = list(groupedDataRefs.keys())
497  visitCat['used'] = 0
498  visitCat['sources_read'] = False
499  else:
500  visitCat = inVisitCat
501 
502  # No matter what, fill the catalog. This will check if it was
503  # already read.
504  self._fillVisitCatalog(visitCat, groupedDataRefs,
505  bkgDataRefDict=bkgDataRefDict,
506  visitCatDataRef=visitCatDataRef)
507 
508  return visitCat
509 

◆ fgcmMatchStars()

def lsst.fgcmcal.fgcmBuildStarsBase.FgcmBuildStarsBaseTask.fgcmMatchStars (   self,
  visitCat,
  obsCat,
  lutDataRef = None 
)
inherited
Use FGCM code to match observations into unique stars.

Parameters
----------
visitCat: `afw.table.BaseCatalog`
   Catalog with visit data for fgcm
obsCat: `afw.table.BaseCatalog`
   Full catalog of star observations for fgcm
lutDataRef: `lsst.daf.persistence.ButlerDataRef` or
            `lsst.daf.butler.DeferredDatasetHandle`, optional
   Data reference to fgcm look-up table (used if matching reference stars).

Returns
-------
fgcmStarIdCat: `afw.table.BaseCatalog`
   Catalog of unique star identifiers and index keys
fgcmStarIndicesCat: `afwTable.BaseCatalog`
   Catalog of unique star indices
fgcmRefCat: `afw.table.BaseCatalog`
   Catalog of matched reference stars.
   Will be None if `config.doReferenceMatches` is False.

Definition at line 687 of file fgcmBuildStarsBase.py.

687  def fgcmMatchStars(self, visitCat, obsCat, lutDataRef=None):
688  """
689  Use FGCM code to match observations into unique stars.
690 
691  Parameters
692  ----------
693  visitCat: `afw.table.BaseCatalog`
694  Catalog with visit data for fgcm
695  obsCat: `afw.table.BaseCatalog`
696  Full catalog of star observations for fgcm
697  lutDataRef: `lsst.daf.persistence.ButlerDataRef` or
698  `lsst.daf.butler.DeferredDatasetHandle`, optional
699  Data reference to fgcm look-up table (used if matching reference stars).
700 
701  Returns
702  -------
703  fgcmStarIdCat: `afw.table.BaseCatalog`
704  Catalog of unique star identifiers and index keys
705  fgcmStarIndicesCat: `afwTable.BaseCatalog`
706  Catalog of unique star indices
707  fgcmRefCat: `afw.table.BaseCatalog`
708  Catalog of matched reference stars.
709  Will be None if `config.doReferenceMatches` is False.
710  """
711  # get filter names into a numpy array...
712  # This is the type that is expected by the fgcm code
713  visitFilterNames = np.zeros(len(visitCat), dtype='a30')
714  for i in range(len(visitCat)):
715  visitFilterNames[i] = visitCat[i]['physicalFilter']
716 
717  # match to put filterNames with observations
718  visitIndex = np.searchsorted(visitCat['visit'],
719  obsCat['visit'])
720 
721  obsFilterNames = visitFilterNames[visitIndex]
722 
723  if self.config.doReferenceMatches:
724  # Get the reference filter names, using the LUT
725  lutCat = lutDataRef.get()
726 
727  stdFilterDict = {filterName: stdFilter for (filterName, stdFilter) in
728  zip(lutCat[0]['physicalFilters'].split(','),
729  lutCat[0]['stdPhysicalFilters'].split(','))}
730  stdLambdaDict = {stdFilter: stdLambda for (stdFilter, stdLambda) in
731  zip(lutCat[0]['stdPhysicalFilters'].split(','),
732  lutCat[0]['lambdaStdFilter'])}
733 
734  del lutCat
735 
736  referenceFilterNames = self._getReferenceFilterNames(visitCat,
737  stdFilterDict,
738  stdLambdaDict)
739  self.log.info("Using the following reference filters: %s" %
740  (', '.join(referenceFilterNames)))
741 
742  else:
743  # This should be an empty list
744  referenceFilterNames = []
745 
746  # make the fgcm starConfig dict
747  starConfig = {'logger': self.log,
748  'filterToBand': self.config.physicalFilterMap,
749  'requiredBands': self.config.requiredBands,
750  'minPerBand': self.config.minPerBand,
751  'matchRadius': self.config.matchRadius,
752  'isolationRadius': self.config.isolationRadius,
753  'matchNSide': self.config.matchNside,
754  'coarseNSide': self.config.coarseNside,
755  'densNSide': self.config.densityCutNside,
756  'densMaxPerPixel': self.config.densityCutMaxPerPixel,
757  'randomSeed': self.config.randomSeed,
758  'primaryBands': self.config.primaryBands,
759  'referenceFilterNames': referenceFilterNames}
760 
761  # initialize the FgcmMakeStars object
762  fgcmMakeStars = fgcm.FgcmMakeStars(starConfig)
763 
764  # make the primary stars
765  # note that the ra/dec native Angle format is radians
766  # We determine the conversion from the native units (typically
767  # radians) to degrees for the first observation. This allows us
768  # to treate ra/dec as numpy arrays rather than Angles, which would
769  # be approximately 600x slower.
770  conv = obsCat[0]['ra'].asDegrees() / float(obsCat[0]['ra'])
771  fgcmMakeStars.makePrimaryStars(obsCat['ra'] * conv,
772  obsCat['dec'] * conv,
773  filterNameArray=obsFilterNames,
774  bandSelected=False)
775 
776  # and match all the stars
777  fgcmMakeStars.makeMatchedStars(obsCat['ra'] * conv,
778  obsCat['dec'] * conv,
779  obsFilterNames)
780 
781  if self.config.doReferenceMatches:
782  fgcmMakeStars.makeReferenceMatches(self.fgcmLoadReferenceCatalog)
783 
784  # now persist
785 
786  objSchema = self._makeFgcmObjSchema()
787 
788  # make catalog and records
789  fgcmStarIdCat = afwTable.BaseCatalog(objSchema)
790  fgcmStarIdCat.reserve(fgcmMakeStars.objIndexCat.size)
791  for i in range(fgcmMakeStars.objIndexCat.size):
792  fgcmStarIdCat.addNew()
793 
794  # fill the catalog
795  fgcmStarIdCat['fgcm_id'][:] = fgcmMakeStars.objIndexCat['fgcm_id']
796  fgcmStarIdCat['ra'][:] = fgcmMakeStars.objIndexCat['ra']
797  fgcmStarIdCat['dec'][:] = fgcmMakeStars.objIndexCat['dec']
798  fgcmStarIdCat['obsArrIndex'][:] = fgcmMakeStars.objIndexCat['obsarrindex']
799  fgcmStarIdCat['nObs'][:] = fgcmMakeStars.objIndexCat['nobs']
800 
801  obsSchema = self._makeFgcmObsSchema()
802 
803  fgcmStarIndicesCat = afwTable.BaseCatalog(obsSchema)
804  fgcmStarIndicesCat.reserve(fgcmMakeStars.obsIndexCat.size)
805  for i in range(fgcmMakeStars.obsIndexCat.size):
806  fgcmStarIndicesCat.addNew()
807 
808  fgcmStarIndicesCat['obsIndex'][:] = fgcmMakeStars.obsIndexCat['obsindex']
809 
810  if self.config.doReferenceMatches:
811  refSchema = self._makeFgcmRefSchema(len(referenceFilterNames))
812 
813  fgcmRefCat = afwTable.BaseCatalog(refSchema)
814  fgcmRefCat.reserve(fgcmMakeStars.referenceCat.size)
815 
816  for i in range(fgcmMakeStars.referenceCat.size):
817  fgcmRefCat.addNew()
818 
819  fgcmRefCat['fgcm_id'][:] = fgcmMakeStars.referenceCat['fgcm_id']
820  fgcmRefCat['refMag'][:, :] = fgcmMakeStars.referenceCat['refMag']
821  fgcmRefCat['refMagErr'][:, :] = fgcmMakeStars.referenceCat['refMagErr']
822 
823  md = PropertyList()
824  md.set("REFSTARS_FORMAT_VERSION", REFSTARS_FORMAT_VERSION)
825  md.set("FILTERNAMES", referenceFilterNames)
826  fgcmRefCat.setMetadata(md)
827 
828  else:
829  fgcmRefCat = None
830 
831  return fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat
832 

◆ runDataRef()

def lsst.fgcmcal.fgcmBuildStarsBase.FgcmBuildStarsBaseTask.runDataRef (   self,
  butler,
  dataRefs 
)
inherited
Cross-match and make star list for FGCM Input

Parameters
----------
butler:  `lsst.daf.persistence.Butler`
dataRefs: `list` of `lsst.daf.persistence.ButlerDataRef`
   Source data references for the input visits.

Raises
------
RuntimeErrror: Raised if `config.doReferenceMatches` is set and
   an fgcmLookUpTable is not available, or if computeFluxApertureRadius()
   fails if the calibFlux is not a CircularAperture flux.

Definition at line 296 of file fgcmBuildStarsBase.py.

296  def runDataRef(self, butler, dataRefs):
297  """
298  Cross-match and make star list for FGCM Input
299 
300  Parameters
301  ----------
302  butler: `lsst.daf.persistence.Butler`
303  dataRefs: `list` of `lsst.daf.persistence.ButlerDataRef`
304  Source data references for the input visits.
305 
306  Raises
307  ------
308  RuntimeErrror: Raised if `config.doReferenceMatches` is set and
309  an fgcmLookUpTable is not available, or if computeFluxApertureRadius()
310  fails if the calibFlux is not a CircularAperture flux.
311  """
312  datasetType = dataRefs[0].butlerSubset.datasetType
313  self.log.info("Running with %d %s dataRefs", len(dataRefs), datasetType)
314 
315  if self.config.doReferenceMatches:
316  self.makeSubtask("fgcmLoadReferenceCatalog", butler=butler)
317  # Ensure that we have a LUT
318  if not butler.datasetExists('fgcmLookUpTable'):
319  raise RuntimeError("Must have fgcmLookUpTable if using config.doReferenceMatches")
320  # Compute aperture radius if necessary. This is useful to do now before
321  # any heavy lifting has happened (fail early).
322  calibFluxApertureRadius = None
323  if self.config.doSubtractLocalBackground:
324  try:
325  calibFluxApertureRadius = computeApertureRadiusFromDataRef(dataRefs[0],
326  self.config.instFluxField)
327  except RuntimeError as e:
328  raise RuntimeError("Could not determine aperture radius from %s. "
329  "Cannot use doSubtractLocalBackground." %
330  (self.config.instFluxField)) from e
331 
332  camera = butler.get('camera')
333  groupedDataRefs = self._findAndGroupDataRefsGen2(butler, camera, dataRefs)
334 
335  # Make the visit catalog if necessary
336  # First check if the visit catalog is in the _current_ path
337  # We cannot use Gen2 datasetExists() because that checks all parent
338  # directories as well, which would make recovering from faults
339  # and fgcmcal reruns impossible.
340  visitCatDataRef = butler.dataRef('fgcmVisitCatalog')
341  filename = visitCatDataRef.get('fgcmVisitCatalog_filename')[0]
342  if os.path.exists(filename):
343  # This file exists and we should continue processing
344  inVisitCat = visitCatDataRef.get()
345  if len(inVisitCat) != len(groupedDataRefs):
346  raise RuntimeError("Existing visitCatalog found, but has an inconsistent "
347  "number of visits. Cannot continue.")
348  else:
349  inVisitCat = None
350 
351  visitCat = self.fgcmMakeVisitCatalog(camera, groupedDataRefs,
352  visitCatDataRef=visitCatDataRef,
353  inVisitCat=inVisitCat)
354 
355  # Persist the visitCat as a checkpoint file.
356  visitCatDataRef.put(visitCat)
357 
358  starObsDataRef = butler.dataRef('fgcmStarObservations')
359  filename = starObsDataRef.get('fgcmStarObservations_filename')[0]
360  if os.path.exists(filename):
361  inStarObsCat = starObsDataRef.get()
362  else:
363  inStarObsCat = None
364 
365  rad = calibFluxApertureRadius
366  sourceSchemaDataRef = butler.dataRef('src_schema')
367  sourceSchema = sourceSchemaDataRef.get('src_schema', immediate=True).schema
368  fgcmStarObservationCat = self.fgcmMakeAllStarObservations(groupedDataRefs,
369  visitCat,
370  sourceSchema,
371  camera,
372  calibFluxApertureRadius=rad,
373  starObsDataRef=starObsDataRef,
374  visitCatDataRef=visitCatDataRef,
375  inStarObsCat=inStarObsCat)
376  visitCatDataRef.put(visitCat)
377  starObsDataRef.put(fgcmStarObservationCat)
378 
379  # Always do the matching.
380  if self.config.doReferenceMatches:
381  lutDataRef = butler.dataRef('fgcmLookUpTable')
382  else:
383  lutDataRef = None
384  fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat = self.fgcmMatchStars(visitCat,
385  fgcmStarObservationCat,
386  lutDataRef=lutDataRef)
387 
388  # Persist catalogs via the butler
389  butler.put(fgcmStarIdCat, 'fgcmStarIds')
390  butler.put(fgcmStarIndicesCat, 'fgcmStarIndices')
391  if fgcmRefCat is not None:
392  butler.put(fgcmRefCat, 'fgcmReferenceStars')
393 
def computeApertureRadiusFromDataRef(dataRef, fluxField)
Definition: utilities.py:812

Member Data Documentation

◆ ConfigClass

lsst.fgcmcal.fgcmBuildStars.FgcmBuildStarsTask.ConfigClass = FgcmBuildStarsConfig
static

Definition at line 95 of file fgcmBuildStars.py.

◆ RunnerClass

lsst.fgcmcal.fgcmBuildStars.FgcmBuildStarsTask.RunnerClass = FgcmBuildStarsRunner
static

Definition at line 96 of file fgcmBuildStars.py.


The documentation for this class was generated from the following file: