Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import os
2import warnings
3from ase.io import iread
4from ase.geometry.dimensionality import analyze_dimensionality
7class CLICommand:
8 """Analyze the dimensionality of the bonded clusters in a structure, using
9 the scoring parameter described in:
11 "Definition of a scoring parameter to identify low-dimensional materials
12 components", P.M. Larsen, M. Pandey, M. Strange, and K. W. Jacobsen
13 Phys. Rev. Materials 3 034003, 2019,
14 https://doi.org/10.1103/PhysRevMaterials.3.034003
15 https://arxiv.org/abs/1808.02114
17 A score in the range [0-1] is assigned to each possible dimensionality
18 classification. The scores sum to 1. A bonded cluster can be a molecular
19 (0D), chain (1D), layer (2D), or bulk (3D) cluster. Mixed dimensionalities,
20 such as 0D+3D are possible. Input files may use any format supported by
21 ASE.
23 Example usage:
25 * ase dimensionality --display-all structure.cif
26 * ase dimensionality structure1.cif structure2.cif
28 For each structure the following data is printed:
30 * type - the dimensionalities present
31 * score - the score of the classification
32 * a - the start of the k-interval (see paper)
33 * b - the end of the k-interval (see paper)
34 * component counts - the number of clusters with each dimensionality type
36 If the `--display-all` option is used, all dimensionality classifications
37 are displayed.
38 """
40 @staticmethod
41 def add_arguments(parser):
42 add = parser.add_argument
43 add('filenames', nargs='+', help='input file(s) to analyze')
44 add('--display-all', dest='full', action='store_true',
45 help='display all dimensionality classifications')
46 add('--no-merge', dest='no_merge', action='store_true',
47 help='do not merge k-intervals with same dimensionality')
49 @staticmethod
50 def run(args, parser):
52 files = [os.path.split(path)[1] for path in args.filenames]
53 lmax = max([len(f) for f in files]) + 2
55 print('file'.ljust(lmax) +
56 'type score a b component counts')
57 print('=' * lmax + '===============================================')
59 merge = not args.no_merge
61 # reading CIF files can produce a ton of distracting warnings
62 with warnings.catch_warnings():
63 warnings.filterwarnings('ignore')
64 for path, f in zip(args.filenames, files):
65 for atoms in iread(path):
66 result = analyze_dimensionality(atoms, merge=merge)
67 if not args.full:
68 result = result[:1]
70 for i, entry in enumerate(result):
71 dimtype = entry.dimtype.rjust(4)
72 score = '{:.3f}'.format(entry.score).ljust(5)
73 a = '{:.3f}'.format(entry.a).ljust(5)
74 b = '{:.3f}'.format(entry.b).ljust(5)
75 if i == 0:
76 name = f.ljust(lmax)
77 else:
78 name = ' ' * lmax
80 line = ('{}{}' + ' {}' * 4).format(name, dimtype,
81 score, a, b,
82 entry.h)
83 print(line)
85 if args.full:
86 print()