Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-11155: Implement object count metrics #9

Merged
merged 7 commits into from
Dec 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions python/lsst/ap/association/assoc_db_sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ def load(self, expMd):
----------
expMd : lsst.pipe.base.Struct
A struct object containing:
bbox : A lsst.afw.geom.Box2D.
wcs : A lsst.afw Wcs object.
* bbox : A lsst.afw.geom.Box2D.
* wcs : A lsst.afw Wcs object.

Returns
-------
Expand Down
20 changes: 18 additions & 2 deletions python/lsst/ap/association/association.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,25 @@ def associate_sources(self, dia_collection, dia_sources):
"""
scores = dia_collection.score(
dia_sources, self.config.maxDistArcSeconds * afwGeom.arcseconds)
updated_dia_objects = dia_collection.match(dia_sources, scores)
match_result = dia_collection.match(dia_sources, scores)

self._add_association_meta_data(match_result)

return pipeBase.Struct(
dia_collection=dia_collection,
updated_ids=updated_dia_objects
updated_ids=match_result.updated_and_new_dia_object_ids,
)

def _add_association_meta_data(self, match_result):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this metadata used anywhere, or is it for future development?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in ap_verify. This is a stop gap until the data products AssocationTask produces better routed through the Butler or similar system.

""" Store summaries of the association step in the task metadata.

Parameters
----------
match_result : lsst.pipe.base.Struct
"""
self.metadata.add('numUpdatedDiaObjects',
match_result.n_updated_dia_objects)
self.metadata.add('numNewDiaObjects',
match_result.n_new_dia_objects)
self.metadata.add('numUnassociatedDiaObjects',
match_result.n_unassociated_dia_objects)
31 changes: 25 additions & 6 deletions python/lsst/ap/association/dia_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,24 @@ def match(self, dia_source_catalog, score_struct):

Returns
-------
Ids of newly updated and created DIAObjects
pipeBase.Struct
A struct containing the following data:
* updated_and_new_dia_object_ids : list of ints specifying the ids
new and updated dia_objects in the collection.
* n_updated_dia_objects : number of previously know dia_objects with
newly associated DIASources.
* n_new_dia_objects : Number of newly created DIAObjects from
unassociated DIASources
* n_unupdated_dia_objects : number of previous DIAObjects that were
not associated to a new DIASource.
"""

used_dia_object = np.zeros(len(self.dia_objects), dtype=np.bool)
n_previous_dia_objects = len(self.dia_objects)
used_dia_object = np.zeros(n_previous_dia_objects, dtype=np.bool)
used_dia_source = np.zeros(len(dia_source_catalog), dtype=np.bool)

updated_and_new_dia_objects = []
updated_dia_objects = []
new_dia_objects = []

# We sort from best match to worst to effectively perform a
# "handshake" match where both the DIASources and DIAObjects agree
Expand All @@ -290,7 +301,7 @@ def match(self, dia_source_catalog, score_struct):
used_dia_object[dia_obj_idx] = True
used_dia_source[score_idx] = True
updated_obj_id = score_struct.obj_ids[score_idx]
updated_and_new_dia_objects.append(updated_obj_id)
updated_dia_objects.append(updated_obj_id)

self.dia_objects[dia_obj_idx].append_dia_source(
dia_source_catalog[int(score_idx)])
Expand All @@ -301,12 +312,20 @@ def match(self, dia_source_catalog, score_struct):
tmp_src_cat = afwTable.SourceCatalog(dia_source_catalog.schema)
tmp_src_cat.append(dia_source_catalog[int(src_idx)])
self.append(DIAObject(tmp_src_cat))
updated_and_new_dia_objects.append(
new_dia_objects.append(
self.dia_objects[-1].id)

# Return the ids of the DIAObjects in this DIAObjectCollection that
# were updated or newly created.
return updated_and_new_dia_objects
n_updated_dia_objects = len(updated_dia_objects)
n_unassociated_dia_objects = \
n_previous_dia_objects - n_updated_dia_objects
updated_dia_objects.extend(new_dia_objects)
return pipeBase.Struct(
updated_and_new_dia_object_ids=updated_dia_objects,
n_updated_dia_objects=n_updated_dia_objects,
n_new_dia_objects=len(new_dia_objects),
n_unassociated_dia_objects=n_unassociated_dia_objects,)

@property
def is_updated(self):
Expand Down
15 changes: 11 additions & 4 deletions tests/test_dia_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,12 @@ def test_score_and_match(self):
# except the last DIAObject in this collection which should be
# newly created during the matching step and contain only one
# DIASource.
updated_ids = obj_collection.match(src_cat, score_struct)
match_result = obj_collection.match(src_cat, score_struct)
updated_ids = match_result.updated_and_new_dia_object_ids
self.assertEqual(len(obj_collection.dia_objects), 5)
self.assertEqual(match_result.n_updated_dia_objects, 4)
self.assertEqual(match_result.n_new_dia_objects, 1)
self.assertEqual(match_result.n_unassociated_dia_objects, 0)

for updated_idx, obj_id in enumerate(updated_ids):
if updated_idx == len(updated_ids) - 1:
Expand Down Expand Up @@ -218,12 +222,15 @@ def test_empty_dia_collection(self):
# to machine noise.
self.assertTrue(np.isinf(score_struct.scores[src_idx]))

updated_indices = dia_collection.match(src_cat, score_struct)
self.assertEqual(len(updated_indices), 5)
match_result = dia_collection.match(src_cat, score_struct)
updated_ids = match_result.updated_and_new_dia_object_ids
self.assertEqual(len(dia_collection.dia_objects), 5)
self.assertEqual(match_result.n_updated_dia_objects, 0)
self.assertEqual(match_result.n_new_dia_objects, 5)
self.assertEqual(match_result.n_unassociated_dia_objects, 0)

for idx, obj_id in enumerate(dia_collection.get_dia_object_ids()):
self.assertEqual(obj_id, updated_indices[idx])
self.assertEqual(obj_id, updated_ids[idx])
# We created a new DIAObject in the collection hence the last
# DIAObject in this collection is new and contains only one
# DIASource.
Expand Down