Statistiques
| Branche: | Tag: | Révision :

dockonsurf / modules / dos_input.py @ 7d37379d

Historique | Voir | Annoter | Télécharger (41,33 ko)

1 b77be9ad Carles
"""Functions to deal with DockOnSurf input files.
2 b77be9ad Carles

3 b77be9ad Carles
Functions
4 0e83e6a6 Carles
try_command:Tries to run a command and logs its exceptions (expected and not).
5 0e83e6a6 Carles
str2lst: Converts a string of integers, and groups of them, to a list of lists.
6 0e83e6a6 Carles
check_expect_val: Checks whether the value of an option has an adequate value.
7 0e83e6a6 Carles
read_input: Sets up the calculation by reading the parameters from input file.
8 0e83e6a6 Carles
get_run_type: Gets 'run_type' value and checks that its value is acceptable.
9 0e83e6a6 Carles
get_code: Gets 'code' value and checks that its value is acceptable.
10 0e83e6a6 Carles
get_batch_q_sys: Gets 'batch_q_sys' value and checks that its value is
11 8887f41d Carles
acceptable.
12 0e83e6a6 Carles
get_relaunch_err: Gets 'relaunch_err' value and checks that its value is
13 8887f41d Carles
acceptable.
14 09c3325a Carles Marti
get_max_jobs: Gets 'max_jobs' value and checks that its value is acceptable.
15 0e83e6a6 Carles
get_special_atoms: Gets 'special_atoms' value and checks that its value is
16 8887f41d Carles
acceptable.
17 0e83e6a6 Carles
get_isol_inp_file: Gets 'isol_inp_file' value and checks that its value is
18 8887f41d Carles
acceptable.
19 0e83e6a6 Carles
get_cluster_magns: Gets 'cluster_magns' value and checks that its value is
20 8887f41d Carles
acceptable.
21 0e83e6a6 Carles
get_num_conformers: Gets 'num_conformers' value and checks that its value is
22 8887f41d Carles
acceptable.
23 0e83e6a6 Carles
get_num_prom_cand: Gets 'num_prom_cand' value and checks that its value is
24 8887f41d Carles
acceptable.
25 a5c74494 Carles
get_iso_rmsd: Gets 'iso_rmsd' value and checks that its value is acceptable.
26 4670488d Carles Marti
get_pre_opt: Gets 'pre_opt' value and checks that its value is acceptable.
27 0e83e6a6 Carles
get_screen_inp_file: Gets 'screen_inp_file' value and checks that its value is
28 8887f41d Carles
acceptable.
29 0e83e6a6 Carles
get_sites: Gets 'sites' value and checks that its value is acceptable.
30 7dd94df7 Carles Marti
get_molec_ctrs: Gets 'molec_ctrs' value and checks that its value is
31 8887f41d Carles
acceptable.
32 0e83e6a6 Carles
get_try_disso: Gets 'try_disso' value and checks that its value is acceptable.
33 0e83e6a6 Carles
get_pts_per_angle: Gets 'pts_per_angle' value and checks that its value is
34 8887f41d Carles
acceptable.
35 0e83e6a6 Carles
get_coll_thrsld: Gets 'coll_thrsld' value and checks that its value is
36 8887f41d Carles
acceptable.
37 0e83e6a6 Carles
get_screen_rmsd: Gets 'screen_rmsd' value and checks that its value is
38 8887f41d Carles
acceptable.
39 0e83e6a6 Carles
get_coll_bottom_z: Gets 'coll_bottom_z' value and checks that its value is
40 8887f41d Carles
acceptable.
41 0e83e6a6 Carles
get_refine_inp_file: Gets 'refine_inp_file' value and checks that its value is
42 8887f41d Carles
acceptable.
43 0e83e6a6 Carles
get_energy_cutoff: Gets 'energy_cutoff' value and checks that its value is
44 8887f41d Carles
acceptable.
45 17e72a49 Carles
"""
46 8887f41d Carles
import os.path
47 b5b2af64 Carles
import logging
48 8887f41d Carles
from configparser import ConfigParser, NoSectionError, NoOptionError, \
49 8887f41d Carles
    MissingSectionHeaderError, DuplicateOptionError
50 5fb01677 Carles Marti
import numpy as np
51 af3e2441 Carles Marti
from modules.utilities import try_command
52 8887f41d Carles
53 8887f41d Carles
logger = logging.getLogger('DockOnSurf')
54 8887f41d Carles
55 8887f41d Carles
dos_inp = ConfigParser(inline_comment_prefixes='#',
56 8887f41d Carles
                       empty_lines_in_values=False)
57 8887f41d Carles
58 8887f41d Carles
new_answers = {'n': False, 'none': False, 'nay': False,
59 8887f41d Carles
               'y': True, '': True, 'aye': True, 'sure': True}
60 8887f41d Carles
for answer, val in new_answers.items():
61 9cd032cf Carles Marti
    dos_inp.BOOLEAN_STATES[answer] = val  # TODO Check value 0
62 8887f41d Carles
turn_false_answers = [answer for answer in dos_inp.BOOLEAN_STATES
63 8887f41d Carles
                      if dos_inp.BOOLEAN_STATES[answer] is False]
64 9cd032cf Carles Marti
turn_true_answers = [answer for answer in dos_inp.BOOLEAN_STATES
65 9cd032cf Carles Marti
                     if dos_inp.BOOLEAN_STATES[answer]]
66 8887f41d Carles
67 8887f41d Carles
no_sect_err = "Section '%s' not found on input file"
68 8887f41d Carles
no_opt_err = "Option '%s' not found on section '%s'"
69 8887f41d Carles
num_error = "'%s' value must be a %s"
70 8887f41d Carles
71 4533134f Carles Marti
72 14e0b660 Carles Martí
# Auxilary functions
73 14e0b660 Carles Martí
74 4533134f Carles Marti
def str2lst(cmplx_str, func=int):  # TODO: enable deeper level of nested lists
75 a7128ce1 Carles Marti
    # TODO Treat all-enclosing parenthesis as a list instead of list of lists.
76 b77be9ad Carles
    """Converts a string of integers, and groups of them, to a list.
77 b77be9ad Carles

78 b77be9ad Carles
    Keyword arguments:
79 4533134f Carles Marti
    @param cmplx_str: str, string of integers (or floats) and groups of them
80 4533134f Carles Marti
    enclosed by parentheses-like characters.
81 b77be9ad Carles
    - Group enclosers: '()' '[]' and '{}'.
82 4533134f Carles Marti
    - Separators: ',' ';' and ' '.
83 b77be9ad Carles
    - Nested groups are not allowed: '3 ((6 7) 8) 4'.
84 4533134f Carles Marti
    @param func: either to use int or float
85 b77be9ad Carles

86 4533134f Carles Marti
    @return list, list of integers (or floats), or list of integers (or floats)
87 4533134f Carles Marti
    in the case they were grouped. First, the singlets are placed, and then the
88 4533134f Carles Marti
    groups in input order.
89 b77be9ad Carles

90 b77be9ad Carles
    eg. '128,(135 138;141] 87 {45, 68}' -> [128, 87, [135, 138, 141], [45, 68]]
91 17e72a49 Carles
    """
92 b77be9ad Carles
93 8887f41d Carles
    # Checks
94 5261a07f Carles Marti
    error_msg = "Function argument should be a str, sequence of " \
95 8887f41d Carles
                "numbers separated by ',' ';' or ' '." \
96 79e3db42 Carles
                "\nThey can be grouped in parentheses-like enclosers: '()', " \
97 79e3db42 Carles
                "'[]' or {}. Nested groups are not allowed. \n" \
98 79e3db42 Carles
                "eg. 128,(135 138;141) 87 {45, 68}"
99 8887f41d Carles
    cmplx_str = try_command(cmplx_str.replace, [(AttributeError, error_msg)],
100 8887f41d Carles
                            ',', ' ')
101 8887f41d Carles
102 8887f41d Carles
    cmplx_str = cmplx_str.replace(';', ' ').replace('[', '(').replace(
103 8887f41d Carles
        ']', ')').replace('{', '(').replace('}', ')')
104 8887f41d Carles
105 4533134f Carles Marti
    try_command(list, [(ValueError, error_msg)], map(func, cmplx_str.replace(
106 8887f41d Carles
        ')', '').replace('(', '').split()))
107 8887f41d Carles
108 b5b2af64 Carles
    deepness = 0
109 b5b2af64 Carles
    for el in cmplx_str.split():
110 b5b2af64 Carles
        if '(' in el:
111 b5b2af64 Carles
            deepness += 1
112 b5b2af64 Carles
        if ')' in el:
113 b5b2af64 Carles
            deepness += -1
114 b5b2af64 Carles
        if deepness > 1 or deepness < 0:
115 9f7bb440 Carles
            logger.error(error_msg)
116 b5b2af64 Carles
            raise ValueError(error_msg)
117 17e72a49 Carles
118 772b40e5 Carles
    init_list = cmplx_str.split()
119 772b40e5 Carles
    start_group = []
120 772b40e5 Carles
    end_group = []
121 772b40e5 Carles
    for i, element in enumerate(init_list):
122 73402e22 Carles
        if '(' in element:
123 772b40e5 Carles
            start_group.append(i)
124 17e72a49 Carles
            init_list[i] = element.replace('(', '')
125 73402e22 Carles
        if ')' in element:
126 772b40e5 Carles
            end_group.append(i)
127 17e72a49 Carles
            init_list[i] = element.replace(')', '')
128 772b40e5 Carles
129 4533134f Carles Marti
    init_list = list(map(func, init_list))
130 772b40e5 Carles
131 17e72a49 Carles
    new_list = []
