예제 #1
0
    def test_spherical_wave(self, do_plot=do_plot):
        #
        # plane wave
        #
        print("#                                                             ")
        print("# Tests for a 1D spherical wave                               ")
        print("#                                                             ")

        wavelength = 1.24e-10

        wavefront_length_x = 400e-6

        npixels_x = 1024

        wavefront_x = numpy.linspace(-0.5 * wavefront_length_x,
                                     0.5 * wavefront_length_x, npixels_x)

        wf1 = GenericWavefront1D.initialize_wavefront_from_steps(
            x_start=wavefront_x[0],
            x_step=numpy.abs(wavefront_x[1] - wavefront_x[0]),
            number_of_points=npixels_x,
            wavelength=wavelength)

        wf2 = GenericWavefront1D.initialize_wavefront_from_steps(
            x_start=wavefront_x[0],
            x_step=numpy.abs(wavefront_x[1] - wavefront_x[0]),
            number_of_points=npixels_x,
            wavelength=wavelength)

        # an spherical wavefront is obtained 1) by creation, 2) focusing a planewave

        wf1.set_spherical_wave(radius=-5.0, complex_amplitude=3 + 0j)
        wf1.clip(-50e-6, 10e-6)

        wf2.set_plane_wave_from_complex_amplitude(3 + 0j)
        ideal_lens = WOIdealLens1D("test", 5.0)
        ideal_lens.applyOpticalElement(wf2)
        wf2.clip(-50e-6, 10e-6)

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

        numpy.testing.assert_almost_equal(wf1.get_phase(), wf2.get_phase(), 5)
예제 #2
0
 def test_save_load_h5_file(self):
     wfr = GenericWavefront1D.initialize_wavefront_from_range(
         -2.0, 2.0, number_of_points=100)
     wfr.set_gaussian(.2, amplitude=5 + 8j)
     print("Saving 1D wavefront to file: tmp.h5")
     wfr.save_h5_file("tmp.h5", "wfr1", intensity=True, phase=True)
     print("Reading 1D wavefront from file: tmp.h5")
     wfr2 = GenericWavefront1D.load_h5_file("tmp.h5", "wfr1")
     print("Cleaning file tmp.h5")
     os.remove("tmp.h5")
     assert (wfr2.is_identical(wfr))
예제 #3
0
    def get_Wavefront1D_from_profile(self, axis, coordinate):
        # swap axis - changed giovanni+manuel
        if axis == 1: # fixed X
            index = numpy.argmin(numpy.abs(self._electric_field_matrix.x_coord - coordinate))

            return GenericWavefront1D(wavelength=self._wavelength,
                                      electric_field_array=ScaledArray(scale=self._electric_field_matrix.y_coord,
                                                                       np_array=self._electric_field_matrix.z_values[index, :]))
        elif axis == 0:
            index = numpy.argmin(numpy.abs(self._electric_field_matrix.y_coord - coordinate))

            return GenericWavefront1D(wavelength=self._wavelength,
                                      electric_field_array=ScaledArray(scale=self._electric_field_matrix.x_coord,
                                                                       np_array=self._electric_field_matrix.z_values[:, index]))
예제 #4
0
def propagator1D_offaxis(input_wavefront, x2_oe, y2_oe, p, q, theta_grazing_in, theta_grazing_out=None,
                         zoom_factor=1.0, normalize_intensities=False):

    from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D

    if theta_grazing_out is None:
        theta_grazing_out = theta_grazing_in

    x1 = input_wavefront.get_abscissas()
    field1 = input_wavefront.get_complex_amplitude()
    wavelength = input_wavefront.get_wavelength()

    x1_oe = -p * numpy.cos(theta_grazing_in) + x1 * numpy.sin(theta_grazing_in)
    y1_oe = p * numpy.sin(theta_grazing_in) + x1 * numpy.cos(theta_grazing_in)

    # field2 is the electric field in the mirror
    field2 = goFromToSequential(field1, x1_oe, y1_oe, x2_oe, y2_oe,
                                wavelength=wavelength, normalize_intensities=normalize_intensities)

    x3 = x1 * zoom_factor

    x3_oe = q * numpy.cos(theta_grazing_out) + x3 * numpy.sin(theta_grazing_out)
    y3_oe = q * numpy.sin(theta_grazing_out) + x3 * numpy.cos(theta_grazing_out)

    # field2 is the electric field in the image plane
    field3 = goFromToSequential(field2, x2_oe, y2_oe, x3_oe, y3_oe,
                                wavelength=wavelength, normalize_intensities=normalize_intensities)

    output_wavefront = GenericWavefront1D.initialize_wavefront_from_arrays(x3, field3  / numpy.sqrt(zoom_factor), wavelength=wavelength)

    return output_wavefront
