Ejemplo n.º 1
0
    def create_magn_field_undulator_test(self, magnetic_structure, electron_beam,method_traj):


        sim_test = create_simulation(magnetic_structure=magnetic_structure,electron_beam=electron_beam,
                                     traj_method=method_traj,rad_method=RADIATION_METHOD_APPROX_FARFIELD)
        print('create')
        source_test=sim_test.source
        Zo=sim_test.trajectory_fact.initial_condition[5]
        Bo=source_test.magnetic_field_strength()
        lambda_u=source_test.magnetic_structure.period_length

        self.assertTrue(Zo<0.)
        Zo_analitic=source_test.magnetic_structure.length*0.5
        Z_test = np.linspace(-Zo_analitic, Zo_analitic, sim_test.trajectory_fact.Nb_pts)
        diff_mf = np.abs(source_test.magnetic_field.By(z=Z_test, y=0.0, x=0.0) -
                         Bo * np.cos((2.0 * np.pi / lambda_u) * Z_test))
        self.assertTrue(all(diff_mf < np.abs(Bo) * 1e-3))

        print('integration 1')
        int1 = integrate.quad((lambda z: source_test.magnetic_field.By(z=z, y=0.0, x=0.0)),Zo,-Zo
                              ,limit=int(source_test.choose_nb_pts_trajectory(2)))
        self.assertAlmostEqual(int1[0], 0.0, 2)
        print('integration 2')#TODO marche pas donne tjr zeros meme qd c'est faux
        int2 = integrate.quad((lambda z: z*source_test.magnetic_field.By(z=z, y=0.0, x=0.0)),Zo,-Zo
                              ,limit=int(source_test.choose_nb_pts_trajectory(2)))
        print(int2[0])
        self.assertAlmostEqual(int2[0], 0.0)
Ejemplo n.º 2
0
    def simul_undulator_traj_method(self, magnetic_struc, electron_beam,
                                    method_rad):

        sim_test = create_simulation(magnetic_structure=magnetic_struc,
                                     electron_beam=electron_beam,
                                     rad_method=method_rad,
                                     distance=100)
        sim_test.calculate_on_central_cone()

        ref = sim_test.copy()
        rad_max = (sim_test.radiation.max())

        sim_test.change_trajectory_method(TRAJECTORY_METHOD_ODE)
        rad_err = ref.radiation.error_max(sim_test.radiation)
        traj_err = ref.trajectory.error_max(sim_test.trajectory)
        self.assertLessEqual(
            np.abs(sim_test.radiation.max() - rad_max) / rad_max, 5e-2, 4)
        self.assertLessEqual(traj_err[1] / ref.trajectory.x.max(), 5e-3)
        self.assertLessEqual(traj_err[3] / ref.trajectory.z.max(), 5e-3)
        self.assertLessEqual(traj_err[4] / ref.trajectory.v_x.max(), 5e-3)
        self.assertLessEqual(traj_err[6] / ref.trajectory.v_z.max(), 5e-3)
        self.assertLessEqual(traj_err[7] / ref.trajectory.a_x.max(), 5e-3)
        self.assertLessEqual(traj_err[9] / ref.trajectory.a_z.max(), 5e-3)
        self.assertLessEqual(
            np.abs(sim_test.radiation.max() - rad_max) / rad_max, 5e-2)
        self.assertLessEqual(rad_err / rad_max, 5e-2)
Ejemplo n.º 3
0
    def simul_undulator_theoric(self, magnetic_struc, electron_beam, method_rad, method_traj):

        sim_test = create_simulation(magnetic_structure=magnetic_struc, electron_beam=electron_beam,
                                     rad_method=method_rad, traj_method=method_traj,distance=100)
        rad_axis=sim_test.radiation.intensity[0,0]
        rad_theo=sim_test.source.theoretical_flux_on_axis(1)#sim_test.radiation_fact.omega)

        print("rad axis %e , theo %e" % (rad_axis, rad_theo))
