dockonsurf / modules / dos_input.py @ a02c931d
Historique | Voir | Annoter | Télécharger (11,12 ko)
1 |
"""Methods to deal with dockonsurf input files
|
---|---|
2 |
"""
|
3 |
|
4 |
|
5 |
def str2lst(cmplx_str): |
6 |
""" Converts a string composed of integers and groups of integers to a
|
7 |
list of lists of integers.
|
8 |
Group enclosers: '()' '[]' and '{}'
|
9 |
separators: ',' ';' and ' '
|
10 |
eg. '128,(135 138;141] 87 {45, 68}' -> [128, [135, 138, 141], 87, [45, 68]]
|
11 |
"""
|
12 |
|
13 |
assert type(cmplx_str) == str, 'parameter should be a string' |
14 |
cmplx_str = cmplx_str.replace(',', ' ').replace(';', ' ').replace( |
15 |
'[', '(').replace(']', ')').replace('{', '(').replace('}', ')') |
16 |
try:
|
17 |
list(map(int, cmplx_str.replace(')','').replace('(','').split())) |
18 |
except:
|
19 |
raise ValueError("Method parameter should be composed of integer numbers" |
20 |
"\nseparated by ',' ';' or ' ' "
|
21 |
"grouped in parentheses-like separators")
|
22 |
#TODO: enable superior level of nested lists (eg. '3 ((6 7) 8) 4')
|
23 |
|
24 |
init_list = cmplx_str.split() |
25 |
start_group = [] |
26 |
end_group = [] |
27 |
for i, element in enumerate(init_list): |
28 |
if '(' in element: |
29 |
start_group.append(i) |
30 |
init_list[i] = element.replace('(', '') |
31 |
if ')' in element: |
32 |
end_group.append(i) |
33 |
init_list[i] = element.replace(')', '') |
34 |
|
35 |
init_list = list(map(int, init_list)) |
36 |
|
37 |
new_list = [] |
38 |
for start_el, end_el in zip(start_group, end_group): |
39 |
new_list.append(init_list[start_el:end_el + 1])
|
40 |
|
41 |
for v in new_list: |
42 |
for el in v: |
43 |
init_list.remove(el) |
44 |
return init_list + new_list
|
45 |
|
46 |
|
47 |
def read_input(in_file): |
48 |
"""Reads the parameters in the input file (.INI file type) and
|
49 |
sets up the corresponding global variables accordingly. Sections should be
|
50 |
capitalized ('Global' is ok but 'global' or 'GLOBAL' are not)
|
51 |
@param in_file: str:
|
52 |
@return:
|
53 |
"""
|
54 |
from configparser import ConfigParser, NoSectionError, NoOptionError |
55 |
|
56 |
dos_inp = ConfigParser(inline_comment_prefixes='#',
|
57 |
empty_lines_in_values=False)
|
58 |
|
59 |
new_answers = {'n': False, 'none': False, 'nay': False, |
60 |
'y': True, 'sí': True, 'aye': True, 'sure': True} |
61 |
|
62 |
for answer, val in new_answers.items(): |
63 |
dos_inp.BOOLEAN_STATES[answer] = val |
64 |
|
65 |
dos_inp.read(in_file) |
66 |
|
67 |
turn_false_answers = [opt for opt in dos_inp.BOOLEAN_STATES |
68 |
if dos_inp.BOOLEAN_STATES[opt] == False] |
69 |
|
70 |
return_vars = {} |
71 |
|
72 |
##############
|
73 |
### Global ###
|
74 |
##############
|
75 |
### Mandatory options ###
|
76 |
if not dos_inp.has_section('Global'): raise NoSectionError('Global') |
77 |
|
78 |
# Checks whether the mandatory options 'run_type', 'code', etc. are
|
79 |
# present in the Global section and ensures they have an adequate
|
80 |
# value
|
81 |
mand_opts = ['run_type', 'code', 'batch_q_sys'] |
82 |
for opt in mand_opts: |
83 |
if not dos_inp.has_option('Global', opt): |
84 |
raise NoOptionError(opt, 'Global') |
85 |
|
86 |
# run_type
|
87 |
run_type_vals = ['isolated', 'screening', 'refinement', |
88 |
'adsorption', 'full'] |
89 |
isolated, screening, refinement = (False, False, False) |
90 |
if dos_inp.get('Global', 'run_type').lower() not in run_type_vals: |
91 |
raise ValueError('\'run_type\' does not have a adequate value.\n \ |
92 |
Adequate values: \'' + '\', \''.join(run_type_vals) + '\'.') |
93 |
else:
|
94 |
run_type = dos_inp.get('Global', 'run_type').lower() |
95 |
if 'isolated' in run_type: isolated = True |
96 |
if 'screening' in run_type: screening = True |
97 |
if 'refinement' in run_type: refinement = True |
98 |
if 'adsorption' in run_type: screening, refinement = (True, True) |
99 |
if 'full' in run_type: |
100 |
isolated, screening, refinement = (True, True, True) |
101 |
return_vars['isolated'] = isolated
|
102 |
return_vars['screening'] = screening
|
103 |
return_vars['refinement'] = refinement
|
104 |
# end run_type
|
105 |
|
106 |
# code
|
107 |
code_vals = ['cp2k']
|
108 |
if dos_inp.get('Global', 'code').lower() not in code_vals: |
109 |
raise ValueError('\'code\' does not have an adequate value.\n \ |
110 |
Adequate values: \'' + '\', \''.join(code_vals) + '\'.') |
111 |
else:
|
112 |
code = dos_inp.get('Global', 'code').lower() |
113 |
return_vars['code'] = code
|
114 |
# end code
|
115 |
|
116 |
# batch_q_sys
|
117 |
batch_q_sys_vals = ['sge']
|
118 |
if dos_inp.get('Global', 'batch_q_sys').lower() not in batch_q_sys_vals: |
119 |
raise ValueError('\'batch_q_sys_vals\' does not have an adequate \ |
120 |
value.\n Adequate values: \'' + '\', \''.join(batch_q_sys_vals) + '\'.') |
121 |
else:
|
122 |
batch_q_sys = dos_inp.get('Global', 'batch_q_sys').lower() |
123 |
return_vars['batch_q_sys'] = batch_q_sys
|
124 |
# end batch_q_sys
|
125 |
|
126 |
### run_type-dependent options ###
|
127 |
# isol_inp_file
|
128 |
if isolated:
|
129 |
if not 'isol_inp_file' in dos_inp.options('Global'): |
130 |
raise NoOptionError('isol_inp_file', 'Global') |
131 |
isol_inp_file = dos_inp.get('Global', 'isol_inp_file') |
132 |
return_vars['isol_inp_file'] = isol_inp_file
|
133 |
# end isol_inp_file
|
134 |
|
135 |
# screen_inp_file
|
136 |
if screening:
|
137 |
if not 'screen_inp_file' in dos_inp.options('Global'): |
138 |
raise NoOptionError('screen_inp_file', 'Global') |
139 |
screen_inp_file = dos_inp.get('Global', 'screen_inp_file') |
140 |
return_vars['screen_inp_file'] = screen_inp_file
|
141 |
# end screen_inp_file
|
142 |
|
143 |
# refine_inp_file
|
144 |
if refinement:
|
145 |
if not 'refine_inp_file' in dos_inp.options('Global'): |
146 |
raise NoOptionError('refine_inp_file', 'Global') |
147 |
refine_inp_file = dos_inp.get('Global', 'refine_inp_file') |
148 |
return_vars['refine_inp_file'] = refine_inp_file
|
149 |
# end refine_inp_file
|
150 |
|
151 |
### Facultative options (Default value present) ###
|
152 |
# relaunch_err
|
153 |
relaunch_err_vals = ['geo_not_conv', 'false'] |
154 |
relaunch_err = dos_inp.get('Global', 'relaunch_err', |
155 |
fallback="False")
|
156 |
if relaunch_err.lower() in turn_false_answers: |
157 |
relaunch_err = False
|
158 |
elif relaunch_err.lower() not in relaunch_err_vals: |
159 |
raise ValueError('\'relaunch_err\' does not have an adequate value.\n \ |
160 |
Adequate values: \'' + '\', \''.join(relaunch_err_vals) + '\'.') |
161 |
return_vars['relaunch_err'] = relaunch_err
|
162 |
# end relaunch_err
|
163 |
|
164 |
# max_qw
|
165 |
max_qw = dos_inp.getint('Global', 'max_qw', fallback=3) |
166 |
return_vars['max_qw'] = max_qw
|
167 |
# end max_qw
|
168 |
|
169 |
# special_atoms
|
170 |
special_atoms = dos_inp.get('Global', 'special_atoms', |
171 |
fallback="False")
|
172 |
if special_atoms.lower() in turn_false_answers: |
173 |
special_atoms = False
|
174 |
else:
|
175 |
lst_tple = [tuple(s.replace("(", "").split()) for s in |
176 |
special_atoms.split(")")[:-1]] |
177 |
if len(lst_tple) == 0 or not all(type(tup) is tuple and len(tup) == 2 |
178 |
for tup in lst_tple): |
179 |
raise ValueError('\'special_atoms\' does not have an adequate ' |
180 |
+ 'format.\n'
|
181 |
+ 'Adequate format: (Fe1 Fe) (O1 O)')
|
182 |
special_atoms = lst_tple |
183 |
return_vars['special_atoms'] = special_atoms
|
184 |
# end special_atoms
|
185 |
|
186 |
################
|
187 |
### Isolated ###
|
188 |
################
|
189 |
if isolated:
|
190 |
### Facultative options (Default value present) ###
|
191 |
# cluster_magns
|
192 |
cluster_magns_vals = ['energy', 'moi'] |
193 |
cluster_magns = dos_inp.get('Isolated', 'cluster_magns', |
194 |
fallback='energy').split(' ') |
195 |
cluster_magns = [m.lower() for m in cluster_magns] |
196 |
if not all(magn in cluster_magns_vals for magn in cluster_magns): |
197 |
raise ValueError('\'cluster_magns\' does not have an adequate ' |
198 |
+ 'value.\n'
|
199 |
'Adequate values: \'' + '\', \''.join(cluster_magns_vals) + '\'.') |
200 |
return_vars['cluster_magns'] = cluster_magns
|
201 |
# end cluster_magns
|
202 |
|
203 |
# num_conformers
|
204 |
num_conformers = dos_inp.getint('Isolated',
|
205 |
'num_conformers', fallback=1000) |
206 |
return_vars['num_conformers'] = num_conformers
|
207 |
# end num_conformers
|
208 |
|
209 |
# num_prom_cand
|
210 |
num_prom_cand = dos_inp.getint('Isolated', 'num_prom_cand', fallback=3) |
211 |
return_vars['num_prom_cand'] = num_prom_cand
|
212 |
# end num_prom_cand
|
213 |
|
214 |
# iso_rmsd_threshold
|
215 |
iso_rmsd_threshold = dos_inp.getfloat('Isolated',
|
216 |
'rmsd_threshold', fallback=0.05) |
217 |
return_vars['iso_rmsd_threshold'] = iso_rmsd_threshold
|
218 |
# end iso_rmsd_threshold
|
219 |
|
220 |
#################
|
221 |
### Screening ###
|
222 |
#################
|
223 |
if screening:
|
224 |
### Mandatory options ###
|
225 |
if not dos_inp.has_section('Screening'): |
226 |
raise NoSectionError('Screening') |
227 |
|
228 |
# Checks whether the mandatory options 'sites', 'molec_ads_ctrs',
|
229 |
# etc. are present in the Screening section
|
230 |
mand_opts = ['sites', 'molec_ads_ctrs'] |
231 |
for opt in mand_opts: |
232 |
if not dos_inp.has_option('Screening', opt): |
233 |
raise NoOptionError(opt, 'Screening') |
234 |
|
235 |
# sites
|
236 |
sites = str2lst(dos_inp.get('Screening', 'sites')) |
237 |
return_vars['sites'] = sites
|
238 |
# end sites
|
239 |
|
240 |
# molec_ads_ctrs
|
241 |
molec_ads_ctrs = str2lst(dos_inp.get('Screening', 'molec_ads_ctrs')) |
242 |
return_vars['molec_ads_ctrs'] = molec_ads_ctrs
|
243 |
# end molec_ads_ctrs
|
244 |
|
245 |
### Facultative options (Default value present) ###
|
246 |
|
247 |
# try_disso
|
248 |
try_disso = dos_inp.getboolean('Screening', 'try_disso', |
249 |
fallback=False)
|
250 |
return_vars['try_disso'] = try_disso
|
251 |
# end try_disso
|
252 |
|
253 |
# sample_points_per_angle
|
254 |
sample_points_per_angle = dos_inp.getint('Screening',
|
255 |
'sample_points_per_angle', fallback=3) |
256 |
return_vars['sample_points_per_angle'] = sample_points_per_angle
|
257 |
# end sample_points_per_angle
|
258 |
|
259 |
# collision_threshold
|
260 |
collision_threshold = dos_inp.getfloat('Screening',
|
261 |
'collision_threshold', fallback=1.2) |
262 |
return_vars['collision_threshold'] = collision_threshold
|
263 |
# end collision_threshold
|
264 |
|
265 |
# screen_rmsd_threshold
|
266 |
screen_rmsd_threshold = dos_inp.getfloat('Screening',
|
267 |
'rmsd_threshold', fallback=0.05) |
268 |
return_vars['screen_rmsd_threshold'] = screen_rmsd_threshold
|
269 |
# end screen_rmsd_threshold
|
270 |
|
271 |
# collision_bottom_z
|
272 |
collision_bottom_z = dos_inp.get('Screening',
|
273 |
'collision_bottom_z', fallback="False") |
274 |
if collision_bottom_z.lower() in turn_false_answers: |
275 |
collision_bottom_z = False
|
276 |
else:
|
277 |
collision_bottom_z = float(
|
278 |
collision_bottom_z) |
279 |
return_vars['collision_bottom_z'] = collision_bottom_z
|
280 |
# end collision_bottom_z
|
281 |
|
282 |
##################
|
283 |
### Refinement ###
|
284 |
##################
|
285 |
if refinement:
|
286 |
### Facultative options (Default value present) ###
|
287 |
# energy_cutoff
|
288 |
energy_cutoff = dos_inp.getfloat('Refinement',
|
289 |
'energy_cutoff', fallback=0.5) |
290 |
return_vars['energy_cutoff'] = energy_cutoff
|
291 |
# end energy_cutoff
|
292 |
return return_vars
|