Example #1
0
    def test_save_load_h5_file(self):

        wfr = GenericWavefront2D.initialize_wavefront_from_range(
            -0.004, 0.004, -0.001, 0.001, (500, 200))
        wfr.set_gaussian(0.002 / 6, 0.001 / 12)
        wfr.save_h5_file("tmp_wofry.h5",
                         subgroupname="wfr",
                         intensity=True,
                         phase=True,
                         overwrite=True)

        wfr.set_gaussian(0.002 / 6 / 2, 0.001 / 12 / 2)
        print("Writing file: tmp_wofry.h5")
        wfr.save_h5_file("tmp_wofry.h5",
                         subgroupname="wfr2",
                         intensity=True,
                         phase=False,
                         overwrite=False)

        # test same amplitudes:
        print("Accessing file, path: ", "tmp_wofry.h5", "wfr2")
        wfr2 = GenericWavefront2D.load_h5_file("tmp_wofry.h5", "wfr2")
        print("Cleaning file tmp_wofry.h5")
        os.remove("tmp_wofry.h5")
        assert (wfr2.is_identical(wfr))
Example #2
0
    def propagate_numpy_wavefront(cls, filename_in, filename_out, beamline, mypropagator, return_wavefront_list=True):

        file_content = numpy.load(filename_in)
        e_field = file_content["e_field"]
        coordinates = file_content["coordinates"]
        energies = file_content["energies"]

        x = numpy.linspace(coordinates[0], coordinates[1], e_field.shape[1])
        y = numpy.linspace(coordinates[2], coordinates[3], e_field.shape[2])
        wofry_wf_in = GenericWavefront2D.initialize_wavefront_from_arrays(x, y, e_field[0, :, :, 0].copy())
        wofry_wf_in.set_photon_energy(energies[0])

        # wofry_wf_out_list = cls.propagate_classmethod(wofry_wf_in,beamline,mypropagator)
        wofry_wf_out = beamline.propagate(wofry_wf_in, mypropagator, return_wavefront_list=return_wavefront_list)

        if return_wavefront_list:
            wofry_wf_out_list = wofry_wf_out
            wofry_wf_out = wofry_wf_out_list[-1]

        e_field[0, :, :, 0] = wofry_wf_out.get_complex_amplitude()

        coordinates[0] = wofry_wf_out.get_coordinate_x()[0]
        coordinates[1] = wofry_wf_out.get_coordinate_x()[-1]
        coordinates[2] = wofry_wf_out.get_coordinate_y()[0]
        coordinates[3] = wofry_wf_out.get_coordinate_y()[-1]

        numpy.savez(filename_out,
                    e_field=e_field,
                    coordinates=coordinates,
                    energies=energies)

        if return_wavefront_list:
            return wofry_wf_out_list
        else:
            return wofry_wf_out
Example #3
0
def propagate_single_mode(af, i, beamline):

    from wofry.propagator.propagator import PropagationManager, PropagationElements, PropagationParameters
    from syned.beamline.beamline_element import BeamlineElement
    from syned.beamline.element_coordinates import ElementCoordinates
    from wofry.propagator.propagators2D.fresnel_zoom_xy import FresnelZoomXY2D

    from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D
    from wofry.beamline.optical_elements.ideal_elements.screen import WOScreen

    mi = af.coherentMode(i)
    evi = af.eigenvalue(i)

    print("propagating mode index", i, evi, mi.shape)

    input_wavefront = GenericWavefront2D.initialize_wavefront_from_arrays(
        x_array=af.xCoordinates(),
        y_array=af.yCoordinates(),
        z_array=mi * numpy.sqrt(evi),
    )
    i0 = input_wavefront.get_integrated_intensity()

    input_wavefront.set_photon_energy(17226.0)

    propagator = PropagationManager.Instance()
    try:
        propagator.add_propagator(FresnelZoomXY2D())
    except:
        pass

    wfp = beamline.propagate(input_wavefront, propagator)

    i1 = wfp[-1].get_integrated_intensity()

    return wfp, i1 / i0
Example #4
0
def create_wavefront_generic(size_factor=1,pixel_size=1e-6,wavelength=1.5e-10):

    w = GenericWavefront2D.initialize_wavefront_from_steps(x_start=-0.5*pixel_size*512*size_factor,x_step=pixel_size,
                                                           y_start=-0.5*pixel_size*512*size_factor,y_step=pixel_size,
                                                           number_of_points=(512*size_factor,512*size_factor),wavelength=wavelength)
    w.set_plane_wave_from_complex_amplitude(complex_amplitude=(1.0+0.0j))
    w.clip_square(x_min=-100e-6,x_max=100e-6,y_min=-10e-6,y_max=10e-6)
    return w
Example #5
0
    def toGenericWavefront(self):
        wavefront = GenericWavefront2D.initialize_wavefront_from_range(self.mesh.xStart,
                                                                       self.mesh.xFin,
                                                                       self.mesh.yStart,
                                                                       self.mesh.yFin,
                                                                       number_of_points=(self.mesh.nx, self.mesh.ny),
                                                                       wavelength=self.get_wavelength(),
                                                                       polarization=Polarization.TOTAL)

        wavefront.set_complex_amplitude(SRWEFieldAsNumpy(srwwf=self)[0, :, :, 0],
                                        SRWEFieldAsNumpy(srwwf=self)[0, :, :, 1])

        return wavefront
Example #6
0
    def test_multiple_slit(self):
        print("#                                                             ")
        print(
            "# Tests multiple slit (2D)                                     ")
        print("#                                                             ")
        wavefront = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-0.5e-3,
            x_max=0.5e-3,
            y_min=-0.5e-3,
            y_max=0.5e-3,
            number_of_points=(2048, 1024),
            wavelength=1.5e-10,
            polarization=Polarization.TOTAL)

        ca = numpy.zeros(wavefront.size())
        wavefront.set_complex_amplitude(ca + (10 + 0j), ca + (0 + 1j))
        #

        window_circle = wavefront.clip_circle(50e-6,
                                              -2e-4,
                                              -2e-4,
                                              apply_to_wavefront=False)
        window_rectangle = wavefront.clip_square(2e-4,
                                                 3e-4,
                                                 2e-4,
                                                 3e-4,
                                                 apply_to_wavefront=False)
        window_ellipse = wavefront.clip_ellipse(50e-6,
                                                25e-6,
                                                -2e-4,
                                                2e-4,
                                                apply_to_wavefront=False)
        window_ellipse2 = wavefront.clip_ellipse(50e-6,
                                                 100e-6,
                                                 2e-4,
                                                 -2e-4,
                                                 apply_to_wavefront=False)

        wavefront.clip_window(window_circle + window_rectangle +
                              window_ellipse + window_ellipse2)

        if True:
            from srxraylib.plot.gol import plot_image
            plot_image(wavefront.get_intensity(),
                       1e6 * wavefront.get_coordinate_x(),
                       1e6 * wavefront.get_coordinate_y())

        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_intensities(
                0, 0, polarization=Polarization.TOTAL), 0.0)
Example #7
0
    def test_gaussianhermite_mode(self, do_plot=do_plot):
        #
        # plane wave
        #
        print("#                                                             ")
        print("# Tests for a 2D Gaussian Hermite mode                        ")
        print("#                                                             ")

        wavelength = 1.24e-10

        # 2D
        sigma_x = 100e-6
        mode_x = 0
        npixels_x = 100
        sigma_y = 50e-6
        mode_y = 3
        npixels_y = 100

        wavefront_length_x = 10 * sigma_x
        wavefront_length_y = 10 * sigma_y

        x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x,
                           npixels_x)
        y = numpy.linspace(-0.5 * wavefront_length_y, 0.5 * wavefront_length_y,
                           npixels_y)

        wf1 = GenericWavefront2D.initialize_wavefront_from_steps(
            x_start=x[0],
            x_step=numpy.abs(x[1] - x[0]),
            y_start=y[0],
            y_step=numpy.abs(y[1] - y[0]),
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        wf1.set_gaussian_hermite_mode(sigma_x,
                                      sigma_y,
                                      mode_x,
                                      mode_y,
                                      amplitude=1.0)

        numpy.testing.assert_almost_equal(wf1.get_amplitude()[30, 40],
                                          1383.76448118, 3)

        if do_plot:
            from srxraylib.plot.gol import plot_image
            plot_image(wf1.get_amplitude(),
                       wf1.get_coordinate_x(),
                       wf1.get_coordinate_y(),
                       title="Amplitude of gaussianhermite mode",
                       show=1)
Example #8
0
    def toGenericWavefront(self):
        x,y = self.get_x_y()
        wavefront = GenericWavefront2D.initialize_wavefront_from_range(x.min(),
                                                                       x.max(),
                                                                       y.min(),
                                                                       y.max(),
                                                                       number_of_points=(x.shape[0], y.shape[0]),
                                                                       wavelength=self.wavelength)

        print("Shape", wavefront.size())
        print("WL", m_to_eV, wavefront.get_wavelength(), wavefront.get_photon_energy())

        wavefront.set_complex_amplitude((numpy.fft.fftshift(self.d)).T)

        return wavefront
Example #9
0
def load_h5_file(filename, filepath):
    try:
        f = h5py.File(filename, 'r')
        mesh_X = f[filepath + "/wfr_mesh_X"].value
        mesh_Y = f[filepath + "/wfr_mesh_Y"].value
        complex_amplitude_s = f[filepath + "/wfr_complex_amplitude_s"].value.T
        wfr = GenericWavefront2D.initialize_wavefront_from_arrays(
            x_array=numpy.linspace(mesh_X[0], mesh_X[1], int(mesh_X[2])),
            y_array=numpy.linspace(mesh_Y[0], mesh_Y[1], int(mesh_Y[2])),
            z_array=complex_amplitude_s)
        wfr.set_photon_energy(f[filepath + "/wfr_photon_energy"].value)
        f.close()
        return wfr
    except:
        raise Exception("Failed to load 2D wavefront to h5 file: " + filename)
def create_wavefront():

    #
    # create input_wavefront
    #
    #
    from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D
    input_wavefront = GenericWavefront2D.initialize_wavefront_from_range(
        x_min=-0.001200,
        x_max=0.001200,
        y_min=-0.001200,
        y_max=0.001200,
        number_of_points=(2048, 2048))
    input_wavefront.set_photon_energy(17225)
    input_wavefront.set_spherical_wave(radius=28.3,
                                       complex_amplitude=complex(1, 0))
    return input_wavefront
Example #11
0
    def test_polarization(self):
        print("#                                                             ")
        print("# Tests polarization (2D)                                     ")
        print("#                                                             ")
        wavefront = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-0.5e-3,
            x_max=0.5e-3,
            y_min=-0.5e-3,
            y_max=0.5e-3,
            number_of_points=(2048, 1024),
            wavelength=1.5e-10,
            polarization=Polarization.TOTAL)

        ca = numpy.zeros(wavefront.size())
        wavefront.set_complex_amplitude(ca + (1 + 0j), ca + (0 + 1j))
        #
        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_phase(0.1e-3,
                                             0.1e-3,
                                             polarization=Polarization.SIGMA),
            0.0)
        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_phase(-0.1e-3,
                                             0.1e-3,
                                             polarization=Polarization.PI),
            numpy.pi / 2)

        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_intensities(
                -0.111e-3, -0.111e-3, polarization=Polarization.TOTAL), 2.0)
        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_intensities(
                -0.111e-3, -0.111e-3, polarization=Polarization.SIGMA), 1.0)
        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_intensities(
                -0.111e-3, -0.111e-3, polarization=Polarization.PI), 1.0)

        numpy.testing.assert_almost_equal(
            wavefront.get_intensity(polarization=Polarization.SIGMA),
            (ca + 1)**2)
        numpy.testing.assert_almost_equal(
            wavefront.get_intensity(polarization=Polarization.PI), (ca + 1)**2)
        numpy.testing.assert_almost_equal(
            wavefront.get_intensity(polarization=Polarization.TOTAL),
            2 * (ca + 1)**2)