Ejemplo n.º 4
0
    def test_simulation(self):
        electron_beam_test = ElectronBeam(Electron_energy=1.3, I_current=1.0)
        beam_ESRF = ElectronBeam(Electron_energy=6.0, I_current=0.2)
        undulator_test = Undulator(K=1.87, period_length=0.035, length=0.035 * 14)
        ESRF18 = Undulator(K=1.68, period_length=0.018, length=2.0)

        sim_test = create_simulation(magnetic_structure=undulator_test,electron_beam=electron_beam_test,
                                     traj_method=TRAJECTORY_METHOD_ANALYTIC,rad_method=RADIATION_METHOD_NEAR_FIELD)
        self.assertFalse(sim_test.radiation.distance == None)
        source_test=sim_test.source

        self.assertFalse(all(sim_test.trajectory_fact.initial_condition==
                             source_test.choose_initial_contidion_automatic()))
        ref=sim_test.copy()
        rad_max = sim_test.radiation.max()

        # test change
        sim_test.change_radiation_method(RADIATION_METHOD_APPROX_FARFIELD)
        self.assertEqual(sim_test.radiation_fact.method, RADIATION_METHOD_APPROX_FARFIELD)
        self.assertFalse(ref.radiation_fact.method==sim_test.radiation_fact.method)
        self.assertFalse(np.all(ref.radiation.intensity == sim_test.radiation.intensity))
        self.assertAlmostEqual(ref.radiation.intensity[0][0]/rad_max, sim_test.radiation.intensity[0][0]/rad_max, 3)

        sim_test.change_trajectory_method(TRAJECTORY_METHOD_ODE)
        self.assertEqual(sim_test.trajectory_fact.method, TRAJECTORY_METHOD_ODE)
        self.assertFalse(ref.trajectory_fact.method==sim_test.trajectory_fact.method)
        time_diff=np.abs(ref.trajectory.t - sim_test.trajectory.t)
        self.assertTrue(np.all(time_diff<=1e-19))
        self.assertFalse(np.all(ref.trajectory.x == sim_test.trajectory.x))
        self.assertFalse(np.all(ref.radiation.intensity == sim_test.radiation.intensity))
        rad_max = sim_test.radiation.max()
        self.assertAlmostEqual(ref.radiation.intensity[0][0]/rad_max, sim_test.radiation.intensity[0][0]/rad_max, 1)

        sim_test.change_Nb_pts_trajectory(ref.trajectory_fact.Nb_pts+1)
        self.assertEqual(sim_test.trajectory_fact.Nb_pts,ref.trajectory_fact.Nb_pts+1)
        self.assertEqual(sim_test.trajectory.nb_points(), ref.trajectory_fact.Nb_pts+1)
        self.assertFalse(ref.trajectory_fact.Nb_pts == sim_test.trajectory_fact.Nb_pts)
        self.assertAlmostEqual(ref.radiation.intensity[0][0]/rad_max,sim_test.radiation.intensity[0][0]/rad_max,1)

        sim_test.change_Nb_pts_radiation(100)
        self.assertEqual(sim_test.radiation_fact.Nb_pts,100)
        self.assertFalse(np.all(ref.radiation.X == sim_test.radiation.X))
        self.assertTrue(ref.radiation.X.min() == sim_test.radiation.X.min())
        self.assertTrue(ref.radiation.X.max() == sim_test.radiation.X.max())
        self.assertTrue(ref.radiation.Y.min() == sim_test.radiation.Y.min())
        self.assertTrue(ref.radiation.Y.max() == sim_test.radiation.Y.max())
        self.assertFalse(len(ref.radiation.X) == len(sim_test.radiation.X))

        sim_test.change_distance(50)
        self.assertEqual(sim_test.radiation.distance,50)
        self.assertFalse(ref.radiation.distance == sim_test.radiation.distance)

        sim_test.change_photon_frequency(source_test.harmonic_frequency(1) * 0.8)
        self.assertEqual(sim_test.radiation_fact.photon_frequency,source_test.harmonic_frequency(1)*0.8)
        self.assertFalse(ref.radiation_fact.photon_frequency == sim_test.radiation_fact.photon_frequency)
Ejemplo n.º 5
0
    def simul_undulator_theoric(self, magnetic_struc, electron_beam,
                                method_rad, method_traj):

        sim_test = create_simulation(magnetic_structure=magnetic_struc,
                                     electron_beam=electron_beam,
                                     rad_method=method_rad,
                                     traj_method=method_traj,
                                     distance=100)
        rad_axis = sim_test.radiation.intensity[0, 0]
        rad_theo = sim_test.source.theoretical_flux_on_axis(
            1)  #sim_test.radiation_fact.omega)

        print("rad axis %e , theo %e" % (rad_axis, rad_theo))
