Exemplo n.º 1
0
    def undulator(self, method, npixels_x, npixels_y, pixelsize_x, pixelsize_y,
                  wavelength, sigma, m, m_x, m_y, propagation_distance, radius,
                  show, image_source, apply_lens):

        wavefront = Wavefront2D.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)

        wavefront.set_spherical_wave(radius=radius)

        if image_source == False:

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

            wavefront.rescale_amplitude(
                numpy.exp(-(X**2 + Y**2) / (2 * sigma**2))
            )  # applichiamo intensita' con profilo gaussiano

        print("Input intensity: ", wavefront.get_intensity().sum())

        if apply_lens == True:
            wavefront.apply_ideal_lens(focal_length_x=propagation_distance,
                                       focal_length_y=propagation_distance)

            print("Intensity after lens: ", wavefront.get_intensity().sum())

        if method == 'fft':
            output_wf = propagate_2D_fresnel(
                wavefront, propagation_distance=propagation_distance)
        elif method == 'rescaling':
            output_wf = propagator2d_fourier_rescaling(
                wavefront, propagation_distance=propagation_distance, m=m)
        elif method == 'rescaling_xy':
            output_wf = propagator2d_fourier_rescaling_xy(
                wavefront,
                propagation_distance=propagation_distance,
                m_x=m_x,
                m_y=m_y)

        plot_undulator(output_wf, method=method, show=show)

        horizontal_profile_wf = line_image(wavefront.get_intensity(),
                                           horizontal_or_vertical='H')

        vertical_profile_wf = line_image(wavefront.get_intensity(),
                                         horizontal_or_vertical='V')

        horizontal_phase_profile_wf = line_image(wavefront.get_phase(),
                                                 horizontal_or_vertical='H')

        if image_source == True:
            return wavefront.get_coordinate_x(
            ), horizontal_profile_wf, horizontal_phase_profile_wf
Exemplo n.º 2
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 = Wavefront2D.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 = Wavefront2D.initialize_wavefront_from_range(x[0],x[-1],y[0],y[-1],number_of_points=Z.shape)
        wf1.set_complex_amplitude(Z)

        wf2 = Wavefront2D.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)
Exemplo n.º 3
0
    def propagate_2D_fresnel(self,
                             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,
                             m=1,
                             m_x=1,
                             m_y=1,
                             show=0):

        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 = Wavefront2D.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))

        if aperture_type == 'circle':
            wf.apply_pinhole(aperture_diameter / 2)
        elif aperture_type == 'square':
            wf.apply_slit(-aperture_diameter / 2, aperture_diameter / 2,
                          -aperture_diameter / 2, aperture_diameter / 2)
        else:
            raise Exception("Not implemented! (accepted: circle, square)")

        if method == 'fft':
            wf1 = propagate_2D_fresnel(wf, propagation_distance)
        elif method == 'rescaling':
            wf1 = propagator2d_fourier_rescaling(wf, propagation_distance, m=m)
        elif method == 'rescaling_xy':
            wf1 = propagator2d_fourier_rescaling_xy(wf,
                                                    propagation_distance,
                                                    m_x=m_x,
                                                    m_y=m_y)
        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 = wf.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.60, 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)

        if method == 'rescaling_xy' and do_plot:
            angle_y = wf.get_coordinate_y() / propagation_distance
            intensity_calculated_v = wf1.get_intensity()[int(wf1.size()[1] /
                                                             2), :]
            intensity_calculated_v /= intensity_calculated_v.max()

            from srxraylib.plot.gol import plot
            plot(
                wf1.get_coordinate_y() * 1e6 / propagation_distance,
                intensity_calculated_v,
                angle_y * 1e6,
                intensity_theory,
                legend=[
                    "%s V profile" % method_label, "Theoretical (far field)"
                ],
                legend_position=(0.60, 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="Y (urad)",
                ytitle="Intensity",
                xrange=[-20, 20],
                show=show)

        return wf1.get_coordinate_x(
        ) / propagation_distance, intensity_calculated, angle_x, intensity_theory
def main(beamline,pixels=100):

    npixels_x = pixels
    npixels_y = npixels_x


    pixelsize_x = beamline['gapH'] / npixels_x
    pixelsize_y = beamline['gapV'] / npixels_y

    print("pixelsize X=%f,Y=%f: "%(pixelsize_x,pixelsize_y))

    propagation_distance = beamline['distance']

    #
    # initialize wavefronts of dimension equal to the lens
    #
    wf_fft = Wavefront2D.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=1e-10)


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


    # photon_wavelength = (1 + beamline['Kv']**2 / 2.0) / 2 / gamma**2 * beamline["PeriodID"] / beamline['harmonicID']

    photon_wavelength = m2ev / beamline["photonEnergy"]


    print ("Photon wavelength [A]: %g \n"%(1e10*photon_wavelength))
    print ("Photon energy [eV]: %g \n"%(beamline["photonEnergy"]))


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


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

    source = SourceUndulatorPlane(undulator=myUndulator,
                        electron_beam=myBeam, magnetic_field=None)


    omega = beamline["photonEnergy"] * 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)
    #print('step 2')

    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]


    wf_fft.set_photon_energy(beamline["photonEnergy"])

    wf_fft.set_complex_amplitude( tmp )

    # plot

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

    # apply lens

    focal_length = propagation_distance / 2

    wf_fft.apply_ideal_lens(focal_length,focal_length)



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

    wf_fft, x_fft, y_fft = propagation_to_image(wf_fft,do_plot=0,method='fft',
                            propagation_steps=1,
                            propagation_distance = propagation_distance, defocus_factor=1.0)


    plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
               title="Intensity at image plane",xtitle="X um",ytitle="Y um",show=1)

    if do_plot:
        plot_table(1e6*x_fft,y_fft,ytitle="Intensity",xtitle="x coordinate [um]",
                   title="Comparison 1:1 focusing ")