예제 #5
0
    def propagate_wavefront(cls,
                            wavefront,
                            propagation_distance,
                            shift_half_pixel=False):

        shape = wavefront.size()
        delta = wavefront.delta()
        wavelength = wavefront.get_wavelength()
        wavenumber = wavefront.get_wavenumber()
        fft_scale = numpy.fft.fftfreq(shape, d=delta)
        fft_scale = numpy.fft.fftshift(fft_scale)
        x2 = fft_scale * propagation_distance * wavelength

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

        p1 = numpy.exp(1.0j * wavenumber * propagation_distance)
        p2 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * x2**2)
        p3 = 1.0j * wavelength * propagation_distance

        fft = numpy.fft.fft(wavefront.get_complex_amplitude())
        fft = fft * p1 * p2 / p3
        fft2 = numpy.fft.fftshift(fft)

        wavefront_out = GenericWavefront1D.initialize_wavefront_from_arrays(
            x2, fft2, wavelength=wavefront.get_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
 def get_eigenvector_wavefront(self, mode):
     complex_amplitude = self.get_eigenvectors()[mode, :] * np.sqrt(
         self.get_eigenvalue(mode))
     wf = GenericWavefront1D.initialize_wavefront_from_arrays(
         self.abscissas, complex_amplitude)
     wf.set_photon_energy(self.photon_energy)
     return wf
    def _calculate_far_field(self):
        #
        # undulator emission
        #
        out = self.calculate_undulator_emission(
            electron_energy=self.electron_energy,
            electron_current=self.electron_current,
            undulator_period=self.undulator_period,
            undulator_nperiods=self.undulator_nperiods,
            K=self.K,
            photon_energy=self.photon_energy,
            abscissas_interval_in_far_field=self.
            _abscissas_interval_in_far_field,
            number_of_points=self.number_of_points,
            distance_to_screen=self.distance_to_screen,
            scan_direction=self.scan_direction,
        )

        #
        #
        #
        from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D

        input_wavefront = GenericWavefront1D.initialize_wavefront_from_arrays(
            out["abscissas"], out["electric_field"][:, 0])
        input_wavefront.set_photon_energy(photon_energy=self.photon_energy)

        self.far_field_wavefront = input_wavefront
def calculate_wavefront1D(wavelength=1e-10,
                          undulator_length=1.0, undulator_distance=10.0,
                          x_min=-0.1, x_max=0.1, number_of_points=101,
                          wavefront_position=0, add_random_phase=0):
    from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D

    sigma_r = 2.740 / 4 / numpy.pi * numpy.sqrt(wavelength * undulator_length)
    sigma_r_prime = 0.69 * numpy.sqrt(wavelength / undulator_length)

    wavefront1D = GenericWavefront1D.initialize_wavefront_from_range(x_min=x_min, x_max=x_max,
                                                                     number_of_points=number_of_points)
    wavefront1D.set_wavelength(wavelength)

    if wavefront_position == 0:  # Gaussian source
        wavefront1D.set_gaussian(sigma_x=sigma_r, amplitude=1.0, shift=0.0)
    elif wavefront_position == 1:  # Spherical source, Gaussian intensity
        wavefront1D.set_spherical_wave(radius=undulator_distance, center=0.0, complex_amplitude=complex(1, 0))
        # weight with Gaussian
        X = wavefront1D.get_abscissas()
        A = wavefront1D.get_complex_amplitude()
        sigma = undulator_distance * sigma_r_prime
        sigma_amplitude = sigma * numpy.sqrt(2)
        Gx = numpy.exp(-X * X / 2 / sigma_amplitude ** 2)
        wavefront1D.set_complex_amplitude(A * Gx)

    if add_random_phase:
        wavefront1D.add_phase_shifts(2 * numpy.pi * numpy.random.random(wavefront1D.size()))

    return wavefront1D
예제 #9
0
    def propagate_wavefront(cls,
                            wavefront1,
                            propagation_distance,
                            magnification_x=1.0):

        wavefront = wavefront1.duplicate()
        shape = wavefront.size()
        delta = wavefront.delta()
        wavenumber = wavefront.get_wavenumber()
        wavelength = wavefront.get_wavelength()

        fft_scale = numpy.fft.fftfreq(shape) / delta

        x = wavefront.get_abscissas()

        x_rescaling = wavefront.get_abscissas() * magnification_x

        r1sq = x**2 * (1 - magnification_x)
        r2sq = x_rescaling**2 * ((magnification_x - 1) / magnification_x)
        fsq = (fft_scale**2 / magnification_x)

        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.fft(wavefront.get_complex_amplitude())
        ifft = numpy.fft.ifft(fft * Q2) * Q3 / numpy.sqrt(magnification_x)

        wf_propagated = GenericWavefront1D.initialize_wavefront_from_arrays(
            x_rescaling, ifft, wavelength=wavelength)

        return wf_propagated
예제 #10
0
def run_beamline_2(error_flag=0,error_file=""):

    #
    # main

    # create input_wavefront
    #
    #
    from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D
    input_wavefront = GenericWavefront1D.initialize_wavefront_from_range(x_min=-0.0002, x_max=0.0002,
                                                                         number_of_points=5000)
    input_wavefront.set_photon_energy(250)
    input_wavefront.set_gaussian(sigma_x=0.000012, amplitude=1.000000, shift=0.000000)


    output_wavefront, abscissas_on_mirror, height = calculate_output_wavefront_after_grazing_reflector1D(
        input_wavefront, shape=2, p_focus=15.0, q_focus=15.0, grazing_angle_in=0.02181661, p_distance=15.0,
        q_distance=15.0,
        zoom_factor=10, #0.3,
        error_flag=error_flag,
        error_file=error_file, write_profile=0)

    # from srxraylib.plot.gol import plot
    # plot(output_wavefront.get_abscissas(), output_wavefront.get_intensity())
    return output_wavefront
예제 #11
0
    def propagate_wavefront(cls,
                            wavefront,
                            propagation_distance,
                            magnification_x=1.0,
                            magnification_N=1.0):
        method = 0

        wavenumber = numpy.pi * 2 / wavefront.get_wavelength()

        x = wavefront.get_abscissas()

        if magnification_N != 1.0:
            npoints_exit = int(magnification_N * x.size)
        else:
            npoints_exit = x.size

        detector_abscissas = numpy.linspace(magnification_x * x[0],
                                            magnification_x * x[-1],
                                            npoints_exit)

        if method == 0:
            # calculate via loop pver detector coordinates
            x1 = wavefront.get_abscissas()
            x2 = detector_abscissas
            fieldComplexAmplitude = numpy.zeros_like(x2, dtype=complex)
            for ix, x in enumerate(x2):
                r = numpy.sqrt(
                    numpy.power(x1 - x, 2) +
                    numpy.power(propagation_distance, 2))
                distances_array = numpy.exp(1.j * wavenumber * r)
                fieldComplexAmplitude[ix] = (
                    wavefront.get_complex_amplitude() * distances_array).sum()
        elif method == 1:
            # calculate via outer product, it spreads over a lot of memory, but it is OK for 1D
            x1 = numpy.outer(wavefront.get_abscissas(),
                             numpy.ones(detector_abscissas.size))
            x2 = numpy.outer(numpy.ones(wavefront.size()), detector_abscissas)
            r = numpy.sqrt(
                numpy.power(x1 - x2, 2) + numpy.power(propagation_distance, 2))

            distances_matrix = numpy.exp(1.j * wavenumber * r)
            fieldComplexAmplitude = numpy.dot(
                wavefront.get_complex_amplitude(), distances_matrix)

        wavefront_out = GenericWavefront1D(
            wavefront.get_wavelength(),
            ScaledArray.initialize_from_steps(
                fieldComplexAmplitude, detector_abscissas[0],
                detector_abscissas[1] - detector_abscissas[0]))

        # 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()
        #                                             / magnification_x))

        wavefront_out.rescale_amplitude( (1/numpy.sqrt(1j*wavefront.get_wavelength()*propagation_distance))*(x1[1]-x1[0]) * \
                                         numpy.exp(1j * wavenumber * propagation_distance))

        return wavefront_out
예제 #12
0
def run_beamline(error_flag=1,error_file="/Users/srio/Oasys/dabam_profile_6010353992.dat"):


    # wf0 = calculate_wavefront1D(wavelength=4.9593679373280105e-09,
    #                                          wavefront_position=0,
    #                                          undulator_length=2.24,
    #                                          undulator_distance=13.73,
    #                                          x_min=-0.00025,
    #                                          x_max=0.00025,
    #                                          number_of_points=1000,
    #                                          add_random_phase=0)

    #
    # create input_wavefront
    #
    #
    from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D
    input_wavefront = GenericWavefront1D.initialize_wavefront_from_range(x_min=-0.0002, x_max=0.0002,
                                                                         number_of_points=1000)
    input_wavefront.set_photon_energy(250)
    input_wavefront.set_gaussian(sigma_x=0.000012, amplitude=1.000000, shift=0.000000)
    wf0 = input_wavefront

    # from srxraylib.plot.gol import plot
    # plot(input_wavefront.get_abscissas(), input_wavefront.get_intensity())







    #
    #
    #
    wf1 = propagate_in_vacuum(wf0)

    # plot(1e6 * wf1.get_abscissas(), wf1.get_intensity())

    #
    #
    #
    wf2, abscissas_on_mirror, height = calculate_output_wavefront_after_reflector1D(wf1,
            shape=1,radius=687.6038987249137,grazing_angle=0.02181661,
            error_flag=error_flag,
            error_file=error_file,
            error_edge_management=0,write_profile="")


    # plot(1e6 * wf2.get_abscissas(),wf2.get_intensity())


    #
    #
    #
    wf3 = propagate_in_vacuum(wf2,magnification_x=0.03,propagator_flag='i')

    return wf3
예제 #13
0
    def toGenericWavefront(self):
        wavelength = self.wise_computation_result.Lambda
        position = self.wise_computation_result.S
        electric_field = numpy.real(
            self.wise_computation_result.Field) + 1j * numpy.imag(
                self.wise_computation_result.Field)

        return GenericWavefront1D.initialize_wavefront_from_arrays(
            x_array=position, y_array=electric_field, wavelength=wavelength)
    def __init__(self, wofry_wavefront=GenericWavefront1D()):
        self.wofry_wavefront = wofry_wavefront

        wavelength = wofry_wavefront.get_wavelength()
        waist0 = fwhm(wofry_wavefront.get_abscissas(),
                      wofry_wavefront.get_intensity()) * numpy.sqrt(2) / 1.66

        print("WAIST", waist0)

        super(DummyElement, self).__init__(Lambda=wavelength, Waist0=waist0)
예제 #15
0
    def test_initializers(self, do_plot=do_plot):

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

        x = numpy.linspace(-100, 100, 50)
        y = numpy.abs(x)**1.5 + 1j * numpy.abs(x)**1.8

        wf0 = GenericWavefront1D.initialize_wavefront_from_steps(
            x[0], numpy.abs(x[1] - x[0]), y.size)
        wf0.set_complex_amplitude(y)

        wf1 = GenericWavefront1D.initialize_wavefront_from_range(
            x[0], x[-1], y.size)
        wf1.set_complex_amplitude(y)

        wf2 = GenericWavefront1D.initialize_wavefront_from_arrays(x, y)

        print("wavefront sizes: ", wf1.size(), wf1.size(), wf2.size())

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

        numpy.testing.assert_almost_equal(wf0.get_intensity(),
                                          numpy.abs(y)**2, 5)
        numpy.testing.assert_almost_equal(wf1.get_intensity(),
                                          numpy.abs(y)**2, 5)

        numpy.testing.assert_almost_equal(x, wf1.get_abscissas(), 11)
        numpy.testing.assert_almost_equal(x, wf2.get_abscissas(), 11)
예제 #16
0
    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()))
