upxo.xtalphy.texops module
- class upxo.xtalphy.texops.tops[source]
Bases:
object- fcc_tc_std = {'A1': (35.0, 45.0, 90.0), 'A2': (55.0, 90.0, 45.0), 'B': (45.0, 90.0, 45.0), 'C': (0.0, 90.0, 45.0), 'D': (59.0, 37.0, 26.0), 'P': (90.0, 45.0, 0.0), 'Q': (35.0, 55.0, 45.0), 'brass': (35.0, 45.0, 0.0), 'copper': (90.0, 35.0, 45.0), 'cube': (0.0, 0.0, 0.0), 'goss': (90.0, 90.0, 45.0), 'rotated_cube': (45.0, 0.0, 0.0), 's': (59.0, 37.0, 63.0)}
- FCC_POLES = {'100': numpy.array, '110': numpy.array, '111': numpy.array}
- sym_ops
- classmethod synth_fcc(N=1000, tc_info={'brass': [0.3, [35.0, 45.0, 0.0]], 'copper': [0.45, [90.0, 35.0, 45.0]], 'goss': [0.1, [0.0, 45.0, 0.0]], 'rotated_cube': [0.15, [45.0, 0.0, 0.0]]}, n_tex_instances=2, n_sampling_instances=50)[source]
Examples
>>> from upxo.xtalphy.texops import tops >>> tex = tops.synth_fcc(N=500, >>> tc_info={"cube": [0.05, [0.0, 0.0, 0.0]], >>> "rotated_cube": [0.05, [45.0, 0.0, 0.0]], >>> "brass": [0.25, [35.0, 45.0, 0.0]], >>> "goss": [0.10, [0.0, 45.0, 0.0]], >>> "copper": [0.35, [90.0, 35.0, 45.0]], >>> "s": [0.2, [59.0, 37.0, 63.0]] >>> }, >>> n_tex_instances=1, >>> n_sampling_instances=5)
>>> b = tex.tex['tex_instance.1']['sampling_instances']['ossi.1']['tc_ori_stacks'] >>> ea = np.vstack(list(b.values())) >>> tex.plot_pole_figure(ea, pole_family='111', title="")
>>> b1 = [tex.tex['tex_instance.1']['sampling_instances'][k]['tc_ori_stacks'] >>> for k in tex.tex['tex_instance.1']['sampling_instances'].keys() if k[:5] == 'ossi.'] >>> b2 = [np.vstack(list(_b1_.values())) for _b1_ in b1] >>> b3 = np.vstack(b2) >>> b3.shape >>> tex.plot_pole_figure(b3, pole_family='111')
- classmethod synth_fcc_quats(N: int = 500, **tc_kwargs) numpy.ndarray[source]
Sample N FCC-consistent quaternions in [w, x, y, z] convention.
Calls
synth_fcc()(single tex/sampling instance), extracts the Bunge Euler angles, and converts them to unit quaternions viascipy.spatial.transform.Rotation. Orientations are returned in the canonical positive-w hemisphere (w >= 0).- Parameters:
N (int) – Number of orientations to generate.
**tc_kwargs – Forwarded to
synth_fcc()(e.g. customtc_infodict).
- Returns:
quats – Unit quaternions in [w, x, y, z] convention.
- Return type:
- plot_pole_figure(euler_angles_deg, pole_family='100', title='')[source]
Creates a complete pole figure scatter plot for a specified pole family.
- cubic_euler_bunge_to_matrix(phi1, Phi, phi2, degrees=True)[source]
Bunge ZXZ rotation matrix:
R = Rz(phi1) @ Rx(Phi) @ Rz(phi2).Examples
>>> from upxo.xtalphy.texops import tops as TO >>> import numpy as np >>> ea = np.array([10, 20, 30]) >>> tex = TO() >>> R = tex.cubic_euler_bunge_to_matrix(*ea) >>> print(R)
- cubic_euler_bunge_to_matrix_v1(phi1, Phi, phi2, degrees=True)[source]
Cubic euler bunge to matrix v1.
- cubic_rotation_axis(R, angle)[source]
Return unit axis for rotation R given angle (rad). For very small angles, returns a default axis.
- cubic_symmetry_operators()[source]
24 proper rotations for m-3m as signed permutation matrices with det=+1.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> # ---------- >>> tex.cubic_symmetry_operators()
- fcc_symmetrise_ori(ea_bunge, dtype=numpy.float32)[source]
Generate symmetric equivalents of an orientation.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> # ---------- >>> ea_bunge = np.array([10, 20, 30]) >>> tex.fcc_symmetrise_ori(ea_bunge, dtype=np.float32)
- fcc_symmetrise_ori_V1(ea_bunge, dtype=numpy.float32)[source]
Generate symmetric equivalents of an orientation inside Fund. Zone.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> # ---------- >>> fcc_tc_std = {"copper": (90.0, 35.0, 45.0), # {112}<111> Rolling >>> "brass": (35.0, 45.0, 0.0), # {110}<112> Rolling >>> "s": (59.0, 37.0, 63.0), # {123}<634> Rolling >>> "goss": (0.0, 45.0, 0.0), # {110}<001> Rolling >>> "cube": (0.0, 0.0, 0.0), # {001}<100> Annealing / RX >>> "rotated_cube": (45.0, 0.0, 0.0), # {001}<110> Annealing / RX >>> "P": (90.0, 45.0, 0.0), # {011}<122> Annealing / RX >>> "A1": (35.0, 45.0, 90.0), # {111}<110> Shear >>> "A2": (55.0, 90.0, 45.0), # {111}<112> Shear >>> "B": (45.0, 90.0, 45.0), # {112}<110> Shear >>> "C": (0.0, 90.0, 45.0), # {001}<110> Shear >>> "Q": (35.0, 55.0, 45.0), # {013}<231> transitional >>> "D": (59.0, 37.0, 26.0), # {4411}<1118> approx. transitional >>> } >>> EA_fund_zone = {} >>> for tc, tcea in fcc_tc_std.items(): >>> ea_bunge = np.array(tcea) >>> tex.fcc_symmetrise_ori(ea_bunge, dtype=np.float32)
>>> g = tex.cubic_euler_bunge_to_matrix(*ea_bunge, degrees=True) >>> eq_mats = [tex._proj_to_so3(S @ g) for S in tex.sym_ops] >>> eq_mats = tex._unique_rotations(eq_mats, tol=1E-8) >>> symm_eq = np.array([list(tex._matrix_to_euler_bunge(R, degrees=True)) >>> for R in eq_mats], dtype=np.float32) >>> EA_fund_zone[tc] = symm_eq[np.where(np.prod(symm_eq <= 90, axis=1))[0]]
- normalize_euler_bunge(ea, degrees=True, eps=1e-06)[source]
- Normalize Bunge ZXZ Euler angles (phi1, Phi, phi2) to canonical ranges.
phi1, phi2 in [0, 360) deg (or [0, 2π) rad)
Phi in [0, 180] deg (or [0, π] rad)
- Handles BOTH Phi > 180 and Phi < 0 via ZXZ symmetry:
Phi’ = -Phi and (phi1’, phi2’) = (phi1+180, phi2+180) [mod 360] Phi’ = 360-Phi and same 180-shift for >180 case.
- cubic_misorientation_V1(EA1, EA2, unique_tol_deg=0.0001, degrees=True)[source]
Vectorized fast misorientation (cubic, m-3m).
Accepts Euler triplet (phi1, Phi, phi2) or 3×3 rotation matrix.
- Returns:
angle_deg_min (float)
axis_min (ndarray, shape (3,)) – Unit vector in sample frame.
top3_angles_deg (list of float) – Up to 3 smallest unique angles (deg), ascending.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> tex.cubic_misorientation_V1([0, 0, 0], [35, 45, 90])
- cubic_misorientation_V2(EA1, EA2, unique_tol_deg=0.0001, degrees=True)[source]
Vectorized fast misorientation (cubic, m-3m).
Accepts Euler triplet (phi1, Phi, phi2) or 3×3 rotation matrix.
- Returns:
angle_deg_min (float)
axis_min (ndarray, shape (3,)) – Unit vector in sample frame.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> tex.cubic_misorientation_V2([0, 0, 0], [35, 45, 90])
- cubic_misorientation_V3(EA1, EA2, degrees=True)[source]
Vectorized fast misorientation (cubic, m-3m).
Accepts Euler triplet (phi1, Phi, phi2) or 3×3 rotation matrix.
- Returns:
angle_deg_min (float)
axis_min (ndarray, shape (3,)) – Unit vector in sample frame.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> tex.cubic_misorientation_V3([0, 0, 0], [35, 45, 90])
- set_tc_info(tc_info, defaults={'hw_Phi': 5, 'hw_phi1': 5, 'hw_phi2': 5, 'perctol_Phi': 5, 'perctol_phi1': 5, 'perctol_phi2': 5, 'std_k_Phi': 3, 'std_k_phi1': 3, 'std_k_phi2': 3})[source]
Standardize a dictionary of texture component information to a consistent format.
- Parameters:
tc_info (dict) – Texture components. Each value is a list whose first two elements are
[percentage, [phi1, Phi, phi2]]; optional further elements are spread, std-k, and percentage-tolerance per Euler angle.- Returns:
Updates
self.tc_infoin place with all values normalised to[percentage, [ang1, ang2, ang3], [std1, std2, std3], [k1, k2, k3], [perctol]].- Return type:
None
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> # ---------- >>> # Possible input for gstslice.tc_info: 1 >>> tex.set_tc_info({"copper": [0.45, [90.0, 35.0, 45.0]], >>> "brass": [0.30, [35.0, 45.0, 0.0]], >>> "goss": [0.20, [90.0, 90.0, 45.0]], >>> "rotated_cube": [0.01, [45.0, 0.0, 0.0]] >>> })
>>> # Possible input for gstslice.tc_info: 2 >>> tex.set_tc_info({"copper": [0.45, [90.0, 35,.0 45.0], 8.0], >>> "s": [0.15, [59.0, 37.0, 63.0], 7.0], >>> "goss": [0.20, [90.0, 90.0, 45.0], 5.5], >>> "rotated_cube": [0.01, [45.0, 0.0, 0.0], 9.8] >>> })
>>> # Possible input for gstslice.tc_info: 3 >>> tex.set_tc_info({"copper": [0.45, [90.0, 35.0, 45.0], [8.0, 8.0, 8.0]], >>> "goss": [0.05, [90.0, 90.0, 45.0], [6.0, 6.0, 6.0]], >>> "brass": [0.30, [35.0, 45.0, 0.0], [6.0, 6.0, 6.0]], >>> "rotated_cube": [0.01, [45.0, 0.0, 0.0], [8.0, 8.0, 8.0]] >>> })
>>> # Possible input for gstslice.tc_info: 4 >>> tex.set_tc_info({"copper": [0.45, [90.0, 35.0, 45.0], [8.0, 8.0, 8.0], [3.0, 3.0, 3.0]], >>> "brass": [0.30, [35.0, 45.0, 0.0], [10.0, 10.0, 10.0], [3.0, 3.0, 3.0]], >>> "goss": [0.05, [90.0, 90.0, 45.0], [6.0, 6.0, 6.0], [3.0, 3.0, 3.0]], >>> "rotated_cube": [0.01, [45.0, 0.0, 0.0], [8.0, 8.0, 8.0], [3.0, 3.0, 3.0]] >>> })
>>> # Possible input for gstslice.tc_info: 5 >>> tex.set_tc_info({"copper": [0.45, [90.0, 35.0, 45.0], [8.0, 8.0, 8.0], [3.0, 3.0, 3.0], [5.0, 5.0, 5.0]], >>> "s": [0.15, [59.0, 37.0, 63.0], [7.0, 7.0, 7.0], [3.0, 3.0, 3.0], [5.0, 5.0, 5.0]], >>> "brass": [0.30, [35.0, 45.0, 0.0], [10.0, 10.0, 10.0], [3.0, 3.0, 3.0], [5.0, 5.0, 5.0]], >>> "goss": [0.05, [90.0, 90.0, 45.0], [6.0, 6.0, 6.0], [3.0, 3.0, 3.0], [5.0, 5.0, 5.0]], >>> "rotated_cube": [0.01, [45.0, 0.0, 0.0], [8.0, 8.0, 8.0], [3.0, 3.0, 3.0], [5.0, 5.0, 5.0]] >>> })
>>> print(tex.tc_info)
Notes
Standard FCC texture-component reference orientations (Bunge Euler angles):
fcc_tc = {"copper": (90.0, 35.0, 45.0), # {112}<111> Rolling "brass": (35.0, 45.0, 0.0), # {110}<112> Rolling "s": (59.0, 37.0, 63.0), # {123}<634> Rolling "goss": (90.0, 90.0, 45.0), # {110}<001> Rolling "cube": (0.0, 0.0, 0.0), # {001}<100> Annealing/RX "rotated_cube": (45.0, 0.0, 0.0), # {001}<110> Annealing/RX "P": (90.0, 45.0, 0.0), # {011}<122> Annealing/RX "A1": (35.0, 45.0, 90.0), # {111}<110> Shear "A2": (55.0, 90.0, 45.0), # {111}<112> Shear "B": (45.0, 90.0, 45.0), # {112}<110> Shear "C": (0.0, 90.0, 45.0), # {001}<110> Shear "Q": (35.0, 55.0, 45.0), # {013}<231> transitional "D": (59.0, 37.0, 26.0), # {4411}<1118> transitional }
- get_tcinfo()[source]
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> # ---------- >>> tex.set_tc_info({"copper": [0.45, [90.0, 35.0, 45.0]], >>> "brass": [0.30, [35.0, 45.0, 0.0]], >>> "goss": [0.20, [90.0, 90.0, 45.0]], >>> "rotated_cube": [0.01, [45.0, 0.0, 0.0]] >>> }) >>> VF, HW, SK, PT, ori_means = tex.get_tcinfo()
- alloc_ori_counts_to_tc(N)[source]
Allocate orientation counts to texture components proportionally.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> tex.set_tc_info({"copper": [0.45, [90.0, 35.0, 45.0]], ... "brass": [0.30, [35.0, 45.0, 0.0]], ... "goss": [0.20, [90.0, 90.0, 45.0]], ... "rotated_cube": [0.01, [45.0, 0.0, 0.0]]}) >>> ori_count = tex.alloc_ori_counts_to_tc(100) >>> print(ori_count)
- gen_tex_fcc_synthetic(N=1000, distr='normal', n_tex_instances=1, n_sampling_instances=1, rand_ori_gen_rule='relaxed')[source]
Generate synthetic FCC texture for all texture and sampling instances.
Examples
>>> from upxo.xtalphy.texops import tops as TO >>> tex = TO() >>> tex.set_tc_info({"copper": [0.45, [90.0, 35.0, 45.0]], ... "brass": [0.30, [35.0, 45.0, 0.0]], ... "goss": [0.10, [90.0, 90.0, 45.0]], ... "rotated_cube": [0.15, [45.0, 0.0, 0.0]]}) >>> tex.gen_tex_fcc_synthetic(N=500, n_tex_instances=2, ... n_sampling_instances=500) >>> tex.tex.keys() >>> tex.n_texture_instances >>> a = tex.tex['tex_instance.1']['sampling_instances']['ossi.1']['nsamples'] >>> b = tex.tex['tex_instance.1']['sampling_instances']['ossi.1']['tc_ori_stacks'] >>> sum([_b_.shape[0] for _b_ in b.values()])
- gen_tex_fcc_synthetic_single_instance(VF, HW, SK, PT, ori_means, tiname)[source]
Gen tex fcc synthetic single instance.
- gen_tex_fcc_sampling_instances(tiname, sampling_instances_ids, tc_comps, rand_ori_gen_rule='relaxed')[source]
Gen tex fcc sampling instances.
- gen_symmetric_equivalents_fcc_ori(VF, HW, SK, PT, ori_means)[source]
BEA_SYMEQ_MO: Misorinetation angle of all orientations around each symmetric equivalent of the mean oreintation of every texcture component specified by user. Note; See descriptions for variable BEA_SYMEQ_MO_TC (in below codes) for more detauils.
BEA_SYMEQ_MO.keys() dict_keys([‘copper’, ‘brass’, ‘s’, ‘goss’, ‘cube’])
After processing, this shoudl have. * len(BEA_SYMEQ_MO[‘copper’]) –> 24 * len(BEA_SYMEQ_MO[‘copper’][0]) == ori_count[‘copper’] –> True
- fcc_variants_in_FZ_old(ea_bunge, *, degrees=True, tol=1e-08)[source]
Return ALL unique variants of an orientation inside the Bunge FZ for cubic (24) crystal + orthorhombic-sheet D2 (4) sample symmetry. Uniqueness is by rotation (not angles), and angles are canonicalized.
- tc_variants_in_FZ()[source]
For every TC mean orientation in self.tc_info, compute the unique FZ variants (cubic + D2). Returns dict: name -> (k,3) array.
- fcc_variants_in_FZ(ea_bunge, *, degrees=True, tol=1e-08)[source]
Unique FZ variants for cubic crystal (24 left ops). Sample symmetry (D2, 4 right ops) is used ONLY to fold into the FZ.
- tc_info
- ori_count
- N
- n_texture_instances
- n_sampling_instances
- tex