Statistiques
| Révision :

chimie4psmn / database / import_gaussian_calc @ 46

Historique | Voir | Annoter | Télécharger (5,41 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 46 tjiang
    parser.add_argument("-j", help="Project name")
124 42 tjiang
    args = parser.parse_args()
125 42 tjiang
    if args.path is None:
126 42 tjiang
        path = '.'
127 42 tjiang
    else:
128 42 tjiang
        path = args.path
129 42 tjiang
    if args.p:
130 42 tjiang
        use_input = True
131 42 tjiang
    else:
132 42 tjiang
        use_input = False
133 42 tjiang
    if args.include_dir is None:
134 42 tjiang
        include_dir = []
135 42 tjiang
    else:
136 42 tjiang
        include_dir = args.include_dir
137 42 tjiang
    if args.exclude_dir is None:
138 42 tjiang
        exclude_dir = []
139 42 tjiang
    else:
140 42 tjiang
        exclude_dir = args.exclude_dir
141 42 tjiang
    if args.d is None:
142 42 tjiang
        db = 'gaussian.db'
143 42 tjiang
    else:
144 42 tjiang
        db = args.d
145 42 tjiang
    if args.n is None:
146 42 tjiang
        nproc = 8
147 42 tjiang
    else:
148 42 tjiang
        nproc = int(args.n)
149 46 tjiang
    if args.j is None:
150 46 tjiang
        project = 'gaussian'
151 46 tjiang
    else:
152 46 tjiang
        project = int(args.j)
153 42 tjiang
154 46 tjiang
    import_gaussian_calculations(path, db, use_input=use_input, include_dir=include_dir, exclude_dir=exclude_dir, project=project, nproc=nproc)