21"""Base class for BuildStars using src tables or sourceTable_visit tables.
31import lsst.daf.persistence
as dafPersist
32import lsst.pex.config
as pexConfig
33import lsst.pipe.base
as pipeBase
34import lsst.afw.table
as afwTable
35import lsst.geom
as geom
36from lsst.daf.base
import PropertyList
37from lsst.daf.base.dateTime
import DateTime
38from lsst.meas.algorithms.sourceSelector
import sourceSelectorRegistry
39from lsst.utils.timer
import timeMethod
41from .utilities
import computeApertureRadiusFromDataRef
42from .fgcmLoadReferenceCatalog
import FgcmLoadReferenceCatalogTask
46REFSTARS_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:
492 visitCat = afwTable.BaseCatalog(schema)
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`
529 bbox = geom.BoxI(geom.PointI(0, 0), geom.PointI(1, 1))
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]
549 if isinstance(dataRef, dafPersist.ButlerDataRef):
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:
606 if isinstance(dataRef, dafPersist.ButlerDataRef):
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
651 sourceMapper = afwTable.SchemaMapper(sourceSchema)
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")
684 sourceMapper.editOutputSchema().addField(
685 "deltaMagAper", type=np.float32, doc=
"Change in magnitude from larger to smaller aperture")
691 Use FGCM code to match observations into unique stars.
695 visitCat: `afw.table.BaseCatalog`
696 Catalog with visit data
for fgcm
697 obsCat: `afw.table.BaseCatalog`
698 Full catalog of star observations
for fgcm
699 lutDataRef: `lsst.daf.persistence.ButlerDataRef`
or
700 `lsst.daf.butler.DeferredDatasetHandle`, optional
701 Data reference to fgcm look-up table (used
if matching reference stars).
705 fgcmStarIdCat: `afw.table.BaseCatalog`
706 Catalog of unique star identifiers
and index keys
707 fgcmStarIndicesCat: `afwTable.BaseCatalog`
708 Catalog of unique star indices
709 fgcmRefCat: `afw.table.BaseCatalog`
710 Catalog of matched reference stars.
711 Will be
None if `config.doReferenceMatches`
is False.
715 visitFilterNames = np.zeros(len(visitCat), dtype=
'a30')
716 for i
in range(len(visitCat)):
717 visitFilterNames[i] = visitCat[i][
'physicalFilter']
720 visitIndex = np.searchsorted(visitCat[
'visit'],
723 obsFilterNames = visitFilterNames[visitIndex]
725 if self.config.doReferenceMatches:
727 lutCat = lutDataRef.get()
729 stdFilterDict = {filterName: stdFilter
for (filterName, stdFilter)
in
730 zip(lutCat[0][
'physicalFilters'].split(
','),
731 lutCat[0][
'stdPhysicalFilters'].split(
','))}
732 stdLambdaDict = {stdFilter: stdLambda
for (stdFilter, stdLambda)
in
733 zip(lutCat[0][
'stdPhysicalFilters'].split(
','),
734 lutCat[0][
'lambdaStdFilter'])}
741 self.log.info(
"Using the following reference filters: %s" %
742 (
', '.join(referenceFilterNames)))
746 referenceFilterNames = []
749 starConfig = {
'logger': self.log,
751 'filterToBand': self.config.physicalFilterMap,
752 'requiredBands': self.config.requiredBands,
753 'minPerBand': self.config.minPerBand,
754 'matchRadius': self.config.matchRadius,
755 'isolationRadius': self.config.isolationRadius,
756 'matchNSide': self.config.matchNside,
757 'coarseNSide': self.config.coarseNside,
758 'densNSide': self.config.densityCutNside,
759 'densMaxPerPixel': self.config.densityCutMaxPerPixel,
760 'randomSeed': self.config.randomSeed,
761 'primaryBands': self.config.primaryBands,
762 'referenceFilterNames': referenceFilterNames}
765 fgcmMakeStars = fgcm.FgcmMakeStars(starConfig)
773 conv = obsCat[0][
'ra'].asDegrees() / float(obsCat[0][
'ra'])
774 fgcmMakeStars.makePrimaryStars(obsCat[
'ra'] * conv,
775 obsCat[
'dec'] * conv,
776 filterNameArray=obsFilterNames,
780 fgcmMakeStars.makeMatchedStars(obsCat[
'ra'] * conv,
781 obsCat[
'dec'] * conv,
784 if self.config.doReferenceMatches:
785 fgcmMakeStars.makeReferenceMatches(self.fgcmLoadReferenceCatalog)
792 fgcmStarIdCat = afwTable.BaseCatalog(objSchema)
793 fgcmStarIdCat.reserve(fgcmMakeStars.objIndexCat.size)
794 for i
in range(fgcmMakeStars.objIndexCat.size):
795 fgcmStarIdCat.addNew()
798 fgcmStarIdCat[
'fgcm_id'][:] = fgcmMakeStars.objIndexCat[
'fgcm_id']
799 fgcmStarIdCat[
'ra'][:] = fgcmMakeStars.objIndexCat[
'ra']
800 fgcmStarIdCat[
'dec'][:] = fgcmMakeStars.objIndexCat[
'dec']
801 fgcmStarIdCat[
'obsArrIndex'][:] = fgcmMakeStars.objIndexCat[
'obsarrindex']
802 fgcmStarIdCat[
'nObs'][:] = fgcmMakeStars.objIndexCat[
'nobs']
806 fgcmStarIndicesCat = afwTable.BaseCatalog(obsSchema)
807 fgcmStarIndicesCat.reserve(fgcmMakeStars.obsIndexCat.size)
808 for i
in range(fgcmMakeStars.obsIndexCat.size):
809 fgcmStarIndicesCat.addNew()
811 fgcmStarIndicesCat[
'obsIndex'][:] = fgcmMakeStars.obsIndexCat[
'obsindex']
813 if self.config.doReferenceMatches:
816 fgcmRefCat = afwTable.BaseCatalog(refSchema)
817 fgcmRefCat.reserve(fgcmMakeStars.referenceCat.size)
819 for i
in range(fgcmMakeStars.referenceCat.size):
822 fgcmRefCat[
'fgcm_id'][:] = fgcmMakeStars.referenceCat[
'fgcm_id']
823 fgcmRefCat[
'refMag'][:, :] = fgcmMakeStars.referenceCat[
'refMag']
824 fgcmRefCat[
'refMagErr'][:, :] = fgcmMakeStars.referenceCat[
'refMagErr']
827 md.set(
"REFSTARS_FORMAT_VERSION", REFSTARS_FORMAT_VERSION)
828 md.set(
"FILTERNAMES", referenceFilterNames)
829 fgcmRefCat.setMetadata(md)
834 return fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat
836 def _makeFgcmVisitSchema(self, nCcd):
838 Make a schema for an fgcmVisitCatalog
843 Number of CCDs
in the camera
847 schema: `afwTable.Schema`
850 schema = afwTable.Schema()
851 schema.addField('visit', type=np.int32, doc=
"Visit number")
852 schema.addField(
'physicalFilter', type=str, size=30, doc=
"Physical filter")
853 schema.addField(
'telra', type=np.float64, doc=
"Pointing RA (deg)")
854 schema.addField(
'teldec', type=np.float64, doc=
"Pointing Dec (deg)")
855 schema.addField(
'telha', type=np.float64, doc=
"Pointing Hour Angle (deg)")
856 schema.addField(
'telrot', type=np.float64, doc=
"Camera rotation (deg)")
857 schema.addField(
'mjd', type=np.float64, doc=
"MJD of visit")
858 schema.addField(
'exptime', type=np.float32, doc=
"Exposure time")
859 schema.addField(
'pmb', type=np.float32, doc=
"Pressure (millibar)")
860 schema.addField(
'psfSigma', type=np.float32, doc=
"PSF sigma (reference CCD)")
861 schema.addField(
'deltaAper', type=np.float32, doc=
"Delta-aperture")
862 schema.addField(
'skyBackground', type=np.float32, doc=
"Sky background (ADU) (reference CCD)")
864 schema.addField(
'deepFlag', type=np.int32, doc=
"Deep observation")
865 schema.addField(
'scaling', type=
'ArrayD', doc=
"Scaling applied due to flat adjustment",
867 schema.addField(
'used', type=np.int32, doc=
"This visit has been ingested.")
868 schema.addField(
'sources_read', type=
'Flag', doc=
"This visit had sources read.")
872 def _makeFgcmObjSchema(self):
874 Make a schema for the objIndexCat
from fgcmMakeStars
878 schema: `afwTable.Schema`
881 objSchema = afwTable.Schema()
882 objSchema.addField('fgcm_id', type=np.int32, doc=
'FGCM Unique ID')
884 objSchema.addField(
'ra', type=np.float64, doc=
'Mean object RA (deg)')
885 objSchema.addField(
'dec', type=np.float64, doc=
'Mean object Dec (deg)')
886 objSchema.addField(
'obsArrIndex', type=np.int32,
887 doc=
'Index in obsIndexTable for first observation')
888 objSchema.addField(
'nObs', type=np.int32, doc=
'Total number of observations')
892 def _makeFgcmObsSchema(self):
894 Make a schema for the obsIndexCat
from fgcmMakeStars
898 schema: `afwTable.Schema`
901 obsSchema = afwTable.Schema()
902 obsSchema.addField('obsIndex', type=np.int32, doc=
'Index in observation table')
906 def _makeFgcmRefSchema(self, nReferenceBands):
908 Make a schema for the referenceCat
from fgcmMakeStars
912 nReferenceBands: `int`
913 Number of reference bands
917 schema: `afwTable.Schema`
920 refSchema = afwTable.Schema()
921 refSchema.addField('fgcm_id', type=np.int32, doc=
'FGCM Unique ID')
922 refSchema.addField(
'refMag', type=
'ArrayF', doc=
'Reference magnitude array (AB)',
923 size=nReferenceBands)
924 refSchema.addField(
'refMagErr', type=
'ArrayF', doc=
'Reference magnitude error array',
925 size=nReferenceBands)
929 def _getReferenceFilterNames(self, visitCat, stdFilterDict, stdLambdaDict):
931 Get the reference filter names, in wavelength order,
from the visitCat
and
932 information
from the look-up-table.
936 visitCat: `afw.table.BaseCatalog`
937 Catalog
with visit data
for FGCM
938 stdFilterDict: `dict`
939 Mapping of filterName to stdFilterName
from LUT
940 stdLambdaDict: `dict`
941 Mapping of stdFilterName to stdLambda
from LUT
945 referenceFilterNames: `list`
946 Wavelength-ordered list of reference filter names
950 filterNames = np.unique(visitCat.asAstropy()[
'physicalFilter'])
953 stdFilterNames = {stdFilterDict[filterName]
for filterName
in filterNames}
956 referenceFilterNames = sorted(stdFilterNames, key=stdLambdaDict.get)
958 return referenceFilterNames
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)
def computeApertureRadiusFromDataRef(dataRef, fluxField)