spacetelescope / poppy

Physical Optics Propagation in Python
https://poppy-optics.readthedocs.io
BSD 3-Clause "New" or "Revised" License
216 stars 72 forks source link

Phase and Amplitude modulation #301

Closed FredericCassaing closed 5 years ago

FredericCassaing commented 5 years ago

Hi Poppy, I am completely new to poppy (&github btw) but I have chosen to use this nice tool for my research rather than my custom IDL tools. However, I would like to implement various kinds of focal-plane WFSs, and there are a few things I have not seen reading the documentation. Is it possible with the current poppy, or expected with next versions, to perform :

Thanks in advance for your answers, and best regards from a new poppyst ! Frederic

mperrin commented 5 years ago

Hi again Frederic,

For phase modulation, there isn't a single function that does exactly what you're asking, but it's fairly straightforward to iterate over a desired diversity yourself and save the output PSFs into a list. Here is some example code:

# Create a Zernike WFE instance and put it into some optical system
zernike_wfe = poppy.ZernikeWFE(radius=1*u.m, coefficients = [0,0,0,0,0])

osys = poppy.OpticalSystem()
osys.add_pupil(poppy.CircularAperture(radius=1*u.m))
osys.add_pupil(zernike_wfe)
osys.add_detector(fov_pixels=128, pixelscale=0.01*u.arcsec/u.pixel, oversample=1)

# What is the desired diversity?
astigmatisms = [0, 5e-8, 1e-7]

# Iterate over the diversity: for each value, update the zernike WFE optic, 
# calculate a PSF, and save in a list
psfs = []
for astig in astigmatisms:
    zernike_wfe.coefficients[4] = astig*u.m
    psfs.append(osys.calc_psf())

# plot the list of PSFs
for i, astig in enumerate(astigmatisms):
    plt.figure()
    poppy.display_psf(psfs[i], title="PSF with astigmatism={}".format(astig))    

In this case you get a list of PSFs rather than a 3D data cube, but desired you can reformat that output data into a data cube via regular numpy array manipulations etc. There's an example of doing this in the calc_datacube function in instrument.py (that example is for a multi wavelength data cube with the 3rd axis being the wavelength, but the same idea could apply just as well to WFE diversity)

For amplitude modulation - you're thinking about for instance a spatial light modulator or digital micro mirror device? You're correct we don't have yet any classes to model such amplitude modulators, but in principle we would implement one in much the same way as the DM classes, by calculating a model for the transmission rather than the OPD based on the device properties. I'd be happy to help you develop such a class to model whichever device is of interest to you. Can you share more details on the type of modulator you'd like to simulate?

FredericCassaing commented 5 years ago

Dear Marshall, Thank you so much for such a fast answer and your example based on poppy iterations. This confirms what I wanted to be sure of: there is no way to create arrays (or lists, I am not a python expert either) such as zernike_coef[index,time] or dm_coef[mode,sub-ap,time] and get psf[pixX,pixY,time]. Is this something that could be of interest to you ? To model dynamic behavior, or modulated systems, or.... ?

For amplitude, for the moment I am not linked to a particular device. I wanted this morning to do something simulating a shutter in each sub-ap of an hexDM but I managed to do it through phase modulation. So there is no more critical need for the moment, but the possibility to put amplitude disturbances over a full aperture (as a set of Zernike coef?) or over an hex DM (as a global transmission ratio for each sub-ap?) may most probably be useful in the future. Any similar needs on your side ?

Best regards,

mperrin commented 5 years ago

This confirms what I wanted to be sure of: there is no way to create arrays (or lists, I am not a python expert either) such as zernike_coef[index,time] or dm_coef[mode,sub-ap,time] and get psf[pixX,pixY,time]. Is this something that could be of interest to you ? To model dynamic behavior, or modulated systems, or.... ?