예제 #17
0
    def _back_propagation_for_size_calculation(self,theta,radiation_flux,photon_energy,
                                                distance=100.0,magnification=0.010000):
        """
        Calculate the radiation_flux vs theta at a "distance"
        Back propagate to -distance
        The result is the size distrubution

        :param theta:
        :param radiation_flux:
        :param photon_energy:
        :param distance:
        :param magnification:
        :return: None; stores results in self._photon_size_distribution
        """

        from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D
        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.propagators1D.fresnel_zoom import FresnelZoom1D
        from wofry.beamline.optical_elements.ideal_elements.screen import WOScreen1D


        input_wavefront = GenericWavefront1D().initialize_wavefront_from_arrays(theta*distance,numpy.sqrt(radiation_flux)+0j)
        input_wavefront.set_photon_energy(photon_energy)
        input_wavefront.set_spherical_wave(radius=distance,complex_amplitude=numpy.sqrt(radiation_flux)+0j)
        # input_wavefront.save_h5_file("tmp2.h5","wfr")

        optical_element = WOScreen1D()
        #
        # propagating
        #
        #
        propagation_elements = PropagationElements()
        beamline_element = BeamlineElement(optical_element=optical_element,
                        coordinates=ElementCoordinates(p=0.0,q=-distance,
                        angle_radial=numpy.radians(0.000000),
                        angle_azimuthal=numpy.radians(0.000000)))
        propagation_elements.add_beamline_element(beamline_element)
        propagation_parameters = PropagationParameters(wavefront=input_wavefront.duplicate(),propagation_elements = propagation_elements)
        propagation_parameters.set_additional_parameters('magnification_x', magnification)

        #
        propagator = PropagationManager.Instance()
        try:
            propagator.add_propagator(FresnelZoom1D())
        except:
            pass
        output_wavefront = propagator.do_propagation(propagation_parameters=propagation_parameters,handler_name='FRESNEL_ZOOM_1D')

        self._result_photon_size_distribution = {"x":output_wavefront.get_abscissas(),"y":output_wavefront.get_intensity()}
    def __init__(self, wofry_wavefront=GenericWavefront1D(), ZOrigin = 0, YOrigin = 0, Theta = 0, units_converter=1e-2):
        self.wofry_wavefront=wofry_wavefront
        self.Lambda = self.wofry_wavefront._wavelength
        self.Name = 'Wofry Wavefront @ %0.2fnm' % (self.Lambda *1e9)

        self.ZOrigin = ZOrigin
        self.YOrigin = YOrigin
        self.ThetaPropagation = Theta

        parameters, covariance_matrix_pv = WofryWavefrontSource_1d.gaussian_fit(self.wofry_wavefront.get_intensity(), self.wofry_wavefront.get_abscissas())

        self.Waist0 = parameters[3]

        self.units_converter = units_converter
