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