Exemplo n.º 5
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 = 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 = Wavefront2D.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))

        if aperture_type == 'circle':
            wf.apply_pinhole(aperture_diameter/2)
        elif aperture_type == 'square':
            wf.apply_slit(-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)")



        wf1 = propagate_2D_fraunhofer(wf, propagation_distance=1.0) # propagating at 1 m means the result is like in angles

        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()[:,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)
Exemplo n.º 6
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 = Wavefront2D.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)

        spherical_or_plane_and_lens = 0
        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)
        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
            wf.apply_ideal_lens(focal_length,focal_length)

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

        # propagation downstream the lens to image plane
        for i in range(propagation_steps):
            if propagation_steps > 1:
                print(">>> Propagating step %d of %d; propagation_distance=%g m"%(i+1,propagation_steps,
                                                    propagation_distance*defocus_factor/propagation_steps))
            if method == 'fft':
                wf = propagate_2D_fresnel(wf, propagation_distance*defocus_factor/propagation_steps)
            elif method == 'convolution':
                wf = propagate_2D_fresnel_convolution(wf, propagation_distance*defocus_factor/propagation_steps)
            elif method == 'srw':
                wf = propagate_2D_fresnel_srw(wf, propagation_distance*defocus_factor/propagation_steps)
            elif method == 'fraunhofer':
                wf = propagate_2D_fraunhofer(wf, propagation_distance*defocus_factor/propagation_steps)
            else:
                raise Exception("Not implemented method: %s"%method)




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

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

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

        print("Output intensity: ",wf.get_intensity().sum())
        return wf.get_coordinate_x(),horizontal_profile
