def testDuplicate(self): photon_one = Photon(4000, Vector(0, 0, 5)) photon_two = photon_one.duplicate() self.assertTrue(photon_one == photon_two) photon_one.setEnergy(1000.0) self.assertFalse(photon_one == photon_two)
def testOperatorNotEqual(self): photon_one = Photon(4000, Vector(0, 0, 5)) photon_two = Photon(4000, Vector(0, 1, 1)) photon_three = Photon(2000, Vector(0, 0, 5)) self.assertFalse(photon_one != photon_one) self.assertTrue(photon_one != photon_two) self.assertTrue(photon_one != photon_three) self.assertTrue(photon_two != photon_three)
def testWavevector(self): direction = Vector(0, 0, 1) photon = Photon(5000.0, direction) wavevector = photon.wavevector() self.assertAlmostEqual(wavevector.norm(), 25338653792.67, places=1) self.assertEqual(wavevector.getNormalizedVector(), direction)
def testWavenumber(self): # Test data in eV : m^-1. test_data = { 3: 15203192.28, 4: 20270923.03, 8: 40541846.07, 5000: 25338653792.67, 10000: 50677307585.34 } for energy, wavenumber in test_data.items(): photon = Photon(energy, Vector(0, 0, 1)) self.assertAlmostEqual(photon.wavenumber(), wavenumber, places=1)
def testFromList(self): npoint = 1000 vx = numpy.zeros(npoint) + 0.0 vy = numpy.zeros(npoint) + 1.0 vz = numpy.zeros(npoint) + 0.0 energy = numpy.zeros(npoint) + 3000.0 photon_bunch1 = PhotonBunch() photon_bunch2 = PhotonBunch() photons_list = list() for i in range(npoint): photon = Photon(energy_in_ev=energy[i], direction_vector=Vector(vx[i], vy[i], vz[i])) photon_bunch1.addPhoton(photon) photons_list.append(photon) photon_bunch2.addPhotonsFromList(photons_list) energies = photon_bunch1.getArrayByKey("energies") for energy in energies: self.assertAlmostEqual(energy, 3000.0) for i in range(len(photon_bunch1)): # print("checking photon %d "%i) self.assertTrue( photon_bunch1.getPhotonIndex(i) == photon_bunch2.getPhotonIndex(i))
def testWavelength(self): # Test data in eV : m. test_data = { 3: 413.28 * 1e-9, 4: 309.96 * 1e-9, 8: 154.98 * 1e-9, 5000: 2.4797 * 1e-10, 10000: 1.2398 * 1e-10 } for energy, wavelength in test_data.items(): photon = Photon(energy, Vector(0, 0, 1)) # print("Energy=%f, Wavelength=%f A (reference = %f A)"%(energy,1e10*photon.wavelength(),1e10*wavelength)) self.assertAlmostEqual(1e10 * photon.wavelength(), 1e10 * wavelength, places=1)
def _perfectCrystalForEnergy(self, diffraction_setup, energy): # Retrieve bragg angle. angle_bragg = diffraction_setup.angleBragg(energy) # Get structure factors for all relevant lattice vectors 0,H,H_bar. F_0 = diffraction_setup.F0(energy) F_H = diffraction_setup.FH(energy) F_H_bar = diffraction_setup.FH_bar(energy) # Check if given Bragg/Laue geometry and given miller indices are possible. self._checkSetup(diffraction_setup, angle_bragg, F_0, F_H, F_H_bar) # Log the structure factors. if self.isDebug: self.logStructureFactors(F_0, F_H, F_H_bar) # Retrieve lattice spacing d. d_spacing = diffraction_setup.dSpacing() * 1e-10 # Calculate the Bragg normal B_H. normal_bragg = diffraction_setup.normalBragg() # Calculate the surface normal n. normal_surface = diffraction_setup.normalSurface() # Calculate the incoming photon direction (parallel to k_0). photon_direction = diffraction_setup.incomingPhotonDirection( energy, 0.0) # Create photon k_0. photon_in = Photon(energy, photon_direction) # Retrieve unitcell volume from xraylib. unitcell_volume = diffraction_setup.unitcellVolume() * 10**-30 # Calculate psis as defined in Zachariasen [3-95] psi_0 = self._calculatePsiFromStructureFactor(unitcell_volume, photon_in, F_0) psi_H = self._calculatePsiFromStructureFactor(unitcell_volume, photon_in, F_H) psi_H_bar = self._calculatePsiFromStructureFactor( unitcell_volume, photon_in, F_H_bar) # Create PerfectCrystalDiffraction instance. perfect_crystal = PerfectCrystalDiffraction( geometry_type=diffraction_setup.geometryType(), bragg_normal=normal_bragg, surface_normal=normal_surface, bragg_angle=angle_bragg, psi_0=psi_0, psi_H=psi_H, psi_H_bar=psi_H_bar, thickness=diffraction_setup.thickness(), d_spacing=d_spacing) return perfect_crystal
def testGetArrayByKey(self): photon = Photon(energy_in_ev=8000.0) bunch = PhotonBunch() for i in range(10): bunch.addPhoton(photon) assert_array_almost_equal(bunch.getArrayByKey("energies"), numpy.ones(10) * 8000.0)
def testCalculatePsiFromStructureFactor(self): diffraction = Diffraction() crystal = xraylib.Crystal_GetCrystal("Si") photon_in = Photon(8000, Vector(-1, 0, -1)) structure_factor = 113.581288 + 1.763808j unitcell_volume = crystal['volume'] * 10**-30 psi = diffraction._calculatePsiFromStructureFactor( unitcell_volume, photon_in, structure_factor) self.assertAlmostEqual(psi.real, -1.527826e-5) self.assertAlmostEqual(psi.imag, -2.372566e-7)
def testAddPhoton(self): photon1 = Photon(energy_in_ev=1000.0) photon2 = Photon(energy_in_ev=2000.0) bunch = PhotonBunch() self.assertTrue(bunch.getNumberOfPhotons() == 0) bunch.addPhoton(photon1) bunch.addPhoton(photon2) self.assertTrue(bunch.getNumberOfPhotons() == 2) bunch.addPhotonsFromList([photon1, photon2]) self.assertTrue(bunch.getNumberOfPhotons() == 4) bunch.addBunch(bunch) self.assertTrue(bunch.getNumberOfPhotons() == 8)
def testDeviationOfIncomingPhoton(self): diffraction = diffractionSetup() for energy in [2500, 6000, 8000, 15000, 22000, 30000]: for test_deviation in [ 0.01, 0.03, 0.5, -0.1, -0.9, 0.00001, -0.0007 ]: photon_direction = diffraction.incomingPhotonDirection( energy, test_deviation) photon = Photon(energy, photon_direction) deviation = diffraction.deviationOfIncomingPhoton(photon) self.assertAlmostEqual(test_deviation, deviation)
def testChangePhotonValue(self): nphotons = 10 bunch = PhotonBunch() list_of_photons = [] for i in range(nphotons): photon = Photon(energy_in_ev=1000.0 + i, direction_vector=Vector(1.0, 0.0, 0)) bunch.addPhoton(photon) list_of_photons.append(photon) for i in range(bunch.getNumberOfPhotons()): self.assertTrue(bunch.getPhotonIndex(i) == list_of_photons[i])
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 __init__(self, energy_in_ev, direction_vector, Esigma=None, Epi=None): """ Constructor. :param complex_amplitude: Complex amplitude of the wave. """ # Call base constructor. Photon.__init__(self, energy_in_ev, direction_vector) if Esigma == None: self._Esigma = ComplexAmplitude(1 / numpy.sqrt(2) + 0j) else: if isinstance(Esigma, ComplexAmplitude): self._Esigma = Esigma else: self._Esigma = ComplexAmplitude(Esigma) if Epi == None: self._Epi = ComplexAmplitude(1 / numpy.sqrt(2) + 0j) else: if isinstance(Epi, ComplexAmplitude): self._Epi = Epi else: self._Epi = ComplexAmplitude(Epi)
def _calculateDiffractionForEnergy(self, diffraction_setup, energy, result): """ Calculates the diffraction/transmission given by the setup. :param diffraction_setup: The diffraction setup. :return: DiffractionResult representing this setup. """ # Get PerfectCrystal instance for the current energy. if not isinstance(diffraction_setup, DiffractionSetupSweeps): raise Exception("Inmut must be of type: DiffractionSetupSweeps") perfect_crystal = self._perfectCrystalForEnergy( diffraction_setup, energy) # Raise calculation start. self._onCalculationStart() # For every deviation from Bragg angle ... for index, deviation in enumerate( diffraction_setup.angleDeviationGrid()): # Raise OnProgress event if progressed by 10 percent. self._onProgressEveryTenPercent( index, diffraction_setup.angleDeviationPoints()) # Calculate deviated incoming photon. photon_direction = diffraction_setup.incomingPhotonDirection( energy, deviation) photon_in = Photon(energy, photon_direction) # Calculate diffraction for current incoming photon. result_deviation = perfect_crystal.calculateDiffraction(photon_in) # Calculate polarization difference between pi and sigma polarization. polarization_difference = result_deviation["P"] / result_deviation[ "S"] # Add result of current deviation. result.add(energy, deviation, result_deviation["S"], result_deviation["P"], polarization_difference) # Raise calculation end. self._onCalculationEnd() # Return diffraction results. return result
def calculate_laue_monochromator(energy_setup=8000.0,energies=numpy.linspace(7990,8010,200)): diffraction_setup_r = DiffractionSetup(geometry_type=LaueDiffraction(), # GeometryType object crystal_name="Si", # string thickness=10e-6, # meters miller_h=1, # int miller_k=1, # int miller_l=1, # int asymmetry_angle=numpy.pi/2, # 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 + numpy.pi / 2 + 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 __init__(self, geometry_type, crystal_name, thickness, miller_h, miller_k, miller_l, asymmetry_angle, azimuthal_angle, energy_min, energy_max, energy_points, angle_deviation_min, angle_deviation_max, angle_deviation_points): """ Constructor. :param geometry_type: GeometryType (BraggDiffraction,...). :param crystal_name: The name of the crystal, e.g. Si. :param thickness: The crystal thickness. :param miller_h: Miller index H. :param miller_k: Miller index K. :param miller_l: Miller index L. :param asymmetry_angle: The asymmetry angle between surface normal and Bragg normal. :param azimuthal_angle: The angle between the projection of the Bragg normal on the crystal surface plane and the x axis. :param energy_min: The minimum energy. :param energy_max: The maximum energy. :param energy_points: Number of energy points. :param angle_deviation_min: Minimal angle deviation. :param angle_deviation_max: Maximal angle deviation. :param angle_deviation_points: Number of deviations points. """ energies = numpy.linspace(energy_min, energy_max, energy_points) deviations = numpy.linspace(angle_deviation_min, angle_deviation_max, angle_deviation_points) # Create an "info setup" solely for the determination of deviation angles. info_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=azimuthal_angle,) # incoming_photons=[Photon(energy_min, Vector(0, 0, -1))]) # Call base constructor. DiffractionSetup.__init__(self, 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=azimuthal_angle,) # incoming_photons=photons) # Create photons according to sweeps. photons = PhotonBunch() # list() for energy in energies: for deviation in deviations: direction = info_setup.incomingPhotonDirection(energy, deviation) incoming_photon = Photon(energy, direction) # photons.append(incoming_photon) photons.addPhoton(incoming_photon) self._incoming_photons = photons # [email protected]: in theory, not needed as this info is in _incoming_photons # but buffering this accelerates a lot the calculations self._deviations = None self._energies = None
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): photon = Photon(4000, Vector(0, 0, 1)) self.assertIsInstance(photon, Photon) self.assertEqual(photon.energy(), 4000) self.assertTrue(photon.unitDirectionVector() == Vector(0, 0, 1))
def testEnergy(self): photon = Photon(4000, Vector(0, 0, 1)) photon.setEnergy(8000.0) self.assertEqual(photon.energy(), 8000)
print("PSI0 ", a.psi0(energy)) print("PSIH ", a.psiH(energy)) print("PSIH_bar ", a.psiH_bar(energy)) # print("V0: ", a.vectorK0direction(energy).components()) print("Bh direction: ", a.vectorHdirection().components()) print("Bh: ", a.vectorH().components()) print("K0: ", a.vectorK0(energy).components()) print("Kh: ", a.vectorKh(energy).components()) print("Vh: ", a.vectorKhdirection(energy).components()) # # from crystalpy.util.Photon import Photon print( "Difference to ThetaB uncorrected: ", a.deviationOfIncomingPhoton( Photon(energy_in_ev=energy, direction_vector=a.vectorK0(energy)))) # # print("Asymmerey factor b: ", a.asymmetryFactor(energy)) print("Bragg angle: %g deg " % (a.angleBragg(energy) * 180 / numpy.pi)) # print("Bragg angle corrected: %g deg " % (a.angleBraggCorrected(energy) * 180 / numpy.pi)) # VIN_BRAGG_UNCORR (Uncorrected): ( 0.00000000, 0.968979, -0.247145) # VIN_BRAGG (Corrected): ( 0.00000000, 0.968971, -0.247176) # VIN_BRAGG_ENERGY : ( 0.00000000, 0.968971, -0.247176) # Reflected directions matching Bragg angle: # VOUT_BRAGG_UNCORR (Uncorrected): ( 0.00000000, 0.968979, 0.247145) # VOUT_BRAGG (Corrected): ( 0.00000000, 0.968971, 0.247176) # VOUT_BRAGG_ENERGY : ( 0.00000000, 0.968971, 0.247176)
def testUnitDirectionVector(self): photon = Photon(4000, Vector(0, 0, 5)) self.assertTrue(photon.unitDirectionVector() == Vector(0, 0, 1))
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_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 testSetUnitDirectionVector(self): photon = Photon(4000, Vector(0, 0, 5)) photon.setUnitDirectionVector(Vector(1, 2, 3)) self.assertTrue(photon.unitDirectionVector() == Vector( 1, 2, 3).getNormalizedVector())
def generatePhotonIn(): direction = Vector(-0.7742395148517507, -0.0, -0.6328927031038719) return Photon(3124, direction)
def generatePhotonOut(): direction = Vector(-0.7742395017022543, 0.0, 0.6328927191901048) return Photon(3124, direction)
def trace_beam(self, beam_in, flag_lost_value=-1): p = self.get_coordinates().p() q = self.get_coordinates().q() theta_grazing1 = numpy.pi / 2 - self.get_coordinates().angle_radial() theta_grazing2 = numpy.pi / 2 - self.get_coordinates( ).angle_radial_out() alpha1 = self.get_coordinates().angle_azimuthal() # beam = beam_in.duplicate() # # put beam in mirror reference system # beam.rotate(alpha1, axis=2) beam.rotate(theta_grazing1, axis=1) beam.translation([ 0.0, -p * numpy.cos(theta_grazing1), p * numpy.sin(theta_grazing1) ]) # # reflect beam in the mirror surface # soe = self.get_optical_element() beam_in_crystal_frame_before_reflection = beam.duplicate() if not isinstance(soe, Crystal): # undefined raise Exception("Undefined Crystal") else: beam_mirr, normal = self.apply_crystal_diffraction( beam) # warning, beam is also changed!! # # apply mirror boundaries # beam_mirr.apply_boundaries_syned(soe.get_boundary_shape(), flag_lost_value=flag_lost_value) ######################################################################################## # # TODO" apply crystal reflectivity # nrays = beam_mirr.get_number_of_rays() # energy = 8000.0 # eV # Create a Diffraction object (the calculator) diffraction = Diffraction() scan_type = 1 # 0=scan, 1=loop on rays, 2=bunch of photons (not functional) # TODO: delete 0,2 if scan_type == 0: # scan energy = 8000.0 # eV # setting_angle = self._crystalpy_diffraction_setup.angleBragg(energy) setting_angle = self._crystalpy_diffraction_setup.angleBraggCorrected( energy) angle_deviation_points = nrays # initialize arrays for storing outputs intensityS = numpy.zeros(nrays) intensityP = numpy.zeros(nrays) angle_deviation_min = -100e-6 # radians angle_deviation_max = 100e-6 # radians angle_step = (angle_deviation_max - angle_deviation_min) / angle_deviation_points deviations = numpy.zeros(angle_deviation_points) for ia in range(angle_deviation_points): deviation = angle_deviation_min + ia * angle_step angle = deviation + setting_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)) # if ia < 10: print(ia, 0.0, yy, zz) # perform the calculation coeffs = diffraction.calculateDiffractedComplexAmplitudes( self._crystalpy_diffraction_setup, photon) # store results deviations[ia] = deviation intensityS[ia] = coeffs['S'].intensity() intensityP[ia] = coeffs['P'].intensity() elif scan_type == 1: # from beam, loop # initialize arrays for storing outputs complex_reflectivity_S = numpy.zeros(nrays, dtype=complex) complex_reflectivity_P = numpy.zeros(nrays, dtype=complex) # we retrieve data from "beam" meaning the beam before reflection, in the crystal frame (incident beam...) xp = beam_in_crystal_frame_before_reflection.get_column(4) yp = beam_in_crystal_frame_before_reflection.get_column(5) zp = beam_in_crystal_frame_before_reflection.get_column(6) energies = beam_in_crystal_frame_before_reflection.get_photon_energy_eV( ) for ia in range(nrays): photon = Photon(energy_in_ev=energies[ia], direction_vector=Vector( xp[ia], yp[ia], zp[ia])) # if ia < 10: print(ia, xp[ia], yp[ia], zp[ia]) # perform the calculation coeffs = diffraction.calculateDiffractedComplexAmplitudes( self._crystalpy_diffraction_setup, photon) # store results complex_reflectivity_S[ia] = coeffs['S'].complexAmplitude() complex_reflectivity_P[ia] = coeffs['P'].complexAmplitude() beam_mirr.apply_complex_reflectivities(complex_reflectivity_S, complex_reflectivity_P) elif scan_type == 2: # from beam, bunch # this is complicated... and not faster... # todo: accelerate crystalpy create calculateDiffractedComplexAmplitudes for a PhotonBunch # we retrieve data from "beam" meaning the beam before reflection, in the crystal frame (incident beam...) xp = beam_in_crystal_frame_before_reflection.get_column(4) yp = beam_in_crystal_frame_before_reflection.get_column(5) zp = beam_in_crystal_frame_before_reflection.get_column(6) energies = beam_in_crystal_frame_before_reflection.get_photon_energy_eV( ) Esigma = numpy.sqrt(beam_in_crystal_frame_before_reflection.get_column(24)) * \ numpy.exp(1j * beam_in_crystal_frame_before_reflection.get_column(14)) Epi = numpy.sqrt(beam_in_crystal_frame_before_reflection.get_column(25)) * \ numpy.exp(1j * beam_in_crystal_frame_before_reflection.get_column(15)) photons = ComplexAmplitudePhotonBunch() for ia in range(nrays): photons.addPhoton( ComplexAmplitidePhoton( energy_in_ev=energies[ia], direction_vector=Vector(xp[ia], yp[ia], zp[ia]), Esigma=1.0, # Esigma[ia], Epi=1.0, # [ia], )) bunch_out = diffraction.calculateDiffractedComplexAmplitudePhotonBunch( self._crystalpy_diffraction_setup, photons) bunch_out_dict = bunch_out.toDictionary() reflectivity_S = numpy.sqrt( numpy.array(bunch_out_dict["intensityS"])) reflectivity_P = numpy.sqrt( numpy.array(bunch_out_dict["intensityP"])) beam_mirr.apply_reflectivities(reflectivity_S, reflectivity_P) beam_mirr.add_phases(numpy.array(bunch_out_dict["intensityS"]), numpy.array(bunch_out_dict["intensityP"])) ######################################################################################## # # from element reference system to image plane # beam_out = beam_mirr.duplicate() beam_out.change_to_image_reference_system(theta_grazing2, q) # plot results if False: if scan_type == 0: pass else: deviations = beam_out.get_column(6) intensityS = beam_out.get_column(24) intensityP = beam_out.get_column(25) from srxraylib.plot.gol import plot plot(1e6 * deviations, intensityS, 1e6 * deviations, intensityP, xtitle="deviation angle [urad]", ytitle="Reflectivity", legend=["Sigma-polarization", "Pi-polarization"], linestyle=['', ''], marker=['+', '.']) return beam_out, beam_mirr
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 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)