From 3f1aaf11fae28270ec05df0afa20abad65cc4deb Mon Sep 17 00:00:00 2001 From: aditya0by0 Date: Tue, 29 Jul 2025 23:46:51 +0200 Subject: [PATCH 1/9] dynamic imports for nn models --- .../prediction_models/electra_predictor.py | 10 ++++-- chebifier/prediction_models/gnn_predictor.py | 31 ++++++++++++------- chebifier/prediction_models/nn_predictor.py | 5 ++- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/chebifier/prediction_models/electra_predictor.py b/chebifier/prediction_models/electra_predictor.py index 7d64418..f73034e 100644 --- a/chebifier/prediction_models/electra_predictor.py +++ b/chebifier/prediction_models/electra_predictor.py @@ -1,6 +1,4 @@ import numpy as np -from chebai.models.electra import Electra -from chebai.preprocessing.reader import EMBEDDING_OFFSET, ChemDataReader from .nn_predictor import NNPredictor @@ -37,10 +35,14 @@ def build_graph_from_attention(att, node_labels, token_labels, threshold=0.0): class ElectraPredictor(NNPredictor): def __init__(self, model_name: str, ckpt_path: str, **kwargs): + from chebai.preprocessing.reader import ChemDataReader + super().__init__(model_name, ckpt_path, reader_cls=ChemDataReader, **kwargs) print(f"Initialised Electra model {self.model_name} (device: {self.device})") - def init_model(self, ckpt_path: str, **kwargs) -> Electra: + def init_model(self, ckpt_path: str, **kwargs) -> "Electra": # noqa: F821 + from chebai.models.electra import Electra + model = Electra.load_from_checkpoint( ckpt_path, map_location=self.device, @@ -53,6 +55,8 @@ def init_model(self, ckpt_path: str, **kwargs) -> Electra: return model def explain_smiles(self, smiles) -> dict: + from chebai.preprocessing.reader import EMBEDDING_OFFSET + reader = self.reader_cls() token_dict = reader.to_data(dict(features=smiles, labels=None)) tokens = np.array(token_dict["features"]).astype(int).tolist() diff --git a/chebifier/prediction_models/gnn_predictor.py b/chebifier/prediction_models/gnn_predictor.py index 3d6fc92..4ccfef9 100644 --- a/chebifier/prediction_models/gnn_predictor.py +++ b/chebifier/prediction_models/gnn_predictor.py @@ -1,15 +1,11 @@ -import chebai_graph.preprocessing.properties as p -import torch -from chebai_graph.models.graph import ResGatedGraphConvNetGraphPred -from chebai_graph.preprocessing.property_encoder import IndexEncoder, OneHotEncoder -from chebai_graph.preprocessing.reader import GraphPropertyReader -from torch_geometric.data.data import Data as GeomData - from .nn_predictor import NNPredictor class ResGatedPredictor(NNPredictor): def __init__(self, model_name: str, ckpt_path: str, molecular_properties, **kwargs): + from chebai_graph.preprocessing.properties import MolecularProperty + from chebai_graph.preprocessing.reader import GraphPropertyReader + super().__init__( model_name, ckpt_path, reader_cls=GraphPropertyReader, **kwargs ) @@ -23,7 +19,7 @@ def __init__(self, model_name: str, ckpt_path: str, molecular_properties, **kwar properties = [] self.molecular_properties = properties assert isinstance(self.molecular_properties, list) and all( - isinstance(prop, p.MolecularProperty) for prop in self.molecular_properties + isinstance(prop, MolecularProperty) for prop in self.molecular_properties ) print(f"Initialised GNN model {self.model_name} (device: {self.device})") @@ -32,7 +28,12 @@ def load_class(self, class_path: str): module = __import__(module_path, fromlist=[class_name]) return getattr(module, class_name) - def init_model(self, ckpt_path: str, **kwargs) -> ResGatedGraphConvNetGraphPred: + def init_model( + self, ckpt_path: str, **kwargs + ) -> "ResGatedGraphConvNetGraphPred": # noqa: F821 + import torch + from chebai_graph.models.graph import ResGatedGraphConvNetGraphPred + model = ResGatedGraphConvNetGraphPred.load_from_checkpoint( ckpt_path, map_location=torch.device(self.device), @@ -45,6 +46,14 @@ def init_model(self, ckpt_path: str, **kwargs) -> ResGatedGraphConvNetGraphPred: return model def read_smiles(self, smiles): + import torch + from chebai_graph.preprocessing.properties import AtomProperty, BondProperty + from chebai_graph.preprocessing.property_encoder import ( + IndexEncoder, + OneHotEncoder, + ) + from torch_geometric.data.data import Data as GeomData + reader = self.reader_cls() d = reader.to_data(dict(features=smiles, labels=None)) geom_data = d["features"] @@ -87,9 +96,9 @@ def read_smiles(self, smiles): encoded_values = encoded_values.unsqueeze(1) else: encoded_values = torch.zeros((0, prop.encoder.get_encoding_length())) - if isinstance(prop, p.AtomProperty): + if isinstance(prop, AtomProperty): x = torch.cat([x, encoded_values], dim=1) - elif isinstance(prop, p.BondProperty): + elif isinstance(prop, BondProperty): edge_attr = torch.cat([edge_attr, encoded_values], dim=1) else: molecule_attr = torch.cat([molecule_attr, encoded_values[0]], dim=1) diff --git a/chebifier/prediction_models/nn_predictor.py b/chebifier/prediction_models/nn_predictor.py index e7d72c9..53e2b8c 100644 --- a/chebifier/prediction_models/nn_predictor.py +++ b/chebifier/prediction_models/nn_predictor.py @@ -1,7 +1,6 @@ from functools import lru_cache import numpy as np -import torch import tqdm from rdkit import Chem @@ -17,6 +16,8 @@ def __init__( target_labels_path: str, **kwargs, ): + import torch + super().__init__(model_name, **kwargs) self.reader_cls = reader_cls @@ -56,6 +57,8 @@ def read_smiles(self, smiles): def predict_smiles_tuple(self, smiles_list: tuple[str]) -> list: """Returns a list with the length of smiles_list, each element is either None (=failure) or a dictionary Of classes and predicted values.""" + import torch + token_dicts = [] could_not_parse = [] index_map = dict() From 68ea5772663a99020b86b7211c0ee4208d08b8b8 Mon Sep 17 00:00:00 2001 From: aditya0by0 Date: Wed, 30 Jul 2025 00:03:39 +0200 Subject: [PATCH 2/9] update pyproject --- pyproject.toml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f01efe9..aa2a96d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,14 +20,15 @@ classifiers = [ dependencies = [ "click", "pyyaml", - "torch", "tqdm", "rdkit", - "chebai>=1.0.1", - "chemlog>=1.0.4", + # Package to install manually if required + #"chebai>=1.0.1", + #"chemlog>=1.0.4", + # pypi does not support git dependencies #"chemlog_extra @ git+https://github.com/ChEB-AI/chemlog-extra.git", - "c3p" + # forked version of c3p is windows-compatible #"c3p @ git+https://github.com/sfluegel05/c3p.git" ] From 1bd6a0b28a1dfd29b54ee8291fded1802bf2e774 Mon Sep 17 00:00:00 2001 From: aditya0by0 Date: Sat, 9 Aug 2025 11:47:07 +0200 Subject: [PATCH 3/9] dynamic imports for rest of predictors --- chebifier/prediction_models/__init__.py | 6 ++- chebifier/prediction_models/c3p_predictor.py | 8 +-- chebifier/prediction_models/chebi_lookup.py | 14 ++--- .../prediction_models/chemlog_predictor.py | 54 +++++++++++-------- .../prediction_models/electra_predictor.py | 7 ++- chebifier/prediction_models/gnn_predictor.py | 9 ++-- 6 files changed, 62 insertions(+), 36 deletions(-) diff --git a/chebifier/prediction_models/__init__.py b/chebifier/prediction_models/__init__.py index 51fa6d6..bc29580 100644 --- a/chebifier/prediction_models/__init__.py +++ b/chebifier/prediction_models/__init__.py @@ -1,8 +1,9 @@ from .base_predictor import BasePredictor -from .chemlog_predictor import ChemlogPeptidesPredictor, ChemlogExtraPredictor +from .c3p_predictor import C3PPredictor +from .chebi_lookup import ChEBILookupPredictor +from .chemlog_predictor import ChemlogExtraPredictor, ChemlogPeptidesPredictor from .electra_predictor import ElectraPredictor from .gnn_predictor import ResGatedPredictor -from .chebi_lookup import ChEBILookupPredictor __all__ = [ "BasePredictor", @@ -11,4 +12,5 @@ "ResGatedPredictor", "ChEBILookupPredictor", "ChemlogExtraPredictor", + "C3PPredictor", ] diff --git a/chebifier/prediction_models/c3p_predictor.py b/chebifier/prediction_models/c3p_predictor.py index 00c71f7..4a28c87 100644 --- a/chebifier/prediction_models/c3p_predictor.py +++ b/chebifier/prediction_models/c3p_predictor.py @@ -1,8 +1,6 @@ from functools import lru_cache -from typing import Optional, List from pathlib import Path - -from c3p import classifier as c3p_classifier +from typing import List, Optional from chebifier.prediction_models import BasePredictor @@ -26,6 +24,8 @@ def __init__( @lru_cache(maxsize=100) def predict_smiles_tuple(self, smiles_list: tuple[str]) -> list: + from c3p import classifier as c3p_classifier + result_list = c3p_classifier.classify( list(smiles_list), self.program_directory, @@ -50,6 +50,8 @@ def explain_smiles(self, smiles): C3P provides natural language explanations for each prediction (positive or negative). Since there are more than 300 classes, only take the positive ones. """ + from c3p import classifier as c3p_classifier + highlights = [] result_list = c3p_classifier.classify( [smiles], self.program_directory, self.chemical_classes, strict=False diff --git a/chebifier/prediction_models/chebi_lookup.py b/chebifier/prediction_models/chebi_lookup.py index f314bf5..e582279 100644 --- a/chebifier/prediction_models/chebi_lookup.py +++ b/chebifier/prediction_models/chebi_lookup.py @@ -1,15 +1,14 @@ +import json +import os from functools import lru_cache from typing import Optional -from chebifier.prediction_models import BasePredictor -import os -import networkx as nx from rdkit import Chem -import json +from chebifier.prediction_models import BasePredictor -class ChEBILookupPredictor(BasePredictor): +class ChEBILookupPredictor(BasePredictor): def __init__( self, model_name: str, @@ -49,6 +48,8 @@ def get_smiles_lookup(self): return smiles_lookup def build_smiles_lookup(self): + import networkx as nx + smiles_lookup = dict() for chebi_id, smiles in nx.get_node_attributes( self.chebi_graph, "smiles" @@ -152,7 +153,8 @@ def explain_smiles(self, smiles: str) -> dict: # Example usage smiles_list = [ "CCO", - "C1=CC=CC=C1" "*C(=O)OC[C@H](COP(=O)([O-])OCC[N+](C)(C)C)OC(*)=O", + "C1=CC=CC=C1", + "*C(=O)OC[C@H](COP(=O)([O-])OCC[N+](C)(C)C)OC(*)=O", ] # SMILES with 251 matches in ChEBI predictions = predictor.predict_smiles_list(smiles_list) print(predictions) diff --git a/chebifier/prediction_models/chemlog_predictor.py b/chebifier/prediction_models/chemlog_predictor.py index 8232641..a450cfc 100644 --- a/chebifier/prediction_models/chemlog_predictor.py +++ b/chebifier/prediction_models/chemlog_predictor.py @@ -1,21 +1,7 @@ +from functools import lru_cache from typing import Optional import tqdm -from chemlog.alg_classification.charge_classifier import get_charge_category -from chemlog.alg_classification.peptide_size_classifier import get_n_amino_acid_residues -from chemlog.alg_classification.proteinogenics_classifier import ( - get_proteinogenic_amino_acids, -) -from chemlog.alg_classification.substructure_classifier import ( - is_diketopiperazine, - is_emericellamide, -) -from chemlog.cli import CLASSIFIERS, _smiles_to_mol, strategy_call -from chemlog_extra.alg_classification.by_element_classification import ( - XMolecularEntityClassifier, - OrganoXCompoundClassifier, -) -from functools import lru_cache from .base_predictor import BasePredictor @@ -47,15 +33,14 @@ class ChemlogExtraPredictor(BasePredictor): - - CHEMLOG_CLASSIFIER = None - def __init__(self, model_name: str, **kwargs): super().__init__(model_name, **kwargs) self.chebi_graph = kwargs.get("chebi_graph", None) - self.classifier = self.CHEMLOG_CLASSIFIER() + self.classifier = None def predict_smiles_tuple(self, smiles_list: tuple[str]) -> list: + from chemlog.cli import _smiles_to_mol + mol_list = [_smiles_to_mol(smiles) for smiles in smiles_list] res = self.classifier.classify(mol_list) if self.chebi_graph is not None: @@ -72,17 +57,29 @@ def predict_smiles_tuple(self, smiles_list: tuple[str]) -> list: class ChemlogXMolecularEntityPredictor(ChemlogExtraPredictor): + def __init__(self, model_name: str, **kwargs): + from chemlog_extra.alg_classification.by_element_classification import ( + XMolecularEntityClassifier, + ) - CHEMLOG_CLASSIFIER = XMolecularEntityClassifier + super().__init__(model_name, **kwargs) + self.classifier = XMolecularEntityClassifier() class ChemlogOrganoXCompoundPredictor(ChemlogExtraPredictor): + def __init__(self, model_name: str, **kwargs): + from chemlog_extra.alg_classification.by_element_classification import ( + OrganoXCompoundClassifier, + ) - CHEMLOG_CLASSIFIER = OrganoXCompoundClassifier + super().__init__(model_name, **kwargs) + self.classifier = OrganoXCompoundClassifier() class ChemlogPeptidesPredictor(BasePredictor): def __init__(self, model_name: str, **kwargs): + from chemlog.cli import CLASSIFIERS + super().__init__(model_name, **kwargs) self.strategy = "algo" self.chebi_graph = kwargs.get("chebi_graph", None) @@ -99,6 +96,8 @@ def __init__(self, model_name: str, **kwargs): @lru_cache(maxsize=100) def predict_smiles(self, smiles: str) -> Optional[dict]: + from chemlog.cli import _smiles_to_mol, strategy_call + mol = _smiles_to_mol(smiles) if mol is None: return None @@ -134,6 +133,19 @@ def predict_smiles_tuple(self, smiles_list: tuple[str]) -> list: def get_chemlog_result_info(self, smiles): """Get classification for single molecule with additional information.""" + from chemlog.alg_classification.charge_classifier import get_charge_category + from chemlog.alg_classification.peptide_size_classifier import ( + get_n_amino_acid_residues, + ) + from chemlog.alg_classification.proteinogenics_classifier import ( + get_proteinogenic_amino_acids, + ) + from chemlog.alg_classification.substructure_classifier import ( + is_diketopiperazine, + is_emericellamide, + ) + from chemlog.cli import _smiles_to_mol + mol = _smiles_to_mol(smiles) if mol is None or not smiles: return {"error": "Failed to parse SMILES"} diff --git a/chebifier/prediction_models/electra_predictor.py b/chebifier/prediction_models/electra_predictor.py index f73034e..ab01616 100644 --- a/chebifier/prediction_models/electra_predictor.py +++ b/chebifier/prediction_models/electra_predictor.py @@ -1,7 +1,12 @@ +from typing import TYPE_CHECKING + import numpy as np from .nn_predictor import NNPredictor +if TYPE_CHECKING: + from chebai.models.electra import Electra + def build_graph_from_attention(att, node_labels, token_labels, threshold=0.0): n_nodes = len(node_labels) @@ -40,7 +45,7 @@ def __init__(self, model_name: str, ckpt_path: str, **kwargs): super().__init__(model_name, ckpt_path, reader_cls=ChemDataReader, **kwargs) print(f"Initialised Electra model {self.model_name} (device: {self.device})") - def init_model(self, ckpt_path: str, **kwargs) -> "Electra": # noqa: F821 + def init_model(self, ckpt_path: str, **kwargs) -> Electra: from chebai.models.electra import Electra model = Electra.load_from_checkpoint( diff --git a/chebifier/prediction_models/gnn_predictor.py b/chebifier/prediction_models/gnn_predictor.py index 4ccfef9..f4df013 100644 --- a/chebifier/prediction_models/gnn_predictor.py +++ b/chebifier/prediction_models/gnn_predictor.py @@ -1,5 +1,10 @@ +from typing import TYPE_CHECKING + from .nn_predictor import NNPredictor +if TYPE_CHECKING: + from chebai_graph.models.graph import ResGatedGraphConvNetGraphPred + class ResGatedPredictor(NNPredictor): def __init__(self, model_name: str, ckpt_path: str, molecular_properties, **kwargs): @@ -28,9 +33,7 @@ def load_class(self, class_path: str): module = __import__(module_path, fromlist=[class_name]) return getattr(module, class_name) - def init_model( - self, ckpt_path: str, **kwargs - ) -> "ResGatedGraphConvNetGraphPred": # noqa: F821 + def init_model(self, ckpt_path: str, **kwargs) -> ResGatedGraphConvNetGraphPred: import torch from chebai_graph.models.graph import ResGatedGraphConvNetGraphPred From 50df35739c95db6e408449441940a04ace99793a Mon Sep 17 00:00:00 2001 From: aditya0by0 Date: Sat, 9 Aug 2025 12:19:51 +0200 Subject: [PATCH 4/9] return types in quotes --- chebifier/prediction_models/electra_predictor.py | 2 +- chebifier/prediction_models/gnn_predictor.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/chebifier/prediction_models/electra_predictor.py b/chebifier/prediction_models/electra_predictor.py index ab01616..4843cad 100644 --- a/chebifier/prediction_models/electra_predictor.py +++ b/chebifier/prediction_models/electra_predictor.py @@ -45,7 +45,7 @@ def __init__(self, model_name: str, ckpt_path: str, **kwargs): super().__init__(model_name, ckpt_path, reader_cls=ChemDataReader, **kwargs) print(f"Initialised Electra model {self.model_name} (device: {self.device})") - def init_model(self, ckpt_path: str, **kwargs) -> Electra: + def init_model(self, ckpt_path: str, **kwargs) -> "Electra": from chebai.models.electra import Electra model = Electra.load_from_checkpoint( diff --git a/chebifier/prediction_models/gnn_predictor.py b/chebifier/prediction_models/gnn_predictor.py index f4df013..6d2a1a5 100644 --- a/chebifier/prediction_models/gnn_predictor.py +++ b/chebifier/prediction_models/gnn_predictor.py @@ -33,7 +33,7 @@ def load_class(self, class_path: str): module = __import__(module_path, fromlist=[class_name]) return getattr(module, class_name) - def init_model(self, ckpt_path: str, **kwargs) -> ResGatedGraphConvNetGraphPred: + def init_model(self, ckpt_path: str, **kwargs) -> "ResGatedGraphConvNetGraphPred": import torch from chebai_graph.models.graph import ResGatedGraphConvNetGraphPred From 6301d8fc67a4ab51ca7f6e277c47b673de3c097f Mon Sep 17 00:00:00 2001 From: sfluegel Date: Mon, 11 Aug 2025 13:37:42 +0200 Subject: [PATCH 5/9] fix cache import --- chebifier/prediction_models/chemlog_predictor.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chebifier/prediction_models/chemlog_predictor.py b/chebifier/prediction_models/chemlog_predictor.py index 1248958..5a402d1 100644 --- a/chebifier/prediction_models/chemlog_predictor.py +++ b/chebifier/prediction_models/chemlog_predictor.py @@ -1,9 +1,9 @@ -from functools import lru_cache from typing import Optional import tqdm from .base_predictor import BasePredictor +from .. import modelwise_smiles_lru_cache AA_DICT = { "A": "L-alanine", @@ -33,7 +33,7 @@ class ChemlogExtraPredictor(BasePredictor): - + def __init__(self, model_name: str, **kwargs): super().__init__(model_name, **kwargs) self.chebi_graph = kwargs.get("chebi_graph", None) @@ -42,6 +42,7 @@ def __init__(self, model_name: str, **kwargs): @modelwise_smiles_lru_cache.batch_decorator def predict_smiles_list(self, smiles_list: list[str]) -> list: from chemlog.cli import _smiles_to_mol + mol_list = [_smiles_to_mol(smiles) for smiles in smiles_list] res = self.classifier.classify(mol_list) if self.chebi_graph is not None: From e541f08697c9d7e5b8c1c530da4d12d9d4e98199 Mon Sep 17 00:00:00 2001 From: sfluegel Date: Mon, 11 Aug 2025 13:38:57 +0200 Subject: [PATCH 6/9] fix line indentation --- chebifier/prediction_models/c3p_predictor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chebifier/prediction_models/c3p_predictor.py b/chebifier/prediction_models/c3p_predictor.py index e1fa8d6..b1a7893 100644 --- a/chebifier/prediction_models/c3p_predictor.py +++ b/chebifier/prediction_models/c3p_predictor.py @@ -26,7 +26,7 @@ def __init__( @modelwise_smiles_lru_cache.batch_decorator def predict_smiles_list(self, smiles_list: list[str]) -> list: - from c3p import classifier as c3p_classifier + from c3p import classifier as c3p_classifier result_list = c3p_classifier.classify( list(smiles_list), self.program_directory, From 26793227f547deb1625f0dd753e80b7b4a85ee55 Mon Sep 17 00:00:00 2001 From: sfluegel Date: Mon, 11 Aug 2025 13:39:40 +0200 Subject: [PATCH 7/9] reformat with black --- chebifier/prediction_models/c3p_predictor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chebifier/prediction_models/c3p_predictor.py b/chebifier/prediction_models/c3p_predictor.py index b1a7893..9bf31e0 100644 --- a/chebifier/prediction_models/c3p_predictor.py +++ b/chebifier/prediction_models/c3p_predictor.py @@ -23,10 +23,11 @@ def __init__( self.program_directory = program_directory self.chemical_classes = chemical_classes self.chebi_graph = kwargs.get("chebi_graph", None) - + @modelwise_smiles_lru_cache.batch_decorator def predict_smiles_list(self, smiles_list: list[str]) -> list: from c3p import classifier as c3p_classifier + result_list = c3p_classifier.classify( list(smiles_list), self.program_directory, From 9dd5102dc76cc55ce967b2ab8cc5db393653b88b Mon Sep 17 00:00:00 2001 From: sfluegel Date: Mon, 11 Aug 2025 13:41:58 +0200 Subject: [PATCH 8/9] fix imports --- chebifier/prediction_models/c3p_predictor.py | 2 -- chebifier/prediction_models/chebi_lookup.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/chebifier/prediction_models/c3p_predictor.py b/chebifier/prediction_models/c3p_predictor.py index 9bf31e0..4ef58a3 100644 --- a/chebifier/prediction_models/c3p_predictor.py +++ b/chebifier/prediction_models/c3p_predictor.py @@ -1,8 +1,6 @@ from pathlib import Path from typing import List, Optional -from c3p import classifier as c3p_classifier - from chebifier import modelwise_smiles_lru_cache from chebifier.prediction_models import BasePredictor diff --git a/chebifier/prediction_models/chebi_lookup.py b/chebifier/prediction_models/chebi_lookup.py index cbd3daa..fa25271 100644 --- a/chebifier/prediction_models/chebi_lookup.py +++ b/chebifier/prediction_models/chebi_lookup.py @@ -8,7 +8,6 @@ from chebifier.prediction_models import BasePredictor from chebifier.utils import load_chebi_graph -from chebifier.prediction_models import BasePredictor class ChEBILookupPredictor(BasePredictor): @@ -19,7 +18,6 @@ def __init__( chebi_version: int = 241, **kwargs, ): - from chebifier.utils import load_chebi_graph super().__init__(model_name, **kwargs) self._description = ( From 92aba6300f47370c0a73011843174ee65c7b6596 Mon Sep 17 00:00:00 2001 From: sfluegel Date: Mon, 11 Aug 2025 13:42:44 +0200 Subject: [PATCH 9/9] reformat with black --- chebifier/prediction_models/chebi_lookup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/chebifier/prediction_models/chebi_lookup.py b/chebifier/prediction_models/chebi_lookup.py index fa25271..c8ad75a 100644 --- a/chebifier/prediction_models/chebi_lookup.py +++ b/chebifier/prediction_models/chebi_lookup.py @@ -9,7 +9,6 @@ from chebifier.utils import load_chebi_graph - class ChEBILookupPredictor(BasePredictor): def __init__( self,