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

dockonsurf / modules / dos_input.py @ a02c931d

Historique | Voir | Annoter | Télécharger (11,12 ko)

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