Example #12
0
    def propagate_numpy_wavefront(cls,
                                  filename_in,
                                  filename_out,
                                  beamline,
                                  mypropagator,
                                  return_wavefront_list=True):

        file_content = numpy.load(filename_in)
        e_field = file_content["e_field"]
        coordinates = file_content["coordinates"]
        energies = file_content["energies"]

        x = numpy.linspace(coordinates[0], coordinates[1], e_field.shape[1])
        y = numpy.linspace(coordinates[2], coordinates[3], e_field.shape[2])
        wofry_wf_in = GenericWavefront2D.initialize_wavefront_from_arrays(
            x, y, e_field[0, :, :, 0].copy())
        wofry_wf_in.set_photon_energy(energies[0])

        # wofry_wf_out_list = cls.propagate_classmethod(wofry_wf_in,beamline,mypropagator)
        wofry_wf_out = beamline.propagate(
            wofry_wf_in,
            mypropagator,
            return_wavefront_list=return_wavefront_list)

        if return_wavefront_list:
            wofry_wf_out_list = wofry_wf_out
            wofry_wf_out = wofry_wf_out_list[-1]

        e_field[0, :, :, 0] = wofry_wf_out.get_complex_amplitude()

        coordinates[0] = wofry_wf_out.get_coordinate_x()[0]
        coordinates[1] = wofry_wf_out.get_coordinate_x()[-1]
        coordinates[2] = wofry_wf_out.get_coordinate_y()[0]
        coordinates[3] = wofry_wf_out.get_coordinate_y()[-1]

        numpy.savez(filename_out,
                    e_field=e_field,
                    coordinates=coordinates,
                    energies=energies)

        if return_wavefront_list:
            return wofry_wf_out_list
        else:
            return wofry_wf_out
Example #13
0
def fresnel(wavefront, propagation_distance, shift_half_pixel=False):
    wavelength = wavefront.get_wavelength()

    #
    # convolving with the Fresnel kernel via FFT multiplication
    #
    fft = numpy.fft.fft2(wavefront.get_complex_amplitude())

    # frequency for axis 1
    shape = wavefront.size()
    delta = wavefront.delta()

    pixelsize = delta[0]  # p_x[1] - p_x[0]
    npixels = shape[0]
    freq_nyquist = 0.5 / pixelsize
    freq_n = numpy.linspace(-1.0, 1.0, npixels)
    freq_x = freq_n * freq_nyquist

    # frequency for axis 2
    pixelsize = delta[1]
    npixels = shape[1]
    freq_nyquist = 0.5 / pixelsize
    freq_n = numpy.linspace(-1.0, 1.0, npixels)
    freq_y = freq_n * freq_nyquist

    if shift_half_pixel:
        freq_x = freq_x - 0.5 * numpy.abs(freq_x[1] - freq_x[0])
        freq_y = freq_y - 0.5 * numpy.abs(freq_y[1] - freq_y[0])

    freq_xy = numpy.array(numpy.meshgrid(freq_y, freq_x))
    # fft *= numpy.exp((-1.0j) * numpy.pi * wavelength * propagation_distance *
    #               numpy.fft.fftshift(freq_xy[0]*freq_xy[0] + freq_xy[1]*freq_xy[1]) )
    fft *= numpy.exp(
        (-1.0j) * numpy.pi * wavelength * propagation_distance *
        numpy.fft.fftshift(freq_xy[0] * freq_xy[0] + freq_xy[1] * freq_xy[1]))

    wf_propagated = GenericWavefront2D.initialize_wavefront_from_arrays(
        x_array=wavefront.get_coordinate_x(),
        y_array=wavefront.get_coordinate_y(),
        z_array=numpy.fft.ifft2(fft),
        wavelength=wavelength)

    return wf_propagated
    def send_mode(self):

        wf = GenericWavefront2D.initialize_wavefront_from_arrays(
            self.af.x_coordinates(), self.af.y_coordinates(),
            self.af.mode(self.MODE_INDEX))
        wf.set_photon_energy(self.af.photon_energy())
        ampl = wf.get_complex_amplitude()

        if self.TYPE_PRESENTATION == 5:
            eigen = self.af.eigenvalues_old()
            wf.set_complex_amplitude(ampl * numpy.sqrt(eigen[self.MODE_INDEX]))
        else:
            wf.set_complex_amplitude(ampl)

        beamline = WOBeamline(light_source=self.get_light_source())
        print(">>> sending mode: ", int(self.MODE_INDEX))
        self.send("WofryData", WofryData(wavefront=wf, beamline=beamline))

        # script
        self.wofry_python_script.set_code(beamline.to_python_code())
    def propagate_wavefront(cls,
                            wavefront,
                            propagation_distance,
                            shift_half_pixel=False):

        from scipy.signal import fftconvolve

        wavelength = wavefront.get_wavelength()

        X = wavefront.get_mesh_x()
        Y = wavefront.get_mesh_y()

        if shift_half_pixel:
            x = wavefront.get_coordinate_x()
            y = wavefront.get_coordinate_y()
            X += 0.5 * numpy.abs(x[0] - x[1])
            Y += 0.5 * numpy.abs(y[0] - y[1])

        kernel = numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() *
                           (X**2 + Y**2) / 2 / propagation_distance)
        kernel *= numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() *
                            propagation_distance)
        kernel /= 1j * wavefront.get_wavelength() * propagation_distance

        wavefront_out = GenericWavefront2D.initialize_wavefront_from_arrays(
            x_array=wavefront.get_coordinate_x(),
            y_array=wavefront.get_coordinate_y(),
            z_array=fftconvolve(wavefront.get_complex_amplitude(),
                                kernel,
                                mode='same'),
            wavelength=wavelength)
        # added [email protected] 2018-03-23 to conserve energy - TODO: review method!
        wavefront_out.rescale_amplitude(
            numpy.sqrt(wavefront.get_intensity().sum() /
                       wavefront_out.get_intensity().sum()))

        return wavefront_out
Example #16
0
    def test_plane_wave(self, do_plot=do_plot):
        #
        # plane wave
        #
        print("#                                                             ")
        print(
            "# Tests for a 2D plane wave                                      "
        )
        print("#                                                             ")

        wavelength = 1.24e-10

        wavefront_length_x = 400e-6
        wavefront_length_y = wavefront_length_x

        npixels_x = 1024
        npixels_y = npixels_x

        x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x,
                           npixels_x)
        y = numpy.linspace(-0.5 * wavefront_length_y, 0.5 * wavefront_length_y,
                           npixels_y)

        wavefront = GenericWavefront2D.initialize_wavefront_from_steps(
            x_start=x[0],
            x_step=numpy.abs(x[1] - x[0]),
            y_start=y[0],
            y_step=numpy.abs(y[1] - y[0]),
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        # possible modifications

        wavefront.set_plane_wave_from_amplitude_and_phase(5.0, numpy.pi / 2)
        numpy.testing.assert_almost_equal(wavefront.get_intensity(), 25, 5)

        wavefront.set_plane_wave_from_complex_amplitude(2.0 + 3j)
        numpy.testing.assert_almost_equal(wavefront.get_intensity(), 13, 5)

        phase_before = wavefront.get_phase()
        wavefront.add_phase_shift(numpy.pi / 2)
        phase_after = wavefront.get_phase()
        numpy.testing.assert_almost_equal(phase_before + numpy.pi / 2,
                                          phase_after, 5)

        intensity_before = wavefront.get_intensity()
        wavefront.rescale_amplitude(10.0)
        intensity_after = wavefront.get_intensity()
        numpy.testing.assert_almost_equal(intensity_before * 100,
                                          intensity_after, 5)

        # interpolation

        wavefront.set_plane_wave_from_complex_amplitude(2.0 + 3j)
        test_value1 = wavefront.get_interpolated_complex_amplitude(0.01, 1.3)
        self.assertAlmostEqual((2.0 + 3j).real, test_value1.real, 5)
        self.assertAlmostEqual((2.0 + 3j).imag, test_value1.imag, 5)

        if do_plot:
            from srxraylib.plot.gol import plot_image
            plot_image(wavefront.get_intensity(),
                       wavefront.get_coordinate_x(),
                       wavefront.get_coordinate_y(),
                       title="Intensity (plane wave)",
                       show=0)
            plot_image(wavefront.get_phase(),
                       wavefront.get_coordinate_x(),
                       wavefront.get_coordinate_y(),
                       title="Phase (plane wave)",
                       show=1)
        (-2 * radius))


