"""
The s4 numerical mesh refractive interface (optical element and beamline element).
"""
import numpy
from syned.beamline.shape import Convexity, Direction
from syned.beamline.element_coordinates import ElementCoordinates
from dabax.dabax_xraylib import DabaxXraylib
from shadow4.beam.s4_beam import S4Beam
from shadow4.beamline.s4_optical_element_decorators import SurfaceCalculation, S4NumericalMeshOpticalElementDecorator
from shadow4.beamline.optical_elements.refractors.s4_interface import S4InterfaceElement, S4Interface
from shadow4.beamline.s4_beamline_element_movements import S4BeamlineElementMovements
[docs]class S4NumericalMeshInterface(S4Interface, S4NumericalMeshOpticalElementDecorator):
"""
Constructor.
Parameters
----------
name : str, optional
The name of the refractive interface.
boundary_shape : instance of BoundaryShape, optional
The boundary shape of the refractive interface.
xx : ndarray, optional
the 1D array with the X points.
yy : ndarray, optional
the 1D array with the Y points.
zz : ndarray, optional
the 2D [shape Nx,Ny] array with the Z points.
surface_data_file : str, optional
the name of the h5 file with the mesh.
surface_shape : instance of SurfaceShape, optional
The surface shape of the refractive interface.
material_object : str, optional
string with material symbol or formula (used when f_r_ind>3).
material_image : str, optional
string with material symbol or formula (used when f_r_ind>3).
density_object : float, optional
density for material_object (used when f_r_ind>3).
density_image : float, optional
density for material_image (used when f_r_ind>3).
f_r_ind : int, optional
source of optical constants, from constant value or PREREFL preprocessor (file):
- (0) constant value in both object and image spaces,
- (1) file in object space, constant value in image space,
- (2) constant value in object space, file in image space,
- (3) file in both object and image space.
- (4) xraylib in object space, constant value in image space,
- (5) constant value in object space, xraylib in image space,
- (6) xraylib in both object and image space.
- (7) dabax in object space, constant value in image space,
- (8) constant value in object space, dabax in image space,
- (9) dabax in both object and image space.
r_ind_obj : float or numpy array
(for f_r_ind=0,2): index of refraction (real) in object space.
r_ind_ima : float or numpy array
(for f_r_ind=0,1): index of refraction (real) in image space.
r_attenuation_obj : float or numpy array
(for f_r_ind=0,2): attenuation coefficient in object space. Units of m^(-1)
r_attenuation_ima : float or numpy array
(for f_r_ind=0,1): attenuation coefficient in image space. Units of m^(-1)
file_r_ind_obj : str, optional
(for f_r_ind=1,3): file generated by PREREFL preprocessor.
file_r_ind_ima : str, optional
(for f_r_ind=2,3): file generated by PREREFL preprocessor.
dabax : None or instance of DabaxXraylib,
The pointer to the dabax library (used for f_r_ind > 6).
Returns
-------
instance of S4NumericalMeshInterface.
"""
def __init__(self,
name="Undefined",
boundary_shape=None,
surface_shape=None,
material_object="",
material_image="",
density_object=1.0,
density_image=1.0,
f_r_ind = 0,
r_ind_obj = 1.0,
r_ind_ima = 1.0,
r_attenuation_obj = 0.0,
r_attenuation_ima = 0.0,
file_r_ind_obj = "",
file_r_ind_ima = "",
dabax=None,
#
xx=None,
yy=None,
zz=None,
surface_data_file="",
):
S4NumericalMeshOpticalElementDecorator.__init__(self, xx, yy, zz, surface_data_file)
S4Interface.__init__(self,
name=name,
boundary_shape=boundary_shape,
surface_shape=self.get_surface_shape_instance(),
material_object=material_object,
material_image=material_image,
density_object=density_object,
density_image=density_image,
f_r_ind=f_r_ind,
r_ind_obj=r_ind_obj,
r_ind_ima=r_ind_ima,
r_attenuation_obj=r_attenuation_obj,
r_attenuation_ima=r_attenuation_ima,
file_r_ind_obj=file_r_ind_obj,
file_r_ind_ima=file_r_ind_ima,
dabax=dabax,
)
if f_r_ind > 6:
if isinstance(dabax, DabaxXraylib):
dabax_txt = 'DabaxXraylib(file_f1f2="%s", file_CrossSec="%s")' % \
(dabax.get_file_f1f2(), dabax.get_file_CrossSec())
else:
dabax_txt = 'DabaxXraylib()'
else:
dabax_txt = "None"
self.__inputs = {
"name": name,
"boundary_shape": boundary_shape,
"xx": xx,
"yy": yy,
"zz": zz,
"surface_data_file": surface_data_file,
"material_object": material_object,
"material_image": material_image,
"density_object": density_object,
"density_image": density_image,
"f_r_ind": f_r_ind,
"r_ind_obj": r_ind_obj,
"r_ind_ima": r_ind_ima,
"r_attenuation_obj": r_attenuation_obj,
"r_attenuation_ima": r_attenuation_ima,
"file_r_ind_obj": file_r_ind_obj,
"file_r_ind_ima": file_r_ind_ima,
"dabax": dabax_txt,
"xx": xx,
"yy": yy,
"zz": zz,
"surface_data_file": surface_data_file,
}
[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.refractors.s4_numerical_mesh_interface import S4NumericalMeshInterface
optical_element = S4NumericalMeshInterface(name='{name:s}',
boundary_shape=boundary_shape,
xx=None, yy=None, zz=None, surface_data_file='{surface_data_file:s}',
f_r_ind={f_r_ind:g}, # source of optical constants:
# (0) cte in both object (O) and image (I) spaces,
# (1) file in O, cte in I, (2) cte in O, file in I, (3) file in O and I
# (4) xraylib in O, cte in I, (5) cte O, xraylib in I, (6) xraylib in O and I
# (7) dabax O, cte in I, (8) cte value in O, dabax in I, (9) dabax in O and I
material_object='{material_object:s}', material_image='{material_image:s}',
density_object={density_object:g}, density_image={density_image:g},
r_ind_obj={r_ind_obj:g}, r_ind_ima={r_ind_ima:g},
r_attenuation_obj={r_attenuation_obj:g}, r_attenuation_ima={r_attenuation_ima:g},
file_r_ind_obj='{file_r_ind_obj:s}', file_r_ind_ima='{file_r_ind_ima:s}',
dabax={dabax}, # if using dabax (f_r_ind > 6), instance of DabaxXraylib() (use None for default)
)
"""
txt += txt_pre.format(**self.__inputs)
return txt
[docs]class S4NumericalMeshInterfaceElement(S4InterfaceElement):
"""
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 : S4NumericalMeshInterface = None,
coordinates : ElementCoordinates = None,
movements: S4BeamlineElementMovements = None,
input_beam : S4Beam = None):
super().__init__(optical_element=optical_element if optical_element is not None else S4NumericalMeshInterface(),
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 += "\nbeamline_element = S4NumericalMeshInterfaceElement(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 = S4NumericalMeshInterface(
name = "my_numerical_mesh_interface",
boundary_shape = None, # BoundaryShape(),
surface_data_file="/users/srio/Oasys/bump.h5",
#
)
# print(g.info())
coordinates_syned = ElementCoordinates(p = 30.0,
q = 10,
angle_radial = 0,
angle_radial_out= numpy.pi,
angle_azimuthal = 0.0)
ge = S4NumericalMeshInterfaceElement(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 = S4NumericalMeshInterface()
print(ge.to_python_code())