Skip to content

Commit

Permalink
update for shadow4
Browse files Browse the repository at this point in the history
  • Loading branch information
srio committed Oct 12, 2023
1 parent cd870be commit 4a45fd7
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 35 deletions.
104 changes: 71 additions & 33 deletions crystalpy/diffraction/Diffraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,53 +502,91 @@ def _checkSetupDiffraction(cls, diffraction_setup, bragg_angle):
# ##################################################################################################

@classmethod
def _perfectCrystalForEnergy(cls, diffraction_setup, energy):
def _perfectCrystalForEnergy(cls, diffraction_setup, energy,
geometry_type=None,
bragg_normal=None,
surface_normal=None,
# bragg_angle=None,
# psi_0=None,
# psi_H=None,
# psi_H_bar=None,
thickness=None,
d_spacing=None,
):
"""
Creates a PerfectCrystalDiffraction instance from parameters in a DiffractionSetupAbstract instance and a
photon energy array.
Parameters
----------
diffraction_setup :
diffraction_setup : instance of PerfectCrystalDiffraction
energy :
energy : numpy array
geometry_type: instance of BraggDiffraction, LaueDiffraction, BraggTransmission, or LaueTransmission
Returns
-------
PerfectCrystalDiffraction instance
bragg_normal : instance of Vector, optional
if None, retrieve from DiffractionSetup
surface_normal : instance of Vector, optional
if None, retrieve from DiffractionSetup
"""
thickness : float or numpy array, optional
crystal thickness in m. If None, retrieve from DiffractionSetup
#
# energy-depending variables
#
# Retrieve bragg angle.
angle_bragg = diffraction_setup.angleBragg(energy)
d_spacing : float or numpy array
d-spacing in m. If None, retrieve from DiffractionSetup
# Check if given Bragg/Laue geometry and given miller indices are possible.
cls._checkSetupDiffraction(diffraction_setup, angle_bragg)

