chimie4psmn / database / import_gaussian_calc @ 48
Historique | Voir | Annoter | Télécharger (5,62 ko)
1 | 42 | tjiang | #!/usr/bin/env python |
---|---|---|---|
2 | 42 | tjiang | # $Id$ |
3 | 42 | tjiang | import os, sys, argparse |
4 | 42 | tjiang | from ase import Atoms |
5 | 46 | tjiang | from ase.io.gaussian import read_gaussian_out |
6 | 42 | tjiang | from ase.db import connect |
7 | 42 | tjiang | from ase.calculators.gaussian import Gaussian |
8 | 46 | tjiang | from ase.calculators.emt import EMT |
9 | 42 | tjiang | from ase.constraints import FixAtoms |
10 | 42 | tjiang | from numpy.linalg import norm |
11 | 42 | tjiang | from bz2 import BZ2File |
12 | 42 | tjiang | from gzip import GzipFile |
13 | 42 | tjiang | from time import time |
14 | 42 | tjiang | import multiprocessing |
15 | 42 | tjiang | import traceback |
16 | 42 | tjiang | |
17 | 42 | tjiang | def error(msg, *args): |
18 | 42 | tjiang | return multiprocessing.get_logger().error(msg, *args) |
19 | 42 | tjiang | |
20 | 42 | tjiang | class LogExceptions(object): |
21 | 42 | tjiang | def __init__(self, callable): |
22 | 42 | tjiang | self.__callable = callable |
23 | 42 | tjiang | |
24 | 42 | tjiang | def __call__(self, *args, **kwargs): |
25 | 42 | tjiang | try: |
26 | 42 | tjiang | result = self.__callable(*args, **kwargs) |
27 | 42 | tjiang | |
28 | 42 | tjiang | except Exception as e: |
29 | 42 | tjiang | # Here we add some debugging help. If multiprocessing's |
30 | 42 | tjiang | # debugging is on, it will arrange to log the traceback |
31 | 42 | tjiang | error(traceback.format_exc()) |
32 | 42 | tjiang | # Re-raise the original exception so the Pool worker can |
33 | 42 | tjiang | # clean up |
34 | 42 | tjiang | raise |
35 | 42 | tjiang | |
36 | 42 | tjiang | # It was fine, give a normal answer |
37 | 42 | tjiang | return result |
38 | 42 | tjiang | |
39 | 46 | tjiang | def import_gaussian_calculations(path,db,include_dir=[],exclude_dir=[],use_input=False,project='gaussian',user=os.environ['USER'], nproc=8): |
40 | 42 | tjiang | #log = open('scan.log','w') |
41 | 42 | tjiang | _all = os.walk(os.path.abspath(path)) |
42 | 42 | tjiang | calculator=None |
43 | 42 | tjiang | xc_dict = {'8': 'PBE', '91': 'PW91', 'CA': 'LDA'} |
44 | 42 | tjiang | read_all_dir = 0 |
45 | 42 | tjiang | filenames = [] |
46 | 42 | tjiang | if os.path.exists(db): |
47 | 42 | tjiang | con = connect(db) |
48 | 46 | tjiang | for row in con.select(project='test'): |
49 | 42 | tjiang | filenames.append(row.filename) |
50 | 42 | tjiang | else: |
51 | 42 | tjiang | con = connect(db) |
52 | 42 | tjiang | if len(include_dir) == 0: |
53 | 42 | tjiang | read_all_dir = 1 |
54 | 42 | tjiang | all_files = [] |
55 | 42 | tjiang | paths = [] |
56 | 42 | tjiang | t1 = time() |
57 | 42 | tjiang | for i,a in enumerate(_all): |
58 | 42 | tjiang | condition1 = (read_all_dir or a[0].split('/')[-1] in include_dir) |
59 | 42 | tjiang | #condition2 = not files[0].split('/')[-1] in exclude_dir |
60 | 42 | tjiang | condition3 = [ i for i, x in enumerate(exclude_dir) if x in a[0] ] |
61 | 46 | tjiang | _gass_out = [i for i in range(len(a[2])) if ('.log' in a[2][i])] |
62 | 42 | tjiang | if condition1 and not condition3: |
63 | 42 | tjiang | for f in _gass_out: |
64 | 42 | tjiang | path = a[0] |
65 | 46 | tjiang | filetoread = path +'/'+ a[2][f] |
66 | 42 | tjiang | if not filetoread in filenames: |
67 | 42 | tjiang | all_files.append(filetoread) |
68 | 42 | tjiang | paths.append(path) |
69 | 42 | tjiang | t2 = time() |
70 | 42 | tjiang | multiprocessing.log_to_stderr() |
71 | 42 | tjiang | print 'using '+str(nproc)+' threads' |
72 | 42 | tjiang | pool = multiprocessing.Pool(nproc) |
73 | 42 | tjiang | for filetoread,path in zip(all_files, paths): |
74 | 46 | tjiang | #def callback(result, func=LogExceptions(mp_worker)): |
75 | 46 | tjiang | # results[func] = result |
76 | 46 | tjiang | result = pool.apply_async(LogExceptions(mp_worker), args=(con,files,use_input,filenames,xc_dict), callback=log_result) |
77 | 42 | tjiang | pool.close() |
78 | 42 | tjiang | pool.join() |
79 | 42 | tjiang | t3 = time() |
80 | 46 | tjiang | con = connect(db) |
81 | 42 | tjiang | print 'total time used: ', t3-t2, ' seconds' |
82 | 42 | tjiang | |
83 | 42 | tjiang | def log_result(log): |
84 | 42 | tjiang | logfile = open('scan.log','a') |
85 | 42 | tjiang | print >> logfile, log |
86 | 46 | tjiang | return log |
87 | 42 | tjiang | |
88 | 46 | tjiang | def mp_worker(con, filetoread, path, use_input,filenames, user, project): |
89 | 42 | tjiang | try: |
90 | 42 | tjiang | t1 = time() |
91 | 46 | tjiang | Atoms, data = read_gaussian_out(filetoread,quantity='all') |
92 | 42 | tjiang | t2 = time() |
93 | 42 | tjiang | print 'timing: ', t2-t1 |
94 | 42 | tjiang | |
95 | 46 | tjiang | _log = 'archived_a: '+filetoread |
96 | 46 | tjiang | id = con.reserve(filename=filetoread) |
97 | 46 | tjiang | con.write(Atoms,functional = data['Method'],charge=data['Charge'],basis_set=data['Basis_set'],path=path,filename=filetoread, version=data['Version'],project='test') |
98 | 46 | tjiang | del con[id] |
99 | 46 | tjiang | record = con.select(filename=filetoread) |
100 | 46 | tjiang | #================================== |
101 | 46 | tjiang | #This part will only exist temporarily, it is for importing other people's calculation |
102 | 46 | tjiang | #For update the user and calculator keys, tjiang's hacked copy of ase is needed, |
103 | 46 | tjiang | #as these two are reserved keys that are not allowed to be updated manually |
104 | 46 | tjiang | id = next(record)['id'] |
105 | 46 | tjiang | con.update(id,user='edumont') |
106 | 46 | tjiang | #================================== |
107 | 46 | tjiang | con.update(id,calculator='gaussian') |
108 | 46 | tjiang | print _log |
109 | 42 | tjiang | except (IndexError, ValueError): |
110 | 42 | tjiang | _log = 'failed: '+filetoread |
111 | 46 | tjiang | print _log |
112 | 46 | tjiang | ##_log.flush() |
113 | 42 | tjiang | return |
114 | 42 | tjiang | |
115 | 42 | tjiang | if __name__ == '__main__': |
116 | 42 | tjiang | parser = argparse.ArgumentParser() |
117 | 42 | tjiang | parser.add_argument("path", help="The path under which the calculations will be scanned") |
118 | 42 | tjiang | parser.add_argument("-p", help="Use input in the same directory to determine the constraint", action="store_true") |
119 | 42 | tjiang | parser.add_argument("-i", "--include_dir",help="Directory to be included in the scanning") |
120 | 42 | tjiang | parser.add_argument("-e", "--exclude_dir",help="Directory to be excluded in the scanning") |
121 | 42 | tjiang | parser.add_argument("-d", help="Name of the database file to store the scanned calculations") |
122 | 42 | tjiang | parser.add_argument("-n", help="Number of processers") |
123 | 47 | tjiang | parser.add_argument("-u", help="The user who did the calculations") |
124 | 46 | tjiang | parser.add_argument("-j", help="Project name") |
125 | 42 | tjiang | args = parser.parse_args() |
126 | 48 | tjiang | nproc = multiprocessing.cpu_count() |
127 | 42 | tjiang | if args.path is None: |
128 | 42 | tjiang | path = '.' |
129 | 42 | tjiang | else: |
130 | 42 | tjiang | path = args.path |
131 | 42 | tjiang | if args.p: |
132 | 42 | tjiang | use_input = True |
133 | 42 | tjiang | else: |
134 | 42 | tjiang | use_input = False |
135 | 42 | tjiang | if args.include_dir is None: |
136 | 42 | tjiang | include_dir = [] |
137 | 42 | tjiang | else: |
138 | 42 | tjiang | include_dir = args.include_dir |
139 | 42 | tjiang | if args.exclude_dir is None: |
140 | 42 | tjiang | exclude_dir = [] |
141 | 42 | tjiang | else: |
142 | 42 | tjiang | exclude_dir = args.exclude_dir |
143 | 42 | tjiang | if args.d is None: |
144 | 42 | tjiang | db = 'gaussian.db' |
145 | 42 | tjiang | else: |
146 | 42 | tjiang | db = args.d |
147 | 42 | tjiang | if args.n is None: |
148 | 48 | tjiang | nproc = nproc / 2 |
149 | 42 | tjiang | else: |
150 | 42 | tjiang | nproc = int(args.n) |
151 | 47 | tjiang | if args.u is None: |
152 | 47 | tjiang | user = os.environ['USER'] |
153 | 47 | tjiang | else: |
154 | 47 | tjiang | user = args.u |
155 | 46 | tjiang | if args.j is None: |
156 | 46 | tjiang | project = 'gaussian' |
157 | 46 | tjiang | else: |
158 | 46 | tjiang | project = int(args.j) |
159 | 42 | tjiang | |
160 | 47 | tjiang | import_gaussian_calculations(path, db, use_input=use_input, include_dir=include_dir, exclude_dir=exclude_dir, project=project, nproc=nproc,user=user) |