Coverage for python/lsst/meas/algorithms/loadIndexedReferenceObjects.py : 21%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#
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#
24__all__ = ["LoadIndexedReferenceObjectsConfig", "LoadIndexedReferenceObjectsTask"]
26from .loadReferenceObjects import hasNanojanskyFluxUnits, convertToNanojansky, getFormatVersionFromRefCat
27from lsst.meas.algorithms import getRefFluxField, LoadReferenceObjectsTask, LoadReferenceObjectsConfig
28import lsst.afw.table as afwTable
29import lsst.pex.config as pexConfig
30import lsst.pipe.base as pipeBase
31from lsst.utils.timer import timeMethod
32from .indexerRegistry import IndexerRegistry
35class LoadIndexedReferenceObjectsConfig(LoadReferenceObjectsConfig):
36 ref_dataset_name = pexConfig.Field(
37 dtype=str,
38 default='cal_ref_cat',
39 doc='Name of the ingested reference dataset'
40 )
43class LoadIndexedReferenceObjectsTask(LoadReferenceObjectsTask):
44 """Load reference objects from an indexed catalog ingested by
45 IngestIndexReferenceTask.
47 Parameters
48 ----------
49 butler : `lsst.daf.persistence.Butler`
50 Data butler for reading catalogs
51 """
52 ConfigClass = LoadIndexedReferenceObjectsConfig
53 _DefaultName = 'LoadIndexedReferenceObjectsTask'
55 def __init__(self, butler, *args, **kwargs):
56 LoadReferenceObjectsTask.__init__(self, *args, **kwargs)
57 self.dataset_config = butler.get("ref_cat_config", name=self.config.ref_dataset_name, immediate=True)
58 self.indexer = IndexerRegistry[self.dataset_config.indexer.name](self.dataset_config.indexer.active)
59 # This needs to come from the loader config, not the dataset_config since directory aliases can
60 # change the path where the shards are found.
61 self.ref_dataset_name = self.config.ref_dataset_name
62 self.butler = butler
64 @timeMethod
65 def loadSkyCircle(self, ctrCoord, radius, filterName=None, epoch=None, centroids=False):
66 shardIdList, isOnBoundaryList = self.indexer.getShardIds(ctrCoord, radius)
67 shards = self.getShards(shardIdList)
68 refCat = self.butler.get('ref_cat',
69 dataId=self.indexer.makeDataId('master_schema', self.ref_dataset_name),
70 immediate=True)
72 # load the catalog, one shard at a time
73 for shard, isOnBoundary in zip(shards, isOnBoundaryList):
74 if shard is None:
75 continue
76 if isOnBoundary:
77 refCat.extend(self._trimToCircle(shard, ctrCoord, radius))
78 else:
79 refCat.extend(shard)
81 # make sure catalog is contiguous: must do this before PM calculations
82 if not refCat.isContiguous():
83 refCat = refCat.copy(True)
85 # apply proper motion corrections
86 self.applyProperMotions(refCat, epoch)
88 # update version=0 style refcats to have nJy fluxes
89 if self.dataset_config.format_version == 0 or not hasNanojanskyFluxUnits(refCat.schema):
90 self.log.warning("Found version 0 reference catalog with old style units in schema.")
91 self.log.warning("run `meas_algorithms/bin/convert_refcat_to_nJy.py` to convert fluxes to nJy.")
92 self.log.warning("See RFC-575 for more details.")
93 refCat = convertToNanojansky(refCat, self.log)
94 else:
95 # For version >= 1, the version should be in the catalog header,
96 # too, and should be consistent with the version in the config.
97 catVersion = getFormatVersionFromRefCat(refCat)
98 if catVersion != self.dataset_config.format_version:
99 raise RuntimeError(f"Format version in reference catalog ({catVersion}) does not match"
100 f" format_version field in config ({self.dataset_config.format_version})")
102 self._addFluxAliases(refCat.schema)
103 fluxField = getRefFluxField(schema=refCat.schema, filterName=filterName)
105 if centroids:
106 # add and initialize centroid and hasCentroid fields (these are
107 # added after loading to avoid wasting space in the saved catalogs)
108 # the new fields are automatically initialized to (nan, nan) and
109 # False so no need to set them explicitly
110 mapper = afwTable.SchemaMapper(refCat.schema, True)
111 mapper.addMinimalSchema(refCat.schema, True)
112 mapper.editOutputSchema().addField("centroid_x", type=float)
113 mapper.editOutputSchema().addField("centroid_y", type=float)
114 mapper.editOutputSchema().addField("hasCentroid", type="Flag")
115 expandedCat = afwTable.SimpleCatalog(mapper.getOutputSchema())
116 expandedCat.extend(refCat, mapper=mapper)
117 refCat = expandedCat
119 # return reference catalog
120 return pipeBase.Struct(
121 refCat=refCat,
122 fluxField=fluxField,
123 )
125 def getShards(self, shardIdList):
126 """Get shards by ID.
128 Parameters
129 ----------
130 shardIdList : `list` of `int`
131 A list of integer shard ids.
133 Returns
134 -------
135 catalogs : `list` of `lsst.afw.table.SimpleCatalog`
136 A list of reference catalogs, one for each entry in shardIdList.
137 """
138 shards = []
139 for shardId in shardIdList:
140 if self.butler.datasetExists('ref_cat',
141 dataId=self.indexer.makeDataId(shardId, self.ref_dataset_name)):
142 shards.append(self.butler.get('ref_cat',
143 dataId=self.indexer.makeDataId(shardId, self.ref_dataset_name),
144 immediate=True))
145 return shards
147 def _trimToCircle(self, refCat, ctrCoord, radius):
148 """Trim a reference catalog to a circular aperture.
150 Parameters
151 ----------
152 refCat : `lsst.afw.table.SimpleCatalog`
153 Reference catalog to be trimmed.
154 ctrCoord : `lsst.geom.SpherePoint`
155 ICRS center of search region.
156 radius : `lsst.geom.Angle`
157 Radius of search region.
159 Returns
160 -------
161 catalog : `lsst.afw.table.SimpleCatalog`
162 Catalog containing objects that fall in the circular aperture.
163 """
164 tempCat = type(refCat)(refCat.schema)
165 for record in refCat:
166 if record.getCoord().separation(ctrCoord) < radius:
167 tempCat.append(record)
168 return tempCat