132 772b40e5 Carles
    for start_el, end_el in zip(start_group, end_group):
133 17e72a49 Carles
        new_list.append(init_list[start_el:end_el + 1])
134 772b40e5 Carles
135 772b40e5 Carles
    for v in new_list:
136 772b40e5 Carles
        for el in v:
137 772b40e5 Carles
            init_list.remove(el)
138 772b40e5 Carles
    return init_list + new_list
139 772b40e5 Carles
140 17e72a49 Carles
141 5f9f1400 Carles Marti
def check_expect_val(value, expect_vals, err_msg=None):
142 b77be9ad Carles
    """Checks whether an option lies within its expected values.
143 b77be9ad Carles

144 b77be9ad Carles
    Keyword arguments:
145 b77be9ad Carles
    @param value: The variable to check if its value lies within the expected
146 b77be9ad Carles
    ones
147 b77be9ad Carles
    @param expect_vals: list, list of values allowed for the present option.
148 5f9f1400 Carles Marti
    @param err_msg: The error message to be prompted in both log and screen.
149 b77be9ad Carles
    @raise ValueError: if the value is not among the expected ones.
150 b77be9ad Carles
    @return True if the value is among the expected ones.
151 b77be9ad Carles
    """
152 5f9f1400 Carles Marti
    if err_msg is None:
153 5f9f1400 Carles Marti
        err_msg = f"'{value}' is not an adequate value.\n" \
154 5f9f1400 Carles Marti
                  f"Adequate values: {expect_vals}"
155 821dca42 Carles Marti
    if not any([exp_val == value for exp_val in expect_vals]):
156 5f9f1400 Carles Marti
        logger.error(err_msg)
157 5f9f1400 Carles Marti
        raise ValueError(err_msg)
158 b77be9ad Carles
159 b77be9ad Carles
    return True
160 b77be9ad Carles
161 b77be9ad Carles
162 7d37379d Carles Martí
def check_inp_files(inp_files, code, potcar_dir=None):
163 03fab2dd Carles
    if code == 'cp2k':
164 03fab2dd Carles
        from pycp2k import CP2K
165 9d3b680c Carles Martí
        if not isinstance(inp_files, str):
166 9d3b680c Carles Martí
            err_msg = "When using CP2K, only one input file is allowed"
167 9d3b680c Carles Martí
            logger.error(err_msg)
168 9d3b680c Carles Martí
            ValueError(err_msg)
169 9d3b680c Carles Martí
        elif not os.path.isfile(inp_files):
170 9d3b680c Carles Martí
            err_msg = f"Input file {inp_files} was not found."
171 9d3b680c Carles Martí
            logger.error(err_msg)
172 9d3b680c Carles Martí
            raise FileNotFoundError(err_msg)
173 03fab2dd Carles
        cp2k = CP2K()
174 03fab2dd Carles
        try_command(cp2k.parse,
175 9d3b680c Carles Martí
                    [(UnboundLocalError, "Invalid CP2K input file")], inp_files)
176 9d3b680c Carles Martí
    elif code == "vasp":
177 f349bb54 Carles
        if not potcar_dir:
178 f349bb54 Carles
            mand_files = ["INCAR", "KPOINTS", "POTCAR"]
179 f349bb54 Carles
        else:
180 f349bb54 Carles
            mand_files = ["INCAR", "KPOINTS"]
181 f349bb54 Carles
            if any("POTCAR" in inp_file for inp_file in inp_files):
182 f349bb54 Carles
                logger.warning("A POTCAR file was specified as input file "
183 f349bb54 Carles
                               "while the automatic generation of POTCAR was "
184 f349bb54 Carles
                               "also enabled via the 'potcar_dir' keyword. The "
185 f349bb54 Carles
                               "POTCAR specified as input_file will be used "
186 f349bb54 Carles
                               "instead of the auto-generated one.")
187 9d3b680c Carles Martí
        # Check that it inp_files is a list of file paths
188 9d3b680c Carles Martí
        if not isinstance(inp_files, list) and all(isinstance(inp_file, str)
189 9d3b680c Carles Martí
                                                   for inp_file in inp_files):
190 9d3b680c Carles Martí
            err_msg = "'inp_files' should be a list of file names/paths"
191 9d3b680c Carles Martí
            logger.error(err_msg)
192 f349bb54 Carles
            raise ValueError(err_msg)
193 9d3b680c Carles Martí
        # Check that all mandatory files are defined once and just once.
194 9d3b680c Carles Martí
        elif [[mand_file in inp_file for inp_file in inp_files].count(True)
195 9d3b680c Carles Martí
              for mand_file in mand_files].count(1) != len(mand_files):
196 9d3b680c Carles Martí
            err_msg = f"Each of the mandatory files {mand_files} must be " \
197 9d3b680c Carles Martí
                      f"defined once and just once."
198 9d3b680c Carles Martí
            logger.error(err_msg)
199 9d3b680c Carles Martí
            raise FileNotFoundError(err_msg)
200 9d3b680c Carles Martí
        # Check that the defined files exist
201 9d3b680c Carles Martí
        elif any(not os.path.isfile(inp_file) for inp_file in inp_files):
202 9d3b680c Carles Martí
            err_msg = f"At least one of the mandatory files {mand_files} was " \
203 9d3b680c Carles Martí
                      "not found."
204 9d3b680c Carles Martí
            logger.error(err_msg)
205 9d3b680c Carles Martí
            raise FileNotFoundError(err_msg)
206 9d3b680c Carles Martí
        # Check that mandatory files are actual vasp files.
207 9d3b680c Carles Martí
        else:
208 9d3b680c Carles Martí
            from pymatgen.io.vasp.inputs import Incar, Kpoints, Potcar
209 9d3b680c Carles Martí
            for inp_file in inp_files:
210 9d3b680c Carles Martí
                file_name = inp_file.split("/")[-1]
211 9d3b680c Carles Martí
                if not any(mand_file in file_name for mand_file in mand_files):
212 9d3b680c Carles Martí
                    continue
213 9d3b680c Carles Martí
                file_type = ""
214 9d3b680c Carles Martí
                for mand_file in mand_files:
215 9d3b680c Carles Martí
                    if mand_file in inp_file:
216 9d3b680c Carles Martí
                        file_type = mand_file
217 9d3b680c Carles Martí
                err = False
218 9d3b680c Carles Martí
                err_msg = f"'{inp_file}' is not a valid {file_name} file."
219 9d3b680c Carles Martí
                try:
220 9d3b680c Carles Martí
                    eval(file_type.capitalize()).from_file(inp_file)
221 9d3b680c Carles Martí
                except ValueError:
222 9d3b680c Carles Martí
                    logger.error(err_msg)
223 9d3b680c Carles Martí
                    err = ValueError(err_msg)
224 9d3b680c Carles Martí
                except IndexError:
225 9d3b680c Carles Martí
                    logger.error(err_msg)
226 9d3b680c Carles Martí
                    err = IndexError(err_msg)
227 9d3b680c Carles Martí
                else:
228 9d3b680c Carles Martí
                    if file_name == "INCAR":
229 9d3b680c Carles Martí
                        Incar.from_file("INCAR").check_params()
230 9d3b680c Carles Martí
                finally:
231 9d3b680c Carles Martí
                    if isinstance(err, BaseException):
232 9d3b680c Carles Martí
                        raise err
233 03fab2dd Carles
234 03fab2dd Carles
235 a7128ce1 Carles Marti
# Global
236 a7128ce1 Carles Marti
237 8887f41d Carles
def get_run_type():
238 b1d27be5 Carles
    isolated, screening, refinement = (False, False, False)
239 5cc4994b Carles
    run_type_vals = ['isolated', 'screening', 'refinement', 'adsorption',
240 5cc4994b Carles
                     'full']
241 081548a0 Carles Marti
    run_types = dos_inp.get('Global', 'run_type').split()
242 081548a0 Carles Marti
    for run_type in run_types:
243 081548a0 Carles Marti
        check_expect_val(run_type.lower(), run_type_vals)
244 081548a0 Carles Marti
        if 'isol' in run_type.lower():
245 081548a0 Carles Marti
            isolated = True
246 081548a0 Carles Marti
        if 'screen' in run_type.lower():
247 081548a0 Carles Marti
            screening = True
248 081548a0 Carles Marti
        if 'refine' in run_type.lower():
249 081548a0 Carles Marti
            refinement = True
250 081548a0 Carles Marti
        if 'adsor' in run_type.lower():
251 081548a0 Carles Marti
            screening, refinement = (True, True)
252 081548a0 Carles Marti
        if 'full' in run_type.lower():
253 081548a0 Carles Marti
            isolated, screening, refinement = (True, True, True)
254 5cc4994b Carles
255 8887f41d Carles
    return isolated, screening, refinement
256 17e72a49 Carles
257 8887f41d Carles
258 8887f41d Carles
def get_code():
259 9d3b680c Carles Martí
    code_vals = ['cp2k', 'vasp']
260 5cc4994b Carles
    check_expect_val(dos_inp.get('Global', 'code').lower(), code_vals)
261 5cc4994b Carles
    code = dos_inp.get('Global', 'code').lower()
262 8887f41d Carles
    return code
263 8887f41d Carles
264 17e72a49 Carles
265 8887f41d Carles
def get_batch_q_sys():
266 ec5bba46 Carles Marti
    batch_q_sys_vals = ['sge', 'lsf', 'irene', 'local'] + turn_false_answers
267 5cc4994b Carles
    check_expect_val(dos_inp.get('Global', 'batch_q_sys').lower(),
268 5cc4994b Carles
                     batch_q_sys_vals)
