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-11041: Implement simple DIAObject to DIASource matching algorithm and flesh out DIACollection #3

Merged
merged 5 commits into from Sep 7, 2017

Conversation

morriscb
Copy link
Contributor

@morriscb morriscb commented Aug 7, 2017

No description provided.

Copy link
Contributor

@parejkoj parejkoj left a comment

Choose a reason for hiding this comment

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

See comments.

@@ -0,0 +1,34 @@
# the Free Software Foundation, either version 3 of the License, or
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you truncated the start of the license here?

# the GNU General Public License along with this program. If not,
# see <http://www.lsstcorp.org/LegalNotices/>.
#

Copy link
Contributor

Choose a reason for hiding this comment

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

File docstring to say what this is supposed to do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For my future reference this is something that should be included in every file yes?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, module-level docstrings should always exist, even if they are just a sentence:

https://developer.lsst.io/docs/py_docs.html#modules

pass


class AssociationTask(pipeBase.Task):
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs a class docstring to describe what the class is for. (is this just a stub?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For now it is just a stub. The ticket to complete the class is DM-11747.

Copy link
Contributor

Choose a reason for hiding this comment

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

Put that that ticket as a TODO in the class docstring then.

@@ -65,7 +69,7 @@ def __init__(self, dia_objects):
self.dia_objects = dia_objects
self._id_to_index = {}
for idx, dia_object in enumerate(self.dia_objects):
self._id_to_index[dia_object.getId()] = idx
self._id_to_index[dia_object.get('id')] = idx
Copy link
Contributor

Choose a reason for hiding this comment

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

I think getId is slightly preferred, because it doesn't have to look up the "id" key, so its faster.

@@ -106,7 +124,7 @@ def update_dia_objects(self, force=False):

Returns
-------
None
bool successfully updated
Copy link
Contributor

Choose a reason for hiding this comment

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

return type is a separate line from description:

Returns
-------
int
    Description of anonymous integer return value.

obj_collection.update_spatial_tree()
self.assertTrue(obj_collection.is_valid_tree)

self.assertEqual(len(obj_collection.get_dia_object_ids()), 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

These two lines should just be self.assertEqual(obj_collection.get_dia_object_ids(), [1,2]), no?

src_cat = create_test_dia_sources(5)
for src_idx, src in enumerate(src_cat):
edit_source_record(
src, src_idx + 4, 0.1 * src_idx, 0.1 * src_idx, -1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, if you're going to split the args on new lines, do them all (and you shouldn't have to for this one)

DIAObjectCollection.

This also tests that a DIASource that can't be associated within
tolerance is addpended to the DIAObjectCollection as a new
Copy link
Contributor

Choose a reason for hiding this comment

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

addpended?


self.assertFalse(np.isfinite(score_struct.scores[-1]))
for src_idx in range(4):
self.assertAlmostEqual(score_struct.scores[src_idx], 0.0,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why shouldn't they be identically zero?

Copy link
Contributor Author

@morriscb morriscb Sep 5, 2017

Choose a reason for hiding this comment

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

They should be. I'm being a bit cautious here as I don't want to assert that two floats be identically equal. If I don't need to check this I am happy to change it.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's up to you: if you expect that the above items really should have a score of zero, then use exact equality. If you think they should have "very small" scores, then leave it as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll change it to identical then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After testing this, the value is not identically zero (it's of order 1e-19). I've changed the test back to assertAlmostEqual(value1, value2, places=16). I've also added a comment stating that this value should be really close to 0.0 but not identical.


for idx, obj_id in enumerate(obj_collection.get_dia_object_ids()):
self.assertEqual(idx, updated_indices[idx])
if idx != 4:
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is idx==4 different?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've changed this to len(dia_objects) - 1 and added a comment explaining why this index is special.

@timj
Copy link
Member

timj commented Aug 25, 2017

There are quite a few PEP8 violations in the file. Maybe some of them were always there but given the amount of code changing can we fix them? And since we are fixing them, please add a setup.cfg to enable flake8 tests and enable test auto discovery.

@timj timj changed the title tickets/DM-11041: Implement simple DIAObject to DIASource matching algorithm and flesh out DIACollection DM-11041: Implement simple DIAObject to DIASource matching algorithm and flesh out DIACollection Aug 25, 2017
import lsst.afw.table as afwTable
import lsst.pipe.base as pipeBase

from .dia_object import *
Copy link
Member

Choose a reason for hiding this comment

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

Usually we don't allow wildcard imports into a non-__init__.py.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, I don't quite know what you mean be "setup.cfg", Tim. Is this a file I should add to the repository somewhere? If so is there an example you can link me to, please?

Copy link
Contributor

Choose a reason for hiding this comment

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

@morriscb your reply is to the wrong comment of @timj : I think you meant to reply to his comment just above, re: adding setup.cfg.

Unfortunately, @timj it looks like DM-10493 was closed Won't Fix, so I don't know where the documentation for configuring auto-flake8 actually lives...

Copy link
Member

Choose a reason for hiding this comment

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

It would be great if you could enable flake8 testing in this package. You do that by copying a setup.cfg from another package (until I update the dev guide). Something like this is fine:

[flake8]
max-line-length = 110
ignore = E133, E226, E228, N802, N803, N806
exclude = __init__.py

[tool:pytest]
addopts = --flake8
flake8-ignore = E133 E226 E228 N802 N803 N806

Then you enable pytest auto discovery in tests/SConscript by adding pyList=[] to the tests() method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @timj, I tried this and I get "scons: Nothing to be done for `tests'." when using pyList=[] in the tests() method. When I remove this, scons then performs the tests. Could you take a look at the current version that I committed, please, and let me know what is missing? I Copied your text above and put it into setup.cfg in the root directory of the repository.

Copy link
Member

Choose a reason for hiding this comment

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

Are you running with an old weekly? You need current master or weekly _35.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @timj, everything works now and comes up "green".

@timj
Copy link
Member

timj commented Aug 25, 2017

There are at least two real bugs found by flake8:

./python/lsst/ap/association/dia_collection.py:268:52: E712 comparison to False should be 'if cond is False:' or 'if not cond:'
./python/lsst/ap/association/dia_object.py:192:15: F821 undefined name 'NotImplimentedError'

if not self._is_valid_tree:
self.update_spatial_tree()

scores = np.ones(len(dia_source_catalog)) * np.nan
Copy link
Contributor

Choose a reason for hiding this comment

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

If you're just making an array of NaNs, use np.empty, since you don't need to initialize 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.

I need the the NaNs to have a positive sign so that they end up at the end of a sort. I'd like to keep this then, unless there is a way to do this with np.empty

Copy link
Contributor

@parejkoj parejkoj Sep 6, 2017

Choose a reason for hiding this comment

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

Per our conversation, NaN isn't signed in an obvious sense, and what you really want is np.inf(or the negative thereof).

dia_collection.py: Finished first pass implimentation
Added association.py

Fixed bugs in dia_collection and unittest.

Passes most of unittests. Need to edit score and match both within
test and class.
Finished unittest and matching implementation.
Finalized tests for second reviewer pass

Completed responses for second reviewer pass.

Added auto-linting/flake8-ing to scons scrips.

Changed assertEqual in test_dia_collection.py

Also fixed linting in association.py

Fixed spelling error.

Fixed some linting errors in test_dia_collection.py
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

3 participants