chemrecon 0.1.1__py3-none-any.whl

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 (86) hide show
  1. chemrecon/__init__.py +73 -0
  2. chemrecon/chem/__init__.py +0 -0
  3. chemrecon/chem/chemreaction.py +223 -0
  4. chemrecon/chem/constant_compounds.py +3 -0
  5. chemrecon/chem/create_mol.py +91 -0
  6. chemrecon/chem/elements.py +141 -0
  7. chemrecon/chem/gml/__init__.py +0 -0
  8. chemrecon/chem/gml/gml.py +324 -0
  9. chemrecon/chem/gml/gml_reactant_matching.py +130 -0
  10. chemrecon/chem/gml/gml_to_rdk.py +217 -0
  11. chemrecon/chem/mol.py +483 -0
  12. chemrecon/chem/sumformula.py +120 -0
  13. chemrecon/connection.py +97 -0
  14. chemrecon/core/__init__.py +0 -0
  15. chemrecon/core/id_types.py +687 -0
  16. chemrecon/core/ontology.py +209 -0
  17. chemrecon/core/populate_query_handler.py +336 -0
  18. chemrecon/core/query_handler.py +587 -0
  19. chemrecon/database/__init__.py +1 -0
  20. chemrecon/database/connect.py +63 -0
  21. chemrecon/database/connection_params/chemrecon_pub.dbinfo +5 -0
  22. chemrecon/database/connection_params/local_docker_dev.dbinfo +5 -0
  23. chemrecon/database/connection_params/local_docker_init.dbinfo +5 -0
  24. chemrecon/database/connection_params/local_docker_pub.dbinfo +5 -0
  25. chemrecon/database/params.py +88 -0
  26. chemrecon/entrygraph/draw.py +119 -0
  27. chemrecon/entrygraph/entrygraph.py +301 -0
  28. chemrecon/entrygraph/explorationprotocol.py +199 -0
  29. chemrecon/entrygraph/explore.py +421 -0
  30. chemrecon/entrygraph/explore_procedure.py +183 -0
  31. chemrecon/entrygraph/filter.py +88 -0
  32. chemrecon/entrygraph/scoring.py +141 -0
  33. chemrecon/query/__init__.py +26 -0
  34. chemrecon/query/create_entry.py +86 -0
  35. chemrecon/query/default_protocols.py +57 -0
  36. chemrecon/query/find_entry.py +84 -0
  37. chemrecon/query/get_relations.py +143 -0
  38. chemrecon/query/get_structures_from_compound.py +65 -0
  39. chemrecon/schema/__init__.py +86 -0
  40. chemrecon/schema/db_object.py +363 -0
  41. chemrecon/schema/direction.py +10 -0
  42. chemrecon/schema/entry_types/__init__.py +0 -0
  43. chemrecon/schema/entry_types/aam.py +34 -0
  44. chemrecon/schema/entry_types/aam_repr.py +37 -0
  45. chemrecon/schema/entry_types/compound.py +52 -0
  46. chemrecon/schema/entry_types/enzyme.py +49 -0
  47. chemrecon/schema/entry_types/molstructure.py +64 -0
  48. chemrecon/schema/entry_types/molstructure_repr.py +41 -0
  49. chemrecon/schema/entry_types/reaction.py +57 -0
  50. chemrecon/schema/enums.py +154 -0
  51. chemrecon/schema/procedural_relation_entrygraph.py +66 -0
  52. chemrecon/schema/relation_types_composed/__init__.py +0 -0
  53. chemrecon/schema/relation_types_composed/compound_has_molstructure_relation.py +59 -0
  54. chemrecon/schema/relation_types_composed/reaction_has_aam_relation.py +50 -0
  55. chemrecon/schema/relation_types_procedural/__init__.py +0 -0
  56. chemrecon/schema/relation_types_procedural/aam_convert_relation.py +69 -0
  57. chemrecon/schema/relation_types_procedural/compound_select_structure_proceduralrelation.py +36 -0
  58. chemrecon/schema/relation_types_procedural/compound_similarlity_proceduralrelation.py +1 -0
  59. chemrecon/schema/relation_types_procedural/molstructure_convert_relation.py +49 -0
  60. chemrecon/schema/relation_types_procedural/reaction_select_aam_proceduralrelation.py +38 -0
  61. chemrecon/schema/relation_types_procedural/reaction_similarity_proceduralrelation.py +1 -0
  62. chemrecon/schema/relation_types_source/__init__.py +0 -0
  63. chemrecon/schema/relation_types_source/aam_involves_molstructure_relation.py +77 -0
  64. chemrecon/schema/relation_types_source/aam_repr_involves_molstructure_repr_relation.py +79 -0
  65. chemrecon/schema/relation_types_source/compound_has_structure_representation_relation.py +33 -0
  66. chemrecon/schema/relation_types_source/compound_reference_relation.py +34 -0
  67. chemrecon/schema/relation_types_source/molstructure_standardisation_relation.py +71 -0
  68. chemrecon/schema/relation_types_source/ontology/__init__.py +0 -0
  69. chemrecon/schema/relation_types_source/ontology/compound_ontology.py +369 -0
  70. chemrecon/schema/relation_types_source/ontology/enzyme_ontology.py +142 -0
  71. chemrecon/schema/relation_types_source/ontology/reaction_ontology.py +140 -0
  72. chemrecon/schema/relation_types_source/reaction_has_aam_representation_relation.py +34 -0
  73. chemrecon/schema/relation_types_source/reaction_has_enzyme_relation.py +71 -0
  74. chemrecon/schema/relation_types_source/reaction_involves_compound_relation.py +69 -0
  75. chemrecon/schema/relation_types_source/reaction_reference_relation.py +33 -0
  76. chemrecon/scripts/initialize_database.py +494 -0
  77. chemrecon/utils/copy_signature.py +10 -0
  78. chemrecon/utils/encodeable_list.py +11 -0
  79. chemrecon/utils/get_id_type.py +70 -0
  80. chemrecon/utils/hungarian.py +31 -0
  81. chemrecon/utils/reactant_matching.py +168 -0
  82. chemrecon/utils/rxnutils.py +44 -0
  83. chemrecon/utils/set_cwd.py +12 -0
  84. chemrecon-0.1.1.dist-info/METADATA +143 -0
  85. chemrecon-0.1.1.dist-info/RECORD +86 -0
  86. chemrecon-0.1.1.dist-info/WHEEL +4 -0
