Closed mperrin closed 5 years ago
Thought about this some more. Possibly the right mental model here is to think of optical systems as linear operators acting on wavefronts. That's true mathematically, but not in how the code here is currently implemented. One could imagine a function on an optical system, maybe call it propagate_through
, which takes a wavefront and returns another wavefront:
wave_out = osys.propagate_through(wave_in)
That would make it easy to compose optical systems arbitrarily:
wave_out = osys2.propagate_through(osys1.propagate_through(wave_in))
The current function propagate_mono
comes closest to that, but doesn't have exactly the right semantics because it creates a new input wavefront rather than accepting one as a parameter, and it hands back a PSF rather than a wavefront.
If we wanted to do something like the above, in some ways it would be simple to re-cast propagate_mono
and calc_psf
to sit on top of propagate_through
as a lower-level framework. In other ways it might be a hassle. Could be worth some experimentation with test code, potentially.
All this needs further discussion anyway.
@sdwill and @douglase - I'd appreciate some feedback & thoughts on this one.
FYI I've got a version of the above implemented now, and will be making a PR for comments shortly. It's a moderately substantial refactoring, which pulls out most of the contents of propagate_mono
into a new function with a different API as described above. That new function is a linear operator that takes an input complex wavefront and returns an output complex wavefront. This makes it straightforward to arbitrarily chain together propagation calculations.
That new function is tentatively named "propagate_through
", but I'm not totally happy with that name. Perhaps just propagate
would be better but I worry that could be more confusing than necessary with all the existing propagate_*
function names. Name suggestions welcome.
Stand by for the PR soon.
This one's tricky. Issue raised by @sdwill:
Right now there is no way to "connect together" multiple optical systems, in the sense of taking an output wavefront from a propagation through one system, and feeding it into a propagation through another system. This could be useful in a variety of contexts including
input_wavefront
function.The complex wavefront output from a given optical system can be obtained using the
retain_final
parameter tocalc_psf
. But there is no easy way to hand that in to another system.Possible enhancements to address this might include one or more of the following alternatives:
input_wavefront
with a function that grabs some other existing wavefront as a starting point. Potentially such a function might even run a completely different other system recursively to get its starting wavefront.CompoundOpticalSystem
, which could work similarly toCompoundOpticalElement
to iterate over multiple other systems and act to glue them together into something that acts like a larger whole.Any of the above might have to deal with potential issues of resampling, padding, and other possible inconsistencies of pixel grid sampling between the different stages of calculation.