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
catalogMatches.py
Go to the documentation of this file.
1 # This file is part of afw.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
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 GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 
22 __all__ = ["makeMergedSchema", "copyIntoCatalog",
23  "matchesToCatalog", "matchesFromCatalog", "copyAliasMapWithPrefix"]
24 
25 import os.path
26 
27 import numpy as np
28 
29 import lsst.pex.exceptions as pexExcept
30 from .schema import Schema
31 from .schemaMapper import SchemaMapper
32 from .base import BaseCatalog
33 from .simple import SimpleCatalog, SimpleTable
34 from .source import SourceCatalog, SourceTable
35 from .match import ReferenceMatch
36 
37 from lsst.utils import getPackageDir
38 
39 
40 def makeMapper(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None):
41  """Create a SchemaMapper between the input source and target schemas
42 
43  @param[in] sourceSchema input source schema that fields will be mapped from
44  @param[in] targetSchema target schema that fields will be mapped to
45  @param[in] sourcePrefix if set, only those keys with that prefix will be mapped
46  @param[in] targetPrefix if set, prepend it to the mapped (target) key name
47 
48  @return SchemaMapper between source and target schemas
49  """
50  m = SchemaMapper(sourceSchema, targetSchema)
51  for key, field in sourceSchema:
52  keyName = field.getName()
53  if sourcePrefix is not None:
54  if not keyName.startswith(sourcePrefix):
55  continue
56  else:
57  keyName = field.getName().replace(sourcePrefix, "", 1)
58  m.addMapping(key, (targetPrefix or "") + keyName)
59  return m
60 
61 
62 def makeMergedSchema(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None):
63  """Return a schema that is a deep copy of a mapping between source and target schemas
64  @param[in] sourceSchema input source schema that fields will be mapped from
65  @param[in] targetSchema target schema that fields will be mapped to
66  @param[in] sourcePrefix if set, only those keys with that prefix will be mapped
67  @param[in] targetPrefix if set, prepend it to the mapped (target) key name
68 
69  @return schema schema that is the result of the mapping between source and target schemas
70  """
71  return makeMapper(sourceSchema, targetSchema, sourcePrefix, targetPrefix).getOutputSchema()
72 
73 
74 def copyIntoCatalog(catalog, target, sourceSchema=None, sourcePrefix=None, targetPrefix=None):
75  """Copy entries from one Catalog into another
76 
77  @param[in] catalog source catalog to be copied from
78  @param[in/out] target target catalog to be copied to (edited in place)
79  @param[in] souceSchema schema of source catalog (optional)
80  @param[in] sourcePrefix if set, only those keys with that prefix will be copied
81  @param[in] targetPrefix if set, prepend it to the copied (target) key name
82  """
83  if sourceSchema is None:
84  sourceSchema = catalog.schema
85 
86  targetSchema = target.schema
87  target.reserve(len(catalog))
88  for i in range(len(target), len(catalog)):
89  target.addNew()
90 
91  if len(catalog) != len(target):
92  raise RuntimeError("Length mismatch: %d vs %d" %
93  (len(catalog), len(target)))
94 
95  m = makeMapper(sourceSchema, targetSchema, sourcePrefix, targetPrefix)
96  for rFrom, rTo in zip(catalog, target):
97  rTo.assign(rFrom, m)
98 
99 
100 def matchesToCatalog(matches, matchMeta):
101  """Denormalise matches into a Catalog of "unpacked matches"
102 
103  @param[in] matches unpacked matches, i.e. a list of Match objects whose schema
104  has "first" and "second" attributes which, resepectively, contain the
105  reference and source catalog entries, and a "distance" field (the
106  measured distance between the reference and source objects)
107  @param[in] matchMeta metadata for matches (must have .add attribute)
108 
109  @return lsst.afw.table.BaseCatalog of matches (with ref_ and src_ prefix identifiers
110  for referece and source entries, respectively, including alias maps
111  from reference and source catalogs)
112  """
113  if len(matches) == 0:
114  raise RuntimeError("No matches provided.")
115 
116  refSchema = matches[0].first.getSchema()
117  srcSchema = matches[0].second.getSchema()
118 
119  mergedSchema = makeMergedSchema(refSchema, Schema(), targetPrefix="ref_")
120  mergedSchema = makeMergedSchema(
121  srcSchema, mergedSchema, targetPrefix="src_")
122 
123  mergedSchema = copyAliasMapWithPrefix(refSchema, mergedSchema, prefix="ref_")
124  mergedSchema = copyAliasMapWithPrefix(srcSchema, mergedSchema, prefix="src_")
125 
126  distKey = mergedSchema.addField(
127  "distance", type=np.float64, doc="Distance between ref and src")
128 
129  mergedCatalog = BaseCatalog(mergedSchema)
130  copyIntoCatalog([m.first for m in matches], mergedCatalog,
131  sourceSchema=refSchema, targetPrefix="ref_")
132  copyIntoCatalog([m.second for m in matches], mergedCatalog,
133  sourceSchema=srcSchema, targetPrefix="src_")
134  for m, r in zip(matches, mergedCatalog):
135  r.set(distKey, m.distance)
136 
137  # obtain reference catalog name if one is setup
138  try:
139  catalogName = os.path.basename(getPackageDir("astrometry_net_data"))
141  catalogName = "NOT_SET"
142  matchMeta.add("REFCAT", catalogName)
143  mergedCatalog.getTable().setMetadata(matchMeta)
144 
145  return mergedCatalog
146 
147 
148 def matchesFromCatalog(catalog, sourceSlotConfig=None):
149  """Generate a list of ReferenceMatches from a Catalog of "unpacked matches"
150 
151  @param[in] catalog catalog of matches. Must have schema where reference entries are
152  prefixed with "ref_" and source entries are prefixed with "src_"
153  @param[in] sourceSlotConfig an lsst.meas.base.baseMeasurement.SourceSlotConfig configuration
154  for source slots (optional)
155 
156  @returns lsst.afw.table.ReferenceMatch of matches
157  """
158  refSchema = makeMergedSchema(
159  catalog.schema, SimpleTable.makeMinimalSchema(), sourcePrefix="ref_")
160  refCatalog = SimpleCatalog(refSchema)
161  copyIntoCatalog(catalog, refCatalog, sourcePrefix="ref_")
162 
163  srcSchema = makeMergedSchema(
164  catalog.schema, SourceTable.makeMinimalSchema(), sourcePrefix="src_")
165  srcCatalog = SourceCatalog(srcSchema)
166  copyIntoCatalog(catalog, srcCatalog, sourcePrefix="src_")
167 
168  if sourceSlotConfig is not None:
169  sourceSlotConfig.setupSchema(srcCatalog.schema)
170 
171  matches = []
172  distKey = catalog.schema.find("distance").key
173  for ref, src, cat in zip(refCatalog, srcCatalog, catalog):
174  matches.append(ReferenceMatch(ref, src, cat[distKey]))
175 
176  return matches
177 
178 
179 def copyAliasMapWithPrefix(inSchema, outSchema, prefix=""):
180  """Copy an alias map from one schema into another
181 
182  This copies the alias map of one schema into another, optionally
183  prepending a prefix to both the "from" and "to" names of the alias
184  (the example use case here is for the "match" catalog created by
185  `lsst.meas.astrom.denormalizeMatches` where prefixes "src_" and
186  "ref_" are added to the source and reference field entries,
187  respectively).
188 
189  Parameters
190  ----------
191  inSchema : `lsst.afw.table.Schema`
192  The input schema whose `lsst.afw.table.AliasMap` is to be
193  copied to ``outSchema``.
194  outSchema : `lsst.afw.table.Schema`
195  The output schema into which the `lsst.afw.table.AliasMap`
196  from ``inSchema`` is to be copied (modified in place).
197  prefix : `str`, optional
198  An optional prefix to add to both the "from" and "to" names
199  of the alias (default is an empty string).
200 
201  Returns
202  -------
203  outSchema : `lsst.afw.table.Schema`
204  The output schema with the alias mappings from `inSchema`
205  added.
206  """
207  for k, v in inSchema.getAliasMap().items():
208  outSchema.getAliasMap().set(prefix + k, prefix + v)
209 
210  return outSchema
CatalogT< BaseRecord > BaseCatalog
Definition: fwd.h:71
def matchesFromCatalog(catalog, sourceSlotConfig=None)
def makeMergedSchema(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None)
def matchesToCatalog(matches, matchMeta)
daf::base::PropertySet * set
Definition: fits.cc:832
std::string getPackageDir(std::string const &packageName)
return the root directory of a setup package
Definition: packaging.cc:33
def makeMapper(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None)
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
def copyIntoCatalog(catalog, target, sourceSchema=None, sourcePrefix=None, targetPrefix=None)
Match< SimpleRecord, SourceRecord > ReferenceMatch
Definition: fwd.h:104
def copyAliasMapWithPrefix(inSchema, outSchema, prefix="")
std::vector< SchemaItem< Flag > > * items
SortedCatalogT< SimpleRecord > SimpleCatalog
Definition: fwd.h:79