예제 #19
0
def gaussian_wavefront(center, angle):
    #
    # create input_wavefront
    #
    #
    input_wavefront = GenericWavefront1D.initialize_wavefront_from_range(
        x_min=-0.0028, x_max=0.0028, number_of_points=8192)
    input_wavefront.set_photon_energy(17225)
    input_wavefront.set_spherical_wave(radius=28.3,
                                       center=center,
                                       complex_amplitude=complex(1, 0))

    #
    # apply Gaussian amplitude
    #
    input_wavefront = apply_gaussian(input_wavefront, shift=28.3 * angle)

    return input_wavefront
예제 #20
0
    def test_interpolator(self, do_plot=do_plot):
        #
        # interpolator
        #
        print("#                                                             ")
        print("# Tests for 1D interpolator                                   ")
        print("#                                                             ")

        x = numpy.linspace(-10, 10, 100)

        sigma = 3.0
        Z = numpy.exp(-1.0 * x**2 / 2 / sigma**2)

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

        wf = GenericWavefront1D.initialize_wavefront_from_steps(
            x[0], numpy.abs(x[1] - x[0]), number_of_points=100)
        print("wf shape: ", wf.size())
        wf.set_complex_amplitude(Z)

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

        print("intensity  at (%g):   %g (exact=%g)" %
              (x1, wf.get_interpolated_intensity(x1), z1**2))
        self.assertAlmostEqual(wf.get_interpolated_intensity(x1), z1**2, 4)

        if do_plot:
            from srxraylib.plot.gol import plot
            plot(wf.get_abscissas(),
                 wf.get_intensity(),
                 title="Original",
                 show=1)
            xx = wf.get_abscissas()
            yy = wf.get_interpolated_intensities(wf.get_abscissas() - 1e-5)
            plot(xx, yy, title="interpolated on same grid", show=1)