psi_0, psi_H, psi_H_bar = diffraction_setup.psiAll(energy)
Returns
-------
PerfectCrystalDiffraction instance
# Create PerfectCrystalDiffraction instance.
perfect_crystal = PerfectCrystalDiffraction(
geometry_type = diffraction_setup.geometryType(),
bragg_normal = diffraction_setup.vectorH(),
surface_normal = diffraction_setup.vectorNormalSurface(),
bragg_angle = angle_bragg,
psi_0 = psi_0,
psi_H = psi_H,
psi_H_bar = psi_H_bar,
thickness = diffraction_setup.thickness(),
d_spacing = diffraction_setup.dSpacing() * 1e-10,
)
"""

return perfect_crystal
return PerfectCrystalDiffraction.initializeFromDiffractionSetupAndEnergy(diffraction_setup, energy,
geometry_type=geometry_type,
bragg_normal=bragg_normal,
surface_normal=surface_normal,
# bragg_angle=None,
# psi_0=None,
# psi_H=None,
# psi_H_bar=None,
thickness=thickness,
d_spacing=d_spacing,
)

# #
# # energy-depending variables
# #
#
# # Retrieve bragg angle.
# bragg_angle = diffraction_setup.angleBragg(energy)
#
# # Check if given Bragg/Laue geometry and given miller indices are possible.
# cls._checkSetupDiffraction(diffraction_setup, bragg_angle)
#
# psi_0, psi_H, psi_H_bar = diffraction_setup.psiAll(energy)
#
#
# # Create PerfectCrystalDiffraction instance.
# perfect_crystal = PerfectCrystalDiffraction(
# geometry_type = geometry_type if not geometry_type is None else diffraction_setup.geometryType(),
# bragg_normal = bragg_normal if not bragg_normal is None else diffraction_setup.vectorH(),
# surface_normal = surface_normal if not surface_normal is None else diffraction_setup.vectorNormalSurface(),
# bragg_angle = bragg_angle,
# psi_0 = psi_0,
# psi_H = psi_H,
# psi_H_bar = psi_H_bar,
# thickness = thickness if not thickness is None else diffraction_setup.thickness(),
# d_spacing = d_spacing if not d_spacing is None else diffraction_setup.dSpacing() * 1e-10,
# )
#
# return perfect_crystal

@classmethod
def _perfectCrystalForPhoton(cls, diffraction_setup, polarized_photon):
def _perfectCrystalForPhoton(cls, diffraction_setup, polarized_photon, **kwargs):
"""
Parameters
Expand All @@ -563,11 +601,11 @@ def _perfectCrystalForPhoton(cls, diffraction_setup, polarized_photon):
"""

return cls._perfectCrystalForEnergy(diffraction_setup, polarized_photon.energy())
return cls._perfectCrystalForEnergy(diffraction_setup, polarized_photon.energy(), **kwargs)


@classmethod
def _perfectCrystalForPhotonBunch(cls, diffraction_setup, incoming_bunch):
def _perfectCrystalForPhotonBunch(cls, diffraction_setup, incoming_bunch, **kwargs):
"""
Parameters
Expand All @@ -582,7 +620,7 @@ def _perfectCrystalForPhotonBunch(cls, diffraction_setup, incoming_bunch):
PerfectCrystalDiffraction instance
"""
return cls._perfectCrystalForPhoton(diffraction_setup, incoming_bunch)
return cls._perfectCrystalForPhoton(diffraction_setup, incoming_bunch, **kwargs)


# these methods use DiffractionSetupSweeps (for scans)
Expand Down
92 changes: 90 additions & 2 deletions crystalpy/diffraction/PerfectCrystalDiffraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,78 @@ def __init__(self, geometry_type, bragg_normal, surface_normal, bragg_angle, psi
else:
self._calculation_strategy = CalculationStrategyMath()


@classmethod
def initializeFromDiffractionSetupAndEnergy(cls, diffraction_setup, energy,
geometry_type=None,
bragg_normal=None,
surface_normal=None,
# bragg_angle=None,
# psi_0=None,
# psi_H=None,
# psi_H_bar=None,
thickness=None,
d_spacing=None,
):
"""
Creates a PerfectCrystalDiffraction instance from parameters in a DiffractionSetupAbstract instance and a
photon energy array.
Parameters
----------
diffraction_setup : instance of PerfectCrystalDiffraction
energy : numpy array
geometry_type: instance of BraggDiffraction, LaueDiffraction, BraggTransmission, or LaueTransmission
bragg_normal : instance of Vector, optional
if None, retrieve from DiffractionSetup
surface_normal : instance of Vector, optional
if None, retrieve from DiffractionSetup
thickness : float or numpy array, optional
crystal thickness in m. If None, retrieve from DiffractionSetup
d_spacing : float or numpy array
d-spacing in m. If None, retrieve from DiffractionSetup
Returns
-------
PerfectCrystalDiffraction instance
"""

#
# energy-depending variables
#

# Retrieve bragg angle.
bragg_angle = diffraction_setup.angleBragg(energy)

psi_0, psi_H, psi_H_bar = diffraction_setup.psiAll(energy)

geometry_type = geometry_type if not geometry_type is None else diffraction_setup.geometryType()
bragg_normal = bragg_normal if not bragg_normal is None else diffraction_setup.vectorH()
surface_normal = surface_normal if not surface_normal is None else diffraction_setup.vectorNormalSurface()
thickness = thickness if not thickness is None else diffraction_setup.thickness()
d_spacing = d_spacing if not d_spacing is None else diffraction_setup.dSpacingSI()

return PerfectCrystalDiffraction(
geometry_type,
bragg_normal,
surface_normal,
bragg_angle,
psi_0,
psi_H,
psi_H_bar,
thickness,
d_spacing)


#
# getters
#
Expand Down Expand Up @@ -382,7 +454,6 @@ def surfaceNormal(self):

def surfaceNormalInwards(self):
"""Returns the surface normal that points inwards the crystal.
:return: Surface normal.
Returns
-------
Expand Down Expand Up @@ -547,7 +618,13 @@ def _calculateGamma(self, photon):
"""
return photon.unitDirectionVector().scalarProduct(self.surfaceNormalInwards())

def _calculatePhotonOut(self, photon_in, method=1):
def _calculatePhotonOut(self, photon_in,
method=1,
apply_reflectivity=False,
calculation_method=0, # 0=Zachariasen, 1=Guigay
is_thick=0, # for Guigay only
use_transfer_matrix=0, # for Guigay only
):
"""
Solves the scattering equation to calculates the outgoing photon from the incoming photon and the Bragg normal.
Expand Down Expand Up @@ -643,6 +720,17 @@ def _calculatePhotonOut(self, photon_in, method=1):
self.logDebug("photon_in direction" + str(photon_in.unitDirectionVector().components()))
self.logDebug("photon_out direction" + str(photon_out.unitDirectionVector().components()))


if apply_reflectivity:
coeffs = self.calculateDiffraction(photon_in,
calculation_method=calculation_method,
is_thick=is_thick,
use_transfer_matrix=use_transfer_matrix)

# apply reflectivities
photon_out.rescaleEsigma(coeffs["S"])
photon_out.rescaleEpi(coeffs["P"])

# Return outgoing photon.

return photon_out
Expand Down

0 comments on commit 4a45fd7

Please sign in to comment.