Skip to content

Commit 9031db7

Browse files
committed
fix site symmetry symbol #309
1 parent 074f042 commit 9031db7

File tree

3 files changed

+180
-115
lines changed

3 files changed

+180
-115
lines changed

pyxtal/XRD_indexer.py

Lines changed: 115 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ def get_cell_params(spg, hkls, two_thetas, wave_length=1.54184):
7373
if spg >= 195: # cubic, only need a
7474
h_sq_sum = np.sum(hkls**2, axis=1)
7575
cells = d_spacings * np.sqrt(h_sq_sum)
76-
for m in range(len(cells)):
77-
print(cells[m], hkls[m], d_spacings[m], two_thetas[m])
76+
#for m in range(len(cells)): print(cells[m], hkls[m], d_spacings[m], two_thetas[m])
7877
mask = cells < 50.0
7978
cells = cells[mask]
8079
cells = np.reshape(cells, [len(cells), 1])
@@ -381,6 +380,8 @@ def get_cell_from_multi_hkls(spg, hkls, two_thetas, long_thetas=None, wave_lengt
381380
if spg < 16:
382381
cells[:, -1] = np.round(cells[:, -1], decimals=2)
383382
cells[:, :3] = np.round(cells[:, :3], decimals=4)
383+
elif spg > 194:
384+
cells = np.round(cells, decimals=5)
384385

385386
_, unique_ids = np.unique(cells, axis=0, return_index=True)
386387
hkls = hkls[unique_ids]#; print(cells) # remove duplicates
@@ -442,7 +443,7 @@ def get_cell_from_multi_hkls(spg, hkls, two_thetas, long_thetas=None, wave_lengt
442443
'cell': cell,
443444
'n_matched': n_matched,
444445
'score': score,
445-
'id': [i, hkls[i]],
446+
'id': hkls[i],
446447
})
447448

