Esempio n. 1
0
    def test_create_radiation_undulator(self):
        undulator_test = Undulator(K=1.87,
                                   period_length=0.035,
                                   length=0.035 * 14)
        electron_beam_test = ElectronBeam(Electron_energy=1.3, I_current=1.0)
        source_test = SourceUndulatorPlane(undulator=undulator_test,
                                           electron_beam=electron_beam_test)
        traj_fact = TrajectoryFactory(Nb_pts=1001,
                                      method=TRAJECTORY_METHOD_ANALYTIC)
        traj = traj_fact.create_from_source(source_test)

        rad_fact = RadiationFactory(
            photon_frequency=source_test.harmonic_frequency(1),
            method=RADIATION_METHOD_NEAR_FIELD)

        rad = rad_fact.create_for_one_relativistic_electron(trajectory=traj,
                                                            source=source_test)
        self.assertFalse(rad.X is None)
        self.assertFalse(rad.Y is None)
        self.assertFalse(rad.distance is None)

        rad_fact.method = RADIATION_METHOD_APPROX_FARFIELD

        rad2 = rad_fact.create_for_one_relativistic_electron(
            trajectory=traj, source=source_test)
        self.assertTrue(rad2.distance == None)

        rad2 = rad_fact.create_for_one_relativistic_electron(
            trajectory=traj, source=source_test, distance=rad.distance)
        self.assertFalse(rad.distance == None)
        err = rad.difference_with(rad2)

        self.assertTrue(rad.XY_are_similar_to(rad2))
        self.assertTrue(rad.XY_are_similar_to(err))
        self.assertTrue(rad.distance == rad2.distance)
        self.assertTrue(err.distance == rad2.distance)
        self.assertGreaterEqual(err.intensity.min(), 0.0)
        self.assertLessEqual(err.max(),
                             rad.max() * 1e-1)  # srio changed 1e-3 by 1e-1

        traj_test2 = TrajectoryFactory(
            Nb_pts=1001,
            method=TRAJECTORY_METHOD_ODE,
            initial_condition=traj_fact.initial_condition).create_from_source(
                source_test)

        rad3 = rad_fact.create_for_one_relativistic_electron(
            trajectory=traj_test2, source=source_test, distance=rad.distance)
        err = rad2.difference_with(rad3)
        self.assertLessEqual(err.max(), rad2.max() * 1e-3)
    def test_create_radiation_undulator(self):
        undulator_test = Undulator(K=1.87, period_length=0.035, length=0.035 * 14)
        electron_beam_test = ElectronBeam(Electron_energy=1.3, I_current=1.0)
        source_test=SourceUndulatorPlane(undulator=undulator_test, electron_beam=electron_beam_test)
        traj_fact=TrajectoryFactory(Nb_pts=1001, method=TRAJECTORY_METHOD_ANALYTIC)
        traj=traj_fact.create_from_source(source_test)

        rad_fact = RadiationFactory(photon_frequency=source_test.harmonic_frequency(1), method=RADIATION_METHOD_NEAR_FIELD)

        rad=rad_fact.create_for_one_relativistic_electron(trajectory=traj, source=source_test)
        self.assertFalse(rad.X is None)
        self.assertFalse(rad.Y is None)
        self.assertFalse(rad.distance is None)





        rad_fact.method=RADIATION_METHOD_APPROX_FARFIELD

        rad2=rad_fact.create_for_one_relativistic_electron(trajectory=traj, source=source_test)
        self.assertTrue(rad2.distance == None)


        rad2=rad_fact.create_for_one_relativistic_electron(trajectory=traj, source=source_test,distance=rad.distance)
        self.assertFalse(rad.distance == None)
        err=rad.difference_with(rad2)

        self.assertTrue(rad.XY_are_similar_to(rad2))
        self.assertTrue(rad.XY_are_similar_to(err))
        self.assertTrue(rad.distance == rad2.distance)
        self.assertTrue(err.distance == rad2.distance)
        self.assertGreaterEqual(err.intensity.min(),0.0)
        self.assertLessEqual(err.max(), rad.max()*1e-1) # srio changed 1e-3 by 1e-1


        traj_test2=TrajectoryFactory(Nb_pts=1001, method=TRAJECTORY_METHOD_ODE,
                                     initial_condition=traj_fact.initial_condition).create_from_source(source_test)

        rad3=rad_fact.create_for_one_relativistic_electron(trajectory=traj_test2,source=source_test,distance=rad.distance)
        err = rad2.difference_with(rad3)
        self.assertLessEqual(err.max(),rad2.max()*1e-3)
