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-11039: Implement simple DIAObject #1

Merged
merged 5 commits into from Aug 1, 2017
Merged

Conversation

morriscb
Copy link
Contributor

@morriscb morriscb commented Jul 7, 2017

No description provided.

# is currently contious and if not we make a deep copy.
if not self._dia_source_catalog.isContiguous():
tmp_dia_source_catalog = self._dia_source_catalog.copy(deep=True)
del self._dia_source_catalog
Copy link
Member

Choose a reason for hiding this comment

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

Is this del really necessary? It's very unpythonic.

None
Return
------
An lsst.afw data type
Copy link
Member

Choose a reason for hiding this comment

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

This is imprecise; I don't think this describes a coherent category of return types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to "A SourceRecord column value"

if name != 'coord_ra' and name != 'coord_dec':
continue

mean_value = np.mean(self._dia_source_catalog[name])
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't work for objects that are (e.g.) on the RA=360 line, or sources near the poles. We have a sophisticated set of operations on coordinates and angles in afw, and we should use that here (or extended it in afw as necessary) rather than ad-hoc python computations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See previous comment. The computation also now uses afw.coord.averageCoord

# set the the rms variables to NaN.
if self.n_dia_sources > 1:
self._dia_object_record[name + '_rms'] = afwGeom.Angle(
np.std(self._dia_source_catalog[name]))
Copy link
Member

Choose a reason for hiding this comment

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

Same, should use afw-defined operations or extend afw as necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no method for compute a covariance matrix on a coordinate. See DM-7101

self._dia_object_record[name + '_rms'] = afwGeom.Angle(
np.std(self._dia_source_catalog[name]))
else:
self._dia_object_record[name + '_rms'] = afwGeom.Angle(np.nan)
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if nan is the right answer here? Numpy returns zero for this case. Either way, I don't think this is the right place to make such a choice; belongs in afw.

@@ -175,24 +206,10 @@ def append_dia_source(self, input_dia_source):
# them until we are finished adding sources.
self._updated = False

# Do stuff to append this SourceRecord.
self._dia_source_catalog.append(input_dia_source_record)
Copy link
Member

Choose a reason for hiding this comment

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

Does this copy the source record?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently, this does not copy the source. This will be taken care of by the update method later which deep copies the full catalog. Would it be enough to add a comment to the docstring that the source isn't properly copied until update is run?

@@ -55,12 +70,11 @@ class DIAObject(object):
of DIASources changes and set to true when the initialize method is
run.
"""

def __init__(self, dia_source_catalog, object_source_record=None):
Copy link
Member

Choose a reason for hiding this comment

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

What's the use case for supplying the object source record? To me this is an internal data structure that shouldn't be exposed to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is for the case where you have already created a DIAObject and don't want to rerun the summary statistics on it's corresponding DIASourceCatalog. This would happen, for instance, when you persist DIAObjects and load them on a subsequent visit.

def setUp(self):
""" Create the DIAObjct schema we will use throughout these tests.
"""
self.dia_obj_schema = make_minimal_dia_object_schema()
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't seem to get used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct. This was left over from when before I had the create_test_dia_sources method in the test. I have removed the setUp and tearDown methds.

Copy link
Member

Choose a reason for hiding this comment

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

These functions are still here ...?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Must not have been committed. They are not removed.

def _generate_property_methods(self):
""" Generate methods for accessing values stored in the
def get(self, name):
""" Return the data stored in column name within the internal
Copy link
Member

Choose a reason for hiding this comment

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

If it's internal, then the user can't know about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to stored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Current text changed to "Retrieve a specific summary statistic value from this DIAObject."

None
"""

for name in self.dia_obj_schema.getNames():
Copy link
Member

Choose a reason for hiding this comment

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

This really doesn't need to be a loop; you already know the names of the things you want to compare to.

@morriscb
Copy link
Contributor Author

Committed updated version with incorporated reviewer responses.

def __init__(self, dia_source_catalog, object_source_record=None):
""" Create a DIAObject given an input SourceCatalog of
DIASources.

Takes as input an lsst.afw.table.SourceCatalog object specifying a
Takes as input an lsst.afw.table.SourceCaatlog object specifying a
Copy link
Member

Choose a reason for hiding this comment

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

Typo.

Raise(NotImplementedError)

schema = afwTable.SourceTable.makeMinimalSchema()
# Currently we do not store
Copy link
Member

Choose a reason for hiding this comment

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

Broken sentence


# Currently the covariance of a coordinate is not defined in the
# stack, so we will hold off until it is implemented. This is to be
# addressed in DM-7101.
Copy link
Member

Choose a reason for hiding this comment

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

These comments only make sense if one knows that fields for the ra/dec uncertainty were removed. I'd drop them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Clarified this to say "In the future we would like to use store the convariance but,... etc."

coord_list = [src.getCoord() for src in self._dia_source_catalog]
ave_coord = averageCoord(coord_list)
return ave_coord
self._dia_object_record.setCoord(ave_coord)
Copy link
Member

Choose a reason for hiding this comment

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

Broken; unreachable code.

# Right now I'm making this the same as returning the
# dia_source_catalog.

return self.dia_source_catalog()
Copy link
Member

Choose a reason for hiding this comment

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

This should raise NotImplementedError rather than returning something that you later plan on changing.

sources = create_test_dia_sources(5)
dia_obj = DIAObject(sources, None)

self._compare_dia_object_values(dia_obj, 0, 2.0, 1.4142135623730951)
Copy link
Member

@ctslater ctslater Jul 28, 2017

Choose a reason for hiding this comment

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

I don't think that actually makes it easier; say you now want to compare a mean flux, you'll still have to go to every instance of _compare_dia_object_values and change them. At least make these keyword arguments so they're not just anonymous numbers laying around.

[morriscb] I can't reply to this comment for some reason so I'll "edit it". These tests aren't going to be tests on a catalog and the idea of the function is that the values in the "source catalog" will be incremented in such as way as to make the expected values the same for each variable that is stored in the dia_object. Hence you can just compare to all the values at once and add them all into _compare_dia_object_values.

[morriscb] After testing you I have found you are correct. I have changed the input of the _compare_dia_object_values to an input dictionary of values. who's key will match up columns in the dia_object_record.

self._compare_dia_object_values(dia_obj, 0, 0.0, np.nan)
self._compare_dia_object_values(dia_obj_dup, dia_obj.id, 0.0, np.nan)

def _compare_dia_object_values(self, dia_object, expected_id,
Copy link
Member

Choose a reason for hiding this comment

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

This function is so much nicer now. expected_std should be eliminated since it's unused.

def setUp(self):
""" Create the DIAObjct schema we will use throughout these tests.
"""
self.dia_obj_schema = make_minimal_dia_object_schema()
Copy link
Member

Choose a reason for hiding this comment

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

These functions are still here ...?

Package and classes are eups-able and scons-able
Missed some edits in last commit. Now added.

Implimented second round of reviewer comments

Changed to dictionary of expected values in unittest

Finished second round of reviewer comments.
@morriscb morriscb merged commit 2c21a0f into master Aug 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants