Source code for shadow4.sources.undulator.s4_undulator

"""
S4 Undulator magnetic structure.
"""

from syned.storage_ring.magnetic_structures.undulator import Undulator
import numpy
import scipy.constants as codata

[docs]class S4Undulator(Undulator): """ Defines a shadow4 undulator magnetic structure. Parameters ---------- K_vertical : float, optional the K value. period_length : float, optional for magnetic_field_periodic=1, the period in m. number_of_periods : float, optional for magnetic_field_periodic=1, the number of periods. emin : float, optional minimum photon energy in eV. emax : float, optional maximum photon energy in eV. ng_e : int, optional Number of points in energy. This is used for the calculation of the spectrum, and also for sampling rays if flag_interpolation=1. maxangle: float, optional Maximum radiation semiaperture in RADIANS. ng_t : int, optional the number of points for angle theta. ng_p : int, optional the number of points for angle phi. ng_j : int, optional Number of points PER PERIOD in calculating the electron trajectory. code_undul_phot : str, optional code to be used for calculating the emission vs angle: internal, pysru, SRW flag_emittance : int, optional Flag: 0=Zero emittance (filament beam), 1=Use emittance. flag_size : int, optional Method used for sampling the source size: 0=point, 1=Gaussian, 2=Backpropagated far field. use_gaussian_approximation : int, optional 0=No, 1=Yes. srw_range: float, optional for code_undul_phot="srw" the range factor. srw_resolution: float, optional for code_undul_phot="srw" the resolution factor. srw_semianalytical: int, optional for code_undul_phot="srw" flag to apply the semianalytical phase treatement (0=No, 1=Yes). magnification: float, optional for code_undul_phot in ["internal", "pysru"]: the magnification factor. flag_backprop_recalculate_source: int, optional for code_undul_phot in ["internal", "pysru"] and flag_size=2: apply Gaussian weight to backprop amplitudes (0=No, 1=Yes). flag_backprop_weight: int, optional for code_undul_phot in ["internal", "pysru"] and flag_size=2: apply Gaussian weight to backprop amplitudes. weight_ratio: float, optional for flag_backprop_weight=1: the Gaussian sigma in units of r.max(). flag_energy_spread : int, optional Flag: 0=do not include energy spread effects, 1=do include energy spread effects (the value will be available from the electron beam). """ def __init__(self, K_vertical=1.0, # syned Undulator parameter period_length=0.01, # syned Undulator parameter number_of_periods=100, # syned Undulator parameter 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) code_undul_phot="internal", # code used for far field and backpropagation: 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=Backpropagation (Divergences) distance=100, # distance to the image plane (for far field calculation) srw_range=0.05, # for code_undul_phot="srw" the range factor. srw_resolution=50.0, # for code_undul_phot="srw" the resolution factor. srw_semianalytical=0, # for code_undul_phot="srw" flag to apply the semianalytical phase treatement magnification=0.01, # for code_undul_phot in ["internal", "pysru"]: the magnification factor flag_backprop_recalculate_source=0, # for code_undul_phot in ["internal", "pysru"] and flag_size=2: source reused (0) or recalculated (1) flag_backprop_weight=0, # for code_undul_phot in ["internal", "pysru"] and flag_size=2: apply Gaussian weight to backprop amplitudes weight_ratio=0.5, # for flag_backprop_weight=1: the Gaussian sigma in units of r.max() flag_energy_spread=0, # include (1) or not (0) energy spread effects. Only valid for monochromatoc simulations. ): super().__init__(K_vertical=K_vertical, K_horizontal = 0.0, period_length = period_length, number_of_periods = number_of_periods) # Photon energy scan self._emin = emin # Photon energy scan from energy (in eV) self._emax = emax # Photon energy scan to energy (in eV) # Photon energy scan number of points if emin == emax: self._ng_e = 1 else: self._ng_e = ng_e # 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) 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 # specific parameters self._distance = distance self._srw_range = srw_range self._srw_resolution = srw_resolution self._srw_semianalytical = srw_semianalytical self._magnification = magnification self._flag_backprop_recalculate_source = flag_backprop_recalculate_source self._flag_backprop_weight = flag_backprop_weight self._weight_ratio = weight_ratio self._flag_energy_spread = flag_energy_spread # support text containg name of variable, help text and unit. Will be stored in self._support_dictionary self._add_support_text([ ("emin", "minimum photon energy", "eV" ), ("emax", "maximum photon energy", "eV"), ("ng_e", "number of energy points", ""), ("maxangle", "Maximum radiation semiaperture", "rad"), ("ng_t", "Number of points in angle theta", ""), ("ng_p", "Number of points in angle phi", ""), ("ng_j", "number of points of the electron trajectory", ""), ("flag_emittance", "Use emittance (0=No, 1=Yes)", ""), ("flag_size", "Size philament beam 0=point,1=Gaussian,2=backpropagate Divergences", ""), ("distance", "Distance to far field plane", "m"), ("srw_range", "for SRW (range magnification)", ""), ("srw_resolution", "for SRW (resolution factor)", ""), ("srw_semianalytical", "for SRW (semianalytical treatment of phase)", ""), ("magnification", "for internal/wofry magnification in propagation", ""), ("flag_backprop_recalculate_source", "for internal or pysru/wofry backpropagation: source reused (0) or recalculated (1)", ""), ("flag_backprop_weight", "for internal or pysru/wofry backpropagation: apply Gaussian weight to amplitudes 0=No, 1=Yes", ""), ("weight_ratio", "for flag_backprop_recalculate_source=1, the ratio value sigma/window halfwidth", ""), ("flag_energy_spread", "for monochromatod sources, apply (1) or not (0) electron energy spread correction", ""), ] )
[docs] def get_info(self, debug=False): """ Returns the specific information for the undulator magnetic structure. Returns ------- str """ undulator = self txt = "" txt = "Undulator source\n" txt += "\n" txt += "Input Undulator parameters: \n" txt += " period: %f m\n"%undulator.period_length() txt += " number of periods: %d\n"%undulator.number_of_periods() txt += " K-value: %f\n"%undulator.K_vertical() txt += "Undulator length: %f m\n"%(undulator.period_length()*undulator.number_of_periods()) K_to_B = (2.0 * numpy.pi / undulator.period_length()) * codata.m_e * codata.c / codata.e txt += "Undulator peak magnetic field: %f T\n"%(K_to_B*undulator.K_vertical()) txt += "\nGrids: \n" if undulator.is_monochromatic(): txt += " photon energy %f eV\n"%(undulator._emin) else: txt += " photon energy from %10.3f eV to %10.3f eV\n"%(undulator._emin,undulator._emax) txt += " number of points for the trajectory: %d\n"%(undulator._ng_j) txt += " number of energy points: %d\n"%(undulator._ng_e) txt += " maximum elevation angle: %f urad\n"%(1e6*undulator._maxangle) txt += " number of angular elevation points: %d\n"%(undulator._ng_t) txt += " number of angular azimuthal points: %d\n"%(undulator._ng_p) txt += "\n" txt += "calculation code: %s\n"%undulator.code_undul_phot txt += "\n" txt += "Sampling: \n" if undulator._flag_size == 0: flag = "point" elif undulator._flag_size == 1: flag = "Gaussian" elif undulator._flag_size == 2: flag = "Far field backpropagated" txt += " Photon source size sampling flag: %d (%s)\n"%(undulator._flag_size, flag) return txt
def __script_dict(self): return { "K_vertical" : self.K_vertical(), "period_length" : self.period_length(), "number_of_periods" : self.number_of_periods(), "emin" : self._emin, "emax" : self._emax, "ng_e" : self._ng_e, "maxangle" : self._maxangle, "ng_t" : self._ng_t, "ng_p" : self._ng_p, "ng_j" : self._ng_j, "code_undul_phot" : self.code_undul_phot, "flag_emittance" : self.get_flag_emittance() , "flag_size" : self._flag_size, "distance" : self._distance, "srw_range" : self._srw_range, "srw_resolution" : self._srw_resolution, "srw_semianalytical" : self._srw_semianalytical, "magnification" : self._magnification, "flag_backprop_recalculate_source" : self._flag_backprop_recalculate_source, "flag_backprop_weight" : self._flag_backprop_weight, "weight_ratio" : self._weight_ratio, "flag_energy_spread" : self._flag_energy_spread, }
[docs] def get_flag_emittance(self): """ Returns the flag for considering electron beam emittance. Returns ------- int 0=No, 1=Yes. """ return self._flag_emittance
[docs] def get_number_of_energy_points(self): """ Returns the number of photon energy points. Returns ------- int """ if self.is_monochromatic(): return 1 else: return self._ng_e
[docs] def set_energy_monochromatic(self, emin): """ Sets a single energy line for the source (monochromatic). Parameters ---------- emin : float photon energy in eV. """ self._emin = emin self._emax = emin self._ng_e = 1
[docs] def set_energy_box(self, emin, emax, npoints=None): """ Sets a box for photon energy distribution for the source. Parameters ---------- emin : float minimum photon energy in eV. emax : float maximum photon energy in eV. npoints : int or None, optional Number of points in energy. If None, it does not modify the number of points already stored. """ self._emin = emin self._emax = emax if npoints != None: self._ng_e = npoints
[docs] def set_maxangle(self, maxangle): """ Defines the maximum angle (in rads) for radiation calculations. Parameters ---------- maxangle : float The angle in rads. """ self._maxangle = maxangle
[docs] def get_energy_box(self): """ Returns the limits of photon energy distribution for the source and the number of points. Returns ------- tuple (emin, emax, npoints) """ if self.is_monochromatic(): return self._emin, self._emin, 1 else: return self._emin, self._emax, self._ng_e
[docs] def is_monochromatic(self): """ Returns a flag indicating if the source is monochromatic (True) or polychromatic (False). Returns ------- boolean """ if self._ng_e == 1: return True if self._emax == self._emin: return True return False
[docs] def to_python_code(self): """ Returns the python code for defining the wiggler magnetic structure. Returns ------- str The python code. """ script_template = """ # magnetic structure from shadow4.sources.undulator.s4_undulator import S4Undulator source = S4Undulator( K_vertical = {K_vertical}, # syned Undulator parameter period_length = {period_length}, # syned Undulator parameter number_of_periods = {number_of_periods}, # syned Undulator parameter emin = {emin}, # Photon energy scan from energy (in eV) emax = {emax}, # Photon energy scan to energy (in eV) ng_e = {ng_e}, # Photon energy scan number of points maxangle = {maxangle}, # Maximum radiation semiaperture in RADIANS ng_t = {ng_t}, # Number of points in angle theta ng_p = {ng_p}, # Number of points in angle phi ng_j = {ng_j}, # Number of points in electron trajectory (per period) for internal calculation only code_undul_phot = '{code_undul_phot}', # internal, pysru, srw flag_emittance = {flag_emittance}, # when sampling rays: Use emittance (0=No, 1=Yes) flag_size = {flag_size}, # when sampling rays: 0=point,1=Gaussian,2=FT(Divergences) distance = {distance}, # distance to far field plane srw_range = {srw_range}, # for SRW backpropagation, the range factor srw_resolution = {srw_resolution}, # for SRW backpropagation, the resolution factor srw_semianalytical= {srw_semianalytical}, # for SRW backpropagation, use semianalytical treatement of phase magnification = {magnification}, # for internal/wofry backpropagation, the magnification factor flag_backprop_recalculate_source = {flag_backprop_recalculate_source}, # for internal or pysru/wofry backpropagation: source reused (0) or recalculated (1) flag_backprop_weight = {flag_backprop_weight}, # for internal or pysru/wofry backpropagation: apply Gaussian weight to amplitudes weight_ratio = {weight_ratio}, # for flag_backprop_recalculate_source=1, the ratio value sigma/window halfwidth flag_energy_spread = {flag_energy_spread}, # for monochromatod sources, apply (1) or not (0) electron energy spread correction )""" script = script_template.format_map(self.__script_dict()) return script
if __name__ == "__main__": u = S4Undulator() # print(u.info()) print(u.get_info()) # print(u.to_python_code())