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 os.path as op
3import sys
5from ase.io import read
6from ase.io.formats import filetype, UnknownFileTypeError
7from ase.db import connect
8from ase.db.core import parse_selection
9from ase.db.jsondb import JSONDatabase
10from ase.db.row import atoms2dict
13class CLICommand:
14 """Find files with atoms in them.
16 Search through files known to ASE applying a query to filter the results.
18 See https://wiki.fysik.dtu.dk/ase/ase/db/db.html#querying for more
19 informations on how to construct the query string.
20 """
22 @staticmethod
23 def add_arguments(parser):
24 parser.add_argument('folder', help='Folder to look in.')
25 parser.add_argument(
26 'query', nargs='?',
27 help='Examples: More than 2 hydrogens and no silver: "H>2,Ag=0". '
28 'More than 1000 atoms: "natoms>1000". '
29 'Slab geometry containing Cu and Ni: "pbc=TTF,Cu,Ni".')
30 parser.add_argument('-v', '--verbose', action='store_true',
31 help='More output.')
32 parser.add_argument('-l', '--long', action='store_true',
33 help='Show also periodic boundary conditions, '
34 'chemical formula and filetype.')
35 parser.add_argument('-i', '--include', help='Include only filenames '
36 'ending with given strings. Example: '
37 '"-i .xyz,.traj".')
38 parser.add_argument('-x', '--exclude', help='Exclude filenames '
39 'ending with given strings. Example: '
40 '"-x .cif".')
42 @staticmethod
43 def run(args):
44 main(args)
47def main(args):
48 query = parse_selection(args.query)
49 include = args.include.split(',') if args.include else []
50 exclude = args.exclude.split(',') if args.exclude else []
52 if args.long:
53 print('pbc {:10} {:15} path'.format('formula', 'filetype'))
55 for path in allpaths(args.folder, include, exclude):
56 format, row = check(path, query, args.verbose)
57 if format:
58 if args.long:
59 print('{} {:10} {:15} {}'
60 .format(''.join(str(p) for p in row.pbc.astype(int)),
61 row.formula,
62 format,
63 path))
64 else:
65 print(path)
68def allpaths(folder, include, exclude):
69 """Generate paths."""
70 exclude += ['.py', '.pyc']
71 for dirpath, dirnames, filenames in os.walk(folder):
72 for name in filenames:
73 if any(name.endswith(ext) for ext in exclude):
74 continue
75 if include:
76 for ext in include:
77 if name.endswith(ext):
78 break
79 else:
80 continue
81 path = op.join(dirpath, name)
82 yield path
84 # Skip .git, __pycache__ and friends:
85 dirnames[:] = (name for name in dirnames if name[0] not in '._')
88def check(path, query, verbose):
89 """Check a path.
91 Returns a (filetype, AtomsRow object) tuple.
92 """
94 try:
95 format = filetype(path, guess=False)
96 except (OSError, UnknownFileTypeError):
97 return '', None
99 if format in ['db', 'json']:
100 db = connect(path)
101 else:
102 try:
103 atoms = read(path, format=format)
104 except Exception as x:
105 if verbose:
106 print(path + ':', x, file=sys.stderr)
107 return '', None
108 db = FakeDB(atoms)
110 try:
111 for row in db._select(*query):
112 return format, row
113 except Exception as x:
114 if verbose:
115 print(path + ':', x, file=sys.stderr)
117 return '', None
120class FakeDB(JSONDatabase):
121 def __init__(self, atoms):
122 self.bigdct = {1: atoms2dict(atoms)}
124 def _read_json(self):
125 return self.bigdct, [1], 2