269 5cc4994b Carles
    batch_q_sys = dos_inp.get('Global', 'batch_q_sys').lower()
270 821dca42 Carles Marti
    if batch_q_sys.lower() in turn_false_answers:
271 821dca42 Carles Marti
        return False
272 821dca42 Carles Marti
    else:
273 821dca42 Carles Marti
        return batch_q_sys
274 17e72a49 Carles
275 8887f41d Carles
276 9d3b680c Carles Martí
def get_pbc_cell():
277 a5d76bfb Carles Martí
    from ase.atoms import Cell
278 9d3b680c Carles Martí
    err_msg = "'pbc_cell' must be either 3 vectors of size 3 or False."
279 9d3b680c Carles Martí
    pbc_cell_str = dos_inp.get('Global', 'pbc_cell', fallback="False")
280 9d3b680c Carles Martí
    if pbc_cell_str.lower() in turn_false_answers:
281 9d3b680c Carles Martí
        return False
282 9d3b680c Carles Martí
    else:
283 9d3b680c Carles Martí
        pbc_cell = np.array(try_command(str2lst, [(ValueError, err_msg)],
284 9d3b680c Carles Martí
                                        pbc_cell_str, float))
285 9d3b680c Carles Martí
        if pbc_cell.shape != (3, 3):
286 9d3b680c Carles Martí
            logger.error(err_msg)
287 9d3b680c Carles Martí
            raise ValueError(err_msg)
288 9d3b680c Carles Martí
        if np.linalg.det(pbc_cell) == 0.0:
289 9d3b680c Carles Martí
            err_msg = "The volume of the defined cell is 0"
290 9d3b680c Carles Martí
            logger.error(err_msg)
291 9d3b680c Carles Martí
            raise ValueError(err_msg)
292 a5d76bfb Carles Martí
        return Cell(pbc_cell)
293 9d3b680c Carles Martí
294 9d3b680c Carles Martí
295 99afde40 Carles
def get_subm_script():
296 14e0b660 Carles Martí
    subm_script = dos_inp.get('Global', 'subm_script')
297 14e0b660 Carles Martí
    if not os.path.isfile(subm_script):
298 695dcff8 Carles Marti
        logger.error(f'File {subm_script} not found.')
299 99afde40 Carles
        raise FileNotFoundError(f'File {subm_script} not found')
300 99afde40 Carles
    return subm_script
301 99afde40 Carles
302 99afde40 Carles
303 99afde40 Carles
def get_project_name():
304 bd573212 Carles
    project_name = dos_inp.get('Global', 'project_name', fallback='')
305 99afde40 Carles
    return project_name
306 99afde40 Carles
307 99afde40 Carles
308 8887f41d Carles
def get_relaunch_err():
309 09c3325a Carles Marti
    relaunch_err_vals = ['geo_not_conv']
310 b1d27be5 Carles
    relaunch_err = dos_inp.get('Global', 'relaunch_err',
311 17e72a49 Carles
                               fallback="False")
312 b1d27be5 Carles
    if relaunch_err.lower() in turn_false_answers:
313 8887f41d Carles
        return False
314 79e3db42 Carles
    else:
315 79e3db42 Carles
        check_expect_val(relaunch_err.lower(), relaunch_err_vals)
316 8887f41d Carles
    return relaunch_err
317 8887f41d Carles
318 8887f41d Carles
319 09c3325a Carles Marti
def get_max_jobs():
320 b6b1b03e Carles Marti
    import re
321 b6b1b03e Carles Marti
    err_msg = "'max_jobs' must be a list of, number plus 'p', 'q' or 'r', or " \
322 b6b1b03e Carles Marti
              "a combination of them without repeating letters.\n" \
323 b6b1b03e Carles Marti
              "eg: '2r 3p 4pr', '5q' or '3r 3p'"
324 b6b1b03e Carles Marti
    max_jobs_str = dos_inp.get('Global', 'max_jobs', fallback="inf").lower()
325 b6b1b03e Carles Marti
    str_vals = ["r", "p", "q", "rp", "rq", "pr", "qr"]
326 b6b1b03e Carles Marti
    max_jobs = {"r": np.inf, "p": np.inf, "rp": np.inf}
327 b6b1b03e Carles Marti
    if "inf" == max_jobs_str:
328 b6b1b03e Carles Marti
        return {"r": np.inf, "p": np.inf, "rp": np.inf}
329 b6b1b03e Carles Marti
    # Iterate over the number of requirements:
330 b6b1b03e Carles Marti
    for req in max_jobs_str.split():
331 b6b1b03e Carles Marti
        # Split numbers from letters into a list
332 b6b1b03e Carles Marti
        req_parts = re.findall(r'[a-z]+|\d+', req)
333 b6b1b03e Carles Marti
        if len(req_parts) != 2:
334 b6b1b03e Carles Marti
            logger.error(err_msg)
335 b6b1b03e Carles Marti
            raise ValueError(err_msg)
336 b6b1b03e Carles Marti
        if req_parts[0].isdecimal():
337 b6b1b03e Carles Marti
            req_parts[1] = req_parts[1].replace('q', 'p').replace('pr', 'rp')
338 b6b1b03e Carles Marti
            if req_parts[1] in str_vals and max_jobs[req_parts[1]] == np.inf:
339 b6b1b03e Carles Marti
                max_jobs[req_parts[1]] = int(req_parts[0])
340 b6b1b03e Carles Marti
        elif req_parts[1].isdecimal():
341 b6b1b03e Carles Marti
            req_parts[0] = req_parts[0].replace('q', 'p').replace('pr', 'rp')
342 b6b1b03e Carles Marti
            if req_parts[0] in str_vals and max_jobs[req_parts[0]] == np.inf:
343 b6b1b03e Carles Marti
                max_jobs[req_parts[0]] = int(req_parts[1])
344 b6b1b03e Carles Marti
        else:
345 b6b1b03e Carles Marti
            logger.error(err_msg)
346 b6b1b03e Carles Marti
            raise ValueError(err_msg)
347 09c3325a Carles Marti
348 09c3325a Carles Marti
    return max_jobs
349 09c3325a Carles Marti
350 09c3325a Carles Marti
351 8887f41d Carles
def get_special_atoms():
352 8887f41d Carles
    from ase.data import chemical_symbols
353 17e72a49 Carles
354 5cc4994b Carles
    spec_at_err = '\'special_atoms\' does not have an adequate format.\n' \
355 5cc4994b Carles
                  'Adequate format: (Fe1 Fe) (O1 O)'
356 5cc4994b Carles
    special_atoms = dos_inp.get('Global', 'special_atoms', fallback="False")
357 b1d27be5 Carles
    if special_atoms.lower() in turn_false_answers:
358 90819cc3 Carles Marti
        special_atoms = []
359 b1d27be5 Carles
    else:
360 8949edd0 Carles
        # Converts the string into a list of tuples
361 8949edd0 Carles
        lst_tple = [tuple(pair.replace("(", "").split()) for pair in
362 b1d27be5 Carles
                    special_atoms.split(")")[:-1]]
363 5cc4994b Carles
        if len(lst_tple) == 0:
364 9f7bb440 Carles
            logger.error(spec_at_err)
365 5cc4994b Carles
            raise ValueError(spec_at_err)
366 9f7bb440 Carles
        for i, tup in enumerate(lst_tple):
367 90819cc3 Carles Marti
            if not isinstance(tup, tuple) or len(tup) != 2:
368 9f7bb440 Carles
                logger.error(spec_at_err)
369 5cc4994b Carles
                raise ValueError(spec_at_err)
370 5cc4994b Carles
            if tup[1].capitalize() not in chemical_symbols:
371 5cc4994b Carles
                elem_err = "The second element of the couple should be an " \
372 9f7bb440 Carles
                           "actual element of the periodic table"
373 9f7bb440 Carles
                logger.error(elem_err)
374 5cc4994b Carles
                raise ValueError(elem_err)
375 9f7bb440 Carles
            if tup[0].capitalize() in chemical_symbols:
376 9f7bb440 Carles
                elem_err = "The first element of the couple is already an " \
377 9f7bb440 Carles
                           "actual element of the periodic table, "
378 9f7bb440 Carles
                logger.error(elem_err)
379 9f7bb440 Carles
                raise ValueError(elem_err)
380 9f7bb440 Carles
            for j, tup2 in enumerate(lst_tple):
381 9f7bb440 Carles
                if j <= i:
382 9f7bb440 Carles
                    continue
383 9f7bb440 Carles
                if tup2[0] == tup[0]:
384 9f7bb440 Carles
                    label_err = f'You have specified the label {tup[0]} to ' \
385 8887f41d Carles
                                f'more than one special atom'
386 9f7bb440 Carles
                    logger.error(label_err)
387 9f7bb440 Carles
                    raise ValueError(label_err)
388 b1d27be5 Carles
        special_atoms = lst_tple
389 8887f41d Carles
    return special_atoms
390 8887f41d Carles
391 8887f41d Carles
392 f349bb54 Carles
def get_potcar_dir():
393 f349bb54 Carles
    potcar_dir = dos_inp.get('Global', 'potcar_dir', fallback="False")
394 f349bb54 Carles
    if potcar_dir.lower() in turn_false_answers:
395 f349bb54 Carles
        return False
396 f349bb54 Carles
    elif not os.path.isdir(potcar_dir):
397 f349bb54 Carles
        err_msg = "'potcar_dir' must be either False or a directory."
398 f349bb54 Carles
        logger.error(err_msg)
399 f349bb54 Carles
        raise ValueError(err_msg)
400 f349bb54 Carles
    else:
