예제 #1
0
    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)
예제 #2
0
    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()
예제 #3
0
    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)
예제 #4
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
예제 #5
0
    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())
예제 #6
0
 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
예제 #8
0
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
예제 #10
0
    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)
예제 #11
0
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
예제 #12
0
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)
예제 #15
0
    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
예제 #17
0
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
예제 #22
0
    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
예제 #23
0
    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)
예제 #24
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 testGeometryType(self):
     diffraction_setup = diffractionSetup()
     self.assertEqual(diffraction_setup.geometryType(), BraggDiffraction())
예제 #26
0
    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
예제 #28
0
 def testConstructor(self):
     bragg_diffraction = BraggDiffraction()
     self.assertEqual(bragg_diffraction.description(), "Bragg diffraction")
예제 #29
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()
예제 #30
0
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']
        )