Ejemplo n.º 6
0
    def simul_undulator_near_to_farfield(self,magnetic_struc,electron_beam, method_traj):

        ref = create_simulation(magnetic_structure=magnetic_struc,electron_beam=electron_beam,
                                     traj_method=method_traj,distance=100)
        ref.calculate_on_central_cone()

        rad_max=(ref.radiation.max())

        sim_test=ref.copy()


        sim_test.change_radiation_method(RADIATION_METHOD_NEAR_FIELD)
        rad_err=ref.radiation.error_max(sim_test.radiation)
        self.assertLessEqual(np.abs(sim_test.radiation.max()-rad_max)/rad_max,5e-2)
        self.assertLessEqual(rad_err / rad_max, 5e-2)
Ejemplo n.º 7
0
    def simul_undulator_near_to_farfield(self, magnetic_struc, electron_beam,
                                         method_traj):

        ref = create_simulation(magnetic_structure=magnetic_struc,
                                electron_beam=electron_beam,
                                traj_method=method_traj,
                                distance=100)
        ref.calculate_on_central_cone()

        rad_max = (ref.radiation.max())

        sim_test = ref.copy()

        sim_test.change_radiation_method(RADIATION_METHOD_NEAR_FIELD)
        rad_err = ref.radiation.error_max(sim_test.radiation)
        self.assertLessEqual(
            np.abs(sim_test.radiation.max() - rad_max) / rad_max, 5e-2)
        self.assertLessEqual(rad_err / rad_max, 5e-2)
Ejemplo n.º 8
0
    def simul_undulator_traj_method(self, magnetic_struc,electron_beam, method_rad):

        sim_test = create_simulation(magnetic_structure=magnetic_struc, electron_beam=electron_beam,
                                     rad_method=method_rad,distance=100)
        sim_test.calculate_on_central_cone()

        ref = sim_test.copy()
        rad_max = (sim_test.radiation.max())

        sim_test.change_trajectory_method(TRAJECTORY_METHOD_ODE)
        rad_err = ref.radiation.error_max(sim_test.radiation)
        traj_err = ref.trajectory.error_max(sim_test.trajectory)
        self.assertLessEqual(np.abs(sim_test.radiation.max() - rad_max) / rad_max, 5e-2,4)
        self.assertLessEqual(traj_err[1] / ref.trajectory.x.max(), 5e-3)
        self.assertLessEqual(traj_err[3] / ref.trajectory.z.max(), 5e-3)
        self.assertLessEqual(traj_err[4] / ref.trajectory.v_x.max(), 5e-3)
        self.assertLessEqual(traj_err[6] / ref.trajectory.v_z.max(), 5e-3)
        self.assertLessEqual(traj_err[7] / ref.trajectory.a_x.max(), 5e-3)
        self.assertLessEqual(traj_err[9] / ref.trajectory.a_z.max(), 5e-3)
        self.assertLessEqual(np.abs(sim_test.radiation.max()-rad_max)/rad_max,5e-2)
        self.assertLessEqual(rad_err / rad_max, 5e-2)
Ejemplo n.º 9
0
    def create_magn_field_undulator_test(self, magnetic_structure,
                                         electron_beam, method_traj):

        sim_test = create_simulation(
            magnetic_structure=magnetic_structure,
            electron_beam=electron_beam,
            traj_method=method_traj,
            rad_method=RADIATION_METHOD_APPROX_FARFIELD)
        print('create')
        source_test = sim_test.source
        Zo = sim_test.trajectory_fact.initial_condition[5]
        Bo = source_test.magnetic_field_strength()
        lambda_u = source_test.magnetic_structure.period_length

        self.assertTrue(Zo < 0.)
        Zo_analitic = source_test.magnetic_structure.length * 0.5
        Z_test = np.linspace(-Zo_analitic, Zo_analitic,
                             sim_test.trajectory_fact.Nb_pts)
        diff_mf = np.abs(
            source_test.magnetic_field.By(z=Z_test, y=0.0, x=0.0) -
            Bo * np.cos((2.0 * np.pi / lambda_u) * Z_test))
        self.assertTrue(all(diff_mf < np.abs(Bo) * 1e-3))

        print('integration 1')
        int1 = integrate.quad(
            (lambda z: source_test.magnetic_field.By(z=z, y=0.0, x=0.0)),
            Zo,
            -Zo,
            limit=int(source_test.choose_nb_pts_trajectory(2)))
        self.assertAlmostEqual(int1[0], 0.0, 2)
        print('integration 2'
              )  #TODO marche pas donne tjr zeros meme qd c'est faux
        int2 = integrate.quad(
            (lambda z: z * source_test.magnetic_field.By(z=z, y=0.0, x=0.0)),
            Zo,
            -Zo,
            limit=int(source_test.choose_nb_pts_trajectory(2)))
        print(int2[0])
        self.assertAlmostEqual(int2[0], 0.0)
Ejemplo n.º 10
0
def erreur_near_ff(und,beam):
    sim_test_analy = create_simulation(magnetic_structure=und, electron_beam=beam,
                                       traj_method=TRAJECTORY_METHOD_ANALYTIC,Nb_pts_radiation=31,
                                       rad_method=RADIATION_METHOD_NEAR_FIELD,
                                       Nb_pts_trajectory=5000,distance=100)
    #sim_test_analy.change_harmonic_number(5.5)
    #sim_test_analy.calculate_on_central_cone()
    rad_max=sim_test_analy.radiation.max()
    print(rad_max)
    rad_max_theo=sim_test_analy.source.theoretical_flux_on_axis(frequency=sim_test_analy.radiation_fact.photon_frequency)
    print(rad_max_theo)
    d = np.linspace(20,60, 21)
    error_rad=sim_test_analy.error_radiation_method_distance(method=RADIATION_METHOD_APPROX,D=d)
    plt.plot(d,error_rad)
    plt.xlabel("distance")
    plt.ylabel("error")
    plt.title('absolut error between two radiation method')
    plt.show()
    plt.plot(d,error_rad/rad_max)
    plt.xlabel("distance")
    plt.ylabel("error")
    plt.title('relative error between two radiation method')
    plt.show()
Ejemplo n.º 11
0
def erreur_nb_pts_traj(und,beam):
    sim_test_analy = create_simulation(magnetic_structure=und, electron_beam=beam,
                                       traj_method=TRAJECTORY_METHOD_ANALYTIC,Nb_pts_radiation=50,
                                       rad_method=RADIATION_METHOD_NEAR_FIELD,
                                       Nb_pts_trajectory=20000,distance=20)
    rad_ref=sim_test_analy.radiation.intensity
    rad_max=sim_test_analy.radiation.max()
    print(rad_max)
    rad_max_theo=sim_test_analy.source.theoretical_flux_on_axis(frequency=sim_test_analy.radiation_fact.photon_frequency)
    # print(rad_max_theo)
    # print((rad_max-rad_max_theo))
    np_pts= np.arange(300,500,10)
    error_rad=sim_test_analy.error_radiation_nb_pts_traj(good_value=rad_ref,nb_pts=np_pts)
    plt.plot(np_pts,error_rad)
    plt.xlabel("number of point")
    plt.ylabel("error")
    plt.title('absolut error, near field formula')
    plt.show()
    plt.plot(np_pts,error_rad/rad_max)
    plt.xlabel("number of point")
    plt.ylabel("error")
    plt.title('relative error, near field formula')
    plt.show()
