Skip to content
This repository has been archived by the owner on Oct 19, 2023. It is now read-only.

Commit

Permalink
Added "SLogP" as new component (+ unit tests).
Browse files Browse the repository at this point in the history
  • Loading branch information
CMargreitter committed Sep 4, 2020
1 parent 2cf3f54 commit 2185ffd
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The scoring function is built-up from components, which together define the "com
* `ROTATABLE BONDS`: Physico-chemical property calculated by `RDKit`[link](https://www.rdkit.org/docs/Cookbook.html#contiguous-rotable-bonds).
* `NUMBER OF HYDROGEN BOND DONORS`: Physico-chemical property calculated by `RDKit`[link](https://www.rdkit.org/docs/source/rdkit.Chem.Lipinski.html).
* `NUMBER OF HYDROGEN BOND ACCEPTORS`: Physico-chemical property calculated by `RDKit`[link](https://www.rdkit.org/docs/source/rdkit.Chem.Lipinski.html).
* `SLOGP`: Atom-based calculation of LogP using Crippen’s approach as implemented in `RDKit`[link](https://www.rdkit.org/docs/source/rdkit.Chem.Crippen.html).
* `NUMBER OF RINGS`: Physico-chemical property calculated by `RDKit`[link](https://www.rdkit.org/docs/source/rdkit.Chem.rdMolDescriptors.html).
* `SELECTIVITY`: If the aim is to optimize activity against one target while reducing activity agains another, i.e. to increase compound's selectivity, this component can be used. Uses two [scikit-learn](https://scikit-learn.org/stable/) models. Works with both classification and regression models. One model is predicting the target activity and the other is providing an off-target prediction. The score is reflecting a user defined activity gap between the target and the off-target predictions.

Expand Down
16 changes: 16 additions & 0 deletions data/examples/templates/reinforcement_learning_all_components.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,22 @@
"transformation": true
}
},
{
"component_type": "slogp",
"name": "SLogP",
"weight": 1,
"model_path": null,
"smiles": [],
"specific_parameters": {
"transformation_type": "double_sigmoid",
"high": 3,
"low": 1,
"coef_div": 3,
"coef_si": 10,
"coef_se": 10,
"transformation": true
}
},
{
"component_type": "num_rings",
"name": "Number of rings",
Expand Down
1 change: 1 addition & 0 deletions scoring/score_components/physchem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
from scoring.score_components.physchem.hbd import HBD_Lipinski
from scoring.score_components.physchem.num_rings import NumRings
from scoring.score_components.physchem.hba import HBA_Lipinski
from scoring.score_components.physchem.slogp import SlogP
11 changes: 11 additions & 0 deletions scoring/score_components/physchem/slogp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from rdkit.Chem.Descriptors import MolLogP
from scoring.component_parameters import ComponentParameters
from scoring.score_components.physchem.base_physchem_component import BasePhysChemComponent


class SlogP(BasePhysChemComponent):
def __init__(self, parameters: ComponentParameters):
super().__init__(parameters)

def _calculate_phys_chem_property(self, mol):
return MolLogP(mol)
3 changes: 2 additions & 1 deletion scoring/score_components/score_component_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from scoring.score_components import TanimotoSimilarity, \
JaccardDistance, CustomAlerts, QedScore, MatchingSubstructure, \
PredictivePropertyComponent, SelectivityComponent, \
SASComponent, MolWeight, PSA, RotatableBonds, HBD_Lipinski, NumRings, HBA_Lipinski
SASComponent, MolWeight, PSA, RotatableBonds, HBD_Lipinski, NumRings, HBA_Lipinski, SlogP
from scoring.score_components.base_score_component import BaseScoreComponent
from utils.enums.scoring_function_component_enum import ScoringFunctionComponentNameEnum

Expand All @@ -28,6 +28,7 @@ def _default_scoring_component_registry(self) -> dict:
enum.NUM_ROTATABLE_BONDS: RotatableBonds,
enum.NUM_HBD_LIPINSKI: HBD_Lipinski,
enum.NUM_HBA_LIPINSKI: HBA_Lipinski,
enum.SLOGP: SlogP,
enum.NUM_RINGS: NumRings,
enum.SELECTIVITY: SelectivityComponent,
enum.SA_SCORE: SASComponent
Expand Down
1 change: 1 addition & 0 deletions unittest_reinvent/scoring_tests/physchem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
from unittest_reinvent.scoring_tests.physchem.test_hbd_lipinski import *
from unittest_reinvent.scoring_tests.physchem.test_hba_lipinski import *
from unittest_reinvent.scoring_tests.physchem.test_num_rings import *
from unittest_reinvent.scoring_tests.physchem.test_slogp_score import *
77 changes: 77 additions & 0 deletions unittest_reinvent/scoring_tests/physchem/test_slogp_score.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import unittest

import numpy as np
import numpy.testing as npt

from scoring.component_parameters import ComponentParameters
from scoring.function import CustomSum
from utils.enums.component_specific_parameters_enum import ComponentSpecificParametersEnum
from utils.enums.scoring_function_component_enum import ScoringFunctionComponentNameEnum
from utils.enums.transformation_type_enum import TransformationTypeEnum


class Test_slogp_score_no_transformation(unittest.TestCase):

@classmethod
def setUpClass(self):
sf_enum = ScoringFunctionComponentNameEnum()
csp_enum = ComponentSpecificParametersEnum()
ts_parameters = ComponentParameters(component_type=sf_enum.SLOGP,
name="SlogP",
weight=1.,
smiles=[],
model_path="",
specific_parameters={
csp_enum.TRANSFORMATION: False
})
self.sf_state = CustomSum(parameters=[ts_parameters])


def test_slogp_1(self):
smiles = [
"OC(=O)P(=O)(O)O",
"Cc1ccccc1N1C(=O)c2cc(S(N)(=O)=O)c(Cl)cc2NC1C",
"N12CC3C(=NC4C(C=3)=CC=CC=4)C1=CC1=C(COC(=O)C1(O)CC)C2=O",
"N12CC3C(=NC4C(C=3C(=O)O)=CC3=C(OCCO3)C=4)C1=CC1=C(COC(=O)C1(O)CC)C2=O",
"FC1C=CC(CC(=NS(=O)(=O)C2C=CC(C)=CC=2)N2CCN(CC3C4C(=CC=CC=4)N=C4C=3CN3C4=CC4=C(COC(=O)C4(O)CC)C3=O)CC2)=CC=1"
]
values = np.array([-0.1579, 2.71412, 2.0796, 1.549, 4.67482])
score = self.sf_state.get_final_score(smiles=smiles)
npt.assert_array_almost_equal(score.total_score, values, 2)

class Test_slogp_score_with_double_sigmoid(unittest.TestCase):

@classmethod
def setUpClass(self):
sf_enum = ScoringFunctionComponentNameEnum()
csp_enum = ComponentSpecificParametersEnum()
tt_enum = TransformationTypeEnum()
specific_parameters = {
csp_enum.TRANSFORMATION: True,
csp_enum.LOW: 1,
csp_enum.HIGH: 3,
csp_enum.COEF_DIV: 3,
csp_enum.COEF_SI: 10,
csp_enum.COEF_SE: 10,
csp_enum.TRANSFORMATION_TYPE: tt_enum.DOUBLE_SIGMOID
}
ts_parameters = ComponentParameters(component_type=sf_enum.SLOGP,
name="SlogP",
weight=1.,
smiles=[],
model_path="",
specific_parameters=specific_parameters
)
self.sf_state = CustomSum(parameters=[ts_parameters])

def test_slogp_1(self):
smiles = [
"OC(=O)P(=O)(O)O",
"Cc1ccccc1N1C(=O)c2cc(S(N)(=O)=O)c(Cl)cc2NC1C",
"N12CC3C(=NC4C(C=3)=CC=CC=4)C1=CC1=C(COC(=O)C1(O)CC)C2=O",
"N12CC3C(=NC4C(C=3C(=O)O)=CC3=C(OCCO3)C=4)C1=CC1=C(COC(=O)C1(O)CC)C2=O",
"FC1C=CC(CC(=NS(=O)(=O)C2C=CC(C)=CC=2)N2CCN(CC3C4C(=CC=CC=4)N=C4C=3CN3C4=CC4=C(COC(=O)C4(O)CC)C3=O)CC2)=CC=1"
]
values = np.array([0.0, 0.9, 1.0, 1.0, 0.0])
score = self.sf_state.get_final_score(smiles=smiles)
npt.assert_array_almost_equal(score.total_score, values, 2)
9 changes: 9 additions & 0 deletions utils/enums/scoring_function_component_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class ScoringFunctionComponentNameEnum():
__NUM_HBA_LIPINSKI = "num_hba_lipinski"
__NUM_RINGS = "num_rings"
__TPSA = "tpsa"
__SLOGP = "slogp"
__TOTAL_SCORE = "total_score" # there is no actual component corresponding to this type
__AZ_LOGD74 = "az_logd74"
__HLM_CLINT = "hlm_clint"
Expand Down Expand Up @@ -117,6 +118,14 @@ def QED_SCORE(self):
def QED_SCORE(self, value):
raise ValueError("Do not assign value to a ScoringFunctionComponentNameEnum field")

@property
def SLOGP(self):
return self.__SLOGP

@SLOGP.setter
def SLOGP(self, value):
raise ValueError("Do not assign value to a ScoringFunctionComponentNameEnum field")

@property
def MOLECULAR_WEIGHT(self):
return self.__MOLECULAR_WEIGHT
Expand Down

0 comments on commit 2185ffd

Please sign in to comment.