"""
The s4 conic 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, S4ConicOpticalElementDecorator
from shadow4.beamline.optical_elements.gratings.s4_grating import S4GratingElement, S4Grating, ElementCoordinates
from shadow4.beamline.s4_beamline_element_movements import S4BeamlineElementMovements
[docs]class S4ConicGrating(S4Grating, S4ConicOpticalElementDecorator):
"""
Constructor.
Parameters
----------
name : str, optional
A name for the crystal
boundary_shape : instance of BoundaryShape, optional
The information on the crystal boundaries.
conic_coefficients : list, ndarray, optional
The list of the 10 conic coefficients.
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 S4ConicGrating.
"""
def __init__(self,
name="Conic 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,
#
conic_coefficients=None,
):
if conic_coefficients is None: conic_coefficients = [0,0,0,0,0,0,0,0,-1,0]
S4ConicOpticalElementDecorator.__init__(self, conic_coefficients)
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,
"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,
"conic_coefficients": repr(conic_coefficients),
}
[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_conic_grating import S4ConicGrating"
txt_pre = """\noptical_element = S4ConicGrating(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},
conic_coefficients={conic_coefficients:s},
)"""
txt += txt_pre.format(**self.__inputs)
return txt
[docs]class S4ConicGratingElement(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 : S4ConicGrating = None,
coordinates : ElementCoordinates = None,
movements: S4BeamlineElementMovements = None,
input_beam : S4Beam = None):
super().__init__(optical_element=optical_element if optical_element is not None else S4ConicGrating(),
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_conic_grating import S4ConicGratingElement"
txt += "\nbeamline_element = S4ConicGratingElement(optical_element=optical_element, coordinates=coordinates, movements=movements, input_beam=beam)"
txt += "\n\nbeam, footprint = beamline_element.trace_beam()"
return txt
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 = S4ConicGrating(
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,
conic_coefficients=[0,0,0,0,0,0,0,0,-1,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 = S4ConicGratingElement(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 = S4ConicGrating()
print(ge.to_python_code())