def _calculate_CSD_GSM(self):

        ebeam = ElectronBeam(energy_in_GeV=self.electron_energy,
                             current=self.electron_current)
        su = Undulator.initialize_as_vertical_undulator(
            K=self.K,
            period_length=self.undulator_period,
            periods_number=self.undulator_nperiods)

        sigma_u, sigma_up = su.get_sigmas_radiation(ebeam.gamma(),
                                                    harmonic=1.0)

        self.abscissas = numpy.linspace(-0.5 * self.abscissas_interval,
                                        0.5 * self.abscissas_interval,
                                        self.number_of_points)

        X1 = numpy.outer(self.abscissas, numpy.ones_like(self.abscissas))
        X2 = numpy.outer(numpy.ones_like(self.abscissas), self.abscissas)

        CF = sigma_u * sigma_up / \
            numpy.sqrt(sigma_up ** 2 + 1 / self.mxpxp) / \
            numpy.sqrt(sigma_u ** 2 + 1 / self.mxx)
        sigmaI = numpy.sqrt(sigma_u**2 + 1 / self.mxx)
        beta = CF / numpy.sqrt(1.0 - CF)
        sigmaMu = beta * sigmaI
        CSD = numpy.exp(-(X1**2 + X2**2) / 4 / sigmaI**2) * numpy.exp(
            -(X2 - X1)**2 / 2 / sigmaMu**2)
        self.CSD = CSD
 def __closest_undulator_harmonic(self, srw):
     from orangecontrib.shadow.util.undulator.source_undulator import SourceUndulator
     from syned.storage_ring.electron_beam import ElectronBeam
     from syned.storage_ring.magnetic_structures.undulator import Undulator
     ebeam = ElectronBeam(energy_in_GeV=srw.electronBeam.energy, )
     gamma = ebeam.gamma()
     u = Undulator(
         K_horizontal=float(srw.undulator.horizontalDeflectingParameter),
         K_vertical=float(srw.undulator.verticalDeflectingParameter),
         period_length=float(srw.undulator.period) * 1e-3,
         number_of_periods=int(
             float(srw.undulator.length) /
             (float(srw.undulator.period) * 1e-3)),
     )
     search_energy = float(srw.simulation.photonEnergy)
     diff = search_energy
     harmonic = '1'
     energy = 1000
     for h in _SHADOW.schema().enum.Harmonic:
         v = u.resonance_energy(gamma, harmonic=int(h[0]))
         if abs(search_energy - v) < diff:
             diff = abs(search_energy - v)
             harmonic = h[0]
             energy = v
         if v > search_energy:
             break
     su = SourceUndulator(
         syned_electron_beam=ebeam,
         syned_undulator=u,
     )
     su.set_energy_monochromatic_at_resonance(int(harmonic))
     return harmonic, round(su._EMIN, 2), round(su._MAXANGLE * 1e6, 4)
    def __init__(
            self,
            name="",
            syned_electron_beam=None,
            syned_undulator=None,
            emin=10000.0,  # Photon energy scan from energy (in eV)
            emax=11000.0,  # Photon energy scan to energy (in eV)
            ng_e=11,  # Photon energy scan number of points
            maxangle=50e-6,  # Maximum radiation semiaperture in RADIANS
            ng_t=31,  # Number of points in angle theta
            ng_p=21,  # Number of points in angle phi
            ng_j=20,  # Number of points in electron trajectory (per period) for internal calculation only
            code_undul_phot="internal",  # internal, pysru, srw
            flag_emittance=0,  # when sampling rays: Use emittance (0=No, 1=Yes)
            flag_size=0,  # when sampling rays: 0=point,1=Gaussian,2=FT(Divergences)
    ):

        # # Machine
        if syned_electron_beam is None:
            self.syned_electron_beam = ElectronBeam()
        else:
            self.syned_electron_beam = syned_electron_beam

        # # Undulator
        if syned_undulator is None:
            self.syned_undulator = Undulator()
        else:
            self.syned_undulator = syned_undulator

        # Photon energy scan
        self._EMIN = emin  # Photon energy scan from energy (in eV)
        self._EMAX = emax  # Photon energy scan to energy (in eV)
        self._NG_E = ng_e  # Photon energy scan number of points
        # Geometry
        self._MAXANGLE = maxangle  # Maximum radiation semiaperture in RADIANS
        self._NG_T = ng_t  # Number of points in angle theta
        self._NG_P = ng_p  # Number of points in angle phi
        self._NG_J = ng_j  # Number of points in electron trajectory (per period)
        # ray tracing
        # self.SEED            = SEED   # Random seed
        # self.NRAYS           = NRAYS  # Number of rays

        self.code_undul_phot = code_undul_phot

        self._FLAG_EMITTANCE = flag_emittance  # Yes  # Use emittance (0=No, 1=Yes)
        self._FLAG_SIZE = flag_size  # 0=point,1=Gaussian,2=backpropagate Divergences

        # results of calculations

        self._result_radiation = None
        self._result_photon_size_distribution = None
        self._result_photon_size_sigma = None
    def __init__(self,
                 name="Undefined",
                 electron_beam=ElectronBeam(),
                 magnetic_structure=MagneticStructure(),
                 additional_parameters=None):
        LightSource.__init__(self, name, electron_beam, magnetic_structure)

        self._shadow3_source = self._build_shadow3_source(additional_parameters)
Exemple #5
0
 def __init__(self,
              name="Undefined",
              electron_beam=ElectronBeam(),
              bending_magnet_magnetic_structure=BendingMagnet(0, 0, 0),
              bending_magnet_parameters=Shadow3BendingMagnetParameters()):
     super().__init__(name,
                      electron_beam=electron_beam,
                      magnetic_structure=bending_magnet_magnetic_structure,
                      additional_parameters=bending_magnet_parameters)
Exemple #6
0
 def __init__(self,
              name="Undefined",
              electron_beam=ElectronBeam(),
              magnetic_structure=MagneticStructure()):
     self._name = name
     self._electron_beam = electron_beam
     self._magnetic_structure = magnetic_structure
     # support text containg name of variable, help text and unit. Will be stored in self._support_dictionary
     self._set_support_text([
         ("name", "Name", ""),
         ("electron_beam", "Electron Beam", ""),
         ("magnetic_structure", "Magnetic Strtructure", ""),
     ])
Exemple #7
0
def _compute_harmonic_photon_energy(data):
    from orangecontrib.shadow.util.undulator.source_undulator import SourceUndulator
    from syned.storage_ring.electron_beam import ElectronBeam
    from syned.storage_ring.magnetic_structures.undulator import Undulator
    undulator = data.undulator
    ebeam = data.undulatorBeam
    su = SourceUndulator(
        syned_electron_beam=ElectronBeam(energy_in_GeV=ebeam.energy),
        syned_undulator=Undulator(
            K_horizontal=undulator.k_horizontal,
            K_vertical=undulator.k_vertical,
            period_length=undulator.period / 1000,
            number_of_periods=int(undulator.length /
                                  (undulator.period / 1000)),
        ),
    )
    su.set_energy_monochromatic_at_resonance(int(undulator.energy_harmonic))
    return PKDict(
        photon_energy=su._EMIN,
        maxangle=su._MAXANGLE * 1e6,
    )
Exemple #8
0
from rafry.raytracer.beam import Beam
from rafry.raytracer.raytracer import RaytracingElements, RaytracingManager, RaytracingParameters

from rafryshadow3.raytracer.shadow3_raytracer import Shadow3Raytracer
from rafryshadow3.storage_ring.light_sources.shadow3_bending_magnet_light_source import Shadow3BendingMagnetLightSource, Shadow3BendingMagnetParameters
from rafryshadow3.optical_elements.absorbers.shadow3_slit import Shadow3Slit, Shadow3SlitParameters

