-
Notifications
You must be signed in to change notification settings - Fork 40
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
Proposed poppy.Instrument refactoring #181
Comments
Can we step back a level for a second? What is the fundamental problem that you are trying to solve here? I think the bar should be pretty high for backwards incompatible API changes, which this would be. That's a lot of pain for end users and I'm not convinced that it's necessary. |
Fundamentally, there are three places to store the state that determines the output of a PSF calculation, when there should only be one. We've noticed this in the past with competing definitions of the oversampling factor, for example. This is also a problem for generalizing the GUI code, since a new model object is needed to hold calculation-related state and then instantiate and apply it to an Instrument instance at calculation time. (It seems to me that Instrument was originally created to hold calculation related state, then instantiate an OpticalSystem, apply said state, and perform a calculation-- so I feel that adding another wrapper layer is the wrong move going forward.) Another option, that I think would not be as convenient for interactive use, is a It's definitely possible to make these changes incrementally (e.g. have an |
This is less "this should go in the next point release!" and more "we need to improve the Instrument class internals, and I believe this would improve the API as well". For example, there is a default instrument FOV:
There is an A better API could be:
Or
Warnings could be emitted in the cases where the FOV exceeds the nyquist sampling of the pupil, or where rounding is required to get an integer number of detector pixels across the FOV. Or to explicitly request a particular parity:
|
This has the additional benefit of making it easy to see what FOV you're going to get if you don't specify one, without looking in the code. (Simply |
There's another conceptual distinction though, which is part of the original motivation for why different parts of calculation state are treated differently. We are of course trying to model the behavior of actual physical objects which can be configured in various ways. To keep the API at least somewhat intuitive for users, the Instrument class is supposed to at some level map onto the actual physical properties of the instruments (detector choice, filter wheel settings, selection of optional stuff like coronagraph or spectrograph masks, etc). Then on the other hand there are aspects that are truly calculation specific, like oversampling or size of output FOV. The original intent was that the Instrument properties handle the former, and function arguments to calc_psf handle the latter. I agree it's gotten a little less clear cut over time, and that there may be better ways to do things. But I'm not convinced that making everything a property is the right approach. |
The problem is that we have multiple keyword arguments to I see the argument that |
Another API could be mechanisms as attributes of instruments, and calculation options as attributes of a PSFCalculation object initialized as an attribute of the instrument:
|
I solicited some comments from an anonymous WebbPSF user 😉
|
While trying to refactor the Jupyter Notebook GUI into a mission-agnostic set of functionality, I came to the conclusion that we need to clarify the responsibilities of the Instrument class. My first idea was to have an Instrument model and a Calculation model, but that has the two disadvantages of there a) not being enough Instrument-specific state that is not also calculation-specific to motivate splitting it up, considering b) that there is an additional cognitive overhead to a more complex API (and the inferior ergonomics of typing such things out when working interactively in a notebook or shell).
SO!
Instead, I propose refactoring the
Instrument
classes to encapsulate all of the necessary state for a calculation. This would include things that are already attributes onInstrument
(filter
,pupil
, etc.), things that are in the options dict (jitter
,jitter_sigma
, etc.), and things that are arguments tocalc_psf
(fov_arcsec
,fov_pixels
, etc.).Instead of providing a lot of optional arguments to
calc_psf
, I propose replacing it with methods for three types of calculations:Instrument.calc_psf(display=False)
- Calculate a broadband PSF with the configured optics and output optionsInstrument.calc_psf_monochromatic(wavelength, display=False)
- Calculate a monochromatic PSFInstrument.calc_psf_cube(wavelengths, display=False)
- Calculate alen(wavelengths)
-plane spectral cube for use in, e.g., PandeiaI also have some ideas about using Python
property
objects to enforce consistent state in the Instrument models. Since this can cause some surprises for advanced users (e.g.auto_pupil
in the past) we could have a single switch for all "automatic" changes (inst.validate_config = False
?).I've got a partial prototype in my POPPY repo. I hope to have it more fleshed out this week.
The text was updated successfully, but these errors were encountered: