Coverage for /builds/ase/ase/ase/cli/dimensionality.py: 100.00%
37 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
1# fmt: off
3# Note:
4# Try to avoid module level import statements here to reduce
5# import time during CLI execution
8class CLICommand:
9 """Analyze the dimensionality of the bonded clusters in a structure, using
10 the scoring parameter described in:
12 "Definition of a scoring parameter to identify low-dimensional materials
13 components", P.M. Larsen, M. Pandey, M. Strange, and K. W. Jacobsen
14 Phys. Rev. Materials 3 034003, 2019,
15 https://doi.org/10.1103/PhysRevMaterials.3.034003
16 https://arxiv.org/abs/1808.02114
18 A score in the range [0-1] is assigned to each possible dimensionality
19 classification. The scores sum to 1. A bonded cluster can be a molecular
20 (0D), chain (1D), layer (2D), or bulk (3D) cluster. Mixed dimensionalities,
21 such as 0D+3D are possible. Input files may use any format supported by
22 ASE.
24 Example usage:
26 * ase dimensionality --display-all structure.cif
27 * ase dimensionality structure1.cif structure2.cif
29 For each structure the following data is printed:
31 * type - the dimensionalities present
32 * score - the score of the classification
33 * a - the start of the k-interval (see paper)
34 * b - the end of the k-interval (see paper)
35 * component counts - the number of clusters with each dimensionality type
37 If the `--display-all` option is used, all dimensionality classifications
38 are displayed.
39 """
41 @staticmethod
42 def add_arguments(parser):
43 add = parser.add_argument
44 add('filenames', nargs='+', help='input file(s) to analyze')
45 add('--display-all', dest='full', action='store_true',
46 help='display all dimensionality classifications')
47 add('--no-merge', dest='no_merge', action='store_true',
48 help='do not merge k-intervals with same dimensionality')
50 @staticmethod
51 def run(args, parser):
52 import os
53 import warnings
55 from ase.geometry.dimensionality import analyze_dimensionality
56 from ase.io import iread
58 files = [os.path.split(path)[1] for path in args.filenames]
59 lmax = max(len(f) for f in files) + 2
61 print('file'.ljust(lmax) +
62 'type score a b component counts')
63 print('=' * lmax + '===============================================')
65 merge = not args.no_merge
67 # reading CIF files can produce a ton of distracting warnings
68 with warnings.catch_warnings():
69 warnings.filterwarnings('ignore')
70 for path, f in zip(args.filenames, files):
71 for atoms in iread(path):
72 result = analyze_dimensionality(atoms, merge=merge)
73 if not args.full:
74 result = result[:1]
76 for i, entry in enumerate(result):
77 dimtype = entry.dimtype.rjust(4)
78 score = f'{entry.score:.3f}'.ljust(5)
79 a = f'{entry.a:.3f}'.ljust(5)
80 b = f'{entry.b:.3f}'.ljust(5)
81 if i == 0:
82 name = f.ljust(lmax)
83 else:
84 name = ' ' * lmax
86 line = ('{}{}' + ' {}' * 4).format(name, dimtype,
87 score, a, b,
88 entry.h)
89 print(line)
91 if args.full:
92 print()