if __name__ == "__main__":

    raytracing_manager = RaytracingManager.Instance()
    raytracing_manager.add_raytracer(raytracer=Shadow3Raytracer())

    ##########################################

    electron_beam = ElectronBeam(energy_in_GeV=2.0,
                                 energy_spread=0.80e-03,
                                 current=0.32)

    electron_beam.set_sigmas_all(sigma_x=0.2529e-3,
                                 sigma_xp=0.02881e-3,
                                 sigma_y=0.01844e-3,
                                 sigma_yp=5.235e-6)

    bm = Shadow3BendingMagnetLightSource(
        electron_beam=electron_beam,
        bending_magnet_magnetic_structure=BendingMagnet(radius=0.0,
                                                        magnetic_field=1.2,
                                                        length=0.0),
        bending_magnet_parameters=Shadow3BendingMagnetParameters(NPOINT=50000))

    slit = Shadow3Slit(name="first slit",
class SourceUndulator(object):
    def __init__(
            self,
            name="",
            syned_electron_beam=None,
            syned_undulator=None,
            emin=10000.0,  # Photon energy scan from energy (in eV)
            emax=11000.0,  # Photon energy scan to energy (in eV)
            ng_e=11,  # Photon energy scan number of points
            maxangle=50e-6,  # Maximum radiation semiaperture in RADIANS
            ng_t=31,  # Number of points in angle theta
            ng_p=21,  # Number of points in angle phi
            ng_j=20,  # Number of points in electron trajectory (per period) for internal calculation only
            code_undul_phot="internal",  # internal, pysru, srw
            flag_emittance=0,  # when sampling rays: Use emittance (0=No, 1=Yes)
            flag_size=0,  # when sampling rays: 0=point,1=Gaussian,2=FT(Divergences)
    ):

        # # Machine
        if syned_electron_beam is None:
            self.syned_electron_beam = ElectronBeam()
        else:
            self.syned_electron_beam = syned_electron_beam

        # # Undulator
        if syned_undulator is None:
            self.syned_undulator = Undulator()
        else:
            self.syned_undulator = syned_undulator

        # Photon energy scan
        self._EMIN = emin  # Photon energy scan from energy (in eV)
        self._EMAX = emax  # Photon energy scan to energy (in eV)
        self._NG_E = ng_e  # Photon energy scan number of points
        # Geometry
        self._MAXANGLE = maxangle  # Maximum radiation semiaperture in RADIANS
        self._NG_T = ng_t  # Number of points in angle theta
        self._NG_P = ng_p  # Number of points in angle phi
        self._NG_J = ng_j  # Number of points in electron trajectory (per period)
        # ray tracing
        # self.SEED            = SEED   # Random seed
        # self.NRAYS           = NRAYS  # Number of rays

        self.code_undul_phot = code_undul_phot

        self._FLAG_EMITTANCE = flag_emittance  # Yes  # Use emittance (0=No, 1=Yes)
        self._FLAG_SIZE = flag_size  # 0=point,1=Gaussian,2=backpropagate Divergences

        # results of calculations

        self._result_radiation = None
        self._result_photon_size_distribution = None
        self._result_photon_size_sigma = None

    def info(self, debug=False):
        """
        gets text info

        :param debug: if True, list the undulator variables (Default: debug=True)
        :return:
        """
        # list all non-empty keywords
        txt = ""

        txt += "-----------------------------------------------------\n"

        txt += "Input Electron parameters: \n"
        txt += "        Electron energy: %f geV\n" % self.syned_electron_beam._energy_in_GeV
        txt += "        Electron current: %f A\n" % self.syned_electron_beam._current
        if self._FLAG_EMITTANCE:
            sigmas = self.syned_electron_beam.get_sigmas_all()
            txt += "        Electron sigmaX: %g [um]\n" % (1e6 * sigmas[0])
            txt += "        Electron sigmaZ: %g [um]\n" % (1e6 * sigmas[2])
            txt += "        Electron sigmaX': %f urad\n" % (1e6 * sigmas[1])
            txt += "        Electron sigmaZ': %f urad\n" % (1e6 * sigmas[3])
        txt += "Input Undulator parameters: \n"
        txt += "        period: %f m\n" % self.syned_undulator.period_length()
        txt += "        number of periods: %d\n" % self.syned_undulator.number_of_periods(
        )
        txt += "        K-value: %f\n" % self.syned_undulator.K_vertical()

        txt += "-----------------------------------------------------\n"

        txt += "Lorentz factor (gamma): %f\n" % self.syned_electron_beam.gamma(
        )
        txt += "Electron velocity: %.12f c units\n" % (
            numpy.sqrt(1.0 - 1.0 / self.syned_electron_beam.gamma()**2))
        txt += "Undulator length: %f m\n" % (
            self.syned_undulator.period_length() *
            self.syned_undulator.number_of_periods())
        K_to_B = (2.0 * numpy.pi / self.syned_undulator.period_length()
                  ) * codata.m_e * codata.c / codata.e

        txt += "Undulator peak magnetic field: %f T\n" % (
            K_to_B * self.syned_undulator.K_vertical())
        txt += "Resonances: \n"
        txt += "        harmonic number [n]                   %10d %10d %10d \n" % (
            1, 3, 5)
        txt += "        wavelength [A]:                       %10.6f %10.6f %10.6f   \n"%(\
                                                                1e10*self.syned_undulator.resonance_wavelength(self.syned_electron_beam.gamma(),harmonic=1),
                                                                1e10*self.syned_undulator.resonance_wavelength(self.syned_electron_beam.gamma(),harmonic=3),
                                                                1e10*self.syned_undulator.resonance_wavelength(self.syned_electron_beam.gamma(),harmonic=5))
        txt += "        energy [eV]   :                       %10.3f %10.3f %10.3f   \n"%(\
                                                                self.syned_undulator.resonance_energy(self.syned_electron_beam.gamma(),harmonic=1),
                                                                self.syned_undulator.resonance_energy(self.syned_electron_beam.gamma(),harmonic=3),
                                                                self.syned_undulator.resonance_energy(self.syned_electron_beam.gamma(),harmonic=5))
        txt += "        frequency [Hz]:                       %10.3g %10.3g %10.3g   \n"%(\
                                                                1e10*self.syned_undulator.resonance_frequency(self.syned_electron_beam.gamma(),harmonic=1),
                                                                1e10*self.syned_undulator.resonance_frequency(self.syned_electron_beam.gamma(),harmonic=3),
                                                                1e10*self.syned_undulator.resonance_frequency(self.syned_electron_beam.gamma(),harmonic=5))
        txt += "        central cone 'half' width [urad]:     %10.6f %10.6f %10.6f   \n"%(\
                                                                1e6*self.syned_undulator.gaussian_central_cone_aperture(self.syned_electron_beam.gamma(),1),
                                                                1e6*self.syned_undulator.gaussian_central_cone_aperture(self.syned_electron_beam.gamma(),3),
                                                                1e6*self.syned_undulator.gaussian_central_cone_aperture(self.syned_electron_beam.gamma(),5))
        txt += "        first ring at [urad]:                 %10.6f %10.6f %10.6f   \n"%(\
                                                                1e6*self.get_resonance_ring(1,1),
                                                                1e6*self.get_resonance_ring(3,1),
                                                                1e6*self.get_resonance_ring(5,1))

        txt += "-----------------------------------------------------\n"
        txt += "Grids: \n"
        if self._NG_E == 1:
            txt += "        photon energy %f eV\n" % (self._EMIN)
        else:
            txt += "        photon energy from %10.3f eV to %10.3f eV\n" % (
                self._EMIN, self._EMAX)
        txt += "        number of points for the trajectory: %d\n" % (
            self._NG_J)
        txt += "        number of energy points: %d\n" % (self._NG_E)
        txt += "        maximum elevation angle: %f urad\n" % (1e6 *
                                                               self._MAXANGLE)
        txt += "        number of angular elevation points: %d\n" % (
            self._NG_T)
        txt += "        number of angular azimuthal points: %d\n" % (
            self._NG_P)
        # txt += "        number of rays: %d\n"%(self.NRAYS)
        # txt += "        random seed: %d\n"%(self.SEED)
        txt += "-----------------------------------------------------\n"

        txt += "calculation code: %s\n" % self.code_undul_phot
        if self._result_radiation is None:
            txt += "radiation: NOT YET CALCULATED\n"
        else:
            txt += "radiation: CALCULATED\n"
        txt += "Sampling: \n"
        if self._FLAG_SIZE == 0:
            flag = "point"
        elif self._FLAG_SIZE == 1:
            flag = "Gaussian"
        elif self._FLAG_SIZE == 2:
            flag = "Far field backpropagated"

        txt += "        Photon source size sampling flag: %d (%s)\n" % (
            self._FLAG_SIZE, flag)
        if self._FLAG_SIZE == 1:
            if self._result_photon_size_sigma is not None:
                txt += "        Photon source size sigma (Gaussian): %6.3f um \n" % (
                    1e6 * self._result_photon_size_sigma)

        txt += "-----------------------------------------------------\n"
        return txt

    def get_resonance_ring(self, harmonic_number=1, ring_order=1):
        return 1.0 / self.syned_electron_beam.gamma() * numpy.sqrt(
            ring_order / harmonic_number *
            (1 + 0.5 * self.syned_undulator.K_vertical()**2))

    def set_energy_monochromatic_at_resonance(self, harmonic_number):

        self.set_energy_monochromatic(
            self.syned_undulator.resonance_energy(
                self.syned_electron_beam.gamma(), harmonic=harmonic_number))
        # take 3*sigma - _MAXANGLE is in RAD
        self._MAXANGLE = 3 * 0.69 * self.syned_undulator.gaussian_central_cone_aperture(
            self.syned_electron_beam.gamma(), harmonic_number)

    def set_energy_monochromatic(self, emin):
        """
        Sets a single energy line for the source (monochromatic)
        :param emin: the energy in eV
        :return:
        """
        self._EMIN = emin
        self._EMAX = emin
        self._NG_E = 1

    def set_energy_box(self, emin, emax, npoints=None):
        """
        Sets a box for photon energy distribution for the source
        :param emin:  Photon energy scan from energy (in eV)
        :param emax:  Photon energy scan to energy (in eV)
        :param npoints:  Photon energy scan number of points (optinal, if not set no changes)
        :return:
        """

        self._EMIN = emin
        self._EMAX = emax
        if npoints != None:
            self._NG_E = npoints

    def get_energy_box(self):
        """
        Gets the limits of photon energy distribution for the source
        :return: emin,emax,number_of_points
        """
        return self._EMIN, self._EMAX, self._NG_E

    def calculate_radiation(self):
        """
        Calculates the radiation (emission) as a function of theta (elevation angle) and phi (azimuthal angle)
        This radiation will be sampled to create the source

        It calls undul_phot* in SourceUndulatorFactory

        :param code_undul_phot: 'internal' (calls undul_phot), 'pysru' (calls undul_phot_pysru) or
                'srw' (calls undul_phot_srw)
        :return: a dictionary (the output from undul_phot*)
        """

        # h = self.to_dictionary()
        # print(self.info())
        # os.system("rm -f xshundul.plt xshundul.par xshundul.traj xshundul.info xshundul.sha")

        # if code_undul_phot != "internal" or code_undul_phot != "srw":
        #     dump_uphot_dot_dat = True

        self._result_radiation = None

        # undul_phot
        if self.code_undul_phot == 'internal':
            undul_phot_dict = SourceUndulatorFactory.undul_phot(
                E_ENERGY=self.syned_electron_beam.energy(),
                INTENSITY=self.syned_electron_beam.current(),
                LAMBDAU=self.syned_undulator.period_length(),
                NPERIODS=self.syned_undulator.number_of_periods(),
                K=self.syned_undulator.K(),
                EMIN=self._EMIN,
                EMAX=self._EMAX,
                NG_E=self._NG_E,
                MAXANGLE=self._MAXANGLE,
                NG_T=self._NG_T,
                NG_P=self._NG_P,
                number_of_trajectory_points=self._NG_J)

        elif self.code_undul_phot == 'pysru' or self.code_undul_phot == 'pySRU':
            undul_phot_dict = SourceUndulatorFactoryPysru.undul_phot(
                E_ENERGY=self.syned_electron_beam.energy(),
                INTENSITY=self.syned_electron_beam.current(),
                LAMBDAU=self.syned_undulator.period_length(),
                NPERIODS=self.syned_undulator.number_of_periods(),
                K=self.syned_undulator.K(),
                EMIN=self._EMIN,
                EMAX=self._EMAX,
                NG_E=self._NG_E,
                MAXANGLE=self._MAXANGLE,
                NG_T=self._NG_T,
                NG_P=self._NG_P,
            )
        elif self.code_undul_phot == 'srw' or self.code_undul_phot == 'SRW':
            undul_phot_dict = SourceUndulatorFactorySrw.undul_phot(
                E_ENERGY=self.syned_electron_beam.energy(),
                INTENSITY=self.syned_electron_beam.current(),
                LAMBDAU=self.syned_undulator.period_length(),
                NPERIODS=self.syned_undulator.number_of_periods(),
                K=self.syned_undulator.K(),
                EMIN=self._EMIN,
                EMAX=self._EMAX,
                NG_E=self._NG_E,
                MAXANGLE=self._MAXANGLE,
                NG_T=self._NG_T,
                NG_P=self._NG_P,
            )
        else:
            raise Exception("Not implemented undul_phot code: " +
                            self.code_undul_phot)

        # add some info
        undul_phot_dict["code_undul_phot"] = self.code_undul_phot
        undul_phot_dict["info"] = self.info()

        self._result_radiation = undul_phot_dict

    #
    # get from results
    #

    def get_result_dictionary(self):
        if self._result_radiation is None:
            self.calculate_radiation()
        return self._result_radiation

    def get_result_radiation(self):
        return self.get_result_dictionary()["radiation"]

    def get_result_polarization(self):
        return self.get_result_dictionary()["polarization"]

    def get_result_polarisation(self):
        return self.get_result_polarization()

    def get_result_theta(self):
        return self.get_result_dictionary()["theta"]

    def get_result_phi(self):
        return self.get_result_dictionary()["phi"]

    def get_result_photon_energy(self):
        return self.get_result_dictionary()["photon_energy"]

    def get_radiation_polar(self):
        return self.get_result_radiation(), self.get_result_photon_energy(
        ), self.get_result_theta(), self.get_result_phi()

    def get_radiation(self):
        return self.get_radiation_polar()

    def get_radiation_interpolated_cartesian(self,
                                             npointsx=100,
                                             npointsz=100,
                                             thetamax=None):

        radiation, photon_energy, thetabm, phi = self.get_radiation_polar()

        if thetamax is None:
            thetamax = thetabm.max()

        vx = numpy.linspace(-1.1 * thetamax, 1.1 * thetamax, npointsx)
        vz = numpy.linspace(-1.1 * thetamax, 1.1 * thetamax, npointsz)
        VX = numpy.outer(vx, numpy.ones_like(vz))
        VZ = numpy.outer(numpy.ones_like(vx), vz)
        VY = numpy.sqrt(1 - VX**2 - VZ**2)

        THETA = numpy.abs(numpy.arctan(numpy.sqrt(VX**2 + VZ**2) / VY))
        PHI = numpy.arctan2(numpy.abs(VZ), numpy.abs(VX))

        radiation_interpolated = numpy.zeros(
            (radiation.shape[0], npointsx, npointsz))

        for i in range(radiation.shape[0]):
            interpolator_value = interpolate.RectBivariateSpline(
                thetabm, phi, radiation[i])
            radiation_interpolated[i] = interpolator_value.ev(THETA, PHI)

        return radiation_interpolated, photon_energy, vx, vz

    def get_power_density(self):

        radiation = self.get_result_radiation().copy()
        theta = self.get_result_theta()
        phi = self.get_result_phi()
        photon_energy = self.get_result_photon_energy()

        step_e = photon_energy[1] - photon_energy[0]

        for i in range(radiation.shape[0]):
            radiation[i] *= 1e-3 * photon_energy[
                i]  # photons/eV/rad2 -> photons/0.1%bw/rad2

        if INTEGRATION_METHOD == 0:
            power_density = radiation.sum(
                axis=0) * step_e * codata.e * 1e3  # W/rad2
        else:
            power_density = numpy.trapz(radiation, photon_energy,
                                        axis=0) * codata.e * 1e3  # W/rad2

        return power_density, theta, phi

    def get_power_density_interpolated_cartesian(self,
                                                 npointsx=100,
                                                 npointsz=100,
                                                 thetamax=None):

        power_density_polar, theta, phi = self.get_power_density()

        if thetamax is None:
            thetamax = theta.max()

        vx = numpy.linspace(-1.1 * thetamax, 1.1 * thetamax, npointsx)
        vz = numpy.linspace(-1.1 * thetamax, 1.1 * thetamax, npointsz)
        VX = numpy.outer(vx, numpy.ones_like(vz))
        VZ = numpy.outer(numpy.ones_like(vx), vz)
        VY = numpy.sqrt(1 - VX**2 - VZ**2)

        THETA = numpy.abs(numpy.arctan(numpy.sqrt(VX**2 + VZ**2) / VY))
        PHI = numpy.arctan2(numpy.abs(VZ), numpy.abs(VX))

        interpolator_value = interpolate.RectBivariateSpline(
            theta, phi, power_density_polar)
        power_density_cartesian = interpolator_value.ev(THETA, PHI)

        return power_density_cartesian, vx, vz

    def get_flux_and_spectral_power(self):

        radiation2 = self.get_result_radiation().copy()
        theta = self.get_result_theta()
        phi = self.get_result_phi()
        photon_energy = self.get_result_photon_energy()
        THETA = numpy.outer(theta, numpy.ones_like(phi))
        for i in range(radiation2.shape[0]):
            radiation2[i] *= THETA

        if INTEGRATION_METHOD == 0:
            flux = radiation2.sum(axis=2).sum(axis=1) * (
                1e-3 * photon_energy)  # photons/eV -> photons/0.1%bw
            flux *= 4 * (theta[1] - theta[0]) * (
                phi[1] - phi[0])  # adding the four quadrants!
        else:
            flux = 4 * numpy.trapz(
                numpy.trapz(radiation2, phi, axis=2), theta, axis=1) * (
                    1e-3 * photon_energy)  # photons/eV -> photons/0.1%bw

        spectral_power = flux * codata.e * 1e3

        return flux, spectral_power, photon_energy

    def get_flux(self):
        flux, spectral_power, photon_energy = self.get_flux_and_spectral_power(
        )
        return flux, photon_energy

    def get_spectral_power(self):
        flux, spectral_power, photon_energy = self.get_flux_and_spectral_power(
        )
        return spectral_power, photon_energy

    def get_photon_size_distribution(self):
        return self._result_photon_size_distribution[
            "x"], self._result_photon_size_distribution["y"]

    def calculate_rays(self,
                       user_unit_to_m=1.0,
                       F_COHER=0,
                       NRAYS=5000,
                       SEED=36255655452):
        """
        compute the rays in SHADOW matrix (shape (npoints,18) )
        :param F_COHER: set this flag for coherent beam
        :param user_unit_to_m: default 1.0 (m)
        :return: rays, a numpy.array((npoits,18))
        """

        if self._result_radiation is None:
            self.calculate_radiation()

        sampled_photon_energy, sampled_theta, sampled_phi = self._sample_photon_energy_theta_and_phi(
            NRAYS)

        if SEED != 0:
            numpy.random.seed(SEED)

        sigmas = self.syned_electron_beam.get_sigmas_all()

        rays = numpy.zeros((NRAYS, 18))

        #
        # sample sizes (cols 1-3)
        #

        if self._FLAG_EMITTANCE:
            x_electron = numpy.random.normal(loc=0.0,
                                             scale=sigmas[0],
                                             size=NRAYS)
            y_electron = 0.0
            z_electron = numpy.random.normal(loc=0.0,
                                             scale=sigmas[2],
                                             size=NRAYS)
        else:
            x_electron = 0.0
            y_electron = 0.0
            z_electron = 0.0

        # calculate (and stores) sizes of the photon undulator beam
        # see formulas 25 & 30 in Elleaume (Onaki & Elleaume)
        # sp_phot = 0.69*numpy.sqrt(lambda1/undulator_length)
        undulator_length = self.syned_undulator.length()
        lambda1 = codata.h * codata.c / codata.e / numpy.array(
            sampled_photon_energy).mean()
        s_phot = 2.740 / (4e0 * numpy.pi) * numpy.sqrt(
            undulator_length * lambda1)
        self._result_photon_size_sigma = s_phot

        if self._FLAG_SIZE == 0:
            x_photon = 0.0
            y_photon = 0.0
            z_photon = 0.0
            # for plot, a delta
            x = numpy.linspace(-1e-6, 1e-6, 101)
            y = numpy.zeros_like(x)
            y[y.size // 2] = 1.0
            self._result_photon_size_distribution = {"x": x, "y": y}
        elif self._FLAG_SIZE == 1:
            # TODO: I added this correction to obtain the sigma in the RADIAL coordinate, not in x and z.
            # RODO: TO be verified!
            s_phot_corrected = s_phot / numpy.sqrt(2)

            cov = [[s_phot_corrected**2, 0], [0, s_phot_corrected**2]]
            mean = [0.0, 0.0]

            tmp = numpy.random.multivariate_normal(mean, cov, NRAYS)
            x_photon = tmp[:, 0]
            y_photon = 0.0
            z_photon = tmp[:, 1]

            # for plot, a Gaussian
            x = numpy.linspace(-5 * s_phot, 5 * s_phot, 101)
            y = numpy.exp(-x**2 / 2 / s_phot**2)
            self._result_photon_size_distribution = {"x": x, "y": y}

        elif self._FLAG_SIZE == 2:
            # we need to retrieve the emission as a function of the angle
            radiation, photon_energy, theta, phi = self.get_radiation_polar()

            mean_photon_energy = numpy.array(
                sampled_photon_energy).mean()  # todo: use the weighted mean?
            shape_radiation = radiation.shape
            radial_flux = radiation.sum(axis=2) / shape_radiation[2]
            radial_flux = radial_flux.sum(axis=0) / shape_radiation[0]
            # doble the arrays for 1D propagation
            THETA = numpy.concatenate((-theta[::-1], theta[1::]), axis=None)
            RADIAL_FLUX = numpy.concatenate(
                (radial_flux[::-1], radial_flux[1::]), axis=None)

            #
            # we propagate the emission at a long distance back to the source plane
            #
            distance = 100.

            magnification = s_phot * 10 / (theta[-1] * distance)

            # do the propagation; result is stored in self._photon_size_distribution
            self._back_propagation_for_size_calculation(
                THETA,
                RADIAL_FLUX,
                mean_photon_energy,
                distance=distance,
                magnification=magnification)

            # we sample rays following the resulting radial distribution
            xx = self._result_photon_size_distribution["x"]
            yy = self._result_photon_size_distribution["y"]

            # #########################################################
            # # for plot, a Gaussian
            # xx = numpy.linspace(-5*s_phot,5*s_phot,101)
            # yy = numpy.exp(-xx**2/2/s_phot**2)
            # self._result_photon_size_distribution = {"x":xx,"y":yy}
            # #########################################################

            sampler_radial = Sampler1D(yy * numpy.abs(xx), xx)
            r, hy, hx = sampler_radial.get_n_sampled_points_and_histogram(
                NRAYS, bins=101)
            angle = numpy.random.random(NRAYS) * 2 * numpy.pi

            x_photon = r / numpy.sqrt(2.0) * numpy.sin(angle)
            y_photon = 0.0
            z_photon = r / numpy.sqrt(2.0) * numpy.cos(angle)

        rays[:, 0] = x_photon + x_electron
        rays[:, 1] = y_photon + y_electron
        rays[:, 2] = z_photon + z_electron

        if user_unit_to_m != 1.0:
            rays[:, 0] /= user_unit_to_m
            rays[:, 1] /= user_unit_to_m
            rays[:, 2] /= user_unit_to_m

        #
        # sample divergences (cols 4-6): the Shadow way
        #
        THETABM = sampled_theta
        PHI = sampled_phi
        A_Z = numpy.arcsin(numpy.sin(THETABM) * numpy.sin(PHI))
        A_X = numpy.arccos(numpy.cos(THETABM) / numpy.cos(A_Z))
        THETABM = A_Z
        PHI = A_X
        # ! C Decide in which quadrant THETA and PHI are.
        myrand = numpy.random.random(NRAYS)
        THETABM[numpy.where(myrand < 0.5)] *= -1.0
        myrand = numpy.random.random(NRAYS)
        PHI[numpy.where(myrand < 0.5)] *= -1.0

        if self._FLAG_EMITTANCE:
            EBEAM1 = numpy.random.normal(loc=0.0, scale=sigmas[1], size=NRAYS)
            EBEAM3 = numpy.random.normal(loc=0.0, scale=sigmas[3], size=NRAYS)
            ANGLEX = EBEAM1 + PHI
            ANGLEV = EBEAM3 + THETABM
        else:
            ANGLEX = PHI  # E_BEAM(1) + PHI
            ANGLEV = THETABM  #  E_BEAM(3) + THETABM

        VX = numpy.tan(ANGLEX)
        VY = 1.0
        VZ = numpy.tan(ANGLEV) / numpy.cos(ANGLEX)
        VN = numpy.sqrt(VX * VX + VY * VY + VZ * VZ)
        VX /= VN
        VY /= VN
        VZ /= VN

        rays[:, 3] = VX
        rays[:, 4] = VY
        rays[:, 5] = VZ

        #
        # electric field vectors (cols 7-9, 16-18) and phases (cols 14-15)
        #

        # beam.rays[:,6] =  1.0

        # ! C
        # ! C  ---------------------------------------------------------------------
        # ! C                 POLARIZATION
        # ! C
        # ! C   Generates the polarization of the ray. This is defined on the
        # ! C   source plane, so that A_VEC is along the X-axis and AP_VEC is along Z-axis.
        # ! C   Then care must be taken so that A will be perpendicular to the ray
        # ! C   direction.
        # ! C
        # ! C
        # A_VEC(1) = 1.0D0
        # A_VEC(2) = 0.0D0
        # A_VEC(3) = 0.0D0

        DIREC = rays[:, 3:6].copy()
        A_VEC = numpy.zeros_like(DIREC)
        A_VEC[:, 0] = 1.0

        # ! C
        # ! C   Rotate A_VEC so that it will be perpendicular to DIREC and with the
        # ! C   right components on the plane.
        # ! C
        # CALL CROSS (A_VEC,DIREC,A_TEMP)
        A_TEMP = self._cross(A_VEC, DIREC)
        # CALL CROSS (DIREC,A_TEMP,A_VEC)
        A_VEC = self._cross(DIREC, A_TEMP)
        # CALL NORM (A_VEC,A_VEC)
        A_VEC = self._norm(A_VEC)
        # CALL CROSS (A_VEC,DIREC,AP_VEC)
        AP_VEC = self._cross(A_VEC, DIREC)
        # CALL NORM (AP_VEC,AP_VEC)
        AP_VEC = self._norm(AP_VEC)

        #
        # obtain polarization for each ray (interpolation)
        #

        if self._NG_E == 1:  # 2D interpolation
            sampled_photon_energy = numpy.array(
                sampled_photon_energy)  # be sure is an array
            fn = interpolate.RegularGridInterpolator(
                (self._result_radiation["theta"],
                 self._result_radiation["phi"]),
                self._result_radiation["polarization"][0])

            pts = numpy.dstack((sampled_theta, sampled_phi))
            pts = pts[0]
            POL_DEG = fn(pts)
        else:  # 3D interpolation
            fn = interpolate.RegularGridInterpolator(
                (self._result_radiation["photon_energy"],
                 self._result_radiation["theta"],
                 self._result_radiation["phi"]),
                self._result_radiation["polarization"])

            pts = numpy.dstack(
                (sampled_photon_energy, sampled_theta, sampled_phi))
            pts = pts[0]
            POL_DEG = fn(pts)

        #     ! C
        #     ! C   WaNT A**2 = AX**2 + AZ**2 = 1 , instead of A_VEC**2 = 1 .
        #     ! C
        #     DENOM = SQRT(1.0D0 - 2.0D0*POL_DEG + 2.0D0*POL_DEG**2)
        #     AX = POL_DEG/DENOM
        #     CALL SCALAR (A_VEC,AX,A_VEC)
        #     ! C
        #     ! C   Same procedure for AP_VEC
        #     ! C
        #     AZ = (1-POL_DEG)/DENOM
        #     CALL SCALAR  (AP_VEC,AZ,AP_VEC)

        DENOM = numpy.sqrt(1.0 - 2.0 * POL_DEG + 2.0 * POL_DEG**2)
        AX = POL_DEG / DENOM
        for i in range(3):
            A_VEC[:, i] *= AX

        AZ = (1.0 - POL_DEG) / DENOM
        for i in range(3):
            AP_VEC[:, i] *= AZ

        rays[:, 6:9] = A_VEC
        rays[:, 15:18] = AP_VEC

        #
        # ! C
        # ! C Now the phases of A_VEC and AP_VEC.
        # ! C
        # IF (F_COHER.EQ.1) THEN
        #     PHASEX = 0.0D0
        # ELSE
        #     PHASEX = WRAN(ISTAR1) * TWOPI
        # END IF
        # PHASEZ = PHASEX + POL_ANGLE*I_CHANGE
        #
        POL_ANGLE = 0.5 * numpy.pi

        if F_COHER == 1:
            PHASEX = 0.0
        else:
            PHASEX = numpy.random.random(NRAYS) * 2 * numpy.pi

        PHASEZ = PHASEX + POL_ANGLE * numpy.sign(ANGLEV)

        rays[:, 13] = PHASEX
        rays[:, 14] = PHASEZ

        # set flag (col 10)
        rays[:, 9] = 1.0

        #
        # photon energy (col 11)
        #

        A2EV = 2.0 * numpy.pi / (codata.h * codata.c / codata.e * 1e2)
        rays[:, 10] = sampled_photon_energy * A2EV

        # col 12 (ray index)
        rays[:, 11] = 1 + numpy.arange(NRAYS)

        # col 13 (optical path)
        rays[:, 11] = 0.0

        return rays

    def _back_propagation_for_size_calculation(self,
                                               theta,
                                               radiation_flux,
                                               photon_energy,
                                               distance=100.0,
                                               magnification=0.010000):
        """
        Calculate the radiation_flux vs theta at a "distance"
        Back propagate to -distance
        The result is the size distrubution

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

        from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D
        from wofry.propagator.propagator import PropagationManager, PropagationElements, PropagationParameters
        from syned.beamline.beamline_element import BeamlineElement
        from syned.beamline.element_coordinates import ElementCoordinates
        from wofryimpl.propagator.propagators1D.fresnel_zoom import FresnelZoom1D
        from wofryimpl.beamline.optical_elements.ideal_elements.screen import WOScreen1D

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

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

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

        self._result_photon_size_distribution = {
            "x": output_wavefront.get_abscissas(),
            "y": output_wavefront.get_intensity()
        }

    def _cross(self, u, v):
        # w = u X v
        # u = array (npoints,vector_index)

        w = numpy.zeros_like(u)
        w[:, 0] = u[:, 1] * v[:, 2] - u[:, 2] * v[:, 1]
        w[:, 1] = u[:, 2] * v[:, 0] - u[:, 0] * v[:, 2]
        w[:, 2] = u[:, 0] * v[:, 1] - u[:, 1] * v[:, 0]

        return w

    def _norm(self, u):
        # w = u / |u|
        # u = array (npoints,vector_index)
        u_norm = numpy.zeros_like(u)
        uu = numpy.sqrt(u[:, 0]**2 + u[:, 1]**2 + u[:, 2]**2)
        for i in range(3):
            u_norm[:, i] = uu
        return u / u_norm

    def _sample_photon_energy_theta_and_phi(self, NRAYS):

        #
        # sample divergences
        #

        theta = self._result_radiation["theta"]
        phi = self._result_radiation["phi"]
        photon_energy = self._result_radiation["photon_energy"]

        photon_energy_spectrum = 'polychromatic'  # 'monochromatic' #
        if self._EMIN == self._EMAX:
            photon_energy_spectrum = 'monochromatic'
        if self._NG_E == 1:
            photon_energy_spectrum = 'monochromatic'

        if photon_energy_spectrum == 'monochromatic':

            #2D case
            tmp = self._result_radiation["radiation"][0, :, :].copy()
            tmp /= tmp.max()

            # correct radiation for DxDz / DthetaDphi
            tmp_theta = numpy.outer(theta, numpy.ones_like(phi))
            tmp_theta /= tmp_theta.max()
            tmp_theta += 1e-6  # to avoid zeros
            tmp *= tmp_theta
            # plot_image(tmp_theta,theta,phi,aspect='auto')

            s2d = Sampler2D(tmp, theta, phi)
            sampled_theta, sampled_phi = s2d.get_n_sampled_points(NRAYS)

            sampled_photon_energy = self._EMIN

        elif photon_energy_spectrum == "polychromatic":
            #3D case
            tmp = self._result_radiation["radiation"].copy()
            tmp /= tmp.max()
            # correct radiation for DxDz / DthetaDphi
            tmp_theta = numpy.outer(theta, numpy.ones_like(phi))
            tmp_theta /= tmp_theta.max()
            tmp_theta += 1e-6  # to avoid zeros
            for i in range(tmp.shape[0]):
                tmp[i, :, :] *= tmp_theta

            s3d = Sampler3D(tmp, photon_energy, theta, phi)

            sampled_photon_energy, sampled_theta, sampled_phi = s3d.get_n_sampled_points(
                NRAYS)

        return sampled_photon_energy, sampled_theta, sampled_phi
Exemple #10
0
        if do_assert:
            if True: # i != 5:  # TODO check why it fails!!!
                assert((numpy.abs(numpy.abs(m0)   -numpy.abs(m1) )    /numpy.abs(m1)) < 15.0)
            assert((numpy.abs(numpy.abs(std0) -numpy.abs(std1))  /numpy.abs(std1)) < 0.075)

if __name__ == "__main__":

    from srxraylib.plot.gol import set_qt
    set_qt()

    shadow3_beam,oe0 = run_bm_shadow3()


    syned_electron_beam = ElectronBeam(energy_in_GeV=6.04,current=0.2,
                                       moment_xx=(0.0078e-2)**2,
                                       moment_xpxp=(3.8e-07/0.0078)**2,
                                       moment_yy=(0.0036*1e-2)**2,
                                       moment_ypyp=(3.8e-09/0.0036)**2,
                                       )

    # syned_bending_magnet = SynedBendingMagnet(radius=25.1772,magnetic_field=0.8,length=25.1772*0.001)

    emin = 5000.0                # Photon energy scan from energy (in eV)
    emax = 100000.0              # Photon energy scan to energy (in eV)
    ng_e = 51                    # Photon energy scan number of points
    ng_j = 20                    # Number of points in electron trajectory (per period) for internal calculation only
    flag_emittance = 1           # when sampling rays: Use emittance (0=No, 1=Yes)


    bm = S4BendingMagnet(
                 radius=25.1772, magnetic_field=0.8, length=25.1772*0.001,
                 emin=emin,               # Photon energy scan from energy (in eV)
    def runShadowSource(self):

        self.setStatusMessage("")
        self.progressBarInit()

        # this is to be able to start the widget out of Oasys
        try:
            tmp = self.workspace_units
        except:
            self.workspace_units = 'm'
            self.workspace_units_label = 'm'
            self.workspace_units_to_m = 1.0
            self.workspace_units_to_cm = 1e2
            self.workspace_units_to_mm = 1e3

        self.checkFields()

        self.progressBarSet(10)

        self.setStatusMessage("Running SHADOW")

        sys.stdout = EmittingStream(textWritten=self.writeStdOut)
        if self.trace_shadow:
            grabber = TTYGrabber()
            grabber.start()

        self.progressBarSet(50)

        try:
            self.shadow_output.setText("")
            su = Undulator.initialize_as_vertical_undulator(
                K=self.K,
                period_length=self.period_length,
                periods_number=int(self.periods_number))

            ebeam = ElectronBeam(energy_in_GeV=self.energy_in_GeV,
                                 energy_spread=0.0,
                                 current=self.current,
                                 number_of_bunches=1,
                                 moment_xx=(self.sigma_x)**2,
                                 moment_xxp=0.0,
                                 moment_xpxp=(self.sigma_divergence_x)**2,
                                 moment_yy=(self.sigma_z)**2,
                                 moment_yyp=0.0,
                                 moment_ypyp=(self.sigma_divergence_z)**2)

            print(ebeam.info())

            codes = ["internal", "pySRU", "SRW"]
            selected_code = codes[self.code_undul_phot]

            self.sourceundulator = SourceUndulator(
                name="shadowOui-Full-Undulator",
                syned_electron_beam=ebeam,
                syned_undulator=su,
                flag_emittance=self.use_emittances_combo,
                flag_size=self.flag_size,
                emin=1000,  # to be set later
                emax=1001,  # to be set later
                ng_e=2,  # to be set later
                maxangle=self.maxangle_urad * 1e-6,
                ng_t=self.ng_t,
                ng_p=self.ng_p,
                ng_j=self.ng_j,
                code_undul_phot=selected_code)

            if self.set_at_resonance == 0:
                if self.delta_e == 0:
                    self.sourceundulator.set_energy_box(
                        self.photon_energy, self.photon_energy, 1)
                else:
                    self.sourceundulator.set_energy_box(
                        self.photon_energy - 0.5 * self.delta_e,
                        self.photon_energy + 0.5 * self.delta_e, self.ng_e)
            else:
                self.sourceundulator.set_energy_monochromatic_at_resonance(
                    self.harmonic)
                if self.delta_e > 0.0:
                    e0, e1, ne = self.sourceundulator.get_energy_box()
                    self.sourceundulator.set_energy_box(
                        e0 - 0.5 * self.delta_e, e0 + 0.5 * self.delta_e,
                        self.ng_e)

            rays = self.sourceundulator.calculate_rays(
                user_unit_to_m=self.workspace_units_to_m,
                F_COHER=self.coherent,
                SEED=self.seed,
                NRAYS=self.number_of_rays)

            if self.plot_aux_graph:
                self.set_PlotAuxGraphs()

            print(self.sourceundulator.info())

            shadow3_beam = Shadow3Beam(N=rays.shape[0])
            shadow3_beam.rays = rays

            if self.file_to_write_out >= 1:
                shadow3_beam.write("begin.dat")
                print("File written to disk: begin.dat")

            if self.file_to_write_out >= 2:
                SourceUndulatorInputOutput.write_file_undul_phot_h5(
                    self.sourceundulator.get_result_dictionary(),
                    file_out="radiation.h5",
                    mode="w",
                    entry_name="radiation")

            beam_out = ShadowBeam(beam=shadow3_beam)
            beam_out.getOEHistory().append(ShadowOEHistoryItem())

            if self.add_power:
                additional_parameters = {}

                pd, vx, vy = self.sourceundulator.get_power_density_interpolated_cartesian(
                )

                total_power = self.power_step if self.power_step > 0 else pd.sum(
                ) * (vx[1] - vx[0]) * (vy[1] - vy[0])

                additional_parameters["total_power"] = total_power
                additional_parameters["photon_energy_step"] = self.delta_e

                beam_out.setScanningData(
                    ShadowBeam.ScanningData("photon_energy",
                                            self.photon_energy,
                                            "Energy for Power Calculation",
                                            "eV", additional_parameters))

            if self.delta_e == 0.0:
                beam_out.set_initial_flux(self.sourceundulator.get_flux()[0])

            self.progressBarSet(80)
            self.plot_results(beam_out)

            #
            # create python script for creating the shadow3 beam and display the script in the standard output
            #
            dict_parameters = {
                "K": self.K,
                "period_length": self.period_length,
                "periods_number": self.periods_number,
                "energy_in_GeV": self.energy_in_GeV,
                "energy_spread": 0.0,
                "current": self.current,
                "number_of_bunches": 1,
                "moment_xx": (self.sigma_x)**2,
                "moment_xxp": 0.0,
                "moment_xpxp": (self.sigma_divergence_x)**2,
                "moment_yy": (self.sigma_z)**2,
                "moment_yyp": 0.0,
                "moment_ypyp": (self.sigma_divergence_z)**2,
                "name": "shadowOui-Full-Undulator",
                "flag_emittance": self.use_emittances_combo,
                "flag_size": self.flag_size,
                "emin": 1000,  # to be set later
                "emax": 1001,  # to be set later
                "ng_e": 2,  # to be set later
                "maxangle": self.maxangle_urad * 1e-6,
                "ng_t": self.ng_t,
                "ng_p": self.ng_p,
                "ng_j": self.ng_j,
                "code_undul_phot": selected_code,
                "user_unit_to_m": self.workspace_units_to_m,
                "F_COHER": self.coherent,
                "SEED": self.seed,
                "NRAYS": self.number_of_rays,
                "EMIN": self.sourceundulator._EMIN,
                "EMAX": self.sourceundulator._EMAX,
                "NG_E": self.sourceundulator._NG_E,
                "MAXANGLE": self.sourceundulator._MAXANGLE,
            }

            # write python script in standard output
            print(self.script_template().format_map(dict_parameters))

            self.setStatusMessage("")
            self.send("Beam", beam_out)

        except Exception as exception:
            QtWidgets.QMessageBox.critical(self, "Error", str(exception),
                                           QtWidgets.QMessageBox.Ok)

            if self.IS_DEVELOP: raise exception

        self.progressBarFinished()
                 title='OPTICAL ELEMENT NR 1',
                 xtitle="x [um]",
                 show=0)

        return output_wavefront


if __name__ == "__main__":
    from srxraylib.plot.gol import plot, plot_image, plot_table, set_qt
    from syned.storage_ring.electron_beam import ElectronBeam
    from syned.storage_ring.magnetic_structures.undulator import Undulator

    set_qt()

    # definitions with syned compatibility
    ebeam = ElectronBeam(energy_in_GeV=6.0, current=0.2)
    su = Undulator.initialize_as_vertical_undulator(K=1.191085,
                                                    period_length=0.02,
                                                    periods_number=100)
    photon_energy = su.resonance_energy(ebeam.gamma(), harmonic=1)
    print("Resonance energy: ", photon_energy)
    # other inputs
    distance_to_screen = 100.0
    number_of_points = 200
    # Electron beam values: sigma_h : 30.184 um, sigma_v:  3.636 um
    sigmaxx = 3.01836e-05
    sigmaxpxp = 4.36821e-06

    # set parameters
    co = UndulatorCoherentModeDecomposition1D(
        electron_energy=ebeam.energy(),
Exemple #13
0
    shift_x_value = 0.0
    shift_betax_flag = 0
    shift_betax_value = 0.0



    #
    # syned
    #
    # syned_wiggler = Wiggler(K_vertical=kValue,K_horizontal=0.0,period_length=per,number_of_periods=nPer)

    syned_electron_beam = ElectronBeam(energy_in_GeV=6.04,
                 energy_spread = 0.0,
                 current = 0.2,
                 number_of_bunches = 400,
                 moment_xx=(400e-6)**2,
                 moment_xxp=0.0,
                 moment_xpxp=(10e-6)**2,
                 moment_yy=(10e-6)**2,
                 moment_yyp=0.0,
                 moment_ypyp=(4e-6)**2 )

    w = S4Wiggler(K_vertical=kValue,period_length=per,number_of_periods=nPer,
                    flag_emittance=use_emittances,
                    emin=e_min,emax=e_max,ng_e=10, ng_j=nTrajPoints)


    print(w.info())

    ls = S4WigglerLightSource(name="Untitled", electron_beam=syned_electron_beam, wiggler_magnetic_structure=w)

    beam = ls.get_beam(NRAYS=NRAYS)
Exemple #14
0
#
# ###########################################################################*/
__authors__ = ["M Glass - ESRF ISDD Advanced Analysis and Modelling"]
__license__ = "MIT"
__date__ = "20/04/2017"



#from comsyl.autocorrelation.SigmaMatrix import SigmaWaist, SigmaMatrixFromCovariance
from syned.storage_ring.electron_beam import ElectronBeam

lb_Ob = ElectronBeam(energy_in_GeV=6.04,
                     current      =0.2,
                     moment_xx    =(37.4e-6)**2,
                     moment_yy    =(3.5e-6)**2,
                     moment_xpxp  =(106.9e-6)**2,
                     moment_ypyp  =(1.2e-6)**2,
                     moment_xxp   =0.0,
                     moment_yyp   =0.0,
                     energy_spread=1.06e-03)


hb_Ob = ElectronBeam(energy_in_GeV=6.04,
                     current      =0.2,
                     moment_xx    =(387.8e-6)**2,
                     moment_yy    =(3.5e-6)**2,
                     moment_xpxp  =(10.3e-6)**2,
                     moment_ypyp  =(1.2e-6)**2,
                     moment_xxp   =0.0,
                     moment_yyp   =0.0,
                     energy_spread=1.06e-03)
from syned.beamline.shape import SurfaceShape, Conic, Ellipsoid, Plane
from syned.beamline.shape import Rectangle
from syned.storage_ring.light_source import LightSource

from syned.beamline.beamline import Beamline
from syned.beamline.beamline_element import BeamlineElement
from syned.beamline.element_coordinates import ElementCoordinates



if __name__ == "__main__":



    src1 = ElectronBeam.initialize_as_pencil_beam(energy_in_GeV=6.0,current=0.2)
    src2 = Undulator()
    screen1 = Screen("screen1")
    lens1 = IdealLens(name="lens1",focal_y=6.0,focal_x=None,)
    filter1 = Filter("filter1","H2O",3.0e-6)
    slit1 = Slit(name="slit1",boundary_shape=Rectangle(-0.5e-3,0.5e-3,-2e-3,2e-3))
    stopper1 = BeamStopper(name="stopper1",boundary_shape=Rectangle(-0.5e-3,0.5e-3,-2e-3,2e-3))
    mirror1 = Mirror(name="mirror1",boundary_shape=Rectangle(-0.5e-3,0.5e-3,-2e-3,2e-3))
    crystal1 = Crystal(name="crystal1",surface_shape=Plane())
    grating1 = Grating(name="grating1",surface_shape=Conic())

    mylist = [src1,src2,screen1,lens1,filter1,slit1, stopper1, mirror1, grating1, crystal1]

    #
    # test individual elements
    #
Exemple #16
0
def run_source_wiggler_shadow4(
    electron_energy=2.0,
    filename="/home/manuel/Oasys/BM_only7.b",
    use_emittances=True,
    e_min=1000.0,
    e_max=1000.1,
    NRAYS=5000,
):

    wigFile = "xshwig.sha"
    inData = ""

    nTrajPoints = 501
    ener_gev = electron_energy
    per = 0.5
    kValue = 4
    trajFile = ""
    shift_x_flag = 0
    shift_x_value = 0.0
    shift_betax_flag = 0
    shift_betax_value = 0.0

    sw = SourceWiggler()

    #
    # syned
    #

    syned_electron_beam = ElectronBeam(
        energy_in_GeV=electron_energy,
        current=0.5,
        moment_xx=(7e-6)**2,  #(39e-6)**2,
        moment_xpxp=(70e-12 / 7e-6)**2,  #(2000e-12 / 51e-6)**2,
        moment_yy=(10e-6)**2,  #(31e-6)**2,
        moment_ypyp=(70e-12 / 10e-6)**2,  #(30e-12 / 31e-6)**2,
    )

    # conventional wiggler
    # syned_wiggler = Wiggler(K_vertical=kValue,K_horizontal=0.0,period_length=per,number_of_periods=nPer)

    # B from file

    syned_wiggler = MagneticStructure1DField.initialize_from_file(filename)
    # syned_wiggler.add_spatial_shift(-0.478)
    # syned_wiggler.flip_B()

    if e_min == e_max:
        ng_e = 1
    else:
        ng_e = 10

    sourcewiggler = SourceWiggler(name="test",
                                  syned_electron_beam=syned_electron_beam,
                                  syned_wiggler=syned_wiggler,
                                  flag_emittance=use_emittances,
                                  emin=e_min,
                                  emax=e_max,
                                  ng_e=ng_e,
                                  ng_j=nTrajPoints)

    sourcewiggler.set_electron_initial_conditions_by_label(
        velocity_label="value_at_zero",
        position_label="value_at_zero",
    )

    print(sourcewiggler.info())

    t00 = time.time()
    rays = sourcewiggler.calculate_rays(NRAYS=NRAYS)
    t11 = time.time() - t00
    print(">>>> time for %d rays: %f s, %f min, " % (NRAYS, t11, t11 / 60))

    beam = Beam3.initialize_from_array(rays)

    return beam
Exemple #17
0
    per = 0.5
    kValue = 4
    trajFile = ""
    shift_x_flag = 0
    shift_x_value = 0.0
    shift_betax_flag = 0
    shift_betax_value = 0.0

    #
    # syned
    #

    syned_electron_beam = ElectronBeam(
        energy_in_GeV=1.9,
        current=0.4,
        moment_xx=(39e-6)**2,
        moment_xpxp=(2000e-12 / 51e-6)**2,
        moment_yy=(31e-6)**2,
        moment_ypyp=(30e-12 / 31e-6)**2,
    )

    # B from file
    filename = "BM_multi.b"
    create_file_with_magnetic_field(filename)
    # syned_wiggler = MagneticStructure1DField.initialize_from_file(filename)
    # syned_wiggler.add_spatial_shift(-0.478)
    # syned_wiggler.flip_B()

    if e_min == e_max:
        ng_e = 1
    else:
        ng_e = 10
Exemple #18
0
def run_shadow4(photon_energy, n_rays=5e5, emittance=True):

    use_emittances = emittance

    if use_emittances:
        # in mm
        EPSI_X = 2.574e-05
        EPSI_Z = 2.574e-07
        SIGMAX = 0.8208
        SIGMAZ = 0.0142

        sigmax = SIGMAX * 1e-3
        sigmaz = SIGMAZ * 1e-3
        sigmaxprime = EPSI_X * 1e-3 / sigmax
        sigmazprime = EPSI_Z * 1e-3 / sigmaz
    else:
        sigmax = 0.0
        sigmaz = 0.0
        sigmaxprime = 0.0
        sigmazprime = 0.0

    e_min = photon_energy
    e_max = photon_energy
    NRAYS = n_rays

    nTrajPoints = 501
    shift_x_flag = 4
    shift_x_value = 0.0
    shift_betax_flag = 4
    shift_betax_value = 0.0

    #
    # syned
    #

    syned_electron_beam = ElectronBeam(
        energy_in_GeV=2.5,
        current=0.4,
        moment_xx=(sigmax)**2,
        moment_xpxp=(sigmaxprime)**2,
        moment_yy=(sigmaz)**2,
        moment_ypyp=(sigmazprime)**2,
    )

    # wiggler: B from file
    # syned_wiggler = MagneticStructure1DField.initialize_from_file("Bz_Alba_rev3.dat")

    if e_min == e_max:
        ng_e = 1
    else:
        ng_e = 10

    sourcewiggler = S4Wiggler(magnetic_field_periodic=0,
                              file_with_magnetic_field="Bz_Alba_rev3.dat",
                              flag_emittance=use_emittances,
                              emin=e_min,
                              emax=e_max,
                              ng_e=ng_e,
                              ng_j=nTrajPoints)

    # sourcewiggler.set_electron_initial_conditions_by_label(position_label="value_at_zero",
    #                                                        velocity_label="value_at_zero")

    sourcewiggler.set_electron_initial_conditions(
        shift_x_flag=shift_x_flag,
        shift_x_value=shift_x_value,
        shift_betax_flag=shift_betax_flag,
        shift_betax_value=shift_betax_value)

    ls = S4WigglerLightSource(name="",
                              electron_beam=syned_electron_beam,
                              wiggler_magnetic_structure=sourcewiggler)
    print(ls.info())

    beam = ls.get_beam(NRAYS=NRAYS)

    return beam
Exemple #19
0
    #
    from shadow4tests.oasys_workspaces.sources_bm_1 import define_source, run_source

    oe0 = define_source()
    beam3 = run_source(oe0)

    #
    # shadow4
    #

    check_congruence(oe0)

    electron_beam = ElectronBeam(
        energy_in_GeV=oe0.BENER,
        current=0.2,
        moment_xx=(oe0.SIGMAX * to_meters)**2,
        moment_xpxp=(oe0.EPSI_X / oe0.SIGMAX)**2,
        moment_yy=(oe0.SIGMAZ * to_meters)**2,
        moment_ypyp=(oe0.EPSI_Z / oe0.SIGMAZ)**2,
    )

    bm = S4BendingMagnet(
        radius=oe0.R_ALADDIN * to_meters,
        magnetic_field=S4BendingMagnet.calculate_magnetic_field(
            oe0.R_MAGNET * to_meters, oe0.BENER),
        length=(oe0.HDIV1 + oe0.HDIV2) * oe0.R_MAGNET,  # BM
        emin=oe0.PH1,  # Photon energy scan from energy (in eV)
        emax=oe0.PH2,  # Photon energy scan to energy (in eV)
        ng_e=200,  # Photon energy scan number of points
        ng_j=
        100,  # Number of points in electron trajectory (per period) for internal calculation only
        flag_emittance=True,  # when sampling rays: Use emittance (0=No, 1=Yes)
Exemple #20
0
from shadow4.sources.undulator.s4_undulator import S4Undulator
from shadow4.sources.undulator.s4_undulator_light_source import S4UndulatorLightSource

if __name__ == "__main__":

    from srxraylib.plot.gol import plot, set_qt
    set_qt()

    do_plots = True

    ebeam = ElectronBeam(energy_in_GeV=6.04,
                         energy_spread=0.0,
                         current=0.2,
                         number_of_bunches=400,
                         moment_xx=(400e-6)**2,
                         moment_xxp=0.0,
                         moment_xpxp=(10e-6)**2,
                         moment_yy=(10e-6)**2,
                         moment_yyp=0.0,
                         moment_ypyp=(4e-6)**2)

    und = S4Undulator(
        K_vertical=0.25,  # syned Undulator parameter
        period_length=0.032,  # syned Undulator parameter
        number_of_periods=50,  # syned Undulator parameter
        emin=10490.0,  # Photon energy scan from energy (in eV)
        emax=10510.0,  # Photon energy scan to energy (in eV)
        ng_e=3,  # Photon energy scan number of points
        maxangle=0.015,  # Maximum radiation semiaperture in RADIANS
        ng_t=100,  # Number of points in angle theta
        ng_p=11,  # Number of points in angle phi
Exemple #21
0
    def test_compare_preprocessor_and_internal_from_shadowvui_json_file(
            self, shadowvui_json_file=None):

        if shadowvui_json_file == None:
            tmp = \
            """
            {
            "LAMBDAU":     0.0320000015,
            "K":      0.250000000,
            "E_ENERGY":       6.03999996,
            "E_ENERGY_SPREAD":    0.00100000005,
            "NPERIODS": 50,
            "_EMIN":       10498.0000,
            "_EMAX":       10499.0000,
            "INTENSITY":      0.200000003,
            "_MAXANGLE":      0.000100,
            "_NG_E": 101,
            "_NG_T": 51,
            "_NG_P": 11,
            "NG_PLOT(1)":"0",
            "NG_PLOT(2)":"No",
            "NG_PLOT(3)":"Yes",
            "UNDUL_PHOT_FLAG(1)":"0",
            "UNDUL_PHOT_FLAG(2)":"Shadow code",
            "UNDUL_PHOT_FLAG(3)":"Urgent code",
            "UNDUL_PHOT_FLAG(4)":"SRW code",
            "UNDUL_PHOT_FLAG(5)":"Gaussian Approximation",
            "UNDUL_PHOT_FLAG(6)":"ESRF python code",
            "SEED": 36255,
            "SX":     0.0399999991,
            "SZ":    0.00100000005,
            "EX":   4.00000005E-07,
            "EZ":   3.99999989E-09,
            "_FLAG_EMITTANCE(1)":"1",
            "_FLAG_EMITTANCE(2)":"No",
            "_FLAG_EMITTANCE(3)":"Yes",
            "NRAYS": 15000,
            "F_BOUND_SOUR": 0,
            "FILE_BOUND":"NONESPECIFIED",
            "SLIT_DISTANCE":       1000.00000,
            "SLIT_XMIN":      -1.00000000,
            "SLIT_XMAX":       1.00000000,
            "SLIT_ZMIN":      -1.00000000,
            "SLIT_ZMAX":       1.00000000,
            "NTOTALPOINT": 10000000,
            "JUNK4JSON":0
            }

            """

            h = json.loads(tmp)

        #
        # clean
        #
        os.system("rm start.00 begin*.dat uphot*.dat xshundul*.sha")

        #
        # run
        #

        methods = ['preprocessor', 'internal']

        for method in methods:

            if method == 'preprocessor':
                # run using binary shadow3 (with preprocessors)
                _calculate_shadow3_beam_using_preprocessors(h)
            else:
                from syned.storage_ring.electron_beam import ElectronBeam
                from syned.storage_ring.magnetic_structures.undulator import Undulator

                #
                # syned
                #

                # su = Undulator.initialize_as_vertical_undulator(K=h["K"],period_length=h["LAMBDAU"],periods_number=h["NPERIODS"])

                ebeam = ElectronBeam(
                    energy_in_GeV=h["E_ENERGY"],
                    energy_spread=h["E_ENERGY_SPREAD"],
                    current=h["INTENSITY"],
                    number_of_bunches=1,
                    moment_xx=(1e-2 * h["SX"])**2,
                    moment_xxp=0.0,
                    moment_xpxp=(h["EX"] / h["SX"])**2,
                    moment_yy=(1e-2 * h["SZ"])**2,
                    moment_yyp=0.0,
                    moment_ypyp=(h["EZ"] / h["SZ"])**2,
                )

                u = S4Undulator(K_vertical=h["K"],
                                period_length=h["LAMBDAU"],
                                number_of_periods=h["NPERIODS"],
                                flag_emittance=int(h["_FLAG_EMITTANCE(1)"]),
                                flag_size=0,
                                emin=h["_EMIN"],
                                emax=h["_EMAX"],
                                ng_e=h["_NG_E"],
                                maxangle=h["_MAXANGLE"],
                                ng_t=h["_NG_T"],
                                ng_p=h["_NG_P"],
                                code_undul_phot="internal")

                ls = S4UndulatorLightSource(name="",
                                            electron_beam=ebeam,
                                            undulator_magnetic_structure=u)
                print(ls.info())

                beam_shadow4 = ls.get_beam(user_unit_to_m=1e-2,
                                           SEED=36255,
                                           NRAYS=h["NRAYS"])
                beam = Beam3.initialize_from_shadow4_beam(beam_shadow4)
                beam.write("begin.dat")

            os.system("cp begin.dat begin_%s.dat" % method)
            os.system("cp uphot.dat uphot_%s.dat" % method)
Exemple #22
0
 def __init__(self, name="Undefined", electron_beam=None, bending_magnet_magnetic_structure=None):
     super().__init__(name,
                      electron_beam=electron_beam if not electron_beam is None else ElectronBeam(),
                      magnetic_structure=bending_magnet_magnetic_structure if not bending_magnet_magnetic_structure is None else S4BendingMagnet())