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-14153 count measured and reference stars after outlier rejection #82
Conversation
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 add a unit test for countStars
I am very uneasy about your first commit and suggest ditching it. I agree it simplifies the call signature of many methods, but the cost is that your task now has state, which is a violation of our task guidelines http://doxygen.lsst.codes/stack/doxygen/x_masterDoxyDoc/pipe_tasks_write_task.html
python/lsst/jointcal/jointcal.py
Outdated
def check_stars(self): | ||
"""Count measured and reference stars per ccd and warn/log them.""" | ||
for ccdImage in self.associations.getCcdImageList(): | ||
stars = ccdImage.countStars() |
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 strongly suggest unpacking the returned value into nMeasStars
and nRefStars
or similar. I think it would make the code clearer, because the name stars
sounds like a collection of star objects, not a count or pair of counts, and stars
gives no hint as to which component is which.
include/lsst/jointcal/CcdImage.h
Outdated
/** | ||
* Count the number of valid measured and reference stars that fall within this ccdImage. | ||
* | ||
* @return (measured, reference) stars in the image. |
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.
Consider adding "number of" before (measured", just to emphasize that this is a pair of counts, not a pair of collections of star objects. It duplicates the brief description, so I certainly won't insist.
python/lsst/jointcal/jointcal.py
Outdated
if stars[1] < self.config.minRefStarsPerCcd: | ||
self.log.warn("ccdImage %s has only %s RefStars (desired %s)", | ||
ccdImage.getName(), stars[1], self.config.minRefStarsPerCcd) | ||
|
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.
Can you do more than just log a warning if a count is too low? Is there a threshold for either value below which the fit should give up (e.g. one or two additional config parameters)?
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.
That is a very good question. I think I'd rather start by issuing warnings now, and turn it into a raise
or equivalent after we've gotten a sense of how often it triggers. Right now, I just want to know about it as part of debugging things, and I don't really have a good sense for what an appropriately "safe" value is a priori. @TallJimbo might have opinions there, though?
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 probably possible to come up with a minimum for at least some specific models from first principles, but I think it's probably most productive to just log things for now.
src/CcdImage.cc
Outdated
std::pair<int, int> CcdImage::countStars() const { | ||
int measuredStars = 0; | ||
int refStars = 0; | ||
for (auto &measuredStar : _catalogForFit) { |
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 insert a const
after auto
since the code does not modify _catalogForFit
I've reverted the "add associations to jointcal instance" commit and reworked the other changes to operate by passing I wanted to add a test for |
716f12a
to
1346822
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 looks great. Some nice improvements here. The new test utilities seem helpful.
A few minor requests for changes.
bin.src/plot_photoCalib.py
Outdated
@@ -140,7 +140,7 @@ def makePhotoCalibImages(visit, butler, step=8, chips=[], tract=None, | |||
return images | |||
|
|||
|
|||
class ImageMaker(object): | |||
class ImageMaker(): |
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 consider deleting the ()
as well, here and in other class definitions with no parent class or metaclass. I think removing unnecessary punctuation adds a bit of clarity. On the other hand flake8
apparently accepts this code, so feel free to ignore this suggestion.
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'd tend to agree that it's cleaner to remove the parens.
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 didn't even know I could! I definitely agree.
include/lsst/jointcal/Associations.h
Outdated
@@ -24,6 +24,8 @@ | |||
namespace lsst { | |||
namespace jointcal { | |||
|
|||
using refFluxMapType = std::map<std::string, std::vector<double>>; |
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 a type so please capitalize the name, e.g. RefFluxMapType
or even RefFluxMap
include/lsst/jointcal/Associations.h
Outdated
@@ -74,8 +91,7 @@ class Associations { | |||
* @param[in] ccd The ccd identifier | |||
* @param[in] control The JointcalControl object | |||
*/ | |||
void addImage(lsst::afw::table::SortedCatalogT<lsst::afw::table::SourceRecord> &catalog, | |||
std::shared_ptr<lsst::afw::geom::SkyWcs> wcs, | |||
void addImage(afw::table::SourceCatalog &catalog, std::shared_ptr<lsst::afw::geom::SkyWcs> wcs, |
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.
Consider renaming this to createCcdImage
or something similar; it may reduce the confusion caused by having a constructor that takes a list of CcdImage
.
@@ -59,7 +59,7 @@ class Gtransfo { | |||
* Transform a bounding box, taking either the inscribed or circumscribed box. | |||
* | |||
* @param[in] inputframe The frame to be transformed. | |||
* @param[in] which Return the inscribed (true) or circumscribed (false) box. | |||
* @param[in] inscribed Return the inscribed (true) or circumscribed (false) box. |
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.
Nice!
include/lsst/jointcal/Associations.h
Outdated
/** | ||
* Sets a shared tangent point for all ccdImages, using the mean of the centers of all ccdImages. | ||
*/ | ||
void setCommonTangentPoint(); |
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.
Consider a name such computeCommonTangentPoint
. It is less confusing than a set
method that takes no arguments (usually set
takes the value to be set). Plus less overloading makes the Python easier to understand.
Result struct with components: | ||
|
||
- `catalog` : Catalogs containing fake sources | ||
(`lsst.afw.table.SourceCatalog`). |
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 swap the type and the description here and for ccdImage
immediately below and clean up bbox
immediately after that. I guess it's not a Parameters
list and maybe it doesn't matter, but it's a bit odd being different than parameter lists for no readily apparently reason (and different item by item).
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.
That's how Struct returns are supposed to be documented: https://developer.lsst.io/python/numpydoc.html#struct-return-types
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, and the reason bbox
looks different is because it's on the same line.
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.
Thanks. I didn't know about that recommendation
python/lsst/jointcal/testUtils.py
Outdated
visitInfo = butler.get("calexp_visitInfo", dataId=dataId) | ||
bbox = butler.get('calexp_bbox', dataId=dataId) | ||
detector = butler.get('calexp_detector', dataId=dataId) | ||
filt = butler.get("calexp_filter", dataId=dataId).getName() |
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.
At risk of being too picky, please consider being uniform in your use of single quotes or double quotes for these strings. In the 5 lines above you have 2 one way and 3 the other. It works, and "a foolish consistency" and all, so ignore if you prefer.
python/lsst/jointcal/testUtils.py
Outdated
---------- | ||
catalog : `lsst.afw.table.SourceCatalog` | ||
The table to get sources from. | ||
pixToFocal : `lsst.afw.geom.Transform` |
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 you mean lsst.afw.geom.TransformPoint2ToPoint2
Transform
is not actually a class in Python (though it is a templated class in C++)
include/lsst/jointcal/CcdImage.h
Outdated
/** | ||
* Count the number of valid measured and reference stars that fall within this ccdImage. | ||
* | ||
* @return Number of (measured, reference) stars in the image. |
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 add a few words explaining whether reference stars that are associated with an invalid measured star are counted or excluded (with some sort of justification, if practical; it may not be worth the trouble, since this count is only intended as a simple diagnostic measure and it may not be clear yet -- or ever -- which option is preferable).
tests/test_ccdImage.py
Outdated
self.associations.setCommonTangentPoint() | ||
self.associations.associateCatalogs(matchCut) | ||
self.assertEqual(measStars, nStars) | ||
self.assertEqual(refStars, 0) |
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.
How can one tell that calling setCommonTangentPoint and associateCatalogs did anything?
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 they don't raise an exception, I guess.
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.
An offline conversation cleared this point up: I've added a couple of sanity checks around this block to show what's happening.
Moving cfht_minimal out of testdata_jointcal, because it's small (~2MB), and it's useful to have a minimally useful dataset for tests that don't require e.g. refcats or full sized real catalogs. fix test_jointcal_cfht_minimal.py to reflect new dataset location. Add flake8 ignore for test data.
A short block of python was starting to proliferate that computed a common tangent point from the ccdImages. That code might as well just live in associations as an argument-less `computeCommonTangentPoint()`. `refFluxMap` in collectRefStars() can take an empty dict, so it might as well have default values for that.
Compare countStars() output with a configurable "minimum" number of measured and reference stars per ccdImage after every outlier rejection loop.
Added test_ccdImage.py with tests of countStars(). Initial version of testUtils came from test_photometryModel.py, which now uses the new code, and now tests many points as part of test_toPhotoCalib().
We have to create the ccdImage before we can add it to the list, and a reviewer suggested this would make that clearer.
No description provided.