if __name__ == "__main__":

    try:
        initialize_default_propagator_2D()
    except:
        pass

    propagator = PropagationManager.Instance()

    wavefront = GenericWavefront2D.initialize_wavefront_from_range(
        x_min=-2.5e-3,
        x_max=2.5e-3,
        y_min=-1e-3,
        y_max=1e-3,
        number_of_points=(2 * 1024, 1024),
        wavelength=73e-12)

    radius = 28.3

    wavefront.set_spherical_wave(radius=radius)

    scale_factor = 1

    screen = WOScreen(name="PIRRONE")
    coordinates = ElementCoordinates(p=0.0, q=-scale_factor * radius)

    propagation_elements = PropagationElements()
    propagation_elements.add_beamline_element(
Example #18
0
            label.set_color('white')
            label.set_fontsize(1)

        self.plot_canvas._histoHPlot.setGraphYLabel('')
        self.plot_canvas._histoVPlot.setGraphXLabel('')

        self.plot_canvas._histoHPlot.replot()
        self.plot_canvas._histoVPlot.replot()

        self.info_box.clear()


if __name__ == "__main__":

    from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D
    w = GenericWavefront2D.initialize_wavefront_from_range(
        -0.002, 0.002, -0.001, 0.001, (200, 200))
    w.set_gaussian(0.00055, 0.0002)

    from PyQt5.QtWidgets import QApplication
    app = QApplication([])

    widget = QWidget()

    layout = QVBoxLayout()

    oo = ImageViewWithFWHM()
    oo.plot_2D(w.get_intensity(),
               w.get_coordinate_x(),
               w.get_coordinate_y(),
               factor1=1e6,
               factor2=1e6,
Example #19
0
    def test_propagate_2D_fraunhofer(self,do_plot=do_plot,aperture_type='square',aperture_diameter=40e-6,
                    pixelsize_x=1e-6,pixelsize_y=1e-6,npixels_x=1024,npixels_y=1024,wavelength=1.24e-10):
        """

        :param do_plot: 0=No plot, 1=Do plot
        :param aperture_type: 'circle' 'square' 'gaussian' (Gaussian sigma = aperture_diameter/2.35)
        :param aperture_diameter:
        :param pixelsize_x:
        :param pixelsize_y:
        :param npixels_x:
        :param npixels_y:
        :param wavelength:
        :return:
        """

        print("\n#                                                            ")
        print("# far field 2D (fraunhofer) diffraction from a square aperture  ")
        print("#                                                            ")

        method = "fraunhofer"

        print("Fraunhoffer diffraction valid for distances > > a^2/lambda = %f m"%((aperture_diameter/2)**2/wavelength))

        wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2,
                                                         y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2,
                                                         number_of_points=(npixels_x,npixels_y),wavelength=wavelength)

        wf.set_plane_wave_from_complex_amplitude((1.0+0j))


        propagation_elements = PropagationElements()

        slit = None

        if aperture_type == 'square':
            slit = WOSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2))
        elif aperture_type == 'gaussian':
            slit = WOGaussianSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2))
        else:
            raise Exception("Not implemented! (accepted: circle, square, gaussian)")

        propagation_elements.add_beamline_element(BeamlineElement(optical_element=slit,
                                                                  coordinates=ElementCoordinates(p=0, q=1.0)))


        propagator = PropagationManager.Instance()
        propagation_parameters = PropagationParameters(wavefront=wf,
                                                       propagation_elements=propagation_elements)
        propagation_parameters.set_additional_parameters("shift_half_pixel", True)

        wf1 = propagator.do_propagation(propagation_parameters, Fraunhofer2D.HANDLER_NAME)

        if aperture_type == 'circle':
            wf.clip_circle(aperture_diameter/2)
        elif aperture_type == 'square':
            wf.clip_square(-aperture_diameter/2, aperture_diameter/2,-aperture_diameter/2, aperture_diameter/2)
        elif aperture_type == 'gaussian':
            X = wf.get_mesh_x()
            Y = wf.get_mesh_y()
            window = numpy.exp(- (X*X + Y*Y)/2/(aperture_diameter/2.35)**2)
            wf.rescale_amplitudes(window)
        else:
            raise Exception("Not implemented! (accepted: circle, square, gaussian)")

        if do_plot:
            plot_image(wf.get_intensity(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(),
                       title="aperture intensity (%s), Diameter=%5.1f um"%
                             (aperture_type,1e6*aperture_diameter),xtitle="X [um]",ytitle="Y [um]",
                       show=0)

            plot_image(wf1.get_intensity(),1e6*wf1.get_coordinate_x(),1e6*wf1.get_coordinate_y(),
                       title="2D Diffracted intensity (%s) by a %s slit of aperture %3.1f um"%
                             (aperture_type,method,1e6*aperture_diameter),
                       xtitle="X [urad]",ytitle="Y [urad]",
                       show=0)

        angle_x = wf1.get_coordinate_x() # + 0.5*wf1.delta()[0] # shifted of half-pixel!!!
        intensity_theory = get_theoretical_diffraction_pattern(angle_x,
                                            aperture_type=aperture_type,aperture_diameter=aperture_diameter,
                                            wavelength=wavelength,normalization=True)


        intensity_calculated =  wf1.get_intensity()[:,int(wf1.size()[1]/2)]
        intensity_calculated /= intensity_calculated.max()

        if do_plot:
            plot(wf1.get_coordinate_x()*1e6,intensity_calculated,
                 angle_x*1e6,intensity_theory,
                 legend=["Calculated (FT) H profile","Theoretical"],legend_position=(0.95, 0.95),
                 title="2D Fraunhofer Diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"%
                       (aperture_type,aperture_diameter*1e6,wavelength*1e10),
                 xtitle="X (urad)", ytitle="Intensity",xrange=[-80,80])

        numpy.testing.assert_almost_equal(intensity_calculated,intensity_theory,1)
Example #20
0
    def test_propagate_2D_fraunhofer_phase(self,do_plot=do_plot,aperture_type='square',
                                aperture_diameter=40e-6,
                                pixelsize_x=1e-6,pixelsize_y=1e-6,npixels_x=1024,npixels_y=1024,
                                propagation_distance=30.0,wavelength=1.24e-10):


        print("\n#                                                            ")
        print("# far field 2D (fraunhofer) diffraction from a square aperture  ")
        print("#                                                            ")

        method = "fraunhofer"

        print("Fraunhoffer diffraction valid for distances > > a^2/lambda = %f m"%((aperture_diameter/2)**2/wavelength))

        wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2,
                                                         y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2,
                                                         number_of_points=(npixels_x,npixels_y),wavelength=wavelength)

        wf.set_plane_wave_from_complex_amplitude((1.0+0j))


        propagation_elements = PropagationElements()

        slit = None

        if aperture_type == 'square':
            slit = WOSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2))
        elif aperture_type == 'gaussian':
            slit = WOGaussianSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2))
        else:
            raise Exception("Not implemented! (accepted: circle, square, gaussian)")

        propagation_elements.add_beamline_element(BeamlineElement(optical_element=slit,
                                                                  coordinates=ElementCoordinates(p=0, q=propagation_distance)))


        propagator = PropagationManager.Instance()
        propagation_parameters = PropagationParameters(wavefront=wf,
                                                       propagation_elements=propagation_elements)


        propagation_parameters.set_additional_parameters("shift_half_pixel", True)
        wf1_fraunhofer = propagator.do_propagation(propagation_parameters, Fraunhofer2D.HANDLER_NAME)

        propagation_parameters.set_additional_parameters("shift_half_pixel", True)
        propagation_parameters.set_additional_parameters("magnification_x", 1.5)
        propagation_parameters.set_additional_parameters("magnification_y", 2.5)
        wf1_zoom = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME)


        if aperture_type == 'circle':
            wf.clip_circle(aperture_diameter/2)
        elif aperture_type == 'square':
            wf.clip_square(-aperture_diameter/2, aperture_diameter/2,-aperture_diameter/2, aperture_diameter/2)
        elif aperture_type == 'gaussian':
            X = wf.get_mesh_x()
            Y = wf.get_mesh_y()
            window = numpy.exp(- (X*X + Y*Y)/2/(aperture_diameter/2.35)**2)
            wf.rescale_amplitudes(window)
        else:
            raise Exception("Not implemented! (accepted: circle, square, gaussian)")

        if do_plot:
            plot_image(wf.get_intensity(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(),
                       title="aperture intensity (%s), Diameter=%5.1f um"%
                             (aperture_type,1e6*aperture_diameter),xtitle="X [um]",ytitle="Y [um]",
                       show=0)

            plot_image(wf1_fraunhofer.get_intensity(),1e6*wf1_fraunhofer.get_coordinate_x(),1e6*wf1_fraunhofer.get_coordinate_y(),
                       title="2D Diffracted intensity (%s) by a %s slit of aperture %3.1f um"%
                             (aperture_type,"Fraunhofer",1e6*aperture_diameter),
                       xtitle="X [urad]",ytitle="Y [urad]",
                       show=0)

            plot_image(wf1_zoom.get_intensity(),1e6*wf1_zoom.get_coordinate_x(),1e6*wf1_zoom.get_coordinate_y(),
                       title="2D Diffracted intensity (%s) by a %s slit of aperture %3.1f um"%
                             (aperture_type,"Zoom",1e6*aperture_diameter),
                       xtitle="X [urad]",ytitle="Y [urad]",
                       show=0)

        intensity_calculated_fraunhofer =  wf1_fraunhofer.get_intensity()[:,int(wf1_fraunhofer.size()[1]/2)]
        intensity_calculated_fraunhofer /= intensity_calculated_fraunhofer.max()

        intensity_calculated_zoom =  wf1_zoom.get_intensity()[:,int(wf1_fraunhofer.size()[1]/2)]
        intensity_calculated_zoom /= intensity_calculated_zoom.max()

        phase_calculated_fraunhofer =  wf1_fraunhofer.get_phase()[:,int(wf1_fraunhofer.size()[1]/2)]
        phase_calculated_fraunhofer = numpy.unwrap(phase_calculated_fraunhofer)

        phase_calculated_zoom =  wf1_zoom.get_phase()[:,int(wf1_zoom.size()[1]/2)]
        phase_calculated_zoom = numpy.unwrap(phase_calculated_zoom)

        if do_plot:
            plot(wf1_fraunhofer.get_coordinate_x()*1e6/propagation_distance, intensity_calculated_fraunhofer,
                 wf1_zoom.get_coordinate_x()*1e6      /propagation_distance, intensity_calculated_zoom,
                 legend=["Fraunhofer H profile","Zoom H profile"],legend_position=(0.95, 0.95),
                 title="2D Diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"%
                       (aperture_type,aperture_diameter*1e6,wavelength*1e10),
                 xtitle="X (urad)", ytitle="Intensity",xrange=[-80,80],show=0)

            plot(wf1_fraunhofer.get_coordinate_x()*1e6/propagation_distance, phase_calculated_fraunhofer,
                 wf1_zoom.get_coordinate_x()*1e6      /propagation_distance, phase_calculated_zoom,
                 legend=["Fraunhofer H profile","Zoom H profile"],legend_position=(0.95, 0.95),
                 title="2D Diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"%
                       (aperture_type,aperture_diameter*1e6,wavelength*1e10),
                 xtitle="X (urad)", ytitle="Phase",xrange=[-80,80])


        numpy.testing.assert_almost_equal(1e-3*intensity_calculated_fraunhofer,1e-3*intensity_calculated_zoom,1)
Example #21
0
    def propagate_2D_fresnel(self,do_plot=do_plot,method='fft',
                                wavelength=1.24e-10,aperture_type='square',aperture_diameter=40e-6,
                                pixelsize_x=1e-6,pixelsize_y=1e-6,npixels_x=1024,npixels_y=1024,
                                propagation_distance = 30.0,show=1,
                                use_additional_parameters_input_way=1, # 0=default (common), 1=new (specific))
                             ):


        method_label = "fresnel (%s)"%method
        print("\n#                                                             ")
        print("# 2D near field fresnel (%s) diffraction from a %s aperture  "%(method_label,aperture_type))
        print("#                                                             ")


        # wf = Wavefront2D.initialize_wavefront_from_steps(x_start=-pixelsize_x*npixels_x/2,
        #                                                         x_step=pixelsize_x,
        #                                                         y_start=-pixelsize_y*npixels_y/2,
        #                                                         y_step=pixelsize_y,
        #                                                         wavelength=wavelength,
        #                                                         number_of_points=(npixels_x,npixels_y))

        wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2,
                                                         y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2,
                                                         number_of_points=(npixels_x,npixels_y),wavelength=wavelength)

        wf.set_plane_wave_from_complex_amplitude((1.0+0j))


        propagation_elements = PropagationElements()

        slit = None

        if aperture_type == 'square':
            slit = WOSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2))
        elif aperture_type == 'gaussian':
            slit = WOGaussianSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2))
        else:
            raise Exception("Not implemented! (accepted: circle, square, gaussian)")


        if use_additional_parameters_input_way == 0:
            propagation_elements.add_beamline_element(BeamlineElement(optical_element=slit,
                                                                      coordinates=ElementCoordinates(p=0, q=propagation_distance)))


            propagator = PropagationManager.Instance()
            propagation_parameters = PropagationParameters(wavefront=wf,
                                                           propagation_elements=propagation_elements)

            if method == 'fft':
                propagation_parameters.set_additional_parameters("shift_half_pixel", True)
                wf1 = propagator.do_propagation(propagation_parameters, Fresnel2D.HANDLER_NAME)
            elif method == 'convolution':
                propagation_parameters.set_additional_parameters("shift_half_pixel", True)
                wf1 = propagator.do_propagation(propagation_parameters, FresnelConvolution2D.HANDLER_NAME)
            elif method == 'integral':
                propagation_parameters.set_additional_parameters("shuffle_interval", 0)
                propagation_parameters.set_additional_parameters("calculate_grid_only", 1)
                wf1 = propagator.do_propagation(propagation_parameters, Integral2D.HANDLER_NAME)
            elif method == 'zoom':
                propagation_parameters.set_additional_parameters("shift_half_pixel", True)
                propagation_parameters.set_additional_parameters("magnification_x", 2.0)
                propagation_parameters.set_additional_parameters("magnification_y", 0.5)
                wf1 = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME)
            else:
                raise Exception("Not implemented method: %s"%method)
        else:

            if method == 'fft':
                additional_parameters = {"shift_half_pixel":True}
            elif method == 'convolution':
                additional_parameters = {"shift_half_pixel":True}
            elif method == 'integral':
                additional_parameters = {"shuffle_interval":0,
                                         "calculate_grid_only":1}
            elif method == 'zoom':
                additional_parameters = {"shift_half_pixel":True,
                                         "magnification_x":2.0,
                                         "magnification_y":0.5}
            else:
                raise Exception("Not implemented method: %s"%method)


            propagation_elements.add_beamline_element(
                        BeamlineElement(optical_element=slit,coordinates=ElementCoordinates(p=0, q=propagation_distance)),
                        element_parameters=additional_parameters)


            propagator = PropagationManager.Instance()
            propagation_parameters = PropagationParameters(wavefront=wf,
                                                           propagation_elements=propagation_elements)

            if method == 'fft':
                wf1 = propagator.do_propagation(propagation_parameters, Fresnel2D.HANDLER_NAME)
            elif method == 'convolution':
                wf1 = propagator.do_propagation(propagation_parameters, FresnelConvolution2D.HANDLER_NAME)
            elif method == 'integral':
                wf1 = propagator.do_propagation(propagation_parameters, Integral2D.HANDLER_NAME)
            elif method == 'zoom':
                wf1 = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME)
            else:
                raise Exception("Not implemented method: %s"%method)


        if do_plot:
            from srxraylib.plot.gol import plot_image
            plot_image(wf.get_intensity(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(),
                       title="aperture intensity (%s), Diameter=%5.1f um"%
                             (aperture_type,1e6*aperture_diameter),xtitle="X [um]",ytitle="Y [um]",
                       show=0)

            plot_image(wf1.get_intensity(),
                       1e6*wf1.get_coordinate_x()/propagation_distance,
                       1e6*wf1.get_coordinate_y()/propagation_distance,
                       title="Diffracted intensity (%s) by a %s slit of aperture %3.1f um"%
                             (aperture_type,method_label,1e6*aperture_diameter),
                       xtitle="X [urad]",ytitle="Y [urad]",
                       show=0)

        # get the theoretical value
        angle_x = wf1.get_coordinate_x() / propagation_distance

        intensity_theory = get_theoretical_diffraction_pattern(angle_x,aperture_type=aperture_type,aperture_diameter=aperture_diameter,
                                            wavelength=wavelength,normalization=True)

        intensity_calculated =  wf1.get_intensity()[:,int(wf1.size()[1]/2)]
        intensity_calculated /= intensity_calculated.max()

        if do_plot:
            from srxraylib.plot.gol import plot
            plot(wf1.get_coordinate_x()*1e6/propagation_distance,intensity_calculated,
                 angle_x*1e6,intensity_theory,
                 legend=["%s H profile"%method_label,"Theoretical (far field)"],
                 legend_position=(0.95, 0.95),
                 title="%s diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"%
                       (method_label,aperture_type,aperture_diameter*1e6,wavelength*1e10),
                 xtitle="X (urad)", ytitle="Intensity",xrange=[-20,20],
                 show=show)

        return wf1.get_coordinate_x()/propagation_distance,intensity_calculated,angle_x,intensity_theory
Example #22
0
    def propagation_with_lens(self,do_plot=do_plot,method='fft',
                                wavelength=1.24e-10,
                                pixelsize_x=1e-6,npixels_x=2000,pixelsize_y=1e-6,npixels_y=2000,
                                propagation_distance=30.0,defocus_factor=1.0,propagation_steps=1,show=1):


        method_label = "fresnel (%s)"%method
        print("\n#                                                             ")
        print("# near field fresnel (%s) diffraction and focusing  "%(method_label))
        print("#                                                             ")

        #                               \ |  /
        #   *                           | | |                      *
        #                               / | \
        #   <-------    d  ---------------><---------   d   ------->
        #   d is propagation_distance

        # wf = Wavefront2D.initialize_wavefront_from_steps(x_start=-pixelsize_x*npixels_x/2,
        #                                                         x_step=pixelsize_x,
        #                                                         y_start=-pixelsize_y*npixels_y/2,
        #                                                         y_step=pixelsize_y,
        #                                                         wavelength=wavelength,
        #                                                         number_of_points=(npixels_x,npixels_y))

        wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2,
                                                         y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2,
                                                         number_of_points=(npixels_x,npixels_y),wavelength=wavelength)
        propagation_elements = PropagationElements()

        spherical_or_plane_and_lens = 1
        if spherical_or_plane_and_lens == 0:
            # set spherical wave at the lens entrance (radius=distance)
            wf.set_spherical_wave(complex_amplitude=1.0,radius=-propagation_distance)

            propagation_elements.add_beamline_element(BeamlineElement(optical_element=WOScreen(),
                                                                      coordinates=ElementCoordinates(p=0, q=propagation_distance)))

        else:
            # apply lens that will focus at propagation_distance downstream the lens.
            # Note that the vertical is a bit defocused
            wf.set_plane_wave_from_complex_amplitude(1.0+0j)

            focal_length = propagation_distance # / 2

            propagation_elements.add_beamline_element(BeamlineElement(optical_element=
                WOIdealLens("IdealLens",focal_x=focal_length, focal_y=focal_length),
                coordinates=ElementCoordinates(p=0, q=propagation_distance)))

        print("Incident intensity: ", wf.get_intensity().sum())

        propagator = PropagationManager.Instance()
        propagation_parameters = PropagationParameters(wavefront=wf,
                                                       propagation_elements=propagation_elements)

        if method == 'fft':
            propagation_parameters.set_additional_parameters("shift_half_pixel", True)
            wf1 = propagator.do_propagation(propagation_parameters, Fresnel2D.HANDLER_NAME)
        elif method == 'convolution':
            propagation_parameters.set_additional_parameters("shift_half_pixel", True)
            wf1 = propagator.do_propagation(propagation_parameters, FresnelConvolution2D.HANDLER_NAME)
        elif method == 'fraunhofer':
            propagation_parameters.set_additional_parameters("shift_half_pixel", True)
            wf1 = propagator.do_propagation(propagation_parameters, Fraunhofer2D.HANDLER_NAME)
        elif method == 'zoom':
            propagation_parameters.set_additional_parameters("shift_half_pixel", True)
            propagation_parameters.set_additional_parameters("magnification_x", 1.5)
            propagation_parameters.set_additional_parameters("magnification_y", 2.5)
            wf1 = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME)
        else:
            raise Exception("Not implemented method: %s"%method)

        horizontal_profile = wf1.get_intensity()[:, int(wf.size()[1]/2)]
        horizontal_profile /= horizontal_profile.max()
        print("FWHM of the horizontal profile: %g um"%(1e6*line_fwhm(horizontal_profile)*wf1.delta()[0]))
        vertical_profile = wf1.get_intensity()[int(wf1.size()[0]/2),:]
        vertical_profile /= vertical_profile.max()
        print("FWHM of the vertical profile: %g um"%(1e6*line_fwhm(vertical_profile)*wf1.delta()[1]))

        if do_plot:
            from srxraylib.plot.gol import plot,plot_image
            plot_image(wf1.get_intensity(),wf1.get_coordinate_x(),wf1.get_coordinate_y(),title='intensity (%s)'%method,show=0)
            plot_image(wf1.get_phase(),wf1.get_coordinate_x(),wf1.get_coordinate_y(),title='phase (%s)'%method,show=0)

            plot(wf1.get_coordinate_x(),horizontal_profile,
                 wf1.get_coordinate_y(),vertical_profile,
                 legend=['Horizontal profile','Vertical profile'],title="%s"%method,show=show)

        print("Output intensity: ",wf1.get_intensity().sum())
        return wf1.get_coordinate_x(),horizontal_profile
