"""
The s4 conic 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, S4ConicOpticalElementDecorator
from shadow4.beamline.s4_beamline_element_movements import S4BeamlineElementMovements
from syned.beamline.shape import Conic, Convexity, Direction
[docs]class S4ConicCrystal(S4Crystal, S4ConicOpticalElementDecorator):
"""
Shadow4 Conic 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.
conic_coefficients : list, optional
The list with the 10 conic coefficients.
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 S4ConicCrystal.
"""
def __init__(self,
name="Conic crystal",
boundary_shape=None,
conic_coefficients=[0.0] * 10,
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
dabax=None,
):
S4ConicOpticalElementDecorator.__init__(self, conic_coefficients)
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,
"conic_coefficients": repr(conic_coefficients),
"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,
"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_conic_crystal import S4ConicCrystal
optical_element = S4ConicCrystal(name='{name}',
boundary_shape=boundary_shape,
conic_coefficients={conic_coefficients:s},
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
dabax={dabax}, # used when material_constants_library_flag=1,
)"""
txt += txt_pre.format(**self.__inputs)
return txt
[docs]class S4ConicCrystalElement(S4CrystalElement):
"""
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 : S4ConicCrystal = None,
coordinates : ElementCoordinates = None,
movements: S4BeamlineElementMovements = None,
input_beam : S4Beam = None):
super().__init__(optical_element=optical_element if optical_element is not None else S4ConicCrystal(),
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(), Conic)):
raise ValueError("Wrong Optical Element: only Conic 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_conic_crystal import S4ConicCrystalElement"
txt += "\nbeamline_element = S4ConicCrystalElement(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 = S4ConicCrystal(
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 = S4ConicCrystalElement(optical_element=c)
print(ce.info())
print(ce.to_python_code())
cc = S4ConicCrystalElement()