Source code for icolos.core.workflow_steps.calculation.base
import numpy as np
import pandas as pd
from pydantic import BaseModel
from rdkit.Chem import AllChem
from typing import List
from icolos.core.containers.compound import Conformer
from icolos.core.workflow_steps.step import StepBase
from icolos.utils.enums.step_enums import StepRMSFilterEnum
_SRF = StepRMSFilterEnum()
[docs]class StepCalculationBase(StepBase, BaseModel):
def __init__(self, **data):
super().__init__(**data)
def _get_rms_method(self):
# there are two modes for the execution: "best" is better, but sometimes has performance issues
# for larger molecules
if self.settings.additional[_SRF.METHOD] == _SRF.METHOD_ALIGNMOL:
return AllChem.AlignMol
elif self.settings.additional[_SRF.METHOD] == _SRF.METHOD_BEST:
return AllChem.GetBestRMS
else:
raise ValueError(
f"RMS mode {self.settings.arguments.parameters[_SRF.METHOD]} not supported (either {_SRF.METHOD_ALIGNMOL} or {_SRF.METHOD_BEST})."
)
@staticmethod
def _get_property_values(conformers: List[Conformer], prop: str) -> List[float]:
return [float(conf.get_molecule().GetProp(prop)) for conf in conformers]
@staticmethod
def _calculate_rms_matrix(
conformers: List[Conformer], rms_method, decimals=3
) -> pd.DataFrame:
n_conf = len(conformers)
df_rms = pd.DataFrame(np.nan, index=range(n_conf), columns=range(n_conf))
np.fill_diagonal(df_rms.values, 0)
for i in range(n_conf - 1):
for j in range(i + 1, n_conf):
df_rms.iloc[i, j] = df_rms.iloc[j, i] = np.round(
rms_method(
conformers[i].get_molecule(), conformers[j].get_molecule()
),
decimals=decimals,
)
return df_rms