Example #23
0
    def test_initializers(self, do_plot=do_plot):

        print("#                                                             ")
        print("# Tests for initializars (2D)                                 ")
        print("#                                                             ")

        x = numpy.linspace(-100, 100, 50)
        y = numpy.linspace(-50, 50, 200)
        XY = numpy.meshgrid(x, y)
        X = XY[0].T
        Y = XY[1].T
        sigma = 10
        Z = numpy.exp(-(X**2 + Y**2) / 2 / sigma**2) * 1j
        print("Shapes x,y,z: ", x.shape, y.shape, Z.shape)

        wf0 = GenericWavefront2D.initialize_wavefront_from_steps(
            x[0],
            numpy.abs(x[1] - x[0]),
            y[0],
            numpy.abs(y[1] - y[0]),
            number_of_points=Z.shape)
        wf0.set_complex_amplitude(Z)

        wf1 = GenericWavefront2D.initialize_wavefront_from_range(
            x[0], x[-1], y[0], y[-1], number_of_points=Z.shape)
        wf1.set_complex_amplitude(Z)

        wf2 = GenericWavefront2D.initialize_wavefront_from_arrays(x, y, Z)

        if do_plot:
            from srxraylib.plot.gol import plot_image
            plot_image(wf0.get_intensity(),
                       wf0.get_coordinate_x(),
                       wf0.get_coordinate_y(),
                       title="initialize_wavefront_from_steps",
                       show=0)
            plot_image(wf1.get_intensity(),
                       wf1.get_coordinate_x(),
                       wf1.get_coordinate_y(),
                       title="initialize_wavefront_from_range",
                       show=0)
            plot_image(wf2.get_intensity(),
                       wf2.get_coordinate_x(),
                       wf2.get_coordinate_y(),
                       title="initialize_wavefront_from_arrays",
                       show=1)

        numpy.testing.assert_almost_equal(
            numpy.abs(Z)**2, wf0.get_intensity(), 11)
        numpy.testing.assert_almost_equal(
            numpy.abs(Z)**2, wf1.get_intensity(), 11)
        numpy.testing.assert_almost_equal(
            numpy.abs(Z)**2, wf2.get_intensity(), 11)

        numpy.testing.assert_almost_equal(x, wf0.get_coordinate_x(), 11)
        numpy.testing.assert_almost_equal(x, wf1.get_coordinate_x(), 11)
        numpy.testing.assert_almost_equal(x, wf2.get_coordinate_x(), 11)

        numpy.testing.assert_almost_equal(y, wf0.get_coordinate_y(), 11)
        numpy.testing.assert_almost_equal(y, wf1.get_coordinate_y(), 11)
        numpy.testing.assert_almost_equal(y, wf2.get_coordinate_y(), 11)
