Closed qzhu2017 closed 5 years ago
@qzhu2017 I have attached the output from running profile.run("a = molecular_crystal(164, ['H2O'], [12], 2.5)") I will look through and see which functions are taking the most time. There is quite a bit listed in the output.
@scottfredericks, I think the following functions needs to be optimized. Please
3602 4.661 0.001 383.575 0.106 crystal.py:1898(check_wyckoff_position)
As I said, the most import recipe is to get ride of these for loops. http://www.physics.unlv.edu/~qzhu/PyXtal/html/_modules/pyxtal/crystal.html#check_wyckoff_position
I suggest you create a test script to only test the performance of this code. For the improvement, you need to think about how to get rid of these complex for loops. Please also talk to David. Maybe he knows how to improve it.
@scottfredericks I am starting to use this code for some production runs. However, the generation of structures are slow. We have to fix this issue asap.
from pyxtal.molecular_crystal import molecular_crystal
from random import randint
for i in range(20):
run = True
while run:
sg = randint(4,191)
print(sg)
rand_crystal = molecular_crystal(sg, ['H2O'], [2], 2.0)
if rand_crystal.valid:
run = False
print(rand_crystal.struct)
Even with such a simple script. You will see that the generation of structures gets stuck occasionally.
@scottfredericks please have a look at this issue. We need to discuss it on Monday during the group meeting.
@qzhu2017 I will try to optimize the core functionality over the weekend.
@qzhu2017 You are right, check_wyckoff_position seems to cost much more time than even the distance checking functions. site_symm and find_generating_point are also quite slow, but I think the list comparisons form the biggest expense.
Within check_wyckoff_position, I think we can use frozen sets to compare the unorganized lists of symmetry operations, since the SymmOp objects in question will either be identical or completely different. However, because the eq function for the SymmOp class uses np.allclose, the comparison is quite slow; we need to call np.allclose for each element pair.
I am trying to find a workaround, but the hash function for SymmOp is "return 7", and the SymmOp's affine_matrix (ndarray) has no hash functions. We could use the index of the SymmOp within the general position, but this would still require using np.allclose for the comparison. So, I am struggling to figure out how to compare the two sets quickly, but I still have a few ideas.
@qzhu2017
I have implemented a hash on the affine matrices of the SymmOp's. Running profile on
rand_crystal = molecular_crystal(10, ['H2O'], [2], 2.0)
I've gotten the time down from about 450 seconds to about 95 seconds. I am not sure if there is a way to use apply_along_axis for this specific situation, but I will ask David tomorrow how to implement apply_along_axis tomorrow.
@qzhu2017 It seems the new implementation broke generation for some space groups. I have re-uploaded with the old method, with the change that exact_translation is no longer a variable.
@scottfredericks don't forget to check the other places which may slow down the calculation. After that, we can close this issue.
@qzhu2017 It seems the reason for incorrect symmetry is due to the hashing function (in check_wyckoff_position) being incorrect (I think it was using the "return 7" value passed by pymatgen). I have a simple fix, but it slows down the code again. I will upload this fix, then work on optimizing it. I spent most of yesterday thinking about our method, and I think there is a lot of room for improvement. I'll work on implementing it today.
@qzhu2017 I have finally managed to vectorize the code for check_wyckoff_position. We use the squared Euclidean distance between the original set of points, and the points generated by the Wyckoff operators. We require that there be at least one unique mapping between the points and the generated points; this is done by checking the distance matrix. If there is at least one 0 in each row, and a zero in each column, then we say a mapping exists, and the point is valid as a generating point.
There are still some groups which are slow to generate. But, overall the code is significantly faster. I will next work on optimizing the regular distance functions.
@scottfredericks
excellent! There still exist a few space groups which takes quite long time. For atomic_3D, 167, 202, 224 seem to take a long time. But you removed it in the previous test. So it is much better now.
For molecular_3D, It looks like there a many space groups take long time. Not sure why it is.
67 | 67 | 67 | 38.38 s ~~~
74 | 74 | 74 | 27.11 s ~~~
129 | 129 | 129 | 123.11 s ~~~~
134 | 134 | 134 | 77.59 s ~~~~
137 | 137 | 137 | 77.72 s ~~~~
These are not in the list of skipped space groups. We need to do another profiling to understand the processes better.
@qzhu2017 I have updated the methods for find_short_dist and check_distance. Note that this required a change in the way the indices work for the lists sites_tmp, coorinates_tmp, final_coor, etc, within the atomic crystal classes. Previously, we had separate lists of points for each Wyckoff position. Now, we simply store all points in a single np array. Likewise, for the species, we just stored one specie per WP, but now we store the specie of every point in the coordinate list separately. Also, check_distance now takes a list of species for specie2, instead of a single specie. These changes have not yet been implemented for molecular crystals.
I have yet to update the following functions and their implementations:
Also, I need to update the molecular versions of these. I will try to have this done by the end of the week, then move onto other issues.
Also, I've noticed that using a squared Euclidean metric with cdist is for some reason not any faster than a standard Euclidean metric. I expected that taking the square root would make 'euclidean' slower than 'squeuclidean', but this doesn't seem to be the case.
@scottfredericks I just ran some test, the code gained quite a big improvement so far. However, I am not sure about the following results.
Couldn't generate crystal after max attempts.
~~~~ Error: Could not generate space group 191 after 14.82 s ~~~
192 | 192 | 192 | 0.65 s
193 | 193 | 193 | 10.64 s ~~~
Couldn't generate crystal after max attempts.
~~~~ Error: Could not generate space group 194 after 93.96 s ~~~~
195 | 195 | 195 | 0.40 s
196 | 196 | 196 | 3.88 s ~~
197 | 197 | 197 | 0.44 s
198 | 198 | 198 | 0.22 s
199 | 199 | 199 | 1.85 s ~
Couldn't generate crystal after max attempts.
~~~~ Error: Could not generate space group 200 after 15.98 s ~~~
201 | 201 | 201 | 0.48 s
202 | 202 | 202 | 15.37 s ~~~
203 | 203 | 203 | 4.46 s ~~
204 | 204 | 204 | 11.2 s ~~~
205 | 205 | 205 | 0.34 s
206 | 206 | 206 | 1.07 s ~
207 | 207 | 207 | 11.54 s ~~~
208 | 208 | 208 | 0.85 s
209 | 209 | 209 | 3.86 s ~~
Couldn't generate crystal after max attempts.
~~~~ Error: Could not generate space group 210 after 1367.73 s ~~~~
211 | 211 | 211 | 5.34 s ~~
212 | 212 | 212 | 1.95 s ~
213 | 213 | 213 | 0.46 s
214 | 214 | 214 | 69.09 s ~~~~
Couldn't generate crystal after max attempts.
~~~~ Error: Could not generate space group 215 after 14.75 s ~~~
For space group 210, it took 1367 s to complete the max attempts, while it took only 14.75 s for space group 215. I thought each cycle should take more or less same time cost. Why do they differ so much?
@qzhu2017 Most of the improvements for atomic crystals haven't been implemented for molecular crystals yet, but I plan to implement them today. The main difficulty is working with lists of coordinates and species, since there are more of them for molecular crystals.
Also, I think we can simplify the merging of Wyckoff positions if we just consider one point in the position. Instead of generating all points and comparing distances, I think it should be possible to first just compare the distance from the generating point to a new point generated by plugging it into a different Wyckoff position. But, I need to think about it more. The space group P6 is a good example for looking at the possible difficulties.
@qzhu2017 I've managed to implement a new distance check method for 3D molecular crystals. Rather than copy this code for 2D and 1D molecular crystals, I plan to modularize the code by having 2D and 1D crystals inherit the same generate_crystal method. Also, I need to clean up the code in a few spots.
Some space groups are still slow, especially 225-228, but this make some sense considering the size of the general positions. Still, I haven't seen any groups take longer than 40 seconds on my machine, which is an improvement. I haven't gotten to test how long failed generation takes for these groups yet.
@scottfredericks This is a big improvement. Btw, I just tried and found the following errors.
~~~ Error:
Traceback (most recent call last):
File "pyxtal/test_cases/test_all.py", line 1017, in test_modules
from pyxtal.operations import orientation
ImportError: cannot import name 'orientation' from 'pyxtal.operations' (/Users/qiangzhu/Desktop/github/PyXtal/pyxtal/operations.py)
~~~ Failed module ~~~
@qzhu2017 That should be fixed now.
@scottfredericks super! I really appreciate your efforts in improving the code.
My test on molecular_3D went smoothly with a total time cost of 234.9 s
. I am very happy about it.
However, some minor issues still exists. This test reports two failed cases which do not return the desired symmetry. Here are the structures.
Structure-1, desired-109, detected-25
Remark: this structure has very close intermolecular contacts. It suggests that we may have some issue in distance check fucntion.
H32 O16
1.0
10.094833 0.000000 0.000000
0.000000 10.094833 0.000000
0.000000 0.000000 6.260018
H O
32 16
direct
0.075630 0.000000 0.116764 H
0.924370 0.000000 0.116764 H
0.924370 0.500000 0.366764 H
0.075630 0.500000 0.366764 H
0.500000 0.575630 0.616764 H
0.500000 0.424370 0.616764 H
0.500000 0.924370 0.866764 H
0.500000 0.075630 0.866764 H
0.075630 0.000000 0.743135 H
0.924370 0.000000 0.743135 H
0.924370 0.500000 0.993135 H
0.075630 0.500000 0.993135 H
0.500000 0.575630 0.243135 H
0.500000 0.424370 0.243135 H
0.500000 0.924370 0.493135 H
0.500000 0.075630 0.493135 H
0.000000 0.924370 0.657396 H
0.000000 0.075630 0.657396 H
0.000000 0.575630 0.907396 H
0.000000 0.424370 0.907396 H
0.575630 0.500000 0.157396 H
0.424370 0.500000 0.157396 H
0.424370 0.000000 0.407396 H
0.575630 0.000000 0.407396 H
0.000000 0.924370 0.935775 H
0.000000 0.075630 0.935775 H
0.000000 0.575630 0.185775 H
0.000000 0.424370 0.185775 H
0.575630 0.500000 0.435775 H
0.424370 0.500000 0.435775 H
0.424370 0.000000 0.685775 H
0.575630 0.000000 0.685775 H
0.000000 0.000000 0.212084 O
0.000000 0.500000 0.462084 O
0.500000 0.500000 0.712084 O
0.500000 0.000000 0.962084 O
0.000000 0.000000 0.838454 O
0.000000 0.500000 0.088454 O
0.500000 0.500000 0.338454 O
0.500000 0.000000 0.588454 O
0.000000 0.000000 0.562077 O
0.000000 0.500000 0.812077 O
0.500000 0.500000 0.062077 O
0.500000 0.000000 0.312077 O
0.000000 0.000000 0.031095 O
0.000000 0.500000 0.281095 O
0.500000 0.500000 0.531095 O
0.500000 0.000000 0.781095 O
Structure-2---desired 80, detected 3
QZ: Remark: this structure looks good to me. I don't understand why it failed. Could you please check it? If it is indeed the error of spglib, we should contact the author.
H16 O8
1.0
5.017367 0.000000 0.000000
0.000000 5.017367 0.000000
0.000000 0.000000 12.670451
H O
16 8
direct
0.910188 0.877167 0.068394 H
0.089812 0.122833 0.068394 H
0.089812 0.622833 0.318394 H
0.910188 0.377167 0.318394 H
0.622833 0.410188 0.568394 H
0.377167 0.589812 0.568394 H
0.377167 0.089812 0.818394 H
0.622833 0.910188 0.818394 H
0.136118 0.931983 0.742144 H
0.863882 0.068017 0.742144 H
0.863882 0.568017 0.992144 H
0.136118 0.431983 0.992144 H
0.568017 0.636118 0.242144 H
0.431983 0.363882 0.242144 H
0.431983 0.863882 0.492144 H
0.568017 0.136118 0.492144 H
0.000000 0.000000 0.021300 O
0.000000 0.500000 0.271300 O
0.500000 0.500000 0.521300 O
0.500000 0.000000 0.771300 O
0.000000 0.000000 0.695050 O
0.000000 0.500000 0.945050 O
0.500000 0.500000 0.195050 O
0.500000 0.000000 0.445050 O
@qzhu2017 It seems I've misunderstood how to implement the covalent radius in distance checks. For hydrogen, the value is 0.31. Clearly, this is too small a distance for Hydrogens to be separated by; in water the O-H distance is about 0.93894 Angstroms (using mol_from_collection('H2O')). In H2, the distance is about 0.74 Angstroms.
Currently, the program takes the average of the covalent radii between two atoms as the tolerance. It looks like we should at least double or maybe triple this. I think that we can use a smaller tolerance for inter-molecular atomic distance checks, and a larger tolerance for the final distance check (which checks distances within the same molecule). In theory, if we use the right value for the first check, we shouldn't need to perform the final distance check at all. We can easily test this by printing a message when the final distance check detects something.
So, for perspective: The current value for H-O tolerance is 0.485 A, while the H-O distance in water is 0.93 A. The current value for H-H tolerance is 0.310 A, while the H-H distance in H2 is 0.74 A.
Given your knowledge, what do you think a reasonable choice would be?
@scottfredericks I see. Remember, this is the covalent radii. So estimation of bond length should be the sum of two radius. Suppose H has 0.31 A and O has 0.66 For H-O, the tolerance should be 0.31+0.66 = 0.97. We should not allow the intermolecular H-O contacts has distance smaller than 0.97. Similarly, the tolerance should be 0.312 for H-H, 0.662 for O-O.
@qzhu2017 For space group 80 and 109 (and for 110), I got similar results, and realized it was only happening for space groups with screw axes. For these cases, I think we just need to use the Wyckoff generators instead of the Wyckoff positions for choosing molecular centers. I have implemented this change, and after testing these space groups 100 times each, I have not seen the issue come up again.
For the tolerance, I have updated to use the sum of both tolerances. For the final verify_distances, I use a factor of 0.75, since otherwise the bonds within a single molecule would fail the check. For some reason the crystal sometimes fails this final distance check. I am not sure why, so I will try to troubleshoot it.
@scottfredericks For molecular crystals, we only check the intermolecular distances, not the intramolecular distances. We don't want the atoms belonging two different molecules to form the bonds.
Say if you have two molecules, H2O-1 and H2O-2. We only check distance between H (in H2O-1) and H (in H2O-2), but not the distance between H and H in both H2O-1.
@scottfredericks , I think your implementation is wrong. Let me make it clear.
For atomic crystal
, we check all atomic distances. For any R(i-j), we set
tolerance = 0.5 * (radii_i + radii_j). If R(i-j) < tol, we reject the structure.
For molecular crystal
, we don't check all distances. Instead, we check only the intermolecular distance
R(i-j), where i and j are from different molecules.
tolerance = 1.0* (radii_i + radii_j), if R(i-j) <tol, we reject this structure.
For future reference and optimization, here is output for profiling molecular_crystal. This is using inter-atomic distances.
>>> profile.run("c = molecular_crystal(225, ['H2O'], [48], 1.0)")
547152321 function calls (544548359 primitive calls) in 3925.418 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
243076 2.077 0.000 2.077 0.000 :0(__array_prepare__)
166556 1.267 0.000 1.267 0.000 :0(__array_wrap__)
79342 1.968 0.000 1.968 0.000 :0(__deepcopy__)
185866 1.719 0.000 1.719 0.000 :0(__new__)
181527 5.403 0.000 6.594 0.000 :0(__reduce_ex__)
9041 0.039 0.000 0.039 0.000 :0(abs)
104 0.001 0.000 0.001 0.000 :0(acos)
9 0.000 0.000 0.000 0.000 :0(add)
270328 0.611 0.000 0.806 0.000 :0(all)
64415 0.442 0.000 0.813 0.000 :0(any)
8580386 22.100 0.000 22.100 0.000 :0(append)
2020 0.016 0.000 0.016 0.000 :0(argmin)
1 0.000 0.000 0.000 0.000 :0(argsort)
68154905 324.507 0.000 324.507 0.000 :0(array)
77586 1.916 0.000 1.916 0.000 :0(astype)
2296 0.007 0.000 0.007 0.000 :0(bit_length)
16 0.000 0.000 0.000 0.000 :0(callable)
64027 14.236 0.000 14.236 0.000 :0(cdist_euclidean_double_wrap)
1 0.000 0.000 0.000 0.000 :0(cluster_dist)
2165 0.041 0.000 0.041 0.000 :0(concatenate)
61993 0.349 0.000 0.349 0.000 :0(copy)
166557 2.441 0.000 2.441 0.000 :0(copyto)
365 0.002 0.000 0.002 0.000 :0(cos)
5512935 40.462 0.000 40.462 0.000 :0(dot)
64043 0.469 0.000 0.469 0.000 :0(empty)
166556 4.362 0.000 4.362 0.000 :0(empty_like)
8 0.015 0.002 0.015 0.002 :0(eval)
1 0.000 0.000 3925.418 3925.418 :0(exec)
40812 0.144 0.000 0.144 0.000 :0(finditer)
2165 0.017 0.000 0.017 0.000 :0(flatten)
54 0.000 0.000 0.000 0.000 :0(format)
262 0.008 0.000 0.008 0.000 :0(frompyfunc)
4422431 59.494 0.000 59.501 0.000 :0(get)
8 0.000 0.000 0.000 0.000 :0(get_value)
1236436 12.203 0.000 13.609 0.000 :0(getattr)
11308 0.044 0.000 0.044 0.000 :0(geterrobj)
3882 0.013 0.000 0.013 0.000 :0(getrandbits)
93816 0.204 0.000 0.204 0.000 :0(group)
234889 5.949 0.000 7.464 0.000 :0(hasattr)
8 0.000 0.000 0.000 0.000 :0(hash)
3110407 40.984 0.000 40.984 0.000 :0(id)
1 0.000 0.000 0.000 0.000 :0(inconsistent)
64185 0.307 0.000 0.307 0.000 :0(index)
42 0.000 0.000 0.000 0.000 :0(insert)
16 0.000 0.000 0.000 0.000 :0(is_float)
1577010 11.913 0.000 11.944 0.000 :0(isinstance)
8 0.000 0.000 0.000 0.000 :0(isscalar)
10954275 34.523 0.000 34.523 0.000 :0(issubclass)
853009 5.680 0.000 5.680 0.000 :0(items)
4216 0.011 0.000 0.011 0.000 :0(join)
82103 0.617 0.000 0.617 0.000 :0(keys)
923473/844384 6.037 0.000 7.301 0.000 :0(len)
70736 0.255 0.000 0.255 0.000 :0(lower)
77299 0.935 0.000 0.935 0.000 :0(max)
238653 1.610 0.000 16.024 0.000 :0(mean)
78710 0.886 0.000 0.886 0.000 :0(min)
1 0.000 0.000 0.000 0.000 :0(mst_single_linkage)
61368164/61201608 122.981 0.000 127.027 0.000 :0(next)
166682 2.175 0.000 2.175 0.000 :0(normalize_axis_index)
17736 0.034 0.000 0.034 0.000 :0(ord)
1 0.000 0.000 0.000 0.000 :0(pdist_euclidean_double_wrap)
306092 0.731 0.000 0.731 0.000 :0(pop)
14 0.000 0.000 0.000 0.000 :0(promote_types)
5014 0.056 0.000 0.056 0.000 :0(random_sample)
4863755 24.577 0.000 24.577 0.000 :0(ravel)
50810657 533.874 0.000 533.874 0.000 :0(reduce)
2067 0.008 0.000 0.008 0.000 :0(remove)
262 0.003 0.000 0.003 0.000 :0(repeat)
6672 0.029 0.000 0.029 0.000 :0(replace)
1 0.000 0.000 0.000 0.000 :0(reshape)
2827 0.024 0.000 0.024 0.000 :0(result_type)
239371 1.983 0.000 1.983 0.000 :0(round)
579 0.001 0.000 0.001 0.000 :0(search)
5654 0.027 0.000 0.027 0.000 :0(seterrobj)
1 0.000 0.000 0.000 0.000 :0(setprofile)
356 0.002 0.000 0.002 0.000 :0(sin)
2165 0.030 0.000 0.030 0.000 :0(sort)
3996 0.029 0.000 0.037 0.000 :0(sorted)
6672 0.026 0.000 0.026 0.000 :0(split)
189 0.001 0.000 0.001 0.000 :0(sqrt)
6672 0.022 0.000 0.022 0.000 :0(strip)
78485 0.455 0.000 1.669 0.000 :0(sum)
334593 2.861 0.000 2.861 0.000 :0(transpose)
181750 3.174 0.000 3.174 0.000 :0(update)
20 0.000 0.000 0.000 0.000 :0(upper)
8689 0.022 0.000 0.022 0.000 :0(values)
16 0.000 0.000 0.000 0.000 :0(values_from_object)
8 0.000 0.000 0.000 0.000 :0(view)
3581 0.251 0.000 0.251 0.000 :0(where)
575780 8.735 0.000 8.735 0.000 :0(zeros)
26682 1.048 0.000 1.772 0.000 <frozen importlib._bootstrap>:989(_handle_fromlist)
9/1 0.000 0.000 3925.417 3925.417 <string>:1(<module>)
108 0.000 0.000 0.001 0.000 __init__.py:1284(debug)
108 0.000 0.000 0.000 0.000 __init__.py:1528(getEffectiveLevel)
108 0.000 0.000 0.001 0.000 __init__.py:1542(isEnabledFor)
84006 1.601 0.000 2.314 0.000 _collections_abc.py:672(keys)
1823 0.011 0.000 0.015 0.000 _collections_abc.py:676(items)
85829 0.718 0.000 0.718 0.000 _collections_abc.py:698(__init__)
76098 1.268 0.000 4.556 0.000 _collections_abc.py:701(__len__)
168012 2.303 0.000 4.472 0.000 _collections_abc.py:719(__iter__)
3646 0.025 0.000 0.091 0.000 _collections_abc.py:742(__iter__)
50484092 157.543 0.000 687.198 0.000 _methods.py:28(_amin)
78096 0.259 0.000 1.214 0.000 _methods.py:31(_sum)
125 0.000 0.000 0.002 0.000 _methods.py:37(_any)
9687 0.050 0.000 0.195 0.000 _methods.py:40(_all)
238657 1.181 0.000 1.726 0.000 _methods.py:43(_count_reduce_items)
238657 6.908 0.000 14.414 0.000 _methods.py:53(_mean)
4278 0.012 0.000 0.012 0.000 _weakrefset.py:70(__contains__)
2334 0.020 0.000 0.032 0.000 abc.py:178(__instancecheck__)
54 0.002 0.000 0.125 0.002 analyzer.py:1005(_check_R2_axes_asym)
54 0.004 0.000 0.111 0.002 analyzer.py:1016(_find_mirror)
12 0.000 0.000 0.026 0.002 analyzer.py:1183(get_pointgroup)
589 0.053 0.000 0.570 0.001 analyzer.py:1190(is_valid_op)
1 0.000 0.000 0.006 0.006 analyzer.py:1212(_get_eq_sets)
1 0.000 0.000 0.000 0.000 analyzer.py:1234(<listcomp>)
1 0.000 0.000 0.002 0.002 analyzer.py:1237(get_clustered_indices)
12 0.000 0.000 0.000 0.000 analyzer.py:1252(<setcomp>)
2 0.000 0.000 0.000 0.000 analyzer.py:1257(<dictcomp>)
1 0.000 0.000 0.001 0.001 analyzer.py:1272(_combine_eq_sets)
2 0.000 0.000 0.000 0.000 analyzer.py:1295(all_equivalent_atoms_of_i)
2 0.000 0.000 0.000 0.000 analyzer.py:1299(<dictcomp>)
1 0.000 0.000 0.007 0.007 analyzer.py:1331(get_equivalent_atoms)
1 0.000 0.000 0.008 0.008 analyzer.py:1354(symmetrize_molecule)
1 0.000 0.000 0.002 0.002 analyzer.py:1454(cluster_sites)
1 0.000 0.000 0.000 0.000 analyzer.py:1469(<listcomp>)
1 0.000 0.000 0.000 0.000 analyzer.py:1475(<dictcomp>)
13 0.005 0.000 0.027 0.002 analyzer.py:1494(generate_full_symmops)
13 0.000 0.000 0.010 0.001 analyzer.py:1512(<listcomp>)
13 0.000 0.000 0.001 0.000 analyzer.py:1530(<listcomp>)
12 0.000 0.000 0.026 0.002 analyzer.py:1607(__init__)
54 0.001 0.000 6.073 0.112 analyzer.py:841(__init__)
54 0.041 0.001 5.237 0.097 analyzer.py:864(_analyze)
54 0.001 0.000 0.239 0.004 analyzer.py:917(_proc_asym_top)
54 0.001 0.000 0.113 0.002 analyzer.py:976(_proc_cyclic)
54 0.000 0.000 0.000 0.000 analyzer.py:980(<lambda>)
2165 0.032 0.000 0.226 0.000 arraysetops.py:113(unique)
2165 0.084 0.000 0.182 0.000 arraysetops.py:256(_unique1d)
8 0.000 0.000 0.000 0.000 base.py:1303(_convert_scalar_indexer)
8 0.000 0.000 0.000 0.000 base.py:1638(__contains__)
8 0.000 0.000 0.001 0.000 base.py:2454(get_value)
8 0.000 0.000 0.000 0.000 base.py:3360(_maybe_cast_indexer)
1 0.000 0.000 0.002 0.002 collection.py:49(__getitem__)
1 0.000 0.000 0.002 0.002 collection.py:57(_read)
16 0.000 0.000 0.000 0.000 common.py:435(_apply_if_callable)
582 0.016 0.000 0.039 0.000 composition.py:102(__init__)
3019 0.029 0.000 0.085 0.000 composition.py:146(__getitem__)
78490 1.244 0.000 1.855 0.000 composition.py:155(__len__)
77921 1.558 0.000 2.166 0.000 composition.py:158(__iter__)
1196 0.033 0.000 0.170 0.000 composition.py:170(__eq__)
3 0.000 0.000 0.000 0.000 composition.py:243(__hash__)
390 0.005 0.000 0.738 0.002 composition.py:431(weight)
390 0.005 0.000 0.728 0.002 composition.py:437(<listcomp>)
1416 0.077 0.000 0.189 0.000 coord_utils.py:31(find_in_coord_list)
1917933/26437 165.182 0.000 424.146 0.016 copy.py:132(deepcopy)
1218003 9.423 0.000 9.423 0.000 copy.py:190(_deepcopy_atomic)
26397/26199 2.746 0.000 367.511 0.014 copy.py:210(_deepcopy_list)
335527/26244 37.820 0.000 398.527 0.015 copy.py:236(_deepcopy_dict)
622793 16.000 0.000 25.945 0.000 copy.py:252(_keep_alive)
181527/26243 26.257 0.000 414.484 0.016 copy.py:268(_reconstruct)
363054 6.627 0.000 33.822 0.000 copy.py:273(<genexpr>)
181522 3.417 0.000 5.123 0.000 copyreg.py:87(__newobj__)
1 0.000 0.000 0.000 0.000 copyreg.py:96(_slotnames)
3 0.000 0.000 0.000 0.000 crystal.py:1027(generate_lattice)
80756 3.418 0.000 158.134 0.002 crystal.py:111(filtered_coords)
776256 28.872 0.000 28.872 0.000 crystal.py:127(filter_vector)
27922 0.239 0.000 251.647 0.009 crystal.py:134(filtered_coords_euclidean)
5 0.028 0.006 0.819 0.164 crystal.py:1432(get_wyckoffs)
4863039 124.466 0.000 124.466 0.000 crystal.py:149(filter_vector_euclidean)
1 0.037 0.037 0.906 0.906 crystal.py:1612(get_wyckoff_symmetry)
2 0.015 0.007 0.700 0.350 crystal.py:1785(get_wyckoff_generators)
1780 0.014 0.000 0.014 0.000 crystal.py:221(jk_from_i)
240949 13.251 0.000 30.773 0.000 crystal.py:489(create_matrix)
2296 0.196 0.000 2469.116 1.075 crystal.py:541(distance_matrix)
2296 0.419 0.000 0.419 0.000 crystal.py:562(<listcomp>)
2296 0.560 0.000 26.702 0.012 crystal.py:564(<listcomp>)
131 0.001 0.000 0.001 0.000 crystal.py:567(dsquared)
27791 0.576 0.000 648.512 0.023 crystal.py:570(distance_matrix_euclidean)
52812 0.650 0.000 0.650 0.000 crystal.py:584(subtract)
75718 3.564 0.000 12.131 0.000 crystal.py:594(get_tol)
132 0.027 0.000 41.510 0.314 crystal.py:618(check_distance)
238653 5.913 0.000 59.094 0.000 crystal.py:666(get_center)
3 0.000 0.000 0.000 0.000 crystal.py:701(para2matrix)
1 0.000 0.000 0.000 0.000 crystal.py:837(cellsize)
2165 1.679 0.001 2444.259 1.129 crystal.py:861(find_short_dist)
1479 2.596 0.002 4.582 0.003 crystal.py:909(connected_components)
240672/238653 0.655 0.000 0.658 0.000 crystal.py:927(add_neighbors)
64028 0.164 0.000 0.164 0.000 distance.py:125(_args_to_kwargs_xdist)
1 0.000 0.000 0.000 0.000 distance.py:1388(pdist)
128055 0.307 0.000 0.656 0.000 distance.py:164(_copy_array_if_base_present)
128055 0.450 0.000 1.628 0.000 distance.py:184(_convert_to_type)
64028 0.159 0.000 0.159 0.000 distance.py:188(_filter_deprecated_kwargs)
2 0.000 0.000 0.000 0.000 distance.py:1958(is_valid_y)
1 0.000 0.000 0.000 0.000 distance.py:2036(num_obs_y)
64027 4.261 0.000 26.602 0.000 distance.py:2065(cdist)
64027 0.912 0.000 2.846 0.000 distance.py:241(_validate_cdist_input)
1 0.000 0.000 0.000 0.000 distance.py:283(_validate_pdist_input)
76297 8.581 0.000 8.581 0.000 element.py:12(__init__)
77580 1.932 0.000 3.180 0.000 enum.py:265(__call__)
77580 1.248 0.000 1.248 0.000 enum.py:515(__new__)
76032 0.652 0.000 0.652 0.000 enum.py:592(name)
8 0.000 0.000 0.000 0.000 frame.py:1940(__getitem__)
8 0.000 0.000 0.000 0.000 frame.py:1966(_getitem_column)
2020 0.009 0.000 0.039 0.000 fromnumeric.py:1007(argmin)
1 0.000 0.000 0.000 0.000 fromnumeric.py:1778(sum)
117 0.001 0.000 0.003 0.000 fromnumeric.py:1934(any)
9452 0.104 0.000 0.441 0.000 fromnumeric.py:2021(all)
50484092 295.609 0.000 982.807 0.000 fromnumeric.py:2323(amin)
239371 0.968 0.000 4.504 0.000 fromnumeric.py:2771(around)
239371 0.835 0.000 5.339 0.000 fromnumeric.py:2840(round_)
4 0.000 0.000 0.000 0.000 fromnumeric.py:2854(mean)
262 0.004 0.000 0.012 0.000 fromnumeric.py:37(_wrapit)
262 0.001 0.000 0.018 0.000 fromnumeric.py:382(repeat)
576205 6.226 0.000 13.292 0.000 fromnumeric.py:50(_wrapfunc)
334551 3.854 0.000 13.565 0.000 fromnumeric.py:529(transpose)
1 0.000 0.000 0.000 0.000 fromnumeric.py:851(argsort)
232677 3.928 0.000 10.468 0.000 function_base.py:1461(copy)
262 0.016 0.000 13.206 0.050 function_base.py:2727(__call__)
262 0.046 0.000 0.223 0.001 function_base.py:2757(_get_ufunc_and_otypes)
262 0.006 0.000 0.056 0.000 function_base.py:2779(<listcomp>)
524 0.006 0.000 0.006 0.000 function_base.py:2780(<genexpr>)
262 0.008 0.000 0.008 0.000 function_base.py:2784(<listcomp>)
262 0.008 0.000 0.020 0.000 function_base.py:2808(<listcomp>)
262 0.840 0.003 13.190 0.050 function_base.py:2818(_vectorize_call)
262 0.006 0.000 0.028 0.000 function_base.py:2828(<listcomp>)
8 0.000 0.000 0.000 0.000 generic.py:1640(_get_item_cache)
8 0.000 0.000 0.000 0.000 generic.py:7(_check)
1 0.000 0.000 0.000 0.000 groups.py:36(get_symm_data)
1 0.000 0.000 0.000 0.000 groups.py:487(sg_symbol_from_int_number)
1 0.000 0.000 0.000 0.000 hierarchy.py:1214(_convert_to_double)
1 0.000 0.000 0.000 0.000 hierarchy.py:1284(inconsistent)
2 0.000 0.000 0.000 0.000 hierarchy.py:1537(is_valid_linkage)
2 0.000 0.000 0.000 0.000 hierarchy.py:1618(_check_hierarchy_uses_cluster_before_formed)
2 0.000 0.000 0.000 0.000 hierarchy.py:1626(_check_hierarchy_uses_cluster_more_than_once)
1 0.000 0.000 0.000 0.000 hierarchy.py:1699(fcluster)
1 0.000 0.000 0.001 0.001 hierarchy.py:1809(fclusterdata)
3 0.000 0.000 0.000 0.000 hierarchy.py:206(_copy_array_if_base_present)
3 0.000 0.000 0.000 0.000 hierarchy.py:218(_copy_arrays_if_base_present)
3 0.000 0.000 0.000 0.000 hierarchy.py:225(<listcomp>)
1 0.000 0.000 0.000 0.000 hierarchy.py:485(linkage)
166556 10.815 0.000 51.826 0.000 index_tricks.py:566(__init__)
166556 0.733 0.000 0.733 0.000 index_tricks.py:574(__iter__)
61201608 219.133 0.000 339.340 0.000 index_tricks.py:585(__next__)
8 0.000 0.000 0.000 0.000 internals.py:154(internal_values)
8 0.000 0.000 0.000 0.000 internals.py:169(to_dense)
8 0.000 0.000 0.000 0.000 internals.py:303(dtype)
24 0.000 0.000 0.000 0.000 internals.py:4124(_block)
8 0.000 0.000 0.000 0.000 internals.py:4194(dtype)
8 0.000 0.000 0.000 0.000 internals.py:4221(internal_values)
8 0.000 0.000 0.000 0.000 internals.py:4224(get_values)
576 0.002 0.000 0.005 0.000 lattice.py:135(get_cartesian_coords)
1 0.000 0.000 0.000 0.000 lattice.py:46(__init__)
1 0.000 0.000 0.000 0.000 lattice.py:79(<listcomp>)
76520 1.082 0.000 1.082 0.000 linalg.py:100(get_linalg_error_extobj)
234 0.021 0.000 0.054 0.000 linalg.py:1021(eig)
76520 2.487 0.000 5.463 0.000 linalg.py:105(_makearray)
5018437 14.742 0.000 23.042 0.000 linalg.py:110(isComplexType)
20 0.001 0.000 0.003 0.000 linalg.py:1162(eigh)
77380 1.372 0.000 2.102 0.000 linalg.py:123(_realType)
98 0.000 0.000 0.000 0.000 linalg.py:126(_complexType)
77224 4.120 0.000 9.097 0.000 linalg.py:138(_commonType)
704 0.021 0.000 0.057 0.000 linalg.py:1822(det)
77224 0.937 0.000 0.937 0.000 linalg.py:197(_assertRankAtLeast2)
77224 2.556 0.000 4.359 0.000 linalg.py:208(_assertNdSquareness)
4863755 122.728 0.000 237.160 0.000 linalg.py:2103(norm)
234 0.002 0.000 0.007 0.000 linalg.py:213(_assertFinite)
76266 15.900 0.000 41.332 0.001 linalg.py:464(inv)
1 0.000 0.000 0.000 0.000 molecular_crystal.py:153(get_box)
2165 1.634 0.001 653.797 0.302 molecular_crystal.py:228(check_wyckoff_position_molecular)
27660 0.183 0.000 0.931 0.000 molecular_crystal.py:262(<listcomp>)
131 0.077 0.001 0.526 0.004 molecular_crystal.py:279(<listcomp>)
2165 5.577 0.003 3168.037 1.463 molecular_crystal.py:302(merge_coordinate_molecular)
2165 0.093 0.000 0.217 0.000 molecular_crystal.py:354(choose_wyckoff_molecular)
131 0.001 0.000 0.001 0.000 molecular_crystal.py:403(__init__)
132 15.933 0.121 695.066 5.266 molecular_crystal.py:423(_get_coords_and_species)
1 0.001 0.001 7.475 7.475 molecular_crystal.py:488(get_coords_and_species)
131 0.169 0.001 729.307 5.567 molecular_crystal.py:519(check_distances)
1 0.001 0.001 3925.417 3925.417 molecular_crystal.py:575(__init__)
1 0.000 0.000 0.000 0.000 molecular_crystal.py:660(Msgs)
1 0.001 0.001 9.004 9.004 molecular_crystal.py:668(get_orientations)
1 0.000 0.000 0.000 0.000 molecular_crystal.py:699(check_compatible)
1 0.000 0.000 0.000 0.000 molecular_crystal.py:705(<listcomp>)
1 0.229 0.229 3914.175 3914.175 molecular_crystal.py:750(generate_crystal)
2165 0.901 0.000 6.220 0.003 molecular_crystal.py:833(<listcomp>)
577 0.006 0.000 0.020 0.000 molecular_crystal.py:916(<genexpr>)
1 0.000 0.000 0.000 0.000 molecular_crystal.py:94(estimate_volume_molecular)
1 0.000 0.000 0.190 0.190 molecule.py:129(reoriented_molecule)
2 0.000 0.000 0.033 0.017 molecule.py:143(reorient)
12 0.000 0.000 1.187 0.099 molecule.py:189(get_symmetry)
41/12 0.060 0.001 9.003 0.750 molecule.py:254(orientation_in_wyckoff_position)
20 0.002 0.000 0.164 0.008 molecule.py:82(get_inertia_tensor)
3 0.000 0.000 0.000 0.000 num.py:16(abs_cap)
8 0.000 0.000 0.000 0.000 numeric.py:134(_convert_scalar_indexer)
84 0.003 0.000 0.006 0.000 numeric.py:1459(normalize_axis_tuple)
1 0.000 0.000 0.000 0.000 numeric.py:146(ones)
168 0.001 0.000 0.002 0.000 numeric.py:1506(<genexpr>)
42 0.003 0.000 0.011 0.000 numeric.py:1515(moveaxis)
42 0.000 0.000 0.000 0.000 numeric.py:1577(<listcomp>)
14 0.004 0.000 0.017 0.001 numeric.py:1591(cross)
26682 1.285 0.000 5.327 0.000 numeric.py:2157(identity)
1913 0.026 0.000 0.573 0.000 numeric.py:2189(allclose)
2827 0.130 0.000 0.975 0.000 numeric.py:2260(isclose)
2827 0.132 0.000 0.459 0.000 numeric.py:2319(within_tol)
5654 0.097 0.000 0.226 0.000 numeric.py:2460(seterr)
5654 0.058 0.000 0.078 0.000 numeric.py:2560(geterr)
2827 0.016 0.000 0.024 0.000 numeric.py:2853(__init__)
2827 0.022 0.000 0.138 0.000 numeric.py:2857(__enter__)
2827 0.023 0.000 0.134 0.000 numeric.py:2862(__exit__)
5236413 16.477 0.000 31.691 0.000 numeric.py:424(asarray)
61459818 181.564 0.000 462.301 0.000 numeric.py:495(asanyarray)
128055 0.384 0.000 1.178 0.000 numeric.py:547(ascontiguousarray)
166556 4.663 0.000 13.993 0.000 numeric.py:83(zeros_like)
6 0.000 0.000 0.000 0.000 numerictypes.py:577(obj2sctype)
3 0.000 0.000 0.000 0.000 numerictypes.py:669(issubsctype)
537846 10.601 0.000 23.686 0.000 operations.py:104(operate)
563 0.017 0.000 0.476 0.001 operations.py:109(is_orthogonal)
194 0.021 0.000 0.054 0.000 operations.py:128(aa2matrix)
207 0.018 0.000 0.439 0.002 operations.py:175(matrix2aa)
3143 0.012 0.000 0.012 0.000 operations.py:183(rotation_matrix)
145 0.007 0.000 0.022 0.000 operations.py:197(__mul__)
72 0.004 0.000 0.074 0.001 operations.py:205(inverse)
162 0.009 0.000 0.033 0.000 operations.py:213(from_axis_angle_and_translation)
14 0.002 0.000 0.067 0.005 operations.py:246(rotate_vector)
108 0.007 0.000 0.026 0.000 operations.py:313(reflection)
280 0.007 0.000 0.025 0.000 operations.py:336(get_order)
207 0.012 0.000 0.707 0.003 operations.py:357(__init__)
6672 0.705 0.000 1.652 0.000 operations.py:406(from_xyz_string)
35847 0.646 0.000 1.121 0.000 operations.py:43(__init__)
158 0.019 0.000 0.328 0.002 operations.py:43(angle)
100 0.001 0.000 0.009 0.000 operations.py:439(is_conjugate)
176 0.003 0.000 0.226 0.001 operations.py:516(__init__)
436 0.004 0.000 0.034 0.000 operations.py:530(get_matrix)
161 0.002 0.000 0.020 0.000 operations.py:560(get_op)
131 0.001 0.000 0.125 0.001 operations.py:596(random_orientation)
35416 2.717 0.000 6.932 0.000 operations.py:61(from_rotation_and_translation)
4183 0.030 0.000 0.057 0.000 periodic_table.py:1256(get_el_sp)
60 0.000 0.000 0.000 0.000 periodic_table.py:486(number)
81184 0.675 0.000 0.675 0.000 periodic_table.py:549(__hash__)
3 0.000 0.000 0.000 0.000 periodic_table.py:555(__str__)
77001 2.111 0.000 5.286 0.000 periodic_table.py:769(__deepcopy__)
579 0.003 0.000 0.009 0.000 periodic_table.py:951(from_string)
1 0.000 0.000 3925.418 3925.418 profile:0(c = molecular_crystal(225, ['H2O'], [48], 1.0))
0 0.000 0.000 profile:0(profiler)
2296 0.028 0.000 0.048 0.000 random.py:222(_randbelow)
2296 0.024 0.000 0.076 0.000 random.py:252(choice)
8 0.000 0.000 0.000 0.000 range.py:446(__len__)
579 0.003 0.000 0.006 0.000 re.py:179(search)
780 0.007 0.000 0.014 0.000 re.py:224(finditer)
13344 0.042 0.000 0.076 0.000 re.py:231(compile)
14703 0.038 0.000 0.038 0.000 re.py:286(_compile)
8 0.000 0.000 0.000 0.000 series.py:331(dtype)
8 0.000 0.000 0.000 0.000 series.py:384(_values)
8 0.000 0.000 0.000 0.000 series.py:389(get_values)
8 0.000 0.000 0.001 0.000 series.py:598(__getitem__)
61201608 236.923 0.000 576.263 0.000 shape_base.py:125(<genexpr>)
166556 706.623 0.004 3196.549 0.019 shape_base.py:23(apply_along_axis)
3 0.000 0.000 0.000 0.000 sites.py:121(species_string)
155797 1.296 0.000 1.296 0.000 sites.py:133(species_and_occu)
76095 4.538 0.000 15.778 0.000 sites.py:141(specie)
232677 4.554 0.000 15.023 0.000 sites.py:156(coords)
3 0.000 0.000 0.000 0.000 sites.py:171(x)
3 0.000 0.000 0.000 0.000 sites.py:178(y)
3 0.000 0.000 0.000 0.000 sites.py:185(z)
576 0.005 0.000 0.088 0.000 sites.py:292(__init__)
153363 5.842 0.000 8.963 0.000 sites.py:42(__init__)
152781 5.033 0.000 7.972 0.000 sites.py:82(properties)
152781 1.729 0.000 1.729 0.000 sites.py:87(<dictcomp>)
231003 4.111 0.000 4.111 0.000 sites.py:89(__getattr__)
64028 0.294 0.000 1.089 0.000 six.py:130(callable)
192084 0.364 0.000 0.364 0.000 six.py:131(<genexpr>)
166556 1.046 0.000 1.046 0.000 stride_tricks.py:20(__init__)
166556 1.077 0.000 1.077 0.000 stride_tricks.py:25(_maybe_view_as_subclass)
166556 12.616 0.000 22.804 0.000 stride_tricks.py:38(as_strided)
1 0.000 0.000 0.000 0.000 structure.py:107(<listcomp>)
76 0.001 0.000 0.003 0.000 structure.py:109(species_and_occu)
76 0.001 0.000 0.001 0.000 structure.py:114(<listcomp>)
76 0.003 0.000 0.009 0.000 structure.py:162(site_properties)
78 0.009 0.000 0.031 0.000 structure.py:1623(__init__)
76 0.013 0.000 0.953 0.013 structure.py:1702(center_of_mass)
28749 0.222 0.000 0.222 0.000 structure.py:1715(sites)
27003 0.639 0.000 0.853 0.000 structure.py:180(__iter__)
1093 0.007 0.000 0.009 0.000 structure.py:183(__getitem__)
653 0.015 0.000 0.024 0.000 structure.py:186(__len__)
728 0.011 0.000 0.082 0.000 structure.py:200(cart_coords)
76 0.004 0.000 1.007 0.013 structure.py:2049(get_centered_molecule)
728 0.010 0.000 0.054 0.000 structure.py:206(<listcomp>)
1 0.000 0.000 0.095 0.095 structure.py:2205(__init__)
78 0.001 0.000 0.032 0.000 structure.py:2869(__init__)
50851 1.901 0.000 58.548 0.001 structure.py:3190(apply_operation)
152553 11.329 0.000 54.214 0.000 structure.py:3198(operate_site)
50851 2.433 0.000 56.646 0.001 structure.py:3203(<listcomp>)
1 0.005 0.005 0.095 0.095 structure.py:338(__init__)
1 0.000 0.000 0.000 0.000 structure.py:98(species)
62275 2.872 0.000 4.289 0.000 twodim_base.py:140(eye)
1106 0.006 0.000 0.006 0.000 type_check.py:106(real)
76032 1.532 0.000 2.184 0.000 types.py:135(__get__)
8688 2.227 0.000 5.076 0.001 units.py:180(check_mappings)
260640 1.104 0.000 1.602 0.000 units.py:183(<listcomp>)
8688 0.233 0.000 5.512 0.001 units.py:196(__init__)
7908 0.019 0.000 0.019 0.000 units.py:217(<dictcomp>)
7908 0.016 0.000 0.016 0.000 units.py:245(__iter__)
7908 0.013 0.000 0.013 0.000 units.py:248(__getitem__)
3954 0.046 0.000 0.108 0.000 units.py:254(__repr__)
3954 0.008 0.000 0.008 0.000 units.py:256(<lambda>)
3954 0.011 0.000 0.011 0.000 units.py:257(<listcomp>)
3954 0.017 0.000 0.125 0.000 units.py:261(__str__)
4344 0.037 0.000 2.820 0.001 units.py:363(__new__)
4344 0.043 0.000 2.910 0.001 units.py:369(__init__)
2592 0.030 0.000 3.226 0.001 units.py:413(__mul__)
390 0.006 0.000 0.704 0.002 units.py:421(__rmul__)
972 0.010 0.000 1.187 0.001 units.py:449(__neg__)
390 0.015 0.000 1.450 0.004 units.py:846(wrapped_f)
@qzhu2017 There is now an option "-s" or "--summary" in test_all.py. This outputs a summary.txt file which contains all the information printed to the terminal during the test run. If any incorrect symmetries are found, this file will be output automatically.
I am still not very happy about the efficiency. By running the tests on molecular_3D. It takes a lot of time for some space groups. We need to figure out which parts of the code need to be optimized.