401 f349bb54 Carles
        return potcar_dir
402 f349bb54 Carles
403 f349bb54 Carles
404 a7128ce1 Carles Marti
# Isolated
405 a7128ce1 Carles Marti
406 7d37379d Carles Martí
def get_isol_inp_file(code, potcar_dir=None):  # TODO allow spaces in path names
407 9d3b680c Carles Martí
    inp_file_lst = dos_inp.get('Isolated', 'isol_inp_file').split()
408 f349bb54 Carles
    check_inp_files(inp_file_lst[0] if len(inp_file_lst) == 1 else inp_file_lst,
409 f349bb54 Carles
                    code, potcar_dir)
410 9d3b680c Carles Martí
    return inp_file_lst[0] if len(inp_file_lst) == 1 else inp_file_lst
411 8887f41d Carles
412 8887f41d Carles
413 95dc2c8e Carles
def get_molec_file():
414 95dc2c8e Carles
    molec_file = dos_inp.get('Isolated', 'molec_file')
415 95dc2c8e Carles
    if not os.path.isfile(molec_file):
416 695dcff8 Carles Marti
        logger.error(f'File {molec_file} not found.')
417 95dc2c8e Carles
        raise FileNotFoundError(f'File {molec_file} not found')
418 95dc2c8e Carles
    return molec_file
419 95dc2c8e Carles
420 95dc2c8e Carles
421 8887f41d Carles
def get_num_conformers():
422 8887f41d Carles
    err_msg = num_error % ('num_conformers', 'positive integer')
423 8887f41d Carles
    num_conformers = try_command(dos_inp.getint, [(ValueError, err_msg)],
424 8887f41d Carles
                                 'Isolated', 'num_conformers', fallback=100)
425 8887f41d Carles
    if num_conformers < 1:
426 8887f41d Carles
        logger.error(err_msg)
427 8887f41d Carles
        raise ValueError(err_msg)
428 8887f41d Carles
    return num_conformers
429 8887f41d Carles
430 8887f41d Carles
431 4670488d Carles Marti
def get_pre_opt():
432 4670488d Carles Marti
    pre_opt_vals = ['uff', 'mmff'] + turn_false_answers
433 4670488d Carles Marti
    check_expect_val(dos_inp.get('Isolated', 'pre_opt').lower(), pre_opt_vals)
434 ad57fd42 Carles Marti
    pre_opt = dos_inp.get('Isolated', 'pre_opt').lower()
435 ad57fd42 Carles Marti
    if pre_opt in turn_false_answers:
436 4670488d Carles Marti
        return False
437 4670488d Carles Marti
    else:
438 4670488d Carles Marti
        return pre_opt
439 b1f6e69d Carles
440 70fa4e74 Carles Marti
441 a7128ce1 Carles Marti
# Screening
442 a7128ce1 Carles Marti
443 7d37379d Carles Martí
def get_screen_inp_file(code,
444 7d37379d Carles Martí
                        potcar_dir=None):  # TODO allow spaces in path names
445 9d3b680c Carles Martí
    inp_file_lst = dos_inp.get('Screening', 'screen_inp_file').split()
446 f349bb54 Carles
    check_inp_files(inp_file_lst[0] if len(inp_file_lst) == 1 else inp_file_lst,
447 f349bb54 Carles
                    code, potcar_dir)
448 9d3b680c Carles Martí
    return inp_file_lst[0] if len(inp_file_lst) == 1 else inp_file_lst
449 8887f41d Carles
450 8887f41d Carles
451 a765b11c Carles Marti
def get_surf_file():
452 a765b11c Carles Marti
    surf_file = dos_inp.get('Screening', 'surf_file')
453 a765b11c Carles Marti
    if not os.path.isfile(surf_file):
454 695dcff8 Carles Marti
        logger.error(f'File {surf_file} not found.')
455 a765b11c Carles Marti
        raise FileNotFoundError(f'File {surf_file} not found')
456 a765b11c Carles Marti
    return surf_file
457 a765b11c Carles Marti
458 a765b11c Carles Marti
459 8887f41d Carles
def get_sites():
460 8887f41d Carles
    err_msg = 'The value of sites should be a list of atom numbers ' \
461 8887f41d Carles
              '(ie. positive integers) or groups of atom numbers ' \
462 8887f41d Carles
              'grouped by parentheses-like enclosers. \n' \
463 8887f41d Carles
              'eg. 128,(135 138;141) 87 {45, 68}'
464 8887f41d Carles
    # Convert the string into a list of lists
465 8887f41d Carles
    sites = try_command(str2lst,
466 8887f41d Carles
                        [(ValueError, err_msg), (AttributeError, err_msg)],
467 8887f41d Carles
                        dos_inp.get('Screening', 'sites'))
468 8887f41d Carles
    # Check all elements of the list (of lists) are positive integers
469 8887f41d Carles
    for site in sites:
470 8887f41d Carles
        if type(site) is list:
471 8887f41d Carles
            for atom in site:
472 8887f41d Carles
                if atom < 0:
473 8887f41d Carles
                    logger.error(err_msg)
474 8887f41d Carles
                    raise ValueError(err_msg)
475 8887f41d Carles
        elif type(site) is int:
476 8887f41d Carles
            if site < 0:
477 8887f41d Carles
                logger.error(err_msg)
478 8887f41d Carles
                raise ValueError(err_msg)
479 8887f41d Carles
        else:
480 8887f41d Carles
            logger.error(err_msg)
481 8887f41d Carles
            raise ValueError(err_msg)
482 8887f41d Carles
483 8887f41d Carles
    return sites
484 8887f41d Carles
485 8887f41d Carles
486 7dd94df7 Carles Marti
def get_surf_ctrs2():
487 7dd94df7 Carles Marti
    err_msg = 'The value of surf_ctrs2 should be a list of atom numbers ' \
488 7dd94df7 Carles Marti
              '(ie. positive integers) or groups of atom numbers ' \
489 7dd94df7 Carles Marti
              'grouped by parentheses-like enclosers. \n' \
490 7dd94df7 Carles Marti
              'eg. 128,(135 138;141) 87 {45, 68}'
491 7dd94df7 Carles Marti
    # Convert the string into a list of lists
492 7dd94df7 Carles Marti
    surf_ctrs2 = try_command(str2lst,
493 7dd94df7 Carles Marti
                             [(ValueError, err_msg), (AttributeError, err_msg)],
494 7dd94df7 Carles Marti
                             dos_inp.get('Screening', 'surf_ctrs2'))
495 7dd94df7 Carles Marti
    # Check all elements of the list (of lists) are positive integers
496 7dd94df7 Carles Marti
    for ctr in surf_ctrs2:
497 7dd94df7 Carles Marti
        if type(ctr) is list:
498 7dd94df7 Carles Marti
            for atom in ctr:
499 7dd94df7 Carles Marti
                if atom < 0:
500 7dd94df7 Carles Marti
                    logger.error(err_msg)
501 7dd94df7 Carles Marti
                    raise ValueError(err_msg)
502 7dd94df7 Carles Marti
        elif type(ctr) is int:
503 7dd94df7 Carles Marti
            if ctr < 0:
504 7dd94df7 Carles Marti
                logger.error(err_msg)
505 7dd94df7 Carles Marti
                raise ValueError(err_msg)
506 7dd94df7 Carles Marti
        else:
507 7dd94df7 Carles Marti
            logger.error(err_msg)
508 7dd94df7 Carles Marti
            raise ValueError(err_msg)
509 7dd94df7 Carles Marti
510 7dd94df7 Carles Marti
    return surf_ctrs2
511 7dd94df7 Carles Marti
512 7dd94df7 Carles Marti
513 7dd94df7 Carles Marti
def get_molec_ctrs():
514 7dd94df7 Carles Marti
    err_msg = 'The value of molec_ctrs should be a list of atom' \
515 8887f41d Carles
              ' numbers (ie. positive integers) or groups of atom ' \
516 8887f41d Carles
              'numbers enclosed by parentheses-like characters. \n' \
517 8887f41d Carles
              'eg. 128,(135 138;141) 87 {45, 68}'
518 8887f41d Carles
    # Convert the string into a list of lists
519 7dd94df7 Carles Marti
    molec_ctrs = try_command(str2lst,
520 7dd94df7 Carles Marti
                             [(ValueError, err_msg),
521 7dd94df7 Carles Marti
                              (AttributeError, err_msg)],
522 7dd94df7 Carles Marti
                             dos_inp.get('Screening', 'molec_ctrs'))
523 7dd94df7 Carles Marti
    # Check all elements of the list (of lists) are positive integers
524 7dd94df7 Carles Marti
    for ctr in molec_ctrs:
525 7dd94df7 Carles Marti
        if isinstance(ctr, list):
526 7dd94df7 Carles Marti
            for atom in ctr:
527 7dd94df7 Carles Marti
                if atom < 0:
528 7dd94df7 Carles Marti
                    logger.error(err_msg)
529 7dd94df7 Carles Marti
                    raise ValueError(err_msg)
530 7dd94df7 Carles Marti
        elif isinstance(ctr, int):
531 7dd94df7 Carles Marti
            if ctr < 0:
532 7dd94df7 Carles Marti
                logger.error(err_msg)
533 7dd94df7 Carles Marti
                raise ValueError(err_msg)
534 7dd94df7 Carles Marti
        else:
535 7dd94df7 Carles Marti
            logger.error(err_msg)
536 7dd94df7 Carles Marti
            raise ValueError(err_msg)
537 7dd94df7 Carles Marti
538 7dd94df7 Carles Marti
    return molec_ctrs
