Coverage for /builds/kinetik161/ase/ase/collections/collection.py: 97.78%
45 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-10 11:04 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-10 11:04 +0000
1import os.path as op
3from ase.db.row import AtomsRow
4from ase.io.jsonio import read_json
7class Collection:
8 """Collection of atomic configurations and associated data.
10 Example of use:
12 >>> from ase.collections import s22
13 >>> len(s22)
14 22
15 >>> s22.names[:3]
16 ['Ammonia_dimer', 'Water_dimer', 'Formic_acid_dimer']
17 >>> dimer = s22['Water_dimer']
18 >>> dimer.get_chemical_symbols()
19 ['O', 'H', 'H', 'O', 'H', 'H']
20 >>> s22.data['Ammonia_dimer']
21 {'cc_energy': -0.1375}
22 >>> sum(len(atoms) for atoms in s22)
23 414
24 """
26 def __init__(self, name):
27 """Create a collection lazily.
29 Will read data from json file when needed.
31 A collection can be iterated over to get the Atoms objects and indexed
32 with names to get individual members.
34 Attributes:
36 name: str
37 Name of collection.
38 data: dict
39 Data dictionary.
40 filename: str
41 Location of json file.
42 names: list
43 Names of configurations in the collection.
44 """
46 self.name = name
47 self._names = []
48 self._systems = {}
49 self._data = {}
50 self.filename = op.join(op.dirname(__file__), f'{name}.json')
52 def __getitem__(self, name):
53 self._read()
54 return self._systems[name].copy()
56 def has(self, name):
57 # Not __contains__() because __iter__ yields the systems.
58 self._read()
59 return name in self._systems
61 def __iter__(self):
62 for name in self.names:
63 yield self[name]
65 def __len__(self):
66 return len(self.names)
68 def __str__(self):
69 return '<{}-collection, {} systems: {}, {}, ...>'.format(
70 self.name, len(self), *self.names[:2])
72 def __repr__(self):
73 return f'Collection({self.name!r})'
75 @property
76 def names(self):
77 self._read()
78 return list(self._names)
80 @property
81 def data(self):
82 self._read()
83 return self._data
85 def _read(self):
86 if self._names:
87 return
88 bigdct = read_json(self.filename)
89 for id in bigdct['ids']:
90 dct = bigdct[id]
91 kvp = dct['key_value_pairs']
92 name = str(kvp['name'])
93 self._names.append(name)
94 self._systems[name] = AtomsRow(dct).toatoms()
95 del kvp['name']
96 self._data[name] = {str(k): v for k, v in kvp.items()}