-
Notifications
You must be signed in to change notification settings - Fork 15
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
Refactor image/stamp workflow #424
base: main
Are you sure you want to change the base?
Conversation
e58012d
to
c145f0c
Compare
c145f0c
to
1d7fefc
Compare
acbac83
to
9f49df7
Compare
The latest commit aligns photon objects in the photon pooling pipeline with their positions in the original pipeline. |
Almost there, but blocked by GalSim-developers/GalSim#1284. |
daae77c
to
7290a11
Compare
… be made if the full image has an even number of pixels in x and/or y, then apply this offset to photon arrays before merging.
bdaadae
to
b786cb0
Compare
This is finally open for review -- all comments welcome. |
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 William. I have a bunch of comments, but this is definitely a good start. If it would be helpful to talk through any of this on a zoom call, let me know.
config/imsim-config.yaml
Outdated
# If using photon pooling, FFT and photon objects are batched separately. | ||
# There will probably be few enough FFT objects to do in a single batch. | ||
# Bright photon objects are treated in all photon batches, but at 1/nbatch_photon of | ||
# their flux. Faint photonobjects are placed at their full flux in random batches. |
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.
# their flux. Faint photonobjects are placed at their full flux in random batches. | |
# their flux. Faint photon objects are placed at their full flux in random batches. |
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 for spotting this. Fixing in the next commit.
config/imsim-config.yaml
Outdated
# These parameters only affect LSST_PhotonPoolingImage images. | ||
# The batch numbers can be changed if desired. | ||
nbatch_fft: 1 | ||
nbatch_photon: 10 |
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 this should be the same parameter as the simple nbatch. We can just document that with photon pooling, nbatch refers only to the photon-shooting objects. Then nbatch_fft can be an optional parameter that defaults to 1. (Maybe not even worth mentioning here if most users wouldn't change 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.
I agree with this. Nice to keep the number of parameters down. nbatch_photon
will be no more, and the photon pooling will be controlled directly with nbatch
.
|
||
class LSST_ImageBuilder(LSST_ImageBuilderBase): | ||
"""This is mostly the same as the GalSim "Scattered" image type. | ||
So far the only change is in the sky background 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.
This doc is probably obsolete. There are quite a few differences now.
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.
Happy to change this. Can you suggest something more suitable?
imsim/lsst_image.py
Outdated
'x' : { 'type' : 'Random' , 'min' : xmin , 'max' : xmax }, | ||
'y' : { 'type' : 'Random' , 'min' : ymin , 'max' : ymax } | ||
} | ||
set_config_image_pos(config, base) |
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.
Rather than making this a free function in a different file, this should probably be a private method of the base class, which both subclasses can call.
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.
Agreed, doing this.
imsim/lsst_image.py
Outdated
base["stamp"]["photon_ops"] = [] | ||
photon_ops = base["stamp"]["photon_ops"] | ||
shift_op = {'type': 'Shift'} | ||
shift_index = next((index for (index, d) in enumerate(photon_ops) if d["type"] == "Shift"), None) |
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 don't love this implementation. I get why something like this is now required. But I think I'd rather have RubinOptics and RubinDiffractionOptics just have an optional parameter to apply this shift or not. Then when running this class, base[image_pos
] is defined and they can apply the shift based on that.
In the photon pooling class, once we've pooled all the photons, we should set the object-specific values (image_pos, sky_pos, maybe others) that apply to a particular object to None
. Then the RubinOptics and RubinDiffractionOptics photon ops would see that the image_pos isn't defined, so not apply any shift.
This feels to me more elegant and possibly more efficient.
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 now be done -- see RubinOptics and RubinDIffractionOptics. If an optional shift_photons = True
is passed, the shift is performed.
tests/test_image.py
Outdated
}, | ||
"psf": {"type": "Convolve", "items": [{"type": "Gaussian", "fwhm": 0.3}]}, | ||
"stamp": { | ||
"type": "LSST_Silicon", |
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 be the new stamp type when image_type is LSST_PhotonPoolingImage
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.
Yes, photon pooling now needs to use the new stamp type rather messing with base
. The test sets the correct stamp type.
tests/test_image.py
Outdated
|
||
def test_lsst_image_photon_pooling_pipeline(): | ||
"""Check that LSST_PhotonPoolingImage batches objects as expected and renders objects at the correct positions.""" | ||
run_lsst_image("LSST_PhotonPoolingImage") |
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 feel like we probably want a few additional tests in this pipeline. E.g. that the FFT and faint objects only got drawn once. And the others got drawn nbatch times.
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 written a set of tests for the partitioning and batching process. As mentioned above, it also confirms that total flux is conserved for photon objects,
help="Similar to -k of pytest / unittest: restrict tests to tests starting with the specified prefix.", | ||
default="test_", | ||
) | ||
args = parser.parse_args() |
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.
FWIW, when working on stuff, I usually just put the name of the test function I'm working on at the start of this name == '__main__'
block, followed by quit(). Then remove it before committing. Seems easier than rolling all of this argparse stuff, but 🤷.
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 also done in test_diffraction_fft.py, but I'm happy to change it if you'd like me to.
expected_x_pic_center = 564.5 | ||
expected_y_pic_center = -1431.4 | ||
expected_x_pic_center = -989.5971378245167 | ||
expected_y_pic_center = -3840.3512012842157 |
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.
Why are these (and subsequent tests) changing so much? This isn't close.
Regression tests are supposed to make sure we don't change the functionality of existing code. I know the implementation of these photon ops changed, but I think we want the tests to remain the same or at least very very close. What happened here?
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 still a big issue. I'm 99% convinced the error is in the original test itself. My current best guess is that with the old code it may not have been internally self-consistent around the WCS used, while the new XyToV
should enforce self-consistency. But it still needs to be looked at.
@@ -52,7 +53,8 @@ def create_test_config(): | |||
}], | |||
}, | |||
"bandpass": galsim.Bandpass('LSST_r.dat', wave_type='nm'), | |||
"wcs": galsim.PixelScale(0.2), | |||
"wcs": wcs, | |||
"current_image": galsim.Image(1024, 1024, wcs=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.
Why was this change required?
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 change to the wcs
field isn't actually necessary, it looks. The addition of current_image
is needed for deserialize_rubin_optics
, deserialize_rubin_diffraction_optics
and deserialize_rubin_diffraction
which uses it to get img_wcs
, required by the new version of XyToV
.
…from LSST_SiliconBuilder.
… creating a new builder on the spot.
…e a single consolidated stamp type LSST_Photons for all types of objects.
…re no longer cached, leaving the index, phot_flux and processing mode only.
…mp is being used.
…ine. Photon pooling translates relative to full_image.center just before accumulation instead.
The latest set of commits should address most of the comments above. I'll respond to those individually. A couple do still need to be looked at. |
Are you waiting on me for anything here? I thought you still had some more comments to address, so I was waiting for that to be done. But if it would be helpful for me to review this again at this point, let me know. |
Not just yet -- I have a couple more commits on the way with fixes and tests for the batching. I'll push these later today or tomorrow, and then I think that should be everything ready for review again. |
…he functions there its static methods.
…beginning. Previously missed. Ensure conservation of photon object fluxes during batching by adding the modulo to random batches.
…ST_ImageBuilderBase.
46461fb
to
eeb67dc
Compare
…than the (0,0) position.
I think this is ready for re-review now, though CI is failing with an error in |
I think there is actually one more commit incoming. I've realised that in edge cases where nominally bright photon objects' |
…ther photon pooling tests.
OK, that should be it -- code open for review! |
No description provided.