LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
LSST Data Management Base Package
Public Member Functions | Public Attributes | Static Public Attributes | List of all members
lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask Class Reference
Inheritance diagram for lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask:
lsst.fgcmcal.fgcmBuildStarsBase.FgcmBuildStarsBaseTask

Public Member Functions

def __init__ (self, initInputs=None, **kwargs)
 
def runQuantum (self, butlerQC, inputRefs, outputRefs)
 
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)
 

Public Attributes

 sourceSchema
 

Static Public Attributes

 ConfigClass = FgcmBuildStarsTableConfig
 
 RunnerClass = FgcmBuildStarsRunner
 
bool canMultiprocess = False
 

Detailed Description

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

Definition at line 215 of file fgcmBuildStarsTable.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask.__init__ (   self,
  initInputs = None,
**  kwargs 
)

Definition at line 225 of file fgcmBuildStarsTable.py.

225  def __init__(self, initInputs=None, **kwargs):
226  super().__init__(initInputs=initInputs, **kwargs)
227  if initInputs is not None:
228  self.sourceSchema = initInputs["sourceSchema"].schema
229 

Member Function Documentation

◆ fgcmMakeAllStarObservations()

def lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask.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 394 of file fgcmBuildStarsTable.py.

400  inStarObsCat=None):
401  startTime = time.time()
402 
403  # If both dataRefs are None, then we assume the caller does not
404  # want to store checkpoint files. If both are set, we will
405  # do checkpoint files. And if only one is set, this is potentially
406  # unintentional and we will warn.
407  if (visitCatDataRef is not None and starObsDataRef is None
408  or visitCatDataRef is None and starObsDataRef is not None):
409  self.log.warning("Only one of visitCatDataRef and starObsDataRef are set, so "
410  "no checkpoint files will be persisted.")
411 
412  if self.config.doSubtractLocalBackground and calibFluxApertureRadius is None:
413  raise RuntimeError("Must set calibFluxApertureRadius if doSubtractLocalBackground is True.")
414 
415  # To get the correct output schema, we use similar code as fgcmBuildStarsTask
416  # We are not actually using this mapper, except to grab the outputSchema
417  sourceMapper = self._makeSourceMapper(sourceSchema)
418  outputSchema = sourceMapper.getOutputSchema()
419 
420  # Construct mapping from ccd number to index
421  ccdMapping = {}
422  for ccdIndex, detector in enumerate(camera):
423  ccdMapping[detector.getId()] = ccdIndex
424 
425  approxPixelAreaFields = computeApproxPixelAreaFields(camera)
426 
427  if inStarObsCat is not None:
428  fullCatalog = inStarObsCat
429  comp1 = fullCatalog.schema.compare(outputSchema, outputSchema.EQUAL_KEYS)
430  comp2 = fullCatalog.schema.compare(outputSchema, outputSchema.EQUAL_NAMES)
431  if not comp1 or not comp2:
432  raise RuntimeError("Existing fgcmStarObservations file found with mismatched schema.")
433  else:
434  fullCatalog = afwTable.BaseCatalog(outputSchema)
435 
436  visitKey = outputSchema['visit'].asKey()
437  ccdKey = outputSchema['ccd'].asKey()
438  instMagKey = outputSchema['instMag'].asKey()
439  instMagErrKey = outputSchema['instMagErr'].asKey()
440 
441  # Prepare local background if desired
442  if self.config.doSubtractLocalBackground:
443  localBackgroundArea = np.pi*calibFluxApertureRadius**2.
444 
445  columns = None
446 
447  k = 2.5/np.log(10.)
448 
449  for counter, visit in enumerate(visitCat):
450  # Check if these sources have already been read and stored in the checkpoint file
451  if visit['sources_read']:
452  continue
453 
454  expTime = visit['exptime']
455 
456  dataRef = groupedDataRefs[visit['visit']][-1]
457 
458  if isinstance(dataRef, dafPersist.ButlerDataRef):
459  srcTable = dataRef.get()
460  if columns is None:
461  columns, detColumn = self._get_sourceTable_visit_columns(srcTable.columns)
462  df = srcTable.toDataFrame(columns)
463  else:
464  if columns is None:
465  inColumns = dataRef.get(component='columns')
466  columns, detColumn = self._get_sourceTable_visit_columns(inColumns)
467  df = dataRef.get(parameters={'columns': columns})
468 
469  goodSrc = self.sourceSelector.selectSources(df)
470 
471  # Need to add a selection based on the local background correction
472  # if necessary
473  if self.config.doSubtractLocalBackground:
474  localBackground = localBackgroundArea*df[self.config.localBackgroundFluxField].values
475  use, = np.where((goodSrc.selected)
476  & ((df[self.config.instFluxField].values - localBackground) > 0.0))
477  else:
478  use, = np.where(goodSrc.selected)
479 
480  tempCat = afwTable.BaseCatalog(fullCatalog.schema)
481  tempCat.resize(use.size)
482 
483  tempCat['ra'][:] = np.deg2rad(df['ra'].values[use])
484  tempCat['dec'][:] = np.deg2rad(df['decl'].values[use])
485  tempCat['x'][:] = df['x'].values[use]
486  tempCat['y'][:] = df['y'].values[use]
487  # The "visit" name in the parquet table is hard-coded.
488  tempCat[visitKey][:] = df['visit'].values[use]
489  tempCat[ccdKey][:] = df[detColumn].values[use]
490  tempCat['psf_candidate'] = df[self.config.psfCandidateName].values[use]
491 
492  if self.config.doSubtractLocalBackground:
493  # At the moment we only adjust the flux and not the flux
494  # error by the background because the error on
495  # base_LocalBackground_instFlux is the rms error in the
496  # background annulus, not the error on the mean in the
497  # background estimate (which is much smaller, by sqrt(n)
498  # pixels used to estimate the background, which we do not
499  # have access to in this task). In the default settings,
500  # the annulus is sufficiently large such that these
501  # additional errors are are negligibly small (much less
502  # than a mmag in quadrature).
503 
504  # This is the difference between the mag with local background correction
505  # and the mag without local background correction.
506  tempCat['deltaMagBkg'] = (-2.5*np.log10(df[self.config.instFluxField].values[use]
507  - localBackground[use]) -
508  -2.5*np.log10(df[self.config.instFluxField].values[use]))
509  else:
510  tempCat['deltaMagBkg'][:] = 0.0
511 
512  # Need to loop over ccds here
513  for detector in camera:
514  ccdId = detector.getId()
515  # used index for all observations with a given ccd
516  use2 = (tempCat[ccdKey] == ccdId)
517  tempCat['jacobian'][use2] = approxPixelAreaFields[ccdId].evaluate(tempCat['x'][use2],
518  tempCat['y'][use2])
519  scaledInstFlux = (df[self.config.instFluxField].values[use[use2]]
520  * visit['scaling'][ccdMapping[ccdId]])
521  tempCat[instMagKey][use2] = (-2.5*np.log10(scaledInstFlux) + 2.5*np.log10(expTime))
522 
523  # Compute instMagErr from instFluxErr/instFlux, any scaling
524  # will cancel out.
525  tempCat[instMagErrKey][:] = k*(df[self.config.instFluxField + 'Err'].values[use]
526  / df[self.config.instFluxField].values[use])
527 
528  # Apply the jacobian if configured
529  if self.config.doApplyWcsJacobian:
530  tempCat[instMagKey][:] -= 2.5*np.log10(tempCat['jacobian'][:])
531 
532  fullCatalog.extend(tempCat)
533 
534  # Now do the aperture information
535  with np.warnings.catch_warnings():
536  # Ignore warnings, we will filter infinites and nans below
537  np.warnings.simplefilter("ignore")
538 
539  instMagIn = -2.5*np.log10(df[self.config.apertureInnerInstFluxField].values[use])
540  instMagErrIn = k*(df[self.config.apertureInnerInstFluxField + 'Err'].values[use]
541  / df[self.config.apertureInnerInstFluxField].values[use])
542  instMagOut = -2.5*np.log10(df[self.config.apertureOuterInstFluxField].values[use])
543  instMagErrOut = k*(df[self.config.apertureOuterInstFluxField + 'Err'].values[use]
544  / df[self.config.apertureOuterInstFluxField].values[use])
545 
546  ok = (np.isfinite(instMagIn) & np.isfinite(instMagErrIn)
547  & np.isfinite(instMagOut) & np.isfinite(instMagErrOut))
548 
549  visit['deltaAper'] = np.median(instMagIn[ok] - instMagOut[ok])
550  visit['sources_read'] = True
551 
552  self.log.info(" Found %d good stars in visit %d (deltaAper = %0.3f)",
553  use.size, visit['visit'], visit['deltaAper'])
554 
555  if ((counter % self.config.nVisitsPerCheckpoint) == 0
556  and starObsDataRef is not None and visitCatDataRef is not None):
557  # We need to persist both the stars and the visit catalog which gets
558  # additional metadata from each visit.
559  starObsDataRef.put(fullCatalog)
560  visitCatDataRef.put(visitCat)
561 
562  self.log.info("Found all good star observations in %.2f s" %
563  (time.time() - startTime))
564 
565  return fullCatalog
566 
def computeApproxPixelAreaFields(camera)
Definition: utilities.py:495

