Source code for shadow4.beamline.optical_elements.gratings.s4_hyperboloid_grating

"""
The s4 hyperboloid grating (optical element and beamline element).
"""
import numpy

from syned.beamline.shape import Convexity, Direction

from shadow4.beam.s4_beam import S4Beam
from shadow4.beamline.s4_optical_element_decorators import SurfaceCalculation, S4HyperboloidOpticalElementDecorator
from shadow4.beamline.optical_elements.gratings.s4_grating import S4GratingElement, S4Grating, ElementCoordinates
from shadow4.beamline.s4_beamline_element_movements import S4BeamlineElementMovements


[docs]class S4HyperboloidGrating(S4Grating, S4HyperboloidOpticalElementDecorator): """ 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: 0=No (there is revolution symmetry along Y) 1=Yes (flat surface along X or Y). cylinder_direction : int (as defined by Direction), optional NONE = -1, UPWARD = 0, DOWNWARD = 1. convexity : int (as defined by Convexity), optional NONE = -1, UPWARD = 0, DOWNWARD = 1. min_axis : float, optional For surface_calculation=0, The minor axis of the hyperboloid (2a). maj_axis : float, optional For surface_calculation=0, The major axis of the hyperboloid (2b) pole_to_focus : float, optional For surface_calculation=0, the p or q distance (from focus to center of the optical element). ruling : float, optional The constant term of the ruling in lines/m. ruling_coeff_linear : float, optional The linear term of the ruling in lines/m^2. ruling_coeff_quadratic : float, optional The quadratic term of the ruling in lines/m^3. ruling_coeff_cubic : float, optional The cubic term of the ruling in lines/m^4. ruling_coeff_quartic : float, optional The quartic term of the ruling in lines/m^5. coating : str, optional The identified if the coating material (not used, passed to syned). coating_thickness : float, optional The thickness of the coating in m (not used, passed to syned). order : int, optional The diffraction order. f_ruling : int, optional A flag to define the type of ruling: - (0) constant on X-Y plane (0) - (1) polynomial line density (5 in shadow3). Returns ------- instance of S4HyperboloidGrating. """ def __init__(self, name="Hyperboloid Grating", boundary_shape=None, ruling=800e3, ruling_coeff_linear=0.0, ruling_coeff_quadratic=0.0, ruling_coeff_cubic=0.0, ruling_coeff_quartic=0.0, coating=None, coating_thickness=None, order=0, f_ruling=0, # 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.DOWNWARD, ): 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) S4Grating.__init__(self, name=name, surface_shape=self.get_surface_shape_instance(), boundary_shape=boundary_shape, ruling=ruling, ruling_coeff_linear=ruling_coeff_linear, ruling_coeff_quadratic=ruling_coeff_quadratic, ruling_coeff_cubic=ruling_coeff_cubic, ruling_coeff_quartic=ruling_coeff_quartic, coating=coating, coating_thickness=coating_thickness, order=order, f_ruling=f_ruling, ) self.__inputs = { "name": name, # "surface_shape": surface_shape, "boundary_shape": boundary_shape, "ruling": ruling, "ruling_coeff_linear": ruling_coeff_linear, "ruling_coeff_quadratic": ruling_coeff_quadratic, "ruling_coeff_cubic": ruling_coeff_cubic, "ruling_coeff_quartic": ruling_coeff_quartic, "order": order, "f_ruling": f_ruling, "min_axis": min_axis, "maj_axis": maj_axis, "pole_to_focus": pole_to_focus, "is_cylinder": is_cylinder, "cylinder_direction": cylinder_direction, "convexity": convexity, }
[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 += "\nfrom shadow4.beamline.optical_elements.gratings.s4_hyperboloid_grating import S4HyperboloidGrating" txt_pre = """\noptical_element = S4HyperboloidGrating(name='{name}', boundary_shape=None, f_ruling={f_ruling}, order={order}, ruling={ruling}, ruling_coeff_linear={ruling_coeff_linear}, ruling_coeff_quadratic={ruling_coeff_quadratic}, ruling_coeff_cubic={ruling_coeff_cubic}, ruling_coeff_quartic={ruling_coeff_quartic}, 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}, )""" txt += txt_pre.format(**self.__inputs) return txt
[docs]class S4HyperboloidGratingElement(S4GratingElement): """ 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 : S4HyperboloidGrating = None, coordinates : ElementCoordinates = None, movements: S4BeamlineElementMovements = None, input_beam : S4Beam = None): super().__init__(optical_element=optical_element if optical_element is not None else S4HyperboloidGrating(), coordinates=coordinates if coordinates is not None else ElementCoordinates(), movements=movements, input_beam=input_beam)
[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.gratings.s4_hyperboloid_grating import S4HyperboloidGratingElement" txt += "\nbeamline_element = S4HyperboloidGratingElement(optical_element=optical_element, coordinates=coordinates, movements=movements, input_beam=beam)" txt += "\n\nbeam, footprint = beamline_element.trace_beam()" return txt
# def apply_grating_diffraction(self, beam): # return self.get_optical_element().apply_grating_diffraction(beam) if __name__ == "__main__": from shadow4.sources.source_geometrical.source_geometrical import SourceGeometrical from shadow4.tools.graphics import plotxy # # source # src = SourceGeometrical(spatial_type="Point", angular_distribution = "Flat", energy_distribution = "Uniform", nrays = 5000, ) src.set_angular_distribution_flat(0,0,0,0) src.set_energy_distribution_uniform(value_min=999.8,value_max=1000.2,unit='eV') # print(src.info()) beam = src.get_beam() print(beam.info()) # plotxy(Beam3.initialize_from_shadow4_beam(beam),1,3,nbins=100,title="SOURCE") # # grating # g = S4HyperboloidGrating( name = "my_grating", boundary_shape = None, # BoundaryShape(), ruling = 800.0e3, ruling_coeff_linear = 0, ruling_coeff_quadratic = 0, ruling_coeff_cubic = 0, ruling_coeff_quartic = 0, coating = None, coating_thickness = None, order=1, maj_axis=20.0, min_axis=0.418848, pole_to_focus=10.0 ) coordinates_syned = ElementCoordinates(p = 30.0, q = 9.93427, angle_radial = 87.29533343 * numpy.pi / 180, angle_radial_out= 89.10466657 * numpy.pi / 180, angle_azimuthal = 0.0) ge = S4HyperboloidGratingElement(optical_element=g, coordinates=coordinates_syned, input_beam=beam) print(ge.info()) beam_out = ge.trace_beam() plotxy(beam_out[0], 1, 3, title="Image 0", nbins=201) s4 = S4HyperboloidGrating() print(ge.to_python_code())