23"""Build star observations for input to FGCM using sourceTable_visit.
25This task finds all the visits and sourceTable_visits in a repository (or a
26subset based on command line parameters) and extracts all the potential
27calibration stars for input into fgcm. This task additionally uses fgcm to
28match star observations into unique stars, and performs
as much cleaning of the
29input catalog
as possible.
35from smatch.matcher import Matcher
36from astropy.table import Table, vstack
38from fgcm.fgcmUtilities import objFlagDict
40import lsst.pex.config as pexConfig
41import lsst.pipe.base as pipeBase
42from lsst.pipe.base import connectionTypes
43from lsst.meas.algorithms import ReferenceObjectLoader, LoadReferenceObjectsConfig
44from lsst.pipe.tasks.reserveIsolatedStars import ReserveIsolatedStarsTask
46from .fgcmBuildStarsBase import FgcmBuildStarsConfigBase, FgcmBuildStarsBaseTask
47from .utilities import computeApproxPixelAreaFields, computeApertureRadiusFromName
48from .utilities import lookupStaticCalibrations
50__all__ = ["FgcmBuildFromIsolatedStarsConfig", "FgcmBuildFromIsolatedStarsTask"]
53class FgcmBuildFromIsolatedStarsConnections(pipeBase.PipelineTaskConnections,
54 dimensions=("instrument",),
56 camera = connectionTypes.PrerequisiteInput(
57 doc=
"Camera instrument",
59 storageClass=
"Camera",
60 dimensions=(
"instrument",),
61 lookupFunction=lookupStaticCalibrations,
64 fgcm_lookup_table = connectionTypes.PrerequisiteInput(
65 doc=(
"Atmosphere + instrument look-up-table for FGCM throughput and "
66 "chromatic corrections."),
67 name=
"fgcmLookUpTable",
68 storageClass=
"Catalog",
69 dimensions=(
"instrument",),
72 ref_cat = connectionTypes.PrerequisiteInput(
73 doc=
"Reference catalog to use for photometric calibration.",
75 storageClass=
"SimpleCatalog",
76 dimensions=(
"skypix",),
80 isolated_star_cats = pipeBase.connectionTypes.Input(
81 doc=(
"Catalog of isolated stars with average positions, number of associated "
82 "sources, and indexes to the isolated_star_sources catalogs."),
83 name=
"isolated_star_cat",
84 storageClass=
"ArrowAstropy",
85 dimensions=(
"instrument",
"tract",
"skymap"),
89 isolated_star_sources = pipeBase.connectionTypes.Input(
90 doc=(
"Catalog of isolated star sources with sourceIds, and indexes to the "
91 "isolated_star_cats catalogs."),
92 name=
"isolated_star_sources",
93 storageClass=
"ArrowAstropy",
94 dimensions=(
"instrument",
"tract",
"skymap"),
98 visit_summaries = connectionTypes.Input(
99 doc=(
"Per-visit consolidated exposure metadata. These catalogs use "
100 "detector id for the id and must be sorted for fast lookups of a "
103 storageClass=
"ExposureCatalog",
104 dimensions=(
"instrument",
"visit"),
108 fgcm_visit_catalog = connectionTypes.Output(
109 doc=
"Catalog of visit information for fgcm.",
110 name=
"fgcmVisitCatalog",
111 storageClass=
"Catalog",
112 dimensions=(
"instrument",),
114 fgcm_star_observations = connectionTypes.Output(
115 doc=
"Catalog of star observations for fgcm.",
116 name=
"fgcm_star_observations",
117 storageClass=
"ArrowAstropy",
118 dimensions=(
"instrument",),
120 fgcm_star_ids = connectionTypes.Output(
121 doc=
"Catalog of fgcm calibration star IDs.",
122 name=
"fgcm_star_ids",
123 storageClass=
"ArrowAstropy",
124 dimensions=(
"instrument",),
126 fgcm_reference_stars = connectionTypes.Output(
127 doc=
"Catalog of fgcm-matched reference stars.",
128 name=
"fgcm_reference_stars",
129 storageClass=
"ArrowAstropy",
130 dimensions=(
"instrument",),
136 if not config.doReferenceMatches:
137 self.prerequisiteInputs.remove(
"ref_cat")
138 self.prerequisiteInputs.remove(
"fgcm_lookup_table")
139 self.outputs.remove(
"fgcm_reference_stars")
143 pipelineConnections=FgcmBuildFromIsolatedStarsConnections):
144 """Config for FgcmBuildFromIsolatedStarsTask."""
145 referenceCCD = pexConfig.Field(
146 doc=
"Reference detector for checking PSF and background.",
150 reserve_selection = pexConfig.ConfigurableField(
151 target=ReserveIsolatedStarsTask,
152 doc=
"Task to select reserved stars.",
168 source_selector.setDefaults()
170 source_selector.doFlags =
False
171 source_selector.doSignalToNoise =
True
172 source_selector.doUnresolved =
False
173 source_selector.doIsolated =
False
174 source_selector.doRequireFiniteRaDec =
False
176 source_selector.flags.bad = []
178 source_selector.signalToNoise.minimum = 11.0
179 source_selector.signalToNoise.maximum = 1000.0
185 """Build star catalog for FGCM global calibration, using the isolated star catalogs.
187 ConfigClass = FgcmBuildFromIsolatedStarsConfig
188 _DefaultName = "fgcmBuildFromIsolatedStars"
190 canMultiprocess =
False
194 self.makeSubtask(
'reserve_selection')
197 input_ref_dict = butlerQC.get(inputRefs)
199 isolated_star_cat_handles = input_ref_dict[
"isolated_star_cats"]
200 isolated_star_source_handles = input_ref_dict[
"isolated_star_sources"]
202 isolated_star_cat_handle_dict = {
203 handle.dataId[
"tract"]: handle
for handle
in isolated_star_cat_handles
205 isolated_star_source_handle_dict = {
206 handle.dataId[
"tract"]: handle
for handle
in isolated_star_source_handles
209 if len(isolated_star_cat_handle_dict) != len(isolated_star_source_handle_dict):
210 raise RuntimeError(
"isolated_star_cats and isolate_star_sources must have same length.")
212 for tract
in isolated_star_cat_handle_dict:
213 if tract
not in isolated_star_source_handle_dict:
214 raise RuntimeError(f
"tract {tract} in isolated_star_cats but not isolated_star_sources")
216 if self.config.doReferenceMatches:
217 lookup_table_handle = input_ref_dict[
"fgcm_lookup_table"]
220 ref_config = LoadReferenceObjectsConfig()
221 ref_config.filterMap = self.config.fgcmLoadReferenceCatalog.filterMap
222 ref_obj_loader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
223 for ref
in inputRefs.ref_cat],
224 refCats=butlerQC.get(inputRefs.ref_cat),
225 name=self.config.connections.ref_cat,
228 self.makeSubtask(
'fgcmLoadReferenceCatalog',
229 refObjLoader=ref_obj_loader,
230 refCatName=self.config.connections.ref_cat)
232 lookup_table_handle =
None
238 visit_summary_handle_dict = {handle.dataId[
'visit']: [handle,
None]
for
239 handle
in input_ref_dict[
'visit_summaries']}
241 camera = input_ref_dict[
"camera"]
245 visit_summary_handle_dict=visit_summary_handle_dict,
246 isolated_star_cat_handle_dict=isolated_star_cat_handle_dict,
247 isolated_star_source_handle_dict=isolated_star_source_handle_dict,
248 lookup_table_handle=lookup_table_handle,
251 butlerQC.put(struct.fgcm_visit_catalog, outputRefs.fgcm_visit_catalog)
252 butlerQC.put(struct.fgcm_star_observations, outputRefs.fgcm_star_observations)
253 butlerQC.put(struct.fgcm_star_ids, outputRefs.fgcm_star_ids)
254 if self.config.doReferenceMatches:
255 butlerQC.put(struct.fgcm_reference_stars, outputRefs.fgcm_reference_stars)
257 def run(self, *, camera, visit_summary_handle_dict, isolated_star_cat_handle_dict,
258 isolated_star_source_handle_dict, lookup_table_handle=None):
259 """Run the fgcmBuildFromIsolatedStarsTask.
263 camera : `lsst.afw.cameraGeom.Camera`
265 visit_summary_handle_dict : `dict` [`int`, [`lsst.daf.butler.DeferredDatasetHandle`]]
266 Visit summary dataset handles, with the visit
as key.
267 isolated_star_cat_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
268 Isolated star catalog dataset handles,
with the tract
as key.
269 isolated_star_source_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
270 Isolated star source dataset handles,
with the tract
as key.
271 lookup_table_handle : `lsst.daf.butler.DeferredDatasetHandle`, optional
272 Data reference to fgcm look-up table (used
if matching reference stars).
276 struct : `lsst.pipe.base.struct`
277 Catalogs
for persistence,
with attributes:
279 ``fgcm_visit_catalog``
280 Catalog of per-visit data (`lsst.afw.table.ExposureCatalog`).
281 ``fgcm_star_observations``
282 Catalog of individual star observations (`astropy.table.Table`).
284 Catalog of per-star ids
and positions (`astropy.table.Table`).
285 ``fgcm_reference_stars``
286 Catalog of reference stars matched to fgcm stars (`astropy.table.Table`).
290 calib_flux_aperture_radius =
None
291 if self.config.doSubtractLocalBackground:
293 calib_flux_aperture_radius = computeApertureRadiusFromName(self.config.instFluxField)
294 except RuntimeError
as e:
295 raise RuntimeError(
"Could not determine aperture radius from %s. "
296 "Cannot use doSubtractLocalBackground." %
297 (self.config.instFluxField))
from e
300 if self.config.doReferenceMatches:
301 if lookup_table_handle
is None:
302 raise RuntimeError(
"Must supply lookup_table_handle if config.doReferenceMatches is True.")
308 isolated_star_cat_handle_dict,
309 isolated_star_source_handle_dict,
312 calib_flux_aperture_radius=calib_flux_aperture_radius,
327 if self.config.doReferenceMatches:
332 return pipeBase.Struct(
333 fgcm_visit_catalog=visit_cat,
334 fgcm_star_observations=star_obs,
335 fgcm_star_ids=fgcm_obj,
336 fgcm_reference_stars=fgcm_ref,
341 isolated_star_cat_handle_dict,
342 isolated_star_source_handle_dict,
345 calib_flux_aperture_radius=None,
347 """Make all star observations from isolated star catalogs.
351 isolated_star_cat_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
352 Isolated star catalog dataset handles, with the tract
as key.
353 isolated_star_source_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
354 Isolated star source dataset handles,
with the tract
as key.
355 visit_cat : `lsst.afw.table.ExposureCatalog`
356 Catalog of per-visit data.
357 camera : `lsst.afw.cameraGeom.Camera`
359 calib_flux_aperture_radius : `float`, optional
360 Radius
for the calibration flux aperture.
364 fgcm_obj : `astropy.table.Table`
365 Catalog of ids
and positions
for each star.
366 star_obs : `astropy.table.Table`
367 Catalog of individual star observations.
380 self.config.instFluxField,
381 self.config.instFluxField +
"Err",
382 self.config.apertureInnerInstFluxField,
383 self.config.apertureInnerInstFluxField +
"Err",
384 self.config.apertureOuterInstFluxField,
385 self.config.apertureOuterInstFluxField +
"Err",
388 if self.config.doSubtractLocalBackground:
389 source_columns.append(self.config.localBackgroundFluxField)
390 local_background_flag_name = self.config.localBackgroundFluxField[0: -len(
'instFlux')] +
'flag'
391 source_columns.append(local_background_flag_name)
393 if self.sourceSelector.config.doFlags:
394 source_columns.extend(self.sourceSelector.config.flags.bad)
396 local_background_area = np.pi*calib_flux_aperture_radius**2.
400 approx_pixel_area_fields = computeApproxPixelAreaFields(camera)
403 detector_mapping = {}
404 for detector_index, detector
in enumerate(camera):
405 detector_mapping[detector.getId()] = detector_index
415 (
"inst_mag_err",
"f4"),
417 (
"delta_mag_bkg",
"f4"),
418 (
"delta_mag_aper",
"f4"),
419 (
"delta_mag_err_aper",
"f4"),
424 (
"isolated_star_id",
"i8"),
427 (
"obs_arr_index",
"i4"),
434 merge_source_counter = 0
438 visit_cat_table = visit_cat.asAstropy()
440 for tract
in sorted(isolated_star_cat_handle_dict):
441 stars = isolated_star_cat_handle_dict[tract].get()
442 sources = isolated_star_source_handle_dict[tract].get(parameters={
"columns": source_columns})
445 good_sources = self.sourceSelector.selectSources(sources).selected
446 if self.config.doSubtractLocalBackground:
447 good_sources &= (~sources[local_background_flag_name])
448 local_background = local_background_area*sources[self.config.localBackgroundFluxField]
449 good_sources &= ((sources[self.config.instFluxField] - local_background) > 0)
451 if good_sources.sum() == 0:
452 self.log.info(
"No good sources found in tract %d", tract)
460 if len(self.config.requiredBands) > 0:
461 loop_bands = self.config.requiredBands
463 loop_bands = np.unique(sources[
"band"])
465 n_req = np.zeros((len(loop_bands), len(stars)), dtype=np.int32)
466 for i, band
in enumerate(loop_bands):
467 (band_use,) = (sources[good_sources][
"band"] == band).nonzero()
470 (i, sources[good_sources][
"obj_index"][band_use]),
474 if len(self.config.requiredBands) > 0:
477 (good_stars,) = (n_req.min(axis=0) >= self.config.minPerBand).nonzero()
481 (good_stars,) = (n_req.max(axis=0) >= self.config.minPerBand).nonzero()
485 obj_index = sources[
"obj_index"][good_sources]
486 a, b = esutil.numpy_util.match(good_stars, obj_index)
489 _, index_new = np.unique(a, return_index=
True)
490 stars[
"source_cat_index"][good_stars] = index_new
491 sources = sources[good_sources][b]
492 sources[
"obj_index"][:] = a
493 stars = stars[good_stars]
495 nsource = np.zeros(len(stars), dtype=np.int32)
498 sources[
"obj_index"],
501 stars[
"nsource"][:] = nsource
514 star_obs = Table(data=np.zeros(len(sources), dtype=star_obs_dtype))
515 star_obs[
"ra"] = sources[
"ra"]
516 star_obs[
"dec"] = sources[
"dec"]
517 star_obs[
"x"] = sources[
"x"]
518 star_obs[
"y"] = sources[
"y"]
519 star_obs[
"visit"] = sources[
"visit"]
520 star_obs[
"detector"] = sources[
"detector"]
522 visit_match, obs_match = esutil.numpy_util.match(visit_cat_table[
"visit"], sources[
"visit"])
524 exp_time = np.zeros(len(star_obs))
525 exp_time[obs_match] = visit_cat_table[
"exptime"][visit_match]
527 with warnings.catch_warnings():
529 warnings.simplefilter(
"ignore")
531 inst_mag_inner = -2.5*np.log10(sources[self.config.apertureInnerInstFluxField])
532 inst_mag_err_inner = k*(sources[self.config.apertureInnerInstFluxField +
"Err"]
533 / sources[self.config.apertureInnerInstFluxField])
534 inst_mag_outer = -2.5*np.log10(sources[self.config.apertureOuterInstFluxField])
535 inst_mag_err_outer = k*(sources[self.config.apertureOuterInstFluxField +
"Err"]
536 / sources[self.config.apertureOuterInstFluxField])
537 star_obs[
"delta_mag_aper"] = inst_mag_inner - inst_mag_outer
538 star_obs[
"delta_mag_err_aper"] = np.sqrt(inst_mag_err_inner**2. + inst_mag_err_outer**2.)
540 bad = ~np.isfinite(star_obs[
"delta_mag_aper"])
541 star_obs[
"delta_mag_aper"][bad] = 99.0
542 star_obs[
"delta_mag_err_aper"][bad] = 99.0
544 if self.config.doSubtractLocalBackground:
558 local_background = local_background_area*sources[self.config.localBackgroundFluxField]
559 star_obs[
"delta_mag_bkg"] = (-2.5*np.log10(sources[self.config.instFluxField]
560 - local_background) -
561 -2.5*np.log10(sources[self.config.instFluxField]))
564 for detector
in camera:
565 detector_id = detector.getId()
567 (use,) = (star_obs[
"detector"][obs_match] == detector_id).nonzero()
575 jac = approx_pixel_area_fields[detector_id].evaluate(
576 star_obs[
"x"][obs_match][use],
577 star_obs[
"y"][obs_match][use],
579 star_obs[
"jacobian"][obs_match[use]] = jac
580 scaled_inst_flux = (sources[self.config.instFluxField][obs_match[use]]
581 * visit_cat_table[
"scaling"][visit_match[use],
582 detector_mapping[detector_id]])
583 star_obs[
"inst_mag"][obs_match[use]] = (-2.5 * np.log10(scaled_inst_flux
587 star_obs[
"inst_mag_err"] = k*(sources[self.config.instFluxField +
"Err"]
588 / sources[self.config.instFluxField])
591 if self.config.doApplyWcsJacobian:
592 star_obs[
"inst_mag"] -= 2.5*np.log10(star_obs[
"jacobian"])
595 fgcm_obj = Table(data=np.zeros(len(stars), dtype=fgcm_obj_dtype))
596 fgcm_obj[
"isolated_star_id"] = stars[
"isolated_star_id"]
597 fgcm_obj[
"ra"] = stars[
"ra"]
598 fgcm_obj[
"dec"] = stars[
"dec"]
599 fgcm_obj[
"obs_arr_index"] = stars[
"source_cat_index"]
600 fgcm_obj[
"n_obs"] = stars[
"nsource"]
603 fgcm_obj[
"obs_arr_index"] += merge_source_counter
605 fgcm_objs.append(fgcm_obj)
606 star_obs_cats.append(star_obs)
608 merge_source_counter += len(star_obs)
610 fgcm_obj = vstack(fgcm_objs)
613 fgcm_obj[
"fgcm_id"][:] = np.arange(len(fgcm_obj)) + 1
615 return fgcm_obj, vstack(star_obs_cats)
618 """Downsample stars according to density.
620 Catalogs are modified in-place.
624 fgcm_obj : `astropy.table.Table`
625 Catalog of per-star ids
and positions.
626 star_obs : `astropy.table.Table`
627 Catalog of individual star observations.
629 if self.config.randomSeed
is not None:
630 np.random.seed(seed=self.config.randomSeed)
632 ipnest = hpg.angle_to_pixel(self.config.densityCutNside, fgcm_obj[
"ra"], fgcm_obj[
"dec"])
636 hist, rev_indices = esutil.stat.histogram(ipnest, rev=
True)
638 obj_use = np.ones(len(fgcm_obj), dtype=bool)
640 (high,) = (hist > self.config.densityCutMaxPerPixel).nonzero()
641 (ok,) = (hist > 0).nonzero()
642 self.log.info(
"There are %d/%d pixels with high stellar density.", high.size, ok.size)
643 for i
in range(high.size):
645 pix_indices = rev_indices[rev_indices[high[i]]: rev_indices[high[i] + 1]]
647 cut = np.random.choice(
649 size=pix_indices.size - self.config.densityCutMaxPerPixel,
654 fgcm_obj = fgcm_obj[obj_use]
656 obs_index = np.zeros(np.sum(fgcm_obj[
"n_obs"]), dtype=np.int32)
658 for i
in range(len(fgcm_obj)):
659 n_obs = fgcm_obj[
"n_obs"][i]
660 obs_index[ctr: ctr + n_obs] = (
661 np.arange(fgcm_obj[
"obs_arr_index"][i], fgcm_obj[
"obs_arr_index"][i] + n_obs)
663 fgcm_obj[
"obs_arr_index"][i] = ctr
666 star_obs = star_obs[obs_index]
669 """Run the star reservation task to flag reserved stars.
673 fgcm_obj : `astropy.table.Table`
674 Catalog of per-star ids and positions.
676 reserved = self.reserve_selection.run(
678 extra=','.join(self.config.requiredBands),
680 fgcm_obj[
"obj_flag"][reserved] |= objFlagDict[
"RESERVED"]
683 """Associate fgcm isolated stars with reference stars.
687 lookup_table_handle : `lsst.daf.butler.DeferredDatasetHandle`, optional
688 Data reference to fgcm look-up table (used if matching reference stars).
689 visit_cat : `lsst.afw.table.ExposureCatalog`
690 Catalog of per-visit data.
691 fgcm_obj : `astropy.table.Table`
692 Catalog of per-star ids
and positions
696 ref_cat : `astropy.table.Table`
697 Catalog of reference stars matched to fgcm stars.
700 lut_cat = lookup_table_handle.get()
702 std_filter_dict = {filter_name: std_filter
for (filter_name, std_filter)
in
703 zip(lut_cat[0][
"physicalFilters"].split(
","),
704 lut_cat[0][
"stdPhysicalFilters"].split(
","))}
705 std_lambda_dict = {std_filter: std_lambda
for (std_filter, std_lambda)
in
706 zip(lut_cat[0][
"stdPhysicalFilters"].split(
","),
707 lut_cat[0][
"lambdaStdFilter"])}
715 self.log.info(
"Using the following reference filters: %s", (
", ".join(reference_filter_names)))
718 ipnest = hpg.angle_to_pixel(self.config.coarseNside, fgcm_obj[
"ra"], fgcm_obj[
"dec"])
719 hpix, revpix = esutil.stat.histogram(ipnest, rev=
True)
724 dtype = [(
"fgcm_id",
"i4"),
725 (
"refMag",
"f4", (len(reference_filter_names), )),
726 (
"refMagErr",
"f4", (len(reference_filter_names), ))]
728 (gdpix,) = (hpix > 0).nonzero()
729 for ii, gpix
in enumerate(gdpix):
730 p1a = revpix[revpix[gpix]: revpix[gpix + 1]]
733 ra_wrap = fgcm_obj[
"ra"][p1a]
734 if (ra_wrap.min() < 10.0)
and (ra_wrap.max() > 350.0):
735 ra_wrap[ra_wrap > 180.0] -= 360.0
736 mean_ra = np.mean(ra_wrap) % 360.0
738 mean_ra = np.mean(ra_wrap)
739 mean_dec = np.mean(fgcm_obj[
"dec"][p1a])
741 dist = esutil.coords.sphdist(mean_ra, mean_dec, fgcm_obj[
"ra"][p1a], fgcm_obj[
"dec"][p1a])
744 if rad < hpg.nside_to_resolution(self.config.coarseNside)/2.:
750 reference_filter_names,
755 self.config.coarseNside,
756 hpg.nest_to_ring(self.config.coarseNside, ipnest[p1a[0]]),
757 reference_filter_names,
759 if ref_cat.size == 0:
763 with Matcher(fgcm_obj[
"ra"][p1a], fgcm_obj[
"dec"][p1a])
as matcher:
764 idx, i1, i2, d = matcher.query_radius(
767 self.config.matchRadius/3600.,
775 pixel_cat = Table(data=np.zeros(i1.size, dtype=dtype))
776 pixel_cat[
"fgcm_id"] = fgcm_obj[
"fgcm_id"][p1a[i1]]
777 pixel_cat[
"refMag"][:, :] = ref_cat[
"refMag"][i2, :]
778 pixel_cat[
"refMagErr"][:, :] = ref_cat[
"refMagErr"][i2, :]
780 pixel_cats.append(pixel_cat)
783 "Found %d reference matches in pixel %d (%d of %d).",
790 ref_cat_full = vstack(pixel_cats)
791 ref_cat_full.meta.update({
'FILTERNAMES': reference_filter_names})
796 """Compute delta aperture summary statistics (per visit).
800 visit_cat : `lsst.afw.table.ExposureCatalog`
801 Catalog of per-visit data.
802 star_obs : `astropy.table.Table`
803 Catalog of individual star observations.
805 (ok,) = ((star_obs["delta_mag_aper"] < 99.0)
806 & (star_obs[
"delta_mag_err_aper"] < 99.0)).nonzero()
808 visit_index = np.zeros(len(star_obs[ok]), dtype=np.int32)
809 a, b = esutil.numpy_util.match(visit_cat[
"visit"], star_obs[
"visit"][ok])
812 h, rev = esutil.stat.histogram(visit_index, rev=
True)
814 visit_cat[
"deltaAper"] = -9999.0
815 h_use, = np.where(h >= 3)
817 i1a = rev[rev[index]: rev[index + 1]]
818 visit_cat[
"deltaAper"][index] = np.median(star_obs[
"delta_mag_aper"][ok[i1a]])
apertureOuterInstFluxField
apertureInnerInstFluxField
__init__(self, *config=None)
runQuantum(self, butlerQC, inputRefs, outputRefs)
_density_downsample(self, fgcm_obj, star_obs)
_mark_reserve_stars(self, fgcm_obj)
run(self, *camera, visit_summary_handle_dict, isolated_star_cat_handle_dict, isolated_star_source_handle_dict, lookup_table_handle=None)
_make_all_star_obs_from_isolated_stars(self, isolated_star_cat_handle_dict, isolated_star_source_handle_dict, visit_cat, camera, calib_flux_aperture_radius=None)
__init__(self, initInputs=None, **kwargs)
_associate_reference_stars(self, lookup_table_handle, visit_cat, fgcm_obj)
_compute_delta_aper_summary_statistics(self, visit_cat, star_obs)
_getReferenceFilterNames(self, visitCat, stdFilterDict, stdLambdaDict)
fgcmMakeVisitCatalog(self, camera, groupedHandles)
apertureOuterInstFluxField
apertureInnerInstFluxField