Esempio n. 3
0
def create_simulation(magnetic_structure,
                      electron_beam,
                      magnetic_field=None,
                      photon_energy=None,
                      traj_method=TRAJECTORY_METHOD_ANALYTIC,
                      Nb_pts_trajectory=None,
                      rad_method=RADIATION_METHOD_APPROX_FARFIELD,
                      Nb_pts_radiation=101,
                      initial_condition=None,
                      distance=None,
                      XY_are_list=False,
                      X=None,
                      Y=None):

    if type(magnetic_structure) == Undulator:
        source = SourceUndulatorPlane(undulator=magnetic_structure,
                                      electron_beam=electron_beam,
                                      magnetic_field=magnetic_field)
        print("Calculating undulator source...")
    elif type(magnetic_structure) == BM:
        source = SourceBendingMagnet(magnetic_structure=magnetic_structure,
                                     electron_beam=electron_beam,
                                     magnetic_field=magnetic_field)
        print("Calculating bending magnet source...")
    else:
        raise Exception('magnet type unknown')

    if photon_energy == None:
        omega = source.choose_photon_frequency()
    else:
        omega = photon_energy * eV_to_J / codata.hbar

    #
    # XY grid
    #
    if distance == None and (rad_method == RADIATION_METHOD_NEAR_FIELD):
        distance = source.choose_distance_automatic(2)

    if Nb_pts_trajectory == None:
        Nb_pts_trajectory = int(
            source.choose_nb_pts_trajectory(0.01, photon_frequency=omega))

    if X is None or Y is None:
        if (X != None):
            Y = X
        elif Y != None:
            X = Y
        else:
            theta_max = source.choose_angle_deflection_max()
            if distance == None:
                X_max = theta_max
                Y_max = theta_max
            else:
                X_max = distance * theta_max
                Y_max = distance * theta_max
            X = np.linspace(0.0, X_max, Nb_pts_radiation)
            Y = np.linspace(0.0, Y_max, Nb_pts_radiation)

    if type(X) == float:
        X = np.linspace(0.0, X, Nb_pts_radiation)
    if type(Y) == float:
        Y = np.linspace(0.0, Y, Nb_pts_radiation)

    # if X.shape != Y.shape :
    #     raise Exception('X and Y must have the same shape')
    Nb_pts_radiation = X.size  # len(X.flatten())

    #print('step 1')
    traj_fact = TrajectoryFactory(Nb_pts=Nb_pts_trajectory,
                                  method=traj_method,
                                  initial_condition=initial_condition)

    if (traj_fact.initial_condition == None):
        # print('crearte initial cond automat')
        traj_fact.initial_condition = source.choose_initial_contidion_automatic(
        )

    #print('step 2')

    rad_fact = RadiationFactory(method=rad_method, 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=XY_are_list,
        distance=distance,
        X=X,
        Y=Y)

    #print('step 5')
    return Simulation(source=source,
                      trajectory_fact=traj_fact,
                      radiation_fact=rad_fact,
                      trajectory=trajectory,
                      radiation=radiation)
