"""
Fresnel1D — 1-D near-field Fresnel propagator using FFT-based convolution with the transfer function.
"""
import numpy
from srxraylib.util.data_structures import ScaledArray
from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D
from wofry.propagator.propagator import Propagator1D
[docs]
class Fresnel1D(Propagator1D):
HANDLER_NAME = "FRESNEL_1D"
[docs]
def get_handler_name(self):
return self.HANDLER_NAME
[docs]
def do_specific_progation_after(self, wavefront, propagation_distance, parameters=None, element_index=None):
return self.do_specific_progation(wavefront, propagation_distance, parameters=parameters, element_index=element_index)
[docs]
def do_specific_progation_before(self, wavefront, propagation_distance, parameters=None, element_index=None):
return self.do_specific_progation( wavefront, propagation_distance, parameters=parameters, element_index=element_index)
[docs]
def do_specific_progation(self, wavefront, propagation_distance, parameters=None, element_index=None):
"""
Propagate a 1-D wavefront using the Fresnel (near-field) FFT method.
Parameters
----------
wavefront : GenericWavefront1D
Input wavefront.
propagation_distance : float
Propagation distance [m].
parameters : PropagationParameters, optional
Propagation parameter container.
element_index : int, optional
Index of the beamline element being propagated through.
Returns
-------
GenericWavefront1D
Propagated wavefront on the same spatial grid.
"""
return self.propagate_wavefront(wavefront,propagation_distance)
[docs]
@classmethod
def propagate_wavefront(cls,wavefront,propagation_distance):
fft_scale = numpy.fft.fftfreq(wavefront.size())/wavefront.delta()
fft = numpy.fft.fft(wavefront.get_complex_amplitude())
fft *= numpy.exp((-1.0j) * numpy.pi * wavefront.get_wavelength() * propagation_distance * fft_scale**2)
ifft = numpy.fft.ifft(fft)
return GenericWavefront1D(wavefront.get_wavelength(), ScaledArray.initialize_from_steps(ifft, wavefront.offset(), wavefront.delta()))