Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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))
Esempio n. 6
0
    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)
Esempio n. 7
0
    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
Esempio n. 8
0
    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)
Esempio n. 9
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)
Esempio n. 10
0
    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)
Esempio n. 12
0
    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])
Esempio n. 13
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 __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)
Esempio n. 15
0
    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
Esempio n. 16
0
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
Esempio n. 17
0
    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
Esempio n. 19
0
    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))
Esempio n. 20
0
 def testEnergy(self):
     photon = Photon(4000, Vector(0, 0, 1))
     photon.setEnergy(8000.0)
     self.assertEqual(photon.energy(), 8000)
Esempio n. 21
0
    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)
Esempio n. 22
0
    def testUnitDirectionVector(self):
        photon = Photon(4000, Vector(0, 0, 5))

        self.assertTrue(photon.unitDirectionVector() == Vector(0, 0, 1))
Esempio n. 23
0
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
Esempio n. 25
0
    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)
Esempio n. 28
0
    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
Esempio n. 29
0
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)