Exemplo n.º 7
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):


        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 = Wavefront2D.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))

        if aperture_type == 'circle':
            wf.apply_pinhole(aperture_diameter/2)
        elif aperture_type == 'square':
            wf.apply_slit(-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 method == 'fft':
            wf1 = propagate_2D_fresnel(wf, propagation_distance)
        elif method == 'convolution':
            wf1 = propagate_2D_fresnel_convolution(wf, propagation_distance)
        elif method == 'srw':
            wf1 = propagate_2D_fresnel_srw(wf, propagation_distance)
        elif method == 'integral':
            wf1 = propagate_2D_integral(wf, propagation_distance)
        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()[:,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
Exemplo n.º 8
0
def propagate_2D_fresnel_srw(wavefront,
                             propagation_distance,
                             srw_autosetting=0):
    """
    2D Fresnel propagator using convolution via Fourier transform
    :param wavefront:
    :param propagation_distance:
    :param srw_autosetting:set to 1 for automatic SRW redimensionate wavefront
    :return:
    """

    #
    # convolving with the Fresnel kernel via SRW package
    #

    from srxraylib.waveoptics.NumpyToSRW import numpyArrayToSRWArray, SRWWavefrontFromElectricField, SRWEFieldAsNumpy

    import scipy.constants as codata
    angstroms_to_eV = codata.h * codata.c / codata.e * 1e10

    srw_wfr = SRWWavefrontFromElectricField(
        wavefront.get_coordinate_x()[0],
        wavefront.get_coordinate_x()[-1], wavefront.get_complex_amplitude(),
        wavefront.get_coordinate_y()[0],
        wavefront.get_coordinate_y()[-1],
        numpy.zeros_like(wavefront.get_complex_amplitude()),
        angstroms_to_eV / (wavefront.get_wavelength() * 1e10), 1.0, 1.0, 1e-3,
        1.0, 1e-3)
    #
    # propagation
    #
    optDrift = srwlib.SRWLOptD(propagation_distance)  #Drift space

    #Wavefront Propagation Parameters:
    #[0]: Auto-Resize (1) or not (0) Before propagation
    #[1]: Auto-Resize (1) or not (0) After propagation
    #[2]: Relative Precision for propagation with Auto-Resizing (1. is nominal)
    #[3]: Allow (1) or not (0) for semi-analytical treatment of the quadratic (leading) phase terms at the propagation
    #[4]: Do any Resizing on Fourier side, using FFT, (1) or not (0)
    #[5]: Horizontal Range modification factor at Resizing (1. means no modification)
    #[6]: Horizontal Resolution modification factor at Resizing
    #[7]: Vertical Range modification factor at Resizing
    #[8]: Vertical Resolution modification factor at Resizing
    #[9]: Type of wavefront Shift before Resizing (not yet implemented)
    #[10]: New Horizontal wavefront Center position after Shift (not yet implemented)
    #[11]: New Vertical wavefront Center position after Shift (not yet implemented)

    if srw_autosetting:
        #                 0  1  2   3  4  5   6   7   8   9 10 11
        propagParDrift = [1, 1, 1., 0, 0, 1., 1., 1., 1., 0, 0, 0]
    else:
        #                 0  1  2   3  4  5   6   7   8   9 10 11
        propagParDrift = [0, 0, 1., 0, 0, 1., 1., 1., 1., 0, 0, 0]

    optBL = srwlib.SRWLOptC(
        [optDrift], [propagParDrift]
    )  #"Beamline" - Container of Optical Elements (together with the corresponding wavefront propagation instructions)

    print('   Simulating Electric Field Wavefront Propagation by SRW ... ',
          end='\n')
    srwlib.srwl.PropagElecField(srw_wfr, optBL)

    wavefront2 = Wavefront2D.initialize_wavefront_from_range(
        srw_wfr.mesh.xStart,
        srw_wfr.mesh.xFin,
        srw_wfr.mesh.yStart,
        srw_wfr.mesh.yFin,
        number_of_points=(srw_wfr.mesh.nx, srw_wfr.mesh.ny),
        wavelength=wavefront.get_wavelength())
    amplitude2 = SRWEFieldAsNumpy(srw_wfr)
    amplitude2 = amplitude2[0, :, :, 0]
    wavefront2.set_complex_amplitude(amplitude2)

    return wavefront2
Exemplo n.º 9
0
    def test_polarization(self, do_plot=0):

        print("#                                                             ")
        print("# Tests polarization                                      ")
        print("#                                                             ")

        #
        # from steps
        #

        x = numpy.linspace(-10, 10, 100)
        y = numpy.linspace(-20, 20, 50)
        # XY = numpy.meshgrid(y,x)
        # sigma = 3.0
        # Z = numpy.exp(- (XY[0]**2+XY[1]**2)/2/sigma**2)

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

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

        wf = Wavefront2D.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())
        wf.set_complex_amplitude(Z, polarization=Polarization.SIGMA)
        wf.set_complex_amplitude(Zp, polarization=Polarization.PI)
        print("Total intensity: ",
              wf.get_intensity(polarization=Polarization.TOTAL).sum())
        print("Sigma intensity: ",
              wf.get_intensity(polarization=Polarization.SIGMA).sum())
        print("Pi intensity: ",
              wf.get_intensity(polarization=Polarization.PI).sum())

        self.assertAlmostEqual(wf.get_intensity(polarization=Polarization.TOTAL).sum(),
                            wf.get_intensity(polarization=Polarization.SIGMA).sum() +\
                            wf.get_intensity(polarization=Polarization.PI).sum())

        #
        # from range
        #

        x = numpy.linspace(-100, 100, 50)
        y = numpy.linspace(-50, 50, 200)
        X = numpy.outer(x, numpy.ones_like(y))
        Y = numpy.outer(numpy.ones_like(x), y)
        sigma = 10
        Z = numpy.exp(-(X**2 + Y**2) / 2 / sigma**2) * 1j
        Zp = 0.3333 * numpy.exp(-(X**2 + Y**2) / 2 / sigma**2) * 1j
        print("Shapes x,y,z: ", x.shape, y.shape, Z.shape)

        wf1 = Wavefront2D.initialize_wavefront_from_range(
            x[0],
            x[-1],
            y[0],
            y[-1],
            number_of_points=Z.shape,
            polarization=Polarization.SIGMA)
        wf1.set_complex_amplitude(Z, polarization=Polarization.SIGMA)
        wf1.set_complex_amplitude(Zp, polarization=Polarization.PI)

        print("Total intensity: ",
              wf1.get_intensity(polarization=Polarization.TOTAL).sum())
        print("Sigma intensity: ",
              wf1.get_intensity(polarization=Polarization.SIGMA).sum())
        print("Pi intensity: ",
              wf1.get_intensity(polarization=Polarization.PI).sum())

        self.assertAlmostEqual(wf1.get_intensity(polarization=Polarization.TOTAL).sum(),
                            wf1.get_intensity(polarization=Polarization.SIGMA).sum() +\
                            wf1.get_intensity(polarization=Polarization.PI).sum())

        #
        # from arrays
        #
        wf2 = Wavefront2D.initialize_wavefront_from_arrays(x, y, Z, Zp)

        self.assertAlmostEqual(wf2.get_intensity(polarization=Polarization.TOTAL).sum(),
                            wf2.get_intensity(polarization=Polarization.SIGMA).sum() +\
                            wf2.get_intensity(polarization=Polarization.PI).sum())
Exemplo n.º 10
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 = Wavefront2D.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)

        spherical_or_plane_and_lens = 0
        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)
        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
            wf.apply_ideal_lens(focal_length, focal_length)

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

        # propagation downstream the lens to image plane
        for i in range(propagation_steps):
            if propagation_steps > 1:
                print(
                    ">>> Propagating step %d of %d; propagation_distance=%g m"
                    % (i + 1, propagation_steps, propagation_distance *
                       defocus_factor / propagation_steps))
            if method == 'fft':
                wf = propagate_2D_fresnel(
                    wf,
                    propagation_distance * defocus_factor / propagation_steps)
            elif method == 'convolution':
                wf = propagate_2D_fresnel_convolution(
                    wf,
                    propagation_distance * defocus_factor / propagation_steps)
            elif method == 'srw':
                wf = propagate_2D_fresnel_srw(
                    wf,
                    propagation_distance * defocus_factor / propagation_steps)
            elif method == 'fraunhofer':
                wf = propagate_2D_fraunhofer(
                    wf,
                    propagation_distance * defocus_factor / propagation_steps)
            else:
                raise Exception("Not implemented method: %s" % method)

        horizontal_profile = wf.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) * wf.delta()[0]))
        vertical_profile = wf.get_intensity()[int(wf.size()[0] / 2), :]
        vertical_profile /= vertical_profile.max()
        print("FWHM of the vertical profile: %g um" %
              (1e6 * line_fwhm(vertical_profile) * wf.delta()[1]))

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

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

        print("Output intensity: ", wf.get_intensity().sum())
        return wf.get_coordinate_x(), horizontal_profile
