LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
LSSTDataManagementBasePackage
loadIndexedReferenceObjects.py
Go to the documentation of this file.
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 #
23 
24 __all__ = ["LoadIndexedReferenceObjectsConfig", "LoadIndexedReferenceObjectsTask"]
25 
26 from lsst.meas.algorithms import getRefFluxField, LoadReferenceObjectsTask, LoadReferenceObjectsConfig
27 import lsst.afw.table as afwTable
28 import lsst.geom
29 import lsst.pex.config as pexConfig
30 import lsst.pipe.base as pipeBase
31 from .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  ----------
48  butler : `lsst.daf.persistence.Butler`
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  dataset_config = butler.get("ref_cat_config", name=self.config.ref_dataset_name, immediate=True)
57  self.indexer = IndexerRegistry[dataset_config.indexer.name](dataset_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_name = self.config.ref_dataset_name
61  self.butler = butler
62 
63  @pipeBase.timeMethod
64  def loadSkyCircle(self, ctrCoord, radius, filterName=None, epoch=None):
65  shardIdList, isOnBoundaryList = self.indexer.getShardIds(ctrCoord, radius)
66  shards = self.getShards(shardIdList)
67  refCat = self.butler.get('ref_cat',
68  dataId=self.indexer.makeDataId('master_schema', self.ref_dataset_name),
69  immediate=True)
70  self._addFluxAliases(refCat.schema)
71  fluxField = getRefFluxField(schema=refCat.schema, filterName=filterName)
72  for shard, isOnBoundary in zip(shards, isOnBoundaryList):
73  if shard is None:
74  continue
75  if isOnBoundary:
76  refCat.extend(self._trimToCircle(shard, ctrCoord, radius))
77  else:
78  refCat.extend(shard)
79 
80  if epoch is not None and "pm_ra" in refCat.schema:
81  # check for a catalog in a non-standard format
82  if isinstance(refCat.schema["pm_ra"].asKey(), lsst.afw.table.KeyAngle):
83  self.applyProperMotions(refCat, epoch)
84  else:
85  self.log.warn("Catalog pm_ra field is not an Angle; not applying proper motion")
86 
87  # add and initialize centroid and hasCentroid fields (these are
88  # added after loading to avoid wasting space in the saved catalogs)
89  # the new fields are automatically initialized to (nan, nan) and
90  # False so no need to set them explicitly
91  mapper = afwTable.SchemaMapper(refCat.schema, True)
92  mapper.addMinimalSchema(refCat.schema, True)
93  mapper.editOutputSchema().addField("centroid_x", type=float)
94  mapper.editOutputSchema().addField("centroid_y", type=float)
95  mapper.editOutputSchema().addField("hasCentroid", type="Flag")
96  expandedCat = afwTable.SimpleCatalog(mapper.getOutputSchema())
97  expandedCat.extend(refCat, mapper=mapper)
98  del refCat # avoid accidentally returning the unexpanded ref cat
99 
100  # make sure catalog is contiguous
101  if not expandedCat.isContiguous():
102  expandedCat = expandedCat.copy(True)
103 
104  # return reference catalog
105  return pipeBase.Struct(
106  refCat=expandedCat,
107  fluxField=fluxField,
108  )
109 
110  def getShards(self, shardIdList):
111  """Get shards by ID.
112 
113  Parameters
114  ----------
115  shardIdList : `list` of `int`
116  A list of integer shard ids.
117 
118  Returns
119  -------
120  catalogs : `list` of `lsst.afw.table.SimpleCatalog`
121  A list of reference catalogs, one for each entry in shardIdList.
122  """
123  shards = []
124  for shardId in shardIdList:
125  if self.butler.datasetExists('ref_cat',
126  dataId=self.indexer.makeDataId(shardId, self.ref_dataset_name)):
127  shards.append(self.butler.get('ref_cat',
128  dataId=self.indexer.makeDataId(shardId, self.ref_dataset_name),
129  immediate=True))
130  return shards
131 
132  def _trimToCircle(self, refCat, ctrCoord, radius):
133  """Trim a reference catalog to a circular aperture.
134 
135  Parameters
136  ----------
137  refCat : `lsst.afw.table.SimpleCatalog`
138  Reference catalog to be trimmed.
139  ctrCoord : `lsst.geom.SpherePoint`
140  ICRS center of search region.
141  radius : `lsst.geom.Angle`
142  Radius of search region.
143 
144  Returns
145  -------
146  catalog : `lsst.afw.table.SimpleCatalog`
147  Catalog containing objects that fall in the circular aperture.
148  """
149  tempCat = type(refCat)(refCat.schema)
150  for record in refCat:
151  if record.getCoord().separation(ctrCoord) < radius:
152  tempCat.append(record)
153  return tempCat
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:21
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations...
table::Key< int > type
Definition: Detector.cc:164
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
Definition: fwd.h:63
Abstract base class to load objects from reference catalogs.