Esempio n. 4
0
def create_simulation(magnetic_structure,electron_beam, magnetic_field=None, photon_energy=None,
                      traj_method=TRAJECTORY_METHOD_ANALYTIC,Nb_pts_trajectory=None,
                      rad_method=RADIATION_METHOD_APPROX_FARFIELD, Nb_pts_radiation=101,
                      initial_condition=None, distance=None,XY_are_list=False,X=None,Y=None) :

    if type(magnetic_structure)==Undulator :
        source=SourceUndulatorPlane(undulator=magnetic_structure,
                                    electron_beam=electron_beam, magnetic_field=magnetic_field)
        print("Calculating undulator source...")
    elif type(magnetic_structure)==BM:
        source = SourceBendingMagnet(magnetic_structure=magnetic_structure,
                                      electron_beam=electron_beam, magnetic_field=magnetic_field)
        print("Calculating bending magnet source...")
    else :
        raise Exception('magnet type unknown')

    if photon_energy==None :
        omega=source.choose_photon_frequency()
    else :
        omega = photon_energy * eV_to_J / codata.hbar

    #
    # XY grid
    #
    if distance==None and (rad_method==RADIATION_METHOD_NEAR_FIELD) :
        distance=source.choose_distance_automatic(2)

    if Nb_pts_trajectory==None :
        Nb_pts_trajectory = int(source.choose_nb_pts_trajectory(0.01,photon_frequency=omega))

    if X is None or Y is None :
        if (X != None) :
            Y=X
        elif Y != None :
            X=Y
        else :
            theta_max=source.choose_angle_deflection_max()
            if distance==None :
                X_max=theta_max
                Y_max=theta_max
            else :
                X_max = distance * theta_max
                Y_max = distance * theta_max
            X = np.linspace(0.0, X_max, Nb_pts_radiation)
            Y = np.linspace(0.0, Y_max, Nb_pts_radiation)

    if type(X) == float:
        X= np.linspace(0.0, X, Nb_pts_radiation)
    if type(Y) == float:
        Y = np.linspace(0.0, Y, Nb_pts_radiation)

    # if X.shape != Y.shape :
    #     raise Exception('X and Y must have the same shape')
    Nb_pts_radiation = X.size # len(X.flatten())

    #print('step 1')
    traj_fact=TrajectoryFactory(Nb_pts=Nb_pts_trajectory,method=traj_method,initial_condition=initial_condition)

    if (traj_fact.initial_condition == None):
        # print('crearte initial cond automat')
        traj_fact.initial_condition = source.choose_initial_contidion_automatic()



    #print('step 2')

    rad_fact=RadiationFactory(method=rad_method, 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=XY_are_list,
                                                              distance=distance, X=X, Y=Y)

    #print('step 5')
    return Simulation(source=source, trajectory_fact=traj_fact,
                               radiation_fact=rad_fact, trajectory=trajectory, radiation=radiation)
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 ")
Esempio n. 6
0
def main(mode_wavefront_before_lens):

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

    lens_diameter = 0.002  # 0.001 # 0.002

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

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

    pixelsize_y = pixelsize_x
    npixels_y = npixels_x

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

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

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

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

        focal_length = propagation_distance / 2.

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

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

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

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

        wf2.set_plane_wave_from_complex_amplitude(1.0 + 0j)

        wf3 = apply_lens(wf2, focal_length)

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

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

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

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

        wf1.set_complex_amplitude(numpy.sqrt(intensity))

        # plot

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

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

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

        focal_length = propagation_distance / 2

        wf3 = apply_lens(wf2, focal_length)

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

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

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

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

        wf1.set_complex_amplitude(efield)

        # plot

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

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

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

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

    elif mode_wavefront_before_lens == 'Undulator with lens':

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

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

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

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

        # red shift 100 eV
        resonance_energy = resonance_energy - 100

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # plot

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

        # apply lens

        focal_length = propagation_distance / 2

        wf3 = apply_lens(wf2, focal_length=focal_length)

    else:
        raise Exception("Unknown mode")

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

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

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

    plot(1e4 * x4,
         h4,
         xtitle='x [um]',
         ytitle='intensity',
         title='horizontal profile',
         show=True)
Esempio n. 7
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)
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)