448449
return solutions
@@ -451,110 +452,122 @@ def get_cell_from_multi_hkls(spg, hkls, two_thetas, long_thetas=None, wave_lengt
451452
if __name__ == "__main__":
452453
from pyxtal import pyxtal
453454
from itertools import combinations
455+
from time import time
454456
np.set_printoptions(precision=4, suppress=True)
455457

456458
xtal = pyxtal()
457-
#xtal.from_seed('pyxtal/database/cifs/JVASP-62168.cif') # 52s -> 16s
458-
#xtal.from_seed('pyxtal/database/cifs/JVASP-98225.cif') # P21/c -> 33s -> 12s
459-
#xtal.from_seed('pyxtal/database/cifs/JVASP-50935.cif') # Pm -> 45s -> 7.6s
460-
#xtal.from_seed('pyxtal/database/cifs/JVASP-28565.cif') # 207s -> 91s -> 80s -> 72s
461-
xtal.from_seed('pyxtal/database/cifs/JVASP-42300.cif') # 178s
462-
#xtal.from_seed('pyxtal/database/cifs/JVASP-47532.cif') #
463-
#xtal.from_seed('pyxtal/database/cifs/JVASP-28634.cif', tol=1e-4) # P21/c -> 33s -> 12s
464-
#xtal.from_seed('pyxtal/database/cifs/JVASP-97915.cif', tol=1e-4) # P21/c -> 33s -> 12s
465-
#xtal.from_seed('pyxtal/database/cifs/JVASP-86205.cif', tol=1e-4) # P21/c -> 33s -> 12s
466-
467-
xrd = xtal.get_XRD(thetas=[0, 120], SCALED_INTENSITY_TOL=0.5)
468-
cell_ref = np.sort(np.array(xtal.lattice.encode()))
469-
long_thetas = xrd.pxrd[:15, 0]
470-
spg = xtal.group.number
471-
print("\nTesting prototype:", xtal.lattice, xtal.group.symbol, xtal.group.number)
472-
print(xrd.by_hkl(N_max=10))
473-
474-
# Get the a list of hkl guesses and sort them by d^2
475-
if spg >= 195:
476-
min_score = 0.96
477-
else:
478-
min_score = 0.999
459+
data = []
460+
for cif in [
461+
#'pyxtal/database/cifs/JVASP-97915.cif', # Fm-3m, 0.9s
462+
#'pyxtal/database/cifs/JVASP-86205.cif', # Im-3 204, 0.1s
463+
#'pyxtal/database/cifs/JVASP-28634.cif', # P3m1, 0.1s
464+
#'pyxtal/database/cifs/JVASP-85365.cif', # P4/mmm, 0.6s
465+
#'pyxtal/database/cifs/JVASP-62168.cif', # Pnma, 33s
466+
'pyxtal/database/cifs/JVASP-98225.cif', # P21/c, 14s
467+
#'pyxtal/database/cifs/JVASP-50935.cif', # Pm, 10s
468+
#'pyxtal/database/cifs/JVASP-28565.cif', # Cm, 100s
469+
#'pyxtal/database/cifs/JVASP-36885.cif', # Cm, 100s
470+
#'pyxtal/database/cifs/JVASP-42300.cif', # C2, 178s
471+
#'pyxtal/database/cifs/JVASP-47532.cif', # P2/m,
472+
]:
473+
t0 = time()
474+
xtal.from_seed(cif)
475+
xrd = xtal.get_XRD(thetas=[0, 120], SCALED_INTENSITY_TOL=0.5)
476+
cell_ref = np.sort(np.array(xtal.lattice.encode()))
477+
long_thetas = xrd.pxrd[:15, 0]
478+
spg = xtal.group.number
479+
print("\n", cif, xtal.lattice, xtal.group.symbol, xtal.group.number)
480+
print(xrd.by_hkl(N_max=10))
481+
482+
# Get the a list of hkl guesses and sort them by d^2
483+
if spg >= 195:
484+
min_score, N_add, N_batch = 0.96, 3, 5
485+
elif spg > 15:
486+
min_score, N_add, N_batch = 0.999, 5, 20
487+
else:
488+
min_score, N_add, N_batch = 0.999, 8, 20
479489

480-
if spg >= 16:
481-
guesses = xtal.group.generate_hkl_guesses(2, 3, 5, max_square=29, total_square=40, verbose=True)
482-
else:
483-
if spg in [5, 8, 12, 15]:
484-
guesses = xtal.group.generate_hkl_guesses(3, 3, 5, max_square=29, total_square=40, verbose=True)
490+
if spg >= 16:
491+
guesses = xtal.group.generate_hkl_guesses(2, 2, 5, max_square=29, total_square=40, verbose=True)
485492
else:
486-
guesses = xtal.group.generate_hkl_guesses(3, 3, 4, max_square=29, total_square=35, verbose=True)
487-
#guesses = xtal.group.generate_hkl_guesses(3, 3, 3, max_square=15, total_square=36, verbose=True)
488-
489-
guesses = np.array(guesses)
490-
print("Total guesses:", len(guesses))
491-
sum_squares = np.sum(guesses**2, axis=(1,2))
492-
sorted_indices = np.argsort(sum_squares)
493-
guesses = guesses[sorted_indices]
494-
if len(guesses) > 500000: guesses = guesses[:500000]
495-
#guesses = np.array([[[2, 0, 0], [1, 1, 0], [0, 1, 1], [0, 0, 2]]])
496-
#guesses = np.array([[[2, 0, 0], [1, 1, 0], [0, 0, 2], [2, 0, -2]]])
497-
#guesses = np.array([[[0, 0, -1], [1, 1, 0], [1, 1, -1], [0, 2, -5]]])
498-
499-
# Check the quality of each (hkl, 2theta) solutions
500-
N_add = 5
501-
N_batch = 10
502-
cell2 = np.sort(np.array(xtal.lattice.encode()))
503-
if spg <= 15 and cell2[3] > 90: cell2[3] = 180 - cell2[3]
504-
cells_all = np.reshape(cell2, (1, len(cell2)))
505-
506-
# Try each combination of n peaks from the first n+1 peaks
507-
n_peaks = len(guesses[0])
508-
N = min(n_peaks + N_add, len(xrd.pxrd))
509-
available_peaks = xrd.pxrd[:N, 0]
510-
511-
thetas = []
512-
for peak_combo in combinations(range(n_peaks + N_add), n_peaks):
513-
thetas.extend(available_peaks[list(peak_combo)])
514-
N_thetas = len(thetas) // n_peaks
515-
thetas = np.array(thetas)
516-
thetas = np.tile(thetas, N_batch)
517-
print(n_peaks, len(long_thetas))#; import sys; sys.exit()
518-
found = False
519-
d2 = 0
520-
for i in range(len(guesses)//N_batch + 1):
521-
if i == len(guesses)//N_batch:
522-
N_batch = len(guesses) - N_batch * i
523-
if N_batch == 0:
524-
break
493+
if spg in [5, 8, 12, 15]:
494+
guesses = xtal.group.generate_hkl_guesses(3, 3, 5, max_square=29, total_square=40, verbose=True)
525495
else:
526-
thetas = thetas[:N_thetas * n_peaks * N_batch]
527-
hkls_b = np.reshape(guesses[N_batch*i:N_batch*(i+1)], [N_batch*n_peaks, 3])
528-
if spg >= 195:
529-
hkls_t = np.tile(hkls_b, (1, N_thetas))
530-
hkls_t = np.reshape(hkls_t, [N_batch*N_thetas*n_peaks, 3])
531-
else:
532-
hkls_t = np.tile(hkls_b, (N_thetas, 1))
533-
#print('hkl shape:', hkls_b.shape, hkls_t.shape)
534-
#print('thetas shape:', thetas.shape)
535-
solutions = get_cell_from_multi_hkls(spg, hkls_t, thetas, long_thetas, use_seed=False)
536-
if i % 1000 == 0:
537-
print(f"Processed {N_batch*(i)}/{d2}, found {len(cells_all)-1} cells so far.")
538-
539-
for sol in solutions:
540-
cell1 = np.sort(np.array(sol['cell']))
541-
542-
# Check if it is a new solution
543-
diffs = np.sum((cells_all - cell1)**2, axis=1)
544-
guess = sol['id'][1]
545-
score = sol['score']
546-
d2 = np.sum(guess**2)
547-
if len(cells_all[diffs < 0.1]) == 0:
548-
print(f"Guess: {guess}, {d2}/{len(cells_all)-1} -> {cell1}, {score:.6f}")
549-
cells_all = np.vstack((cells_all, cell1))
550-
551-
# Early stopping for getting high-quality solutions
552-
if diffs[0] < 0.1:
553-
print(f"Guess: {guess}, {d2}/{len(cells_all)-1} -> {cell1}, {score:.6f}")
554-
print("High score, exiting early.")
555-
found = True
496+
guesses = xtal.group.generate_hkl_guesses(3, 3, 4, max_square=29, total_square=35, verbose=True)
497+
#guesses = xtal.group.generate_hkl_guesses(3, 3, 3, max_square=15, total_square=36, verbose=True)
498+
499+
guesses = np.array(guesses)
500+
print("Total guesses:", len(guesses))
501+
sum_squares = np.sum(guesses**2, axis=(1,2))
502+
sorted_indices = np.argsort(sum_squares)
503+
guesses = guesses[sorted_indices]
504+
if len(guesses) > 500000: guesses = guesses[:500000]
505+
#guesses = np.array([[[2, 0, 0], [1, 1, 0], [0, 1, 1], [0, 0, 2]]])
506+
#guesses = np.array([[[2, 0, 0], [1, 1, 0], [0, 0, 2], [2, 0, -2]]])
507+
#guesses = np.array([[[0, 0, -1], [1, 1, 0], [1, 1, -1], [0, 2, -5]]])
508+
509+
# Check the quality of each (hkl, 2theta) solutions
510+
cell2 = np.sort(np.array(xtal.lattice.encode()))
511+
if spg <= 15 and cell2[3] > 90: cell2[3] = 180 - cell2[3]
512+
cells_all = np.reshape(cell2, (1, len(cell2)))
513+
514+
# Try each combination of n peaks from the first n+1 peaks
515+
n_peaks = len(guesses[0])
516+
N = min(n_peaks + N_add, len(xrd.pxrd))
517+
available_peaks = xrd.pxrd[:N, 0]
518+
519+
thetas = []
520+
for peak_combo in combinations(range(n_peaks + N_add), n_peaks):
521+
thetas.extend(available_peaks[list(peak_combo)])
522+
N_thetas = len(thetas) // n_peaks
523+
thetas = np.array(thetas)
524+
thetas = np.tile(thetas, N_batch)
525+
found = False
526+
d2 = 0
527+
for i in range(len(guesses)//N_batch + 1):
528+
if i == len(guesses)//N_batch:
529+
N_batch = len(guesses) - N_batch * i
530+
if N_batch == 0:
531+
break
532+
else:
533+
thetas = thetas[:N_thetas * n_peaks * N_batch]
534+
hkls_t = np.tile(guesses[N_batch*i:N_batch*(i+1)], (1, N_thetas, 1))
535+
hkls_t = np.reshape(hkls_t, (-1, 3))#, order='F')
536+
solutions = get_cell_from_multi_hkls(spg, hkls_t, thetas, long_thetas, min_score=min_score, use_seed=False)
537+
if i % 1000 == 0:
538+
print(f"Processed {N_batch*(i)}/{d2}, found {len(cells_all)-1} cells.")
539+
540+
for sol in solutions:
541+
cell1 = np.sort(np.array(sol['cell']))
542+
543+
# Check if it is a new solution
544+
diffs = np.sum((cells_all - cell1)**2, axis=1)
545+
guess = sol['id']
546+
score = sol['score']
547+
d2 = np.sum(guess**2)
548+
if len(cells_all[diffs < 0.1]) == 0:
549+
print(f"Guess: {guess}, {d2}/{len(cells_all)-1} -> {cell1}, {score:.6f}")
550+
cells_all = np.vstack((cells_all, cell1))
551+
552+
# Early stopping for getting high-quality solutions
553+
if diffs[0] < 0.1:
554+
print(f"Guess: {guess}, {d2}/{len(cells_all)-1} -> {cell1}, {score:.6f}")
555+
print("High score, exiting early.")
556+
found = True
557+
break
558+
if found:
556559
break
557-
if found:
558-
break
559-
560+
t1 = time()
561+
data.append((cif, spg, d2, len(cells_all), score, t1-t0))
560562

563+
for d in data: print(d)
564+
"""
565+
('pyxtal/database/cifs/JVASP-97915.cif', 225, 11, 1, 0.9944178674744656, 0.8724310398101807)
566+
('pyxtal/database/cifs/JVASP-86205.cif', 204, 4, 1, 0.9999808799880138, 0.10700225830078125)
567+
('pyxtal/database/cifs/JVASP-28634.cif', 156, 2, 1, 0.9999999999999456, 0.12210202217102051)
568+
('pyxtal/database/cifs/JVASP-85365.cif', 123, 16, 11, 0.999999999999978, 0.5885009765625)
569+
('pyxtal/database/cifs/JVASP-62168.cif', 62, 34, 123, 0.9999999999999891, 32.97966909408569)
570+
('pyxtal/database/cifs/JVASP-98225.cif', 14, 14, 3, 0.9999291925203678, 35.536349296569824)
571+
('pyxtal/database/cifs/JVASP-50935.cif', 6, 6, 25, 0.9998350565457528, 11.00560998916626)
572+
('pyxtal/database/cifs/JVASP-28565.cif', 8, 35, 3824, 0.9995855322890919, 490.50669598579407)
573+
"""

pyxtal/miscellaneous/test_spgs.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@
5757
elif g.symbol[0] == 'A':
5858
acs.append(i)
5959
ss = g.get_spg_symmetry_object()
60-
matrix = ss.to_matrix_representation()
61-
# 1 -1 2 2_1 m a b c n d 3 3_1 3_2 4 4_1 4_2 4_3 -4
60+
matrix = ss.to_matrix_representation() # 15 * 18
61+
# 18 columns: 1 -1 2 2_1 m a b c n d 3 3_1 3_2 4 4_1 4_2 4_3 -4
62+
# 15 row: (100) ..... https://pyxtal.readthedocs.io/en/latest/Symmetry_representation.html
63+
64+
# srew axis
6265
if matrix[0, 3] == 1: screw_21a.append(i)
6366
if matrix[0, -4] == 1: screw_41a.append(i)
6467
if matrix[0, -3] == 1: screw_42a.append(i)
@@ -71,20 +74,20 @@
7174
if matrix[2, -4] == 1: screw_41c.append(i)
7275
if matrix[2, -3] == 1: screw_42c.append(i)
7376
if matrix[2, -2] == 1: screw_43c.append(i)
74-
7577
if matrix[2, 11] == 1: screw_31c.append(i)
7678
if matrix[2, 12] == 1: screw_32c.append(i)
77-
78-
if matrix[2, 3] == 1 and matrix[2, 10] == 1: # 2_1, 3
79+
80+
if matrix[2, 3] == 1 and matrix[2, 10] == 1: # 2_1, 3 => 6_3 axis
7981
screw_63c.append(i)
80-
if matrix[2, 2] == 1 and matrix[2, 12] == 1: # 2, 3_2
82+
if matrix[2, 2] == 1 and matrix[2, 12] == 1: # 2, 3_2 => 6_2 axis
8183
screw_62c.append(i)
8284
if matrix[2, 2] == 1 and matrix[2, 11] == 1: # 2, 3_1
8385
screw_64c.append(i)
8486
if matrix[2, 3] == 1 and matrix[2, 11] == 1: # 2_1, 3_1
8587
screw_61c.append(i)
8688
if matrix[2, 3] == 1 and matrix[2, 12] == 1: # 2_1, 3_2
8789
screw_65c.append(i)
90+
8891
# glide planes
8992
if matrix[0, 6] == 1: b_glide_a.append(i)
9093
if matrix[0, 7] == 1: c_glide_a.append(i)
@@ -114,7 +117,7 @@
114117
elif 1 == matrix[12, 9]:
115118
d_glide_101.append(i)
116119

117-
dicts = {"fcs (all odd/even)": fcs,
120+
dicts = {"fcs (all odd/even)": fcs,
118121
"bcs (h+k+l=2n)": bcs,
119122
"acs (k+l=2n)": acs,
120123
"ccs (h+k=2n)": ccs,
@@ -163,4 +166,4 @@
163166
print(f'{item}: {spg.symbol}')
164167

165168
for key in dicts:
166-
print(key, dicts[key])
169+
print(key, dicts[key])

0 commit comments

Comments
 (0)