◆ 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 459 of file fgcmBuildStarsBase.py.

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

◆ 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 686 of file fgcmBuildStarsBase.py.

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

◆ 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 295 of file fgcmBuildStarsBase.py.

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

◆ runQuantum()

def lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask.runQuantum (   self,
  butlerQC,
  inputRefs,
  outputRefs 
)

Definition at line 230 of file fgcmBuildStarsTable.py.

230  def runQuantum(self, butlerQC, inputRefs, outputRefs):
231  inputRefDict = butlerQC.get(inputRefs)
232 
233  sourceTableRefs = inputRefDict['sourceTable_visit']
234 
235  self.log.info("Running with %d sourceTable_visit dataRefs",
236  len(sourceTableRefs))
237 
238  sourceTableDataRefDict = {sourceTableRef.dataId['visit']: sourceTableRef for
239  sourceTableRef in sourceTableRefs}
240 
241  if self.config.doReferenceMatches:
242  # Get the LUT dataRef
243  lutDataRef = inputRefDict['fgcmLookUpTable']
244 
245  # Prepare the refCat loader
246  refConfig = self.config.fgcmLoadReferenceCatalog.refObjLoader
247  refObjLoader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
248  for ref in inputRefs.refCat],
249  refCats=butlerQC.get(inputRefs.refCat),
250  config=refConfig,
251  log=self.log)
252  self.makeSubtask('fgcmLoadReferenceCatalog', refObjLoader=refObjLoader)
253  else:
254  lutDataRef = None
255 
256  # Compute aperture radius if necessary. This is useful to do now before
257  # any heave lifting has happened (fail early).
258  calibFluxApertureRadius = None
259  if self.config.doSubtractLocalBackground:
260  try:
261  calibFluxApertureRadius = computeApertureRadiusFromDataRef(sourceTableRefs[0],
262  self.config.instFluxField)
263  except RuntimeError as e:
264  raise RuntimeError("Could not determine aperture radius from %s. "
265  "Cannot use doSubtractLocalBackground." %
266  (self.config.instFluxField)) from e
267 
268  visitSummaryRefs = inputRefDict['visitSummary']
269  visitSummaryDataRefDict = {visitSummaryRef.dataId['visit']: visitSummaryRef for
270  visitSummaryRef in visitSummaryRefs}
271 
272  camera = inputRefDict['camera']
273  groupedDataRefs = self._groupDataRefs(sourceTableDataRefDict,
274  visitSummaryDataRefDict)
275 
276  if self.config.doModelErrorsWithBackground:
277  bkgRefs = inputRefDict['background']
278  bkgDataRefDict = {(bkgRef.dataId.byName()['visit'],
279  bkgRef.dataId.byName()['detector']): bkgRef for
280  bkgRef in bkgRefs}
281  else:
282  bkgDataRefDict = None
283 
284  # Gen3 does not currently allow "checkpoint" saving of datasets,
285  # so we need to have this all in one go.
286  visitCat = self.fgcmMakeVisitCatalog(camera, groupedDataRefs,
287  bkgDataRefDict=bkgDataRefDict,
288  visitCatDataRef=None,
289  inVisitCat=None)
290 
291  rad = calibFluxApertureRadius
292  # sourceSchemaDataRef = inputRefDict['sourceSchema']
293  fgcmStarObservationCat = self.fgcmMakeAllStarObservations(groupedDataRefs,
294  visitCat,
295  self.sourceSchema,
296  camera,
297  calibFluxApertureRadius=rad,
298  starObsDataRef=None,
299  visitCatDataRef=None,
300  inStarObsCat=None)
301 
302  butlerQC.put(visitCat, outputRefs.fgcmVisitCatalog)
303  butlerQC.put(fgcmStarObservationCat, outputRefs.fgcmStarObservations)
304 
305  fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat = self.fgcmMatchStars(visitCat,
306  fgcmStarObservationCat,
307  lutDataRef=lutDataRef)
308 
309  butlerQC.put(fgcmStarIdCat, outputRefs.fgcmStarIds)
310  butlerQC.put(fgcmStarIndicesCat, outputRefs.fgcmStarIndices)
311  if fgcmRefCat is not None:
312  butlerQC.put(fgcmRefCat, outputRefs.fgcmReferenceStars)
313 

Member Data Documentation

◆ canMultiprocess

bool lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask.canMultiprocess = False
static

Definition at line 223 of file fgcmBuildStarsTable.py.

◆ ConfigClass

lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask.ConfigClass = FgcmBuildStarsTableConfig
static

Definition at line 219 of file fgcmBuildStarsTable.py.

◆ RunnerClass

lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask.RunnerClass = FgcmBuildStarsRunner
static

Definition at line 220 of file fgcmBuildStarsTable.py.

◆ sourceSchema

lsst.fgcmcal.fgcmBuildStarsTable.FgcmBuildStarsTableTask.sourceSchema

Definition at line 228 of file fgcmBuildStarsTable.py.


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