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)
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)
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", ""), ])
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, )
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
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(),
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)
# # ###########################################################################*/ __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 #
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
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
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
# 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)
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
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)
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())