-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add function to convert matches to denormalized catalog
This produces persisted catalogs that are easier to read, even though they take more space.
- Loading branch information
Showing
3 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import lsst.afw.table | ||
|
||
__all__ = ["denormalizeMatches"] | ||
|
||
def denormalizeMatches(matches, matchMeta=None): | ||
"""Generate a denormalized Catalog of matches | ||
This is intended for writing matches in a convenient way. | ||
Normally we write matches in a 'normalized' form: recording only the join | ||
table (reference ID, source ID) to minimise space (the reference and source | ||
catalogs should both be available separately, so the only extra information | ||
we need is how to join them). However, using that can be a pain, since it | ||
requires reading each catalog and doing the join. | ||
This function generates a Catalog containing all the information in the | ||
matches. The reference catalog entries are in columns with "ref_" | ||
prepended, while the source catalog entries are in columns with "src_" | ||
prepended. The distance between the matches is in a column named | ||
"distance". | ||
Parameters | ||
---------- | ||
matches : `list` of `lsst.afw.table.ReferenceMatch` | ||
List of matches between reference catalog and source catalog. | ||
matchMeta : `lsst.daf.base.PropertyList` | ||
Matching metadata to write in catalog. | ||
Returns | ||
------- | ||
catalog : `lsst.afw.table.BaseCatalog` | ||
Catalog containing matchlist entries. | ||
See also | ||
-------- | ||
`lsst.afw.table.packMatches` | ||
""" | ||
if len(matches) == 0: | ||
raise RuntimeError("No matches provided.") | ||
|
||
refSchema = matches[0].first.getSchema() | ||
srcSchema = matches[0].second.getSchema() | ||
|
||
refMapper, srcMapper = lsst.afw.table.SchemaMapper.join([refSchema, srcSchema], ["ref_", "src_"]) | ||
schema = refMapper.editOutputSchema() | ||
distKey = schema.addField("distance", type=float, doc="Distance between ref and src") | ||
|
||
catalog = lsst.afw.table.BaseCatalog(schema) | ||
catalog.reserve(len(matches)) | ||
for mm in matches: | ||
row = catalog.addNew() | ||
row.assign(mm.first, refMapper) | ||
row.assign(mm.second, srcMapper) | ||
row.set(distKey, mm.distance) | ||
|
||
if matchMeta is not None: | ||
catalog.getTable().setMetadata(matchMeta) | ||
|
||
return catalog |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import sys | ||
import unittest | ||
|
||
import lsst.afw.geom | ||
import lsst.afw.table | ||
|
||
from lsst.meas.astrom import denormalizeMatches | ||
|
||
class DenormalizeMatchesTestCase(unittest.TestCase): | ||
"""Test the behaviour of the denormalizedMatches function""" | ||
|
||
def checkDenormalizeMatches(self, refType, srcType, MatchClass, num=10): | ||
"""Check that denormalizeMatches works | ||
We create reference and source catalogs, generate matches, | ||
run denormalizeMatches and verify that the results are as expected. | ||
Parameters | ||
---------- | ||
refType : `str` | ||
Type of reference catalog/table; "Simple" or "Source". | ||
srcType : `str` | ||
Type of source catalog/table; "Simple" or "Source". | ||
MatchClass : `type` | ||
Class for match; should be suitable for the refType and srcType. | ||
""" | ||
refSchema = getattr(lsst.afw.table, refType + "Table").makeMinimalSchema() | ||
refCat = getattr(lsst.afw.table, refType + "Catalog")(refSchema) | ||
for ii in range(num): | ||
ref = refCat.addNew() | ||
ref.set("id", ii) | ||
|
||
srcSchema = getattr(lsst.afw.table, srcType + "Table").makeMinimalSchema() | ||
srcCat = getattr(lsst.afw.table, srcType + "Catalog")(srcSchema) | ||
for ii in range(2*num, num, -1): | ||
src = srcCat.addNew() | ||
src.set("id", ii) | ||
|
||
matches = [MatchClass(ref, src, ref.get("id")) for ref, src in zip(refCat, srcCat)] | ||
catalog = denormalizeMatches(matches) | ||
for row, ref, src in zip(catalog, refCat, srcCat): | ||
self.assertEqual(row.get("ref_id"), ref.get("id")) | ||
self.assertEqual(row.get("src_id"), src.get("id")) | ||
self.assertEqual(row.get("distance"), ref.get("id")) | ||
|
||
def testDenormalizeMatches(self): | ||
"""Test denormalizeMatches for various types""" | ||
for args in (("Simple", "Simple", lsst.afw.table.SimpleMatch), | ||
("Simple", "Source", lsst.afw.table.ReferenceMatch), | ||
("Source", "Source", lsst.afw.table.SourceMatch), | ||
): | ||
self.checkDenormalizeMatches(*args) | ||
|
||
|
||
class MemoryTester(lsst.utils.tests.MemoryTestCase): | ||
pass | ||
|
||
|
||
def setup_module(module): | ||
lsst.utils.tests.init() | ||
|
||
|
||
if __name__ == "__main__": | ||
setup_module(sys.modules[__name__]) | ||
unittest.main() |