539 7dd94df7 Carles Marti
540 7dd94df7 Carles Marti
541 7dd94df7 Carles Marti
def get_molec_ctrs2():
542 7dd94df7 Carles Marti
    err_msg = 'The value of molec_ctrs2 should be a list of atom ' \
543 7dd94df7 Carles Marti
              'numbers (ie. positive integers) or groups of atom ' \
544 7dd94df7 Carles Marti
              'numbers enclosed by parentheses-like characters. \n' \
545 7dd94df7 Carles Marti
              'eg. 128,(135 138;141) 87 {45, 68}'
546 7dd94df7 Carles Marti
    # Convert the string into a list of lists
547 7dd94df7 Carles Marti
    molec_ctrs2 = try_command(str2lst, [(ValueError, err_msg),
548 7dd94df7 Carles Marti
                                        (AttributeError, err_msg)],
549 7dd94df7 Carles Marti
                              dos_inp.get('Screening', 'molec_ctrs2'))
550 7dd94df7 Carles Marti
551 8887f41d Carles
    # Check all elements of the list (of lists) are positive integers
552 7dd94df7 Carles Marti
    for ctr in molec_ctrs2:
553 c845c6f2 Carles Marti
        if isinstance(ctr, list):
554 8887f41d Carles
            for atom in ctr:
555 8887f41d Carles
                if atom < 0:
556 8887f41d Carles
                    logger.error(err_msg)
557 8887f41d Carles
                    raise ValueError(err_msg)
558 c845c6f2 Carles Marti
        elif isinstance(ctr, int):
559 8887f41d Carles
            if ctr < 0:
560 8887f41d Carles
                logger.error(err_msg)
561 8887f41d Carles
                raise ValueError(err_msg)
562 8887f41d Carles
        else:
563 8887f41d Carles
            logger.error(err_msg)
564 8887f41d Carles
            raise ValueError(err_msg)
565 8887f41d Carles
566 7dd94df7 Carles Marti
    return molec_ctrs2
567 8887f41d Carles
568 8887f41d Carles
569 7dd94df7 Carles Marti
def get_molec_ctrs3():
570 7dd94df7 Carles Marti
    err_msg = 'The value of molec_ctrs3 should be a list of atom ' \
571 c845c6f2 Carles Marti
              'numbers (ie. positive integers) or groups of atom ' \
572 c845c6f2 Carles Marti
              'numbers enclosed by parentheses-like characters. \n' \
573 c845c6f2 Carles Marti
              'eg. 128,(135 138;141) 87 {45, 68}'
574 c845c6f2 Carles Marti
    # Convert the string into a list of lists
575 7dd94df7 Carles Marti
    molec_ctrs3 = try_command(str2lst, [(ValueError, err_msg),
576 7dd94df7 Carles Marti
                                        (AttributeError, err_msg)],
577 7dd94df7 Carles Marti
                              dos_inp.get('Screening', 'molec_ctrs3'))
578 c845c6f2 Carles Marti
579 c845c6f2 Carles Marti
    # Check all elements of the list (of lists) are positive integers
580 7dd94df7 Carles Marti
    for ctr in molec_ctrs3:
581 c845c6f2 Carles Marti
        if isinstance(ctr, list):
582 c845c6f2 Carles Marti
            for atom in ctr:
583 c845c6f2 Carles Marti
                if atom < 0:
584 c845c6f2 Carles Marti
                    logger.error(err_msg)
585 c845c6f2 Carles Marti
                    raise ValueError(err_msg)
586 c845c6f2 Carles Marti
        elif isinstance(ctr, int):
587 c845c6f2 Carles Marti
            if ctr < 0:
588 c845c6f2 Carles Marti
                logger.error(err_msg)
589 c845c6f2 Carles Marti
                raise ValueError(err_msg)
590 c845c6f2 Carles Marti
        else:
591 c845c6f2 Carles Marti
            logger.error(err_msg)
592 c845c6f2 Carles Marti
            raise ValueError(err_msg)
593 c845c6f2 Carles Marti
594 7dd94df7 Carles Marti
    return molec_ctrs3
595 c845c6f2 Carles Marti
596 c845c6f2 Carles Marti
597 a98d4172 Carles Marti
def get_max_helic_angle():
598 a98d4172 Carles Marti
    err_msg = "'max_helic_angle' must be a positive number in degrees"
599 a98d4172 Carles Marti
    max_helic_angle = try_command(dos_inp.getfloat, [(ValueError, err_msg)],
600 a98d4172 Carles Marti
                                  'Screening', 'max_helic_angle',
601 a98d4172 Carles Marti
                                  fallback=180.0)
602 a98d4172 Carles Marti
    if max_helic_angle < 0:
603 a98d4172 Carles Marti
        logger.error(err_msg)
604 a98d4172 Carles Marti
        raise ValueError(err_msg)
605 a98d4172 Carles Marti
606 a98d4172 Carles Marti
    return max_helic_angle
607 a98d4172 Carles Marti
608 a98d4172 Carles Marti
609 8af49f6d Carles Marti
def get_select_magns():
610 8af49f6d Carles Marti
    select_magns_vals = ['energy', 'moi']
611 8af49f6d Carles Marti
    select_magns_str = dos_inp.get('Screening', 'select_magns',
612 14e0b660 Carles Martí
                                   fallback='moi')
613 8af49f6d Carles Marti
    select_magns_str.replace(',', ' ').replace(';', ' ')
614 8af49f6d Carles Marti
    select_magns = select_magns_str.split(' ')
615 8af49f6d Carles Marti
    select_magns = [m.lower() for m in select_magns]
616 8af49f6d Carles Marti
    for m in select_magns:
617 8af49f6d Carles Marti
        check_expect_val(m, select_magns_vals)
618 8af49f6d Carles Marti
    return select_magns
619 8af49f6d Carles Marti
620 8af49f6d Carles Marti
621 af2bf62f Carles Marti
def get_confs_per_magn():
622 af2bf62f Carles Marti
    err_msg = num_error % ('confs_per_magn', 'positive integer')
623 af2bf62f Carles Marti
    confs_per_magn = try_command(dos_inp.getint, [(ValueError, err_msg)],
624 af2bf62f Carles Marti
                                 'Screening', 'confs_per_magn', fallback=2)
625 af2bf62f Carles Marti
    if confs_per_magn <= 0:
626 af2bf62f Carles Marti
        logger.error(err_msg)
627 af2bf62f Carles Marti
        raise ValueError(err_msg)
628 af2bf62f Carles Marti
    return confs_per_magn
629 af2bf62f Carles Marti
630 af2bf62f Carles Marti
631 c845c6f2 Carles Marti
def get_surf_norm_vect():
632 d6da8693 Carles Marti
    err = "'surf_norm_vect' must be a 3 component vector, 'x', 'y' or 'z', " \
633 d6da8693 Carles Marti
          "'auto' or 'asann'."
634 9c16a7e2 Carles Marti
    cart_axes = {'x': [1.0, 0.0, 0.0], '-x': [-1.0, 0.0, 0.0],
635 9c16a7e2 Carles Marti
                 'y': [0.0, 1.0, 0.0], '-y': [0.0, -1.0, 0.0],
636 9c16a7e2 Carles Marti
                 'z': [0.0, 0.0, 1.0], '-z': [0.0, 0.0, -1.0]}
637 c845c6f2 Carles Marti
    surf_norm_vect_str = dos_inp.get('Screening', 'surf_norm_vect',
638 d6da8693 Carles Marti
                                     fallback="auto").lower()
639 d6da8693 Carles Marti
    if surf_norm_vect_str == "asann" or surf_norm_vect_str == "auto":
640 d6da8693 Carles Marti
        return 'auto'
641 9c16a7e2 Carles Marti
    if surf_norm_vect_str in cart_axes:
642 d6da8693 Carles Marti
        return np.array(cart_axes[surf_norm_vect_str])
643 d6da8693 Carles Marti
    surf_norm_vect = try_command(str2lst, [(ValueError, err)],
644 d6da8693 Carles Marti
                                 surf_norm_vect_str, float)
645 d6da8693 Carles Marti
    if len(surf_norm_vect) != 3:
646 d6da8693 Carles Marti
        logger.error(err)
647 d6da8693 Carles Marti
        raise ValueError(err)
648 3d56e566 Carles Marti
649 b6b1b03e Carles Marti
    return np.array(surf_norm_vect) / np.linalg.norm(surf_norm_vect)
650 c845c6f2 Carles Marti
651 c845c6f2 Carles Marti
652 fe91ddb2 Carles Marti
def get_adsorption_height():
653 fe91ddb2 Carles Marti
    err_msg = num_error % ('adsorption_height', 'positive number')
654 fe91ddb2 Carles Marti
    ads_height = try_command(dos_inp.getfloat, [(ValueError, err_msg)],
655 fe91ddb2 Carles Marti
                             'Screening', 'adsorption_height', fallback=2.5)
656 fe91ddb2 Carles Marti
    if ads_height <= 0:
657 fe91ddb2 Carles Marti
        logger.error(err_msg)
658 fe91ddb2 Carles Marti
        raise ValueError(err_msg)
659 fe91ddb2 Carles Marti
    return ads_height
660 fe91ddb2 Carles Marti
661 fe91ddb2 Carles Marti
662 7dd94df7 Carles Marti
def get_set_angles():
663 609104e3 Carles Marti
    set_vals = ['euler', 'internal']
664 7dd94df7 Carles Marti
    check_expect_val(dos_inp.get('Screening', 'set_angles').lower(), set_vals)
665 5261a07f Carles Marti
    set_angles = dos_inp.get('Screening', 'set_angles',
666 5261a07f Carles Marti
                             fallback='euler').lower()
