Source code for shadow4.beamline.optical_elements.crystals.s4_hyperboloid_crystal

"""
The s4 hyperboloid crystal (optical element and beamline element).
"""
from syned.beamline.element_coordinates import ElementCoordinates

from shadow4.beam.s4_beam import S4Beam
from shadow4.beamline.optical_elements.crystals.s4_crystal import S4CrystalElement, S4Crystal
from shadow4.beamline.s4_optical_element_decorators import SurfaceCalculation, S4HyperboloidOpticalElementDecorator
from shadow4.beamline.s4_beamline_element_movements import S4BeamlineElementMovements

from syned.beamline.shape import Hyperboloid, HyperbolicCylinder, Convexity, Direction

[docs]class S4HyperboloidCrystal(S4Crystal, S4HyperboloidOpticalElementDecorator): """ Shadow4 Hyperboloid Crystal Class This is a spherically curved perfect crystal in reflection geometry (Bragg), using the diffracted beam. Constructor. Parameters ---------- name : str, optional A name for the crystal boundary_shape : instance of BoundaryShape, optional The information on the crystal boundaries. is_cylinder : int, optional Flag to indicate that the surface has cylindrical symmetry (it is flat in one direction). cylinder_direction : int, optional For is_cylinder=1, the direction where the surface is flat. Use synedDirection.TANGENTIAL (0) or Direction.SAGITTAL (1). convexity : int, optional The surface is concave (0) or convex (1). Use syned Convexity.UPWARD (0) for concave or Convexity.DOWNWARD (1). min_axis : float, optional The hyperbola/hyperboloid minor axis. maj_axis : float, optional The hyperbola/hyperboloid major axis. pole_to_focus : float, optional The distance from focus 1 (locus of the source) to the crystal pole. material : str, optional The crystal material name (a name accepted by crystalpy). miller_index_h : int, optional The Miller index H. miller_index_k : int, optional The Miller index K. miller_index_l : int, optional The Miller index L. f_bragg_a : int, optional Asymmetric crystal 0:No, 1:Yes. asymmetry_angle : float, optional For f_bragg_a=1, the asymmetry angle (angle between crystal planes and surface) in rads. is_thick : int, optional Use thick crystal approximation. thickness : float, optional For is_thick=0, the crystal thickness in m. f_central : int, optional Flag for autosetting the crystal to the corrected Bragg angle. f_phot_cent : int, optional 0: setting photon energy in eV, 1:setting photon wavelength in m. phot_cent : float, optional for f_central=1, the value of the photon energy (f_phot_cent=0) or photon wavelength (f_phot_cent=1). f_ext : inf, optional Flag for autosetting the crystal surface parameters. 0: internal/calculated parameters, 1:external/user defined parameters. TODO: delete? material_constants_library_flag : int, optional Flag for indicating the origin of the crystal data: 0: xraylib, 1: dabax, 2: preprocessor file v1, 3: preprocessor file v2. file_refl : str, optional for material_constants_library_flag=2,3, the name of the file containing the crystal parameters. dabax : None or instance of DabaxXraylib, The pointer to the dabax library (used for material_constants_library_flag=1). Returns ------- instance of S4HyperboloidCrystal. """ def __init__(self, name="Hyperboloid crystal", boundary_shape=None, material=None, # diffraction_geometry=DiffractionGeometry.BRAGG, # ?? not supposed to be in syned... miller_index_h=1, miller_index_k=1, miller_index_l=1, asymmetry_angle=0.0, is_thick=0, thickness=0.010, f_central=False, f_phot_cent=0, phot_cent=8000.0, file_refl="", f_bragg_a=False, f_ext=0, material_constants_library_flag=0, # 0=xraylib, 1=dabax # 2=shadow preprocessor file v1 # 3=shadow preprocessor file v2 min_axis=0.0, maj_axis=0.0, pole_to_focus=0.0, # for external calculation is_cylinder=False, cylinder_direction=Direction.TANGENTIAL, convexity=Convexity.UPWARD, dabax=None, ): p_focus, q_focus, grazing_angle = 1.0, 1.0, 1e-3 S4HyperboloidOpticalElementDecorator.__init__(self, SurfaceCalculation.EXTERNAL, is_cylinder, cylinder_direction, convexity, min_axis, maj_axis, pole_to_focus, p_focus, q_focus, grazing_angle) S4Crystal.__init__(self, name=name, boundary_shape=boundary_shape, surface_shape=self.get_surface_shape_instance(), material=material, # diffraction_geometry=diffraction_geometry, # ?? not supposed to be in syned... miller_index_h=miller_index_h, miller_index_k=miller_index_k, miller_index_l=miller_index_l, asymmetry_angle=asymmetry_angle, is_thick=is_thick, thickness=thickness, f_central=f_central, f_phot_cent=f_phot_cent, phot_cent=phot_cent, file_refl=file_refl, f_bragg_a=f_bragg_a, f_ext=f_ext, material_constants_library_flag=material_constants_library_flag, dabax=dabax, ) self.__inputs = { "name": name, "boundary_shape": boundary_shape, "material": material, # "diffraction_geometry": diffraction_geometry, "miller_index_h": miller_index_h, "miller_index_k": miller_index_k, "miller_index_l": miller_index_l, "asymmetry_angle": asymmetry_angle, "is_thick": is_thick, "thickness": thickness, "f_central": f_central, "f_phot_cent": f_phot_cent, "phot_cent": phot_cent, "file_refl": file_refl, "f_bragg_a": f_bragg_a, "f_ext": f_ext, "material_constants_library_flag": material_constants_library_flag, "min_axis": min_axis, "maj_axis": maj_axis, "pole_to_focus": pole_to_focus, "is_cylinder": is_cylinder, "cylinder_direction": cylinder_direction, "convexity": convexity, "dabax": self._get_dabax_txt(), }
[docs] def to_python_code(self, **kwargs): """ Creates the python code for defining the element. Parameters ---------- **kwargs Returns ------- str Python code. """ txt = self.to_python_code_boundary_shape() txt_pre = """ from shadow4.beamline.optical_elements.crystals.s4_hyperboloid_crystal import S4HyperboloidCrystal optical_element = S4HyperboloidCrystal(name='{name}', boundary_shape=boundary_shape, material='{material}', miller_index_h={miller_index_h}, miller_index_k={miller_index_k}, miller_index_l={miller_index_l}, f_bragg_a={f_bragg_a}, asymmetry_angle={asymmetry_angle}, is_thick={is_thick}, thickness={thickness}, f_central={f_central}, f_phot_cent={f_phot_cent}, phot_cent={phot_cent}, file_refl='{file_refl}', f_ext={f_ext}, material_constants_library_flag={material_constants_library_flag}, # 0=xraylib,1=dabax,2=preprocessor v1,3=preprocessor v2 min_axis={min_axis:f}, maj_axis={maj_axis:f}, pole_to_focus={pole_to_focus:f}, is_cylinder={is_cylinder:d}, cylinder_direction={cylinder_direction:d}, convexity={convexity:d}, dabax={dabax}, # used when material_constants_library_flag=1 )""" txt += txt_pre.format(**self.__inputs) return txt
[docs]class S4HyperboloidCrystalElement(S4CrystalElement): """ The Shadow4 hyperboloid crystal element. It is made of a S4HyperboloidCrystal and an ElementCoordinates instance. It also includes the input beam. Constructor. Parameters ---------- optical_element : instance of OpticalElement, optional The syned optical element. coordinates : instance of ElementCoordinates, optional The syned element coordinates. movements : instance of S4BeamlineElementMovements, optional The S4 element movements. input_beam : instance of S4Beam, optional The S4 incident beam. """ def __init__(self, optical_element : S4HyperboloidCrystal = None, coordinates : ElementCoordinates = None, movements: S4BeamlineElementMovements = None, input_beam : S4Beam = None): super().__init__(optical_element=optical_element if optical_element is not None else S4HyperboloidCrystal(), coordinates=coordinates if coordinates is not None else ElementCoordinates(), movements=movements, input_beam=input_beam) if not (isinstance(self.get_optical_element().get_surface_shape(), HyperbolicCylinder) or isinstance(self.get_optical_element().get_surface_shape(), Hyperboloid)): raise ValueError("Wrong Optical Element: only Hyperboloid or Hyperbolic Cylinder shape is accepted")
[docs] def to_python_code(self, **kwargs): """ Creates the python code for defining the element. Parameters ---------- **kwargs Returns ------- str Python code. """ txt = "\n\n# optical element number XX" txt += self.get_optical_element().to_python_code() txt += self.to_python_code_coordinates() txt += self.to_python_code_movements() txt += "\nfrom shadow4.beamline.optical_elements.crystals.s4_hyperboloid_crystal import S4HyperboloidCrystalElement" txt += "\nbeamline_element = S4HyperboloidCrystalElement(optical_element=optical_element, coordinates=coordinates, movements=movements, input_beam=beam)" txt += "\n\nbeam, footprint = beamline_element.trace_beam()" return txt
if __name__ == "__main__": c = S4HyperboloidCrystal( name="Undefined", boundary_shape=None, material="Si", # diffraction_geometry=DiffractionGeometry.BRAGG, #?? not supposed to be in syned... miller_index_h=1, miller_index_k=1, miller_index_l=1, asymmetry_angle=0.0, thickness=0.010, f_central=False, f_phot_cent=0, phot_cent=8000.0, file_refl="", f_bragg_a=False, f_ext=0,) # print(c.info()) # print(c.to_python_code()) ce = S4HyperboloidCrystalElement(optical_element=c) print(ce.info()) print(ce.to_python_code()) cc = S4HyperboloidCrystalElement()