LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
loadIndexedReferenceObjects.py
Go to the documentation of this file.
2# LSST Data Management System
3#
4# Copyright 2008-2017 AURA/LSST.
5#
6# This product includes software developed by the
7# LSST Project (http://www.lsst.org/).
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the LSST License Statement and
20# the GNU General Public License along with this program. If not,
21# see <https://www.lsstcorp.org/LegalNotices/>.
22#
23
24__all__ = ["LoadIndexedReferenceObjectsConfig", "LoadIndexedReferenceObjectsTask"]
25
26from .loadReferenceObjects import hasNanojanskyFluxUnits, convertToNanojansky, getFormatVersionFromRefCat
27from lsst.meas.algorithms import getRefFluxField, LoadReferenceObjectsTask, LoadReferenceObjectsConfig
28import lsst.pex.config as pexConfig
29import lsst.pipe.base as pipeBase
30from lsst.utils.timer import timeMethod
31from .indexerRegistry import IndexerRegistry
32
33
35 ref_dataset_name = pexConfig.Field(
36 dtype=str,
37 default='cal_ref_cat',
38 doc='Name of the ingested reference dataset'
39 )
40
41
43 """Load reference objects from an indexed catalog ingested by
44 IngestIndexReferenceTask.
45
46 Parameters
47 ----------
49 Data butler for reading catalogs
50 """
51 ConfigClass = LoadIndexedReferenceObjectsConfig
52 _DefaultName = 'LoadIndexedReferenceObjectsTask'
53
54 def __init__(self, butler, *args, **kwargs):
55 LoadReferenceObjectsTask.__init__(self, *args, **kwargs)
56 self.dataset_configdataset_config = butler.get("ref_cat_config", name=self.configconfig.ref_dataset_name, immediate=True)
57 self.indexerindexer = IndexerRegistry[self.dataset_configdataset_config.indexer.name](self.dataset_configdataset_config.indexer.active)
58 # This needs to come from the loader config, not the dataset_config since directory aliases can
59 # change the path where the shards are found.
60 self.ref_dataset_nameref_dataset_name = self.configconfig.ref_dataset_name
61 self.butlerbutlerbutler = butler
62
63 @timeMethod
64 def loadSkyCircle(self, ctrCoord, radius, filterName, epoch=None, centroids=False):
65 shardIdList, isOnBoundaryList = self.indexerindexer.getShardIds(ctrCoord, radius)
66 shards = self.getShardsgetShards(shardIdList)
67 refCat = self.butlerbutlerbutler.get('ref_cat',
68 dataId=self.indexerindexer.makeDataId('master_schema', self.ref_dataset_nameref_dataset_name),
69 immediate=True)
70
71 # load the catalog, one shard at a time
72 for shard, isOnBoundary in zip(shards, isOnBoundaryList):
73 if shard is None:
74 continue
75 if isOnBoundary:
76 refCat.extend(self._trimToCircle_trimToCircle(shard, ctrCoord, radius))
77 else:
78 refCat.extend(shard)
79
80 # make sure catalog is contiguous: must do this before PM calculations
81 if not refCat.isContiguous():
82 refCat = refCat.copy(True)
83
84 # apply proper motion corrections
85 self.applyProperMotionsapplyProperMotions(refCat, epoch)
86
87 # update version=0 style refcats to have nJy fluxes
88 if self.dataset_configdataset_config.format_version == 0 or not hasNanojanskyFluxUnits(refCat.schema):
89 self.log.warning("Found version 0 reference catalog with old style units in schema.")
90 self.log.warning("run `meas_algorithms/bin/convert_refcat_to_nJy.py` to convert fluxes to nJy.")
91 self.log.warning("See RFC-575 for more details.")
92 refCat = convertToNanojansky(refCat, self.log)
93 else:
94 # For version >= 1, the version should be in the catalog header,
95 # too, and should be consistent with the version in the config.
96 catVersion = getFormatVersionFromRefCat(refCat)
97 if catVersion != self.dataset_configdataset_config.format_version:
98 raise RuntimeError(f"Format version in reference catalog ({catVersion}) does not match"
99 f" format_version field in config ({self.dataset_config.format_version})")
100
101 expandedCat = self._remapReferenceCatalogSchema_remapReferenceCatalogSchema(refCat,
102 anyFilterMapsToThis=self.configconfig.anyFilterMapsToThis,
103 filterMap=self.configconfig.filterMap,
104 centroids=centroids)
105 fluxField = getRefFluxField(refCat.schema, filterName)
106
107 # return reference catalog
108 return pipeBase.Struct(
109 refCat=expandedCat,
110 fluxField=fluxField,
111 )
112
113 def getShards(self, shardIdList):
114 """Get shards by ID.
115
116 Parameters
117 ----------
118 shardIdList : `list` of `int`
119 A list of integer shard ids.
120
121 Returns
122 -------
123 catalogs : `list` of `lsst.afw.table.SimpleCatalog`
124 A list of reference catalogs, one for each entry in shardIdList.
125 """
126 shards = []
127 for shardId in shardIdList:
128 if self.butlerbutlerbutler.datasetExists('ref_cat',
129 dataId=self.indexerindexer.makeDataId(shardId, self.ref_dataset_nameref_dataset_name)):
130 shards.append(self.butlerbutlerbutler.get('ref_cat',
131 dataId=self.indexerindexer.makeDataId(shardId, self.ref_dataset_nameref_dataset_name),
132 immediate=True))
133 return shards
134
135 def _trimToCircle(self, refCat, ctrCoord, radius):
136 """Trim a reference catalog to a circular aperture.
137
138 Parameters
139 ----------
141 Reference catalog to be trimmed.
142 ctrCoord : `lsst.geom.SpherePoint`
143 ICRS center of search region.
144 radius : `lsst.geom.Angle`
145 Radius of search region.
146
147 Returns
148 -------
150 Catalog containing objects that fall in the circular aperture.
151 """
152 tempCat = type(refCat)(refCat.schema)
153 for record in refCat:
154 if record.getCoord().separation(ctrCoord) < radius:
155 tempCat.append(record)
156 return tempCat
table::Key< int > type
Definition: Detector.cc:163
Custom catalog class for record/table subclasses that are guaranteed to have an ID,...
Definition: SortedCatalog.h:42
A class representing an angle.
Definition: Angle.h:128
Point in an unspecified spherical coordinate system.
Definition: SpherePoint.h:57
def loadSkyCircle(self, ctrCoord, radius, filterName, epoch=None, centroids=False)
def _remapReferenceCatalogSchema(refCat, *anyFilterMapsToThis=None, filterMap=None, centroids=False)
def convertToNanojansky(catalog, log, doConvert=True)
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations.