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-14102 makePsfCandidates is now its own Task #118
Conversation
317b4ae
to
ce1bb65
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks good. Please see the individual comments.
|
||
- starCat catalog of stars that were selected as stars and successfuly made into PSF candidates | ||
(a subset of sourceCat whose records are shallow copies) | ||
- psfCandidates list of PSF candidates (lsst.meas.algorithms.PsfCandidate) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result struct no longer contains psfCandidates
, just starCat
(an lsst.afw.table.ReferenceMatchVector), or None. Some star selectors | ||
will ignore this argument, others may require it. See the usesMatches class variable. | ||
@param[in] isStarField name of flag field to set True for stars, or None to not set a field; | ||
isStarField : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay numpydoc! Please finish these up nicely by adding what flavor of object each parameter is. You may have bonus points if you finish converting the rest of the docstrings in here to numpydoc.
@@ -20,8 +20,6 @@ | |||
# the GNU General Public License along with this program. If not, | |||
# see <https://www.lsstcorp.org/LegalNotices/>. | |||
# | |||
from __future__ import absolute_import, division, print_function | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should technically be in a separate de-python2-ification commit
|
||
vmax = afwMath.makeStatistics(im, afwMath.MAX).getValue() | ||
if not np.isfinite(vmax): | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this vmax
business used for? Again, I realize it was in the original code but it's not clear why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We think it is a way of checking if the candidate cutout image doesn't contain NaN or inf. Whether this is the best approach for that, I don't know. Not knowing more, I'd rather not attempt to clarify it in place.
# The setXXX methods are class static, but it's convenient to call them on | ||
# an instance as we don't know exposures's pixel type | ||
# (and hence psfCandidate's exact type) | ||
if not didSetSize: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You set didSetSize
to False right before this loop, so I'm confused how it could ever be True (and therefore skip this if-block). I realize this was in the original code but I still want to understand it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
psfCandidate
and its parent class SpatialCellImageCandidate
, inappropriately use static
members for border, width, and height (among other things), meaning once you set them, they apply to all psfCandidates. We have to make those not static
if we want to clean up this block. That's going to require an RFC, as according to @PaulPrice there is some code that assumes they are static.
``lsst.meas.algorithms.starSelector.run()``. | ||
exposure : `lsst.afw.image.Exposure` (optional) | ||
The exposure containing the sources. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add isStarField
to the docstring here. The name suggests to me it's a Boolean flag, but defaulting to None
is weird. I'd prefer to have it True/False throughout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I've renamed it starSelectedField
, since it's actually str
, not a bool
.
This is, however, reminding me that we don't have a unittest for makePsfCandidates...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great idea! How about a unit test! 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my work on the new test, I've renamed it again to psfCandidateField
, which I think is even better. And there's a new unittest in another commit.
|
||
|
||
class MakePsfCandidatesTask(pipeBase.Task): | ||
"""Create PSF candiates given an input catalog. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: candidates
tests/test_psfSelectTest.py
Outdated
@@ -298,7 +300,8 @@ def testPsfCandidate(self): | |||
|
|||
# select psf stars | |||
print("PSF selection") | |||
psfCandidateList = self.starSelector.run(exposDist, sourceList).psfCandidates | |||
stars = self.starSelector.run(exposDist, sourceList) | |||
psfCandidateList = self.makePsfCandidates.run(stars.starCat, exposure=exposDist).psfCandidates | |||
|
|||
# determine the PSF | |||
print("PSF determination") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this test really have a bunch of print
statements floating around?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it shouldn't. But there are so many janky things about this test, I don't want to touch it other than to get it to work with the new API.
I also noticed this is failing Travis, but I'm not sure whether that is meaningful or not since we're still in the process of getting Travis set up across the Stack. |
I enabled Travis, but did not set it to block merges of failing code. Once I merge DM-14253 we can require the Travis check to pass in order to merge to master. Just waiting on review. |
d55ac03
to
91abe95
Compare
I've pushed a cleanup commit (no review needed) based on your comments and a new test of |
tests/test_psfCandidate.py
Outdated
@@ -37,46 +36,96 @@ | |||
display = False | |||
|
|||
|
|||
def makeEmptyCatalog(psfCandidateField=''): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you're using ''
as the default rather than just None?
tests/test_psfCandidate.py
Outdated
found = True | ||
print(fp.getBBox()) | ||
break | ||
assert found, "Unable to find central peak in footprint: faulty test" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not immediately clear that this line is asserting found
must be True
and prints the "unable to find..." message if it's False. But if this is the correct/pythonic way to do so, I can live with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the syntax for the python assert
statement. Is the purpose of the assert here clear?
Would you be happier with assert found is True, "sometext"
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's really a question of it looking different because everywhere else in tests you see self.assertTrue(found)
but here you see a bare assert because self
has not been passed in to the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this was in a class that the other test classes inherited from (maybe with multiple inheritance) then the standard scheme could be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, it's supposed to be "is my test even sane?", hence the raw assert.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a note to clarify the purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't use foo is True
; it isn't the same as testing the boolean value of foo
and it's not good Python unless you are sure you need exactly the True
singleton.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right @r-owen I forgot about that. Anyway, I think it should be clear with the comment I added.
tests/test_psfCandidate.py
Outdated
@@ -139,6 +188,48 @@ def testFaintNeighborMasking(self): | |||
self.checkCandidateMasking([(self.x+5, self.y, 0.5)], threshold=0.9, pixelThreshold=1.0) | |||
|
|||
|
|||
class MakePsfCandiatesTaskTest(lsst.utils.tests.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably don't want a typo in the class name ("Candidates") 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clearly I cannot type that word.
tests/test_psfCandidate.py
Outdated
self.badIds = [1, ] | ||
self.goodIds = [2, 3] | ||
# x and y coordinate: keep these in sync with the above good/bad list. | ||
self.xx = [0, 100, 200] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xcoord and ycoord might be nicer variable names than xx and yy
Thanks for adding the test! It looks fine to me. |
Fix existing tests to use new MakePsfCandidatesTask following StarSelectorTask. Add tests for MakePsfCandidates and cleanup existing psfCandidate tests. * Pull out the catalog and false source creation to use in both tests. * Refactor `CandidateMaskingTestCase.createCandidate()` to call `makePsfCandidate` instead of the raw constructor, since that is what is most commonly used elsewhere. * Rename self.exp->self.exposure in CandidateMaskingTestCase.
No description provided.