Example #24
0
def main(mode_wavefront_before_lens):

    #                               \ |  /
    #   *                           | | |                      *
    #                               / | \
    #   <-------    d  ---------------><---------   d   ------->
    #   d is propagation_distance
    # wavefron names at different positions
    #   wf1                     wf2     wf3                   wf4

    lens_diameter = 0.002  # 0.001 # 0.002

    if mode_wavefront_before_lens == 'Undulator with lens':
        npixels_x = 512
    else:
        npixels_x = int(2048 * 1.5)

    pixelsize_x = lens_diameter / npixels_x
    print("pixelsize: ", pixelsize_x)

    pixelsize_y = pixelsize_x
    npixels_y = npixels_x

    wavelength = 1.24e-10
    propagation_distance = 30.0
    defocus_factor = 1.0  # 1.0 is at focus
    propagation_steps = 1

    # for Gaussian source
    sigma_x = lens_diameter / 400  # 5e-6
    sigma_y = sigma_x  # 5e-6
    # for Hermite-Gauss, the H and V mode index (start from 0)
    hm = 3
    hn = 1

    if mode_wavefront_before_lens == 'convergent spherical':
        # no need to propagate nor define lens
        wf3 = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-pixelsize_x * npixels_x / 2,
            x_max=pixelsize_x * npixels_x / 2,
            y_min=-pixelsize_y * npixels_y / 2,
            y_max=pixelsize_y * npixels_y / 2,
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)
        wf3.set_spherical_wave(complex_amplitude=1.0,
                               radius=-propagation_distance)

    elif mode_wavefront_before_lens == 'divergent spherical with lens':
        # define wavefront at zero distance upstream the lens and apply lens

        focal_length = propagation_distance / 2.

        wf2 = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-pixelsize_x * npixels_x / 2,
            x_max=pixelsize_x * npixels_x / 2,
            y_min=-pixelsize_y * npixels_y / 2,
            y_max=pixelsize_y * npixels_y / 2,
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        wf2.set_spherical_wave(complex_amplitude=1.0,
                               radius=propagation_distance)
        wf3 = apply_lens(wf2, focal_length)

    elif mode_wavefront_before_lens == 'plane with lens':
        # define wavefront at zero distance upstream the lens and apply lens
        focal_length = propagation_distance

        wf2 = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-pixelsize_x * npixels_x / 2,
            x_max=pixelsize_x * npixels_x / 2,
            y_min=-pixelsize_y * npixels_y / 2,
            y_max=pixelsize_y * npixels_y / 2,
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        wf2.set_plane_wave_from_complex_amplitude(1.0 + 0j)

        wf3 = apply_lens(wf2, focal_length)

    elif mode_wavefront_before_lens == 'Gaussian with lens':
        # define wavefront at source point, propagate to the lens and apply lens

        wf1 = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-pixelsize_x * npixels_x / 2,
            x_max=pixelsize_x * npixels_x / 2,
            y_min=-pixelsize_y * npixels_y / 2,
            y_max=pixelsize_y * npixels_y / 2,
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        X = wf1.get_mesh_x()
        Y = wf1.get_mesh_y()

        intensity = numpy.exp(-X**2 /
                              (2 * sigma_x**2)) * numpy.exp(-Y**2 /
                                                            (2 * sigma_y**2))

        wf1.set_complex_amplitude(numpy.sqrt(intensity))

        # plot

        plot_image(wf1.get_intensity(),
                   1e6 * wf1.get_coordinate_x(),
                   1e6 * wf1.get_coordinate_y(),
                   xtitle="X um",
                   ytitle="Y um",
                   title="Gaussian source",
                   show=1)

        wf2, x2, h2 = propagation_in_vacuum(
            wf1, propagation_distance=propagation_distance)

        plot_image(wf2.get_intensity(),
                   1e6 * wf2.get_coordinate_x(),
                   1e6 * wf2.get_coordinate_y(),
                   xtitle="X um",
                   ytitle="Y um",
                   title="Before lens fft",
                   show=1)

        focal_length = propagation_distance / 2

        wf3 = apply_lens(wf2, focal_length)

    elif mode_wavefront_before_lens == 'Hermite with lens':
        # define wavefront at source point, propagate to the lens and apply lens

        wf1 = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-pixelsize_x * npixels_x / 2,
            x_max=pixelsize_x * npixels_x / 2,
            y_min=-pixelsize_y * npixels_y / 2,
            y_max=pixelsize_y * npixels_y / 2,
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        X = wf1.get_mesh_x()
        Y = wf1.get_mesh_y()

        efield =     (hermite(hm)(numpy.sqrt(2)*X/sigma_x)*numpy.exp(-X**2/sigma_x**2))**2 \
                   * (hermite(hn)(numpy.sqrt(2)*Y/sigma_y)*numpy.exp(-Y**2/sigma_y**2))**2

        wf1.set_complex_amplitude(efield)

        # plot

        plot_image(wf1.get_intensity(),
                   1e6 * wf1.get_coordinate_x(),
                   1e6 * wf1.get_coordinate_y(),
                   xtitle="X um",
                   ytitle="Y um",
                   title="Hermite-Gauss source",
                   show=1)

        wf2, x2, h2 = propagation_in_vacuum(wf1,
                                            propagation_distance=30.0,
                                            defocus_factor=1.0,
                                            propagation_steps=1)

        plot_image(wf2.get_intensity(),
                   1e6 * wf2.get_coordinate_x(),
                   1e6 * wf2.get_coordinate_y(),
                   xtitle="X um",
                   ytitle="Y um",
                   title="Before lens %s" % USE_PROPAGATOR,
                   show=1)

        wf3 = apply_lens(wf2, focal_length=propagation_distance / 2)

    elif mode_wavefront_before_lens == 'Undulator with lens':

        beamline = {}
        # beamline['name'] = "ESRF_NEW_OB"
        # beamline['ElectronBeamDivergenceH'] = 5.2e-6    # these values are not used (zero emittance)
        # beamline['ElectronBeamDivergenceV'] = 1.4e-6    # these values are not used (zero emittance)
        # beamline['ElectronBeamSizeH'] = 27.2e-6         # these values are not used (zero emittance)
        # beamline['ElectronBeamSizeV'] = 3.4e-6          # these values are not used (zero emittance)
        # beamline['ElectronEnergySpread'] = 0.001        # these values are not used (zero emittance)
        beamline['ElectronCurrent'] = 0.2
        beamline['ElectronEnergy'] = 6.0
        beamline['Kv'] = 1.68  # 1.87
        beamline['NPeriods'] = 111  # 14
        beamline['PeriodID'] = 0.018  # 0.035
        beamline['distance'] = propagation_distance
        # beamline['gapH']      = pixelsize_x*npixels_x
        # beamline['gapV']      = pixelsize_x*npixels_x

        gamma = beamline['ElectronEnergy'] / (codata_mee * 1e-3)
        print("Gamma: %f \n" % (gamma))

        resonance_wavelength = (
            1 + beamline['Kv']**2 / 2.0) / 2 / gamma**2 * beamline["PeriodID"]
        resonance_energy = m2ev / resonance_wavelength

        print("Resonance wavelength [A]: %g \n" %
              (1e10 * resonance_wavelength))
        print("Resonance energy [eV]: %g \n" % (resonance_energy))

        # red shift 100 eV
        resonance_energy = resonance_energy - 100

        myBeam = ElectronBeam(Electron_energy=beamline['ElectronEnergy'],
                              I_current=beamline['ElectronCurrent'])
        myUndulator = MagneticStructureUndulatorPlane(
            K=beamline['Kv'],
            period_length=beamline['PeriodID'],
            length=beamline['PeriodID'] * beamline['NPeriods'])

        wf2 = GenericWavefront2D.initialize_wavefront_from_range(
            x_min=-pixelsize_x * npixels_x / 2,
            x_max=pixelsize_x * npixels_x / 2,
            y_min=-pixelsize_y * npixels_y / 2,
            y_max=pixelsize_y * npixels_y / 2,
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        XX = wf2.get_mesh_x()
        YY = wf2.get_mesh_y()
        X = wf2.get_coordinate_x()
        Y = wf2.get_coordinate_y()

        source = SourceUndulatorPlane(undulator=myUndulator,
                                      electron_beam=myBeam,
                                      magnetic_field=None)
        omega = resonance_energy * codata.e / codata.hbar
        Nb_pts_trajectory = int(
            source.choose_nb_pts_trajectory(0.01, photon_frequency=omega))
        print("Number of trajectory points: ", Nb_pts_trajectory)

        traj_fact = TrajectoryFactory(Nb_pts=Nb_pts_trajectory,
                                      method=TRAJECTORY_METHOD_ODE,
                                      initial_condition=None)

        print("Number of trajectory points: ", traj_fact.Nb_pts)

        if (traj_fact.initial_condition == None):
            traj_fact.initial_condition = source.choose_initial_contidion_automatic(
            )

        print("Number of trajectory points: ", traj_fact.Nb_pts,
              traj_fact.initial_condition)

        rad_fact = RadiationFactory(method=RADIATION_METHOD_NEAR_FIELD,
                                    photon_frequency=omega)

        #print('step 3')
        trajectory = traj_fact.create_from_source(source=source)

        #print('step 4')
        radiation = rad_fact.create_for_one_relativistic_electron(
            trajectory=trajectory,
            source=source,
            XY_are_list=False,
            distance=beamline['distance'],
            X=X,
            Y=Y)

        efield = rad_fact.calculate_electrical_field(
            trajectory=trajectory,
            source=source,
            distance=beamline['distance'],
            X_array=XX,
            Y_array=YY)

        tmp = efield.electrical_field()[:, :, 0]

        wf2.set_photon_energy(resonance_energy)
        wf2.set_complex_amplitude(tmp)

        # plot

        plot_image(wf2.get_intensity(),
                   1e6 * wf2.get_coordinate_x(),
                   1e6 * wf2.get_coordinate_y(),
                   xtitle="X um",
                   ytitle="Y um",
                   title="UND source at lens plane",
                   show=1)

        # apply lens

        focal_length = propagation_distance / 2

        wf3 = apply_lens(wf2, focal_length=focal_length)

    else:
        raise Exception("Unknown mode")

    plot_image(wf3.get_phase(),
               1e6 * wf3.get_coordinate_x(),
               1e6 * wf3.get_coordinate_y(),
               title="Phase just after the lens %s" % USE_PROPAGATOR,
               xtitle="X um",
               ytitle="Y um",
               show=1)

    wf4, x4, h4 = propagation_in_vacuum(
        wf3,
        propagation_distance=propagation_distance,
        defocus_factor=1.0,
        propagation_steps=1)

    plot_image(wf4.get_intensity(),
               1e6 * wf4.get_coordinate_x(),
               1e6 * wf4.get_coordinate_y(),
               title="Intensity at focal point %s" % USE_PROPAGATOR,
               xtitle="X um",
               ytitle="Y um",
               show=1)

    plot(1e4 * x4,
         h4,
         xtitle='x [um]',
         ytitle='intensity',
         title='horizontal profile',
         show=True)
if __name__ == "__main__":

    from json_tools import load_from_json_file
    from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D
    from srxraylib.plot.gol import plot_image

    from wofry.propagator.propagator import PropagationManager, PropagationElements, PropagationParameters
    from wofryimpl.propagator.propagators2D.fresnel_zoom_xy import FresnelZoomXY2D

    wfr = GenericWavefront2D.load_h5_file("source.h5", "wfr")
    plot_image(wfr.get_intensity(),
               1e6 * wfr.get_coordinate_x(),
               1e6 * wfr.get_coordinate_y(),
               title="Source",
               xtitle="X [um]",
               ytitle="Y [um]")

    bl = load_from_json_file("beamline.json")

    #
    # propagate elements using Fresnel Zoom propagator
    #
    magnification_x = [1, 1, 0.01, 440, 1, 1, 1, 0.00007]
    magnification_y = [1, 1, 1, 5, 1, 0.5, 1, 0.00009]

    # define propagator to be used
    propagator = PropagationManager.Instance()

    try:
        propagator.add_propagator(FresnelZoomXY2D())
    except:
Example #26
0
    def test_spherical_wave(self, do_plot=do_plot):
        #
        # plane wave
        #
        print("#                                                             ")
        print("# Tests for a 2D spherical wave                               ")
        print("#                                                             ")

        wavelength = 1.24e-10

        wavefront_length_x = 400e-6
        wavefront_length_y = wavefront_length_x

        npixels_x = 1024
        npixels_y = npixels_x

        x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x,
                           npixels_x)
        y = numpy.linspace(-0.5 * wavefront_length_y, 0.5 * wavefront_length_y,
                           npixels_y)

        wf1 = GenericWavefront2D.initialize_wavefront_from_steps(
            x_start=x[0],
            x_step=numpy.abs(x[1] - x[0]),
            y_start=y[0],
            y_step=numpy.abs(y[1] - y[0]),
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        numpy.testing.assert_almost_equal(x, wf1.get_coordinate_x(), 9)
        numpy.testing.assert_almost_equal(y, wf1.get_coordinate_y(), 9)

        wf2 = GenericWavefront2D.initialize_wavefront_from_steps(
            x_start=x[0],
            x_step=numpy.abs(x[1] - x[0]),
            y_start=y[0],
            y_step=numpy.abs(y[1] - y[0]),
            number_of_points=(npixels_x, npixels_y),
            wavelength=wavelength)

        numpy.testing.assert_almost_equal(x, wf2.get_coordinate_x(), 9)
        numpy.testing.assert_almost_equal(y, wf2.get_coordinate_y(), 9)
        # an spherical wavefront is obtained 1) by creation, 2) focusing a planewave

        wf1.set_spherical_wave(-5.0, 3 + 0j)
        wf1.clip_square(-50e-6, 10e-6, -20e-6, 40e-6)

        wf2.set_plane_wave_from_complex_amplitude(3 + 0j)

        ideal_lens = WOIdealLens("test", 5.0, 5.0)
        ideal_lens.applyOpticalElement(wf2)

        wf2.clip_square(-50e-6, 10e-6, -20e-6, 40e-6)

        if do_plot:
            from srxraylib.plot.gol import plot_image
            plot_image(wf1.get_phase(),
                       wf2.get_coordinate_x(),
                       wf2.get_coordinate_y(),
                       title="Phase of spherical wavefront",
                       show=0)
            plot_image(wf2.get_phase(),
                       wf2.get_coordinate_x(),
                       wf2.get_coordinate_y(),
                       title="Phase of focused plane wavefront",
                       show=0)
            plot_image(
                wf1.get_phase(from_minimum_intensity=0.1),
                wf2.get_coordinate_x(),
                wf2.get_coordinate_y(),
                title="Phase of spherical wavefront (for intensity > 0.1)",
                show=0)
            plot_image(
                wf2.get_phase(from_minimum_intensity=0.1),
                wf2.get_coordinate_x(),
                wf2.get_coordinate_y(),
                title="Phase of focused plane wavefront (for intensity > 0.1)",
                show=1)

        numpy.testing.assert_almost_equal(wf1.get_phase(), wf2.get_phase(), 5)
Example #27
0
    def write_file(self):
        self.setStatusMessage("")

        try:
            if not self.af is None:
                congruence.checkDir(self.file_name)

                if self.TYPE_OF_OUTPUT == 0:  # ['COMSYL hdf5 with multi-mode','WOFRY hdf5 with multi-mode','WOFRY multiple files'
                    if self.ALL_MODES:
                        self.af.write_h5(self.file_name,
                                         maximum_number_of_modes=None)
                    else:
                        self.af.write_h5(self.file_name,
                                         maximum_number_of_modes=self.MODE_TO)
                        path, file_name = os.path.split(self.file_name)
                        self.setStatusMessage("File Out: " + file_name)
                else:  # WOFRY
                    if self.ALL_MODES == 0 and (self.MODE_TO <
                                                self.af.number_of_modes()):
                        nmax = self.MODE_TO
                    else:
                        nmax = self.af.number_of_modes()

                    for i in range(nmax + 1):
                        eigenvalue = numpy.real(self.af.eigenvalue(i), )
                        eigenfunction = self.af.mode(i)
                        w = GenericWavefront2D.initialize_wavefront_from_arrays(
                            self.af.x_coordinates(), self.af.y_coordinates(),
                            eigenfunction * numpy.sqrt(eigenvalue))
                        w.set_photon_energy(self.af.photon_energy())

                        if self.TYPE_OF_OUTPUT == 1:  #
                            file_name = self.file_name
                            subgroupname = "mode" + self.index_format % (i)
                            overwrite = False
                        elif self.TYPE_OF_OUTPUT == 2:
                            subgroupname = "mode" + self.index_format % (i)
                            file_name = self.file_name.split(".")[0] + "_" + (
                                self.index_format % i) + ".h5"
                            overwrite = True

                        if i == 0:
                            w.save_h5_file(file_name,
                                           subgroupname=subgroupname,
                                           intensity=True,
                                           phase=True,
                                           overwrite=True)
                        else:
                            w.save_h5_file(file_name,
                                           subgroupname=subgroupname,
                                           intensity=True,
                                           phase=True,
                                           overwrite=overwrite)
                        path, file_name = os.path.split(file_name)
                        self.setStatusMessage("File Out: " + file_name)

                # path, file_name = os.path.split(self.file_name)

                # self.setStatusMessage("File Out: " + file_name)

            else:
                QMessageBox.critical(self, "Error", "COMSYL modes not present",
                                     QMessageBox.Ok)
        except Exception as exception:
            QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)
