21 """Base class for BuildStars using src tables or sourceTable_visit tables.
40 from .utilities
import computeApertureRadiusFromDataRef
41 from .fgcmLoadReferenceCatalog
import FgcmLoadReferenceCatalogTask
45 REFSTARS_FORMAT_VERSION = 1
47 __all__ = [
'FgcmBuildStarsConfigBase',
'FgcmBuildStarsRunner',
'FgcmBuildStarsBaseTask']
51 """Base config for FgcmBuildStars tasks"""
53 instFluxField = pexConfig.Field(
54 doc=(
"Faull name of the source instFlux field to use, including 'instFlux'. "
55 "The associated flag will be implicitly included in badFlags"),
57 default=
'slot_CalibFlux_instFlux',
59 minPerBand = pexConfig.Field(
60 doc=
"Minimum observations per band",
64 matchRadius = pexConfig.Field(
65 doc=
"Match radius (arcseconds)",
69 isolationRadius = pexConfig.Field(
70 doc=
"Isolation radius (arcseconds)",
74 densityCutNside = pexConfig.Field(
75 doc=
"Density cut healpix nside",
79 densityCutMaxPerPixel = pexConfig.Field(
80 doc=
"Density cut number of stars per pixel",
84 randomSeed = pexConfig.Field(
85 doc=
"Random seed for high density down-sampling.",
90 matchNside = pexConfig.Field(
91 doc=
"Healpix Nside for matching",
95 coarseNside = pexConfig.Field(
96 doc=
"Healpix coarse Nside for partitioning matches",
103 physicalFilterMap = pexConfig.DictField(
104 doc=
"Mapping from 'physicalFilter' to band.",
109 requiredBands = pexConfig.ListField(
110 doc=
"Bands required for each star",
114 primaryBands = pexConfig.ListField(
115 doc=(
"Bands for 'primary' star matches. "
116 "A star must be observed in one of these bands to be considered "
117 "as a calibration star."),
121 visitDataRefName = pexConfig.Field(
122 doc=
"dataRef name for the 'visit' field, usually 'visit'.",
126 ccdDataRefName = pexConfig.Field(
127 doc=
"dataRef name for the 'ccd' field, usually 'ccd' or 'detector'.",
131 doApplyWcsJacobian = pexConfig.Field(
132 doc=
"Apply the jacobian of the WCS to the star observations prior to fit?",
136 doModelErrorsWithBackground = pexConfig.Field(
137 doc=
"Model flux errors with background term?",
141 psfCandidateName = pexConfig.Field(
142 doc=
"Name of field with psf candidate flag for propagation",
144 default=
"calib_psf_candidate"
146 doSubtractLocalBackground = pexConfig.Field(
147 doc=(
"Subtract the local background before performing calibration? "
148 "This is only supported for circular aperture calibration fluxes."),
152 localBackgroundFluxField = pexConfig.Field(
153 doc=
"Full name of the local background instFlux field to use.",
155 default=
'base_LocalBackground_instFlux'
157 sourceSelector = sourceSelectorRegistry.makeField(
158 doc=
"How to select sources",
161 apertureInnerInstFluxField = pexConfig.Field(
162 doc=(
"Full name of instFlux field that contains inner aperture "
163 "flux for aperture correction proxy"),
165 default=
'base_CircularApertureFlux_12_0_instFlux'
167 apertureOuterInstFluxField = pexConfig.Field(
168 doc=(
"Full name of instFlux field that contains outer aperture "
169 "flux for aperture correction proxy"),
171 default=
'base_CircularApertureFlux_17_0_instFlux'
173 doReferenceMatches = pexConfig.Field(
174 doc=
"Match reference catalog as additional constraint on calibration",
178 fgcmLoadReferenceCatalog = pexConfig.ConfigurableField(
179 target=FgcmLoadReferenceCatalogTask,
180 doc=
"FGCM reference object loader",
182 nVisitsPerCheckpoint = pexConfig.Field(
183 doc=
"Number of visits read between checkpoints",
190 sourceSelector.setDefaults()
192 sourceSelector.doFlags =
True
193 sourceSelector.doUnresolved =
True
194 sourceSelector.doSignalToNoise =
True
195 sourceSelector.doIsolated =
True
197 sourceSelector.signalToNoise.minimum = 10.0
198 sourceSelector.signalToNoise.maximum = 1000.0
202 sourceSelector.unresolved.maximum = 0.5
206 """Subclass of TaskRunner for FgcmBuildStars tasks
208 fgcmBuildStarsTask.run() and fgcmBuildStarsTableTask.run() take a number of
209 arguments, one of which is the butler (for persistence and mapper data),
210 and a list of dataRefs extracted from the command line. Note that FGCM
211 runs on a large set of dataRefs, and not on single dataRef/tract/patch.
212 This class transforms the process arguments generated by the ArgumentParser
213 into the arguments expected by FgcmBuildStarsTask.run(). This runner does
214 not use any parallelization.
219 Return a list with one element: a tuple with the butler and
223 return [(parsedCmd.butler, parsedCmd.id.refList)]
229 args: `tuple` with (butler, dataRefList)
233 exitStatus: `list` with `lsst.pipe.base.Struct`
234 exitStatus (0: success; 1: failure)
236 butler, dataRefList = args
238 task = self.TaskClass(config=self.config, log=self.log)
242 task.runDataRef(butler, dataRefList)
245 task.runDataRef(butler, dataRefList)
246 except Exception
as e:
248 task.log.fatal(
"Failed: %s" % e)
249 if not isinstance(e, pipeBase.TaskError):
250 traceback.print_exc(file=sys.stderr)
252 task.writeMetadata(butler)
255 return [pipeBase.Struct(exitStatus=exitStatus)]
259 Run the task, with no multiprocessing
263 parsedCmd: `lsst.pipe.base.ArgumentParser` parsed command line
268 if self.precall(parsedCmd):
270 resultList = self(targetList[0])
277 Base task to build stars for FGCM global calibration
281 butler : `lsst.daf.persistence.Butler`
283 def __init__(self, initInputs=None, butler=None, **kwargs):
286 self.makeSubtask(
"sourceSelector")
288 self.sourceSelector.log.setLevel(self.sourceSelector.log.WARN)
291 def _getMetadataName(self):
297 Cross-match and make star list for FGCM Input
301 butler: `lsst.daf.persistence.Butler`
302 dataRefs: `list` of `lsst.daf.persistence.ButlerDataRef`
303 Source data references for the input visits.
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.
311 datasetType = dataRefs[0].butlerSubset.datasetType
312 self.log.
info(
"Running with %d %s dataRefs", len(dataRefs), datasetType)
314 if self.config.doReferenceMatches:
315 self.makeSubtask(
"fgcmLoadReferenceCatalog", butler=butler)
317 if not butler.datasetExists(
'fgcmLookUpTable'):
318 raise RuntimeError(
"Must have fgcmLookUpTable if using config.doReferenceMatches")
321 calibFluxApertureRadius =
None
322 if self.config.doSubtractLocalBackground:
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
331 camera = butler.get(
'camera')
339 visitCatDataRef = butler.dataRef(
'fgcmVisitCatalog')
340 filename = visitCatDataRef.get(
'fgcmVisitCatalog_filename')[0]
341 if os.path.exists(filename):
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.")
351 visitCatDataRef=visitCatDataRef,
352 inVisitCat=inVisitCat)
355 visitCatDataRef.put(visitCat)
357 starObsDataRef = butler.dataRef(
'fgcmStarObservations')
358 filename = starObsDataRef.get(
'fgcmStarObservations_filename')[0]
359 if os.path.exists(filename):
360 inStarObsCat = starObsDataRef.get()
364 rad = calibFluxApertureRadius
365 sourceSchemaDataRef = butler.dataRef(
'src_schema')
366 sourceSchema = sourceSchemaDataRef.get(
'src_schema', immediate=
True).schema
371 calibFluxApertureRadius=rad,
372 starObsDataRef=starObsDataRef,
373 visitCatDataRef=visitCatDataRef,
374 inStarObsCat=inStarObsCat)
375 visitCatDataRef.put(visitCat)
376 starObsDataRef.put(fgcmStarObservationCat)
379 if self.config.doReferenceMatches:
380 lutDataRef = butler.dataRef(
'fgcmLookUpTable')
383 fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat = self.
fgcmMatchStarsfgcmMatchStars(visitCat,
384 fgcmStarObservationCat,
385 lutDataRef=lutDataRef)
388 butler.put(fgcmStarIdCat,
'fgcmStarIds')
389 butler.put(fgcmStarIndicesCat,
'fgcmStarIndices')
390 if fgcmRefCat
is not None:
391 butler.put(fgcmRefCat,
'fgcmReferenceStars')
394 def _findAndGroupDataRefsGen2(self, butler, camera, dataRefs):
396 Find and group dataRefs (by visit); Gen2 only.
400 butler : `lsst.daf.persistence.Butler`
402 camera : `lsst.afw.cameraGeom.Camera`
403 Camera from the butler.
404 dataRefs : `list` of `lsst.daf.persistence.ButlerDataRef`
405 Data references for the input visits.
409 groupedDataRefs : `dict` [`int`, `list`]
410 Dictionary with sorted visit keys, and `list`s of
411 `lsst.daf.persistence.ButlerDataRef`
413 raise NotImplementedError(
"_findAndGroupDataRefsGen2 not implemented.")
419 calibFluxApertureRadius=None,
420 visitCatDataRef=None,
424 Compile all good star observations from visits in visitCat. Checkpoint files
425 will be stored if both visitCatDataRef and starObsDataRef are not None.
429 groupedDataRefs : `dict` of `list`s
430 Lists of `~lsst.daf.persistence.ButlerDataRef` or
431 `~lsst.daf.butler.DeferredDatasetHandle`, grouped by visit.
432 visitCat : `~afw.table.BaseCatalog`
433 Catalog with visit data for FGCM
434 sourceSchema : `~lsst.afw.table.Schema`
435 Schema for the input src catalogs.
436 camera : `~lsst.afw.cameraGeom.Camera`
437 calibFluxApertureRadius : `float`, optional
438 Aperture radius for calibration flux.
439 visitCatDataRef : `~lsst.daf.persistence.ButlerDataRef`, optional
440 Dataref to write visitCat for checkpoints
441 starObsDataRef : `~lsst.daf.persistence.ButlerDataRef`, optional
442 Dataref to write the star observation catalog for checkpoints.
443 inStarObsCat : `~afw.table.BaseCatalog`
444 Input observation catalog. If this is incomplete, observations
445 will be appended from when it was cut off.
449 fgcmStarObservations : `afw.table.BaseCatalog`
450 Full catalog of good observations.
454 RuntimeError: Raised if doSubtractLocalBackground is True and
455 calibFluxApertureRadius is not set.
457 raise NotImplementedError(
"fgcmMakeAllStarObservations not implemented.")
460 visitCatDataRef=None, inVisitCat=None):
462 Make a visit catalog with all the keys from each visit
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
480 visitCat: `afw.table.BaseCatalog`
483 self.log.
info(
"Assembling visitCatalog from %d %ss" %
484 (len(groupedDataRefs), self.config.visitDataRefName))
488 if inVisitCat
is None:
492 visitCat.reserve(len(groupedDataRefs))
493 visitCat.resize(len(groupedDataRefs))
495 visitCat[
'visit'] =
list(groupedDataRefs.keys())
497 visitCat[
'sources_read'] =
False
499 visitCat = inVisitCat
504 bkgDataRefDict=bkgDataRefDict,
505 visitCatDataRef=visitCatDataRef)
509 def _fillVisitCatalog(self, visitCat, groupedDataRefs, bkgDataRefDict=None,
510 visitCatDataRef=None):
512 Fill the visit catalog with visit metadata
516 visitCat : `afw.table.BaseCatalog`
517 Visit catalog. See _makeFgcmVisitSchema() for schema definition.
518 groupedDataRefs : `dict`
519 Dictionary with visit keys, and `list`s of
520 `lsst.daf.persistence.ButlerDataRef` or
521 `lsst.daf.butler.DeferredDatasetHandle`
522 visitCatDataRef : `lsst.daf.persistence.ButlerDataRef`, optional
523 Dataref to write ``visitCat`` for checkpoints. Gen2 only.
524 bkgDataRefDict : `dict`, optional
525 Dictionary of Gen3 `lsst.daf.butler.DeferredDatasetHandle`
530 for i, visit
in enumerate(groupedDataRefs):
537 if visitCat[
'used'][i]:
540 if (i % self.config.nVisitsPerCheckpoint) == 0:
541 self.log.
info(
"Retrieving metadata for %s %d (%d/%d)" %
542 (self.config.visitDataRefName, visit, i, len(groupedDataRefs)))
544 if visitCatDataRef
is not None:
545 visitCatDataRef.put(visitCat)
547 dataRef = groupedDataRefs[visit][0]
551 exp = dataRef.get(datasetType=
'calexp_sub', bbox=bbox)
552 visitInfo = exp.getInfo().getVisitInfo()
553 label = dataRef.get(datasetType=
'calexp_filterLabel')
554 physicalFilter = label.physicalLabel
556 bbox = dataRef.get(datasetType=
'calexp_bbox')
557 psfSigma = psf.computeShape(bbox.getCenter()).getDeterminantRadius()
560 summary = dataRef.get()
562 summaryRow = summary.find(self.config.referenceCCD)
563 if summaryRow
is None:
565 summaryRow = summary[0]
567 summaryDetector = summaryRow[
'id']
568 visitInfo = summaryRow.getVisitInfo()
569 physicalFilter = summaryRow[
'physical_filter']
571 goodSigma, = np.where(summary[
'psfSigma'] > 0)
572 if goodSigma.size > 2:
573 psfSigma = np.median(summary[
'psfSigma'][goodSigma])
575 psfSigma = np.mean(summary[
'psfSigma'][goodSigma])
581 rec[
'physicalFilter'] = physicalFilter
585 radec = visitInfo.getBoresightRaDec()
586 rec[
'telra'] = radec.getRa().asDegrees()
587 rec[
'teldec'] = radec.getDec().asDegrees()
588 rec[
'telha'] = visitInfo.getBoresightHourAngle().asDegrees()
589 rec[
'telrot'] = visitInfo.getBoresightRotAngle().asDegrees()
590 rec[
'mjd'] = visitInfo.getDate().get(system=DateTime.MJD)
591 rec[
'exptime'] = visitInfo.getExposureTime()
594 rec[
'pmb'] = visitInfo.getWeather().getAirPressure() / 100
598 rec[
'scaling'][:] = 1.0
600 rec[
'deltaAper'] = 0.0
601 rec[
'psfSigma'] = psfSigma
603 if self.config.doModelErrorsWithBackground:
607 det = dataRef.dataId[self.config.ccdDataRefName]
608 if dataRef.datasetExists(datasetType=
'calexpBackground'):
609 bgList = dataRef.get(datasetType=
'calexpBackground')
615 bkgRef = bkgDataRefDict[(visit, summaryDetector)]
616 bgList = bkgRef.get()
622 bgStats = (bg[0].getStatsImage().getImage().array
624 rec[
'skyBackground'] = sum(np.median(bg[np.isfinite(bg)])
for bg
in bgStats)
626 self.log.
warning(
'Sky background not found for visit %d / ccd %d' %
628 rec[
'skyBackground'] = -1.0
630 rec[
'skyBackground'] = -1.0
634 def _makeSourceMapper(self, sourceSchema):
636 Make a schema mapper for fgcm sources
640 sourceSchema: `afwTable.Schema`
641 Default source schema from the butler
645 sourceMapper: `afwTable.schemaMapper`
646 Mapper to the FGCM source schema
653 sourceMapper.addMapping(sourceSchema[
'coord_ra'].asKey(),
'ra')
654 sourceMapper.addMapping(sourceSchema[
'coord_dec'].asKey(),
'dec')
655 sourceMapper.addMapping(sourceSchema[
'slot_Centroid_x'].asKey(),
'x')
656 sourceMapper.addMapping(sourceSchema[
'slot_Centroid_y'].asKey(),
'y')
662 sourceMapper.addMapping(sourceSchema[self.config.psfCandidateName].asKey(),
665 sourceMapper.editOutputSchema().addField(
666 "psf_candidate", type=
'Flag',
667 doc=(
"Flag set if the source was a candidate for PSF determination, "
668 "as determined by the star selector."))
671 sourceMapper.editOutputSchema().addField(
672 "visit", type=np.int32, doc=
"Visit number")
673 sourceMapper.editOutputSchema().addField(
674 "ccd", type=np.int32, doc=
"CCD number")
675 sourceMapper.editOutputSchema().addField(
676 "instMag", type=np.float32, doc=
"Instrumental magnitude")
677 sourceMapper.editOutputSchema().addField(
678 "instMagErr", type=np.float32, doc=
"Instrumental magnitude error")
679 sourceMapper.editOutputSchema().addField(
680 "jacobian", type=np.float32, doc=
"Relative pixel scale from wcs jacobian")
681 sourceMapper.editOutputSchema().addField(
682 "deltaMagBkg", type=np.float32, doc=
"Change in magnitude due to local background offset")
688 Use FGCM code to match observations into unique stars.
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).
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.
712 visitFilterNames = np.zeros(len(visitCat), dtype=
'a30')
713 for i
in range(len(visitCat)):
714 visitFilterNames[i] = visitCat[i][
'physicalFilter']
717 visitIndex = np.searchsorted(visitCat[
'visit'],
720 obsFilterNames = visitFilterNames[visitIndex]
722 if self.config.doReferenceMatches:
724 lutCat = lutDataRef.get()
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'])}
738 self.log.
info(
"Using the following reference filters: %s" %
739 (
', '.join(referenceFilterNames)))
743 referenceFilterNames = []
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}
761 fgcmMakeStars = fgcm.FgcmMakeStars(starConfig)
769 conv = obsCat[0][
'ra'].asDegrees() / float(obsCat[0][
'ra'])
770 fgcmMakeStars.makePrimaryStars(obsCat[
'ra'] * conv,
771 obsCat[
'dec'] * conv,
772 filterNameArray=obsFilterNames,
776 fgcmMakeStars.makeMatchedStars(obsCat[
'ra'] * conv,
777 obsCat[
'dec'] * conv,
780 if self.config.doReferenceMatches:
781 fgcmMakeStars.makeReferenceMatches(self.fgcmLoadReferenceCatalog)
789 fgcmStarIdCat.reserve(fgcmMakeStars.objIndexCat.size)
790 for i
in range(fgcmMakeStars.objIndexCat.size):
791 fgcmStarIdCat.addNew()
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']
803 fgcmStarIndicesCat.reserve(fgcmMakeStars.obsIndexCat.size)
804 for i
in range(fgcmMakeStars.obsIndexCat.size):
805 fgcmStarIndicesCat.addNew()
807 fgcmStarIndicesCat[
'obsIndex'][:] = fgcmMakeStars.obsIndexCat[
'obsindex']
809 if self.config.doReferenceMatches:
813 fgcmRefCat.reserve(fgcmMakeStars.referenceCat.size)
815 for i
in range(fgcmMakeStars.referenceCat.size):
818 fgcmRefCat[
'fgcm_id'][:] = fgcmMakeStars.referenceCat[
'fgcm_id']
819 fgcmRefCat[
'refMag'][:, :] = fgcmMakeStars.referenceCat[
'refMag']
820 fgcmRefCat[
'refMagErr'][:, :] = fgcmMakeStars.referenceCat[
'refMagErr']
823 md.set(
"REFSTARS_FORMAT_VERSION", REFSTARS_FORMAT_VERSION)
824 md.set(
"FILTERNAMES", referenceFilterNames)
825 fgcmRefCat.setMetadata(md)
830 return fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat
832 def _makeFgcmVisitSchema(self, nCcd):
834 Make a schema for an fgcmVisitCatalog
839 Number of CCDs in the camera
843 schema: `afwTable.Schema`
847 schema.addField(
'visit', type=np.int32, doc=
"Visit number")
848 schema.addField(
'physicalFilter', type=str, size=30, doc=
"Physical filter")
849 schema.addField(
'telra', type=np.float64, doc=
"Pointing RA (deg)")
850 schema.addField(
'teldec', type=np.float64, doc=
"Pointing Dec (deg)")
851 schema.addField(
'telha', type=np.float64, doc=
"Pointing Hour Angle (deg)")
852 schema.addField(
'telrot', type=np.float64, doc=
"Camera rotation (deg)")
853 schema.addField(
'mjd', type=np.float64, doc=
"MJD of visit")
854 schema.addField(
'exptime', type=np.float32, doc=
"Exposure time")
855 schema.addField(
'pmb', type=np.float32, doc=
"Pressure (millibar)")
856 schema.addField(
'psfSigma', type=np.float32, doc=
"PSF sigma (reference CCD)")
857 schema.addField(
'deltaAper', type=np.float32, doc=
"Delta-aperture")
858 schema.addField(
'skyBackground', type=np.float32, doc=
"Sky background (ADU) (reference CCD)")
860 schema.addField(
'deepFlag', type=np.int32, doc=
"Deep observation")
861 schema.addField(
'scaling', type=
'ArrayD', doc=
"Scaling applied due to flat adjustment",
863 schema.addField(
'used', type=np.int32, doc=
"This visit has been ingested.")
864 schema.addField(
'sources_read', type=
'Flag', doc=
"This visit had sources read.")
868 def _makeFgcmObjSchema(self):
870 Make a schema for the objIndexCat from fgcmMakeStars
874 schema: `afwTable.Schema`
878 objSchema.addField(
'fgcm_id', type=np.int32, doc=
'FGCM Unique ID')
880 objSchema.addField(
'ra', type=np.float64, doc=
'Mean object RA (deg)')
881 objSchema.addField(
'dec', type=np.float64, doc=
'Mean object Dec (deg)')
882 objSchema.addField(
'obsArrIndex', type=np.int32,
883 doc=
'Index in obsIndexTable for first observation')
884 objSchema.addField(
'nObs', type=np.int32, doc=
'Total number of observations')
888 def _makeFgcmObsSchema(self):
890 Make a schema for the obsIndexCat from fgcmMakeStars
894 schema: `afwTable.Schema`
898 obsSchema.addField(
'obsIndex', type=np.int32, doc=
'Index in observation table')
902 def _makeFgcmRefSchema(self, nReferenceBands):
904 Make a schema for the referenceCat from fgcmMakeStars
908 nReferenceBands: `int`
909 Number of reference bands
913 schema: `afwTable.Schema`
917 refSchema.addField(
'fgcm_id', type=np.int32, doc=
'FGCM Unique ID')
918 refSchema.addField(
'refMag', type=
'ArrayF', doc=
'Reference magnitude array (AB)',
919 size=nReferenceBands)
920 refSchema.addField(
'refMagErr', type=
'ArrayF', doc=
'Reference magnitude error array',
921 size=nReferenceBands)
925 def _getReferenceFilterNames(self, visitCat, stdFilterDict, stdLambdaDict):
927 Get the reference filter names, in wavelength order, from the visitCat and
928 information from the look-up-table.
932 visitCat: `afw.table.BaseCatalog`
933 Catalog with visit data for FGCM
934 stdFilterDict: `dict`
935 Mapping of filterName to stdFilterName from LUT
936 stdLambdaDict: `dict`
937 Mapping of stdFilterName to stdLambda from LUT
941 referenceFilterNames: `list`
942 Wavelength-ordered list of reference filter names
946 filterNames = np.unique(visitCat.asAstropy()[
'physicalFilter'])
949 stdFilterNames = {stdFilterDict[filterName]
for filterName
in filterNames}
952 referenceFilterNames = sorted(stdFilterNames, key=stdLambdaDict.get)
954 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)