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

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, '': 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