def testAllGeometryTypes(self): all_geometries = GeometryType.allGeometryTypes() self.assertIn(BraggDiffraction(), all_geometries) self.assertIn(LaueDiffraction(), all_geometries) self.assertIn(BraggTransmission(), all_geometries) self.assertIn(LaueTransmission(), all_geometries)
def _checkSetup(self, diffraction_setup, bragg_angle, F_0, F_H, F_H_bar): """ Checks if a given diffraction setup is possible, i.e. if a given Diffraction/Transmission for the given asymmetry and Miller indices is possible. Raises an exception if impossible. :param diffraction_setup: Diffraction setup. :param bragg_angle: Bragg angle. :param F_0: Structure factor F_0. :param F_H: Structure factor F_H. :param F_H_bar: Structure factor F_H_bar. """ # Check if the given geometry is a valid Bragg/Laue geometry. if diffraction_setup.geometryType() == BraggDiffraction( ) or diffraction_setup.geometryType() == BraggTransmission(): if diffraction_setup.asymmetryAngle() >= bragg_angle: raise ReflectionImpossibleException() elif diffraction_setup.geometryType() == LaueDiffraction( ) or diffraction_setup.geometryType() == LaueTransmission(): if diffraction_setup.asymmetryAngle() <= bragg_angle: raise TransmissionImpossibleException() # Check structure factor F_0. if abs(F_0.real) < 1e-7 or isnan(F_0.real): raise StructureFactorF0isZeroException() # Check structure factor F_H. if abs(F_H.real) < 1e-7 or isnan( F_H.real) or abs(F_H.imag) < 1e-7 or isnan(F_H.imag): raise StructureFactorFHisZeroException() # Check structure factor F_H_bar. if abs(F_H_bar.real) < 1e-7 or isnan( F_H_bar.real) or abs(F_H_bar.imag) < 1e-7 or isnan( F_H_bar.imag): raise StructureFactorFHbarIsZeroException()
def testConstructor(self): diffraction_setup = diffractionSetup() self.assertIsInstance(diffraction_setup, DiffractionSetup) self.assertEqual(diffraction_setup._geometry_type, BraggDiffraction()) self.assertEqual(diffraction_setup._crystal_name, "Si") self.assertEqual(diffraction_setup._thickness, 0.0001) self.assertEqual(diffraction_setup._miller_h, 1) self.assertEqual(diffraction_setup._miller_k, 1) self.assertEqual(diffraction_setup._miller_l, 1) self.assertEqual(diffraction_setup._asymmetry_angle, 10 * numpy.pi / 180) self.assertEqual(diffraction_setup._azimuthal_angle, 0)
def diffractionSetup(): directions = [Vector(0, 0, 1.0 / float(n)) for n in range(1, 176)] photons = [Photon(10000, direction) for direction in directions] diffraction_setup = DiffractionSetup( BraggDiffraction(), "Si", thickness=0.0001, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=10 * numpy.pi / 180, azimuthal_angle=0.0, ) # incoming_photons=photons) return diffraction_setup
def testOperatorNotEqual(self): diffraction_setup_one = diffractionSetup() diffraction_setup_two = DiffractionSetup( BraggDiffraction(), "Diamond", thickness=0.001, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=10 * numpy.pi / 180, azimuthal_angle=0.0, ) # incoming_photons=None) self.assertTrue(diffraction_setup_one != diffraction_setup_two) self.assertFalse(diffraction_setup_one != diffractionSetup())
def _checkSetupDiffraction(self, diffraction_setup, bragg_angle): """ Checks if a given diffraction setup is possible, i.e. if a given Diffraction/Transmission for the given asymmetry and Miller indices is possible. Raises an exception if impossible. :param diffraction_setup: Diffraction setup. :param bragg_angle: Bragg angle. """ # Check if the given geometry is a valid Bragg/Laue geometry. if diffraction_setup.geometryType() == BraggDiffraction( ) or diffraction_setup.geometryType() == BraggTransmission(): if diffraction_setup.asymmetryAngle() >= bragg_angle: raise ReflectionImpossibleException() elif diffraction_setup.geometryType() == LaueDiffraction( ) or diffraction_setup.geometryType() == LaueTransmission(): if diffraction_setup.asymmetryAngle() <= bragg_angle: raise TransmissionImpossibleException()
def calculateDiffraction(self, photon_in): """ Calculate diffraction for incoming photon. :param photon_in: Incoming photon. :return: Complex amplitude of the diffraction. """ # Initialize return variable. result = {"S": None, "P": None} # Calculate photon out. photon_out = self._calculatePhotonOut(photon_in) # Calculate crystal field refraction index difference. zac_alpha = self._calculateZacAlpha(photon_in) # Calculate asymmetry ratio. zac_b = self._calculateZacB(photon_in, photon_out) # Calculate z as defined in Zachariasen [3-123]. zac_z = self._calculateZacZ(zac_b, zac_alpha) # Calculate projection cosine. gamma_0 = self._calculateGamma(photon_in) # Calculate complex amplitude for S and P polarization. result["S"] = self._calculatePolarizationS(photon_in, zac_b, zac_z, gamma_0) result["P"] = self._calculatePolarizationP(photon_in, zac_b, zac_z, gamma_0) # Note division by |b| in intensity (thus sqrt(|b|) in amplitude) # for power balance (see Zachariasen pag. 122) # # This factor only applies to diffracted beam, not to transmitted beams # (see private communication M. Rio (ESRF) and J. Sutter (DLS)) if (self.geometryType() == BraggDiffraction() or self.geometryType() == LaueDiffraction()): result["S"].rescale(1.0 / sqrt(abs(zac_b))) result["P"].rescale(1.0 / sqrt(abs(zac_b))) # If debugging output is turned on. if self.isDebug: self._logMembers(zac_b, zac_alpha, photon_in, photon_out, result) # Returns the complex amplitudes. return result
def diffractionSetupMultipleEnergy(): diffraction_setup = DiffractionSetupSweeps(BraggDiffraction(), "Si", thickness=0.0100 * 1e-2, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=3 * numpy.pi / 180, azimuthal_angle=0.0, energy_min=10000, energy_max=10001, energy_points=2, angle_deviation_min=-100.0e-6, angle_deviation_max=100e-6, angle_deviation_points=50) return diffraction_setup
def diffractionSetup(): diffraction_setup = DiffractionSetupSweeps(BraggDiffraction(), "Si", thickness=0.0001, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=10.0 * numpy.pi / 180, azimuthal_angle=0.0, energy_min=10000, energy_max=10000, energy_points=1, angle_deviation_min=-100.0e-6, angle_deviation_max=100e-6, angle_deviation_points=175) return diffraction_setup
def testAsPlotData1D(self): diffraction_setup = DiffractionSetupSweeps( BraggDiffraction(), "Si", thickness=0.0100 * 1e-2, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=3 * numpy.pi / 180, azimuthal_angle=3 * numpy.pi / 180, energy_min=10000, energy_max=10000, energy_points=1, angle_deviation_min=-100.0e-6, angle_deviation_max=100e-6, angle_deviation_points=50) diffraction = Diffraction() res = diffraction.calculateDiffraction(diffraction_setup)
def calculate_bragg_dcm(energy_setup=8000.0,energies=numpy.linspace(7990,8010,200)): diffraction_setup_r = DiffractionSetup(geometry_type=BraggDiffraction(), # GeometryType object crystal_name="Si", # string thickness=100e-6, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle=0, # 10.0*numpy.pi/180., # radians azimuthal_angle=0.0) # radians # int diffraction = Diffraction() scan = numpy.zeros_like(energies) r = numpy.zeros_like(energies) for i in range(energies.size): # # gets Bragg angle needed to create deviation's scan # energy = energies[i] bragg_angle = diffraction_setup_r.angleBragg(energy_setup) print("Bragg angle for E=%f eV is %f deg" % (energy, bragg_angle * 180.0 / numpy.pi)) # Create a Diffraction object (the calculator) deviation = 0.0 # angle_deviation_min + ia * angle_step angle = deviation + bragg_angle # calculate the components of the unitary vector of the incident photon scan # Note that diffraction plane is YZ yy = numpy.cos(angle) zz = - numpy.abs(numpy.sin(angle)) photon = Photon(energy_in_ev=energy,direction_vector=Vector(0.0,yy,zz)) # perform the calculation coeffs_r = diffraction.calculateDiffractedComplexAmplitudes(diffraction_setup_r, photon) scan[i] = energy r[i] = numpy.abs( coeffs_r['S'].complexAmplitude() )**4 return scan,r
def calculate_standard_interface(): # Create a diffraction setup. print("\nCreating a diffraction setup...") diffraction_setup = DiffractionSetupSweeps( geometry_type=BraggDiffraction(), # GeometryType object crystal_name="Si", # string thickness=1e-2, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle= 0, #10.0*numpy.pi/180., # radians azimuthal_angle=0.0, # radians energy_min=8000.0, # eV energy_max=8000.0, # eV energy_points=1, # int angle_deviation_min=-100e-6, # radians angle_deviation_max=100e-6, # radians angle_deviation_points=500) # int # Create a Diffraction object. diffraction = Diffraction() # Create a DiffractionResult object holding the results of the diffraction calculations. print("\nCalculating the diffraction results...") diffraction_result = diffraction.calculateDiffraction(diffraction_setup) # # Now the Mueller/Stokes calculation from the diffraction results # mueller_diffraction = MuellerDiffraction( diffraction_result, StokesVector([1, 0, 1, 0]), inclination_angle=0.0) #np.pi*45/180) # Create a MullerResult object. print("\nCalculating the Stokes vector...") mueller_result = mueller_diffraction.calculate_stokes() return mueller_result
def testOperatorNotEqual(self): diffraction_setup_one = diffractionSetup() diffraction_setup_two = DiffractionSetupSweeps( BraggDiffraction(), "Diamond", thickness=0.001, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=11, azimuthal_angle=0.0, energy_min=8000, energy_max=8000, energy_points=1, angle_deviation_min=-100.0e-6, angle_deviation_max=100e-6, angle_deviation_points=175) self.assertTrue(diffraction_setup_one != diffraction_setup_two) self.assertFalse(diffraction_setup_one != diffractionSetup())
def testConstructor(self): diffraction_setup = diffractionSetup() self.assertIsInstance(diffraction_setup, DiffractionSetupSweeps) self.assertEqual(diffraction_setup._geometry_type, BraggDiffraction()) self.assertEqual(diffraction_setup._crystal_name, "Si") self.assertEqual(diffraction_setup._thickness, 0.0001) self.assertEqual(diffraction_setup._miller_h, 1) self.assertEqual(diffraction_setup._miller_k, 1) self.assertEqual(diffraction_setup._miller_l, 1) self.assertEqual(diffraction_setup._asymmetry_angle, 10 * numpy.pi / 180) self.assertEqual(diffraction_setup._azimuthal_angle, 0) self.assertEqual(diffraction_setup.energyMin(), 10000) self.assertEqual(diffraction_setup.energyMax(), 10000) self.assertEqual(diffraction_setup.energyPoints(), 1) self.assertAlmostEqual(diffraction_setup.angleDeviationMin(), -100.0e-6) self.assertAlmostEqual(diffraction_setup.angleDeviationMax(), 100.0e-6) self.assertEqual(diffraction_setup.angleDeviationPoints(), 175)
def testCalculateBraggDiffraction(self): diffraction_setup = DiffractionSetupSweeps(BraggDiffraction(), "Si", thickness=0.0100 * 1e-2, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=3*numpy.pi/180, azimuthal_angle=0.0, energy_min=10000, energy_max=10000, energy_points=1, angle_deviation_min= -20.0e-6, angle_deviation_max=20e-6, angle_deviation_points=5) diffraction = Diffraction() res = diffraction.calculateDiffraction(diffraction_setup) # s_intensity_fraction=[0.017519141613069177, 0.0321954521714361, 0.07981125895068454, 0.920965084591721, 0.9417181994525138] # s_phase=[-0.745427562155594, -0.8048350757616735, -0.7441070552657782, -1.0347178161614214, -2.353510138419943] # p_intensity_fraction=[0.014173087736472335, 0.025303154305706777, 0.06615101317795873, 0.5244213525516417, 0.9369357917670563] # p_phase=[-0.793312359389805, -0.7582549664194022, -0.750381901971316, -0.8168058020223106, -2.353282699138147] # TODO: check correctness of phases!! s_intensity_fraction = [ 0.01726512, 0.03246927, 0.07909485, 0.92019219, 0.9417577 ] s_phase = [ 2.39724121, 2.3388142 , 2.39913351, 2.10984245, 0.78904046] p_intensity_fraction = [ 0.01433174, 0.02517142, 0.06566106, 0.52116638, 0.93697839] p_phase = [ 2.34537175, 2.37937306, 2.39282075, 2.32528928, 0.78934907] self.assertDiffractionResult(10000, s_intensity_fraction, s_phase, p_intensity_fraction, p_phase, res)
def calculate_with_crystalpy( bragg_or_laue=0, # diffracted_or_transmitted=0, # crystal_name="Si", # string thickness=1e-2, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle=0.0, # radians energy=8000.0, # eV angle_deviation_min=-100e-6, # radians angle_deviation_max=100e-6, # radians angle_deviation_points=500, ): if bragg_or_laue == 0: if diffracted_or_transmitted == 0: geometry_type = BraggDiffraction() elif diffracted_or_transmitted == 1: geometry_type = BraggTransmission() else: raise Exception("Bad geometry type") elif bragg_or_laue == 1: if diffracted_or_transmitted == 0: geometry_type = LaueDiffraction() elif diffracted_or_transmitted == 1: geometry_type = LaueTransmission() else: raise Exception("Bad geometry type") else: raise Exception("Bad geometry type") # Create a diffraction setup. print("\nCreating a diffraction setup...") diffraction_setup = DiffractionSetup(geometry_type=geometry_type, crystal_name=crystal_name, thickness=thickness, miller_h=miller_h, miller_k=miller_k, miller_l=miller_l, asymmetry_angle=asymmetry_angle, azimuthal_angle=0.0) # energy = 8000.0 # eV # angle_deviation_min = -100e-6 # radians # angle_deviation_max = 100e-6 # radians # angle_deviation_points = 500 angle_step = (angle_deviation_max - angle_deviation_min) / angle_deviation_points # # gets Bragg angle needed to create deviation's scan # bragg_angle = diffraction_setup.angleBragg(energy) print("Bragg angle for E=%f eV is %f deg" % (energy, bragg_angle * 180.0 / numpy.pi)) # Create a Diffraction object (the calculator) diffraction = Diffraction() # initialize arrays for storing outputs deviations = numpy.zeros(angle_deviation_points) intensityS = numpy.zeros(angle_deviation_points) intensityP = numpy.zeros(angle_deviation_points) k_0_unitary = diffraction_setup.incomingPhotonDirection(energy, 0.0) # photon_0 = Photon(energy_in_ev=energy,direction_vector=k_0_unitary) # k_H_unitary = diffraction_setup._ # print(">>>>>>>>>>>>>>>>>>>>>>>>k_0: ",k_0_unitary._components ) # plot_crystal_sketch(k_0_unitary,k_0_unitary,) for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step # angle = deviation + bragg_angle + asymmetry_angle # # calculate the components of the unitary vector of the incident photon scan # # Note that diffraction plane is YZ # yy = numpy.cos(angle) # zz = - numpy.abs(numpy.sin(angle)) # photon = Photon(energy_in_ev=energy,direction_vector=Vector(0.0,yy,zz)) k_unitary = diffraction_setup.incomingPhotonDirection( energy, deviation) # or equivalently # k_0_unitary = diffraction_setup.incomingPhotonDirection(energy, 0.0) # k_unitary = k_0_unitary.rotateAroundAxis( Vector(1.0,0.0,0.0), -deviation) photon = Photon(energy_in_ev=energy, direction_vector=k_unitary) # perform the calculation coeffs = diffraction.calculateDiffractedComplexAmplitudes( diffraction_setup, photon) # store results deviations[ia] = deviation intensityS[ia] = coeffs['S'].intensity() intensityP[ia] = coeffs['P'].intensity() # print(">>>>>>>>>>>>>>>>>>>>>>>>k_0: ",k_0_unitary._components,k_0_unitary.getNormalizedVector()._components ) return deviations, intensityS, intensityP
def calculate_with_polarized_photon(method=0): # Create a diffraction setup. print("\nCreating a diffraction setup...") diffraction_setup = DiffractionSetup( geometry_type=BraggDiffraction(), # GeometryType object crystal_name="Si", # string thickness=1e-2, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle= 0, #10.0*numpy.pi/180., # radians azimuthal_angle=0.0) # radians # int energy = 8000.0 # eV angle_deviation_min = -100e-6 # radians angle_deviation_max = 100e-6 # radians angle_deviation_points = 500 angle_step = (angle_deviation_max - angle_deviation_min) / angle_deviation_points bunch_in = PolarizedPhotonBunch() bragg_angle = diffraction_setup.angleBragg(energy) print("Bragg angle for E=%f eV is %f deg" % (energy, bragg_angle * 180.0 / numpy.pi)) # Create a Diffraction object. diffraction = Diffraction() # # get wavevector with incident direction matching Bragg angle # K0 = diffraction_setup.getK0(energy) K0unitary = K0.getNormalizedVector() print("K0", K0.components()) # method = 0 # diffraction for individual photons # method = 1 # diffraction for bunch ZZ = numpy.zeros(angle_deviation_points) if method == 0: bunch_out = PolarizedPhotonBunch() for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step # angle = deviation + bragg_angle # yy = numpy.cos(angle) # zz = - numpy.abs(numpy.sin(angle)) # photon = PolarizedPhoton(energy_in_ev=energy,direction_vector=Vector(0.0,yy,zz), # stokes_vector=StokesVector([1,0,1,0])) # minus sign in angle is to perform cw rotation when deviation increses Vin = K0unitary.rotateAroundAxis(Vector(1, 0, 0), -deviation) photon = PolarizedPhoton(energy_in_ev=energy, direction_vector=Vin, stokes_vector=StokesVector([1, 0, 1, 0])) photon_out = diffraction.calculateDiffractedPolarizedPhoton( diffraction_setup, incoming_polarized_photon=photon, inclination_angle=0.0) bunch_out.addPhoton(photon_out) ZZ[ia] = angle_deviation_min + ia * angle_step elif method == 1: # diffraction for bunch for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step # angle = deviation + bragg_angle # yy = numpy.cos(angle) # zz = - numpy.abs(numpy.sin(angle)) # photon = PolarizedPhoton(energy_in_ev=energy,direction_vector=Vector(0.0,yy,zz), # stokes_vector=StokesVector([1,0,1,0])) # minus sign in angle is to perform cw rotation when deviation increses Vin = K0unitary.rotateAroundAxis(Vector(1, 0, 0), -deviation) photon = PolarizedPhoton(energy_in_ev=energy, direction_vector=Vin, stokes_vector=StokesVector([1, 0, 1, 0])) bunch_in.addPhoton(photon) ZZ[ia] = angle_deviation_min + ia * angle_step bunch_out = diffraction.calculateDiffractedPolarizedPhotonBunch( diffraction_setup, bunch_in, 0.0) bunch_out_dict = bunch_out.toDictionary() plot(1e6 * ZZ, bunch_out_dict["s0"], 1e6 * ZZ, bunch_out_dict["s1"], legend=["S0", "S1"], xtitle="theta - thetaB [urad]", title="Polarized reflectivity calculation using method %d" % method)
def calculate_simple_diffraction_energy_scan_accelerated(): # Create a diffraction setup. print("\nCreating a diffraction setup...") diffraction_setup = DiffractionSetup( geometry_type=BraggDiffraction(), # GeometryType object crystal_name="Si", # string thickness=1e-2, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle= 0, #10.0*numpy.pi/180., # radians azimuthal_angle=0.0) # radians # int import socket if socket.getfqdn().find("esrf") >= 0: dx = DabaxXraylib( dabax_repository="http://ftp.esrf.fr/pub/scisoft/DabaxFiles/") else: dx = DabaxXraylib() diffraction_setup_dabax = DiffractionSetupDabax( geometry_type=BraggDiffraction(), # GeometryType object crystal_name="Si", # string thickness=1e-2, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle= 0, #10.0*numpy.pi/180., # radians azimuthal_angle=0.0, dabax=dx) # radians energy = 8000.0 # eV angle_deviation_min = -100e-6 # radians angle_deviation_max = 100e-6 # radians angle_deviation_points = 50 angle_step = (angle_deviation_max - angle_deviation_min) / angle_deviation_points # # gets Bragg angle needed to create deviation's scan # bragg_angle_corrected = diffraction_setup.angleBraggCorrected(energy) print("Bragg angle corrected for E=%f eV is %f deg" % (energy, bragg_angle_corrected * 180.0 / numpy.pi)) DeltaE = energy * 1e-4 npoints = 100 energies = numpy.linspace(energy - 3 * DeltaE, energy + 3 * DeltaE, npoints) # Create a Diffraction object (the calculator) diffraction = Diffraction() diffraction_dabax = Diffraction() # initialize arrays for storing outputs intensityS = numpy.zeros(npoints) intensityP = numpy.zeros(npoints) intensityS_dabax = numpy.zeros(npoints) intensityP_dabax = numpy.zeros(npoints) t0 = time.time() for ia in range(npoints): # calculate the components of the unitary vector of the incident photon scan # Note that diffraction plane is YZ yy = numpy.cos(bragg_angle_corrected) zz = -numpy.abs(numpy.sin(bragg_angle_corrected)) photon = Photon(energy_in_ev=energies[ia], direction_vector=Vector(0.0, yy, zz)) # perform the calculation coeffs = diffraction.calculateDiffractedComplexAmplitudes( diffraction_setup, photon) # store results intensityS[ia] = coeffs['S'].intensity() intensityP[ia] = coeffs['P'].intensity() COOR = [] ENER = [] for ia in range(npoints): # calculate the components of the unitary vector of the incident photon scan # Note that diffraction plane is YZ yy = numpy.cos(bragg_angle_corrected) zz = -numpy.abs(numpy.sin(bragg_angle_corrected)) COOR.append([0.0, yy, zz]) ENER.append(energies[ia]) t1 = time.time() Psi_0, Psi_H, Psi_H_bar = diffraction_setup_dabax.psiAll(ENER) for ia in range(npoints): # perform the calculation incoming_photon = Photon(energy_in_ev=ENER[ia], direction_vector=Vector( COOR[ia][0], COOR[ia][1], COOR[ia][2])) energy = ENER[ia] # psi_0, psi_H, psi_H_bar = diffraction_setup_dabax.psiAll(energy) psi_0, psi_H, psi_H_bar = Psi_0[ia], Psi_H[ia], Psi_H_bar[ia] # Create PerfectCrystalDiffraction instance. perfect_crystal = PerfectCrystalDiffraction( geometry_type=diffraction_setup_dabax.geometryType(), bragg_normal=diffraction_setup_dabax.normalBragg(), surface_normal=diffraction_setup_dabax.normalSurface(), bragg_angle=diffraction_setup_dabax.angleBragg(energy), psi_0=psi_0, psi_H=psi_H, psi_H_bar=psi_H_bar, thickness=diffraction_setup_dabax.thickness(), d_spacing=diffraction_setup_dabax.dSpacing() * 1e-10) complex_amplitudes = perfect_crystal.calculateDiffraction( incoming_photon) intensityS_dabax[ia] = complex_amplitudes['S'].intensity( ) # 0.0 # coeffs_dabax['S'].intensity() intensityP_dabax[ia] = complex_amplitudes['P'].intensity( ) # 0.0 # coeffs_dabax['P'].intensity() t2 = time.time() # plot results import matplotlib.pylab as plt plt.plot(energies, intensityS) plt.plot(energies, intensityP) plt.plot(energies, intensityS_dabax) plt.plot(energies, intensityP_dabax) plt.xlabel("photon energy [eV]") plt.ylabel("Reflectivity") plt.legend([ "Sigma-polarization XRAYLIB", "Pi-polarization XRAYLIB", "Sigma-polarization DABAX", "Pi-polarization DABAX" ]) plt.show() print("Total time, Time per points XRAYLIB: ", t1 - t0, (t1 - t0) / npoints) print("Total time, Time per points DABAX: ", t2 - t1, (t2 - t1) / npoints)
def _calculateComplexAmplitude(self, photon_in, zac_q, zac_z, gamma_0, effective_psi_h_bar): """ Calculates the complex amplitude of the questioned wave: diffracted or transmission. :param photon_in: Incoming photon. :param zac_q: q as defined in Zachariasen [3-123]. :param zac_z: z as defined in Zachariasen [3-123]. :param gamma_0: Projection cosine as defined in Zachariasen [3-115]. :param effective_psi_h_bar: Effective PsiHBar (depending of polarisation. See text following [3.-139]). :return: Complex amplitude. """ # Calculate geometry independent parts. tmp_root = (zac_q + zac_z * zac_z)**0.5 zac_x1 = (-1.0 * zac_z + tmp_root) / effective_psi_h_bar zac_x2 = (-1.0 * zac_z - tmp_root) / effective_psi_h_bar zac_delta1 = 0.5 * (self.Psi0() - zac_z + tmp_root) zac_delta2 = 0.5 * (self.Psi0() - zac_z - tmp_root) zac_phi1 = 2 * pi / gamma_0 / photon_in.wavelength() * zac_delta1 zac_phi2 = 2 * pi / gamma_0 / photon_in.wavelength() * zac_delta2 zac_c1 = -1j * self.thickness() * zac_phi1 zac_c2 = -1j * self.thickness() * zac_phi2 if self.isDebug: self.logDebug("__zac_c1" + str(zac_c1)) self.logDebug("__zac_c2" + str(zac_c2)) cv_zac_c1 = self._exponentiate(zac_c1) cv_zac_c2 = self._exponentiate(zac_c2) cv_zac_x1 = self._createVariable(zac_x1) cv_zac_x2 = self._createVariable(zac_x2) # Calculate complex amplitude according to given geometry. if self.geometryType() == BraggDiffraction(): complex_amplitude = cv_zac_x1 * cv_zac_x2 * (cv_zac_c2 - cv_zac_c1) / \ (cv_zac_c2 * cv_zac_x2 - cv_zac_c1 * cv_zac_x1) elif self.geometryType() == LaueDiffraction(): complex_amplitude = cv_zac_x1 * cv_zac_x2 * (cv_zac_c1 - cv_zac_c2) / \ (cv_zac_x2 - cv_zac_x1) elif self.geometryType() == BraggTransmission(): complex_amplitude = cv_zac_c1 * cv_zac_c2 * (cv_zac_x2 - cv_zac_x1) / \ (cv_zac_c2 * cv_zac_x2 - cv_zac_c1 * cv_zac_x1) elif self.geometryType() == LaueTransmission(): complex_amplitude = (cv_zac_x2 * cv_zac_c1 - cv_zac_x1 * cv_zac_c2) / \ (cv_zac_x2 - cv_zac_x1) else: raise Exception if self.isDebug: self.logDebug("ctemp: " + str(tmp_root)) self.logDebug("zac_z" + str(zac_z)) self.logDebug("zac_q" + str(zac_q)) self.logDebug("zac delta 1" + str(zac_delta1)) self.logDebug("zac delta 2" + str(zac_delta2)) self.logDebug("gamma_0" + str(gamma_0)) self.logDebug("wavelength" + str(photon_in.wavelength())) self.logDebug("zac phi 1" + str(zac_phi1)) self.logDebug("zac phi 2" + str(zac_phi2)) self.logDebug("zac_c1: " + str(cv_zac_c1)) self.logDebug("zac_c2: " + str(cv_zac_c2)) self.logDebug("zac_x1: " + str(cv_zac_x1)) self.logDebug("zac_x2: " + str(cv_zac_x2)) return ComplexAmplitude(complex(complex_amplitude))
def _calculatePhotonOut(self, photon_in): """ Solves the Laue equation to calculates the outgoing photon from the incoming photon and the Bragg normal. :param photon_in: Incoming photon. :return: Outgoing photon. """ # # Retrieve k_0. # k_in = photon_in.wavevector() # # Solve unscaled Laue equation. # k_out = self.braggNormal().addVector(k_in) # Create photon in k_out direction and scale by setting the photon energy. # photon_out = Photon(photon_in.energy(), k_out) """ GENERAL VERSION: Solves the Laue equation for the parallel components of the vectors and uses the conservation of the wavevector modulus to calculate the outgoing wavevector even for diffraction not at the Bragg angle. """ # Retrieve k_0. k_in = photon_in.wavevector() # Decompose the vector into a component parallel to the surface normal and # a component parallel to the surface: (k_in * n) n. k_in_normal = self.surface_normal().scalarMultiplication( k_in.scalarProduct(self.surface_normal())) k_in_parallel = k_in.subtractVector(k_in_normal) # Retrieve the B_H vector. B_H = self.braggNormal() # Decompose the vector into a component parallel to the surface normal and # a component parallel to the surface: (B_H * n) n. B_H_normal = self.surface_normal().scalarMultiplication( B_H.scalarProduct(self.surface_normal())) B_H_parallel = B_H.subtractVector(B_H_normal) # Apply the Laue formula for the parallel components. k_out_parallel = k_in_parallel.addVector(B_H_parallel) # Calculate K_out normal. k_out_normal_modulus = sqrt(k_in.norm()**2 - k_out_parallel.norm()**2) k_out_normal = self.surface_normal().scalarMultiplication( k_out_normal_modulus) # # Calculate the outgoing photon. # # changed [email protected] to negative normal component to take into account that crystal normal points # # outsize # k_out_1 = k_out_parallel.addVector(k_out_normal) # k_out_2 = k_out_parallel.scalarMultiplication(-1.0).addVector(k_out_normal) # # # select k_out_1 or k_out_2 # # k_out_Ewald = photon_in.unitDirectionVector().scalarMultiplication(photon_in.wavenumber()) # k_out_Ewald = k_out_Ewald.addVector(B_H) # k_out_Ewald = k_out_Ewald.getNormalizedVector() # # tmp1 = k_out_1.scalarProduct(k_out_Ewald) # tmp2 = k_out_2.scalarProduct(k_out_Ewald) # TODO: try to put some logic here if self.geometryType() == BraggDiffraction(): k_out = k_out_parallel.addVector(k_out_normal) elif self.geometryType() == LaueDiffraction(): k_out = k_out_parallel.addVector( k_out_normal.scalarMultiplication(-1.0)) elif self.geometryType() == BraggTransmission(): k_out = k_out_parallel.addVector(k_out_normal) elif self.geometryType() == LaueTransmission(): k_out = k_out_parallel.addVector( k_out_normal.scalarMultiplication(-1.0)) else: raise Exception photon_out = photon_in.duplicate() photon_out.setUnitDirectionVector(k_out) if self.isDebug: self.logDebug("surface normal" + str(self.surface_normal().components())) self.logDebug("Angle bragg normal photon_in" + str( (photon_in.unitDirectionVector().angle(self.braggNormal()), pi * 0.5 - photon_in.unitDirectionVector().angle(self.braggNormal())))) self.logDebug("Angle bragg normal photon_out" + str( (photon_out.unitDirectionVector().angle(self.braggNormal()), pi * 0.5 - photon_out.unitDirectionVector().angle(self.braggNormal())))) self.logDebug("photon_in direction" + str(photon_in.unitDirectionVector().components())) self.logDebug("photon_out direction" + str(photon_out.unitDirectionVector().components())) # Return outgoing photon. return photon_out
def calculate_external_CrystalCalculator(GEOMETRY_TYPE, CRYSTAL_NAME, THICKNESS, MILLER_H, MILLER_K, MILLER_L, ASYMMETRY_ANGLE, AZIMUTHAL_ANGLE, ENERGY_POINTS, ENERGY_MIN, ENERGY_MAX, ANGLE_DEVIATION_POINTS, ANGLE_DEVIATION_MIN, ANGLE_DEVIATION_MAX, STOKES_S0, STOKES_S1, STOKES_S2, STOKES_S3, INCLINATION_ANGLE, DUMP_TO_FILE, FILE_NAME="tmp.dat"): # Create a GeometryType object: # Bragg diffraction = 0 # Bragg transmission = 1 # Laue diffraction = 2 # Laue transmission = 3 if GEOMETRY_TYPE == 0: GEOMETRY_TYPE_OBJECT = BraggDiffraction() elif GEOMETRY_TYPE == 1: GEOMETRY_TYPE_OBJECT = BraggTransmission() elif GEOMETRY_TYPE == 2: GEOMETRY_TYPE_OBJECT = LaueDiffraction() elif GEOMETRY_TYPE == 3: GEOMETRY_TYPE_OBJECT = LaueTransmission() else: raise Exception( "CrystalCalculator: The geometry type could not be interpreted!" ) # Create a diffraction setup. # At this stage I translate angles in radians, energy in eV and all other values in SI units. print("CrystalCalculator: Creating a diffraction setup...\n") if ENERGY_POINTS == 1: if ENERGY_MIN != ENERGY_MAX: raise Exception( "CrystalCalculator: Finite energy range with only one sampled value!" ) diffraction_setup = DiffractionSetupSweeps( geometry_type=GEOMETRY_TYPE_OBJECT, # GeometryType object crystal_name=str(CRYSTAL_NAME), # string thickness=float(THICKNESS) * 1e-2, # meters miller_h=int(MILLER_H), # int miller_k=int(MILLER_K), # int miller_l=int(MILLER_L), # int asymmetry_angle=float(ASYMMETRY_ANGLE) / 180 * np.pi, # radians azimuthal_angle=float(AZIMUTHAL_ANGLE) / 180 * np.pi, # radians energy_min=float(ENERGY_MIN), # eV energy_max=float(ENERGY_MAX), # eV energy_points=int(ENERGY_POINTS), # int angle_deviation_min=float(ANGLE_DEVIATION_MIN) * 1e-6, # radians angle_deviation_max=float(ANGLE_DEVIATION_MAX) * 1e-6, # radians angle_deviation_points=int(ANGLE_DEVIATION_POINTS)) # int # Create a Diffraction object. diffraction = Diffraction() # Create a DiffractionResult object holding the results of the diffraction calculations. print("CrystalCalculator: Calculating the diffraction results...\n") diffraction_result = diffraction.calculateDiffraction( diffraction_setup) # Create a StokesVector object. incoming_stokes_vector = StokesVector( [STOKES_S0, STOKES_S1, STOKES_S2, STOKES_S3]) # Create a MuellerDiffraction object. mueller_diffraction = MuellerDiffraction( diffraction_result, incoming_stokes_vector, float(INCLINATION_ANGLE) * np.pi / 180) # Create a MullerResult object. print("CrystalCalculator: Calculating the Stokes vector...\n") mueller_result = mueller_diffraction.calculate_stokes() # Create the data to output. output_data = MailingBox(diffraction_result, mueller_result) # Dump data to file if requested. if DUMP_TO_FILE == 1: print("CrystalCalculator: Writing data in {file}...\n".format( file=FILE_NAME)) with open(FILE_NAME, "w") as file: try: file.write( "VALUES:\n\n" "geometry type: {geometry_type}\n" "crystal name: {crystal_name}\n" "thickness: {thickness}\n" "miller H: {miller_h}\n" "miller K: {miller_k}\n" "miller L: {miller_l}\n" "asymmetry angle: {asymmetry_angle}\n" "azimuthal angle: {azimuthal_angle}\n" "energy points: {energy_points}\n" "energy minimum: {energy_min}\n" "energy maximum: {energy_max}\n" "deviation angle points: {angle_deviation_points}\n" "deviation angle minimum: {angle_deviation_min}\n" "deviation angle maximum: {angle_deviation_max}\n" "inclination angle: {inclination_angle}\n" "incoming Stokes vector: {incoming_stokes_vector}\n\n" "RESULTS:\n\n" "S-Polarization:\n" "Intensity: {s_intensity}\n" "Phase: {s_phase}\n\n" "P-Polarization:\n" "Intensity: {p_intensity}\n" "Phase: {p_phase}\n\n" "SP-Difference:\n" "Intensity: {sp_intensity}\n" "Phase: {sp_phase}\n\n" "Stokes vector:\n" "S0: {s0}\n" "S1: {s1}\n" "S2: {s2}\n" "S3: {s3}\n\n" "Degree of circular polarization: {pol_degree}".format( geometry_type=GEOMETRY_TYPE_OBJECT.description(), crystal_name=CRYSTAL_NAME, thickness=THICKNESS, miller_h=MILLER_H, miller_k=MILLER_K, miller_l=MILLER_L, asymmetry_angle=ASYMMETRY_ANGLE, azimuthal_angle=AZIMUTHAL_ANGLE, energy_points=ENERGY_POINTS, energy_min=ENERGY_MIN, energy_max=ENERGY_MAX, angle_deviation_points=ANGLE_DEVIATION_POINTS, angle_deviation_min=ANGLE_DEVIATION_MIN, angle_deviation_max=ANGLE_DEVIATION_MAX, inclination_angle=INCLINATION_ANGLE, incoming_stokes_vector=incoming_stokes_vector. components(), s_intensity=diffraction_result.sIntensityByEnergy( ENERGY_MIN), s_phase=diffraction_result.sPhaseByEnergy( ENERGY_MIN, deg=True), p_intensity=diffraction_result.pIntensityByEnergy( ENERGY_MIN), p_phase=diffraction_result.pPhaseByEnergy( ENERGY_MIN, deg=True), sp_intensity=diffraction_result. differenceIntensityByEnergy(ENERGY_MIN), sp_phase=diffraction_result. differencePhaseByEnergy(ENERGY_MIN, deg=True), s0=mueller_result.s0_by_energy(ENERGY_MIN), s1=mueller_result.s1_by_energy(ENERGY_MIN), s2=mueller_result.s2_by_energy(ENERGY_MIN), s3=mueller_result.s3_by_energy(ENERGY_MIN), pol_degree=mueller_result. polarization_degree_by_energy(ENERGY_MIN))) file.close() print("File written to disk: %s" % FILE_NAME) except: raise Exception( "CrystalCalculator: The data could not be dumped onto the specified file!" ) return output_data
def calculate_external_Crystal(GEOMETRY_TYPE, CRYSTAL_NAME, THICKNESS, MILLER_H, MILLER_K, MILLER_L, ASYMMETRY_ANGLE, AZIMUTHAL_ANGLE, incoming_bunch, INCLINATION_ANGLE, DUMP_TO_FILE, FILE_NAME="tmp.dat"): # Create a GeometryType object: # Bragg diffraction = 0 # Bragg transmission = 1 # Laue diffraction = 2 # Laue transmission = 3 if GEOMETRY_TYPE == 0: GEOMETRY_TYPE_OBJECT = BraggDiffraction() elif GEOMETRY_TYPE == 1: GEOMETRY_TYPE_OBJECT = BraggTransmission() elif GEOMETRY_TYPE == 2: GEOMETRY_TYPE_OBJECT = LaueDiffraction() elif GEOMETRY_TYPE == 3: GEOMETRY_TYPE_OBJECT = LaueTransmission() else: raise Exception("Crystal: The geometry type could not be interpreted!\n") # Create a diffraction setup. # At this stage I translate angles in radians, energy in eV and all other values in SI units. print("Crystal: Creating a diffraction setup...\n") diffraction_setup = DiffractionSetup(geometry_type=GEOMETRY_TYPE_OBJECT, # GeometryType object crystal_name=str(CRYSTAL_NAME), # string thickness=float(THICKNESS) * 1e-2, # meters miller_h=int(MILLER_H), # int miller_k=int(MILLER_K), # int miller_l=int(MILLER_L), # int asymmetry_angle=float(ASYMMETRY_ANGLE) / 180 * np.pi, # radians azimuthal_angle=float(AZIMUTHAL_ANGLE) / 180 * np.pi) # radians # incoming_photons=incoming_bunch) # Create a Diffraction object. diffraction = Diffraction() # Create a PolarizedPhotonBunch object holding the results of the diffraction calculations. print("Crystal: Calculating the outgoing photons...\n") outgoing_bunch = diffraction.calculateDiffractedPolarizedPhotonBunch(diffraction_setup, incoming_bunch, INCLINATION_ANGLE) # Check that the result of the calculation is indeed a PolarizedPhotonBunch object. if not isinstance(outgoing_bunch, PolarizedPhotonBunch): raise Exception("Crystal: Expected PolarizedPhotonBunch as a result, found {}!\n".format(type(outgoing_bunch))) # Dump data to file if requested. if DUMP_TO_FILE == 0: print("Crystal: Writing data in {file}...\n".format(file=FILE_NAME)) with open(FILE_NAME, "w") as file: try: file.write("#S 1 photon bunch\n" "#N 8\n" "#L Energy [eV] Vx Vy Vz S0 S1 S2 S3\n") file.write(outgoing_bunch.toString()) file.close() print("File written to disk: %s"%FILE_NAME) except: raise Exception("Crystal: The data could not be dumped onto the specified file!\n") return outgoing_bunch
def testCheckSetup(self): diffraction = Diffraction() diffraction_setup = DiffractionSetupSweeps( BraggDiffraction(), "Si", thickness=128 * 1e-6, miller_h=1, miller_k=1, miller_l=1, asymmetry_angle=0, azimuthal_angle=0.0, energy_min=8174, energy_max=8174, energy_points=1, angle_deviation_min=-20.0e-6, angle_deviation_max=20e-6, angle_deviation_points=5) angle_bragg = 0.19902705045 F_0 = 113.581288 + 1.763808j F_H = 43.814631 - 42.050823J F_H_bar = 42.050823 + 43.814631j # Test possible setup. diffraction._checkSetup(diffraction_setup, angle_bragg, F_0, F_H, F_H_bar) # Test impossible Bragg reflection. diffraction_setup._asymmetry_angle = 45 * numpy.pi / 180 self.assertRaises(ReflectionImpossibleException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, F_H, F_H_bar) diffraction_setup._geometry_type = BraggTransmission() self.assertRaises(ReflectionImpossibleException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, F_H, F_H_bar) # Test impossible Laue reflection. diffraction_setup._asymmetry_angle = 10 * numpy.pi / 180 diffraction_setup._geometry_type = LaueDiffraction() self.assertRaises(TransmissionImpossibleException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, F_H, F_H_bar) diffraction_setup._geometry_type = LaueTransmission() self.assertRaises(TransmissionImpossibleException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, F_H, F_H_bar) # Test forbidden reflection diffraction_setup._geometry_type = BraggDiffraction() diffraction_setup._asymmetry_angle = 0 # ... for F_0. self.assertRaises(StructureFactorF0isZeroException, diffraction._checkSetup, diffraction_setup, angle_bragg, 0.0, F_H, F_H_bar) # ... for F_H. self.assertRaises(StructureFactorFHisZeroException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, 0.0, F_H_bar) self.assertRaises(StructureFactorFHisZeroException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, float('nan') * 1j, F_H_bar) # ... for F_H_bar. self.assertRaises(StructureFactorFHbarIsZeroException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, F_H, 0.0) self.assertRaises(StructureFactorFHbarIsZeroException, diffraction._checkSetup, diffraction_setup, angle_bragg, F_0, F_H, float('nan') * 1j)
def calculate_simple_diffraction_angular_scan_accelerated(): # Create a diffraction setup. diffraction_setup_dabax = DiffractionSetupDabax( geometry_type=BraggDiffraction(), # GeometryType object crystal_name="YB66", # string thickness=7e-3, # meters miller_h=4, # int miller_k=0, # int miller_l=0, # int asymmetry_angle= 0, #10.0*numpy.pi/180., # radians azimuthal_angle=0.0, dabax=DabaxXraylib()) # radians energy = 8040.0 # eV angle_deviation_min = 20e-6 # radians angle_deviation_max = 80e-6 # radians angle_deviation_points = 200 angle_step = (angle_deviation_max - angle_deviation_min) / angle_deviation_points # # gets Bragg angle needed to create deviation's scan # bragg_angle = diffraction_setup_dabax.angleBragg(energy) print("Bragg angle for E=%f eV is %f deg" % (energy, bragg_angle * 180.0 / numpy.pi)) # Create a Diffraction object (the calculator) diffraction = Diffraction() diffraction_dabax = Diffraction() # initialize arrays for storing outputs deviations = numpy.zeros(angle_deviation_points) intensityS = numpy.zeros(angle_deviation_points) intensityP = numpy.zeros(angle_deviation_points) intensityS_dabax = numpy.zeros(angle_deviation_points) intensityP_dabax = numpy.zeros(angle_deviation_points) for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step angle = deviation + bragg_angle # calculate the components of the unitary vector of the incident photon scan # Note that diffraction plane is YZ yy = numpy.cos(angle) zz = -numpy.abs(numpy.sin(angle)) photon = Photon(energy_in_ev=energy, direction_vector=Vector(0.0, yy, zz)) # perform the calculation coeffs = diffraction.calculateDiffractedComplexAmplitudes( diffraction_setup_dabax, photon) # store results deviations[ia] = deviation intensityS[ia] = coeffs['S'].intensity() intensityP[ia] = coeffs['P'].intensity() psi_0, psi_H, psi_H_bar = diffraction_setup_dabax.psiAll(energy) for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step angle = deviation + bragg_angle # calculate the components of the unitary vector of the incident photon scan # Note that diffraction plane is YZ yy = numpy.cos(angle) zz = -numpy.abs(numpy.sin(angle)) photon = Photon(energy_in_ev=energy, direction_vector=Vector(0.0, yy, zz)) # perform the calculation # coeffs_dabax = diffraction_dabax.calculateDiffractedComplexAmplitudes(diffraction_setup_dabax, photon) # # # store results # deviations[ia] = deviation # intensityS_dabax[ia] = coeffs_dabax['S'].intensity() # intensityP_dabax[ia] = coeffs_dabax['P'].intensity() # Create PerfectCrystalDiffraction instance. perfect_crystal = PerfectCrystalDiffraction( geometry_type=diffraction_setup_dabax.geometryType(), bragg_normal=diffraction_setup_dabax.normalBragg(), surface_normal=diffraction_setup_dabax.normalSurface(), bragg_angle=diffraction_setup_dabax.angleBragg(energy), psi_0=psi_0, psi_H=psi_H, psi_H_bar=psi_H_bar, thickness=diffraction_setup_dabax.thickness(), d_spacing=diffraction_setup_dabax.dSpacing() * 1e-10) complex_amplitudes = perfect_crystal.calculateDiffraction(photon) deviations[ia] = deviation intensityS_dabax[ia] = complex_amplitudes['S'].intensity( ) # 0.0 # coeffs_dabax['S'].intensity() intensityP_dabax[ia] = complex_amplitudes['P'].intensity( ) # 0.0 # coeffs_dabax['P'].intensity() # plot results import matplotlib.pylab as plt plt.plot(1e6 * deviations, intensityS_dabax) plt.plot(1e6 * deviations, intensityP_dabax) plt.xlabel("deviation angle [urad]") plt.ylabel("Reflectivity") plt.legend(["Sigma-polarization DABAX", "Pi-polarization DABAX"]) plt.show()
def testGeometryType(self): diffraction_setup = diffractionSetup() self.assertEqual(diffraction_setup.geometryType(), BraggDiffraction())
def align_crystal(self): oe = self.get_optical_element() coor = self.get_coordinates() if oe._material_constants_library_flag == 0: print("\nCreating a diffraction setup (XRAYLIB)...") diffraction_setup = DiffractionSetup( geometry_type=BraggDiffraction( ), # todo: use oe._diffraction_geometry crystal_name=oe._material, # string thickness=oe._thickness, # meters miller_h=oe._miller_index_h, # int miller_k=oe._miller_index_k, # int miller_l=oe._miller_index_l, # int asymmetry_angle=oe._asymmetry_angle, # radians azimuthal_angle=0.0) elif oe._material_constants_library_flag == 1: print("\nCreating a diffraction setup (DABAX)...") diffraction_setup = DiffractionSetupDabax( geometry_type=BraggDiffraction( ), # todo: use oe._diffraction_geometry crystal_name=oe._material, # string thickness=oe._thickness, # meters miller_h=oe._miller_index_h, # int miller_k=oe._miller_index_k, # int miller_l=oe._miller_index_l, # int asymmetry_angle=oe._asymmetry_angle, # radians azimuthal_angle=0.0) elif oe._material_constants_library_flag == 2: print( "\nCreating a diffraction setup (shadow preprocessor file V1)..." ) diffraction_setup = DiffractionSetupShadowPreprocessorV1( geometry_type=BraggDiffraction( ), # todo: use oe._diffraction_geometry crystal_name=oe._material, # string thickness=oe._thickness, # meters miller_h=oe._miller_index_h, # int miller_k=oe._miller_index_k, # int miller_l=oe._miller_index_l, # int asymmetry_angle=oe._asymmetry_angle, # radians azimuthal_angle=0.0, preprocessor_file=oe._file_refl) elif oe._material_constants_library_flag == 3: print( "\nCreating a diffraction setup (shadow preprocessor file V2)..." ) diffraction_setup = DiffractionSetupShadowPreprocessorV2( geometry_type=BraggDiffraction( ), # todo: use oe._diffraction_geometry crystal_name=oe._material, # string thickness=oe._thickness, # meters miller_h=oe._miller_index_h, # int miller_k=oe._miller_index_k, # int miller_l=oe._miller_index_l, # int asymmetry_angle=oe._asymmetry_angle, # radians azimuthal_angle=0.0, preprocessor_file=oe._file_refl) else: raise NotImplementedError self._crystalpy_diffraction_setup = diffraction_setup if oe._f_central: if oe._f_phot_cent == 0: energy = oe._phot_cent else: energy = codata.h * codata.c / codata.e * 1e2 / ( oe._phot_cent * 1e-8) setting_angle = diffraction_setup.angleBraggCorrected(energy) print("Bragg angle for E=%f eV is %f deg" % (energy, setting_angle * 180.0 / numpy.pi)) coor.set_angles(angle_radial=numpy.pi / 2 - setting_angle, angle_radial_out=numpy.pi / 2 - setting_angle, angle_azimuthal=0.0) else: print("Info: nothing to align: f_central=0") print(coor.info())
def calculate_with_crystalpy( bragg_or_laue=0, # diffracted_or_transmitted=0, # crystal_name="Si", # string thickness=1e-2, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle=0.0, # radians energy=8000.0, # eV angle_deviation_min=-100e-6, # radians angle_deviation_max=100e-6, # radians angle_deviation_points=500, method=0, # 0=crystalpy input, 1=shadow4 preprocessor file ): if bragg_or_laue == 0: if diffracted_or_transmitted == 0: geometry_type = BraggDiffraction() elif diffracted_or_transmitted == 1: geometry_type = BraggTransmission() else: raise Exception("Bad geometry type") elif bragg_or_laue == 1: if diffracted_or_transmitted == 0: geometry_type = LaueDiffraction() elif diffracted_or_transmitted == 1: geometry_type = LaueTransmission() else: raise Exception("Bad geometry type") else: raise Exception("Bad geometry type") # Create a diffraction setup. # print("\nCreating a diffraction setup...") if method == 0: diffraction_setup = DiffractionSetup(geometry_type=geometry_type, crystal_name=crystal_name, thickness=thickness, miller_h=miller_h, miller_k=miller_k, miller_l=miller_l, asymmetry_angle=asymmetry_angle, azimuthal_angle=0.0) else: create_bragg_preprocessor_file_v1(interactive=False, DESCRIPTOR=crystal_name, H_MILLER_INDEX=miller_h, K_MILLER_INDEX=miller_k, L_MILLER_INDEX=miller_l, TEMPERATURE_FACTOR=1.0, E_MIN=5000.0, E_MAX=15000.0, E_STEP=100.0, SHADOW_FILE="bragg_xop.dat") diffraction_setup = DiffractionSetupShadowPreprocessor( geometry_type=geometry_type, crystal_name=crystal_name, thickness=thickness, miller_h=miller_h, miller_k=miller_k, miller_l=miller_l, asymmetry_angle=asymmetry_angle, azimuthal_angle=0.0, preprocessor_file="bragg_xop.dat") angle_step = (angle_deviation_max - angle_deviation_min) / angle_deviation_points # # gets Bragg angle needed to create deviation's scan # bragg_angle = diffraction_setup.angleBragg(energy) # print("Bragg angle for E=%f eV is %f deg"%(energy,bragg_angle*180.0/numpy.pi)) # Create a Diffraction object (the calculator) diffraction = Diffraction() # initialize arrays for storing outputs deviations = numpy.zeros(angle_deviation_points) intensityS = numpy.zeros(angle_deviation_points) intensityP = numpy.zeros(angle_deviation_points) for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step # angle = deviation + bragg_angle + asymmetry_angle # # calculate the components of the unitary vector of the incident photon scan # # Note that diffraction plane is YZ # yy = numpy.cos(angle) # zz = - numpy.abs(numpy.sin(angle)) # photon = Photon(energy_in_ev=energy,direction_vector=Vector(0.0,yy,zz)) k_unitary = diffraction_setup.incomingPhotonDirection( energy, deviation) # or equivalently # k_0_unitary = diffraction_setup.incomingPhotonDirection(energy, 0.0) # k_unitary = k_0_unitary.rotateAroundAxis( Vector(1.0,0.0,0.0), -deviation) photon = Photon(energy_in_ev=energy, direction_vector=k_unitary) # perform the calculation coeffs = diffraction.calculateDiffractedComplexAmplitudes( diffraction_setup, photon) # store results deviations[ia] = deviation intensityS[ia] = coeffs['S'].intensity() intensityP[ia] = coeffs['P'].intensity() return deviations, intensityS, intensityP
def testConstructor(self): bragg_diffraction = BraggDiffraction() self.assertEqual(bragg_diffraction.description(), "Bragg diffraction")
def calculate_simple_diffraction(): # Create a diffraction setup. print("\nCreating a diffraction setup...") diffraction_setup = DiffractionSetup( geometry_type=BraggDiffraction(), # GeometryType object crystal_name="Si", # string thickness=1e-2, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle= 0, #10.0*numpy.pi/180., # radians azimuthal_angle=0.0) # radians # int energy = 8000.0 # eV angle_deviation_min = -100e-6 # radians angle_deviation_max = 100e-6 # radians angle_deviation_points = 500 angle_step = (angle_deviation_max - angle_deviation_min) / angle_deviation_points # # gets Bragg angle needed to create deviation's scan # bragg_angle = diffraction_setup.angleBragg(energy) print("Bragg angle for E=%f eV is %f deg" % (energy, bragg_angle * 180.0 / numpy.pi)) # Create a Diffraction object (the calculator) diffraction = Diffraction() # initialize arrays for storing outputs deviations = numpy.zeros(angle_deviation_points) intensityS = numpy.zeros(angle_deviation_points) intensityP = numpy.zeros(angle_deviation_points) for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step angle = deviation + bragg_angle # calculate the components of the unitary vector of the incident photon scan # Note that diffraction plane is YZ yy = numpy.cos(angle) zz = -numpy.abs(numpy.sin(angle)) photon = Photon(energy_in_ev=energy, direction_vector=Vector(0.0, yy, zz)) # perform the calculation coeffs = diffraction.calculateDiffractedComplexAmplitudes( diffraction_setup, photon) # store results deviations[ia] = deviation intensityS[ia] = coeffs['S'].intensity() intensityP[ia] = coeffs['P'].intensity() # plot results import matplotlib.pylab as plt plt.plot(1e6 * deviations, intensityS) plt.plot(1e6 * deviations, intensityP) plt.xlabel("deviation angle [urad]") plt.ylabel("Reflectivity") plt.legend(["Sigma-polarization", "Pi-polarization"]) plt.show()
def calculate_simple_diffraction(): # Create a diffraction setup. thickness = 2e-6 print("\nCreating a diffraction setup...") diffraction_setup_r = DiffractionSetup(geometry_type = BraggDiffraction(), # GeometryType object crystal_name = "Si", # string thickness = thickness, # meters miller_h = 1, # int miller_k = 1, # int miller_l = 1, # int asymmetry_angle = 0,#10.0*numpy.pi/180., # radians azimuthal_angle = 0.0) # radians # int diffraction_setup_t = DiffractionSetup(geometry_type = BraggTransmission(), # GeometryType object crystal_name = "Si", # string thickness = thickness, # meters miller_h = 1, # int miller_k = 1, # int miller_l = 1, # int asymmetry_angle = 0,#10.0*numpy.pi/180., # radians azimuthal_angle = 0.0) # radians diffraction_setup_r_half = DiffractionSetup(geometry_type = BraggDiffraction(), # GeometryType object crystal_name = "Si", # string thickness = thickness/2, # meters miller_h = 1, # int miller_k = 1, # int miller_l = 1, # int asymmetry_angle = 0,#10.0*numpy.pi/180., # radians azimuthal_angle = 0.0) # radians # int diffraction_setup_t_half = DiffractionSetup(geometry_type = BraggTransmission(), # GeometryType object crystal_name = "Si", # string thickness = thickness/2, # meters miller_h = 1, # int miller_k = 1, # int miller_l = 1, # int asymmetry_angle = 0,#10.0*numpy.pi/180., # radians azimuthal_angle = 0.0) # radians energy = 8000.0 # eV angle_deviation_min = -300e-6 # radians angle_deviation_max = 300e-6 # radians angle_deviation_points = 500 wavelength = codata.h * codata.c / codata.e / energy print(">>>>>>>>>>>>", wavelength) angle_step = (angle_deviation_max-angle_deviation_min)/angle_deviation_points # # gets Bragg angle needed to create deviation's scan # bragg_angle = diffraction_setup_r.angleBragg(energy) print("Bragg angle for E=%f eV is %f deg"%(energy,bragg_angle*180.0/numpy.pi)) # Create a Diffraction object (the calculator) diffraction = Diffraction() # initialize arrays for storing outputs deviations = numpy.zeros(angle_deviation_points) intensityS_r = numpy.zeros(angle_deviation_points) intensityS_r_half = numpy.zeros(angle_deviation_points) intensityS_t = numpy.zeros(angle_deviation_points) intensityS_rr = numpy.zeros(angle_deviation_points) intensityS_tt = numpy.zeros(angle_deviation_points) r = numpy.zeros(angle_deviation_points, dtype=complex) r2um = numpy.zeros(angle_deviation_points, dtype=complex) t = numpy.zeros(angle_deviation_points, dtype=complex) for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step angle = deviation + bragg_angle # calculate the components of the unitary vector of the incident photon scan # Note that diffraction plane is YZ yy = numpy.cos(angle) zz = - numpy.abs(numpy.sin(angle)) photon = Photon(energy_in_ev=energy,direction_vector=Vector(0.0,yy,zz)) # perform the calculation coeffs_r = diffraction.calculateDiffractedComplexAmplitudes(diffraction_setup_r, photon) coeffs_t = diffraction.calculateDiffractedComplexAmplitudes(diffraction_setup_t, photon) coeffs_r_half = diffraction.calculateDiffractedComplexAmplitudes(diffraction_setup_r_half, photon) coeffs_t_half = diffraction.calculateDiffractedComplexAmplitudes(diffraction_setup_t_half, photon) # coeffs_rr = \ # coeffs_r_half['S'] * \ # (coeffs_t_half['S']**0 + \ # coeffs_t_half['S']**2 * ( \ # coeffs_r_half['S'] ** 0 + \ # coeffs_r_half['S'] ** 2 + \ # coeffs_r_half['S'] ** 4 + \ # coeffs_r_half['S'] ** 6 + \ # coeffs_r_half['S'] ** 8 + \ # coeffs_r_half['S'] ** 10 + \ # coeffs_r_half['S'] ** 12 + \ # coeffs_r_half['S'] ** 14 + \ # coeffs_r_half['S'] ** 16 + \ # coeffs_r_half['S'] ** 18 \ # ) ) # a = coeffs_r_half['S'] # b = coeffs_t_half['S'] r[ia] = coeffs_r_half['S'].complexAmplitude() # t[ia] = coeffs_t_half['S'].complexAmplitude() #* numpy.exp(1j * 2 * numpy.pi / wavelength * (0.5 * thickness / numpy.sin(bragg_angle)) ) t[ia] = coeffs_t_half['S'].complexAmplitude() * numpy.exp(-1j * 2 * numpy.pi / wavelength * numpy.cos(bragg_angle) * deviation * (thickness/2) ) r2um[ia] = coeffs_r['S'].complexAmplitude() # # sum = a**0 # # for i in range(2,400,2): # # sum += a**i # sum = a**0 / (a**0 - a**2) # # coeffs_rr = a * (b**0 + b**2 * sum) # one = a**0 # coeffs_rr = a * ( one + b**2 / (one - a**2)) # coeffs_tt = b**2 * sum # # intensityS_rr[ia] = coeffs_rr.intensity() # intensityS_tt[ia] = coeffs_tt.intensity() # # # print(coeffs_r) # # print(coeffs_r['S'].complexAmplitude()) # # # store results deviations[ia] = deviation # intensityS_r[ia] = coeffs_r['S'].intensity() # intensityS_r_half[ia] = coeffs_r_half['S'].intensity() # intensityS_t[ia] = coeffs_t['S'].intensity() # print(">>>>>>>>>>", coeffs_r['S'].complexAmplitude() , coeffs_rr.complexAmplitude() ) # plot results print(r, r.shape) from srxraylib.plot.gol import plot # plot(1e6 * deviations, numpy.abs(r)**2, # 1e6 * deviations, numpy.abs(t)**2, # ) # plot(1e6 * deviations, numpy.abs(r)**2, 1e6 * deviations, numpy.abs(r+r*t*t/(1-r*r))**2, 1e6 * deviations, numpy.abs(r2um) ** 2, 1e6 * deviations, numpy.abs(r2um) ** 2 - numpy.abs(r+r*t*t/(1-r*r))**2, legend=['r','r2','r 2um','r 2 um - r2'] )