21 """Base class for BuildStars using src tables or sourceTable_visit tables.
39 from lsst.utils.timer
import timeMethod
41 from .utilities
import computeApertureRadiusFromDataRef
42 from .fgcmLoadReferenceCatalog
import FgcmLoadReferenceCatalogTask
46 REFSTARS_FORMAT_VERSION = 1
48 __all__ = [
'FgcmBuildStarsConfigBase',
'FgcmBuildStarsRunner',
'FgcmBuildStarsBaseTask']
52 """Base config for FgcmBuildStars tasks"""
54 instFluxField = pexConfig.Field(
55 doc=(
"Faull name of the source instFlux field to use, including 'instFlux'. "
56 "The associated flag will be implicitly included in badFlags"),
58 default=
'slot_CalibFlux_instFlux',
60 minPerBand = pexConfig.Field(
61 doc=
"Minimum observations per band",
65 matchRadius = pexConfig.Field(
66 doc=
"Match radius (arcseconds)",
70 isolationRadius = pexConfig.Field(
71 doc=
"Isolation radius (arcseconds)",
75 densityCutNside = pexConfig.Field(
76 doc=
"Density cut healpix nside",
80 densityCutMaxPerPixel = pexConfig.Field(
81 doc=
"Density cut number of stars per pixel",
85 randomSeed = pexConfig.Field(
86 doc=
"Random seed for high density down-sampling.",
91 matchNside = pexConfig.Field(
92 doc=
"Healpix Nside for matching",
96 coarseNside = pexConfig.Field(
97 doc=
"Healpix coarse Nside for partitioning matches",
104 physicalFilterMap = pexConfig.DictField(
105 doc=
"Mapping from 'physicalFilter' to band.",
110 requiredBands = pexConfig.ListField(
111 doc=
"Bands required for each star",
115 primaryBands = pexConfig.ListField(
116 doc=(
"Bands for 'primary' star matches. "
117 "A star must be observed in one of these bands to be considered "
118 "as a calibration star."),
122 visitDataRefName = pexConfig.Field(
123 doc=
"dataRef name for the 'visit' field, usually 'visit'.",
127 ccdDataRefName = pexConfig.Field(
128 doc=
"dataRef name for the 'ccd' field, usually 'ccd' or 'detector'.",
132 doApplyWcsJacobian = pexConfig.Field(
133 doc=
"Apply the jacobian of the WCS to the star observations prior to fit?",
137 doModelErrorsWithBackground = pexConfig.Field(
138 doc=
"Model flux errors with background term?",
142 psfCandidateName = pexConfig.Field(
143 doc=
"Name of field with psf candidate flag for propagation",
145 default=
"calib_psf_candidate"
147 doSubtractLocalBackground = pexConfig.Field(
148 doc=(
"Subtract the local background before performing calibration? "
149 "This is only supported for circular aperture calibration fluxes."),
153 localBackgroundFluxField = pexConfig.Field(
154 doc=
"Full name of the local background instFlux field to use.",
156 default=
'base_LocalBackground_instFlux'
158 sourceSelector = sourceSelectorRegistry.makeField(
159 doc=
"How to select sources",
162 apertureInnerInstFluxField = pexConfig.Field(
163 doc=(
"Full name of instFlux field that contains inner aperture "
164 "flux for aperture correction proxy"),
166 default=
'base_CircularApertureFlux_12_0_instFlux'
168 apertureOuterInstFluxField = pexConfig.Field(
169 doc=(
"Full name of instFlux field that contains outer aperture "
170 "flux for aperture correction proxy"),
172 default=
'base_CircularApertureFlux_17_0_instFlux'
174 doReferenceMatches = pexConfig.Field(
175 doc=
"Match reference catalog as additional constraint on calibration",
179 fgcmLoadReferenceCatalog = pexConfig.ConfigurableField(
180 target=FgcmLoadReferenceCatalogTask,
181 doc=
"FGCM reference object loader",
183 nVisitsPerCheckpoint = pexConfig.Field(
184 doc=
"Number of visits read between checkpoints",
191 sourceSelector.setDefaults()
193 sourceSelector.doFlags =
True
194 sourceSelector.doUnresolved =
True
195 sourceSelector.doSignalToNoise =
True
196 sourceSelector.doIsolated =
True
198 sourceSelector.signalToNoise.minimum = 10.0
199 sourceSelector.signalToNoise.maximum = 1000.0
203 sourceSelector.unresolved.maximum = 0.5
207 """Subclass of TaskRunner for FgcmBuildStars tasks
209 fgcmBuildStarsTask.run() and fgcmBuildStarsTableTask.run() take a number of
210 arguments, one of which is the butler (for persistence and mapper data),
211 and a list of dataRefs extracted from the command line. Note that FGCM
212 runs on a large set of dataRefs, and not on single dataRef/tract/patch.
213 This class transforms the process arguments generated by the ArgumentParser
214 into the arguments expected by FgcmBuildStarsTask.run(). This runner does
215 not use any parallelization.
220 Return a list with one element: a tuple with the butler and
224 return [(parsedCmd.butler, parsedCmd.id.refList)]
230 args: `tuple` with (butler, dataRefList)
234 exitStatus: `list` with `lsst.pipe.base.Struct`
235 exitStatus (0: success; 1: failure)
237 butler, dataRefList = args
239 task = self.TaskClass(config=self.config, log=self.log)
243 task.runDataRef(butler, dataRefList)
246 task.runDataRef(butler, dataRefList)
247 except Exception
as e:
249 task.log.fatal(
"Failed: %s" % e)
250 if not isinstance(e, pipeBase.TaskError):
251 traceback.print_exc(file=sys.stderr)
253 task.writeMetadata(butler)
256 return [pipeBase.Struct(exitStatus=exitStatus)]
260 Run the task, with no multiprocessing
264 parsedCmd: `lsst.pipe.base.ArgumentParser` parsed command line
269 if self.precall(parsedCmd):
271 resultList = self(targetList[0])
278 Base task to build stars for FGCM global calibration
282 butler : `lsst.daf.persistence.Butler`
284 def __init__(self, initInputs=None, butler=None, **kwargs):
287 self.makeSubtask(
"sourceSelector")
289 self.sourceSelector.log.setLevel(self.sourceSelector.log.WARN)
292 def _getMetadataName(self):
298 Cross-match and make star list for FGCM Input
302 butler: `lsst.daf.persistence.Butler`
303 dataRefs: `list` of `lsst.daf.persistence.ButlerDataRef`
304 Source data references for the input visits.
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.
312 datasetType = dataRefs[0].butlerSubset.datasetType
313 self.log.
info(
"Running with %d %s dataRefs", len(dataRefs), datasetType)
315 if self.config.doReferenceMatches:
316 self.makeSubtask(
"fgcmLoadReferenceCatalog", butler=butler)
318 if not butler.datasetExists(
'fgcmLookUpTable'):
319 raise RuntimeError(
"Must have fgcmLookUpTable if using config.doReferenceMatches")
322 calibFluxApertureRadius =
None
323 if self.config.doSubtractLocalBackground:
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
332 camera = butler.get(
'camera')
340 visitCatDataRef = butler.dataRef(
'fgcmVisitCatalog')
341 filename = visitCatDataRef.get(
'fgcmVisitCatalog_filename')[0]
342 if os.path.exists(filename):
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.")
352 visitCatDataRef=visitCatDataRef,
353 inVisitCat=inVisitCat)
356 visitCatDataRef.put(visitCat)
358 starObsDataRef = butler.dataRef(
'fgcmStarObservations')
359 filename = starObsDataRef.get(
'fgcmStarObservations_filename')[0]
360 if os.path.exists(filename):
361 inStarObsCat = starObsDataRef.get()
365 rad = calibFluxApertureRadius
366 sourceSchemaDataRef = butler.dataRef(
'src_schema')
367 sourceSchema = sourceSchemaDataRef.get(
'src_schema', immediate=
True).schema
372 calibFluxApertureRadius=rad,
373 starObsDataRef=starObsDataRef,
374 visitCatDataRef=visitCatDataRef,
375 inStarObsCat=inStarObsCat)
376 visitCatDataRef.put(visitCat)
377 starObsDataRef.put(fgcmStarObservationCat)
380 if self.config.doReferenceMatches:
381 lutDataRef = butler.dataRef(
'fgcmLookUpTable')
384 fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat = self.
fgcmMatchStarsfgcmMatchStars(visitCat,
385 fgcmStarObservationCat,
386 lutDataRef=lutDataRef)
389 butler.put(fgcmStarIdCat,
'fgcmStarIds')
390 butler.put(fgcmStarIndicesCat,
'fgcmStarIndices')
391 if fgcmRefCat
is not None:
392 butler.put(fgcmRefCat,
'fgcmReferenceStars')
395 def _findAndGroupDataRefsGen2(self, butler, camera, dataRefs):
397 Find and group dataRefs (by visit); Gen2 only.
401 butler : `lsst.daf.persistence.Butler`
403 camera : `lsst.afw.cameraGeom.Camera`
404 Camera from the butler.
405 dataRefs : `list` of `lsst.daf.persistence.ButlerDataRef`
406 Data references for the input visits.
410 groupedDataRefs : `dict` [`int`, `list`]
411 Dictionary with sorted visit keys, and `list`s of
412 `lsst.daf.persistence.ButlerDataRef`
414 raise NotImplementedError(
"_findAndGroupDataRefsGen2 not implemented.")
420 calibFluxApertureRadius=None,
421 visitCatDataRef=None,
425 Compile all good star observations from visits in visitCat. Checkpoint files
426 will be stored if both visitCatDataRef and starObsDataRef are not None.
430 groupedDataRefs : `dict` of `list`s
431 Lists of `~lsst.daf.persistence.ButlerDataRef` or
432 `~lsst.daf.butler.DeferredDatasetHandle`, grouped by visit.
433 visitCat : `~afw.table.BaseCatalog`
434 Catalog with visit data for FGCM
435 sourceSchema : `~lsst.afw.table.Schema`
436 Schema for the input src catalogs.
437 camera : `~lsst.afw.cameraGeom.Camera`
438 calibFluxApertureRadius : `float`, optional
439 Aperture radius for calibration flux.
440 visitCatDataRef : `~lsst.daf.persistence.ButlerDataRef`, optional
441 Dataref to write visitCat for checkpoints
442 starObsDataRef : `~lsst.daf.persistence.ButlerDataRef`, optional
443 Dataref to write the star observation catalog for checkpoints.
444 inStarObsCat : `~afw.table.BaseCatalog`
445 Input observation catalog. If this is incomplete, observations
446 will be appended from when it was cut off.
450 fgcmStarObservations : `afw.table.BaseCatalog`
451 Full catalog of good observations.
455 RuntimeError: Raised if doSubtractLocalBackground is True and
456 calibFluxApertureRadius is not set.
458 raise NotImplementedError(
"fgcmMakeAllStarObservations not implemented.")
461 visitCatDataRef=None, inVisitCat=None):
463 Make a visit catalog with all the keys from each visit
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
481 visitCat: `afw.table.BaseCatalog`
484 self.log.
info(
"Assembling visitCatalog from %d %ss" %
485 (len(groupedDataRefs), self.config.visitDataRefName))
489 if inVisitCat
is None:
493 visitCat.reserve(len(groupedDataRefs))
494 visitCat.resize(len(groupedDataRefs))
496 visitCat[
'visit'] =
list(groupedDataRefs.keys())
498 visitCat[
'sources_read'] =
False
500 visitCat = inVisitCat
505 bkgDataRefDict=bkgDataRefDict,
506 visitCatDataRef=visitCatDataRef)
510 def _fillVisitCatalog(self, visitCat, groupedDataRefs, bkgDataRefDict=None,
511 visitCatDataRef=None):
513 Fill the visit catalog with visit metadata
517 visitCat : `afw.table.BaseCatalog`
518 Visit catalog. See _makeFgcmVisitSchema() for schema definition.
519 groupedDataRefs : `dict`
520 Dictionary with visit keys, and `list`s of
521 `lsst.daf.persistence.ButlerDataRef` or
522 `lsst.daf.butler.DeferredDatasetHandle`
523 visitCatDataRef : `lsst.daf.persistence.ButlerDataRef`, optional
524 Dataref to write ``visitCat`` for checkpoints. Gen2 only.
525 bkgDataRefDict : `dict`, optional
526 Dictionary of Gen3 `lsst.daf.butler.DeferredDatasetHandle`
531 for i, visit
in enumerate(groupedDataRefs):
538 if visitCat[
'used'][i]:
541 if (i % self.config.nVisitsPerCheckpoint) == 0:
542 self.log.
info(
"Retrieving metadata for %s %d (%d/%d)" %
543 (self.config.visitDataRefName, visit, i, len(groupedDataRefs)))
545 if visitCatDataRef
is not None:
546 visitCatDataRef.put(visitCat)
548 dataRef = groupedDataRefs[visit][0]
552 exp = dataRef.get(datasetType=
'calexp_sub', bbox=bbox)
553 visitInfo = exp.getInfo().getVisitInfo()
554 label = dataRef.get(datasetType=
'calexp_filterLabel')
555 physicalFilter = label.physicalLabel
557 bbox = dataRef.get(datasetType=
'calexp_bbox')
558 psfSigma = psf.computeShape(bbox.getCenter()).getDeterminantRadius()
561 summary = dataRef.get()
563 summaryRow = summary.find(self.config.referenceCCD)
564 if summaryRow
is None:
566 summaryRow = summary[0]
568 summaryDetector = summaryRow[
'id']
569 visitInfo = summaryRow.getVisitInfo()
570 physicalFilter = summaryRow[
'physical_filter']
572 goodSigma, = np.where(summary[
'psfSigma'] > 0)
573 if goodSigma.size > 2:
574 psfSigma = np.median(summary[
'psfSigma'][goodSigma])
576 psfSigma = np.mean(summary[
'psfSigma'][goodSigma])
582 rec[
'physicalFilter'] = physicalFilter
586 radec = visitInfo.getBoresightRaDec()
587 rec[
'telra'] = radec.getRa().asDegrees()
588 rec[
'teldec'] = radec.getDec().asDegrees()
589 rec[
'telha'] = visitInfo.getBoresightHourAngle().asDegrees()
590 rec[
'telrot'] = visitInfo.getBoresightRotAngle().asDegrees()
591 rec[
'mjd'] = visitInfo.getDate().get(system=DateTime.MJD)
592 rec[
'exptime'] = visitInfo.getExposureTime()
595 rec[
'pmb'] = visitInfo.getWeather().getAirPressure() / 100
599 rec[
'scaling'][:] = 1.0
601 rec[
'deltaAper'] = 0.0
602 rec[
'psfSigma'] = psfSigma
604 if self.config.doModelErrorsWithBackground:
608 det = dataRef.dataId[self.config.ccdDataRefName]
609 if dataRef.datasetExists(datasetType=
'calexpBackground'):
610 bgList = dataRef.get(datasetType=
'calexpBackground')
616 bkgRef = bkgDataRefDict[(visit, summaryDetector)]
617 bgList = bkgRef.get()
623 bgStats = (bg[0].getStatsImage().getImage().array
625 rec[
'skyBackground'] = sum(np.median(bg[np.isfinite(bg)])
for bg
in bgStats)
627 self.log.
warning(
'Sky background not found for visit %d / ccd %d' %
629 rec[
'skyBackground'] = -1.0
631 rec[
'skyBackground'] = -1.0
635 def _makeSourceMapper(self, sourceSchema):
637 Make a schema mapper for fgcm sources
641 sourceSchema: `afwTable.Schema`
642 Default source schema from the butler
646 sourceMapper: `afwTable.schemaMapper`
647 Mapper to the FGCM source schema
654 sourceMapper.addMapping(sourceSchema[
'coord_ra'].asKey(),
'ra')
655 sourceMapper.addMapping(sourceSchema[
'coord_dec'].asKey(),
'dec')
656 sourceMapper.addMapping(sourceSchema[
'slot_Centroid_x'].asKey(),
'x')
657 sourceMapper.addMapping(sourceSchema[
'slot_Centroid_y'].asKey(),
'y')
663 sourceMapper.addMapping(sourceSchema[self.config.psfCandidateName].asKey(),
666 sourceMapper.editOutputSchema().addField(
667 "psf_candidate", type=
'Flag',
668 doc=(
"Flag set if the source was a candidate for PSF determination, "
669 "as determined by the star selector."))
672 sourceMapper.editOutputSchema().addField(
673 "visit", type=np.int32, doc=
"Visit number")
674 sourceMapper.editOutputSchema().addField(
675 "ccd", type=np.int32, doc=
"CCD number")
676 sourceMapper.editOutputSchema().addField(
677 "instMag", type=np.float32, doc=
"Instrumental magnitude")
678 sourceMapper.editOutputSchema().addField(
679 "instMagErr", type=np.float32, doc=
"Instrumental magnitude error")
680 sourceMapper.editOutputSchema().addField(
681 "jacobian", type=np.float32, doc=
"Relative pixel scale from wcs jacobian")
682 sourceMapper.editOutputSchema().addField(
683 "deltaMagBkg", type=np.float32, doc=
"Change in magnitude due to local background offset")
689 Use FGCM code to match observations into unique stars.
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).
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.
713 visitFilterNames = np.zeros(len(visitCat), dtype=
'a30')
714 for i
in range(len(visitCat)):
715 visitFilterNames[i] = visitCat[i][
'physicalFilter']
718 visitIndex = np.searchsorted(visitCat[
'visit'],
721 obsFilterNames = visitFilterNames[visitIndex]
723 if self.config.doReferenceMatches:
725 lutCat = lutDataRef.get()
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'])}
739 self.log.
info(
"Using the following reference filters: %s" %
740 (
', '.join(referenceFilterNames)))
744 referenceFilterNames = []
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}
762 fgcmMakeStars = fgcm.FgcmMakeStars(starConfig)
770 conv = obsCat[0][
'ra'].asDegrees() / float(obsCat[0][
'ra'])
771 fgcmMakeStars.makePrimaryStars(obsCat[
'ra'] * conv,
772 obsCat[
'dec'] * conv,
773 filterNameArray=obsFilterNames,
777 fgcmMakeStars.makeMatchedStars(obsCat[
'ra'] * conv,
778 obsCat[
'dec'] * conv,
781 if self.config.doReferenceMatches:
782 fgcmMakeStars.makeReferenceMatches(self.fgcmLoadReferenceCatalog)
790 fgcmStarIdCat.reserve(fgcmMakeStars.objIndexCat.size)
791 for i
in range(fgcmMakeStars.objIndexCat.size):
792 fgcmStarIdCat.addNew()
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']
804 fgcmStarIndicesCat.reserve(fgcmMakeStars.obsIndexCat.size)
805 for i
in range(fgcmMakeStars.obsIndexCat.size):
806 fgcmStarIndicesCat.addNew()
808 fgcmStarIndicesCat[
'obsIndex'][:] = fgcmMakeStars.obsIndexCat[
'obsindex']
810 if self.config.doReferenceMatches:
814 fgcmRefCat.reserve(fgcmMakeStars.referenceCat.size)
816 for i
in range(fgcmMakeStars.referenceCat.size):
819 fgcmRefCat[
'fgcm_id'][:] = fgcmMakeStars.referenceCat[
'fgcm_id']
820 fgcmRefCat[
'refMag'][:, :] = fgcmMakeStars.referenceCat[
'refMag']
821 fgcmRefCat[
'refMagErr'][:, :] = fgcmMakeStars.referenceCat[
'refMagErr']
824 md.set(
"REFSTARS_FORMAT_VERSION", REFSTARS_FORMAT_VERSION)
825 md.set(
"FILTERNAMES", referenceFilterNames)
826 fgcmRefCat.setMetadata(md)
831 return fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat
833 def _makeFgcmVisitSchema(self, nCcd):
835 Make a schema for an fgcmVisitCatalog
840 Number of CCDs in the camera
844 schema: `afwTable.Schema`
848 schema.addField(
'visit', type=np.int32, doc=
"Visit number")
849 schema.addField(
'physicalFilter', type=str, size=30, doc=
"Physical filter")
850 schema.addField(
'telra', type=np.float64, doc=
"Pointing RA (deg)")
851 schema.addField(
'teldec', type=np.float64, doc=
"Pointing Dec (deg)")
852 schema.addField(
'telha', type=np.float64, doc=
"Pointing Hour Angle (deg)")
853 schema.addField(
'telrot', type=np.float64, doc=
"Camera rotation (deg)")
854 schema.addField(
'mjd', type=np.float64, doc=
"MJD of visit")
855 schema.addField(
'exptime', type=np.float32, doc=
"Exposure time")
856 schema.addField(
'pmb', type=np.float32, doc=
"Pressure (millibar)")
857 schema.addField(
'psfSigma', type=np.float32, doc=
"PSF sigma (reference CCD)")
858 schema.addField(
'deltaAper', type=np.float32, doc=
"Delta-aperture")
859 schema.addField(
'skyBackground', type=np.float32, doc=
"Sky background (ADU) (reference CCD)")
861 schema.addField(
'deepFlag', type=np.int32, doc=
"Deep observation")
862 schema.addField(
'scaling', type=
'ArrayD', doc=
"Scaling applied due to flat adjustment",
864 schema.addField(
'used', type=np.int32, doc=
"This visit has been ingested.")
865 schema.addField(
'sources_read', type=
'Flag', doc=
"This visit had sources read.")
869 def _makeFgcmObjSchema(self):
871 Make a schema for the objIndexCat from fgcmMakeStars
875 schema: `afwTable.Schema`
879 objSchema.addField(
'fgcm_id', type=np.int32, doc=
'FGCM Unique ID')
881 objSchema.addField(
'ra', type=np.float64, doc=
'Mean object RA (deg)')
882 objSchema.addField(
'dec', type=np.float64, doc=
'Mean object Dec (deg)')
883 objSchema.addField(
'obsArrIndex', type=np.int32,
884 doc=
'Index in obsIndexTable for first observation')
885 objSchema.addField(
'nObs', type=np.int32, doc=
'Total number of observations')
889 def _makeFgcmObsSchema(self):
891 Make a schema for the obsIndexCat from fgcmMakeStars
895 schema: `afwTable.Schema`
899 obsSchema.addField(
'obsIndex', type=np.int32, doc=
'Index in observation table')
903 def _makeFgcmRefSchema(self, nReferenceBands):
905 Make a schema for the referenceCat from fgcmMakeStars
909 nReferenceBands: `int`
910 Number of reference bands
914 schema: `afwTable.Schema`
918 refSchema.addField(
'fgcm_id', type=np.int32, doc=
'FGCM Unique ID')
919 refSchema.addField(
'refMag', type=
'ArrayF', doc=
'Reference magnitude array (AB)',
920 size=nReferenceBands)
921 refSchema.addField(
'refMagErr', type=
'ArrayF', doc=
'Reference magnitude error array',
922 size=nReferenceBands)
926 def _getReferenceFilterNames(self, visitCat, stdFilterDict, stdLambdaDict):
928 Get the reference filter names, in wavelength order, from the visitCat and
929 information from the look-up-table.
933 visitCat: `afw.table.BaseCatalog`
934 Catalog with visit data for FGCM
935 stdFilterDict: `dict`
936 Mapping of filterName to stdFilterName from LUT
937 stdLambdaDict: `dict`
938 Mapping of stdFilterName to stdLambda from LUT
942 referenceFilterNames: `list`
943 Wavelength-ordered list of reference filter names
947 filterNames = np.unique(visitCat.asAstropy()[
'physicalFilter'])
950 stdFilterNames = {stdFilterDict[filterName]
for filterName
in filterNames}
953 referenceFilterNames = sorted(stdFilterNames, key=stdLambdaDict.get)
955 return referenceFilterNames
Defines the fields and offsets for a table.
A mapping between the keys of two Schemas, used to copy data between them.
Class for storing ordered metadata with comments.
def fgcmMatchStars(self, visitCat, obsCat, lutDataRef=None)
def _makeFgcmVisitSchema(self, nCcd)
def _getReferenceFilterNames(self, visitCat, stdFilterDict, stdLambdaDict)
def runDataRef(self, butler, dataRefs)
def _makeFgcmObjSchema(self)
def _fillVisitCatalog(self, visitCat, groupedDataRefs, bkgDataRefDict=None, visitCatDataRef=None)
def fgcmMakeAllStarObservations(self, groupedDataRefs, visitCat, sourceSchema, camera, calibFluxApertureRadius=None, visitCatDataRef=None, starObsDataRef=None, inStarObsCat=None)
def __init__(self, initInputs=None, butler=None, **kwargs)
def _makeFgcmObsSchema(self)
def fgcmMakeVisitCatalog(self, camera, groupedDataRefs, bkgDataRefDict=None, visitCatDataRef=None, inVisitCat=None)
def _findAndGroupDataRefsGen2(self, butler, camera, dataRefs)
def _makeFgcmRefSchema(self, nReferenceBands)
def getTargetList(parsedCmd)
An integer coordinate rectangle.
daf::base::PropertyList * list
def computeApertureRadiusFromDataRef(dataRef, fluxField)