Example #28
0
    def propagate_wavefront(cls,
                            wavefront1,
                            propagation_distance,
                            magnification_x=1.0,
                            magnification_y=1.0,
                            shift_half_pixel=False):

        wavefront = wavefront1.duplicate()
        wavelength = wavefront.get_wavelength()
        wavenumber = wavefront.get_wavenumber()

        shape = wavefront.size()
        delta = wavefront.delta()

        # frequency for axis 1
        pixelsize = delta[0]
        npixels = shape[0]
        freq_nyquist = 0.5 / pixelsize
        freq_n = numpy.linspace(-1.0, 1.0, npixels)
        freq_x0 = freq_n * freq_nyquist

        freq_x1 = numpy.fft.fftfreq(npixels, pixelsize)
        freq_x1 = numpy.fft.ifftshift(freq_x1)

        # frequency for axis 2
        pixelsize = delta[1]
        npixels = shape[1]
        freq_nyquist = 0.5 / pixelsize
        freq_n = numpy.linspace(-1.0, 1.0, npixels)
        freq_y0 = freq_n * freq_nyquist

        freq_y1 = numpy.fft.fftfreq(npixels, pixelsize)
        freq_y1 = numpy.fft.ifftshift(freq_y1)

        print(freq_x0[0:10], freq_x1[0:10])

        # It happens that with method=0 (old) the propagation of a centro-symmetric beam
        # is not longer center but shifted.
        # This is due to "shifted" storage of the frequencies that is dependent on the
        # even or odd number of pixels.
        # It seems that with the new method (method=1) the beam is center.
        # Note: The new method ignores the shift_half_pixel keyword
        # See also doscussion with V. Favre-Nicolin email to srio on 2018-05-02
        method = 1  # 0-old, 1-new

        if method == 0:
            freq_x = freq_x0
            freq_y = freq_y0
            if shift_half_pixel:
                freq_x = freq_x - 0.5 * numpy.abs(freq_x[1] - freq_x[0])
                freq_y = freq_y - 0.5 * numpy.abs(freq_y[1] - freq_y[0])
        else:
            freq_x = freq_x1
            freq_y = freq_y1

        f_x, f_y = numpy.meshgrid(freq_x, freq_y, indexing='ij')
        fsq = numpy.fft.fftshift(f_x**2 / magnification_x +
                                 f_y**2 / magnification_y)

        x = wavefront.get_mesh_x()
        y = wavefront.get_mesh_y()

        x_rescaling = wavefront.get_mesh_x() * magnification_x
        y_rescaling = wavefront.get_mesh_y() * magnification_y

        r1sq = x**2 * (1 - magnification_x) + y**2 * (1 - magnification_y)
        r2sq = x_rescaling**2 * (
            (magnification_x - 1) / magnification_x) + y_rescaling**2 * (
                (magnification_y - 1) / magnification_y)

        Q1 = wavenumber / 2 / propagation_distance * r1sq
        Q2 = numpy.exp(-1.0j * numpy.pi * wavelength * propagation_distance *
                       fsq)
        Q3 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * r2sq)

        wavefront.add_phase_shift(Q1)

        fft = numpy.fft.fft2(wavefront.get_complex_amplitude())

        ifft = numpy.fft.ifft2(fft * Q2) * Q3 / numpy.sqrt(
            magnification_x * magnification_y)

        wf_propagated = GenericWavefront2D.initialize_wavefront_from_arrays(
            x_array=wavefront.get_coordinate_x() * magnification_x,
            y_array=wavefront.get_coordinate_y() * magnification_y,
            z_array=ifft,
            wavelength=wavelength)
        return wf_propagated
