Révision 1d8c374e modules/screening.py

b/modules/screening.py
5 5
logger = logging.getLogger('DockOnSurf')
6 6

  
7 7

  
8
def assign_prop(atoms: ase.Atoms, prop_name: str, prop_val):  # TODO Needed?
9
    atoms.info[prop_name] = prop_val
10

  
11

  
12
def select_confs(orig_conf_list: list, calc_dirs: list, magns: list,
13
                 num_sel: int, code: str):
8
def select_confs(conf_list: list, magns: list, num_sel: int):
14 9
    """Takes a list ase.Atoms and selects the most different magnitude-wise.
15 10

  
16 11
    Given a list of ase.Atoms objects and a list of magnitudes, it selects a
17 12
    number of the most different conformers according to every magnitude
18 13
    specified.
19 14
     
20
    @param orig_conf_list: list of ase.Atoms objects to select among.
21
    @param calc_dirs: List of directories where to read the energies from.
15
    @param conf_list: list of ase.Atoms objects to select among.
22 16
    @param magns: list of str with the names of the magnitudes to use for the
23 17
        conformer selection. Supported magnitudes: 'energy', 'moi'.
24 18
    @param num_sel: number of conformers to select for every of the magnitudes.
25
    @param code: The code that generated the magnitude information.
26
         Supported codes: See formats.py
27 19
    @return: list of the selected ase.Atoms objects.
28 20
    """
29
    from copy import deepcopy
30
    from modules.formats import collect_energies
31

  
32
    conf_list = deepcopy(orig_conf_list)
33
    conf_enrgs, mois, selected_ids = [], [], []
21
    selected_ids = []
34 22
    if num_sel >= len(conf_list):
35 23
        logger.warning('Number of conformers per magnitude is equal or larger '
36 24
                       'than the total number of conformers. Using all '
37 25
                       f'available conformers: {len(conf_list)}.')
38 26
        return conf_list
39 27

  
40
    # Read properties
41
    if 'energy' in magns:
42
        if code == 'cp2k':
43
            conf_enrgs = collect_energies(calc_dirs, code, 'isolated')
44
        elif code == 'vasp':
45
            conf_enrgs = np.array([conf.get_total_energy()
46
                                   for conf in orig_conf_list])
28
    # Assign mois
47 29
    if 'moi' in magns:
48
        mois = np.array([conf.get_moments_of_inertia() for conf in conf_list])
49

  
50
    # Assign values
51
    for i, conf in enumerate(conf_list):
52
        assign_prop(conf, 'idx', i)
53
        assign_prop(conf, 'iso', calc_dirs[i])
54
        if 'energy' in magns:
55
            assign_prop(conf, 'energy', conf_enrgs[i])
56
        if 'moi' in magns:
57
            assign_prop(conf, 'moi', mois[i, 2])
30
        for conf in conf_list:
31
            conf.info["moi"] = conf.get_moments_of_inertia()[2]
58 32

  
59 33
    # pick ids
60 34
    for magn in magns:
61 35
        sorted_list = sorted(conf_list, key=lambda conf: abs(conf.info[magn]))
62
        if sorted_list[-1].info['idx'] not in selected_ids:
63
            selected_ids.append(sorted_list[-1].info['idx'])
36
        if sorted_list[-1].info['iso'] not in selected_ids:
37
            selected_ids.append(sorted_list[-1].info['iso'])
64 38
        if num_sel > 1:
65 39
            for i in range(0, len(sorted_list) - 1,
66 40
                           len(conf_list) // (num_sel - 1)):
67
                if sorted_list[i].info['idx'] not in selected_ids:
68
                    selected_ids.append(sorted_list[i].info['idx'])
41
                if sorted_list[i].info['iso'] not in selected_ids:
42
                    selected_ids.append(sorted_list[i].info['iso'])
69 43

  
70 44
    logger.info(f'Selected {len(selected_ids)} conformers for adsorption.')
71
    return [conf_list[idx] for idx in selected_ids]
45
    return [conf for conf in conf_list if conf.info["iso"] in selected_ids]
72 46

  
73 47

  
74 48
def get_vect_angle(v1: list, v2: list, ref=None, degrees=True):
......
1026 1000
    """
1027 1001
    import os
1028 1002
    import random
1029
    from modules.formats import collect_coords, adapt_format
1003
    from modules.formats import collect_confs, adapt_format
1030 1004
    from modules.calculation import run_calc, check_finished_calcs
1031 1005

  
1032 1006
    logger.info('Carrying out procedures for the screening of adsorbate-surface'
......
1042 1016
            logger.error(err)
1043 1017
            raise FileNotFoundError(err)
1044 1018

  
1045
        correct_calcs, failed_calcs = check_finished_calcs('isolated',
1046
                                                           inp_vars['code'])
1047
        if not correct_calcs:
1019
        finished_calcs, failed_calcs = check_finished_calcs('isolated',
1020
                                                            inp_vars['code'])
1021
        if not finished_calcs:
1048 1022
            err_msg = "No calculations on 'isolated' finished normally."
1049 1023
            logger.error(err_msg)
1050 1024
            raise FileNotFoundError(err_msg)
1051 1025

  
1052
        logger.info(f"Found {len(correct_calcs)} structures of isolated "
1026
        logger.info(f"Found {len(finished_calcs)} structures of isolated "
1053 1027
                    f"conformers whose calculation finished normally.")
1054 1028
        if len(failed_calcs) != 0:
1055 1029
            logger.warning(
1056 1030
                f"Found {len(failed_calcs)} calculations more that "
1057 1031
                f"did not finish normally: {failed_calcs}. \n"
1058 1032
                f"Using only the ones that finished normally: "
1059
                f"{correct_calcs}.")
1060

  
1061
        conformer_atoms_list = collect_coords(correct_calcs, inp_vars['code'],
1062
                                              'isolated',
1063
                                              inp_vars['special_atoms'])
1064
        selected_confs = select_confs(conformer_atoms_list, correct_calcs,
1065
                                      inp_vars['select_magns'],
1066
                                      inp_vars['confs_per_magn'],
1067
                                      inp_vars['code'])
1033
                f"{finished_calcs}.")
1034

  
1035
        conf_list = collect_confs(finished_calcs, inp_vars['code'], 'isolated',
1036
                                  inp_vars['special_atoms'])
1037
        selected_confs = select_confs(conf_list, inp_vars['select_magns'],
1038
                                      inp_vars['confs_per_magn'])
1068 1039
    surf = adapt_format('ase', inp_vars['surf_file'], inp_vars['special_atoms'])
1069 1040
    surf.info = {}
1070 1041
    surf_ads_list = adsorb_confs(selected_confs, surf, inp_vars)

Formats disponibles : Unified diff