667 7dd94df7 Carles Marti
    return set_angles
668 a7c7b43e Carles Marti
669 a7c7b43e Carles Marti
670 8887f41d Carles
def get_pts_per_angle():
671 d4bedc18 Carles Marti
    err_msg = num_error % ('sample_points_per_angle', 'positive integer')
672 8887f41d Carles
    pts_per_angle = try_command(dos_inp.getint,
673 8887f41d Carles
                                [(ValueError, err_msg)],
674 8887f41d Carles
                                'Screening', 'sample_points_per_angle',
675 8887f41d Carles
                                fallback=3)
676 d4bedc18 Carles Marti
    if pts_per_angle <= 0:
677 d4bedc18 Carles Marti
        logger.error(err_msg)
678 d4bedc18 Carles Marti
        raise ValueError(err_msg)
679 8887f41d Carles
    return pts_per_angle
680 8887f41d Carles
681 8887f41d Carles
682 7d97341d Carles Marti
def get_max_structures():
683 7d97341d Carles Marti
    err_msg = num_error % ('max_structures', 'positive integer')
684 21209d96 Carles Marti
    max_structs = dos_inp.get('Screening', 'max_structures', fallback="False")
685 21209d96 Carles Marti
    if max_structs.lower() in turn_false_answers:
686 21209d96 Carles Marti
        return np.inf
687 21209d96 Carles Marti
    if try_command(int, [(ValueError, err_msg)], max_structs) <= 0:
688 7d97341d Carles Marti
        logger.error(err_msg)
689 7d97341d Carles Marti
        raise ValueError(err_msg)
690 21209d96 Carles Marti
    return int(max_structs)
691 7d97341d Carles Marti
692 7d97341d Carles Marti
693 8887f41d Carles
def get_coll_thrsld():
694 fe91ddb2 Carles Marti
    err_msg = num_error % ('collision_threshold', 'positive number')
695 eef995b8 Carles Marti
    coll_thrsld_str = dos_inp.get('Screening', 'collision_threshold',
696 a44ad3c2 Carles Martí
                                  fallback="False")
697 eef995b8 Carles Marti
    if coll_thrsld_str.lower() in turn_false_answers:
698 eef995b8 Carles Marti
        return False
699 eef995b8 Carles Marti
    coll_thrsld = try_command(float, [(ValueError, err_msg)], coll_thrsld_str)
700 8887f41d Carles
701 8887f41d Carles
    if coll_thrsld <= 0:
702 8887f41d Carles
        logger.error(err_msg)
703 8887f41d Carles
        raise ValueError(err_msg)
704 8887f41d Carles
705 8887f41d Carles
    return coll_thrsld
706 8887f41d Carles
707 8887f41d Carles
708 f98ba5b0 Carles Marti
def get_min_coll_height(norm_vect):
709 5fb01677 Carles Marti
    err_msg = num_error % ('min_coll_height', 'decimal number')
710 5fb01677 Carles Marti
    min_coll_height = dos_inp.get('Screening', 'min_coll_height',
711 5fb01677 Carles Marti
                                  fallback="False")
712 5fb01677 Carles Marti
    if min_coll_height.lower() in turn_false_answers:
713 f98ba5b0 Carles Marti
        return False
714 f98ba5b0 Carles Marti
    min_coll_height = try_command(float, [(ValueError, err_msg)],
715 f98ba5b0 Carles Marti
                                  min_coll_height)
716 f98ba5b0 Carles Marti
    cart_axes = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0],
717 f98ba5b0 Carles Marti
                 [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]]
718 f98ba5b0 Carles Marti
    err_msg = "'min_coll_height' option is only implemented for " \
719 f98ba5b0 Carles Marti
              "'surf_norm_vect' to be one of the x, y or z axes. "
720 8279a51d Carles Marti
    if not isinstance(norm_vect, str) or norm_vect != 'auto':
721 d6da8693 Carles Marti
        check_expect_val(norm_vect.tolist(), cart_axes, err_msg)
722 5fb01677 Carles Marti
    return min_coll_height
723 8887f41d Carles
724 8887f41d Carles
725 9cd032cf Carles Marti
def get_exclude_ads_ctr():
726 9cd032cf Carles Marti
    err_msg = "exclude_ads_ctr must have a boolean value."
727 9cd032cf Carles Marti
    exclude_ads_ctr = try_command(dos_inp.getboolean, [(ValueError, err_msg)],
728 9cd032cf Carles Marti
                                  "Screening", "exclude_ads_ctr",
729 9cd032cf Carles Marti
                                  fallback=False)
730 9cd032cf Carles Marti
    return exclude_ads_ctr
731 9cd032cf Carles Marti
732 9cd032cf Carles Marti
733 c25aa299 Carles Marti
def get_H_donor(spec_atoms):
734 c25aa299 Carles Marti
    from ase.data import chemical_symbols
735 7d37379d Carles Martí
    err_msg = "The value of 'h_donor' must be either False, a chemical symbol " \
736 c25aa299 Carles Marti
              "or an atom index"
737 c25aa299 Carles Marti
    h_donor_str = dos_inp.get('Screening', 'h_donor', fallback="False")
738 c25aa299 Carles Marti
    h_donor = []
739 c25aa299 Carles Marti
    if h_donor_str.lower() in turn_false_answers:
740 c25aa299 Carles Marti
        return False
741 c25aa299 Carles Marti
    err = False
742 c25aa299 Carles Marti
    for el in h_donor_str.split():
743 c25aa299 Carles Marti
        try:
744 c25aa299 Carles Marti
            h_donor.append(int(el))
745 c25aa299 Carles Marti
        except ValueError:
746 c25aa299 Carles Marti
            if el not in chemical_symbols + [nw_sym for pairs in spec_atoms
747 c25aa299 Carles Marti
                                             for nw_sym in pairs]:
748 c25aa299 Carles Marti
                err = True
749 c25aa299 Carles Marti
            else:
750 c25aa299 Carles Marti
                h_donor.append(el)
751 c25aa299 Carles Marti
        finally:
752 c25aa299 Carles Marti
            if err:
753 c25aa299 Carles Marti
                logger.error(err_msg)
754 c25aa299 Carles Marti
                ValueError(err_msg)
755 c25aa299 Carles Marti
    return h_donor
756 c25aa299 Carles Marti
757 c25aa299 Carles Marti
758 c25aa299 Carles Marti
def get_H_acceptor(spec_atoms):
759 c25aa299 Carles Marti
    from ase.data import chemical_symbols
760 c25aa299 Carles Marti
    err_msg = "The value of 'h_acceptor' must be either 'all', a chemical " \
761 30e34792 Carles Martí
              "symbol or an atom index."
762 c25aa299 Carles Marti
    h_acceptor_str = dos_inp.get('Screening', 'h_acceptor', fallback="all")
763 c25aa299 Carles Marti
    if h_acceptor_str.lower() == "all":
764 c25aa299 Carles Marti
        return "all"
765 c25aa299 Carles Marti
    h_acceptor = []
766 c25aa299 Carles Marti
    err = False
767 c25aa299 Carles Marti
    for el in h_acceptor_str.split():
768 c25aa299 Carles Marti
        try:
769 c25aa299 Carles Marti
            h_acceptor.append(int(el))
770 c25aa299 Carles Marti
        except ValueError:
771 c25aa299 Carles Marti
            if el not in chemical_symbols + [nw_sym for pairs in spec_atoms
772 c25aa299 Carles Marti
                                             for nw_sym in pairs]:
773 c25aa299 Carles Marti
                err = True
774 c25aa299 Carles Marti
            else:
775 c25aa299 Carles Marti
                h_acceptor.append(el)
776 c25aa299 Carles Marti
        finally:
777 c25aa299 Carles Marti
            if err:
778 c25aa299 Carles Marti
                logger.error(err_msg)
779 30e34792 Carles Martí
                raise ValueError(err_msg)
780 c25aa299 Carles Marti
    return h_acceptor
781 a765b11c Carles Marti
782 a765b11c Carles Marti
783 b75bf97d Carles Marti
def get_use_molec_file():
784 b75bf97d Carles Marti
    use_molec_file = dos_inp.get('Screening', 'use_molec_file',
785 b75bf97d Carles Marti
                                 fallback='False')
786 13731dc4 Carles Marti
    if use_molec_file.lower() in turn_false_answers:
787 b75bf97d Carles Marti
        return False
788 b75bf97d Carles Marti
    if not os.path.isfile(use_molec_file):
789 b75bf97d Carles Marti
        logger.error(f'File {use_molec_file} not found.')
790 b75bf97d Carles Marti
        raise FileNotFoundError(f'File {use_molec_file} not found')
791 b75bf97d Carles Marti
792 b75bf97d Carles Marti
    return use_molec_file
793 b75bf97d Carles Marti
794 b75bf97d Carles Marti
795 a7128ce1 Carles Marti
# Refinement
796 a7128ce1 Carles Marti
797 7d37379d Carles Martí
def get_refine_inp_file(code, potcar_dir=None):
798 9d3b680c Carles Martí
    inp_file_lst = dos_inp.get('Refinement', 'refine_inp_file').split()
799 f349bb54 Carles
    check_inp_files(inp_file_lst[0] if len(inp_file_lst) == 1 else inp_file_lst,
800 f349bb54 Carles
                    code, potcar_dir)
801 9d3b680c Carles Martí
    return inp_file_lst[0] if len(inp_file_lst) == 1 else inp_file_lst
802 8887f41d Carles
803 8887f41d Carles
804 8887f41d Carles
def get_energy_cutoff():
805 8887f41d Carles
    err_msg = num_error % ('energy_cutoff', 'positive decimal number')