Example #29
0
    def propagate_wavefront(cls,wavefront,propagation_distance,shuffle_interval=False,calculate_grid_only=True):
        #
        # Fresnel-Kirchhoff integral (neglecting inclination factor)
        #

        if not calculate_grid_only:
            #
            # calculation over the whole detector area
            #
            p_x = wavefront.get_coordinate_x()
            p_y = wavefront.get_coordinate_y()
            wavelength = wavefront.get_wavelength()
            amplitude = wavefront.get_complex_amplitude()

            det_x = p_x.copy()
            det_y = p_y.copy()

            p_X = wavefront.get_mesh_x()
            p_Y = wavefront.get_mesh_y()

            det_X = p_X
            det_Y = p_Y


            amplitude_propagated = numpy.zeros_like(amplitude,dtype='complex')

            wavenumber = 2 * numpy.pi / wavelength

            for i in range(det_x.size):
                for j in range(det_y.size):
                    if not shuffle_interval:
                        rd_x = 0.0
                        rd_y = 0.0
                    else:
                        rd_x = (numpy.random.rand(p_x.size,p_y.size)-0.5)*shuffle_interval
                        rd_y = (numpy.random.rand(p_x.size,p_y.size)-0.5)*shuffle_interval

                    r = numpy.sqrt( numpy.power(p_X + rd_x - det_X[i,j],2) +
                                    numpy.power(p_Y + rd_y - det_Y[i,j],2) +
                                    numpy.power(propagation_distance,2) )

                    amplitude_propagated[i,j] = (amplitude / r * numpy.exp(1.j * wavenumber *  r)).sum()

            output_wavefront = GenericWavefront2D.initialize_wavefront_from_arrays(det_x,det_y,amplitude_propagated)

        else:
            x = wavefront.get_coordinate_x()
            y = wavefront.get_coordinate_y()
            X = wavefront.get_mesh_x()
            Y = wavefront.get_mesh_y()
            wavenumber = 2 * numpy.pi / wavefront.get_wavelength()
            amplitude = wavefront.get_complex_amplitude()

            used_indices = wavefront.get_mask_grid(width_in_pixels=(1,1),number_of_lines=(1,1))
            indices_x = wavefront.get_mesh_indices_x()
            indices_y = wavefront.get_mesh_indices_y()

            indices_x_flatten = indices_x[numpy.where(used_indices == 1)].flatten()
            indices_y_flatten = indices_y[numpy.where(used_indices == 1)].flatten()
            X_flatten         =         X[numpy.where(used_indices == 1)].flatten()
            Y_flatten         =         Y[numpy.where(used_indices == 1)].flatten()
            complex_amplitude_propagated = amplitude*0

            print("propagate_2D_integral: Calculating %d points from a total of %d x %d = %d"%(
                X_flatten.size,amplitude.shape[0],amplitude.shape[1],amplitude.shape[0]*amplitude.shape[1]))

            for i in range(X_flatten.size):
                r = numpy.sqrt( numpy.power(wavefront.get_mesh_x() - X_flatten[i],2) +
                                numpy.power(wavefront.get_mesh_y() - Y_flatten[i],2) +
                                numpy.power(propagation_distance,2) )

                complex_amplitude_propagated[int(indices_x_flatten[i]),int(indices_y_flatten[i])] = (amplitude / r * numpy.exp(1.j * wavenumber *  r)).sum()

            output_wavefront = GenericWavefront2D.initialize_wavefront_from_arrays(x_array=x,
                                                                                   y_array=y,
                                                                                   z_array=complex_amplitude_propagated,
                                                                                   wavelength=wavefront.get_wavelength())

        # added [email protected] 2018-03-23 to conserve energy - TODO: review method!
        output_wavefront.rescale_amplitude( numpy.sqrt(wavefront.get_intensity().sum() /
                                                    output_wavefront.get_intensity().sum()))

        return output_wavefront
