nerdd-module 0.3.13__tar.gz → 0.3.15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/PKG-INFO +1 -1
  2. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/models.py +2 -0
  3. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/converters/__init__.py +2 -1
  4. nerdd_module-0.3.13/nerdd_module/converters/identity_converter.py → nerdd_module-0.3.15/nerdd_module/converters/basic_type_converter.py +4 -4
  5. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/converters/converter.py +1 -1
  6. nerdd_module-0.3.15/nerdd_module/converters/mol_converter.py +24 -0
  7. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/converters/mol_to_image_converter.py +4 -4
  8. nerdd_module-0.3.15/nerdd_module/converters/representation_converter.py +42 -0
  9. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/inchi_reader.py +2 -2
  10. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/sdf_reader.py +2 -2
  11. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/smiles_reader.py +2 -2
  12. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/convert_representations_step.py +5 -1
  13. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/simple_model.py +42 -8
  14. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/sdf_writer.py +13 -4
  15. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/polyfills/__init__.py +1 -0
  16. nerdd_module-0.3.15/nerdd_module/polyfills/block_logs.py +45 -0
  17. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/chembl_structure_pipeline.py +11 -17
  18. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/models/AtomicMassModel.py +2 -0
  19. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/models/MolWeightModel.py +3 -2
  20. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/representations.py +6 -2
  21. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module.egg-info/PKG-INFO +1 -1
  22. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module.egg-info/SOURCES.txt +3 -1
  23. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/pyproject.toml +1 -1
  24. nerdd_module-0.3.13/nerdd_module/converters/mol_converter.py +0 -41
  25. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/LICENSE +0 -0
  26. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/README.md +0 -0
  27. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/__init__.py +0 -0
  28. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/cli.py +0 -0
  29. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/__init__.py +0 -0
  30. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/configuration.py +0 -0
  31. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/default_configuration.py +0 -0
  32. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/dict_configuration.py +0 -0
  33. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/merged_configuration.py +0 -0
  34. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/package_configuration.py +0 -0
  35. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/search_yaml_configuration.py +0 -0
  36. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/config/yaml_configuration.py +0 -0
  37. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/converters/converter_config.py +0 -0
  38. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/converters/problem_list_converter.py +0 -0
  39. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/converters/void_converter.py +0 -0
  40. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/__init__.py +0 -0
  41. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/depth_first_explorer.py +0 -0
  42. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/explorer.py +0 -0
  43. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/file_reader.py +0 -0
  44. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/gzip_reader.py +0 -0
  45. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/list_reader.py +0 -0
  46. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/mol_reader.py +0 -0
  47. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/reader.py +0 -0
  48. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/reader_config.py +0 -0
  49. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/string_reader.py +0 -0
  50. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/tar_reader.py +0 -0
  51. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/input/zip_reader.py +0 -0
  52. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/__init__.py +0 -0
  53. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/assign_mol_id_step.py +0 -0
  54. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/assign_name_step.py +0 -0
  55. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/enforce_schema_step.py +0 -0
  56. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/model.py +0 -0
  57. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/read_input_step.py +0 -0
  58. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/model/write_output_step.py +0 -0
  59. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/__init__.py +0 -0
  60. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/csv_writer.py +0 -0
  61. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/file_writer.py +0 -0
  62. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/iterator_writer.py +0 -0
  63. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/pandas_writer.py +0 -0
  64. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/record_list_writer.py +0 -0
  65. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/output/writer.py +0 -0
  66. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/polyfills/files.py +0 -0
  67. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/polyfills/get_entry_points.py +0 -0
  68. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/polyfills/literal.py +0 -0
  69. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/polyfills/typed_dict.py +0 -0
  70. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/polyfills/types.py +0 -0
  71. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/polyfills/version.py +0 -0
  72. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/__init__.py +0 -0
  73. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/check_valid_smiles.py +0 -0
  74. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/filter_by_element.py +0 -0
  75. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/filter_by_weight.py +0 -0
  76. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/preprocessing_step.py +0 -0
  77. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/remove_stereochemistry.py +0 -0
  78. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/preprocessing/sanitize.py +0 -0
  79. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/problem.py +0 -0
  80. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/py.typed +0 -0
  81. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/steps/__init__.py +0 -0
  82. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/steps/map_step.py +0 -0
  83. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/steps/output_step.py +0 -0
  84. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/steps/step.py +0 -0
  85. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/__init__.py +0 -0
  86. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/checks.py +0 -0
  87. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/files.py +0 -0
  88. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/models/__init__.py +0 -0
  89. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/predictions.py +0 -0
  90. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/preprocessing/DummyPreprocessingStep.py +0 -0
  91. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/tests/preprocessing/__init__.py +0 -0
  92. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/util/__init__.py +0 -0
  93. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/util/call_with_mappings.py +0 -0
  94. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/util/package.py +0 -0
  95. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module/version.py +0 -0
  96. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module.egg-info/dependency_links.txt +0 -0
  97. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module.egg-info/requires.txt +0 -0
  98. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/nerdd_module.egg-info/top_level.txt +0 -0
  99. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/setup.cfg +0 -0
  100. {nerdd_module-0.3.13 → nerdd_module-0.3.15}/tests/test_features.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nerdd-module