806 8887f41d Carles
    energy_cutoff = try_command(dos_inp.getfloat,
807 8887f41d Carles
                                [(ValueError, err_msg)],
808 8887f41d Carles
                                'Refinement', 'energy_cutoff', fallback=0.5)
809 8887f41d Carles
    if energy_cutoff < 0:
810 8887f41d Carles
        logger.error(err_msg)
811 8887f41d Carles
        raise ValueError(err_msg)
812 8887f41d Carles
    return energy_cutoff
813 8887f41d Carles
814 8887f41d Carles
815 c25aa299 Carles Marti
# Read input parameters
816 c25aa299 Carles Marti
817 8887f41d Carles
def read_input(in_file):
818 9d3b680c Carles Martí
    from modules.formats import adapt_format
819 9d3b680c Carles Martí
820 9d3b680c Carles Martí
    err_msg = False
821 8887f41d Carles
    try:
822 8887f41d Carles
        dos_inp.read(in_file)
823 8887f41d Carles
    except MissingSectionHeaderError as e:
824 8887f41d Carles
        logger.error('There are options in the input file without a Section '
825 695dcff8 Carles Marti
                     'header.')
826 14e0b660 Carles Martí
        err_msg = e
827 8887f41d Carles
    except DuplicateOptionError as e:
828 8887f41d Carles
        logger.error('There is an option in the input file that has been '
829 0bca5abb Carles Marti
                     'specified more than once.')
830 14e0b660 Carles Martí
        err_msg = e
831 8887f41d Carles
    except Exception as e:
832 14e0b660 Carles Martí
        err_msg = e
833 8887f41d Carles
    else:
834 14e0b660 Carles Martí
        err_msg = False
835 8887f41d Carles
    finally:
836 14e0b660 Carles Martí
        if isinstance(err_msg, BaseException):
837 14e0b660 Carles Martí
            raise err_msg
838 17e72a49 Carles
839 7dd94df7 Carles Marti
    inp_vars = {}
840 8887f41d Carles
841 8887f41d Carles
    # Global
842 8887f41d Carles
    if not dos_inp.has_section('Global'):
843 8887f41d Carles
        logger.error(no_sect_err % 'Global')
844 8887f41d Carles
        raise NoSectionError('Global')
845 8887f41d Carles
846 8887f41d Carles
    # Mandatory options
847 8887f41d Carles
    # Checks whether the mandatory options 'run_type', 'code', etc. are present.
848 14e0b660 Carles Martí
    glob_mand_opts = ['run_type', 'code', 'batch_q_sys']
849 7fd58762 Carles
    for opt in glob_mand_opts:
850 8887f41d Carles
        if not dos_inp.has_option('Global', opt):
851 8887f41d Carles
            logger.error(no_opt_err % (opt, 'Global'))
852 8887f41d Carles
            raise NoOptionError(opt, 'Global')
853 8887f41d Carles
854 8887f41d Carles
    # Gets which sections are to be carried out
855 8887f41d Carles
    isolated, screening, refinement = get_run_type()
856 7dd94df7 Carles Marti
    inp_vars['isolated'] = isolated
857 7dd94df7 Carles Marti
    inp_vars['screening'] = screening
858 7dd94df7 Carles Marti
    inp_vars['refinement'] = refinement
859 14e0b660 Carles Martí
    inp_vars['code'] = get_code()
860 7dd94df7 Carles Marti
    inp_vars['batch_q_sys'] = get_batch_q_sys()
861 8887f41d Carles
862 99afde40 Carles
    # Dependent options:
863 7dd94df7 Carles Marti
    if inp_vars['batch_q_sys']:
864 7dd94df7 Carles Marti
        inp_vars['max_jobs'] = get_max_jobs()
865 7dd94df7 Carles Marti
        if inp_vars['batch_q_sys'] != 'local':
866 09c3325a Carles Marti
            if not dos_inp.has_option('Global', 'subm_script'):
867 09c3325a Carles Marti
                logger.error(no_opt_err % ('subm_script', 'Global'))
868 09c3325a Carles Marti
                raise NoOptionError('subm_script', 'Global')
869 7dd94df7 Carles Marti
            inp_vars['subm_script'] = get_subm_script()
870 f349bb54 Carles
    if inp_vars['code'] == "vasp":
871 f349bb54 Carles
        inp_vars['potcar_dir'] = get_potcar_dir()
872 99afde40 Carles
873 8887f41d Carles
    # Facultative options (Default/Fallback value present)
874 9d3b680c Carles Martí
    inp_vars['pbc_cell'] = get_pbc_cell()
875 7dd94df7 Carles Marti
    inp_vars['project_name'] = get_project_name()
876 8b3d4772 Carles Marti
    # inp_vars['relaunch_err'] = get_relaunch_err()
877 7dd94df7 Carles Marti
    inp_vars['special_atoms'] = get_special_atoms()
878 8887f41d Carles
879 8887f41d Carles
    # Isolated
880 b1d27be5 Carles
    if isolated:
881 b606c71a Carles
        if not dos_inp.has_section('Isolated'):
882 b606c71a Carles
            logger.error(no_sect_err % 'Isolated')
883 b606c71a Carles
            raise NoSectionError('Isolated')
884 8887f41d Carles
        # Mandatory options
885 8887f41d Carles
        # Checks whether the mandatory options are present.
886 95dc2c8e Carles
        iso_mand_opts = ['isol_inp_file', 'molec_file']
887 8887f41d Carles
        for opt in iso_mand_opts:
888 8887f41d Carles
            if not dos_inp.has_option('Isolated', opt):
889 8887f41d Carles
                logger.error(no_opt_err % (opt, 'Isolated'))
890 8887f41d Carles
                raise NoOptionError(opt, 'Isolated')
891 7d37379d Carles Martí
        if 'potcar_dir' in inp_vars:
892 7d37379d Carles Martí
            inp_vars['isol_inp_file'] = get_isol_inp_file(inp_vars['code'],
893 7d37379d Carles Martí
                                                          inp_vars[
894 7d37379d Carles Martí
                                                              'potcar_dir'])
895 7d37379d Carles Martí
        else:
896 7d37379d Carles Martí
            inp_vars['isol_inp_file'] = get_isol_inp_file(inp_vars['code'])
897 7dd94df7 Carles Marti
        inp_vars['molec_file'] = get_molec_file()
898 8887f41d Carles
899 9d3b680c Carles Martí
        # Checks for PBC
900 9d3b680c Carles Martí
        atms = adapt_format('ase', inp_vars['molec_file'],
901 9d3b680c Carles Martí
                            inp_vars['special_atoms'])
902 9d3b680c Carles Martí
        if inp_vars['code'] == 'vasp' and np.linalg.det(atms.cell) == 0.0 \
903 9d3b680c Carles Martí
                and inp_vars['pbc_cell'] is False:
904 a5d76bfb Carles Martí
            err_msg = "When running calculations with 'VASP', the PBC cell " \
905 9d3b680c Carles Martí
                      "should be provided either implicitely inside " \
906 9d3b680c Carles Martí
                      "'molec_file' or by setting the 'pbc_cell' option."
907 9d3b680c Carles Martí
            logger.error(err_msg)
908 9d3b680c Carles Martí
            raise ValueError(err_msg)
909 a5d76bfb Carles Martí
        elif inp_vars['pbc_cell'] is False and np.linalg.det(atms.cell) != 0.0:
910 a5d76bfb Carles Martí
            inp_vars['pbc_cell'] = atms.cell
911 a5d76bfb Carles Martí
            logger.info(f"Obtained pbc_cell from '{inp_vars['molec_file']}' "
912 a5d76bfb Carles Martí
                        f"file.")
913 a5d76bfb Carles Martí
        elif (atms.cell != 0).any() and not np.allclose(inp_vars['pbc_cell'],
914 a5d76bfb Carles Martí
                                                        atms.cell):
915 9d3b680c Carles Martí
            logger.warning("'molec_file' has an implicit cell defined "
916 a5d76bfb Carles Martí
                           f"different than 'pbc_cell'.\n"
917 a5d76bfb Carles Martí
                           f"'molec_file' = {atms.cell}.\n"
918 a5d76bfb Carles Martí
                           f"'pbc_cell' = {inp_vars['pbc_cell']}).\n"
919 a5d76bfb Carles Martí
                           "'pbc_cell' value will be used.")
920 9d3b680c Carles Martí
921 8887f41d Carles
        # Facultative options (Default/Fallback value present)
922 7dd94df7 Carles Marti
        inp_vars['num_conformers'] = get_num_conformers()
923 7dd94df7 Carles Marti
        inp_vars['pre_opt'] = get_pre_opt()
924 8887f41d Carles
925 8887f41d Carles
    # Screening
926 b1d27be5 Carles
    if screening:
927 772b40e5 Carles
        if not dos_inp.has_section('Screening'):
928 9f7bb440 Carles
            logger.error(no_sect_err % 'Screening')
929 772b40e5 Carles
            raise NoSectionError('Screening')
930 8887f41d Carles
        # Mandatory options:
931 8887f41d Carles
        # Checks whether the mandatory options are present.
932 a765b11c Carles Marti
        screen_mand_opts = ['screen_inp_file', 'surf_file', 'sites',
933 7dd94df7 Carles Marti
                            'molec_ctrs']
934 8887f41d Carles
        for opt in screen_mand_opts:
935 772b40e5 Carles
            if not dos_inp.has_option('Screening', opt):
936 9f7bb440 Carles
                logger.error(no_opt_err % (opt, 'Screening'))
937 b1d27be5 Carles
                raise NoOptionError(opt, 'Screening')