Example #30
0
    def propagate_wavefront(cls,
                            wavefront1,
                            propagation_distance,
                            magnification_x=1.0,
                            magnification_y=1.0,
                            shift_half_pixel=False):

        wavefront = wavefront1.duplicate()
        wavelength = wavefront.get_wavelength()
        wavenumber = wavefront.get_wavenumber()

        shape = wavefront.size()
        delta = wavefront.delta()

        pixelsize = delta[0]
        npixels = shape[0]
        freq_nyquist = 0.5 / pixelsize
        freq_n = numpy.linspace(-1.0, 1.0, npixels)
        freq_x = freq_n * freq_nyquist

        # frequency for axis 2
        pixelsize = delta[1]
        npixels = shape[1]
        freq_nyquist = 0.5 / pixelsize
        freq_n = numpy.linspace(-1.0, 1.0, npixels)
        freq_y = freq_n * freq_nyquist

        if shift_half_pixel:
            freq_x = freq_x - 0.5 * numpy.abs(freq_x[1] - freq_x[0])
            freq_y = freq_y - 0.5 * numpy.abs(freq_y[1] - freq_y[0])

        f_x, f_y = numpy.meshgrid(freq_x, freq_y, indexing='ij')
        fsq = numpy.fft.fftshift(f_x**2 / magnification_x +
                                 f_y**2 / magnification_y)

        x = wavefront.get_mesh_x()
        y = wavefront.get_mesh_y()

        x_rescaling = wavefront.get_mesh_x() * magnification_x
        y_rescaling = wavefront.get_mesh_y() * magnification_y

        r1sq = x**2 * (1 - magnification_x) + y**2 * (1 - magnification_y)
        r2sq = x_rescaling**2 * (
            (magnification_x - 1) / magnification_x) + y_rescaling**2 * (
                (magnification_y - 1) / magnification_y)

        Q1 = wavenumber / 2 / propagation_distance * r1sq
        Q2 = numpy.exp(-1.0j * numpy.pi * wavelength * propagation_distance *
                       fsq)
        Q3 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * r2sq)

        wavefront.add_phase_shift(Q1)

        fft = numpy.fft.fft2(wavefront.get_complex_amplitude())

        ifft = numpy.fft.ifft2(fft * Q2) * Q3 / numpy.sqrt(
            magnification_x * magnification_y)

        wf_propagated = GenericWavefront2D.initialize_wavefront_from_arrays(
            x_array=wavefront.get_coordinate_x() * magnification_x,
            y_array=wavefront.get_coordinate_y() * magnification_y,
            z_array=ifft,
            wavelength=wavelength)
        return wf_propagated
Example #31
0
    def test_interpolator(self, do_plot=do_plot):
        #
        # interpolator
        #
        print("#                                                             ")
        print("# Tests for 2D interpolator                                   ")
        print("#                                                             ")

        x = numpy.linspace(-10, 10, 100)
        y = numpy.linspace(-20, 20, 50)

        xy = numpy.meshgrid(x, y)
        X = xy[0].T
        Y = xy[1].T
        sigma = 3.0
        Z = 3 * numpy.exp(-(X**2 + Y**2) / 2 / sigma**2) + 4j

        print("shape of Z", Z.shape)

        wf = GenericWavefront2D.initialize_wavefront_from_steps(
            x[0], x[1] - x[0], y[0], y[1] - y[0], number_of_points=(100, 50))
        print("wf shape: ", wf.size())
        print("wf polarized: ", wf.is_polarized())
        wf.set_complex_amplitude(Z)

        x1 = 3.2
        y1 = -2.5
        z1 = 3 * numpy.exp(-(x1**2 + y1**2) / 2 / sigma**2) + 4j
        print("complex ampl at (%g,%g): %g+%gi (exact=%g+%gi)" %
              (x1, y1, wf.get_interpolated_complex_amplitude(
                  x1, y1).real, wf.get_interpolated_complex_amplitude(
                      x1, y1).imag, z1.real, z1.imag))
        self.assertAlmostEqual(
            wf.get_interpolated_complex_amplitude(x1, y1).real, z1.real, 4)
        self.assertAlmostEqual(
            wf.get_interpolated_complex_amplitude(x1, y1).imag, z1.imag, 4)
        #
        print(
            "intensity  at (%g,%g):   %g (exact=%g)" %
            (x1, y1, wf.get_interpolated_intensity(x1, y1), numpy.abs(z1)**2))
        self.assertAlmostEqual(wf.get_interpolated_intensity(x1, y1),
                               numpy.abs(z1)**2, 3)

        # interpolate on same grid

        interpolated_complex_amplitude_on_same_grid = wf.get_interpolated_complex_amplitudes(
            X, Y)
        print("Shape interpolated at same grid: ",
              interpolated_complex_amplitude_on_same_grid.shape)

        numpy.testing.assert_array_almost_equal(
            wf.get_complex_amplitude(),
            interpolated_complex_amplitude_on_same_grid, 4)

        print(
            "Total intensity original wavefront: %g, interpolated on the same grid: %g"
            % (wf.get_intensity().sum(),
               (numpy.abs(interpolated_complex_amplitude_on_same_grid)**
                2).sum()))

        if do_plot:
            from srxraylib.plot.gol import plot_image
            plot_image(wf.get_intensity(),
                       wf.get_coordinate_x(),
                       wf.get_coordinate_y(),
                       title="Original",
                       show=0)
            plot_image(wf.get_interpolated_intensity(X, Y),
                       wf.get_coordinate_x(),
                       wf.get_coordinate_y(),
                       title="interpolated on same grid",
                       show=1)

        # rebin wavefront

        # wf.set_plane_wave_from_complex_amplitude(3+4j)
        wf_rebin = wf.rebin(2.0,
                            5.0,
                            0.5,
                            0.8,
                            keep_the_same_intensity=1,
                            set_extrapolation_to_zero=1)
        print("Shape before rebinning: ", wf.size())
        print("Shape after rebinning: ", wf_rebin.size())

        print("Total intensity original wavefront: %g, rebinned: %g" %
              (wf.get_intensity().sum(), wf_rebin.get_intensity().sum()))

        if do_plot:
            from srxraylib.plot.gol import plot_image
            plot_image(wf.get_intensity(),
                       wf.get_coordinate_x(),
                       wf.get_coordinate_y(),
                       title="BEFORE REBINNING",
                       show=0)
            plot_image(wf_rebin.get_intensity(),
                       wf_rebin.get_coordinate_x(),
                       wf_rebin.get_coordinate_y(),
                       title="REBINNED",
                       show=1)