Exemplo n.º 11
0
    pixelsize_y = 1e-7
    npixels_x = 2024
    npixels_y = 2024
    propagation_distance = 1.0
    show = 1

    method_label = "fresnel (fft)"
    print("\n#                                                             ")
    print("# 2D near field fresnel (%s) diffraction from a a circular stop  " %
          (method_label))
    print("#                                                             ")

    wf = Wavefront2D.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))

    wf.apply_pinhole(aperture_diameter / 2, negative=True)

    wf1 = propagate_2D_fresnel(wf, propagation_distance)

    plot_image(wf.get_intensity(),
               1e6 * wf.get_coordinate_x(),
               1e6 * wf.get_coordinate_y(),
               title="intensity at screen/aperture plane, Diameter=%5.1f um" %
               (1e6 * aperture_diameter),
Exemplo n.º 12
0
def main(mode_wavefront_before_lens):

    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

    #
    # initialize wavefronts of dimension equal to the lens
    #
    wf_fft = Wavefront2D.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_convolution = Wavefront2D.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)
    if SRWLIB_AVAILABLE:
        wf_srw = Wavefront2D.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)

    #
    # calculate/define wavefront at zero distance downstream the lens
    #
    if mode_wavefront_before_lens == 'convergent spherical':
        # no need to propagate nor define lens
        wf_fft.set_spherical_wave(complex_amplitude=1.0,radius=-propagation_distance)
        wf_convolution.set_spherical_wave(complex_amplitude=1.0,radius=-propagation_distance)
        if SRWLIB_AVAILABLE: wf_srw.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.

        wf_fft.set_spherical_wave(complex_amplitude=1.0,radius=propagation_distance)
        wf_fft.apply_ideal_lens(focal_length,focal_length)

        wf_convolution.set_spherical_wave(complex_amplitude=1.0,radius=propagation_distance)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)

        if SRWLIB_AVAILABLE:
            wf_srw.set_spherical_wave(complex_amplitude=1.0,radius=propagation_distance)
            wf_srw.apply_ideal_lens(focal_length,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

        wf_fft.set_plane_wave_from_complex_amplitude(1.0+0j)
        wf_fft.apply_ideal_lens(focal_length,focal_length)

        wf_convolution.set_plane_wave_from_complex_amplitude(1.0+0j)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)

        if SRWLIB_AVAILABLE:
            wf_srw.set_plane_wave_from_complex_amplitude(1.0+0j)
            wf_srw.apply_ideal_lens(focal_length,focal_length)

    elif mode_wavefront_before_lens == 'Gaussian with lens':
        # define wavefront at source point, propagate to the lens and apply lens
        X = wf_fft.get_mesh_x()
        Y = wf_fft.get_mesh_y()

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


        wf_fft.set_complex_amplitude( numpy.sqrt(intensity) )
        wf_convolution.set_complex_amplitude( numpy.sqrt(intensity) )
        if SRWLIB_AVAILABLE: wf_srw.set_complex_amplitude( numpy.sqrt(intensity) )

        # plot

        plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
                   xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um (%d pixels)"%(wf_fft.size()[1]),title="Gaussian source",show=1)

        wf_fft, tmp1, tmp2 = propagation_to_image(wf_fft,method='fft',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        wf_convolution, tmp1, tmp2 = propagation_to_image(wf_convolution,method='convolution',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        if SRWLIB_AVAILABLE:
            wf_srw, tmp1, tmp2 = propagation_to_image(wf_srw,method='srw',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")


        plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
                   xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um",title="Before lens fft",show=1)

        plot_image(wf_convolution.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
                   xtitle="X um (%d pixels)"%(wf_convolution.size()[0]),ytitle="Y um",title="Before lens convolution",show=1)

        focal_length = propagation_distance / 2

        wf_fft.apply_ideal_lens(focal_length,focal_length)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)
        if SRWLIB_AVAILABLE: wf_srw.apply_ideal_lens(focal_length,focal_length)

    elif mode_wavefront_before_lens == 'Hermite with lens':
        # define wavefront at source point, propagate to the lens and apply lens
        X = wf_fft.get_mesh_x()
        Y = wf_fft.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

        wf_fft.set_complex_amplitude( efield )
        wf_convolution.set_complex_amplitude( efield )
        if SRWLIB_AVAILABLE: wf_srw.set_complex_amplitude( efield )

        # plot

        plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
                   xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um (%d pixels)"%(wf_fft.size()[0]),title="Hermite-Gauss source",show=1)

        wf_fft, tmp1, tmp2 = propagation_to_image(wf_fft,method='fft',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        wf_convolution, tmp1, tmp2 = propagation_to_image(wf_convolution,method='convolution',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        if SRWLIB_AVAILABLE:
            wf_srw, tmp1, tmp2 = propagation_to_image(wf_srw,method='srw',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")


        plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
                   xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um (%d pixels)"%(wf_fft.size()[0]),title="Before lens fft",show=1)

        plot_image(wf_convolution.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
                   xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um (%d pixels)"%(wf_fft.size()[0]),title="Before lens convolution",show=1)

        focal_length = propagation_distance / 2

        wf_fft.apply_ideal_lens(focal_length,focal_length)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)
        if SRWLIB_AVAILABLE: wf_srw.apply_ideal_lens(focal_length,focal_length)

    elif mode_wavefront_before_lens == 'Undulator with lens':

        beamline = {}
        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

        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'])


        XX = wf_fft.get_mesh_x()
        YY = wf_fft.get_mesh_y()
        X = wf_fft.get_coordinate_x()
        Y = wf_fft.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)
        #print('step 2')

        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]


        wf_fft.set_photon_energy(resonance_energy)
        wf_convolution.set_photon_energy(resonance_energy)
        if SRWLIB_AVAILABLE: wf_srw.set_photon_energy(resonance_energy)

        wf_fft.set_complex_amplitude( tmp )
        wf_convolution.set_complex_amplitude( numpy.sqrt(tmp) )
        if SRWLIB_AVAILABLE: wf_srw.set_complex_amplitude( numpy.sqrt(tmp) )

        # plot

        plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
                   xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um (%d pixels)"%(wf_fft.size()[0]),title="UND source at lens plane",show=1)

        # apply lens

        focal_length = propagation_distance / 2

        wf_fft.apply_ideal_lens(focal_length,focal_length)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)
        if SRWLIB_AVAILABLE: wf_srw.apply_ideal_lens(focal_length,focal_length)

    else:
        raise Exception("Unknown mode")


    plot_image(wf_fft.get_phase(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
               title="Phase just after the lens",xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um (%d pixels)"%(wf_fft.size()[0]),show=1)

    wf_fft, x_fft, y_fft = propagation_to_image(wf_fft,do_plot=0,method='fft',
                            propagation_steps=propagation_steps,
                            propagation_distance = propagation_distance, defocus_factor=defocus_factor)

    wf_convolution, x_convolution, y_convolution = propagation_to_image(wf_convolution,do_plot=0,method='convolution',
                            propagation_steps=propagation_steps,
                            propagation_distance = propagation_distance, defocus_factor=defocus_factor)
    if SRWLIB_AVAILABLE:
        wf_srw, x_srw, y_srw = propagation_to_image(wf_srw,do_plot=0,method='srw',
                                propagation_steps=propagation_steps,
                                propagation_distance = propagation_distance, defocus_factor=defocus_factor)

    plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
               title="Intensity at image plane",xtitle="X um (%d pixels)"%(wf_fft.size()[0]),ytitle="Y um (%d pixels)"%(wf_fft.size()[0]),show=1)

    if do_plot:
        if SRWLIB_AVAILABLE:
            x = x_fft
            y = numpy.vstack((y_fft,y_srw,y_convolution))

            plot_table(1e6*x,y,legend=["fft","srw","convolution"],ytitle="Intensity",xtitle="x coordinate [um]",
                       title="Comparison 1:1 focusing "+mode_wavefront_before_lens)
        else:
            x = x_fft
            y = numpy.vstack((y_fft,y_convolution))

            plot_table(1e6*x,y,legend=["fft","convolution"],ytitle="Intensity",xtitle="x coordinate [um]",
                       title="Comparison 1:1 focusing "+mode_wavefront_before_lens)
Exemplo n.º 13
0
def propagate_2D(calculation_parameters, input_parameters):
    shadow_oe = calculation_parameters.shadow_oe_end

    if calculation_parameters.do_ff_z and calculation_parameters.do_ff_x:
        global_phase_shift_profile = None

        if shadow_oe._oe.F_MOVE == 1 and shadow_oe._oe.X_ROT != 0.0:
            if input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
                global_phase_shift_profile = calculation_parameters.w_mirr_2D_values
            elif input_parameters.ghy_calcType == 2:
                global_phase_shift_profile = ScaledMatrix.initialize_from_range(numpy.zeros((3, 3)),
                                                                                shadow_oe._oe.RWIDX2, shadow_oe._oe.RWIDX1,
                                                                                shadow_oe._oe.RLEN2,  shadow_oe._oe.RLEN1)

            for x_index in range(global_phase_shift_profile.size_x()):
                global_phase_shift_profile.z_values[x_index, :] += global_phase_shift_profile.get_y_values()*numpy.sin(numpy.radians(-shadow_oe._oe.X_ROT))
        elif input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
            global_phase_shift_profile = calculation_parameters.w_mirr_2D_values

        # only tangential slopes
        if input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
            rms_slope = hy_findrmsslopefromheight(ScaledArray(np_array=global_phase_shift_profile.z_values[int(global_phase_shift_profile.size_x()/2), :],
                                                              scale=global_phase_shift_profile.get_y_values()))

            print("Using RMS slope = " + str(rms_slope))

        # ------------------------------------------
        # far field calculation
        # ------------------------------------------
        focallength_ff = calculate_focal_length_ff_2D(calculation_parameters.ghy_x_min,
                                                      calculation_parameters.ghy_x_max,
                                                      calculation_parameters.ghy_z_min,
                                                      calculation_parameters.ghy_z_max,
                                                      input_parameters.ghy_npeak,
                                                      calculation_parameters.gwavelength)

        if (input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4) and rms_slope != 0:
            focallength_ff = min(focallength_ff,(calculation_parameters.ghy_z_max-calculation_parameters.ghy_z_min) / 16 / rms_slope ) #xshi changed
        elif input_parameters.ghy_calcType == 2 and not global_phase_shift_profile is None:
            focallength_ff = min(focallength_ff, input_parameters.ghy_distance*4) #TODO: PATCH to be found with a formula

        print("FF: calculated focal length: " + str(focallength_ff))

        fftsize_x = int(calculate_fft_size(calculation_parameters.ghy_x_min,
                                           calculation_parameters.ghy_x_max,
                                           calculation_parameters.gwavelength,
                                           focallength_ff,
                                           input_parameters.ghy_fftnpts,
                                           factor=20))

        fftsize_z = int(calculate_fft_size(calculation_parameters.ghy_z_min,
                                        calculation_parameters.ghy_z_max,
                                        calculation_parameters.gwavelength,
                                        focallength_ff,
                                        input_parameters.ghy_fftnpts,
                                        factor=20))

        print("FF: creating plane wave begin, fftsize_x = " +  str(fftsize_x) + ", fftsize_z = " +  str(fftsize_z))

        wavefront = Wavefront2D.initialize_wavefront_from_range(wavelength=calculation_parameters.gwavelength,
                                                                number_of_points=(fftsize_x, fftsize_z),
                                                                x_min=calculation_parameters.ghy_x_min,
                                                                x_max=calculation_parameters.ghy_x_max,
                                                                y_min=calculation_parameters.ghy_z_min,
                                                                y_max=calculation_parameters.ghy_z_max)

        try:
            for i in range(0, len(wavefront.electric_field_array.x_coord)):
                for j in range(0, len(wavefront.electric_field_array.y_coord)):
                    interpolated = calculation_parameters.wIray_2d.interpolate_value(wavefront.electric_field_array.x_coord[i],
                                                                                     wavefront.electric_field_array.y_coord[j])
                    wavefront.electric_field_array.set_z_value(i, j, numpy.sqrt(0.0 if interpolated < 0 else interpolated))
        except IndexError:
            raise Exception("Unexpected Error during interpolation: try reduce Number of bins for I(Tangential) histogram")

        wavefront.apply_ideal_lens(focallength_ff, focallength_ff)

        shadow_oe = calculation_parameters.shadow_oe_end

        if input_parameters.ghy_calcType == 3 or \
                (input_parameters.ghy_calcType == 2 and not global_phase_shift_profile is None):
            print("FF: calculating phase shift due to Height Error Profile")

            phase_shifts = numpy.zeros(wavefront.size())

            for index in range(0, phase_shifts.shape[0]):
                np_array = numpy.zeros(global_phase_shift_profile.shape()[1])
                for j in range(0, len(np_array)):
                    np_array[j] = global_phase_shift_profile.interpolate_value(wavefront.get_coordinate_x()[index], calculation_parameters.w_mirr_2D_values.get_y_value(j))

                global_phase_shift_profile_z = ScaledArray.initialize_from_steps(np_array,
                                                                                 global_phase_shift_profile.y_coord[0],
                                                                                 global_phase_shift_profile.y_coord[1] - global_phase_shift_profile.y_coord[0])

                phase_shifts[index, :] = get_mirror_phase_shift(wavefront.get_coordinate_y(),
                                                                calculation_parameters.gwavelength,
                                                                calculation_parameters.wangle_z,
                                                                calculation_parameters.wl_z,
                                                                global_phase_shift_profile_z)
            wavefront.add_phase_shifts(phase_shifts)
        elif input_parameters.ghy_calcType == 4:
            print("FF: calculating phase shift due to Height Error Profile")

            phase_shifts = numpy.zeros(wavefront.size())

            for index in range(0, phase_shifts.shape[0]):
                global_phase_shift_profile_z = ScaledArray.initialize_from_steps(global_phase_shift_profile.z_values[index, :],
                                                                                 global_phase_shift_profile.y_coord[0],
                                                                                 global_phase_shift_profile.y_coord[1] - global_phase_shift_profile.y_coord[0])

                phase_shifts[index, :] = get_grating_phase_shift(wavefront.get_coordinate_y(),
                                                                 calculation_parameters.gwavelength,
                                                                 calculation_parameters.wangle_z,
                                                                 calculation_parameters.wangle_ref_z,
                                                                 calculation_parameters.wl_z,
                                                                 global_phase_shift_profile_z)
            wavefront.add_phase_shifts(phase_shifts)
        elif input_parameters.ghy_calcType == 6:
            for w_mirr_2D_values in calculation_parameters.w_mirr_2D_values:
                phase_shift = get_crl_phase_shift(w_mirr_2D_values,
                                                  input_parameters,
                                                  calculation_parameters,
                                                  [wavefront.get_coordinate_x(), wavefront.get_coordinate_y()])

                wavefront.add_phase_shift(phase_shift)

        print("calculated plane wave: begin FF propagation (distance = " +  str(focallength_ff) + ")")

        propagated_wavefront = propagator2D.propagate_2D_fresnel(wavefront, focallength_ff)

        print("dif_zp: begin calculation")

        imagesize_x = min(abs(calculation_parameters.ghy_x_max), abs(calculation_parameters.ghy_x_min)) * 2
        imagesize_x = min(imagesize_x,
                          input_parameters.ghy_npeak*2*0.88*calculation_parameters.gwavelength*focallength_ff/abs(calculation_parameters.ghy_x_max-calculation_parameters.ghy_x_min))

        # TODO: this is a patch: to be rewritten
        if shadow_oe._oe.F_MOVE==1 and not shadow_oe._oe.Y_ROT==0:
            imagesize_x = max(imagesize_x, 8*(focallength_ff*numpy.tan(numpy.radians(numpy.abs(shadow_oe._oe.Y_ROT))) + numpy.abs(shadow_oe._oe.OFFX)))

        delta_x = propagated_wavefront.delta()[0]
        imagenpts_x = int(round(imagesize_x/delta_x/2) * 2 + 1)

        imagesize_z = min(abs(calculation_parameters.ghy_z_max), abs(calculation_parameters.ghy_z_min)) * 2
        imagesize_z = min(imagesize_z,
                          input_parameters.ghy_npeak*2*0.88*calculation_parameters.gwavelength*focallength_ff/abs(calculation_parameters.ghy_z_max-calculation_parameters.ghy_z_min))

        # TODO: this is a patch: to be rewritten
        if shadow_oe._oe.F_MOVE==1 and not shadow_oe._oe.X_ROT==0:
            imagesize_z = max(imagesize_z, 8*(focallength_ff*numpy.tan(numpy.radians(numpy.abs(shadow_oe._oe.X_ROT))) + numpy.abs(shadow_oe._oe.OFFZ)))

        delta_z = propagated_wavefront.delta()[1]
        imagenpts_z = int(round(imagesize_z/delta_z/2) * 2 + 1)

        dif_xpzp = ScaledMatrix.initialize_from_range(numpy.ones((imagenpts_x, imagenpts_z)),
                                                      min_scale_value_x = -(imagenpts_x - 1) / 2 * delta_x,
                                                      max_scale_value_x =(imagenpts_x - 1) / 2 * delta_x,
                                                      min_scale_value_y = -(imagenpts_z - 1) / 2 * delta_z,
                                                      max_scale_value_y =(imagenpts_z - 1) / 2 * delta_z)

        for i in range(0, dif_xpzp.shape()[0]):
            for j in range(0, dif_xpzp.shape()[1]):
                dif_xpzp.set_z_value(i, j, numpy.absolute(propagated_wavefront.get_interpolated_complex_amplitude(
                                                               dif_xpzp.x_coord[i],
                                                               dif_xpzp.y_coord[j]))**2
                                                           )

        dif_xpzp.set_scale_from_range(0,
                                      -(imagenpts_x - 1) / 2 * delta_x / focallength_ff,
                                      (imagenpts_x - 1) / 2 * delta_x / focallength_ff)

        dif_xpzp.set_scale_from_range(1,
                                      -(imagenpts_z - 1) / 2 * delta_z / focallength_ff,
                                      (imagenpts_z - 1) / 2 * delta_z / focallength_ff)

        calculation_parameters.dif_xpzp = dif_xpzp
Exemplo n.º 14
0
def main(mode_wavefront_before_lens):

    lens_diameter = 0.002 # 0.001 # 0.002

    if mode_wavefront_before_lens == 'Undulator with lens':
        npixels_x = 512
    else:
        npixels_x = 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

    #
    # initialize wavefronts of dimension equal to the lens
    #
    wf_fft = Wavefront2D.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_convolution = Wavefront2D.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)
    if SRWLIB_AVAILABLE:
        wf_srw = Wavefront2D.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)

    #
    # calculate/define wavefront at zero distance downstream the lens
    #
    if mode_wavefront_before_lens == 'convergent spherical':
        # no need to propagate nor define lens
        wf_fft.set_spherical_wave(complex_amplitude=1.0,radius=-propagation_distance)
        wf_convolution.set_spherical_wave(complex_amplitude=1.0,radius=-propagation_distance)
        if SRWLIB_AVAILABLE: wf_srw.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.

        wf_fft.set_spherical_wave(complex_amplitude=1.0,radius=propagation_distance)
        wf_fft.apply_ideal_lens(focal_length,focal_length)

        wf_convolution.set_spherical_wave(complex_amplitude=1.0,radius=propagation_distance)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)

        if SRWLIB_AVAILABLE:
            wf_srw.set_spherical_wave(complex_amplitude=1.0,radius=propagation_distance)
            wf_srw.apply_ideal_lens(focal_length,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

        wf_fft.set_plane_wave_from_complex_amplitude(1.0+0j)
        wf_fft.apply_ideal_lens(focal_length,focal_length)

        wf_convolution.set_plane_wave_from_complex_amplitude(1.0+0j)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)

        if SRWLIB_AVAILABLE:
            wf_srw.set_plane_wave_from_complex_amplitude(1.0+0j)
            wf_srw.apply_ideal_lens(focal_length,focal_length)

    elif mode_wavefront_before_lens == 'Gaussian with lens':
        # define wavefront at source point, propagate to the lens and apply lens
        X = wf_fft.get_mesh_x()
        Y = wf_fft.get_mesh_y()

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


        wf_fft.set_complex_amplitude( numpy.sqrt(intensity) )
        wf_convolution.set_complex_amplitude( numpy.sqrt(intensity) )
        if SRWLIB_AVAILABLE: wf_srw.set_complex_amplitude( numpy.sqrt(intensity) )

        # plot

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

        wf_fft, tmp1, tmp2 = propagation_to_image(wf_fft,method='fft',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        wf_convolution, tmp1, tmp2 = propagation_to_image(wf_convolution,method='convolution',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        if SRWLIB_AVAILABLE:
            wf_srw, tmp1, tmp2 = propagation_to_image(wf_srw,method='srw',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")


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

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

        focal_length = propagation_distance / 2

        wf_fft.apply_ideal_lens(focal_length,focal_length)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)
        if SRWLIB_AVAILABLE: wf_srw.apply_ideal_lens(focal_length,focal_length)

    elif mode_wavefront_before_lens == 'Hermite with lens':
        # define wavefront at source point, propagate to the lens and apply lens
        X = wf_fft.get_mesh_x()
        Y = wf_fft.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

        wf_fft.set_complex_amplitude( efield )
        wf_convolution.set_complex_amplitude( efield )
        if SRWLIB_AVAILABLE: wf_srw.set_complex_amplitude( efield )

        # plot

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

        wf_fft, tmp1, tmp2 = propagation_to_image(wf_fft,method='fft',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        wf_convolution, tmp1, tmp2 = propagation_to_image(wf_convolution,method='convolution',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")
        if SRWLIB_AVAILABLE:
            wf_srw, tmp1, tmp2 = propagation_to_image(wf_srw,method='srw',propagation_distance=propagation_distance,
                                              do_plot=0,plot_title="Before lens")


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

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

        focal_length = propagation_distance / 2

        wf_fft.apply_ideal_lens(focal_length,focal_length)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)
        if SRWLIB_AVAILABLE: wf_srw.apply_ideal_lens(focal_length,focal_length)

    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'])


        XX = wf_fft.get_mesh_x()
        YY = wf_fft.get_mesh_y()
        X = wf_fft.get_coordinate_x()
        Y = wf_fft.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)
        #print('step 2')

        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]


        wf_fft.set_photon_energy(resonance_energy)
        wf_convolution.set_photon_energy(resonance_energy)
        if SRWLIB_AVAILABLE: wf_srw.set_photon_energy(resonance_energy)

        wf_fft.set_complex_amplitude( tmp )
        wf_convolution.set_complex_amplitude( numpy.sqrt(tmp) )
        if SRWLIB_AVAILABLE: wf_srw.set_complex_amplitude( numpy.sqrt(tmp) )

        # plot

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

        # apply lens

        focal_length = propagation_distance / 2

        wf_fft.apply_ideal_lens(focal_length,focal_length)
        wf_convolution.apply_ideal_lens(focal_length,focal_length)
        if SRWLIB_AVAILABLE: wf_srw.apply_ideal_lens(focal_length,focal_length)

    else:
        raise Exception("Unknown mode")


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

    wf_fft, x_fft, y_fft = propagation_to_image(wf_fft,do_plot=0,method='fft',
                            propagation_steps=propagation_steps,
                            propagation_distance = propagation_distance, defocus_factor=defocus_factor)

    wf_convolution, x_convolution, y_convolution = propagation_to_image(wf_convolution,do_plot=0,method='convolution',
                            propagation_steps=propagation_steps,
                            propagation_distance = propagation_distance, defocus_factor=defocus_factor)
    if SRWLIB_AVAILABLE:
        wf_srw, x_srw, y_srw = propagation_to_image(wf_srw,do_plot=0,method='srw',
                                propagation_steps=propagation_steps,
                                propagation_distance = propagation_distance, defocus_factor=defocus_factor)

    plot_image(wf_fft.get_intensity(),1e6*wf_fft.get_coordinate_x(),1e6*wf_fft.get_coordinate_y(),
               title="Intensity at image plane",xtitle="X um",ytitle="Y um",show=1)

    if do_plot:
        if SRWLIB_AVAILABLE:
            x = x_fft
            y = numpy.vstack((y_fft,y_srw,y_convolution))

            plot_table(1e6*x,y,legend=["fft","srw","convolution"],ytitle="Intensity",xtitle="x coordinate [um]",
                       title="Comparison 1:1 focusing "+mode_wavefront_before_lens)
        else:
            x = x_fft
            y = numpy.vstack((y_fft,y_convolution))

            plot_table(1e6*x,y,legend=["fft","convolution"],ytitle="Intensity",xtitle="x coordinate [um]",
                       title="Comparison 1:1 focusing "+mode_wavefront_before_lens)
Exemplo n.º 15
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 = 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 = Wavefront2D.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))

        if aperture_type == 'circle':
            wf.apply_pinhole(aperture_diameter / 2)
        elif aperture_type == 'square':
            wf.apply_slit(-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)")

        wf1 = propagate_2D_fraunhofer(
            wf, propagation_distance=1.0
        )  # propagating at 1 m means the result is like in angles

        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)
