hexrd.phase_transition.texture package
Submodules
Module contents
- class hexrd.phase_transition.texture.DeLaValleePoussinKernel(halfwidth: float, crystal_symmetry: str | ndarray | None = None, sample_symmetry: str | ndarray | None = None)[source]
Bases:
SO3KernelDe la Vallée Poussin kernel on SO(3).
A radially symmetric kernel on SO(3) defined by:
K(ω) = C · cos(ω/2)^(2κ)
where ω is the misorientation angle, κ is the shape parameter, and C = B(3/2, 1/2) / B(3/2, κ + 1/2) is the normalization constant (B denotes the Beta function).
The halfwidth h is the angle at which the kernel drops to half its peak value. It is related to κ analytically by:
κ = ln(0.5) / (2 · ln(cos(h/2)))
Parameters
- halfwidthfloat
Half-width parameter in radians — the angle at which K drops to half its maximum. Must be > 0, typically in [π/180, π/2].
- crystal_symmetrystr or numpy.ndarray, optional
Crystal symmetry used to compute symmetry-reduced misorientation angles. Strings are interpreted as Laue group labels.
- sample_symmetrystr or numpy.ndarray, optional
Sample symmetry used to compute symmetry-reduced misorientation angles. Strings are interpreted as Laue group labels, with triclinic, monoclinic, and orthorhombic sample labels mapped to their corresponding finite Laue groups.
Attributes
- halfwidthfloat
Half-width parameter in radians
- kappafloat
Shape parameter κ derived from half-width
- norm_constantfloat
Normalization constant from the Beta function
Notes
Symmetry is opt-in and must be supplied explicitly. By default the kernel applies NO crystal or sample symmetry: symmetry-equivalent orientations are treated as distinct and the misorientation angle is the raw geometric one. To have the kernel respect symmetry - i.e. treat orientations related by a symmetry operation as identical and use the smallest equivalent misorientation - you must pass
crystal_symmetry(and/orsample_symmetry). For example, a cubic material must be built withcrystal_symmetry='oh'; omitting it silently ignores cubic symmetry and will overestimate misorientation angles.Examples
>>> kernel = DeLaValleePoussinKernel(halfwidth=np.radians(15)) >>> R1 = np.eye(3) >>> R2 = np.eye(3) # Same orientation >>> value = kernel.eval(R1, R2) # Maximum value = C >>> >>> # Respect cubic crystal symmetry (otherwise it is ignored): >>> kernel = DeLaValleePoussinKernel( ... halfwidth=np.radians(15), crystal_symmetry='oh' ... )
- property crystal_symmetry: str | None
str or None: Crystal symmetry label, if built from a label.
Returns None when the symmetry was supplied directly as a quaternion array, even if symmetry reduction is active. Use
has_symmetryto test whether reduction is enabled.
- eval(R1: ndarray, R2: ndarray) float | ndarray[source]
Evaluate de la Vallée Poussin kernel between rotations.
K(ω) = C · cos(ω/2)^(2κ)
Parameters
- R1, R2array_like
Rotation matrices of shape (…, 3, 3)
Returns
- float or numpy.ndarray
Kernel values, shape matches broadcasting of R1 and R2
Examples
>>> kernel = DeLaValleePoussinKernel( ... halfwidth=np.radians(10) ... ) >>> value = kernel.eval(np.eye(3), np.eye(3))
- property halfwidth: float
float: Half-width in radians (angle where K = K_max / 2).
- property has_symmetry: bool
bool: Whether non-trivial symmetry reduction is enabled.
- property kappa: float
float: Shape parameter κ.
- misorientation_angle(R1: ndarray, R2: ndarray) float | ndarray[source]
Calculate misorientation angle between rotation matrices.
Without symmetry, uses the formula: cos(ω) = (trace(R1^T @ R2) - 1) / 2, and supports arbitrary broadcasting of R1 and R2. With crystal or sample symmetry, delegates to hexrd.core.rotations.misorientation for symmetry-reduced angles; in that case one of R1/R2 must be a single orientation (shape (3, 3)), which is reduced against the other as a batch.
Parameters
- R1, R2array_like
Rotation matrices of shape (…, 3, 3)
Returns
- float or numpy.ndarray
Misorientation angles in radians, shape matches input broadcasting
- property norm_constant: float
float: Normalization constant from Beta function.
- property sample_symmetry: str | None
str or None: Sample symmetry label, if built from a label.
Returns None when the symmetry was supplied directly as a quaternion array, even if symmetry reduction is active. Use
has_symmetryto test whether reduction is enabled.
- class hexrd.phase_transition.texture.SO3Kernel[source]
Bases:
ABCAbstract base class for kernels on the SO(3) rotation group.
All SO(3) kernels should inherit from this class and implement the eval() method for kernel evaluation.
- class hexrd.phase_transition.texture.UniformODF(crystal_symmetry: str | ndarray | None = None, sample_symmetry: str | ndarray | None = None)[source]
Bases:
objectUniform (random) orientation distribution function.
Represents a completely isotropic texture where all crystal orientations are equally likely. The value is constant at 1 MRD (multiples of a random distribution), the standard normalization where the uniform distribution serves as the reference density.
Parameters
- crystal_symmetrystr or numpy.ndarray, optional
Crystal symmetry as a Laue group label (‘ci’, ‘c2h’, ‘d2h’, ‘c4h’, ‘d4h’, ‘s6’, ‘d3d’, ‘c6h’, ‘d6h’, ‘th’, ‘oh’) or a quaternion symmetry array. Validated but inert (the value is 1 MRD regardless); default None.
- sample_symmetrystr or numpy.ndarray, optional
Sample symmetry as a label (‘triclinic’, ‘monoclinic’, ‘orthorhombic’) or a quaternion array. Validated but inert; default None.
Attributes
- valuefloat
Constant ODF value = 1.0 (MRD)
- crystal_symmetrystr or None
Crystal symmetry label, or None if unset or given as an array
- sample_symmetrystr or None
Sample symmetry label, or None if unset or given as an array
Examples
>>> odf = UniformODF('d6h', 'triclinic') # hexagonal crystal >>> orientations = np.eye(3).reshape(1, 3, 3) >>> values = odf.eval(orientations) >>> print(values[0]) # 1.0
- property crystal_symmetry: str | None
Crystal symmetry label, or None if unset or given as an array.
- eval(orientations: ndarray) float | ndarray[source]
Evaluate uniform ODF at given orientations.
For a uniform ODF, all orientations return 1.0 MRD (multiples of a random distribution).
Parameters
- orientationsarray_like
Orientation matrices. Can be: - Single 3x3 rotation matrix - Array of shape (N, 3, 3) for N orientations - Any shape ending in (3, 3) for rotation matrices
Returns
- float or numpy.ndarray
ODF values, all equal to 1.0 (MRD). A scalar float for a single (3, 3) orientation; otherwise an array whose shape matches the leading dimensions of the input.
Examples
>>> odf = UniformODF('oh', 'triclinic') >>> >>> # Single orientation >>> R = np.eye(3) >>> value = odf.eval(R) # scalar >>> >>> # Multiple orientations >>> Rs = np.array([np.eye(3), np.eye(3)]) # shape (2, 3, 3) >>> values = odf.eval(Rs) # shape (2,)
- property sample_symmetry: str | None
Sample symmetry label, or None if unset or given as an array.
- property value: float
Constant ODF value in MRD.
- class hexrd.phase_transition.texture.UnimodalODF(modal_orientations, kernel, weights=None)[source]
Bases:
objectUnimodal orientation distribution function.
Represents a texture with one or more preferred orientations around which crystal orientations are concentrated. Uses kernel functions to create smooth distributions around modal orientations.
Mathematical form: f(g) = Σᵢ wᵢ K(g, g₀ᵢ), Σᵢ wᵢ = 1 Because the de la Vallée Poussin kernel is normalized so its mean over SO(3) is 1 (MRD), this weighted sum is itself a valid ODF in MRD units (uniform texture = 1).
Parameters
- modal_orientationsarray_like
Modal (preferred) orientation(s). Can be: - Single 3x3 rotation matrix - Array of shape (N, 3, 3) for N modal orientations
- kernelDeLaValleePoussinKernel
Kernel function defining the shape of the distribution. The kernel is the single source of truth for symmetry: any crystal/sample symmetry must be set on the kernel, and the ODF exposes it via the
crystal_symmetry/sample_symmetryproperties.- weightsarray_like, optional
Weights for multiple modal orientations. Must sum to 1. If None, equal weights are used for multiple orientations.
Attributes
- modal_orientationsnumpy.ndarray
Array of modal orientations, shape (N, 3, 3)
- kernelDeLaValleePoussinKernel
Kernel function used for the distribution
- weightsnumpy.ndarray
Component weights, shape (N,)
- crystal_symmetrystr or None
Crystal symmetry label, delegated from the kernel
- sample_symmetrystr or None
Sample symmetry label, delegated from the kernel
- n_componentsint
Number of modal orientations
Examples
>>> from hexrd.phase_transition.texture import UnimodalODF >>> from hexrd.phase_transition.texture import DeLaValleePoussinKernel >>> >>> # Single modal orientation (cubic crystal symmetry on the kernel) >>> kernel = DeLaValleePoussinKernel( ... halfwidth=np.radians(15), crystal_symmetry='oh' ... ) >>> modal = np.eye(3) # Identity orientation >>> odf = UnimodalODF(modal, kernel) >>> >>> # Evaluate at modal orientation (should give maximum value) >>> value = odf.eval(modal)
- property crystal_symmetry
str or None: Crystal symmetry label, delegated from the kernel.
- estimated_max_value()[source]
Estimate the maximum ODF value, in MRD.
The ODF maxima occur at (or very near) the modal orientations, so this evaluates the full ODF at each mode and returns the largest value.
Returns
- float
Maximum ODF value in MRD (multiples of a random distribution)
- eval(orientations)[source]
Evaluate unimodal ODF at given orientations.
Computes f(g) = Σᵢ wᵢ K(g, g₀ᵢ) for all input orientations, in MRD.
Parameters
- orientationsarray_like
Orientation matrices of shape (…, 3, 3)
Returns
- numpy.ndarray
ODF values with shape matching leading dimensions of input
Examples
>>> modal = np.eye(3) >>> kernel = DeLaValleePoussinKernel(halfwidth=np.radians(10)) >>> odf = UnimodalODF(modal, kernel) >>> >>> # Single evaluation >>> value = odf.eval(modal) # Should give maximum >>> >>> # Batch evaluation >>> Rs = np.array([np.eye(3), rotation_matrix_z(np.pi/4)]) >>> values = odf.eval(Rs) # shape (2,)
- property kernel
DeLaValleePoussinKernel: Kernel function.
- property modal_orientations
numpy.ndarray: Modal orientations, shape (N, 3, 3).
- property n_components
int: Number of modal orientations.
- property sample_symmetry
str or None: Sample symmetry label, delegated from the kernel.
- property weights
numpy.ndarray: Component weights, shape (N,).
- hexrd.phase_transition.texture.eval_odf_batch(odf, orientations, chunk_size=10000)[source]
Evaluate ODF on large batches of orientations with memory management.
For very large orientation datasets, this function processes orientations in chunks to avoid memory issues while maintaining vectorization benefits.
Parameters
- odfODF object
ODF object with eval() method
- orientationsarray_like
Large array of orientation matrices, shape (N, 3, 3). A single (3, 3) matrix is also accepted.
- chunk_sizeint, optional
Number of orientations to process per chunk, default 10000
Returns
- numpy.ndarray or float
ODF values, shape (N,) for an (N, 3, 3) input, or a scalar float for a single (3, 3) orientation.
Examples
>>> odf = UniformODF('oh', 'triclinic') >>> # Large batch of orientations >>> Rs = np.random.normal(size=(50000, 3, 3)) # Not actual rotations! >>> # In practice, use proper rotation matrices >>> values = eval_odf_batch(odf, Rs, chunk_size=5000)
- hexrd.phase_transition.texture.eval_random_orientations(odf, n_orientations=1000, seed=None)[source]
Evaluate ODF at random orientations for statistical analysis.
Generates random rotation matrices and evaluates the ODF at these orientations. Useful for normalization checks and Monte Carlo integration.
Parameters
- odfODF object
ODF to evaluate
- n_orientationsint, optional
Number of random orientations to generate, default 1000
- seedint, optional
Random seed for reproducibility
Returns
- tuple of (numpy.ndarray, numpy.ndarray)
orientations : Random rotation matrices, shape (n_orientations, 3, 3) values : ODF values at these orientations, shape (n_orientations,)
Examples
>>> odf = UniformODF('oh', 'triclinic') >>> orientations, values = eval_random_orientations(odf, n_orientations=100) >>> print(f"Mean ODF value: {np.mean(values)}") # Should be ~1.0 (MRD)