3
- Version: 0.3.13
3
+ Version: 0.3.15
4
4
  Summary: Base package to create NERDD modules
5
5
  Author-email: Steffen Hirte <steffen.hirte@univie.ac.at>
6
6
  Maintainer-email: Steffen Hirte <steffen.hirte@univie.ac.at>
@@ -71,12 +71,14 @@ class ResultProperty(BaseModel):
71
71
  name: str
72
72
  type: str
73
73
  visible_name: Optional[str] = None
74
+ visible: bool = True
74
75
  help_text: Optional[str] = None
75
76
  sortable: bool = False
76
77
  group: Optional[str] = None
77
78
  level: Level = "molecule"
78
79
  formats: Union[FormatSpec, IncludeExcludeFormatSpec, None] = None
79
80
  representation: Optional[str] = None
81
+ from_property: Optional[str] = None
80
82
  image_width: Optional[int] = None
81
83
  image_height: Optional[int] = None
82
84
 
@@ -1,7 +1,8 @@
1
+ from .basic_type_converter import *
1
2
  from .converter import *
2
3
  from .converter_config import *
3
- from .identity_converter import *
4
4
  from .mol_converter import *
5
5
  from .mol_to_image_converter import *
6
6
  from .problem_list_converter import *
7
+ from .representation_converter import *
7
8
  from .void_converter import *
@@ -3,9 +3,9 @@ from typing import Any
3
3
  from .converter import Converter
4
4
  from .converter_config import ALL, ConverterConfig
5
5
 
6
- __all__ = ["IdentityConverter", "primitive_data_types"]
6
+ __all__ = ["BasicTypeConverter", "basic_data_types"]
7
7
 