예제 #21
0
    def test_polarization(self):
        print("#                                                             ")
        print("# Tests polarization (1D)                                     ")
        print("#                                                             ")
        wavefront = GenericWavefront1D.initialize_wavefront_from_range(
            x_min=-0.5e-3,
            x_max=0.5e-3,
            number_of_points=2048,
            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,
                                             polarization=Polarization.SIGMA),
            0.0)
        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_phase(-0.1e-3,
                                             polarization=Polarization.PI),
            numpy.pi / 2)

        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_intensities(
                -0.111e-3, polarization=Polarization.TOTAL), 2.0)
        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_intensities(
                -0.111e-3, polarization=Polarization.SIGMA), 1.0)
        numpy.testing.assert_almost_equal(
            wavefront.get_interpolated_intensities(
                -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)
예제 #22
0
    def propagate_wavefront(cls, wavefront, propagation_distance):

        kernel = numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() *
                           wavefront.get_abscissas()**2 / 2 /
                           propagation_distance)
        kernel *= numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() *
                            propagation_distance)
        kernel /= 1j * wavefront.get_wavelength() * propagation_distance
        tmp = numpy.convolve(wavefront.get_complex_amplitude(),
                             kernel,
                             mode='same')

        wavefront_out = GenericWavefront1D(
            wavefront.get_wavelength(),
            ScaledArray.initialize_from_steps(tmp, wavefront.offset(),
                                              wavefront.delta()))

        # 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
예제 #23
0
    def test_gaussianhermite_mode(self, do_plot=do_plot):
        #
        # plane wave
        #
        print("#                                                             ")
        print("# Tests for a 1D Gaussian Hermite mode                        ")
        print("#                                                             ")

        wavelength = 1.24e-10

        # 2D
        sigma_x = 100e-6
        mode_x = 0
        npixels_x = 100

        wavefront_length_x = 10 * sigma_x

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

        wf1 = GenericWavefront1D.initialize_wavefront_from_steps(
            x_start=x[0],
            x_step=numpy.abs(x[1] - x[0]),
            number_of_points=npixels_x,
            wavelength=wavelength)

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

        numpy.testing.assert_almost_equal(wf1.get_amplitude()[30],
                                          23.9419082194, 5)

        if do_plot:
            from srxraylib.plot.gol import plot
            plot(wf1.get_abscissas(),
                 wf1.get_amplitude(),
                 title="Amplitude of gaussianhermite",
                 show=0)
예제 #24
0
 def test_guess_wavefront_curvature(self):
     print("#                                                             ")
     print("# Tests guessing wavefront curvature                          ")
     print("#                                                             ")
     #
     # create source
     #
     wavefront = GenericWavefront1D.initialize_wavefront_from_range(
         x_min=-0.5e-3,
         x_max=0.5e-3,
         number_of_points=2048,
         wavelength=1.5e-10)
     radius = -50.0  # 50.
     wavefront.set_spherical_wave(radius=radius)
     if do_plot:
         from srxraylib.plot.gol import plot
         radii, fig_of_mer = wavefront.scan_wavefront_curvature(rmin=-1000,
                                                                rmax=1000,
                                                                rpoints=100)
         plot(radii, fig_of_mer)
     guess_radius = wavefront.guess_wavefront_curvature(rmin=-1000,
                                                        rmax=1000,
                                                        rpoints=100)
     assert (numpy.abs(radius - guess_radius) < 1e-3)