Ejemplo n.º 12
0
    beam_ESRF = ElectronBeam(Electron_energy=6.0, I_current=0.2)
    # ESRF18 = Undulator(K=1.68, period_length=0.018, length=2.0)
    ESRF18 = Undulator(K=1.0, period_length=0.1, length=1.0)

    #
    # radiation in a defined mesh with only one point to save time
    #

    distance = None
    simulation_test = create_simulation(
        magnetic_structure=ESRF18,
        electron_beam=beam_ESRF,
        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=distance,
        XY_are_list=False,
        X=np.array([0]),
        Y=np.array([0]))

    simulation_test0 = simulation_test.copy()
    #
    # central cone
    #

    if False:
        harmonic_number = 1
        print(
Ejemplo n.º 13
0
beam_test=ElectronBeam(Electron_energy=1.3, I_current=1.0)
beam_ESRF=ElectronBeam(Electron_energy=6.0, I_current=0.2)
und_test=Undulator(  K = 1.87,  period_length= 0.035, length=0.035 * 14)
ESRF18=Undulator( K = 1.68, period_length = 0.018, length=2.0)
ESRFBM=BM(Bo=0.8,horizontale_divergeance=0.005,electron_energy=6.0)



vx= 2e-4
vz= np.sqrt(beam_test.electron_speed()**2-vx**2)*codata.c

# initial_cond=np.array([ vx*codata.c,  0.00000000e+00 ,vz , 0.0 , 0.0 ,-0.42,])
#X=np.linspace(-0.02,0.02,150)
#Y=np.linspace(-0.02,0.02,150)
sim_test = create_simulation(magnetic_structure=und_test, electron_beam=beam_test, traj_method=TRAJECTORY_METHOD_ANALYTIC,
                            rad_method=RADIATION_METHOD_APPROX_FARFIELD, Nb_pts_trajectory=1000,distance=100)
sim_test.calculate_on_central_cone()
sim_test.change_energy_eV(E=2000)
#sim_test.change_harmonic_number(5.5)
#print(sim_test.source.choose_nb_pts_trajectory())
#print(sim_test.source.choose_distance_automatic())
#sim_test.print_parameters()


#sim_test.trajectory.plot_3D(title="Analytical electron trajectory in bending magnet")
#sim_test.trajectory.plot(title="Analytical electron trajectory in undulator")
#sim_test.calculate_on_central_cone()
#sim_test.calculate_spectrum_on_axis()
# omega1=sim_test.source.harmonic_frequency(1)
# omega_array=np.arange(.9*omega1,3.06*omega1,0.01*omega1)
# sim_test.calculate_spectrum_central_cone(abscissas_array=omega_array)
    def calculate_undulator_emission(cls,
                                     electron_energy=6.04,
                                     electron_current=0.2,
                                     undulator_period=0.032,
                                     undulator_nperiods=50,
                                     K=0.25,
                                     photon_energy=10490.0,
                                     abscissas_interval_in_far_field=250e-6,
                                     number_of_points=100,
                                     distance_to_screen=100,
                                     scan_direction="V"):

        myelectronbeam = PysruElectronBeam(Electron_energy=electron_energy,
                                           I_current=electron_current)
        myundulator = PysruUndulator(K=K,
                                     period_length=undulator_period,
                                     length=undulator_period *
                                     undulator_nperiods)

        abscissas = np.linspace(-0.5 * abscissas_interval_in_far_field,
                                0.5 * abscissas_interval_in_far_field,
                                number_of_points)

        if scan_direction == "H":
            X = abscissas
            Y = np.zeros_like(abscissas)
        elif scan_direction == "V":
            X = np.zeros_like(abscissas)
            Y = abscissas

        print("   photon energy %g eV" % photon_energy)
        simulation_test = create_simulation(
            magnetic_structure=myundulator,
            electron_beam=myelectronbeam,
            magnetic_field=None,
            photon_energy=photon_energy,
            traj_method=TRAJECTORY_METHOD_ANALYTIC,
            Nb_pts_trajectory=None,
            rad_method=RADIATION_METHOD_APPROX_FARFIELD,
            initial_condition=None,
            distance=distance_to_screen,
            X=X,
            Y=Y,
            XY_are_list=True)

        # TODO: this is not nice: I redo the calculations because I need the electric vectors to get polarization
        #       this should be avoided after refactoring pySRU to include electric field in simulations!!
        electric_field = simulation_test.radiation_fact.calculate_electrical_field(
            simulation_test.trajectory, simulation_test.source, X, Y,
            distance_to_screen)

        E = electric_field._electrical_field
        pol_deg1 = (np.abs(E[:, 0]) / (np.abs(E[:, 0]) + np.abs(E[:, 1]))
                    ).flatten()  # SHADOW definition!!

        intens1 = simulation_test.radiation.intensity.copy()

        #  Conversion from pySRU units (photons/mm^2/0.1%bw) to SHADOW units (photons/rad^2/eV)
        intens1 *= (distance_to_screen *
                    1e3)**2  # photons/mm^2 -> photons/rad^2
        intens1 /= 1e-3 * photon_energy  # photons/o.1%bw -> photons/eV

        # unpack trajectory
        T0 = simulation_test.trajectory
        T = np.vstack((T0.t, T0.x, T0.y, T0.z, T0.v_x, T0.v_y, T0.v_z, T0.a_x,
                       T0.a_y, T0.a_z))

        return {
            'intensity': intens1,
            'polarization': pol_deg1,
            'electric_field': E,
            'trajectory': T,
            'photon_energy': photon_energy,
            "abscissas": abscissas,
            "D": distance_to_screen,
            "theta": abscissas / distance_to_screen,
        }
Ejemplo n.º 15
0
    def _buildForXY(self, electron_beam, x_0, y_0, xp_0, yp_0, z, X, Y):

        #TODO: X dimension equals Y dimension?
        Y = X

        beam = ElectronBeam(Electron_energy=electron_beam.energy(),
                            I_current=electron_beam.averageCurrent())
        undulator = Undulator(K=self._undulator.K_vertical(),
                              period_length=self._undulator.periodLength(),
                              length=self._undulator.length())

        initial_conditions = SourceUndulatorPlane(
            undulator=undulator, electron_beam=beam,
            magnetic_field=None).choose_initial_contidion_automatic()

        v_z = initial_conditions[2]

        initial_conditions[0] = xp_0 * speed_of_light
        initial_conditions[1] = yp_0 * speed_of_light
        initial_conditions[2] = np.sqrt(beam.electron_speed()**2 - xp_0**2 -
                                        yp_0**2) * speed_of_light
        initial_conditions[3] = x_0
        initial_conditions[4] = y_0

        if self._source_position == VIRTUAL_SOURCE_CENTER:
            initial_conditions[5] = 0.0
        print("initial cond:", initial_conditions)

        simulation = create_simulation(
            magnetic_structure=undulator,
            electron_beam=beam,
            traj_method=TRAJECTORY_METHOD_ODE,
            rad_method=RADIATION_METHOD_NEAR_FIELD,  #RADIATION_METHOD_FARFIELD,
            distance=z,
            X=X,
            Y=Y,
            photon_energy=self._photon_energy,
            initial_condition=initial_conditions)
        #simulation.trajectory.plot_3D()
        #simulation.trajectory.plot()
        #simulation.radiation.plot()

        electrical_field = simulation.radiation_fact.calculate_electrical_field(
            trajectory=simulation.trajectory,
            source=simulation.source,
            distance=simulation.radiation.distance,
            X_array=simulation.radiation.X,
            Y_array=simulation.radiation.Y)

        efield = electrical_field.electrical_field()[np.newaxis, :, :, :]
        efield = efield[:, :, :, 0:2]

        calc_wavefront = NumpyWavefront(
            e_field=efield,
            x_start=X.min(),
            x_end=X.max(),
            y_start=Y.min(),
            y_end=Y.max(),
            z=z,
            energies=np.array([self._photon_energy]),
        )

        #calc_wavefront.showEField()

        self._last_simulation = simulation
        self._last_initial_conditions = initial_conditions.copy()

        return calc_wavefront
Ejemplo n.º 16
0
    def undul_phot(E_ENERGY, INTENSITY, LAMBDAU, NPERIODS, K, EMIN, EMAX, NG_E,
                   MAXANGLE, NG_T, NG_P):

        myelectronbeam = PysruElectronBeam(Electron_energy=E_ENERGY,
                                           I_current=INTENSITY)
        myundulator = PysruUndulator(K=K,
                                     period_length=LAMBDAU,
                                     length=LAMBDAU * NPERIODS)

        #
        # polar grid matrix
        #
        photon_energy = np.linspace(EMIN, EMAX, NG_E, dtype=float)

        intens = np.zeros((NG_E, NG_T, NG_P))
        pol_deg = np.zeros_like(intens)
        theta = np.linspace(0, MAXANGLE, NG_T, dtype=float)
        phi = np.linspace(0, np.pi / 2, NG_P, dtype=float)

        D = 100.0  # placed far away (100 m)

        THETA = np.outer(theta, np.ones_like(phi))
        PHI = np.outer(np.ones_like(theta), phi)

        X = (D / np.cos(THETA)) * np.sin(THETA) * np.cos(PHI)
        Y = (D / np.cos(THETA)) * np.sin(THETA) * np.sin(PHI)

        for ie, e in enumerate(photon_energy):
            print("Calculating energy %g eV (%d of %d)" %
                  (e, ie + 1, photon_energy.size))
            simulation_test = create_simulation(
                magnetic_structure=myundulator,
                electron_beam=myelectronbeam,
                magnetic_field=None,
                photon_energy=e,
                traj_method=TRAJECTORY_METHOD_ANALYTIC,
                Nb_pts_trajectory=None,
                rad_method=RADIATION_METHOD_APPROX_FARFIELD,
                initial_condition=None,
                distance=D,
                X=X.flatten(),
                Y=Y.flatten(),
                XY_are_list=True)

            # TODO: this is not nice: I redo the calculations because I need the electric vectors to get polarization
            #       this should be avoided after refactoring pySRU to include electric field in simulations!!
            electric_field = simulation_test.radiation_fact.calculate_electrical_field(
                simulation_test.trajectory, simulation_test.source,
                X.flatten(), Y.flatten(), D)

            E = electric_field._electrical_field
            # pol_deg1 = (np.abs(E[:,0])**2 / (np.abs(E[:,0])**2 + np.abs(E[:,1])**2)).flatten()
            pol_deg1 = (np.abs(E[:, 0]) / (np.abs(E[:, 0]) + np.abs(E[:, 1]))
                        ).flatten()  # SHADOW definition!!

            intens1 = simulation_test.radiation.intensity.copy()
            intens1.shape = (theta.size, phi.size)
            pol_deg1.shape = (theta.size, phi.size)

            #  Conversion from pySRU units (photons/mm^2/0.1%bw) to SHADOW units (photons/rad^2/eV)
            intens1 *= (D * 1e3)**2  # photons/mm^2 -> photons/rad^2
            intens1 /= 1e-3 * e  # photons/o.1%bw -> photons/eV

            intens[ie] = intens1
            pol_deg[ie] = pol_deg1

            T0 = simulation_test.trajectory
            T = np.vstack((T0.t, T0.x, T0.y, T0.z, T0.v_x, T0.v_y, T0.v_z,
                           T0.a_x, T0.a_y, T0.a_z))

        return {
            'radiation': intens,
            'polarization': pol_deg,
            'photon_energy': photon_energy,
            'theta': theta,
            'phi': phi,
            'trajectory': T
        }
Ejemplo n.º 17
0
    def _buildForXY(self, electron_beam, x_0, y_0, xp_0, yp_0, z, X, Y):

        #TODO: X dimension equals Y dimension?
        Y = X

        beam = ElectronBeam(Electron_energy=electron_beam.energy(), I_current=electron_beam.averageCurrent())
        undulator = Undulator(K=self._undulator.K_vertical(),
                              period_length=self._undulator.periodLength(),
                              length=self._undulator.length())

        initial_conditions = SourceUndulatorPlane(undulator=undulator, electron_beam=beam, magnetic_field=None).choose_initial_contidion_automatic()

        v_z = initial_conditions[2]

        initial_conditions[0] = xp_0 * speed_of_light
        initial_conditions[1] = yp_0 * speed_of_light
        initial_conditions[2] = np.sqrt(beam.electron_speed()**2-xp_0**2-yp_0**2) * speed_of_light
        initial_conditions[3] = x_0
        initial_conditions[4] = y_0

        if self._source_position == VIRTUAL_SOURCE_CENTER:
            initial_conditions[5] = 0.0
        print("initial cond:", initial_conditions)

        simulation = create_simulation(magnetic_structure=undulator,
                                       electron_beam=beam,
                                       traj_method=TRAJECTORY_METHOD_ODE,
                                       rad_method=RADIATION_METHOD_NEAR_FIELD, #RADIATION_METHOD_FARFIELD,
                                       distance=z,
                                       X=X,
                                       Y=Y,
                                       photon_energy=self._photon_energy,
                                       initial_condition=initial_conditions)
        #simulation.trajectory.plot_3D()
        #simulation.trajectory.plot()
        #simulation.radiation.plot()

        electrical_field = simulation.radiation_fact.calculate_electrical_field(trajectory=simulation.trajectory,
                                                                                source=simulation.source,
                                                                                distance=simulation.radiation.distance,
                                                                                X_array=simulation.radiation.X,
                                                                                Y_array=simulation.radiation.Y)

        efield = electrical_field.electrical_field()[np.newaxis, :, :, :]
        efield = efield[:, :, :, 0:2]

        calc_wavefront = NumpyWavefront(e_field=efield,
                                        x_start=X.min(),
                                        x_end=X.max(),
                                        y_start=Y.min(),
                                        y_end=Y.max(),
                                        z=z,
                                        energies=np.array([self._photon_energy]),
                                        )

        #calc_wavefront.showEField()

        self._last_simulation = simulation
        self._last_initial_conditions = initial_conditions.copy()

        return calc_wavefront