Skip to content

Commit

Permalink
Add functions to generate 'unpacked matches' in a Catalog.
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulPrice committed Sep 25, 2012
1 parent 53a02a1 commit 210fcdc
Showing 1 changed file with 109 additions and 0 deletions.
109 changes: 109 additions & 0 deletions python/hsc/pipe/base/matches.py
@@ -0,0 +1,109 @@
import os.path
import lsst.afw.table as afwTable

def copySchema(schema, target, targetPrefix=None, sourcePrefix=None):
"""Return a deep copy the provided schema
If sourcePrefix is set, only copy those keys that have that prefix.
If targetPrefix is set, add that to the key name.
"""
existing = set(target.getNames())
for keyName in schema.getNames():
if sourcePrefix is not None:
if not keyName.startswith(sourcePrefix):
continue
keyNameFix = keyName[len(sourcePrefix):]
else:
keyNameFix = keyName
if keyNameFix in existing:
continue
field = schema.find(keyName).field
typeStr = field.getTypeString()
fieldDoc = field.getDoc()
fieldUnits = field.getUnits()
if typeStr in ("ArrayF", "ArrayD", "CovF", "CovD"):
fieldSize = field.getSize()
else:
fieldSize = None

target.addField((targetPrefix if targetPrefix is not None else "") + keyNameFix,
type=typeStr, doc=fieldDoc, units=fieldUnits, size=fieldSize)
return target

def copyCatalog(catalog, target, sourceSchema=None, targetPrefix=None, sourcePrefix=None):
"""Copy entries from one Catalog to another.
If sourcePrefix is set, only copy those keys that have that prefix.
If targetPrefix is set, add that to the key name.
"""
if sourceSchema is None:
sourceSchema = catalog.schema

targetSchema = target.schema
target.reserve(len(catalog))
for i in range(len(target), len(catalog)):
target.addNew()

if len(catalog) != len(target):
raise RuntimeError("Length mismatch: %d vs %d" % (len(catalog), len(target)))

sourceKeys = []
targetKeys = []
for k in sourceSchema.getNames():
if sourcePrefix is not None:
if not k.startswith(sourcePrefix):
continue
kFix = k[len(sourcePrefix):]
else:
kFix = k
sourceKeys.append(sourceSchema.find(k).key)
targetKeys.append(targetSchema.find((targetPrefix if targetPrefix is not None else "") + kFix).key)

for rFrom, rTo in zip(catalog, target):
for kFrom, kTo in zip(sourceKeys, targetKeys):
rTo.set(kTo, rFrom.get(kFrom))

return target

def matchesToCatalog(matches, matchMeta):
"""Denormalise matches into a Catalog of "unpacked matches" """

refSchema = matches[0].first.getSchema()
srcSchema = matches[0].second.getSchema()

mergedSchema = copySchema(refSchema, afwTable.Schema(), targetPrefix="ref.")
mergedSchema = copySchema(srcSchema, mergedSchema, targetPrefix="src.")
distKey = mergedSchema.addField("distance", type=float, doc="Distance between ref and src")

mergedCatalog = afwTable.BaseCatalog(mergedSchema)
copyCatalog([m.first for m in matches], mergedCatalog, sourceSchema=refSchema, targetPrefix="ref.")
copyCatalog([m.second for m in matches], mergedCatalog, sourceSchema=srcSchema, targetPrefix="src.")
for m, r in zip(matches, mergedCatalog):
r.set(distKey, m.distance)

# obtaining reference catalog name
catalogName = os.path.basename(os.getenv("ASTROMETRY_NET_DATA_DIR").rstrip('/'))
matchMeta.add('REFCAT', catalogName)
mergedCatalog.getTable().setMetadata(matchMeta)

return mergedCatalog

def matchesFromCatalog(catalog, sourceSlotConfig=None, prefix=""):
"""Generate a list of ReferenceMatches from a Catalog of "unpacked matches" """
refSchema = copySchema(catalog.schema, afwTable.SimpleTable.makeMinimalSchema(), sourcePrefix="ref.")
refCatalog = afwTable.SimpleCatalog(refSchema)
copyCatalog(catalog, refCatalog, sourcePrefix="ref.")

srcSchema = copySchema(catalog.schema, afwTable.SourceTable.makeMinimalSchema(), sourcePrefix="src.")
srcCatalog = afwTable.SourceCatalog(srcSchema)
copyCatalog(catalog, srcCatalog, sourcePrefix="src.")

if sourceSlotConfig is not None:
sourceSlotConfig.setupTable(srcCatalog.table, prefix=prefix)

matches = []
distKey = catalog.schema.find("distance").key
for ref, src, cat in zip(refCatalog, srcCatalog, catalog):
matches.append(afwTable.ReferenceMatch(ref, src, cat[distKey]))

return matches

0 comments on commit 210fcdc

Please sign in to comment.