-
Notifications
You must be signed in to change notification settings - Fork 4
/
qorcaCoulson.py
154 lines (117 loc) · 5.09 KB
/
qorcaCoulson.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python3
import os
import argparse
def get_args():
"""Get the command line arguments passed to this script using argparse"""
parser = argparse.ArgumentParser()
parser.add_argument("filenames",
action='store',
help='.inp file(s) submit to the queue',
nargs='+')
parser.add_argument("-ca", "--copy_all",
action='store_true',
default=False,
help='Copy all of the files in the current directory '
'to the compute node.')
parser.add_argument("-cs", "--copy_scratch",
action='store_true',
default=False,
help="Copy all files from the scratch directory back "
"to this directory when the calculation is "
"finished.")
parser.add_argument('-v', '--version',
action='store',
type=str,
choices=['4_1', '4_2', '5_0'],
default='5_0',
help="Which version of ORCA should be used for the "
"calculation? Default: 5_0_4")
parser.add_argument("-np", "--num_processors",
type=int,
default=0,
help="Override the number of cores specified in the "
"input file. Useful for running calculations "
"with >4 GB memory per core.")
return parser.parse_args()
def num_cores(inp_filename, args):
"""Get the number of cores that this input file will need
Returns:
(int): Number of cores
Raises:
(ValueError, IndexError): If the input file is malformatted
"""
_num_cores = 1 # Default value
try:
keyword_line = next(line for line in open(inp_filename, 'r')
if line.startswith('!'))
# Number of cores can be defined with PALX in the keyword line
for item in keyword_line.split():
if item.lower().startswith("pal"):
_num_cores = int(item[3:])
except StopIteration:
exit(f'{inp_filename} was not a correctly formatted. Must have a '
f'line starting with a !')
# Could also have a %pal directive in the input file...
for line in open(inp_filename, 'r'):
if 'nprocs' in line:
# expecting a ... nprocs X ... format to the line
idx = next(i for i, item in enumerate(line.split())
if 'nprocs' == item.lower())
_num_cores = int(line.split()[idx+1])
# Command line argument overrides whatever is found
if args.num_processors != 0:
_num_cores = args.num_processors
return _num_cores
def print_sub_script(sh_filename, inp_filename, args):
"""
Print the submission script appropriate for an ORCA input file
-------------------------------------------------------------
Arguments:
sh_filename (str): Submission script filename
inp_filename (str): Input filename
args (Namespace): Command line arguments
"""
mpi_version='mpi/openmpi3-x86_64'
if args.version == '4_1':
orca_path = '/usr/local/orca_4_1_1_linux_x86-64/orca'
elif args.version == '4_2':
orca_path = '/usr/local/orca_4_2_1_linux_x86-64/orca'
elif args.version == '5_0':
orca_path = '/usr/local/orca_5_0_3/orca'
mpi_version='openmpi4.1.1'
else:
exit(f"{args.version} is not a recognised ORCA version")
with open(sh_filename, 'w') as sub_script:
print('#!/bin/bash',
'#$ -cwd',
f'#$ -pe smp {num_cores(inp_filename, args)}',
'#$ -l s_rt=360:00:00',
'#',
'export ORIG=$PWD',
'export SCR=$TMPDIR',
'export NBOEXE=/usr/local/nbo7/bin/nbo7.i4.exe',
f'module load {mpi_version}',
f'cp {"*" if args.copy_all else inp_filename} $SCR',
f'cd $SCR',
f'{orca_path} {inp_filename} > {inp_filename.replace(".inp", ".out")}',
'rm -f *.tmp',
sep='\n', file=sub_script)
if args.copy_scratch:
print('cp -R * $ORIG', file=sub_script)
else:
print('cp *.xyz *.hess *.out $ORIG', file=sub_script)
print('rm *.sh.*', file=sub_script)
return None
if __name__ == '__main__':
arguments = get_args()
for filename in arguments.filenames:
if not filename.endswith('.inp'):
exit(f'Filename must end with .inp. Found: {filename}')
script_filename = filename.replace('.inp', '.sh')
# The queuing system cannot work with scripts starting with a digit...
if script_filename[0].isdigit():
script_filename = f'_{script_filename}'
print_sub_script(script_filename,
inp_filename=filename,
args=arguments)
os.system(f'qsub {script_filename}')