GalSim-developers / GalSim

The modular galaxy image simulation toolkit. Documentation:
http://galsim-developers.github.io/GalSim/
Other
226 stars 107 forks source link

Factor out pupil sampling from `PhaseScreenPSF._shoot` #1175

Closed jmeyers314 closed 2 years ago

jmeyers314 commented 2 years ago

Both phase screen physics and optical raytracing require first defining entrance pupil positions of individual photons. We currently populate PhotonArray.pupil_u and pupil_v inside of PhaseScreenPSF._shoot just in time for applying kicks. However, there's currently no good way to populate these values for use by the raytracing done in ImSim without also using the detailed atmosphere model.

I think a better design would be to create a PupilSampler PhotonOp that could be applied independently. This refactor would also create an opportunity to sample the pupil continuously in an annulus (or more complicated geometry), rather than discretely from the illuminated pixels of a pupil image (as is currently done).

The tricky bit, I think, is that sampling the pupil needs to be accomplished before PhaseScreenPSF._shoot is called. I believe the current API only supports PhotonOps occurring after all the _shoot methods are called. One thought I had was to apply the PhaseScreenPSF as a photon op directly (after PupilSampler), rather than lumping it into a galsim.Convolution. We could also potentially make separate pre_ops and post_ops arguments to drawImage. Any thoughts appreciated.

rmjarvis commented 2 years ago

PhotonOps are evaluated in order of the list. So if a PSF is lumped in with the other photon_ops, then the user can make sure PupilSampler is listed first. Also, I think we can have the _shoot method check if pupil_u and pupil_v are made yet, and if not, then automatically call the sampling function using the current pupil image. So the current use patterns could be preserved, but allow more expressiveness if the user wanted to be more explicit about the order of all the photon operations.

jmeyers314 commented 2 years ago

PhotonOps are evaluated in order of the list. So if a PSF is lumped in with the other photon_ops, then the user can make sure PupilSampler is listed first.

Yeah, I thought something like that would work. It does make it hard for a user to compare the output of, e.g.,

obj = galsim.Convolve(atm_psf, gal)
obj.drawImage(img_fft, method='fft')
obj.drawImage(img_phot, method='phot')

But maybe that's unusual enough not to matter.

rmjarvis commented 2 years ago

I have a start on this that seems to be working, although my unit test isn't quite going right. I think just rng differences, but I'm trying to make sure. I didn't try to get the continuous sampling you wanted, so I'll push this once I have the basic structure working, and then you can improve the sampling function the way you want before the PR.

rmjarvis commented 2 years ago

OK Josh, check out the pupil_sample branch and add/edit as needed.

jmeyers314 commented 2 years ago

Done in #1176