lsst.afw
g41b6eb5643+4d2cc932f6
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
afw
table
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
"reindexCatalog"
]
25
26
import
numpy
as
np
27
28
from
._schema
import
Schema
29
from
._schemaMapper
import
SchemaMapper
30
from
._base
import
BaseCatalog
31
from
._table
import
SimpleTable
32
from
._simple
import
SimpleCatalog
33
from
._source
import
SourceCatalog, SourceTable
34
from
._match
import
ReferenceMatch
35
36
37
def
makeMapper
(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None):
38
"""Create a SchemaMapper between the input source and target schemas.
39
40
Parameters
41
----------
42
sourceSchema : :py:class:`lsst.afw.table.Schema`
43
Input source schema that fields will be mapped from.
44
targetSchema : :py:class:`lsst.afw.table.Schema`
45
Target schema that fields will be mapped to.
46
sourcePrefix : `str`, optional
47
If set, only those keys with that prefix will be mapped.
48
targetPrefix : `str`, optional
49
If set, prepend it to the mapped (target) key name.
50
51
Returns
52
-------
53
SchemaMapper : :py:class:`lsst.afw.table.SchemaMapper`
54
Mapping between source and target schemas.
55
"""
56
m =
SchemaMapper
(sourceSchema, targetSchema)
57
for
key, field
in
sourceSchema:
58
keyName = field.getName()
59
if
sourcePrefix
is
not
None
:
60
if
not
keyName.startswith(sourcePrefix):
61
continue
62
else
:
63
keyName = field.getName().replace(sourcePrefix,
""
, 1)
64
m.addMapping(key, (targetPrefix
or
""
) + keyName)
65
return
m
66
67
68
def
makeMergedSchema
(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None):
69
"""Return a schema that is a deep copy of a mapping between source and target schemas.
70
71
Parameters
72
----------
73
sourceSchema : :py:class:`lsst.afw.table.Schema`
74
Input source schema that fields will be mapped from.
75
targetSchema : :py:class:`lsst.afw.atable.Schema`
76
Target schema that fields will be mapped to.
77
sourcePrefix : `str`, optional
78
If set, only those keys with that prefix will be mapped.
79
targetPrefix : `str`, optional
80
If set, prepend it to the mapped (target) key name.
81
82
Returns
83
-------
84
schema : :py:class:`lsst.afw.table.Schema`
85
Schema that is the result of the mapping between source and target schemas.
86
"""
87
return
makeMapper
(sourceSchema, targetSchema, sourcePrefix, targetPrefix).getOutputSchema()
88
89
90
def
copyIntoCatalog
(catalog, target, sourceSchema=None, sourcePrefix=None, targetPrefix=None):
91
"""Copy entries from one Catalog into another.
92
93
Parameters
94
----------
95
catalog : :py:class:`lsst.afw.table.base.Catalog`
96
Source catalog to be copied from.
97
target : :py:class:`lsst.afw.table.base.Catalog`
98
Target catalog to be copied to (edited in place).
99
sourceSchema : :py:class:`lsst.afw.table.Schema`, optional
100
Schema of source catalog.
101
sourcePrefix : `str`, optional
102
If set, only those keys with that prefix will be copied.
103
targetPrefix : `str`, optional
104
If set, prepend it to the copied (target) key name
105
106
Returns
107
-------
108
target : :py:class:`lsst.afw.table.base.Catalog`
109
Target catalog that is edited in place.
110
"""
111
if
sourceSchema
is
None
:
112
sourceSchema = catalog.schema
113
114
targetSchema = target.schema
115
target.reserve(len(catalog))
116
for
i
in
range(len(target), len(catalog)):
117
target.addNew()
118
119
if
len(catalog) != len(target):
120
raise
RuntimeError(f
"Length mismatch: {len(catalog)} vs {len(target)}"
)
121
122
m =
makeMapper
(sourceSchema, targetSchema, sourcePrefix, targetPrefix)
123
for
rFrom, rTo
in
zip(catalog, target):
124
rTo.assign(rFrom, m)
125
126
127
def
matchesToCatalog
(matches, matchMeta):
128
"""Denormalise matches into a Catalog of "unpacked matches".
129
130
Parameters
131
----------
132
matches : `~lsst.afw.table.match.SimpleMatch`
133
Unpacked matches, i.e. a list of Match objects whose schema
134
has "first" and "second" attributes which, resepectively,
135
contain the reference and source catalog entries, and a
136
"distance" field (the measured distance between the reference
137
and source objects).
138
matchMeta : `~lsst.daf.base.PropertySet`
139
Metadata for matches (must have .add attribute).
140
141
Returns
142
-------
143
mergedCatalog : :py:class:`lsst.afw.table.BaseCatalog`
144
Catalog of matches (with ``ref_`` and ``src_`` prefix identifiers for
145
referece and source entries, respectively, including alias
146
maps from reference and source catalogs)
147
"""
148
if
len(matches) == 0:
149
raise
RuntimeError(
"No matches provided."
)
150
151
refSchema = matches[0].first.getSchema()
152
srcSchema = matches[0].second.getSchema()
153
154
mergedSchema =
makeMergedSchema
(refSchema,
Schema
(), targetPrefix=
"ref_"
)
155
mergedSchema =
makeMergedSchema
(
156
srcSchema, mergedSchema, targetPrefix=
"src_"
)
157
158
mergedSchema =
copyAliasMapWithPrefix
(refSchema, mergedSchema, prefix=
"ref_"
)
159
mergedSchema =
copyAliasMapWithPrefix
(srcSchema, mergedSchema, prefix=
"src_"
)
160
161
distKey = mergedSchema.addField(
162
"distance"
, type=np.float64, doc=
"Distance between ref and src"
)
163
164
mergedCatalog =
BaseCatalog
(mergedSchema)
165
copyIntoCatalog
([m.first
for
m
in
matches], mergedCatalog,
166
sourceSchema=refSchema, targetPrefix=
"ref_"
)
167
copyIntoCatalog
([m.second
for
m
in
matches], mergedCatalog,
168
sourceSchema=srcSchema, targetPrefix=
"src_"
)
169
for
m, r
in
zip(matches, mergedCatalog):
170
r.set(distKey, m.distance)
171
172
# The reference catalog is not known.
173
catalogName =
"NOT_SET"
174
matchMeta.add(
"REFCAT"
, catalogName)
175
mergedCatalog.getTable().setMetadata(matchMeta)
176
177
return
mergedCatalog
178
179
180
def
matchesFromCatalog
(catalog, sourceSlotConfig=None):
181
"""Generate a list of ReferenceMatches from a Catalog of "unpacked matches".
182
183
Parameters
184
----------
185
catalog : :py:class:`lsst.afw.table.BaseCatalog`
186
Catalog of matches. Must have schema where reference entries
187
are prefixed with ``ref_`` and source entries are prefixed with
188
``src_``.
189
sourceSlotConfig : `lsst.meas.base.baseMeasurement.SourceSlotConfig`, optional
190
Configuration for source slots.
191
192
Returns
193
-------
194
matches : :py:class:`lsst.afw.table.ReferenceMatch`
195
List of matches.
196
"""
197
refSchema =
makeMergedSchema
(
198
catalog.schema, SimpleTable.makeMinimalSchema(), sourcePrefix=
"ref_"
)
199
refCatalog =
SimpleCatalog
(refSchema)
200
copyIntoCatalog
(catalog, refCatalog, sourcePrefix=
"ref_"
)
201
202
srcSchema =
makeMergedSchema
(
203
catalog.schema, SourceTable.makeMinimalSchema(), sourcePrefix=
"src_"
)
204
srcCatalog =
SourceCatalog
(srcSchema)
205
copyIntoCatalog
(catalog, srcCatalog, sourcePrefix=
"src_"
)
206
207
if
sourceSlotConfig
is
not
None
:
208
sourceSlotConfig.setupSchema(srcCatalog.schema)
209
210
matches = []
211
distKey = catalog.schema.find(
"distance"
).key
212
for
ref, src, cat
in
zip(refCatalog, srcCatalog, catalog):
213
matches.append(
ReferenceMatch
(ref, src, cat[distKey]))
214
215
return
matches
216
217
218
def
copyAliasMapWithPrefix
(inSchema, outSchema, prefix=""):
219
"""Copy an alias map from one schema into another.
220
221
This copies the alias map of one schema into another, optionally
222
prepending a prefix to both the "from" and "to" names of the alias
223
(the example use case here is for the "match" catalog created by
224
`lsst.meas.astrom.denormalizeMatches` where prefixes ``src_`` and
225
``ref_`` are added to the source and reference field entries,
226
respectively).
227
228
Parameters
229
----------
230
inSchema : `lsst.afw.table.Schema`
231
The input schema whose `lsst.afw.table.AliasMap` is to be
232
copied to ``outSchema``.
233
outSchema : `lsst.afw.table.Schema`
234
The output schema into which the `lsst.afw.table.AliasMap`
235
from ``inSchema`` is to be copied (modified in place).
236
prefix : `str`, optional
237
An optional prefix to add to both the "from" and "to" names
238
of the alias (default is an empty string).
239
240
Returns
241
-------
242
outSchema : `lsst.afw.table.Schema`
243
The output schema with the alias mappings from `inSchema`
244
added.
245
"""
246
for
k, v
in
inSchema.getAliasMap().items():
247
outSchema.getAliasMap().set(prefix + k, prefix + v)
248
249
return
outSchema
250
251
252
def
reindexCatalog
(catalog, indices, deep=True):
253
"""Apply a numpy index array to an afw Catalog
254
255
Parameters
256
----------
257
catalog : `lsst.afw.table.SourceCatalog`
258
Catalog to reindex.
259
indices : `numpy.ndarray` of `int`
260
Index array.
261
deep : `bool`
262
Whether or not to make a deep copy of the original catalog.
263
264
Returns
265
-------
266
new : subclass of `lsst.afw.table.BaseCatalog`
267
Reindexed catalog. Records are shallow copies of those in ``catalog``.
268
"""
269
new =
SourceCatalog
(catalog.table.clone()
if
deep
else
catalog.table)
270
records = [catalog[int(ii)]
for
ii
in
indices]
271
new.extend(records, deep=deep)
272
return
new
lsst::afw::table._schema.Schema
Definition
_schema.py:91
lsst::afw::table._schemaMapper.SchemaMapper
Definition
_schemaMapper.py:32
lsst::afw::table._source.SourceCatalog
Definition
_source.py:33
lsst::afw::table::CatalogT< BaseRecord >
lsst::afw::table::SortedCatalogT< SimpleRecord >
lsst::afw::table.catalogMatches.makeMapper
makeMapper(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None)
Definition
catalogMatches.py:37
lsst::afw::table.catalogMatches.copyAliasMapWithPrefix
copyAliasMapWithPrefix(inSchema, outSchema, prefix="")
Definition
catalogMatches.py:218
lsst::afw::table.catalogMatches.matchesFromCatalog
matchesFromCatalog(catalog, sourceSlotConfig=None)
Definition
catalogMatches.py:180
lsst::afw::table.catalogMatches.reindexCatalog
reindexCatalog(catalog, indices, deep=True)
Definition
catalogMatches.py:252
lsst::afw::table.catalogMatches.copyIntoCatalog
copyIntoCatalog(catalog, target, sourceSchema=None, sourcePrefix=None, targetPrefix=None)
Definition
catalogMatches.py:90
lsst::afw::table.catalogMatches.matchesToCatalog
matchesToCatalog(matches, matchMeta)
Definition
catalogMatches.py:127
lsst::afw::table.catalogMatches.makeMergedSchema
makeMergedSchema(sourceSchema, targetSchema, sourcePrefix=None, targetPrefix=None)
Definition
catalogMatches.py:68
lsst::afw::table::Match< SimpleRecord, SourceRecord >
Generated on
for lsst.afw by
1.17.0