938 7d37379d Carles Martí
        if 'potcar_dir' in inp_vars:
939 7d37379d Carles Martí
            inp_vars['screen_inp_file'] = get_screen_inp_file(inp_vars['code'],
940 7d37379d Carles Martí
                                                              inp_vars[
941 7d37379d Carles Martí
                                                                  'potcar_dir'])
942 7d37379d Carles Martí
        else:
943 7d37379d Carles Martí
            inp_vars['screen_inp_file'] = get_screen_inp_file(inp_vars['code'])
944 7dd94df7 Carles Marti
        inp_vars['surf_file'] = get_surf_file()
945 7dd94df7 Carles Marti
        inp_vars['sites'] = get_sites()
946 7dd94df7 Carles Marti
        inp_vars['molec_ctrs'] = get_molec_ctrs()
947 8887f41d Carles
948 9d3b680c Carles Martí
        # Checks for PBC
949 a5d76bfb Carles Martí
        # Checks for PBC
950 9d3b680c Carles Martí
        atms = adapt_format('ase', inp_vars['surf_file'],
951 9d3b680c Carles Martí
                            inp_vars['special_atoms'])
952 9d3b680c Carles Martí
        if inp_vars['code'] == 'vasp' and np.linalg.det(atms.cell) == 0.0 \
953 9d3b680c Carles Martí
                and inp_vars['pbc_cell'] is False:
954 a5d76bfb Carles Martí
            err_msg = "When running calculations with 'VASP', the PBC cell " \
955 9d3b680c Carles Martí
                      "should be provided either implicitely inside " \
956 a5d76bfb Carles Martí
                      "'surf_file' or by setting the 'pbc_cell' option."
957 9d3b680c Carles Martí
            logger.error(err_msg)
958 9d3b680c Carles Martí
            raise ValueError(err_msg)
959 a5d76bfb Carles Martí
        elif inp_vars['pbc_cell'] is False and np.linalg.det(atms.cell) != 0.0:
960 a5d76bfb Carles Martí
            inp_vars['pbc_cell'] = atms.cell
961 a5d76bfb Carles Martí
            logger.info(f"Obtained pbc_cell from '{inp_vars['surf_file']}' "
962 a5d76bfb Carles Martí
                        f"file.")
963 a5d76bfb Carles Martí
        elif (atms.cell != 0).any() and not np.allclose(inp_vars['pbc_cell'],
964 a5d76bfb Carles Martí
                                                        atms.cell):
965 a5d76bfb Carles Martí
            logger.warning("'surf_file' has an implicit cell defined "
966 a5d76bfb Carles Martí
                           f"different than 'pbc_cell'.\n"
967 a5d76bfb Carles Martí
                           f"'surf_file' = {atms.cell}.\n"
968 a5d76bfb Carles Martí
                           f"'pbc_cell' = {inp_vars['pbc_cell']}).\n"
969 9d3b680c Carles Martí
                           "'pbc_cell' value will be used.")
970 9d3b680c Carles Martí
971 8887f41d Carles
        # Facultative options (Default value present)
972 7dd94df7 Carles Marti
        inp_vars['select_magns'] = get_select_magns()
973 7dd94df7 Carles Marti
        inp_vars['confs_per_magn'] = get_confs_per_magn()
974 7dd94df7 Carles Marti
        inp_vars['surf_norm_vect'] = get_surf_norm_vect()
975 fe91ddb2 Carles Marti
        inp_vars['adsorption_height'] = get_adsorption_height()
976 7dd94df7 Carles Marti
        inp_vars['set_angles'] = get_set_angles()
977 7dd94df7 Carles Marti
        inp_vars['sample_points_per_angle'] = get_pts_per_angle()
978 7dd94df7 Carles Marti
        inp_vars['collision_threshold'] = get_coll_thrsld()
979 f98ba5b0 Carles Marti
        inp_vars['min_coll_height'] = get_min_coll_height(
980 f98ba5b0 Carles Marti
            inp_vars['surf_norm_vect'])
981 8b3d4772 Carles Marti
        if inp_vars['min_coll_height'] is False \
982 8b3d4772 Carles Marti
                and inp_vars['collision_threshold'] is False:
983 8b3d4772 Carles Marti
            logger.warning("Collisions are deactivated: Overlapping of "
984 8b3d4772 Carles Marti
                           "adsorbate and surface is possible")
985 9cd032cf Carles Marti
        inp_vars['exclude_ads_ctr'] = get_exclude_ads_ctr()
986 b75bf97d Carles Marti
        inp_vars['h_donor'] = get_H_donor(inp_vars['special_atoms'])
987 b75bf97d Carles Marti
        inp_vars['max_structures'] = get_max_structures()
988 b75bf97d Carles Marti
        inp_vars['use_molec_file'] = get_use_molec_file()
989 8887f41d Carles
990 8b3d4772 Carles Marti
        # Options depending on the value of others
991 609104e3 Carles Marti
        if inp_vars['set_angles'] == "internal":
992 609104e3 Carles Marti
            internal_opts = ['molec_ctrs2', 'molec_ctrs3', 'surf_ctrs2',
993 609104e3 Carles Marti
                             'max_helic_angle']
994 609104e3 Carles Marti
            for opt in internal_opts:
995 7dd94df7 Carles Marti
                if not dos_inp.has_option('Screening', opt):
996 7dd94df7 Carles Marti
                    logger.error(no_opt_err % (opt, 'Screening'))
997 7dd94df7 Carles Marti
                    raise NoOptionError(opt, 'Screening')
998 a98d4172 Carles Marti
            inp_vars['max_helic_angle'] = get_max_helic_angle()
999 7dd94df7 Carles Marti
            inp_vars['molec_ctrs2'] = get_molec_ctrs2()
1000 7dd94df7 Carles Marti
            inp_vars['molec_ctrs3'] = get_molec_ctrs3()
1001 7dd94df7 Carles Marti
            inp_vars['surf_ctrs2'] = get_surf_ctrs2()
1002 7dd94df7 Carles Marti
            if len(inp_vars["molec_ctrs2"]) != len(inp_vars['molec_ctrs']) \
1003 7dd94df7 Carles Marti
                    or len(inp_vars["molec_ctrs3"]) != \
1004 7dd94df7 Carles Marti
                    len(inp_vars['molec_ctrs']) \
1005 7dd94df7 Carles Marti
                    or len(inp_vars['surf_ctrs2']) != len(inp_vars['sites']):
1006 14e0b660 Carles Martí
                err_msg = "'molec_ctrs' 'molec_ctrs2' and 'molec_ctrs3' must " \
1007 14e0b660 Carles Martí
                          "have the same number of indices "
1008 14e0b660 Carles Martí
                logger.error(err_msg)
1009 14e0b660 Carles Martí
                raise ValueError(err_msg)
1010 7dd94df7 Carles Marti
1011 c25aa299 Carles Marti
        if inp_vars['h_donor'] is False:
1012 c25aa299 Carles Marti
            inp_vars['h_acceptor'] = False
1013 c25aa299 Carles Marti
        else:
1014 c25aa299 Carles Marti
            inp_vars['h_acceptor'] = get_H_acceptor(inp_vars['special_atoms'])
1015 c25aa299 Carles Marti
1016 8887f41d Carles
    # Refinement
1017 b1d27be5 Carles
    if refinement:
1018 8887f41d Carles
        if not dos_inp.has_section('Refinement'):
1019 8887f41d Carles
            logger.error(no_sect_err % 'Refinement')
1020 8887f41d Carles
            raise NoSectionError('Refinement')
1021 8887f41d Carles
        # Mandatory options
1022 8887f41d Carles
        # Checks whether the mandatory options are present.
1023 8887f41d Carles
        ref_mand_opts = ['refine_inp_file']
1024 8887f41d Carles
        for opt in ref_mand_opts:
1025 8887f41d Carles
            if not dos_inp.has_option('Refinement', opt):
1026 8887f41d Carles
                logger.error(no_opt_err % (opt, 'Refinement'))
1027 8887f41d Carles
                raise NoOptionError(opt, 'Refinement')
1028 7d37379d Carles Martí
        if 'potcar_dir' in inp_vars:
1029 7d37379d Carles Martí
            inp_vars['refine_inp_file'] = get_refine_inp_file(inp_vars['code'],
1030 7d37379d Carles Martí
                                                              inp_vars[
1031 7d37379d Carles Martí
                                                                  'potcar_dir'])
1032 7d37379d Carles Martí
        else:
1033 7d37379d Carles Martí
            inp_vars['refine_inp_file'] = get_refine_inp_file(inp_vars['code'])
1034 8887f41d Carles
1035 8887f41d Carles
        # Facultative options (Default value present)
1036 7dd94df7 Carles Marti
        inp_vars['energy_cutoff'] = get_energy_cutoff()
1037 b1d27be5 Carles
        # end energy_cutoff
1038 9f7bb440 Carles
1039 a5cc42ff Carles Marti
    return_vars_str = "\n\t".join([str(key) + ": " + str(value)
1040 7dd94df7 Carles Marti
                                   for key, value in inp_vars.items()])
1041 14e0b660 Carles Martí
    logger.info(f'Correctly read {in_file} parameters:'
1042 14e0b660 Carles Martí
                f' \n\n\t{return_vars_str}\n')
1043 d8a6314e Carles
1044 7dd94df7 Carles Marti
    return inp_vars
1045 8887f41d Carles
1046 8887f41d Carles
1047 8887f41d Carles
if __name__ == "__main__":
1048 8887f41d Carles
    import sys
1049 8887f41d Carles
1050 8887f41d Carles
    print(read_input(sys.argv[1]))