Source code for shadow4.beamline.s4_beamline

"""
Defines the S4 beamline.

As a reminder, and following the SYNED philosophy, the S4 beamline is a container of the S4 light source and a
list of S4 beamline elements.

"""
from syned.beamline.beamline import Beamline
from shadow4.beamline.s4_beamline_element import S4BeamlineElement
import numpy

from shadow4.beamline.optical_elements.ideal_elements.s4_empty import S4Empty
from shadow4.beamline.optical_elements.mirrors.s4_mirror import S4Mirror
from shadow4.beamline.optical_elements.crystals.s4_crystal import S4Crystal
from shadow4.beamline.optical_elements.gratings.s4_grating import S4Grating
from shadow4.beamline.optical_elements.multilayers.s4_multilayer import S4Multilayer
from shadow4.beamline.optical_elements.refractors.s4_lens import S4Lens
from shadow4.beamline.optical_elements.refractors.s4_transfocator import S4Transfocator
from shadow4.beamline.optical_elements.refractors.s4_crl import S4CRL
from shadow4.beamline.optical_elements.absorbers.s4_screen import S4Screen
from shadow4.beamline.optical_elements.compound.s4_compound import S4Compound




[docs]class S4Beamline(Beamline): """ Constructor. Parameters ---------- light_source : instance of LightSource The light source beamline_elements_list : list The beamline elements (each one an instance of S4BeamlineElement). """ def __init__(self, light_source=None, beamline_elements_list=None): super().__init__(light_source=light_source, beamline_elements_list=beamline_elements_list)
[docs] def duplicate(self): """ Returns a copy of the S4 beamline instance. Returns ------- S4BeamlineElement instance A copy of the object instance. """ if self.get_beamline_elements_number() == 0: beamline_elements_list = None else: beamline_elements_list = [] for beamline_element in self._beamline_elements_list: beamline_elements_list.append(beamline_element.duplicate()) return S4Beamline(light_source=self._light_source, beamline_elements_list = beamline_elements_list)
[docs] def append_beamline_element(self, beamline_element: S4BeamlineElement): """ Appends a S4 beamline element. Parameters ---------- beamline_element : instance of S4BeamlineElement. The beamline element to append. """ self._beamline_elements_list.append(beamline_element)
[docs] def to_python_code(self, **kwargs): """ Returns the python code to create the beamline. Parameters ---------- partial_code: int set to 0: returns full beamline (default), 1: returns only source, 2: returns only beamline elements. **kwargs Passed arguments. Returns ------- str The python code. """ partial_code = kwargs.get('partial_code', 0) # default to 0 script = "import numpy as np" script += "\nfrom dabax.dabax_xraylib import DabaxXraylib" script += "\nfrom shadow4.beamline.s4_beamline import S4Beamline" script += "\n\nbeamline = S4Beamline()\n" if partial_code in [0,1]: try: script += self.get_light_source().to_python_code() script += "\n\nbeamline.set_light_source(light_source)" except: script += "\n\n\n# Error getting python code for S4Beamline S4LightSource " if partial_code == 1: return script for i,element in enumerate(self.get_beamline_elements()): try: script += element.to_python_code() script += "\n\nbeamline.append_beamline_element(beamline_element)" except: script += "\n\n\n# Error getting python code for S4Beamline S4BeamlineElement # %d :" % (i+1) script += "\n# %s " % (str(element)) return script
[docs] def run_beamline(self, **params): """ Runs (performs the ray tracing) of the full beamline. Parameters ---------- **params Passed params. Returns ------- tuple (output_beam, output_mirr) the traced beam and footprint (after the last beamline element). """ try: output_beam = self.get_light_source().get_beam(**params) output_mirr = None except: raise Exception("Error running beamline light source") for i, element in enumerate(self.get_beamline_elements()): try: element.set_input_beam(output_beam) output_beam, output_mirr = element.trace_beam(**params) except: raise Exception("Error running beamline element # %d" % (i+1) ) return output_beam, output_mirr
def _get_info_coordinates(self, oe_index): coordinates = self.get_beamline_element_at(oe_index).get_coordinates() T_SOURCE, T_IMAGE, T_INCIDENCE, T_REFLECTION, ALPHA = coordinates.get_positions() print(coordinates) txt_coordinates = "" txt_coordinates += "Central Axis parameters : \n" txt_coordinates += "Source Plane Distance %f m\n" % T_SOURCE txt_coordinates += "Image Plane %f m\n" % T_IMAGE txt_coordinates += "Incidence Angle (to normal) %f deg\n" % numpy.degrees(T_INCIDENCE) txt_coordinates += "Reflection/Diffraction Angle (to normal) %f deg\n" % numpy.degrees(T_REFLECTION) txt_coordinates += "Grazing Incidence Angle %f mrad\n" % (1e3 * (numpy.pi / 2 - T_INCIDENCE)) txt_coordinates += "Grazing Reflection/Diffraction Angle %f mrad\n" % (1e3 * (numpy.pi / 2 - T_REFLECTION)) return txt_coordinates
[docs] def sourcinfo(self): """ Returns the source information (sourcinfo in shadow3). Returns ------- str """ from shadow4.sources.source_geometrical.source_grid_cartesian import SourceGridCartesian from shadow4.sources.source_geometrical.source_grid_polar import SourceGridPolar from shadow4.sources.s4_light_source_from_file import S4LightSourceFromFile from shadow4.sources.s4_light_source_from_beamlines import S4LightSourceFromBeamlines light_source = self.get_light_source() txt_source = \ """ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ************** S O U R C E D E S C R I P T I O N ************** +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ """ if isinstance(light_source, SourceGridCartesian): txt_source += "Grid source (cartesian)\n" elif isinstance(light_source, SourceGridPolar): txt_source += "Grid source (polar)\n" elif isinstance(light_source, S4LightSourceFromFile): txt_source += "Source from file\n" elif isinstance(light_source, S4LightSourceFromBeamlines): txt_source += "Source from merging lightsources/beamlines\n" else: txt_source += "Random source\n" try: txt_source += "Generated total %d rays.\n" % light_source.get_nrays() except: pass txt_end = \ """ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *************** E N D *************** +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ """ return txt_source + "\n" + self.get_light_source().get_info() + txt_end
[docs] def oeinfo(self, oe_index=None): """ Returns the optical element(s) information (oeinfo or mirinfo in shadow3). Returns ------- str """ top_txt1 = \ """ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ******************** OPTICAL ELEMENT DESCRIPTION ******************** """ top_txt2 = \ """ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ """ bottom_txt = \ """ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *************** E N D *************** +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ """ if oe_index is None: txt = "" for i, element in enumerate(self.get_beamline_elements()): txt += top_txt1 txt += "O.E. %d (%s)" % (i + 1, element.get_optical_element().get_name()) txt += top_txt2 txt += self._get_info_coordinates(i) txt += element.get_optical_element().get_info() txt += bottom_txt else: txt = "" txt += top_txt1 txt += "O.E. %d (%s)" % (oe_index + 1, self.get_beamline_element_at(oe_index).get_optical_element().get_name()) txt += top_txt2 txt += self._get_info_coordinates(i) txt += self.get_beamline_element_at(oe_index).get_optical_element().get_info() txt += bottom_txt return txt
[docs] def syspositions(self): """ Returns a dictionary with the positions of the source, o.e. and images. Returns ------- dict dict["source"] numpy array (icoor) with the three coordinates of source dict["source"] numpy array (n_oe,icoor) with the three coordinates of optical elements for all elements dict["source"] numpy array (n_oe,icoor) with the three coordinates of image positions for all elements dict["optical_axis_x"] numpy array with the x coordinates of the optical axis dict["optical_axis_y"] numpy array with the y coordinates of the optical axis dict["optical_axis_z"] numpy array with the z coordinates of the optical axis """ # # This is a translation of the OPTAXIS routine in shadow3 # CENTRAL = numpy.zeros( (25) ) U_VEC = numpy.zeros( (4) ) V_VEC = numpy.zeros( (4) ) W_VEC = numpy.zeros( (4) ) V_REF = numpy.zeros( (4) ) V_PERP = numpy.zeros( (4) ) n_elements = self.get_beamline_elements_number() mirr = numpy.zeros((3, n_elements)) star = numpy.zeros_like(mirr) for i in range(n_elements): oe = self.get_beamline_element_at(i) coor = oe.get_coordinates() T_SOURCE, T_IMAGE, T_INCIDENCE, T_REFLECTION, ALPHA = coor.get_positions() T_IMAGE += oe.get_optical_element().interthickness() COSAL = numpy.cos(ALPHA) SINAL = numpy.sin(ALPHA) PIHALF = numpy.pi/2 PI = numpy.pi DEFLECTION = T_INCIDENCE + T_REFLECTION if i == 0: U_VEC [1] = COSAL U_VEC [2] = 0.0 U_VEC [3] = SINAL V_VEC [1] = - numpy.sin(PIHALF - T_INCIDENCE)*SINAL V_VEC [2] = numpy.cos(PIHALF - T_INCIDENCE) V_VEC [3] = numpy.sin(PIHALF - T_INCIDENCE)*COSAL W_VEC [1] = - numpy.sin(PI - T_INCIDENCE)*SINAL W_VEC [2] = numpy.cos(PI - T_INCIDENCE) W_VEC [3] = numpy.sin(PI - T_INCIDENCE)*COSAL V_REF [1] = - numpy.sin(PI - DEFLECTION)*SINAL V_REF [2] = numpy.cos(PI - DEFLECTION) V_REF [3] = numpy.sin(PI - DEFLECTION)*COSAL V_PERP [1] = - numpy.sin(3*PIHALF - DEFLECTION)*SINAL V_PERP [2] = numpy.cos(3*PIHALF - DEFLECTION) V_PERP [3] = numpy.sin(3*PIHALF - DEFLECTION)*COSAL CENTRAL[1] = .0 CENTRAL[2] = .0 CENTRAL[3] = .0 CENTRAL[4] = .0 CENTRAL[5] = T_SOURCE CENTRAL[6] = .0 CENTRAL[7] = T_IMAGE*V_REF[1] CENTRAL[8] = T_IMAGE*V_REF[2] + T_SOURCE CENTRAL[9] = T_IMAGE*V_REF[3] CENTRAL[10] = U_VEC[1] CENTRAL[11] = U_VEC[2] CENTRAL[12] = U_VEC[3] CENTRAL[13] = V_VEC[1] CENTRAL[14] = V_VEC[2] CENTRAL[15] = V_VEC[3] CENTRAL[16] = W_VEC[1] CENTRAL[17] = W_VEC[2] CENTRAL[18] = W_VEC[3] CENTRAL[19] = V_REF[1] CENTRAL[20] = V_REF[2] CENTRAL[21] = V_REF[3] CENTRAL[22] = V_PERP[1] CENTRAL[23] = V_PERP[2] CENTRAL[24] = V_PERP[3] source = numpy.zeros(3) source [0] = CENTRAL[1] source [1] = CENTRAL[2] source [2] = CENTRAL[3] else: # ! ** Computes now the OLD mirror reference frame in the lab. coordinates # ! ** system. The rotation angle ALPHA of the current mirror is defined in # ! ** this reference frame, as ALPHA measure the angle between the two # ! ** incidence planes (not necessarily the same). CENTRAL_OLD = CENTRAL.copy() U_OLD = numpy.array( [0.0,CENTRAL[10],CENTRAL[11],CENTRAL[12]]) R_OLD = numpy.array( [0.0,CENTRAL[19],CENTRAL[20],CENTRAL[21]]) RP_OLD = numpy.array( [0.0,CENTRAL[22],CENTRAL[23],CENTRAL[24]]) # ! ** This vector is the NORMAL of the new mirror in the OMRF (U,R_OLD,RP_OLD) ** V_TEMP = numpy.zeros(4) V_TEMP [1] = - numpy.sin(PI - T_INCIDENCE)*SINAL V_TEMP [2] = numpy.cos(PI - T_INCIDENCE) V_TEMP [3] = numpy.sin(PI - T_INCIDENCE)*COSAL # ! ** Rotate it finally to (x,y,z) SRF ** W_VEC [1] = V_TEMP[1]*U_OLD[1] + V_TEMP[2]*R_OLD[1] + V_TEMP[3]*RP_OLD[1] W_VEC [2] = V_TEMP[1]*U_OLD[2] + V_TEMP[2]*R_OLD[2] + V_TEMP[3]*RP_OLD[2] W_VEC [3] = V_TEMP[1]*U_OLD[3] + V_TEMP[2]*R_OLD[3] + V_TEMP[3]*RP_OLD[3] # ! ** This vector is the reflected beam from the new mirror in the OMRF ** V_TEMP[1] = - numpy.sin(PI - DEFLECTION)*SINAL V_TEMP[2] = numpy.cos(PI - DEFLECTION) V_TEMP[3] = numpy.sin(PI - DEFLECTION)*COSAL # ! ** Express it now in the (x,y,z) SRF V_REF[1] = V_TEMP[1] * U_OLD[1] + V_TEMP[2] * R_OLD[1] + V_TEMP[3]*RP_OLD[1] V_REF[2] = V_TEMP[1] * U_OLD[2] + V_TEMP[2] * R_OLD[2] + V_TEMP[3]*RP_OLD[2] V_REF[3] = V_TEMP[1] * U_OLD[3] + V_TEMP[2] * R_OLD[3] + V_TEMP[3]*RP_OLD[3] # ! ** This is now the perp. vector in the OMRF ** V_TEMP[1] = - numpy.sin(3*PIHALF - DEFLECTION)*SINAL V_TEMP[2] = numpy.cos(3*PIHALF - DEFLECTION) V_TEMP[3] = numpy.sin(3*PIHALF - DEFLECTION)*COSAL # ! ** Rotate it to the SRF\ V_PERP[1] = V_TEMP[1]*U_OLD[1] + V_TEMP[2]*R_OLD[1] + V_TEMP[3]*RP_OLD[1] V_PERP[2] = V_TEMP[1]*U_OLD[2] + V_TEMP[2]*R_OLD[2] + V_TEMP[3]*RP_OLD[2] V_PERP[3] = V_TEMP[1]*U_OLD[3] + V_TEMP[2]*R_OLD[3] + V_TEMP[3]*RP_OLD[3] # ! ** This is the tangent vector in the OMRF ** V_TEMP[1] = - numpy.sin(PIHALF - T_INCIDENCE)*SINAL V_TEMP[2] = numpy.cos(PIHALF - T_INCIDENCE) V_TEMP[3] = numpy.sin(PIHALF - T_INCIDENCE)*COSAL # ! ** Rotate it to the SRF. V_VEC[1] = V_TEMP[1] * U_OLD[1] + V_TEMP[2] * R_OLD[1] + V_TEMP[3] * RP_OLD[1] V_VEC[2] = V_TEMP[1] * U_OLD[2] + V_TEMP[2] * R_OLD[2] + V_TEMP[3] * RP_OLD[2] V_VEC[3] = V_TEMP[1] * U_OLD[3] + V_TEMP[2] * R_OLD[3] + V_TEMP[3] * RP_OLD[3] # ! ** Last, we generate U_VEC in the OMRF ** V_TEMP[1] = COSAL V_TEMP[2] = .0 V_TEMP[3] = SINAL # ! ** rotate to SRF U_VEC[1] = V_TEMP[1] * U_OLD[1] + V_TEMP[2] * R_OLD[1] + V_TEMP[3] * RP_OLD[1] U_VEC[2] = V_TEMP[1] * U_OLD[2] + V_TEMP[2] * R_OLD[2] + V_TEMP[3] * RP_OLD[2] U_VEC[3] = V_TEMP[1] * U_OLD[3] + V_TEMP[2] * R_OLD[3] + V_TEMP[3] * RP_OLD[3] # ! ** All done. Write to the array and leave. CENTRAL[1] = CENTRAL_OLD[7] CENTRAL[2] = CENTRAL_OLD[8] CENTRAL[3] = CENTRAL_OLD[9] CENTRAL[4] = T_SOURCE * R_OLD[1] + CENTRAL[1] CENTRAL[5] = T_SOURCE * R_OLD[2] + CENTRAL[2] CENTRAL[6] = T_SOURCE * R_OLD[3] + CENTRAL[3] CENTRAL[7] = T_IMAGE * V_REF[1] + CENTRAL[4] CENTRAL[8] = T_IMAGE * V_REF[2] + CENTRAL[5] CENTRAL[9] = T_IMAGE * V_REF[3] + CENTRAL[6] CENTRAL[10] = U_VEC[1] CENTRAL[11] = U_VEC[2] CENTRAL[12] = U_VEC[3] CENTRAL[13] = V_VEC[1] CENTRAL[14] = V_VEC[2] CENTRAL[15] = V_VEC[3] CENTRAL[16] = W_VEC[1] CENTRAL[17] = W_VEC[2] CENTRAL[18] = W_VEC[3] CENTRAL[19] = V_REF[1] CENTRAL[20] = V_REF[2] CENTRAL[21] = V_REF[3] CENTRAL[22] = V_PERP[1] CENTRAL[23] = V_PERP[2] CENTRAL[24] = V_PERP[3] mirr[0,i] = CENTRAL[4] mirr[1,i] = CENTRAL[5] mirr[2,i] = CENTRAL[6] star[0,i] = CENTRAL[7] star[1,i] = CENTRAL[8] star[2,i] = CENTRAL[9] if n_elements > 0: x = numpy.append(source[0],mirr[0,:]) x = numpy.append(x,star[0,-1]) x = numpy.round(x,10) y = numpy.append(source[1],mirr[1,:]) y = numpy.append(y,star[1,-1]) y = numpy.round(y,10) z = numpy.append(source[2],mirr[2,:]) z = numpy.append(z,star[2,-1]) z = numpy.round(z,10) # print(">>>>>> source: ", source) # print(">>>>>> X", x) return {"source":source, "mirr":mirr, "star":star, "optical_axis_x":x, "optical_axis_y":y, "optical_axis_z":z} else: return {"source": numpy.zeros(3)}
[docs] def sysinfo(self, title="", comment=""): """ Returns the system information (sysinfo in shadow3). Returns ------- str """ txt = "\n" TOPLIN = '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n' TSCR = {} TYPE1 = {} TSCR["1"] = 'AFTER Mirror' TSCR["2"] = 'BEFORE Mirror' TYPE1["1"] = 'SPHERICAL ' TYPE1["2"] = 'ELLIPTICAL ' TYPE1["3"] = 'TOROIDAL ' TYPE1["4"] = 'PARABOLICAL ' TYPE1["5"] = 'PLANE ' TYPE1["6"] = 'CODLING SLIT' TYPE1["7"] = 'HYPERBOLICAL' TYPE1["8"] = 'CONICAL ' TYPE1["9"] = ' ' TYPE1["10"] = ' ' TYPE1["11"] = ' ' TYPE1["12"] = ' ' BREAK =' ----------------\n' txt += TOPLIN txt += '************** S Y S T E M D E S C R I P T I O N **************\n' txt += TOPLIN txt += title + "\n" txt += comment + "\n" txt += TOPLIN n_elements = self.get_beamline_elements_number() for i in range(n_elements): ble = self.get_beamline_element_at(i) coor = ble.get_coordinates() oe = ble.get_optical_element() txt += ' \n' txt += 'Optical Element # %d\n'%(i + 1) if isinstance(oe, S4Empty): TEXT = "EMPTY ELEMENT" elif isinstance(oe, S4Mirror): TEXT = "MIRROR" elif isinstance(oe, S4Crystal): TEXT = "CRYSTAL" elif isinstance(oe, S4Grating): TEXT = "GRATING" elif isinstance(oe, S4Multilayer): TEXT = "MULTILAYER" elif isinstance(oe, S4Lens): TEXT = "LENS" elif isinstance(oe, S4CRL): TEXT = "COMPOUND REFRACTIVE LENS" elif isinstance(oe, S4Transfocator): TEXT = "TRANSFOCATOR" elif isinstance(oe, S4Screen): TEXT = "SCREEN/SLIT/ABSORBER" elif isinstance(oe, S4Compound): TEXT = "COMPOUND" else: TEXT = "*** Error: NOT IDENTIFIED OE %s ***" % repr(oe) T_SOURCE, T_IMAGE, T_INCIDENCE, T_REFLECTION, ALPHA = coor.get_positions() txt += '\n' txt += TEXT+"\n" txt += '\n' txt += ' Orientation %f deg\n' %(numpy.degrees(ALPHA)) txt += ' Source Plane %f m \n' %(T_SOURCE) txt += ' Incidence Ang. %f deg (grazing: %f mrad)\n' %( numpy.degrees(T_INCIDENCE), (numpy.pi / 2 - T_INCIDENCE) * 1e3) txt += ' Reflection Ang. %f deg (grazing: %f mrad)\n' %( numpy.degrees(T_REFLECTION),(numpy.pi / 2 - T_REFLECTION) * 1e3) txt += ' Image Plane %f m \n' %(T_IMAGE) txt += ' O.E. (inter) thickness %f m \n' % (oe.interthickness()) txt += BREAK txt += "\n\n OPTICAL SYSTEM CONFIGURATION\n" txt += " Laboratory Reference Frame.\n" txt += "OPT. Elem # X = Y = Z =\n\n" dic = self.syspositions() txt += " 0 %18.11f %18.11f %18.11f\n"%(dic["source"][0],dic["source"][1],dic["source"][2]) for i in range(n_elements): txt += " %d %18.11f %18.11f %18.11f\n"%( i+1,dic["mirr"][0,i],dic["mirr"][1,i],dic["mirr"][2,i]) txt += " %d' %18.11f %18.11f %18.11f\n"%(i+1,dic["star"][0,i],dic["star"][1,i],dic["star"][2,i]) txt += TOPLIN txt += '******** E N D ***************\n' txt += TOPLIN return(txt)
[docs] def distances_summary(self,file=''): """ Returns a summary of the real distances, focal distances and orientation angles. Returns ------- str """ txt = ' ******** SUMMARY OF DISTANCES ********\n' txt += ' ** DISTANCES FOR ALL O.E. [m] ** \n' txt += "%12s %12s %14s %14s %14s %14s \n"%('OE','TYPE','p[m]','q[m]','src-oe','src-screen') tot = 0.0 alphatot=0.0 deflection_H = 0.0 deflection_V = 0.0 pihalf = numpy.pi/2 txt1 = '' txt2 = '' oeshape = '?' n_elements = self.get_beamline_elements_number() for i in range(n_elements): ble = self.get_beamline_element_at(i) coor = ble.get_coordinates() oe = ble.get_optical_element() T_SOURCE, T_IMAGE, T_INCIDENCE, T_REFLECTION, ALPHA = coor.get_positions() is_focusing = 0 # txt += ' \n' # txt += 'Optical Element # %d\n'%(i + 1) if isinstance(oe, S4Empty): oetype = "EMPTY ELEMENT" elif isinstance(oe, S4Mirror): oetype = "MIRROR" is_focusing = 1 elif isinstance(oe, S4Crystal): oetype = "CRYSTAL" elif isinstance(oe, S4Grating): oetype = "GRATING" elif isinstance(oe, S4Multilayer): oetype = "MULTILAYER" elif isinstance(oe, S4Lens): oetype = "LENS" is_focusing = 1 elif isinstance(oe, S4CRL): oetype = "COMPOUND REFRACTIVE LENS" is_focusing = 1 elif isinstance(oe, S4Transfocator): oetype = "TRANSFOCATOR" is_focusing = 1 elif isinstance(oe, S4Screen): oetype = "SCR/SLIT/ABS" elif isinstance(oe, S4Compound): oetype = "COMPOUND" else: oetype = "*** Error: NOT IDENTIFIED OE %s ***" % repr(oe) #1) Distances summary tot = tot + T_SOURCE + oe.interthickness() + T_IMAGE totoe = tot - T_IMAGE line="%12d %12s %14.4f %14.4f %14.4f %14.4f \n"%(i+1,oetype,T_SOURCE,T_IMAGE,totoe,tot) txt1 += line # 2) focusing summary try: sh1 = oe.get_surface_shape_instance() oeshape = sh1.__class__.__name__ except: oeshape = "?????" got_focal_distances = 0 try: sc = oe._surface_calculation if sc == 0: pp = sh1.get_p_focus() qq = sh1.get_q_focus() got_focal_distances = 1 except: pass if is_focusing: if got_focal_distances: line = '%10d %20s %10.2f %10.2f %10.2f \n' % (i + 1, oeshape, pp, qq, pp / qq) else: line = '%10d %20s %10s %10s %10s \n'%( i+1,oeshape,'?','?','?') txt2 += line T_INCIDENCE = T_INCIDENCE T_REFLECTION = T_REFLECTION ALPHA = ALPHA # 3) total deflection alphatot = alphatot + ALPHA deflection_H = deflection_H + numpy.sin(alphatot) * ( (pihalf-T_INCIDENCE) + (pihalf-T_REFLECTION) ) deflection_V = deflection_V + numpy.cos(alphatot) * ( (pihalf-T_INCIDENCE) + (pihalf-T_REFLECTION) ) txt += txt1 txt += '\n' txt += ' ** FOCUSING ELEMENTS ** \n' # focusing elements line = '%10s %20s %10s %10s %10s \n'%('OE','SHAPE','p_foc','q_foc','1/M') txt += line txt += txt2 txt += '\n' line = 'Sum of Alphas [deg]: %.3f \n'%(alphatot*180/numpy.pi) txt += line line = 'Sum of Alphas Mod 180 [deg]: %.3f \n'%( numpy.mod(alphatot*180/numpy.pi,180)) txt += line line = 'Sum of Alphas Mod 360 [deg]: %.3f \n'%( numpy.mod(alphatot*180/numpy.pi,360)) txt += line txt += '\n' line = 'Total deflection angle H = %12.6f rad = %9.3f deg\n'%(deflection_H,deflection_H*180/numpy.pi) txt += line line = 'Total deflection angle V = %12.6f rad = %9.3f deg \n'%(deflection_V,deflection_V*180/numpy.pi) txt += line return(txt)
if __name__ == "__main__": if False: from shadow4.sources.source_geometrical.source_geometrical import SourceGeometrical from shadow4.beamline.optical_elements.mirrors.s4_plane_mirror import S4PlaneMirror, S4PlaneMirrorElement from shadow4.beamline.optical_elements.refractors.s4_transfocator import S4Transfocator, S4TransfocatorElement from syned.beamline.element_coordinates import ElementCoordinates light_source = SourceGeometrical(name='SourceGeometrical', nrays=10000, seed=5676561) m1 = S4PlaneMirror() # m2 = S4PlaneMirror() m2 = S4Transfocator() e1 = S4PlaneMirrorElement(m1, ElementCoordinates()) # e2 = S4PlaneMirrorElement(m2, ElementCoordinates()) e2 = S4TransfocatorElement(m2, ElementCoordinates()) bl = S4Beamline(light_source=light_source) # , beamline_elements_list=[e1,e2]) print(bl.distances_summary()) print(">>>> oe info: ", bl.oeinfo()) print(">>>> sys info: ", bl.sysinfo()) if False: # check source from file from shadow4.beamline.s4_beamline import S4Beamline import numpy as np beamline = S4Beamline() # # # from shadow4.sources.s4_light_source_from_file import S4LightSourceFromFile light_source = S4LightSourceFromFile(name='Shadow4 File Reader', file_name='/home/srio/Oasys/tmp.h5', simulation_name='run001', beam_name='begin') # beam = light_source.get_beam() beamline.set_light_source(light_source) print(beamline.sourcinfo()) if False: # check source from merged beamlines from shadow4.beamline.s4_beamline import S4Beamline import numpy as np beamline = S4Beamline() def run_beamline_1(): from shadow4.beamline.s4_beamline import S4Beamline import numpy as np beamline = S4Beamline() # # # from shadow4.sources.s4_light_source_from_file import S4LightSourceFromFile light_source = S4LightSourceFromFile(name='Shadow4 File Reader', file_name='/home/srio/Oasys/tmp.h5', simulation_name='run001', beam_name='begin') beam = light_source.get_beam() beamline.set_light_source(light_source) return beamline def run_beamline_2(): from shadow4.beamline.s4_beamline import S4Beamline import numpy as np beamline = S4Beamline() # # # from shadow4.sources.s4_light_source_from_file import S4LightSourceFromFile light_source = S4LightSourceFromFile(name='Shadow4 File Reader', file_name='/home/srio/Oasys/tmp.h5', simulation_name='run001', beam_name='begin') beam = light_source.get_beam() beamline.set_light_source(light_source) return beamline # # # from shadow4.sources.s4_light_source_from_beamlines import S4LightSourceFromBeamlines light_source = S4LightSourceFromBeamlines(name='Merge Shadow4 Beam') light_source.append_beamline(run_beamline_1(), id='beamline channel 1', weight=10.000000) light_source.append_beamline(run_beamline_2(), id='beamline channel 2', weight=10.000000) # beam = light_source.get_beam() beamline.set_light_source(light_source) print(beamline.sourcinfo()) if 1: # check compound from shadow4.beamline.s4_beamline import S4Beamline import numpy as np beamline = S4Beamline() # # # from shadow4.sources.s4_light_source_from_file import S4LightSourceFromFile light_source = S4LightSourceFromFile(name='Shadow4 File Reader', file_name='tmp.h5', simulation_name='run001', beam_name='begin') beam = light_source.get_beam() beamline.set_light_source(light_source) # optical element number XX def get_oe_1(): boundary_shape = None from shadow4.beamline.optical_elements.crystals.s4_conic_crystal import S4ConicCrystal optical_element = S4ConicCrystal(name='Crystal 1', boundary_shape=boundary_shape, conic_coefficients=[np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(-1.0), np.float64(-0.0025)], material='Si', miller_index_h=1, miller_index_k=1, miller_index_l=1, f_bragg_a=False, asymmetry_angle=0.0, is_thick=1, thickness=0.001, f_central=0, f_phot_cent=0, phot_cent=5000.0, file_refl='bragg.dat', f_ext=0, material_constants_library_flag=1, # 0=xraylib,1=dabax,2=preprocessor v1,3=preprocessor v2 ) return optical_element def get_oe_2(): boundary_shape = None from shadow4.beamline.optical_elements.crystals.s4_conic_crystal import S4ConicCrystal optical_element = S4ConicCrystal(name='Crystal 2', boundary_shape=boundary_shape, conic_coefficients=[np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(1.0), np.float64(-0.0025)], material='Si', miller_index_h=1, miller_index_k=1, miller_index_l=1, f_bragg_a=False, asymmetry_angle=0.0, is_thick=1, thickness=0.001, f_central=0, f_phot_cent=0, phot_cent=5000.0, file_refl='bragg.dat', f_ext=0, material_constants_library_flag=1, # 0=xraylib,1=dabax,2=preprocessor v1,3=preprocessor v2 ) return optical_element oe_list = [get_oe_1(), get_oe_2(), ] from shadow4.beamline.optical_elements.compound.s4_compound import S4Compound optical_element = S4Compound(name='ChannelCut (2)', oe_list=oe_list) from syned.beamline.element_coordinates import ElementCoordinates coordinates = ElementCoordinates(p=0, q=0.01, angle_radial=1.45421466, angle_azimuthal=0, angle_radial_out=1.687377993) movements = None from shadow4.beamline.optical_elements.compound.s4_compound import S4CompoundElement beamline_element = S4CompoundElement(optical_element=optical_element, coordinates=coordinates, input_beam=beam, movements=movements) # beam, footprint = beamline_element.trace_beam() beamline.append_beamline_element(beamline_element) print(beamline.oeinfo())