17
17
from ase .optimize import LBFGS
18
18
from ase .io .trajectory import PickleTrajectory
19
19
from ase .utils .eos import EquationOfState
20
- from ase .calculators .calculator import get_calculator
20
+ from ase .calculators .calculator import get_calculator , names as calcnames
21
21
import ase .db as db
22
22
23
23
24
- def main (runner = None ):
25
- if runner is None :
26
- runner = Runner ()
24
+ def main ():
25
+ runner = Runner ()
27
26
runner .parse ()
28
27
if runner .errors :
29
28
sys .exit (runner .errors )
30
29
31
30
32
31
class Runner :
33
- names = []
34
-
35
- parameter_namespace = {}
36
-
37
- calculator_name = None
38
-
39
32
def __init__ (self ):
40
33
self .db = None
41
34
self .opts = None
42
35
self .errors = 0
36
+ self .names = []
37
+ self .calculator_name = None
43
38
44
39
if world .rank == 0 :
45
40
self .logfile = sys .stdout
46
41
else :
47
42
self .logfile = devnull
48
43
49
44
def parse (self , args = None ):
50
- # create the top-level parser
45
+ parser = self .make_parser ()
46
+ self .add_options (parser )
47
+ self .opts , names = parser .parse_args (args )
48
+
49
+ if args is None and self .opts .interactive_python_session :
50
+ file = tempfile .NamedTemporaryFile ()
51
+ file .write ('import os\n ' )
52
+ file .write ('if "PYTHONSTARTUP" in os.environ:\n ' )
53
+ file .write (' execfile(os.environ["PYTHONSTARTUP"])\n ' )
54
+ file .write ('from ase.cli.run import Runner\n ' )
55
+ file .write ('atoms = Runner().parse(%r)\n ' %
56
+ ([self .calculator_name ] + sys .argv [1 :]))
57
+ file .flush ()
58
+ os .system ('python -i %s' % file .name )
59
+ return
60
+
61
+ if self .calculator_name is None :
62
+ if names :
63
+ self .calculator_name = names .pop (0 )
64
+ else :
65
+ parser .error ('Missing calculator name' )
66
+
67
+ atoms = self .run (names )
68
+ return atoms
69
+
70
+ def make_parser (self ):
51
71
parser = optparse .OptionParser (
52
- usage = '%prog calculator [options] [name, name, ...]' )
72
+ usage = 'ase-run calculator [options] [system, ...]' ,
73
+ description = "Run calculation with one of ASE's calculators: " +
74
+ ', ' .join (calcnames ) + '.' )
75
+ return parser
76
+
77
+ def add_options (self , parser ):
53
78
add = parser .add_option
54
- add ('-q' , '--quiet' , action = 'store_const' , const = 0 , default = 1 ,
55
- dest = 'verbosity' )
56
- add ('-V' , '--verbose' , action = 'store_const' , const = 2 , default = 1 ,
57
- dest = 'verbosity' )
58
79
add ('-t' , '--tag' ,
59
80
help = 'String tag added to filenames.' )
60
- add ('--plugin' )
61
81
add ('-p' , '--parameters' , default = '' ,
62
82
metavar = 'key=value,...' ,
63
83
help = 'Comma-separated key=value pairs of ' +
64
84
'calculator specific parameters.' )
65
85
add ('-d' , '--database' ,
66
- help = 'Use a filename with a ".sqlite " extension for a sqlite3 ' +
86
+ help = 'Use a filename with a ".db " extension for a sqlite3 ' +
67
87
'database or a ".json" extension for a simple json database. ' +
68
88
'Default is no database' )
69
89
add ('-S' , '--skip' , action = 'store_true' ,
@@ -81,42 +101,13 @@ def parse(self, args=None):
81
101
help = 'Relax unit-cell and internal coordinates.' )
82
102
add ('-E' , '--equation-of-state' , help = 'Equation of state ...' )
83
103
add ('--eos-type' , default = 'sjeos' , help = 'Selects the type of eos.' )
84
- add ('-i' , '--interactive-python-session' , action = 'store_true' ,
85
- ) # help=optparse.SUPPRESS)
104
+ add ('-i' , '--interactive-python-session' , action = 'store_true' )
86
105
add ('-c' , '--collection' )
87
106
add ('--modify' , metavar = '...' ,
88
107
help = 'Modify atoms with Python statement. ' +
89
108
'Example: --modify="atoms.positions[-1,2]+=0.1".' )
90
109
add ('--after' , help = 'Perform operation after calculation. ' +
91
110
'Example: --after="atoms.calc.write(...)"' )
92
-
93
- self .opts , names = parser .parse_args (args )
94
-
95
- if args is None and self .opts .interactive_python_session :
96
- file = tempfile .NamedTemporaryFile ()
97
- file .write ('import os\n ' )
98
- file .write ('if "PYTHONSTARTUP" in os.environ:\n ' )
99
- file .write (' execfile(os.environ["PYTHONSTARTUP"])\n ' )
100
- file .write ('from ase.cli.run import Runner\n ' )
101
- file .write ('atoms = Runner().parse(%r)\n ' %
102
- ([self .calculator_name ] + sys .argv [1 :]))
103
- file .flush ()
104
- os .system ('python -i %s' % file .name )
105
- return
106
-
107
- if self .calculator_name is None :
108
- if names :
109
- self .calculator_name = names .pop (0 )
110
- else :
111
- parser .error ('Missing calculator name' )
112
-
113
- if self .opts .plugin :
114
- runner = self .get_runner ()
115
- else :
116
- runner = self
117
-
118
- atoms = runner .run (names )
119
- return atoms
120
111
121
112
def log (self , * args , ** kwargs ):
122
113
print (file = self .logfile , * args , ** kwargs )
@@ -193,20 +184,6 @@ def calculate(self, atoms, name):
193
184
194
185
return data
195
186
196
- def get_plugin (self , name ):
197
- f = open (self .opts .plugin )
198
- script = f .read ()
199
- f .close ()
200
- namespace = {}
201
- exec script in namespace
202
- for cls in namespace :
203
- if issubclass (namespace [cls ], Runner ):
204
- runner = namespace [cls ]()
205
- runner .opts = self .opts
206
- runner .calculator_name = self .calculator_name
207
- runner .parameter_namespace = self .parameter_namespace
208
- return runner
209
-
210
187
def expand (self , names ):
211
188
if not self .names and self .opts .collection :
212
189
con = db .connect (self .opts .collection )
@@ -240,17 +217,12 @@ def build(self, name):
240
217
241
218
def set_calculator (self , atoms , name ):
242
219
cls = get_calculator (self .calculator_name )
243
- parameters = self .get_parameters ( )
220
+ parameters = str2dict ( self .opts . parameters )
244
221
if getattr (cls , 'nolabel' , False ):
245
222
atoms .calc = cls (** parameters )
246
223
else :
247
224
atoms .calc = cls (label = self .get_filename (name ), ** parameters )
248
225
249
- def get_parameters (self ):
250
- namespace = self .parameter_namespace
251
- parameters = str2dict (self .opts .parameters , namespace )
252
- return parameters
253
-
254
226
def calculate_once (self , atoms , name ):
255
227
opts = self .opts
256
228
0 commit comments