Exemplo n.º 16
0
def propagate_2D_fresnel_srw(wavefront, propagation_distance,
                             srw_autosetting=0):
    """
    2D Fresnel propagator using convolution via Fourier transform
    :param wavefront:
    :param propagation_distance:
    :param srw_autosetting:set to 1 for automatic SRW redimensionate wavefront
    :return:
    """

    #
    # convolving with the Fresnel kernel via SRW package
    #


    from srxraylib.waveoptics.NumpyToSRW import numpyArrayToSRWArray, SRWWavefrontFromElectricField, SRWEFieldAsNumpy

    import scipy.constants as codata
    angstroms_to_eV = codata.h*codata.c/codata.e*1e10


    srw_wfr = SRWWavefrontFromElectricField(
                    wavefront.get_coordinate_x()[0],wavefront.get_coordinate_x()[-1],wavefront.get_complex_amplitude(),
                    wavefront.get_coordinate_y()[0],wavefront.get_coordinate_y()[-1],numpy.zeros_like(wavefront.get_complex_amplitude()),
                    angstroms_to_eV/(wavefront.get_wavelength()*1e10), 1.0, 1.0, 1e-3, 1.0, 1e-3)
    #
    # propagation
    #
    optDrift = srwlib.SRWLOptD(propagation_distance) #Drift space


    #Wavefront Propagation Parameters:
    #[0]: Auto-Resize (1) or not (0) Before propagation
    #[1]: Auto-Resize (1) or not (0) After propagation
    #[2]: Relative Precision for propagation with Auto-Resizing (1. is nominal)
    #[3]: Allow (1) or not (0) for semi-analytical treatment of the quadratic (leading) phase terms at the propagation
    #[4]: Do any Resizing on Fourier side, using FFT, (1) or not (0)
    #[5]: Horizontal Range modification factor at Resizing (1. means no modification)
    #[6]: Horizontal Resolution modification factor at Resizing
    #[7]: Vertical Range modification factor at Resizing
    #[8]: Vertical Resolution modification factor at Resizing
    #[9]: Type of wavefront Shift before Resizing (not yet implemented)
    #[10]: New Horizontal wavefront Center position after Shift (not yet implemented)
    #[11]: New Vertical wavefront Center position after Shift (not yet implemented)

    if srw_autosetting:
        #                 0  1  2   3  4  5   6   7   8   9 10 11
        propagParDrift = [1, 1, 1., 0, 0, 1., 1., 1., 1., 0, 0, 0]
    else:
        #                 0  1  2   3  4  5   6   7   8   9 10 11
        propagParDrift = [0, 0, 1., 0, 0, 1., 1., 1., 1., 0, 0, 0]

    optBL = srwlib.SRWLOptC([optDrift], [propagParDrift]) #"Beamline" - Container of Optical Elements (together with the corresponding wavefront propagation instructions)

    print('   Simulating Electric Field Wavefront Propagation by SRW ... ', end='\n')
    srwlib.srwl.PropagElecField(srw_wfr, optBL)



    wavefront2 = Wavefront2D.initialize_wavefront_from_range(srw_wfr.mesh.xStart, srw_wfr.mesh.xFin,
                                                             srw_wfr.mesh.yStart, srw_wfr.mesh.yFin,
                                                             number_of_points=(srw_wfr.mesh.nx,srw_wfr.mesh.ny),
                                                             wavelength=wavefront.get_wavelength())
    amplitude2 = SRWEFieldAsNumpy(srw_wfr)
    amplitude2 = amplitude2[0,:,:,0]
    wavefront2.set_complex_amplitude(amplitude2)

    return wavefront2
Exemplo n.º 17
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 = Wavefront2D.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 = Wavefront2D.initialize_wavefront_from_range(
            x[0], x[-1], y[0], y[-1], number_of_points=Z.shape)
        wf1.set_complex_amplitude(Z)

        wf2 = Wavefront2D.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)