6
6
import typing
7
7
from collections import defaultdict
8
8
from itertools import pairwise
9
+ from warnings import warn
9
10
10
11
import numpy as np
11
12
import pandas as pd
@@ -67,6 +68,15 @@ def __init__(
67
68
inner_states : np.ndarray
68
69
Input states for inner sites
69
70
"""
71
+ if not (sites .is_ordered ):
72
+ warn (
73
+ 'Input `sites` are disordered! '
74
+ 'Although the code may work, it was written under the assumption '
75
+ 'that an ordered structure would be passed. '
76
+ 'See https://github.com/GEMDAT-repos/GEMDAT/issues/339 for more information.' ,
77
+ stacklevel = 2 ,
78
+ )
79
+
70
80
self .sites = sites
71
81
self .trajectory = trajectory
72
82
self .diff_trajectory = diff_trajectory
@@ -252,7 +262,10 @@ def occupancy(self) -> Structure:
252
262
counts = counts / len (states )
253
263
occupancies = dict (zip (unq , counts ))
254
264
255
- species = [{site .specie .name : occupancies .get (i , 0 )} for i , site in enumerate (sites )]
265
+ species = [
266
+ {site .species .elements [0 ].name : occupancies .get (i , 0 )}
267
+ for i , site in enumerate (sites )
268
+ ]
256
269
257
270
return Structure (
258
271
lattice = sites .lattice ,
@@ -262,27 +275,36 @@ def occupancy(self) -> Structure:
262
275
labels = sites .labels ,
263
276
)
264
277
265
- def atom_locations (self ):
278
+ def occupancy_by_site_type (self ) -> dict [str , float ]:
279
+ """Calculate average occupancy per a type of site.
280
+
281
+ Returns
282
+ -------
283
+ occupancy : dict[str, float]
284
+ Return dict with average occupancy per site type
285
+ """
286
+ compositions_by_label = defaultdict (list )
287
+
288
+ for site in self .occupancy ():
289
+ compositions_by_label [site .label ].append (site .species .num_atoms )
290
+
291
+ return {k : sum (v ) / len (v ) for k , v in compositions_by_label .items ()}
292
+
293
+ def atom_locations (self ) -> dict [str , float ]:
266
294
"""Calculate fraction of time atoms spent at a type of site.
267
295
268
296
Returns
269
297
-------
270
298
dict[str, float]
271
299
Return dict with the fraction of time atoms spent at a site
272
300
"""
273
- multiplier = len (self .sites ) / self .n_floating
274
-
301
+ n = self .n_floating
275
302
compositions_by_label = defaultdict (list )
276
303
277
304
for site in self .occupancy ():
278
305
compositions_by_label [site .label ].append (site .species .num_atoms )
279
306
280
- ret = {}
281
-
282
- for k , v in compositions_by_label .items ():
283
- ret [k ] = (sum (v ) / len (v )) * multiplier
284
-
285
- return ret
307
+ return {k : sum (v ) / n for k , v in compositions_by_label .items ()}
286
308
287
309
def split (self , n_parts : int = 10 ) -> list [Transitions ]:
288
310
"""Split data into equal parts in time for statistics.
0 commit comments