@@ -0,0 +1,69 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Optional
4
+
5
+ from chemrecon.chem.chemreaction import ChemReaction, chem_reaction_from_rxn
6
+ from chemrecon.chem.gml.gml_to_rdk import gml_to_rdkit_reaction
7
+ from chemrecon.core.id_types import A_GML_RULE, A_RXN
8
+ from chemrecon.schema import (ProceduralGeneratorError, ProceduralRelation, AAMRepr, AAM, )
9
+
10
+
11
+ class AAMConvert(ProceduralRelation[AAMRepr, AAM]):
12
+ """ Standardized and canonical conversion of AAM representations (e.g. reaction SMILES, MolFile, …) into a
13
+ consistent format, stored as a canonical reaction SMILES string.
14
+ """
15
+ # Attributes
16
+
17
+ # Database
18
+ entrytype_name = 'AAM Convert'
19
+ _table_name = 'AAMConvert'
20
+ symmetric = False
21
+ source_entrytype = AAMRepr
22
+ target_entrytype = AAM
23
+ _attribute_columns = []
24
+ _index = []
25
+
26
+ def __init__(
27
+ self,
28
+ recon_id_1: Optional[int] = None,
29
+ recon_id_2: Optional[int] = None
30
+ ):
31
+ super().__init__(recon_id_1, recon_id_2)
32
+
33
+ @classmethod
34
+ def generate(
35
+ cls,
36
+ take_entry: AAMRepr
37
+ ) -> list[tuple[ProceduralRelation[AAMRepr, AAM], AAM]]:
38
+
39
+ r: Optional[ChemReaction] = None
40
+ try:
41
+ match take_entry.id_type:
42
+ case A_RXN.enum_type:
43
+ r = chem_reaction_from_rxn(rxn = take_entry.source_id)
44
+ case A_GML_RULE.enum_type:
45
+ rdk_reaction = gml_to_rdkit_reaction(gml = take_entry.source_id)
46
+ r = ChemReaction(
47
+ rdk_reaction = rdk_reaction
48
+ )
49
+ case _:
50
+ # Log error and continue
51
+ raise ProceduralGeneratorError('Cannot create atom-to-atom map for reaction (unsupported format).')
52
+ except Exception as e:
53
+ raise ProceduralGeneratorError(f'Failed converting AAM representation to internal format.') from e
54
+ if r is None:
55
+ raise ProceduralGeneratorError(f'AAM conversion failed.')
56
+
57
+ assert take_entry.recon_id is not None
58
+ r_smarts = r.to_reaction_smiles()
59
+ r_entry = AAM(
60
+ reaction_smiles = r_smarts
61
+ )
62
+
63
+ # Return AAM
64
+ return [
65
+ (
66
+ AAMConvert(),
67
+ r_entry
68
+ )
69
+ ]
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ from chemrecon.schema.procedural_relation_entrygraph import ProceduralRelationEG
4
+ from chemrecon.schema.direction import Direction
5
+ from chemrecon.entrygraph.scoring import Scorer
6
+ from chemrecon.schema.entry_types.compound import Compound
7
+ from chemrecon.schema.entry_types.molstructure import MolStructure
8
+ from chemrecon.schema.relation_types_composed.compound_has_molstructure_relation import CompoundHasMolStructure
9
+ from chemrecon.schema.relation_types_source.compound_reference_relation import CompoundReference
10
+ from chemrecon.schema.relation_types_source.molstructure_standardisation_relation import MolStructureStandardization
11
+ from chemrecon.entrygraph.explorationprotocol import ExplorationProtocol
12
+
13
+ ProtocolSelectStructure = ExplorationProtocol(
14
+ relation_types = {
15
+ (CompoundReference, Direction.SYMMETRIC),
16
+ (CompoundHasMolStructure, Direction.FORWARDS),
17
+ (MolStructureStandardization, Direction.FORWARDS),
18
+ },
19
+ )
20
+ eg_scorer_compound_select_structure = Scorer[MolStructure](
21
+ score_entry_type = MolStructure
22
+ )
23
+
24
+ class CompoundSelectStructure(ProceduralRelationEG[Compound, MolStructure]):
25
+ """ Procedural relation which computes the most related molecular structures for a given compound using entry graph
26
+ scoring.
27
+ """
28
+
29
+ # Database
30
+ _table_name = 'CompoundSelectStructure'
31
+ source_entrytype = Compound
32
+ target_entrytype = MolStructure
33
+
34
+ # For EG
35
+ protocol = ProtocolSelectStructure
36
+ entrygraph_scorer = eg_scorer_compound_select_structure
@@ -0,0 +1,49 @@
1
+ from typing import Optional
2
+
3
+ from chemrecon.chem.mol import Mol
4
+ from chemrecon.chem.create_mol import mol_from_structurerepresentation
5
+ from chemrecon.schema import MolStructureRepr, MolStructure
6
+ from chemrecon.schema.db_object import ProceduralGeneratorError, ProceduralRelation
7
+
8
+
9
+ class MolStructureConvert(ProceduralRelation[MolStructureRepr, MolStructure]):
10
+ """ Standardized and canonical conversion of molecular structure representations (e.g. SMILES, InChI, ...) into
11
+ a consistent format, stored as a canonical SMILES string.
12
+ """
13
+ # Attributes
14
+
15
+ # Database
16
+ entrytype_name = 'MolStructureConvert'
17
+ _table_name = 'MolStructureConvert'
18
+ symmetric = False
19
+ source_entrytype = MolStructureRepr
20
+ target_entrytype = MolStructure
21
+ _attribute_columns = []
22
+ _index = []
23
+
24
+ def __init__(
25
+ self,
26
+ recon_id_1: Optional[int] = None,
27
+ recon_id_2: Optional[int] = None
28
+ ):
29
+ super().__init__(recon_id_1, recon_id_2)
30
+
31
+
32
+ @classmethod
33
+ def generate(
34
+ cls, take_entry: MolStructureRepr
35
+ ) -> list[tuple[ProceduralRelation[MolStructureRepr, MolStructure], MolStructure]]:
36
+
37
+ try:
38
+ mol: Mol = mol_from_structurerepresentation(take_entry, template = True)
39
+ new_entry: MolStructure = mol.to_database_struct()
40
+ return [
41
+ (
42
+ MolStructureConvert(),
43
+ new_entry
44
+ )
45
+ ]
46
+
47
+ except Exception as e:
48
+ # Failed for this item
49
+ raise ProceduralGeneratorError(f'Creating molecule failed for {take_entry.source_id}') from e
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ from chemrecon.schema.direction import Direction
4
+ from chemrecon.entrygraph.scoring import Scorer
5
+ from chemrecon.schema.entry_types.aam import AAM
6
+ from chemrecon.schema.entry_types.enzyme import Enzyme
7
+ from chemrecon.schema.entry_types.reaction import Reaction
8
+ from chemrecon.schema.procedural_relation_entrygraph import ProceduralRelationEG
9
+ from chemrecon.schema.relation_types_composed.reaction_has_aam_relation import ReactionHasAAM
10
+ from chemrecon.schema.relation_types_source.reaction_has_enzyme_relation import ReactionHasEnzyme
11
+ from chemrecon.schema.relation_types_source.reaction_reference_relation import ReactionReference
12
+ from chemrecon.entrygraph.explorationprotocol import ExplorationProtocol
13
+
14
+ ProtocolSelectAAM = ExplorationProtocol(
15
+ relation_types = {
16
+ (ReactionReference, Direction.SYMMETRIC),
17
+ (ReactionHasEnzyme, Direction.BOTH),
18
+ (ReactionHasAAM, Direction.FORWARDS)
19
+ },
20
+ # TODO filter (filter out name entries)
21
+ )
22
+ eg_scorer_reaction_select_aam = Scorer(
23
+ score_entry_type = AAM,
24
+ # TODO more advanced weighing
25
+ )
26
+
27
+ class ReactionSelectAAM(ProceduralRelationEG[Reaction, AAM]):
28
+ """ Procedural relation which computes the most related AAMs for a given reaction using entry graph scoring.
29
+ """
30
+
31
+ # Database
32
+ _table_name = 'ReactionSelectAAM'
33
+ source_entrytype = Reaction
34
+ target_entrytype = AAM
35
+
36
+ # For EG
37
+ protocol = ProtocolSelectAAM
38
+ entrygraph_scorer = eg_scorer_reaction_select_aam
File without changes
@@ -0,0 +1,77 @@
1
+ from typing import Optional
2
+
3
+ from chemrecon.schema.db_object import Column, Relation, InverseRelation
4
+ from chemrecon.schema.entry_types.aam import AAM
5
+ from chemrecon.schema.entry_types.molstructure import MolStructure
6
+
7
+
8
+ class AAMInvolvesMolStructure(Relation[AAM, MolStructure]):
9
+ """ Relates the molecular structures involved in an atom-to-atom-mapped reaction.
10
+ These molecular structures are implicitly a part of the AAM structure.
11
+ """
12
+ # Attributes
13
+ side: int #: The side of the reaction which contains this structure (-1 or 1)
14
+ structure_atom_index_in_aam: list[int] #: Atom mapping numbers of the atoms in the structure w.r.t. the AAM.
15
+
16
+ # Database
17
+ entrytype_name = 'AAM Involves MolStructure'
18
+ _table_name = 'AAMInvolvesMolStructure'
19
+ symmetric = False
20
+ source_entrytype = AAM
21
+ target_entrytype = MolStructure
22
+ _attribute_columns = [
23
+ Column('structure_atom_index_in_aam', list[int])
24
+ ]
25
+ _index = [0]
26
+
27
+ def __init__(
28
+ self,
29
+ side: int,
30
+ structure_atom_index_in_aam: list[int],
31
+ recon_id_1: Optional[int] = None,
32
+ recon_id_2: Optional[int] = None
33
+ ):
34
+ super().__init__(recon_id_1, recon_id_2)
35
+ self.side = side
36
+ self.structure_atom_index_in_aam = structure_atom_index_in_aam
37
+
38
+ def _vis_str(self) -> str:
39
+ return f'has structure ({self.side})'
40
+
41
+ class MolStructureParticipatesInAAM(InverseRelation[MolStructure, AAM]):
42
+ """ Relates the molecular structures involved in an atom-to-atom-mapped reaction.
43
+ These molecular structures are implicitly a part of the AAM structure.
44
+ """
45
+ # Attributes
46
+ side: int #: The side of the reaction which contains this structure (-1 or 1)
47
+ structure_atom_index_in_aam: list[int] #: Atom mapping numbers of the atoms in the structure w.r.t. the AAM.
48
+
49
+ # Inverse
50
+ inverse_main_relation = AAMInvolvesMolStructure
51
+
52
+ # Database
53
+ entrytype_name = 'MolStructure Participats in AAM'
54
+ _table_name = 'MolStructureParticipatesInAAM'
55
+ symmetric = False
56
+ source_entrytype = MolStructure
57
+ target_entrytype = AAM
58
+ _attribute_columns = [
59
+ Column('structure_atom_index_in_aam', list[int])
60
+ ]
61
+ _index = [0]
62
+
63
+ def __init__(
64
+ self,
65
+ side: int,
66
+ structure_atom_index_in_aam: list[int],
67
+ recon_id_1: Optional[int] = None,
68
+ recon_id_2: Optional[int] = None
69
+ ):
70
+ super().__init__(recon_id_1, recon_id_2)
71
+ self.side = side
72
+ self.structure_atom_index_in_aam = structure_atom_index_in_aam
73
+
74
+ def _vis_str(self) -> str:
75
+ return f'in reaction ({self.side})'
76
+
77
+ AAMInvolvesMolStructure.has_inverse = MolStructureParticipatesInAAM
@@ -0,0 +1,79 @@
1
+ from typing import Optional
2
+
3
+ from chemrecon.schema.db_object import Column, Relation, InverseRelation
4
+ from chemrecon.schema.entry_types.aam_repr import AAMRepr
5
+ from chemrecon.schema.entry_types.molstructure_repr import MolStructureRepr
6
+
7
+
8
+ class AAMReprInvolvesMolStructureRepr(Relation[AAMRepr, MolStructureRepr]):
9
+ """ Relates the molecular structure representation involved in an atom-to-atom-mapped reaction.
10
+ These molecular structures are implicitly a part of the AAM structure.
11
+ """
12
+ # Attributes
13
+ index: int #: Index in the mapping string
14
+ stoich: int #: The stoichiometric coefficient of the MolStructureRepr
15
+
16
+ # Database
17
+ entrytype_name = 'AAMRepr Involves MolStructureRepr'
18
+ _table_name = 'AAMReprInvolvesMolStructureRepr'
19
+ symmetric = False
20
+ source_entrytype = AAMRepr
21
+ target_entrytype = MolStructureRepr
22
+ _attribute_columns = [
23
+ Column('index', int),
24
+ Column('stoich', int)
25
+ ]
26
+ _index = [0]
27
+
28
+ def __init__(
29
+ self,
30
+ index: int,
31
+ stoich: int,
32
+ recon_id_1: Optional[int] = None,
33
+ recon_id_2: Optional[int] = None
34
+ ):
35
+ super().__init__(recon_id_1, recon_id_2)
36
+ self.index = index
37
+ self.stoich = stoich
38
+
39
+ def _vis_str(self) -> str:
40
+ return f'has structure (side: {self.stoich})'
41
+
42
+ class MolStructureReprParticipatesInAAMRepr(InverseRelation[MolStructureRepr, AAMRepr]):
43
+ """ Relates the molecular structure representation involved in an atom-to-atom-mapped reaction.
44
+ These molecular structures are implicitly a part of the AAM structure.
45
+ """
46
+ # Attributes
47
+ index: int #: Index in the mapping string
48
+ stoich: int #: The stoichiometric coefficient of the MolStructureRepr
49
+
50
+ # Inverse
51
+ inverse_main_relation = AAMReprInvolvesMolStructureRepr
52
+
53
+ # Database
54
+ entrytype_name = 'MolStructureRepr Participates in AAMRepr'
55
+ _table_name = 'MolStructureReprParticipatesInAAMRepr'
56
+ symmetric = False
57
+ source_entrytype = MolStructureRepr
58
+ target_entrytype = AAMRepr
59
+ _attribute_columns = [
60
+ Column('index', int),
61
+ Column('stoich', int)
62
+ ]
63
+ _index = [0]
64
+
65
+ def __init__(
66
+ self,
67
+ index: int,
68
+ stoich: int,
69
+ recon_id_1: Optional[int] = None,
70
+ recon_id_2: Optional[int] = None
71
+ ):
72
+ super().__init__(recon_id_1, recon_id_2)
73
+ self.index = index
74
+ self.stoich = stoich
75
+
76
+ def _vis_str(self) -> str:
77
+ return f'in aam ({self.stoich})'
78
+
79
+ AAMReprInvolvesMolStructureRepr.has_inverse = MolStructureReprParticipatesInAAMRepr
@@ -0,0 +1,33 @@
1
+ from typing import Optional
2
+
3
+ from chemrecon.schema import Relation, Compound, SourceDatabase, MolStructureRepr
4
+ from chemrecon.schema.db_object import col_src
5
+
6
+
7
+ class CompoundHasStructureRepresentation(Relation[Compound, MolStructureRepr]):
8
+ """ Relates a compound entry to the structure representation (e.g. SMILES, InChI) given by that database.
9
+ """
10
+ # Attributes
11
+ src: SourceDatabase #: The source database containing this representation.
12
+
13
+ # Database
14
+ _table_name = 'CompoundHasStructureRepresentation'
15
+ symmetric = False
16
+ source_entrytype = Compound
17
+ target_entrytype = MolStructureRepr
18
+ _attribute_columns = [
19
+ col_src
20
+ ]
21
+ _index = [0]
22
+
23
+ def __init__(
24
+ self,
25
+ src: SourceDatabase = SourceDatabase.unknown,
26
+ recon_id_1: Optional[int] = None,
27
+ recon_id_2: Optional[int] = None
28
+ ):
29
+ super().__init__(recon_id_1, recon_id_2)
30
+ self.src = src
31
+
32
+ def _vis_str(self) -> str:
33
+ return f'{self.src.name}'
@@ -0,0 +1,34 @@
1
+ from typing import Optional
2
+
3
+ from chemrecon.schema import Relation, Compound, SourceDatabase
4
+ from chemrecon.schema.db_object import col_src
5
+
6
+
7
+ class CompoundReference(Relation[Compound, Compound]):
8
+ """ Inter- or intra-database reference between compounds.
9
+ """
10
+ # Attributes
11
+ src: SourceDatabase #: The source of the relation
12
+
13
+ # Database
14
+ entrytype_name = 'Compound Reference'
15
+ _table_name = 'CompoundReference'
16
+ symmetric = True
17
+ source_entrytype = Compound
18
+ target_entrytype = Compound
19
+ _attribute_columns = [
20
+ col_src
21
+ ]
22
+ _index = [0]
23
+
24
+ def __init__(
25
+ self,
26
+ src: SourceDatabase = SourceDatabase.unknown,
27
+ recon_id_1: Optional[int] = None,
28
+ recon_id_2: Optional[int] = None
29
+ ):
30
+ super().__init__(recon_id_1, recon_id_2)
31
+ self.src = src
32
+
33
+ def _vis_str(self) -> str:
34
+ return f'ref ({self.src.name})'
@@ -0,0 +1,71 @@
1
+ from typing import Optional
2
+
3
+ from chemrecon.chem.mol import feats, Mol
4
+ from chemrecon.chem.create_mol import mol_from_smiles
5
+ from chemrecon.schema import Column, FeatureEnum, ProceduralGeneratorError, ProceduralRelation, MolStructure
6
+
7
+
8
+ class MolStructureStandardization(ProceduralRelation[MolStructure, MolStructure]):
9
+ """ Standardization of molecular structures according to a particular 'feature' (Fragment, Isotope, Charge,
10
+ Tautomerism, Stereochemical).
11
+ """
12
+
13
+ # Attributes
14
+ feat: FeatureEnum #: The feature w.r.t. which the structure is standardized.
15
+
16
+ # Database
17
+ entrytype_name = 'MolStructure standardisation'
18
+ _table_name = 'MolStructureStandardisation'
19
+ ignore_generation_limit = True
20
+ symmetric = False
21
+ source_entrytype = MolStructure
22
+ target_entrytype = MolStructure
23
+ _attribute_columns = [
24
+ Column('feat', FeatureEnum)
25
+ ]
26
+ _index = [0]
27
+
28
+ def __init__(
29
+ self,
30
+ feat: FeatureEnum,
31
+ recon_id_1: Optional[int] = None,
32
+ recon_id_2: Optional[int] = None
33
+ ):
34
+ super().__init__(recon_id_1, recon_id_2)
35
+ self.feat = feat
36
+
37
+ @classmethod
38
+ def generate(
39
+ cls, take_entry: MolStructure
40
+ ) -> list[tuple[ProceduralRelation[MolStructure, MolStructure], MolStructure]]:
41
+
42
+ # Create mol object
43
+ m: Mol
44
+ try:
45
+ m = mol_from_smiles(take_entry.smiles)
46
+ except ValueError as e:
47
+ # Mol creation fails
48
+ raise ProceduralGeneratorError('Could not create mol for std.') from e
49
+
50
+ feat_entries: list[tuple[FeatureEnum, MolStructure]] = list()
51
+ for f in feats:
52
+ if f not in m.features:
53
+ try:
54
+ m_: Mol = Mol(f.standardise(m))
55
+ except Exception as e:
56
+ # Failed standardisation
57
+ continue
58
+
59
+ feat_entries.append((f.feature_enum, m_.to_database_struct()))
60
+
61
+ return [
62
+ (
63
+ MolStructureStandardization(feat = f),
64
+ e
65
+ )
66
+ for f, e in feat_entries
67
+ ]
68
+
69
+ # Visualisation
70
+ def _vis_str(self) -> str:
71
+ return f'std: {self.feat.name}'