We're certainly interested in modeling dynamics and modulated systems! But it's hard to write a generalized solution for all of that - different optical models will have many different possible modulations. For instance you gave examples of possibly varying Zernike coefficients vs. time or DM coefficients vs time, there's also for instance Kolmogorov turbulence vs time, or any number of other parameters. We can imagine varying DM coefficients on multiple DMs in a system as well. So it is not straightforward to write a single function that could handle all the possible cases of iteration of interest. We think it is best to let the user write their own iteration code, because then the method of iteration and which optic(s) it is applied to can be flexibly adjusted as needed for each particular simulation case.

So there is no more critical need for the moment, but the possibility to put amplitude disturbances over a full aperture (as a set of Zernike coef?) or over an hex DM (as a global transmission ratio for each sub-ap?) may most probably be useful in the future. Any similar needs on your side ?

So far those have not been the top priority needs for any of the users of this code, but we'd gladly accept contributions of code to implement those if they're useful for you in your work. I agree that it would be good to have a generalized way to represent amplitude disturbances over the full aperture. That said, Zernikes are not likely to be an efficient parameterization for those, compared to e.g. a representation of nonuniform mirror coatings as a power spectral density, or similar.

For now, there are the general-purpose ArrayOpticalElement and FITSOpticalElement classes which allow modeling any arbitrary optic if you want to create your own representations of amplitude errors there.

FredericCassaing commented 5 years ago

Dear Marshall,

Thank you very much for this detailed answer.

If we have to write something new, we will do it with a recycling spec in mind and try to make something general that can be added to poppy (a kind of multipsf procedure). I agree it is not simple since the iterable input can take several forms. And similarly, if we make some new amplitude control, I will certainly do something as generic as possible and let you know.

I muted the thread. Best regards, -- Frédéric CASSAING - DOTA/HRA - HDR Tél: +33 1 46 73 48 54 ONERA - The French Aerospace Lab - Centre de Châtillon 29 avenue de la Division Leclerc BP 72 F-92322 CHATILLON CEDEX http://www.onera.fr | Frederic.Cassaing@onera.fr Avertissement/disclaimer http://www.onera.fr/onera-en/emails-terms

Le 25/03/2019 21:41, Marshall Perrin a écrit :

This confirms what I wanted to be sure of: there is no way to create
arrays (or lists, I am not a python expert either) such as
zernike_coef[index,time] or dm_coef[mode,sub-ap,time] and get
psf[pixX,pixY,time]. Is this something that could be of interest to you
? To model dynamic behavior, or modulated systems, or.... ?

We're certainly interested in modeling dynamics and modulated systems! But it's hard to write a generalized solution for all of that - different optical models will have many different possible modulations. For instance you gave examples of possibly varying Zernike coefficients vs. time or DM coefficients vs time, there's also for instance Kolmogorov turbulence vs time, or any number of other parameters. We can imagine varying DM coefficients on multiple DMs in a system as well. So it is not straightforward to write a single function that could handle all the possible cases of iteration of interest. We think it is best to let the user write their own iteration code, because then the method of iteration and which optic(s) it is applied to can be flexibly adjusted as needed for each particular simulation case.

So there is no more critical need for the moment, but the possibility to
put amplitude disturbances over a full aperture (as a set of Zernike
coef?) or over an hex DM (as a global transmission ratio for each
sub-ap?) may most probably be useful in the future. Any similar needs on
your side ?

So far those have not been the top priority needs for any of the users of this code, but we'd gladly accept contributions of code to implement those if they're useful for you in your work. I agree that it would be good to have a generalized way to represent amplitude disturbances over the full aperture. That said, Zernikes are not likely to be an efficient parameterization for those, compared to e.g. a representation of nonuniform mirror coatings as a power spectral density, or similar.

For now, there are the general-purpose |ArrayOpticalElement| and |FITSOpticalElement| classes which allow modeling any arbitrary optic if you want to create your own representations of amplitude errors there.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/spacetelescope/poppy/issues/301#issuecomment-476368726, or mute the thread https://github.com/notifications/unsubscribe-auth/AuVuY1O7ytmk5u7cQbyYpGnZkN4m2_I2ks5vaTRzgaJpZM4b2enu.