8
- primitive_data_types = [
8
+ basic_data_types = [
9
9
  "int",
10
10
  "float",
11
11
  "string",
@@ -13,11 +13,11 @@ primitive_data_types = [
13
13
  ]
14
14
 
15
15
 
16
- class IdentityConverter(Converter):
16
+ class BasicTypeConverter(Converter):
17
17
  def _convert(self, input: Any, context: dict) -> Any:
18
18
  return input
19
19
 
20
20
  config = ConverterConfig(
21
- data_types=primitive_data_types,
21
+ data_types=basic_data_types,
22
22
  output_formats=ALL,
23
23
  )
@@ -25,7 +25,7 @@ class Converter(ABC):
25
25
 
26
26
  def __init__(self, result_property: ResultProperty, output_format: str, **kwargs: Any) -> None:
27
27
  super().__init__()
28
- self.property = result_property
28
+ self.result_property = result_property
29
29
  self.output_format = output_format
30
30
 
31
31
  @classmethod
@@ -0,0 +1,24 @@
1
+ from typing import Any
2
+
3
+ from ..config import ResultProperty
4
+ from .converter import Converter
5
+ from .converter_config import ConverterConfig
6
+
7
+ __all__ = ["MolConverter"]
8
+
9
+
10
+ class MolConverter(Converter):
11
+ def __init__(self, result_property: ResultProperty, output_format: str, **kwargs: Any) -> None:
12
+ super().__init__(result_property, output_format, **kwargs)
13
+
14
+ def _convert(self, input: Any, context: dict) -> Any:
15
+ if self.output_format == "sdf" and self.result_property.name != "input_mol":
16
+ # in an SDF, the main molecule (input_mol) can be a Mol object
17
+ return Converter.HIDE
18
+ elif self.output_format in ["sdf", "pandas", "record_list", "iterator"]:
19
+ return input
20
+
21
+ config = ConverterConfig(
22
+ data_types="mol",
23
+ output_formats=["sdf", "pandas", "record_list", "iterator"],
24
+ )
@@ -9,14 +9,14 @@ from .converter_config import ConverterConfig
9
9
 
10
10
  __all__ = ["MolToImageConverter"]
11
11
 
12
- default_width = 400
13
- default_height = 300
12
+ default_width = 300
13
+ default_height = 180
14
14
 
15
15
 
16
16
  class MolToImageConverter(Converter):
17
17
  def _convert(self, input: Any, context: dict) -> Any:
18
- width = self.property.image_width
19
- height = self.property.image_height
18
+ width = self.result_property.image_width
19
+ height = self.result_property.image_height
20
20
 
21
21
  if width is None:
22
22
  width = default_width
@@ -0,0 +1,42 @@
1
+ from typing import Any
2
+
3
+ from rdkit.Chem import MolToInchi, MolToSmiles
4
+
5
+ from ..config import ResultProperty
6
+ from .converter import Converter
7
+ from .converter_config import ALL, ConverterConfig
8
+
9
+ __all__ = ["RepresentationConverter"]
10
+
11
+
12
+ class RepresentationConverter(Converter):
13
+ def __init__(self, result_property: ResultProperty, output_format: str, **kwargs: Any) -> None:
14
+ super().__init__(result_property, output_format, **kwargs)
15
+
16
+ representation = result_property.representation or "smiles"
17
+ if representation == "inchi":
18
+ self._serialize = MolToInchi
19
+ elif representation == "smiles":
20
+ self._serialize = MolToSmiles
21
+ else:
22
+ raise ValueError(f"Unsupported representation: {representation}")
23
+
24
+ def _convert(self, input: Any, context: dict) -> Any:
25
+ from_property = self.result_property.from_property
26
+
27
+ if from_property is None:
28
+ actual_input = input
29
+ else:
30
+ actual_input = context[from_property]
31
+
32
+ try:
33
+ representation = self._serialize(actual_input)
34
+ except: # noqa: E722 (allow bare except, because RDKit is unpredictable)
35
+ representation = None
36
+
37
+ return representation
38
+
39
+ config = ConverterConfig(
40
+ data_types="representation",
41
+ output_formats=ALL,
42
+ )
@@ -2,8 +2,8 @@ from codecs import getreader
2
2
  from typing import Any, Iterator
3
3
 
4
4
  from rdkit.Chem import MolFromInchi
5
- from rdkit.rdBase import BlockLogs
6
5
 
6
+ from ..polyfills import BlockLogs
7
7
  from ..problem import Problem
8
8
  from .reader import ExploreCallable, MoleculeEntry, Reader
9
9
  from .reader_config import ReaderConfig
@@ -47,7 +47,7 @@ class InchiReader(Reader):
47
47
  errors = []
48
48
 
49
49
  yield MoleculeEntry(
50
- raw_input=line,
50
+ raw_input=line.strip("\n"),
51
51
  input_type="inchi",
52
52
  source=("raw_input",),
53
53
  mol=mol,
@@ -2,8 +2,8 @@ from codecs import getreader
2
2
  from typing import Any, Iterator
3
3
 
4
4
  from rdkit.Chem import MolFromMolBlock
5
- from rdkit.rdBase import BlockLogs
6
5
 
6
+ from ..polyfills import BlockLogs
7
7
  from ..problem import Problem
8
8
  from .reader import ExploreCallable, MoleculeEntry, Reader
9
9
 
@@ -59,7 +59,7 @@ class SdfReader(Reader):
59
59
  errors = []
60
60
 
61
61
  yield MoleculeEntry(
62
- raw_input=mol_block,
62
+ raw_input=mol_block.strip("\n"),
63
63
  input_type="mol_block",
64
64
  source=("raw_input",),
65
65
  mol=mol,
@@ -2,8 +2,8 @@ from codecs import getreader
2
2
  from typing import Any, Iterator
3
3
 
4
4
  from rdkit.Chem import MolFromSmiles
5
- from rdkit.rdBase import BlockLogs
6
5
 
6
+ from ..polyfills import BlockLogs
7
7
  from ..problem import Problem
8
8
  from .reader import ExploreCallable, MoleculeEntry, Reader
9
9
  from .reader_config import ReaderConfig
@@ -57,7 +57,7 @@ class SmilesReader(Reader):
57
57
  errors = []
58
58
 
59
59
  yield MoleculeEntry(
60
- raw_input=line,
60
+ raw_input=line.strip("\n"),
61
61
  input_type="smiles",
62
62
  source=("raw_input",),
63
63
  mol=mol,
@@ -12,13 +12,17 @@ class ConvertRepresentationsStep(MapStep):
12
12
  self, result_properties: List[ResultProperty], output_format: str, **kwargs: Any
13
13
  ) -> None:
14
14
  super().__init__()
15
+ self._result_properties = result_properties
15
16
  self._converter_map = {
16
17
  p.name: Converter.get_converter(p, output_format, **kwargs) for p in result_properties
17
18
  }
18
19
 
19
20
  def _process(self, record: dict) -> dict:
20
21
  result = {
21
- k: self._converter_map[k].convert(input=v, context=record) for k, v in record.items()
22
+ k.name: self._converter_map[k.name].convert(
23
+ input=record.get(k.name, None), context=record
24
+ )
25
+ for k in self._result_properties
22
26
  }
23
27
 
24
28
  return {k: v for k, v in result.items() if v is not Converter.HIDE}
@@ -113,26 +113,60 @@ class SimpleModel(Model):
113
113
  task_based_property = []
114
114
  if task == "atom_property_prediction":
115
115
  task_based_property = [
116
- {"name": "atom_id", "type": "int"},
116
+ {"name": "atom_id", "type": "int", "visible": False},
117
117
  ]
118
118
  elif task == "derivative_property_prediction":
119
119
  task_based_property = [
120
- {"name": "derivative_id", "type": "int"},
120
+ {"name": "derivative_id", "type": "int", "visible": False},
121
121
  ]
122
122
 
123
123
  default_properties_start = [
124
- {"name": "mol_id", "type": "int"},
124
+ {"name": "mol_id", "type": "int", "visible": False},
125
125
  *task_based_property,
126
- {"name": "input_text", "visible_name": "Input text", "type": "string"},
127
- {"name": "input_type", "visible_name": "Input type", "type": "string"},
128
- {"name": "source", "visible_name": "Source", "type": "string"},
126
+ {
127
+ "name": "input_text",
128
+ "visible_name": "Input text",
129
+ "type": "string",
130
+ "visible": False,
131
+ },
132
+ {
133
+ "name": "input_type",
134
+ "visible_name": "Input type",
135
+ "type": "string",
136
+ "visible": False,
137
+ },
138
+ {
139
+ "name": "source",
140
+ "visible_name": "Source",
141
+ "type": "string",
142
+ "visible": False,
143
+ },
129
144
  {"name": "name", "visible_name": "Name", "type": "string"},
130
- {"name": "input_mol", "visible_name": "Input SMILES", "type": "mol"},
145
+ {
146
+ "name": "input_mol",
147
+ "visible_name": "Input Structure",
148
+ "type": "mol",
149
+ "visible": False,
150
+ },
151
+ {
152
+ "name": "input_smiles",
153
+ "visible_name": "Input SMILES",
154
+ "type": "representation",
155
+ "from_property": "input_mol",
156
+ "visible": False,
157
+ },
131
158
  {
132
159
  "name": "preprocessed_mol",
133
- "visible_name": "Preprocessed SMILES",
160
+ "visible_name": "Preprocessed Structure",
134
161
  "type": "mol",
135
162
  },
163
+ {
164
+ "name": "preprocessed_smiles",
165
+ "visible_name": "Preprocessed SMILES",
166
+ "type": "representation",
167
+ "from_property": "preprocessed_mol",
168
+ "visible": False,
169
+ },
136
170
  ]
137
171
 
138
172
  default_properties_end = [
@@ -1,6 +1,6 @@
1
1
  from typing import IO, Any, Dict, Iterable
2
2
 
3
- from rdkit.Chem import SDWriter
3
+ from rdkit.Chem import Mol, SDWriter
4
4
 
5
5
  from .file_writer import FileLike, FileWriter
6
6
 
@@ -18,13 +18,22 @@ class SdfWriter(FileWriter, output_format="sdf"):
18
18
  # assume that there is a mol object
19
19
  mol = entry["input_mol"]
20
20
 
21
+ # if the molecule is erroneous, use an empty molecule
22
+ if mol is None:
23
+ mol = Mol()
24
+
21
25
  # write (almost) all properties to the mol object
22
26
  for key, value in entry.items():
23
- value_as_str = str(value)
24
- if "\n" in value_as_str:
25
- # SDF can't write multi-line strings
27
+ # skip "input_mol" key, because we use it as the main molecule
28
+ if key == "input_mol":
26
29
  continue
27
30
 
31
+ value_as_str = str(value)
32
+
33
+ # SDF can't write multi-line strings
34
+ # -> replace newline with space
35
+ value_as_str = value_as_str.replace("\n", " ")
36
+
28
37
  mol.SetProp(key, value_as_str)
29
38
 
30
39
  # write molecule
@@ -1,3 +1,4 @@
1
+ from .block_logs import *
1
2
  from .files import *
2
3
  from .get_entry_points import *
3
4
  from .literal import *
@@ -0,0 +1,45 @@
1
+ from typing import Optional, Protocol, Type
2
+
3
+ from rdkit.rdBase import BlockLogs as OriginalBlockLogs
4
+
5
+ __all__ = ["BlockLogs"]
6
+
7
+
8
+ class BlockLogsProtocol(Protocol):
9
+ def __init__(self) -> None: ...
10
+ def __enter__(self) -> "BlockLogsProtocol": ...
11
+
12
+ def __exit__(
13
+ self,
14
+ exc_type: Optional[Type[BaseException]],
15
+ exc_val: Optional[BaseException],
16
+ exc_tb: Optional[Type[BaseException]],
17
+ ) -> None: ...
18
+
19
+
20
+ BlockLogs: Type[BlockLogsProtocol]
21
+
22
+ if hasattr(OriginalBlockLogs, "__enter__"):
23
+ BlockLogs = OriginalBlockLogs
24
+ else:
25
+ # We would like to use
26
+ # with BlockLogs(): ...
27
+ # but this does not work with old versions of RDKit. Therefore, we create an instance of
28
+ # BlockLogs that will suppress log messages as long as it exists. When it is deleted (in the
29
+ # "__exit__" block), logs are enabled again.
30
+ class CustomBlockLogs:
31
+ block_logs: Optional[OriginalBlockLogs] = None
32
+
33
+ def __enter__(self) -> BlockLogsProtocol:
34
+ self.block_logs = OriginalBlockLogs()
35
+ return self
36
+
37
+ def __exit__(
38
+ self,
39
+ exc_type: Optional[Type[BaseException]],
40
+ exc_val: Optional[BaseException],
41
+ exc_tb: Optional[Type[BaseException]],
42
+ ) -> None:
43
+ del self.block_logs
44
+
45
+ BlockLogs = CustomBlockLogs
@@ -2,8 +2,8 @@ import warnings
2
2
  from typing import List, Optional, Tuple
3
3
 
4
4
  from rdkit.Chem import Mol
5
- from rdkit.rdBase import BlockLogs
6
5
 
6
+ from ..polyfills import BlockLogs
7
7
  from ..problem import Problem
8
8
  from .preprocessing_step import PreprocessingStep
9
9
 
@@ -15,22 +15,16 @@ warnings.filterwarnings(
15
15
  )
16
16
 
17
17
  # We check if chembl_structure_pipeline is installed. Since importing this library already logs
18
- # messages, we suppress them using RDKit's BlockLogs. We would like to use
19
- # with BlockLogs(): ...
20
- # but this does not work with old versions of RDKit. Therefore, we create an instance of
21
- # BlockLogs that will suppress log messages as long as it exists. When it is deleted (in the
22
- # "finally" block), logs are enabled again.
23
- block_logs = BlockLogs()
24
- try:
25
- from chembl_structure_pipeline import get_parent_mol, standardize_mol
26
-
27
- import_error = None
28
- except ImportError as e:
29
- # raise ImportError later when using this class
30
- # --> this allows to use the rest of the package without chembl_structure_pipeline
31
- import_error = e
32
- finally:
33
- del block_logs
18
+ # messages, we suppress them using RDKit's BlockLogs.
19
+ with BlockLogs():
20
+ try:
21
+ from chembl_structure_pipeline import get_parent_mol, standardize_mol
22
+
23
+ import_error = None
24
+ except ImportError as e:
25
+ # raise ImportError later when using this class
26
+ # --> this allows to use the rest of the package without chembl_structure_pipeline
27
+ import_error = e
34
28
 
35
29
  __all__ = ["GetParentMolWithCsp", "StandardizeWithCsp"]
36
30
 
@@ -64,3 +64,5 @@ class AtomicMassModel(SimpleModel):
64
64
  {"name": "mass", "type": "float", "level": "atom"},
65
65
  ],
66
66
  }
67
+
68
+
@@ -1,6 +1,7 @@
1
+ from rdkit.Chem.rdMolDescriptors import CalcExactMolWt
2
+
1
3
  from nerdd_module import SimpleModel
2
4
  from nerdd_module.preprocessing import Sanitize
3
- from rdkit.Chem.rdMolDescriptors import CalcExactMolWt
4
5
 
5
6
  __all__ = ["MolWeightModel"]
6
7
 
@@ -47,4 +48,4 @@ class MolWeightModel(SimpleModel):
47
48
  "result_properties": [
48
49
  {"name": "weight", "type": "float"},
49
50
  ],
50
- }
51
+ }
@@ -2,12 +2,11 @@ import numpy as np
2
2
  from hypothesis import given as hgiven
3
3
  from hypothesis import seed, settings
4
4
  from hypothesis import strategies as st
5
-
6
5
  # TODO: remove "type: ignore" later
7
6
  from hypothesis_rdkit import mols # type: ignore
8
7
  from pytest_bdd import given, parsers
9
8
  from rdkit.Chem import MolToInchi, MolToMolBlock, MolToSmiles
10
- from rdkit.rdBase import BlockLogs
9
+ from ..polyfills import BlockLogs
11
10
 
12
11
 
13
12
  @given(parsers.parse("a random seed set to {seed:d}"), target_fixture="random_seed")
@@ -69,6 +68,11 @@ def molecules_with_none(num, num_none=None, random_seed=0):
69
68
 
70
69
  generate()
71
70
 
71
+ for m in result:
72
+ if m is None:
73
+ continue
74
+ m.SetProp("_Name", "mol")
75
+
72
76
  # replace random entries with None
73
77
  indices = np.random.choice(num, num_none, replace=False)
74
78
  for i in indices:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nerdd-module
3
- Version: 0.3.13
3
+ Version: 0.3.15
4
4
  Summary: Base package to create NERDD modules
5
5
  Author-email: Steffen Hirte <steffen.hirte@univie.ac.at>
6
6
  Maintainer-email: Steffen Hirte <steffen.hirte@univie.ac.at>
@@ -21,12 +21,13 @@ nerdd_module/config/package_configuration.py
21
21
  nerdd_module/config/search_yaml_configuration.py
22
22
  nerdd_module/config/yaml_configuration.py
23
23
  nerdd_module/converters/__init__.py
24
+ nerdd_module/converters/basic_type_converter.py
24
25
  nerdd_module/converters/converter.py
25
26
  nerdd_module/converters/converter_config.py
26
- nerdd_module/converters/identity_converter.py
27
27
  nerdd_module/converters/mol_converter.py
28
28
  nerdd_module/converters/mol_to_image_converter.py
29
29
  nerdd_module/converters/problem_list_converter.py
30
+ nerdd_module/converters/representation_converter.py
30
31
  nerdd_module/converters/void_converter.py
31
32
  nerdd_module/input/__init__.py
32
33
  nerdd_module/input/depth_first_explorer.py
@@ -61,6 +62,7 @@ nerdd_module/output/record_list_writer.py
61
62
  nerdd_module/output/sdf_writer.py
62
63
  nerdd_module/output/writer.py
63
64
  nerdd_module/polyfills/__init__.py
65
+ nerdd_module/polyfills/block_logs.py
64
66
  nerdd_module/polyfills/files.py
65
67
  nerdd_module/polyfills/get_entry_points.py
66
68
  nerdd_module/polyfills/literal.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "nerdd-module"
7
- version = "0.3.13"
7
+ version = "0.3.15"
8
8
  description = "Base package to create NERDD modules"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -1,41 +0,0 @@
1
- from typing import Any
2
-
3
- from rdkit.Chem import MolToInchi, MolToSmiles
4
-
5
- from ..config import ResultProperty
6
- from .converter import Converter
7
- from .converter_config import ALL, ConverterConfig
8
-
9
- __all__ = ["MolConverter"]
10
-
11
-
12
- class MolConverter(Converter):
13
- def __init__(self, result_property: ResultProperty, output_format: str, **kwargs: Any) -> None:
14
- super().__init__(result_property, output_format, **kwargs)
15
-
16
- if output_format == "sdf" and result_property.name == "input_mol":
17
- # in an SDF, the main molecule (input_mol) can be a Mol object
18
- self._serialize = lambda x: x
19
- elif output_format in ["pandas", "record_list", "iterator"]:
20
- self._serialize = lambda mol: mol
21
- else:
22
- representation = result_property.representation or "smiles"
23
- if representation == "inchi":
24
- self._serialize = MolToInchi
25
- elif representation == "smiles":
26
- self._serialize = MolToSmiles
27
- else:
28
- raise ValueError(f"Unsupported representation: {representation}")
29
-
30
- def _convert(self, input: Any, context: dict) -> Any:
31
- try:
32
- representation = self._serialize(input)
33
- except: # noqa: E722 (allow bare except, because RDKit is unpredictable)
34
- representation = None
35
-
36
- return representation
37
-
38
- config = ConverterConfig(
39
- data_types="mol",
40
- output_formats=ALL,
41
- )
File without changes
File without changes
File without changes