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.
34from smatch.matcher import Matcher
35from astropy.table import Table, vstack
37from fgcm.fgcmUtilities import objFlagDict
39import lsst.pex.config as pexConfig
40import lsst.pipe.base as pipeBase
41from lsst.pipe.base import connectionTypes
42from lsst.meas.algorithms import ReferenceObjectLoader, LoadReferenceObjectsConfig
43from lsst.pipe.tasks.reserveIsolatedStars import ReserveIsolatedStarsTask
45from .fgcmBuildStarsBase import FgcmBuildStarsConfigBase, FgcmBuildStarsBaseTask
46from .utilities import computeApproxPixelAreaFields, computeApertureRadiusFromName
47from .utilities import lookupStaticCalibrations
49__all__ = ["FgcmBuildFromIsolatedStarsConfig", "FgcmBuildFromIsolatedStarsTask"]
52class FgcmBuildFromIsolatedStarsConnections(pipeBase.PipelineTaskConnections,
53 dimensions=("instrument",),
55 camera = connectionTypes.PrerequisiteInput(
56 doc=
"Camera instrument",
58 storageClass=
"Camera",
59 dimensions=(
"instrument",),
60 lookupFunction=lookupStaticCalibrations,
63 fgcm_lookup_table = connectionTypes.PrerequisiteInput(
64 doc=(
"Atmosphere + instrument look-up-table for FGCM throughput and "
65 "chromatic corrections."),
66 name=
"fgcmLookUpTable",
67 storageClass=
"Catalog",
68 dimensions=(
"instrument",),
71 ref_cat = connectionTypes.PrerequisiteInput(
72 doc=
"Reference catalog to use for photometric calibration.",
74 storageClass=
"SimpleCatalog",
75 dimensions=(
"skypix",),
79 isolated_star_cats = pipeBase.connectionTypes.Input(
80 doc=(
"Catalog of isolated stars with average positions, number of associated "
81 "sources, and indexes to the isolated_star_sources catalogs."),
82 name=
"isolated_star_cat",
83 storageClass=
"ArrowAstropy",
84 dimensions=(
"instrument",
"tract",
"skymap"),
88 isolated_star_sources = pipeBase.connectionTypes.Input(
89 doc=(
"Catalog of isolated star sources with sourceIds, and indexes to the "
90 "isolated_star_cats catalogs."),
91 name=
"isolated_star_sources",
92 storageClass=
"ArrowAstropy",
93 dimensions=(
"instrument",
"tract",
"skymap"),
97 visit_summaries = connectionTypes.Input(
98 doc=(
"Per-visit consolidated exposure metadata. These catalogs use "
99 "detector id for the id and must be sorted for fast lookups of a "
102 storageClass=
"ExposureCatalog",
103 dimensions=(
"instrument",
"visit"),
107 fgcm_visit_catalog = connectionTypes.Output(
108 doc=
"Catalog of visit information for fgcm.",
109 name=
"fgcmVisitCatalog",
110 storageClass=
"Catalog",
111 dimensions=(
"instrument",),
113 fgcm_star_observations = connectionTypes.Output(
114 doc=
"Catalog of star observations for fgcm.",
115 name=
"fgcm_star_observations",
116 storageClass=
"ArrowAstropy",
117 dimensions=(
"instrument",),
119 fgcm_star_ids = connectionTypes.Output(
120 doc=
"Catalog of fgcm calibration star IDs.",
121 name=
"fgcm_star_ids",
122 storageClass=
"ArrowAstropy",
123 dimensions=(
"instrument",),
125 fgcm_reference_stars = connectionTypes.Output(
126 doc=
"Catalog of fgcm-matched reference stars.",
127 name=
"fgcm_reference_stars",
128 storageClass=
"ArrowAstropy",
129 dimensions=(
"instrument",),
135 if not config.doReferenceMatches:
136 self.prerequisiteInputs.remove(
"ref_cat")
137 self.prerequisiteInputs.remove(
"fgcm_lookup_table")
138 self.outputs.remove(
"fgcm_reference_stars")
142 pipelineConnections=FgcmBuildFromIsolatedStarsConnections):
143 """Config for FgcmBuildFromIsolatedStarsTask."""
144 referenceCCD = pexConfig.Field(
145 doc=
"Reference detector for checking PSF and background.",
149 reserve_selection = pexConfig.ConfigurableField(
150 target=ReserveIsolatedStarsTask,
151 doc=
"Task to select reserved stars.",
167 source_selector.setDefaults()
169 source_selector.doFlags =
True
170 source_selector.doSignalToNoise =
True
171 source_selector.doUnresolved =
False
172 source_selector.doIsolated =
False
173 source_selector.doRequireFiniteRaDec =
False
175 source_selector.flags.bad = []
179 source_selector.flags.bad.append(local_background_flag_name)
181 source_selector.signalToNoise.minimum = 11.0
182 source_selector.signalToNoise.maximum = 1000.0
188 """Build star catalog for FGCM global calibration, using the isolated star catalogs.
190 ConfigClass = FgcmBuildFromIsolatedStarsConfig
191 _DefaultName = "fgcmBuildFromIsolatedStars"
193 canMultiprocess =
False
197 self.makeSubtask(
'reserve_selection')
200 input_ref_dict = butlerQC.get(inputRefs)
202 isolated_star_cat_handles = input_ref_dict[
"isolated_star_cats"]
203 isolated_star_source_handles = input_ref_dict[
"isolated_star_sources"]
205 isolated_star_cat_handle_dict = {
206 handle.dataId[
"tract"]: handle
for handle
in isolated_star_cat_handles
208 isolated_star_source_handle_dict = {
209 handle.dataId[
"tract"]: handle
for handle
in isolated_star_source_handles
212 if len(isolated_star_cat_handle_dict) != len(isolated_star_source_handle_dict):
213 raise RuntimeError(
"isolated_star_cats and isolate_star_sources must have same length.")
215 for tract
in isolated_star_cat_handle_dict:
216 if tract
not in isolated_star_source_handle_dict:
217 raise RuntimeError(f
"tract {tract} in isolated_star_cats but not isolated_star_sources")
219 if self.config.doReferenceMatches:
220 lookup_table_handle = input_ref_dict[
"fgcm_lookup_table"]
223 ref_config = LoadReferenceObjectsConfig()
224 ref_config.filterMap = self.config.fgcmLoadReferenceCatalog.filterMap
225 ref_obj_loader = ReferenceObjectLoader(dataIds=[ref.datasetRef.dataId
226 for ref
in inputRefs.ref_cat],
227 refCats=butlerQC.get(inputRefs.ref_cat),
228 name=self.config.connections.ref_cat,
231 self.makeSubtask(
'fgcmLoadReferenceCatalog',
232 refObjLoader=ref_obj_loader,
233 refCatName=self.config.connections.ref_cat)
235 lookup_table_handle =
None
241 visit_summary_handle_dict = {handle.dataId[
'visit']: [handle,
None]
for
242 handle
in input_ref_dict[
'visit_summaries']}
244 camera = input_ref_dict[
"camera"]
248 visit_summary_handle_dict=visit_summary_handle_dict,
249 isolated_star_cat_handle_dict=isolated_star_cat_handle_dict,
250 isolated_star_source_handle_dict=isolated_star_source_handle_dict,
251 lookup_table_handle=lookup_table_handle,
254 butlerQC.put(struct.fgcm_visit_catalog, outputRefs.fgcm_visit_catalog)
255 butlerQC.put(struct.fgcm_star_observations, outputRefs.fgcm_star_observations)
256 butlerQC.put(struct.fgcm_star_ids, outputRefs.fgcm_star_ids)
257 if self.config.doReferenceMatches:
258 butlerQC.put(struct.fgcm_reference_stars, outputRefs.fgcm_reference_stars)
260 def run(self, *, camera, visit_summary_handle_dict, isolated_star_cat_handle_dict,
261 isolated_star_source_handle_dict, lookup_table_handle=None):
262 """Run the fgcmBuildFromIsolatedStarsTask.
266 camera : `lsst.afw.cameraGeom.Camera`
268 visit_summary_handle_dict : `dict` [`int`, [`lsst.daf.butler.DeferredDatasetHandle`]]
269 Visit summary dataset handles, with the visit
as key.
270 isolated_star_cat_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
271 Isolated star catalog dataset handles,
with the tract
as key.
272 isolated_star_source_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
273 Isolated star source dataset handles,
with the tract
as key.
274 lookup_table_handle : `lsst.daf.butler.DeferredDatasetHandle`, optional
275 Data reference to fgcm look-up table (used
if matching reference stars).
279 struct : `lsst.pipe.base.struct`
280 Catalogs
for persistence,
with attributes:
282 ``fgcm_visit_catalog``
283 Catalog of per-visit data (`lsst.afw.table.ExposureCatalog`).
284 ``fgcm_star_observations``
285 Catalog of individual star observations (`astropy.table.Table`).
287 Catalog of per-star ids
and positions (`astropy.table.Table`).
288 ``fgcm_reference_stars``
289 Catalog of reference stars matched to fgcm stars (`astropy.table.Table`).
293 calib_flux_aperture_radius =
None
294 if self.config.doSubtractLocalBackground:
296 calib_flux_aperture_radius = computeApertureRadiusFromName(self.config.instFluxField)
297 except RuntimeError
as e:
298 raise RuntimeError(
"Could not determine aperture radius from %s. "
299 "Cannot use doSubtractLocalBackground." %
300 (self.config.instFluxField))
from e
303 if self.config.doReferenceMatches:
304 if lookup_table_handle
is None:
305 raise RuntimeError(
"Must supply lookup_table_handle if config.doReferenceMatches is True.")
311 isolated_star_cat_handle_dict,
312 isolated_star_source_handle_dict,
315 calib_flux_aperture_radius=calib_flux_aperture_radius,
330 if self.config.doReferenceMatches:
335 return pipeBase.Struct(
336 fgcm_visit_catalog=visit_cat,
337 fgcm_star_observations=star_obs,
338 fgcm_star_ids=fgcm_obj,
339 fgcm_reference_stars=fgcm_ref,
342 def _make_all_star_obs_from_isolated_stars(
344 isolated_star_cat_handle_dict,
345 isolated_star_source_handle_dict,
348 calib_flux_aperture_radius=None,
350 """Make all star observations from isolated star catalogs.
354 isolated_star_cat_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
355 Isolated star catalog dataset handles, with the tract
as key.
356 isolated_star_source_handle_dict : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
357 Isolated star source dataset handles,
with the tract
as key.
358 visit_cat : `lsst.afw.table.ExposureCatalog`
359 Catalog of per-visit data.
360 camera : `lsst.afw.cameraGeom.Camera`
362 calib_flux_aperture_radius : `float`, optional
363 Radius
for the calibration flux aperture.
367 fgcm_obj : `astropy.table.Table`
368 Catalog of ids
and positions
for each star.
369 star_obs : `astropy.table.Table`
370 Catalog of individual star observations.
383 self.config.instFluxField,
384 self.config.instFluxField +
"Err",
385 self.config.apertureInnerInstFluxField,
386 self.config.apertureInnerInstFluxField +
"Err",
387 self.config.apertureOuterInstFluxField,
388 self.config.apertureOuterInstFluxField +
"Err",
391 if self.config.doSubtractLocalBackground:
392 source_columns.append(self.config.localBackgroundFluxField)
394 if self.sourceSelector.config.doFlags:
395 source_columns.extend(self.sourceSelector.config.flags.bad)
397 local_background_area = np.pi*calib_flux_aperture_radius**2.
401 approx_pixel_area_fields = computeApproxPixelAreaFields(camera)
404 detector_mapping = {}
405 for detector_index, detector
in enumerate(camera):
406 detector_mapping[detector.getId()] = detector_index
416 (
"inst_mag_err",
"f4"),
418 (
"delta_mag_bkg",
"f4"),
419 (
"delta_mag_aper",
"f4"),
420 (
"delta_mag_err_aper",
"f4"),
425 (
"isolated_star_id",
"i8"),
428 (
"obs_arr_index",
"i4"),
435 merge_source_counter = 0
439 visit_cat_table = visit_cat.asAstropy()
441 for tract
in sorted(isolated_star_cat_handle_dict):
442 stars = isolated_star_cat_handle_dict[tract].get()
443 sources = isolated_star_source_handle_dict[tract].get(parameters={
"columns": source_columns})
446 good_sources = self.sourceSelector.selectSources(sources).selected
447 if self.config.doSubtractLocalBackground:
448 good_sources &= (~sources[
"localBackground_flag"])
449 local_background = local_background_area*sources[self.config.localBackgroundFluxField]
450 good_sources &= ((sources[self.config.instFluxField] - local_background) > 0)
452 if good_sources.sum() == 0:
453 self.log.info(
"No good sources found in tract %d", tract)
457 if len(self.config.requiredBands) > 0:
458 n_req = np.zeros((len(self.config.requiredBands), len(stars)), dtype=np.int32)
459 for i, band
in enumerate(self.config.requiredBands):
460 (band_use,) = (sources[good_sources][
"band"] == band).nonzero()
463 (i, sources[good_sources][
"obj_index"][band_use]),
466 (good_stars,) = (n_req.min(axis=0) >= self.config.minPerBand).nonzero()
468 good_stars = np.arange(len(stars))
472 obj_index = sources[
"obj_index"][good_sources]
473 a, b = esutil.numpy_util.match(good_stars, obj_index)
476 _, index_new = np.unique(a, return_index=
True)
477 stars[
"source_cat_index"][good_stars] = index_new
478 sources = sources[good_sources][b]
479 sources[
"obj_index"][:] = a
480 stars = stars[good_stars]
482 nsource = np.zeros(len(stars), dtype=np.int32)
485 sources[
"obj_index"],
488 stars[
"nsource"][:] = nsource
501 star_obs = Table(data=np.zeros(len(sources), dtype=star_obs_dtype))
502 star_obs[
"ra"] = sources[
"ra"]
503 star_obs[
"dec"] = sources[
"decl"]
504 star_obs[
"x"] = sources[
"x"]
505 star_obs[
"y"] = sources[
"y"]
506 star_obs[
"visit"] = sources[
"visit"]
507 star_obs[
"detector"] = sources[
"detector"]
509 visit_match, obs_match = esutil.numpy_util.match(visit_cat_table[
"visit"], sources[
"visit"])
511 exp_time = np.zeros(len(star_obs))
512 exp_time[obs_match] = visit_cat_table[
"exptime"][visit_match]
514 with np.warnings.catch_warnings():
516 np.warnings.simplefilter(
"ignore")
518 inst_mag_inner = -2.5*np.log10(sources[self.config.apertureInnerInstFluxField])
519 inst_mag_err_inner = k*(sources[self.config.apertureInnerInstFluxField +
"Err"]
520 / sources[self.config.apertureInnerInstFluxField])
521 inst_mag_outer = -2.5*np.log10(sources[self.config.apertureOuterInstFluxField])
522 inst_mag_err_outer = k*(sources[self.config.apertureOuterInstFluxField +
"Err"]
523 / sources[self.config.apertureOuterInstFluxField])
524 star_obs[
"delta_mag_aper"] = inst_mag_inner - inst_mag_outer
525 star_obs[
"delta_mag_err_aper"] = np.sqrt(inst_mag_err_inner**2. + inst_mag_err_outer**2.)
527 bad = ~np.isfinite(star_obs[
"delta_mag_aper"])
528 star_obs[
"delta_mag_aper"][bad] = 99.0
529 star_obs[
"delta_mag_err_aper"][bad] = 99.0
531 if self.config.doSubtractLocalBackground:
545 local_background = local_background_area*sources[self.config.localBackgroundFluxField]
546 star_obs[
"delta_mag_bkg"] = (-2.5*np.log10(sources[self.config.instFluxField]
547 - local_background) -
548 -2.5*np.log10(sources[self.config.instFluxField]))
551 for detector
in camera:
552 detector_id = detector.getId()
554 (use,) = (star_obs[
"detector"][obs_match] == detector_id).nonzero()
562 jac = approx_pixel_area_fields[detector_id].evaluate(
563 star_obs[
"x"][obs_match][use],
564 star_obs[
"y"][obs_match][use],
566 star_obs[
"jacobian"][obs_match[use]] = jac
567 scaled_inst_flux = (sources[self.config.instFluxField][obs_match[use]]
568 * visit_cat_table[
"scaling"][visit_match[use],
569 detector_mapping[detector_id]])
570 star_obs[
"inst_mag"][obs_match[use]] = (-2.5 * np.log10(scaled_inst_flux
574 star_obs[
"inst_mag_err"] = k*(sources[self.config.instFluxField +
"Err"]
575 / sources[self.config.instFluxField])
578 if self.config.doApplyWcsJacobian:
579 star_obs[
"inst_mag"] -= 2.5*np.log10(star_obs[
"jacobian"])
582 fgcm_obj = Table(data=np.zeros(len(stars), dtype=fgcm_obj_dtype))
583 fgcm_obj[
"isolated_star_id"] = stars[
"isolated_star_id"]
584 fgcm_obj[
"ra"] = stars[
"ra"]
585 fgcm_obj[
"dec"] = stars[
"decl"]
586 fgcm_obj[
"obs_arr_index"] = stars[
"source_cat_index"]
587 fgcm_obj[
"n_obs"] = stars[
"nsource"]
590 fgcm_obj[
"obs_arr_index"] += merge_source_counter
592 fgcm_objs.append(fgcm_obj)
593 star_obs_cats.append(star_obs)
595 merge_source_counter += len(star_obs)
598 fgcm_obj[
"fgcm_id"][:] = np.arange(len(fgcm_obj)) + 1
600 return vstack(fgcm_objs), vstack(star_obs_cats)
602 def _density_downsample(self, fgcm_obj, star_obs):
603 """Downsample stars according to density.
605 Catalogs are modified in-place.
609 fgcm_obj : `astropy.table.Table`
610 Catalog of per-star ids
and positions.
611 star_obs : `astropy.table.Table`
612 Catalog of individual star observations.
614 if self.config.randomSeed
is not None:
615 np.random.seed(seed=self.config.randomSeed)
617 ipnest = hpg.angle_to_pixel(self.config.densityCutNside, fgcm_obj[
"ra"], fgcm_obj[
"dec"])
621 hist, rev_indices = esutil.stat.histogram(ipnest, rev=
True)
623 obj_use = np.ones(len(fgcm_obj), dtype=bool)
625 (high,) = (hist > self.config.densityCutMaxPerPixel).nonzero()
626 (ok,) = (hist > 0).nonzero()
627 self.log.info(
"There are %d/%d pixels with high stellar density.", high.size, ok.size)
628 for i
in range(high.size):
630 pix_indices = rev_indices[rev_indices[high[i]]: rev_indices[high[i] + 1]]
632 cut = np.random.choice(
634 size=pix_indices.size - self.config.densityCutMaxPerPixel,
639 fgcm_obj = fgcm_obj[obj_use]
641 obs_index = np.zeros(np.sum(fgcm_obj[
"n_obs"]), dtype=np.int32)
643 for i
in range(len(fgcm_obj)):
644 n_obs = fgcm_obj[
"n_obs"][i]
645 obs_index[ctr: ctr + n_obs] = (
646 np.arange(fgcm_obj[
"obs_arr_index"][i], fgcm_obj[
"obs_arr_index"][i] + n_obs)
648 fgcm_obj[
"obs_arr_index"][i] = ctr
651 star_obs = star_obs[obs_index]
653 def _mark_reserve_stars(self, fgcm_obj):
654 """Run the star reservation task to flag reserved stars.
658 fgcm_obj : `astropy.table.Table`
659 Catalog of per-star ids and positions.
661 reserved = self.reserve_selection.run(
663 extra=','.join(self.config.requiredBands),
665 fgcm_obj[
"obj_flag"][reserved] |= objFlagDict[
"RESERVED"]
667 def _associate_reference_stars(self, lookup_table_handle, visit_cat, fgcm_obj):
668 """Associate fgcm isolated stars with reference stars.
672 lookup_table_handle : `lsst.daf.butler.DeferredDatasetHandle`, optional
673 Data reference to fgcm look-up table (used if matching reference stars).
674 visit_cat : `lsst.afw.table.ExposureCatalog`
675 Catalog of per-visit data.
676 fgcm_obj : `astropy.table.Table`
677 Catalog of per-star ids
and positions
681 ref_cat : `astropy.table.Table`
682 Catalog of reference stars matched to fgcm stars.
685 lut_cat = lookup_table_handle.get()
687 std_filter_dict = {filter_name: std_filter
for (filter_name, std_filter)
in
688 zip(lut_cat[0][
"physicalFilters"].split(
","),
689 lut_cat[0][
"stdPhysicalFilters"].split(
","))}
690 std_lambda_dict = {std_filter: std_lambda
for (std_filter, std_lambda)
in
691 zip(lut_cat[0][
"stdPhysicalFilters"].split(
","),
692 lut_cat[0][
"lambdaStdFilter"])}
700 self.log.info(
"Using the following reference filters: %s", (
", ".join(reference_filter_names)))
703 ipnest = hpg.angle_to_pixel(self.config.coarseNside, fgcm_obj[
"ra"], fgcm_obj[
"dec"])
704 hpix, revpix = esutil.stat.histogram(ipnest, rev=
True)
709 dtype = [(
"fgcm_id",
"i4"),
710 (
"refMag",
"f4", (len(reference_filter_names), )),
711 (
"refMagErr",
"f4", (len(reference_filter_names), ))]
713 (gdpix,) = (hpix > 0).nonzero()
714 for ii, gpix
in enumerate(gdpix):
715 p1a = revpix[revpix[gpix]: revpix[gpix + 1]]
718 ra_wrap = fgcm_obj[
"ra"][p1a]
719 if (ra_wrap.min() < 10.0)
and (ra_wrap.max() > 350.0):
720 ra_wrap[ra_wrap > 180.0] -= 360.0
721 mean_ra = np.mean(ra_wrap) % 360.0
723 mean_ra = np.mean(ra_wrap)
724 mean_dec = np.mean(fgcm_obj[
"dec"][p1a])
726 dist = esutil.coords.sphdist(mean_ra, mean_dec, fgcm_obj[
"ra"][p1a], fgcm_obj[
"dec"][p1a])
729 if rad < hpg.nside_to_resolution(self.config.coarseNside)/2.:
731 ref_cat = self.fgcmLoadReferenceCatalog.getFgcmReferenceStarsSkyCircle(
735 reference_filter_names,
739 ref_cat = self.fgcmLoadReferenceCatalog.getFgcmReferenceStarsHealpix(
740 self.config.coarseNside,
741 hpg.nest_to_ring(self.config.coarseNside, ipnest[p1a[0]]),
742 reference_filter_names,
744 if ref_cat.size == 0:
748 with Matcher(fgcm_obj[
"ra"][p1a], fgcm_obj[
"dec"][p1a])
as matcher:
749 idx, i1, i2, d = matcher.query_radius(
752 self.config.matchRadius/3600.,
760 pixel_cat = Table(data=np.zeros(i1.size, dtype=dtype))
761 pixel_cat[
"fgcm_id"] = fgcm_obj[
"fgcm_id"][p1a[i1]]
762 pixel_cat[
"refMag"][:, :] = ref_cat[
"refMag"][i2, :]
763 pixel_cat[
"refMagErr"][:, :] = ref_cat[
"refMagErr"][i2, :]
765 pixel_cats.append(pixel_cat)
768 "Found %d reference matches in pixel %d (%d of %d).",
775 ref_cat_full = vstack(pixel_cats)
776 ref_cat_full.meta.update({
'FILTERNAMES': reference_filter_names})
780 def _compute_delta_aper_summary_statistics(self, visit_cat, star_obs):
781 """Compute delta aperture summary statistics (per visit).
785 visit_cat : `lsst.afw.table.ExposureCatalog`
786 Catalog of per-visit data.
787 star_obs : `astropy.table.Table`
788 Catalog of individual star observations.
790 (ok,) = ((star_obs["delta_mag_aper"] < 99.0)
791 & (star_obs[
"delta_mag_err_aper"] < 99.0)).nonzero()
793 visit_index = np.zeros(len(star_obs[ok]), dtype=np.int32)
794 a, b = esutil.numpy_util.match(visit_cat[
"visit"], star_obs[
"visit"][ok])
797 h, rev = esutil.stat.histogram(visit_index, rev=
True)
799 visit_cat[
"deltaAper"] = -9999.0
800 h_use, = np.where(h >= 3)
802 i1a = rev[rev[index]: rev[index + 1]]
803 visit_cat[
"deltaAper"][index] = np.median(star_obs[
"delta_mag_aper"][ok[i1a]])
apertureOuterInstFluxField
apertureInnerInstFluxField
def __init__(self, *config=None)
def _associate_reference_stars(self, lookup_table_handle, visit_cat, fgcm_obj)
def _density_downsample(self, fgcm_obj, star_obs)
def runQuantum(self, butlerQC, inputRefs, outputRefs)
def run(self, *camera, visit_summary_handle_dict, isolated_star_cat_handle_dict, isolated_star_source_handle_dict, lookup_table_handle=None)
def _compute_delta_aper_summary_statistics(self, visit_cat, star_obs)
def _mark_reserve_stars(self, fgcm_obj)
def _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)
def __init__(self, initInputs=None, **kwargs)
def _getReferenceFilterNames(self, visitCat, stdFilterDict, stdLambdaDict)
def fgcmMakeVisitCatalog(self, camera, groupedHandles)
apertureOuterInstFluxField
apertureInnerInstFluxField
doSubtractLocalBackground