예제 #25
0
TODO: remove this file
"""

from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D
from srxraylib.plot.gol import plot

#
# Import section
#
import numpy
from wofry.propagator.propagator import PropagationManager, PropagationElements, PropagationParameters
from syned.beamline.beamline_element import BeamlineElement
from shadow4.syned.element_coordinates import ElementCoordinates
from wofry.propagator.propagators1D.fresnel_zoom import FresnelZoom1D

input_wavefront = GenericWavefront1D()
input_wavefront = input_wavefront.load_h5_file(
    "/users/srio/OASYS1.1/minishadow/minishadow/undulator/tmp.h5", "wfr")

# input_wavefront.rescale_amplitude( 1.0/numpy.sqrt(input_wavefront.get_intensity().max()))

# input_wavefront.set_spherical_wave(radius=100,complex_amplitude=numpy.abs(input_wavefront.get_intensity()) )
# plot(input_wavefront.get_abscissas()*1e6,input_wavefront.get_intensity())

from wofry.beamline.optical_elements.ideal_elements.screen import WOScreen1D

optical_element = WOScreen1D()

#
# propagating
#
예제 #26
0
    def test_propagate_1D_fraunhofer_phase(self, do_plot=do_plot):

        # aperture_type="square"
        # aperture_diameter = 40e-6
        # wavefront_length = 800e-6
        # wavelength = 1.24e-10
        # npoints=1024
        # propagation_distance=40
        show = 1

        aperture_type = "square"
        aperture_diameter = 40e-6
        wavefront_length = 800e-6
        wavelength = 1.24e-10
        propagation_distance = 30.0
        npoints = 1024

        print(
            "\n#                                                            ")
        print(
            "# far field 1D (fraunhofer and zoom) diffraction from a %s aperture  "
            % aperture_type)
        print("#                                                            ")

        wf = GenericWavefront1D.initialize_wavefront_from_range(
            x_min=-wavefront_length / 2,
            x_max=wavefront_length / 2,
            number_of_points=npoints,
            wavelength=wavelength)

        wf.set_plane_wave_from_complex_amplitude(
            (2.0 + 1.0j))  # an arbitraty value

        propagation_elements = PropagationElements()

        if aperture_type == 'square':
            slit = WOSlit1D(boundary_shape=Rectangle(-aperture_diameter /
                                                     2, aperture_diameter /
                                                     2, 0, 0))
        else:
            raise Exception("Not implemented! ")

        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)

        wf1_franuhofer = propagator.do_propagation(propagation_parameters,
                                                   Fraunhofer1D.HANDLER_NAME)

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

        intensity_fraunhofer = wf1_franuhofer.get_intensity(
        ) / wf1_franuhofer.get_intensity().max()
        intensity_zoom = wf1_zoom.get_intensity() / wf1_zoom.get_intensity(
        ).max()

        if do_plot:
            from srxraylib.plot.gol import plot
            plot(
                wf1_franuhofer.get_abscissas() * 1e6 / propagation_distance,
                intensity_fraunhofer,
                wf1_zoom.get_abscissas() * 1e6 / propagation_distance,
                intensity_zoom,
                legend=["Fraunhofer", "Zoom"],
                legend_position=(0.95, 0.95),
                title=
                "1D  INTENSITY diffraction from aperture of %3.1f um at wavelength of %3.1f A"
                % (aperture_diameter * 1e6, wavelength * 1e10),
                xtitle="X (urad)",
                ytitle="Intensity",
                xrange=[-20, 20],
                show=show)
            plot(
                wf1_franuhofer.get_abscissas() * 1e6 / propagation_distance,
                wf1_franuhofer.get_phase(unwrap=1),
                wf1_zoom.get_abscissas() * 1e6 / propagation_distance,
                wf1_zoom.get_phase(unwrap=1),
                legend=["Fraunhofer", "Zoom"],
                legend_position=(0.95, 0.95),
                title=
                "1D  diffraction from a %s aperture of %3.1f um at wavelength of %3.1f A"
                % (aperture_type, aperture_diameter * 1e6, wavelength * 1e10),
                xtitle="X (urad)",
                ytitle="Intensity",
                xrange=[-20, 20],
                show=show)
예제 #27
0
    def propagate_1D(
        self,
        do_plot=do_plot,
        method='fft',
        wavelength=1.24e-10,
        aperture_type='square',
        aperture_diameter=40e-6,
        wavefront_length=100e-6,
        npoints=500,
        propagation_distance=30.0,
        normalization=True,  # TODO put False
        show=1,
        amplitude=(0.0 + 1.0j)):

        print(
            "\n#                                                            ")
        print("# 1D (%s) propagation from a %s aperture  " %
              (method, aperture_type))
        print("#                                                            ")

        wf = GenericWavefront1D.initialize_wavefront_from_range(
            x_min=-wavefront_length / 2,
            x_max=wavefront_length / 2,
            number_of_points=npoints,
            wavelength=wavelength)

        wf.set_plane_wave_from_complex_amplitude(
            amplitude)  # an arbitraty value

        deltax = wf.get_abscissas()[1] - wf.get_abscissas()[0]

        propagation_elements = PropagationElements()

        slit = None

        if aperture_type == 'square':
            slit = WOSlit1D(boundary_shape=Rectangle(-aperture_diameter /
                                                     2, aperture_diameter /
                                                     2, 0, 0))
        elif aperture_type == 'gaussian':
            slit = WOGaussianSlit1D(
                boundary_shape=Rectangle(-aperture_diameter /
                                         2, aperture_diameter / 2, 0, 0))
        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)

        print("Using propagator method:  ", method)
        fresnel_analytical = True
        if method == 'fft':
            wf1 = propagator.do_propagation(propagation_parameters,
                                            Fresnel1D.HANDLER_NAME)
        elif method == 'convolution':
            wf1 = propagator.do_propagation(propagation_parameters,
                                            FresnelConvolution1D.HANDLER_NAME)
        elif method == 'integral':
            propagation_parameters.set_additional_parameters(
                "magnification_x", 1.5)
            propagation_parameters.set_additional_parameters(
                "magnification_N", 2.0)
            wf1 = propagator.do_propagation(propagation_parameters,
                                            Integral1D.HANDLER_NAME)
        elif method == 'fraunhofer':
            fresnel_analytical = False
            # propagation_parameters.set_additional_parameters("shift_half_pixel", 0)
            wf1 = propagator.do_propagation(propagation_parameters,
                                            Fraunhofer1D.HANDLER_NAME)
        elif method == 'zoom':
            propagation_parameters.set_additional_parameters(
                "magnification_x", 1.5)
            wf1 = propagator.do_propagation(propagation_parameters,
                                            FresnelZoom1D.HANDLER_NAME)
        else:
            raise Exception("Not implemented method: %s" % method)

        if fresnel_analytical:
            xx, alpha = fresnel_analytical_rectangle(
                fresnel_number=None,
                propagation_distance=propagation_distance,
                aperture_half=0.5 * aperture_diameter,
                wavelength=wavelength,
                detector_array=wf1.get_abscissas(),
                npoints=None)
        else:
            xx, alpha = fraunhofer_analytical_rectangle(
                fresnel_number=None,
                propagation_distance=propagation_distance,
                aperture_half=0.5 * aperture_diameter,
                wavelength=wavelength,
                detector_array=wf1.get_abscissas(),
                npoints=None)

        angle_x = xx / propagation_distance
        intensity_theory = numpy.abs(amplitude * alpha)**2

        intensity_calculated = wf1.get_intensity()

        if normalization:
            intensity_calculated /= intensity_calculated.max()
            intensity_theory /= intensity_theory.max()

        if do_plot:
            from srxraylib.plot.gol import plot
            plot(
                wf1.get_abscissas() * 1e6 / propagation_distance,
                intensity_calculated,
                angle_x * 1e6,
                intensity_theory,
                legend=["%s " % method, "analytical"],
                legend_position=(0.95, 0.95),
                title=
                "1D (%s) diffraction from a %s aperture of %3.1f um at \n wavelength of %3.1f A"
                % (method, aperture_type, aperture_diameter * 1e6,
                   wavelength * 1e10),
                xtitle="X (urad)",
                ytitle="Intensity",
                xrange=[-20, 20],
                ylog=True,
                show=show)

            plot(
                wf1.get_abscissas() * 1e6,
                wf1.get_phase(unwrap=True),
                1e6 * xx,
                numpy.unwrap(numpy.angle(alpha)),
                legend=["%s " % method, "analytical"],
                title=
                "1D (%s) diffraction from a %s aperture of %3.1f um at \n wavelength of %3.1f A NOT ASSERTED!!"
                % (method, aperture_type, aperture_diameter * 1e6,
                   wavelength * 1e10),
                xtitle="X (urad)",
                ytitle="Phase",
                # xrange=[-20, 20],
            )

        return wf1.get_abscissas(
        ) / propagation_distance, intensity_calculated, intensity_theory
예제 #28
0
    def propagate_wavefront_new(
            cls,
            wavefront,
            propagation_distance,
            fraunhofer_kernel=True,  # set to False for far field propagator
            shift_half_pixel=None,  # not more used, kept for version compatibility
    ):
        #
        # check validity
        #
        x = wavefront.get_abscissas()
        deltax = wavefront.delta()

        #
        # compute Fourier transform
        #

        # frequency for axis 1
        npixels = wavefront.size()
        pixelsize = wavefront.delta()
        wavenumber = wavefront.get_wavenumber()
        wavelength = wavefront.get_wavelength()

        freq_nyquist = 0.5 / pixelsize
        if numpy.mod(npixels, 2) == 0:
            freq_n = numpy.arange(-npixels // 2, npixels // 2,
                                  1) / (npixels // 2)
        else:
            freq_n = numpy.arange(-(npixels - 1) // 2,
                                  (npixels + 1) // 2, 1) / ((npixels - 1) // 2)

        freq_x = freq_n * freq_nyquist

        x2 = freq_x * propagation_distance * wavelength

        P1 = numpy.exp(1.0j * wavenumber * propagation_distance)

        # fsq = freq_x ** 2
        # P2 = numpy.exp(-1.0j * wavenumber / 2 / propagation_distance * fsq)

        P2 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * x**2)
        P3 = 1.0j * wavelength * propagation_distance

        if fraunhofer_kernel:
            exponential = 1.0 + 0j
        else:
            exponential = numpy.exp(1j * wavenumber / 2 /
                                    propagation_distance * x**2)

        F1 = numpy.fft.fft(exponential * wavefront.get_complex_amplitude()
                           )  # Take the fourier transform of the image.
        #  Now shift the quadrants around so that low spatial frequencies are in
        # the center of the 2D fourier transformed image.
        F1 *= P1
        F1 *= P2
        F1 /= numpy.sqrt(P3)  # this is 1D -> no sqrt for 2D
        F2 = numpy.fft.fftshift(F1)
        F2 *= deltax  # why??

        wavefront_out = GenericWavefront1D.initialize_wavefront_from_arrays(
            x_array=x2, y_array=F2, 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
예제 #29
0
    def propagate_wavefront(cls,
                            wavefront1,
                            propagation_distance1,
                            magnification_x=1.0,
                            radius=1e6):
        wavefront = wavefront1.duplicate()
        shape = wavefront.size()
        delta = wavefront.delta()
        wavenumber = wavefront.get_wavenumber()
        wavelength = wavefront.get_wavelength()

        # radius = -50.0
        magnification = (propagation_distance1 + radius) / radius
        propagation_distance = propagation_distance1 / magnification

        #
        # make plane wave by adding a spherical wavefront with radius -R
        #
        new_phase = 1.0 * wavefront.get_wavenumber() * (
            wavefront.get_abscissas()**2) / (-2 * radius)
        wavefront.add_phase_shifts(new_phase)

        #
        # main 2 FFT block
        #
        fft_scale = numpy.fft.fftfreq(shape) / delta

        x = wavefront.get_abscissas()

        x_rescaling = wavefront.get_abscissas() * magnification_x

        r1sq = x**2 * (1 - magnification_x)
        r2sq = x_rescaling**2 * ((magnification_x - 1) / magnification_x)
        fsq = (fft_scale**2 / magnification_x)

        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.fft(wavefront.get_complex_amplitude())
        ifft = numpy.fft.ifft(fft * Q2) * Q3 / numpy.sqrt(magnification_x)
        #
        #
        #

        #
        # calculate new phase term and scale coordinates
        #
        k = wavefront.get_wavenumber()

        PHASE1 = numpy.ones(
            wavefront.get_abscissas().size) * (k * propagation_distance *
                                               (1 - 1 / magnification))
        PHASE2 = k / 2 / propagation_distance * (
            magnification - 1) / magnification * (wavefront.get_abscissas() *
                                                  magnification)**2
        PHASE = PHASE2 + PHASE1

        wf_propagated = GenericWavefront1D.initialize_wavefront_from_arrays(
            x_rescaling * magnification,
            ifft / numpy.sqrt(magnification) * numpy.exp(1j * PHASE),
            wavelength=wavelength)

        return wf_propagated
예제 #30
0
    def test_plane_wave(self, do_plot=do_plot):
        #
        # plane wave
        #
        print("#                                                             ")
        print("# Tests for a 1D plane wave                                   ")
        print("#                                                             ")

        wavelength = 1.24e-10

        wavefront_length_x = 400e-6

        npixels_x = 1024

        wavefront_x = numpy.linspace(-0.5 * wavefront_length_x,
                                     0.5 * wavefront_length_x, npixels_x)

        wavefront = GenericWavefront1D.initialize_wavefront_from_steps(
            x_start=wavefront_x[0],
            x_step=numpy.abs(wavefront_x[1] - wavefront_x[0]),
            number_of_points=npixels_x,
            wavelength=wavelength)

        numpy.testing.assert_almost_equal(wavefront_x,
                                          wavefront.get_abscissas(), 9)

        # 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)
        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
            plot(wavefront.get_abscissas(),
                 wavefront.get_intensity(),
                 title="Intensity (plane wave)",
                 show=0)
            plot(wavefront.get_abscissas(),
                 wavefront.get_phase(),
                 title="Phase (plane wave)",
                 show=1)