From c418bbb8429582978025b50192c4a347f775d2d7 Mon Sep 17 00:00:00 2001 From: bries Date: Fri, 2 Feb 2024 15:50:45 +0100 Subject: [PATCH 01/12] ring hybridization filter --- src/kartograf/filters/__init__.py | 1 + src/kartograf/filters/ring_changes.py | 56 ++++++++++++++++++++++++ src/kartograf/tests/test_ring_filters.py | 23 ++++++++++ 3 files changed, 80 insertions(+) diff --git a/src/kartograf/filters/__init__.py b/src/kartograf/filters/__init__.py index 5b6ba0f..0f2e923 100644 --- a/src/kartograf/filters/__init__.py +++ b/src/kartograf/filters/__init__.py @@ -8,4 +8,5 @@ filter_ringsize_changes, filter_ringbreak_changes, filter_whole_rings_only, + filter_hybridization_rings, ) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index 59d9268..4030169 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -97,3 +97,59 @@ def filter_whole_rings_only( proposed_mapping = {v: k for k, v in filtered_mapping.items()} return proposed_mapping + + +def filter_hybridization_rings( + molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] +) -> dict[int, int]: + """Ensure that any mapped rings are either both aromatic or aliphatic""" + + def get_atom_ring_hybridization_map(rdmol: Chem.Mol): + """ + Helper function, getting molecule information about ring hybridizations. + + Parameters + ---------- + rdmol: Chem.Mol + + Returns + ------- + dict[int, list[bool]]: + returns a dict, that maps each atom to a list of ring + hybridizations it is in. (If True the ring is aromatic, if False + it is not entirely aromatic and therefore not necessarily + sterically restraint by a pi-orbital-system.) + """ + riInf = rdmol.GetRingInfo() + + # get_ring_hybridization + is_ring_aromatic = {} + for i, ring in enumerate(riInf.BondRings()): + is_ring_aromatic[i] = all( + rdmol.GetBondWithIdx(atomI).GetIsAromatic() + for atomI in ring) + + # map atoms to rings: + atom_ring_map = defaultdict(list) + [atom_ring_map[a].append(is_ring_aromatic[ri]) for ri, r in + enumerate(riInf.AtomRings()) for a + in r] + + return atom_ring_map + + atomA_ring_hyb_map = get_atom_ring_hybridization_map(molA) + atomB_ring_hyb_map = get_atom_ring_hybridization_map( + molB) + print(atomA_ring_hyb_map) + print(atomB_ring_hyb_map) + + # Filtering Mapping + filtered_mapping = {} + for ai, aj in mapping.items(): + ai_only_arom_sys = all(atomA_ring_hyb_map[ai]) + aj_only_arom_sys = all(atomB_ring_hyb_map[aj]) + + if (not ai_only_arom_sys ^ aj_only_arom_sys): + filtered_mapping[ai] = aj + + return filtered_mapping diff --git a/src/kartograf/tests/test_ring_filters.py b/src/kartograf/tests/test_ring_filters.py index 00ef8f0..1a6ff14 100644 --- a/src/kartograf/tests/test_ring_filters.py +++ b/src/kartograf/tests/test_ring_filters.py @@ -85,3 +85,26 @@ def test_whole_rings_safe(): newmapping = filters.filter_whole_rings_only(m1, m2, mapping) assert newmapping == mapping + + +@pytest.mark.parametrize('molA_B_exp_mapping', [ + (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), Chem.MolFromSmiles( + "C1CCCC2C1CCCC2"), {i:i for i in range(10)}), + (Chem.MolFromSmiles("c1cccc2c1cccc2"), Chem.MolFromSmiles( + "c1cccc2c1cccc2"), {i: i for i in range(10)}), + (Chem.MolFromSmiles("C1CCCc2c1cccc2"), Chem.MolFromSmiles( + "C1CCCC2C1CCCC2"), {i: i for i in range(6)}), + (Chem.MolFromSmiles("C1CCCC2C1cccc2"), Chem.MolFromSmiles( + "C1CCCC2C1CCCC2"), {i: i for i in range(10)}), + (Chem.MolFromSmiles("c1cccc2c1CCCC2"), Chem.MolFromSmiles( + "C1CCCC2C1CCCC2"), {i: i for i in range(4,10)}), +]) +def test_ring_hybridization(molA_B_exp_mapping): + molA, molB, expected_mapping = molA_B_exp_mapping + initial_mapping = {i: i for i in range(molA.GetNumAtoms())} + + newmapping = filters.filter_hybridization_rings(molA, molB, initial_mapping) + + assert newmapping != {} + assert len(newmapping) == len(expected_mapping) + assert newmapping == expected_mapping From bb8a2796b81cfc4d149b21c66a005a0286fff689 Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 29 Feb 2024 18:22:03 +0100 Subject: [PATCH 02/12] Update ring_changes.py --- src/kartograf/filters/ring_changes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index 4030169..4c6a51d 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -102,7 +102,7 @@ def filter_whole_rings_only( def filter_hybridization_rings( molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] ) -> dict[int, int]: - """Ensure that any mapped rings are either both aromatic or aliphatic""" + """Ensure that any mapped rings are either both aromatic or aliphatic - e.g. would unmap hexane to benzene type transformations""" def get_atom_ring_hybridization_map(rdmol: Chem.Mol): """ From 240b4cd416bd4c30425ce079cf0590e76b64dde4 Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 29 Feb 2024 18:23:37 +0100 Subject: [PATCH 03/12] Update ring_changes.py --- src/kartograf/filters/ring_changes.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index 4c6a51d..0ce6efd 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -131,10 +131,11 @@ def get_atom_ring_hybridization_map(rdmol: Chem.Mol): # map atoms to rings: atom_ring_map = defaultdict(list) - [atom_ring_map[a].append(is_ring_aromatic[ri]) for ri, r in - enumerate(riInf.AtomRings()) for a - in r] + for ri, r in enumerate(riInf.AtomRings()): + for a in r: + atom_ring_map[a].append(is_ring_aromatic[ri]) + return atom_ring_map atomA_ring_hyb_map = get_atom_ring_hybridization_map(molA) From 79edac1984c58dfd64599b14ff9e886588477932 Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 29 Feb 2024 18:24:05 +0100 Subject: [PATCH 04/12] Update ring_changes.py --- src/kartograf/filters/ring_changes.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index 0ce6efd..4fcc2bb 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -141,8 +141,6 @@ def get_atom_ring_hybridization_map(rdmol: Chem.Mol): atomA_ring_hyb_map = get_atom_ring_hybridization_map(molA) atomB_ring_hyb_map = get_atom_ring_hybridization_map( molB) - print(atomA_ring_hyb_map) - print(atomB_ring_hyb_map) # Filtering Mapping filtered_mapping = {} From 16a75a7be7c84ddab93e11a7573d8701f8fc37a2 Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 29 Feb 2024 18:27:53 +0100 Subject: [PATCH 05/12] Update test_ring_filters.py --- src/kartograf/tests/test_ring_filters.py | 25 ++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/kartograf/tests/test_ring_filters.py b/src/kartograf/tests/test_ring_filters.py index 1a6ff14..b4dfb68 100644 --- a/src/kartograf/tests/test_ring_filters.py +++ b/src/kartograf/tests/test_ring_filters.py @@ -88,16 +88,21 @@ def test_whole_rings_safe(): @pytest.mark.parametrize('molA_B_exp_mapping', [ - (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), Chem.MolFromSmiles( - "C1CCCC2C1CCCC2"), {i:i for i in range(10)}), - (Chem.MolFromSmiles("c1cccc2c1cccc2"), Chem.MolFromSmiles( - "c1cccc2c1cccc2"), {i: i for i in range(10)}), - (Chem.MolFromSmiles("C1CCCc2c1cccc2"), Chem.MolFromSmiles( - "C1CCCC2C1CCCC2"), {i: i for i in range(6)}), - (Chem.MolFromSmiles("C1CCCC2C1cccc2"), Chem.MolFromSmiles( - "C1CCCC2C1CCCC2"), {i: i for i in range(10)}), - (Chem.MolFromSmiles("c1cccc2c1CCCC2"), Chem.MolFromSmiles( - "C1CCCC2C1CCCC2"), {i: i for i in range(4,10)}), + (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), + {i:i for i in range(10)}), + (Chem.MolFromSmiles("c1cccc2c1cccc2"), + Chem.MolFromSmiles("c1cccc2c1cccc2"), + {i: i for i in range(10)}), + (Chem.MolFromSmiles("C1CCCc2c1cccc2"), + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), + {i: i for i in range(6)}), + (Chem.MolFromSmiles("C1CCCC2C1cccc2"), + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), + {i: i for i in range(10)}), + (Chem.MolFromSmiles("c1cccc2c1CCCC2"), + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), + {i: i for i in range(4,10)}), ]) def test_ring_hybridization(molA_B_exp_mapping): molA, molB, expected_mapping = molA_B_exp_mapping From 1b7a369cc60ed5b4bbfdf511ce8868ba0be53d3f Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 29 Feb 2024 18:35:04 +0100 Subject: [PATCH 06/12] Update test_ring_filters.py --- src/kartograf/tests/test_ring_filters.py | 42 ++++++++++++++---------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/kartograf/tests/test_ring_filters.py b/src/kartograf/tests/test_ring_filters.py index b4dfb68..90abdc3 100644 --- a/src/kartograf/tests/test_ring_filters.py +++ b/src/kartograf/tests/test_ring_filters.py @@ -88,25 +88,33 @@ def test_whole_rings_safe(): @pytest.mark.parametrize('molA_B_exp_mapping', [ - (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), - {i:i for i in range(10)}), - (Chem.MolFromSmiles("c1cccc2c1cccc2"), - Chem.MolFromSmiles("c1cccc2c1cccc2"), - {i: i for i in range(10)}), - (Chem.MolFromSmiles("C1CCCc2c1cccc2"), - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), - {i: i for i in range(6)}), - (Chem.MolFromSmiles("C1CCCC2C1cccc2"), - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), - {i: i for i in range(10)}), - (Chem.MolFromSmiles("c1cccc2c1CCCC2"), - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), - {i: i for i in range(4,10)}), + (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(10)}, # initial_mapping + {i:i for i in range(10)}), # expected: map all atoms + + (Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic + Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic + {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(10)}), # expected: map all atoms + + (Chem.MolFromSmiles("C1CCCc2c1cccc2"), # 2rings: aliphatic/aromatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(6)}), # expected: map aliphatic rings onto each other + + (Chem.MolFromSmiles("C1CCCC2C1cccc2"), # 2rings: aliphatic/aromatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(10)}), # expected: map all atoms + + (Chem.MolFromSmiles("c1cccc2c1CCCC2"), # 2rings: aromatic/aliphatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(4,10)}), # expected: map the aliphatic rings ontoeach other ]) def test_ring_hybridization(molA_B_exp_mapping): - molA, molB, expected_mapping = molA_B_exp_mapping - initial_mapping = {i: i for i in range(molA.GetNumAtoms())} + molA, molB, initial_mapping, expected_mapping = molA_B_exp_mapping newmapping = filters.filter_hybridization_rings(molA, molB, initial_mapping) From ed5c4502022742841e5874de533e11d3c91bc6e6 Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 29 Feb 2024 18:39:24 +0100 Subject: [PATCH 07/12] Update ring_changes.py --- src/kartograf/filters/ring_changes.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index 4fcc2bb..8d4fdbc 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -135,8 +135,13 @@ def get_atom_ring_hybridization_map(rdmol: Chem.Mol): for ri, r in enumerate(riInf.AtomRings()): for a in r: atom_ring_map[a].append(is_ring_aromatic[ri]) - - return atom_ring_map + + atom_aromatic={} + for a,v in atom_ring_map.items(): + atom_aromatic[a] = all(v) + + + return atom_aromatic atomA_ring_hyb_map = get_atom_ring_hybridization_map(molA) atomB_ring_hyb_map = get_atom_ring_hybridization_map( From 20f71d1bcb883202490506450074b67cfa5b931c Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 29 Feb 2024 18:39:45 +0100 Subject: [PATCH 08/12] Update ring_changes.py --- src/kartograf/filters/ring_changes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index 8d4fdbc..bac8c1f 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -150,8 +150,8 @@ def get_atom_ring_hybridization_map(rdmol: Chem.Mol): # Filtering Mapping filtered_mapping = {} for ai, aj in mapping.items(): - ai_only_arom_sys = all(atomA_ring_hyb_map[ai]) - aj_only_arom_sys = all(atomB_ring_hyb_map[aj]) + ai_only_arom_sys = atomA_ring_hyb_map[ai] + aj_only_arom_sys = atomB_ring_hyb_map[aj] if (not ai_only_arom_sys ^ aj_only_arom_sys): filtered_mapping[ai] = aj From eb0c732b0357c04fcb0622ffc2baf5afc4263f48 Mon Sep 17 00:00:00 2001 From: Richard Gowers Date: Fri, 1 Mar 2024 16:20:28 +0000 Subject: [PATCH 09/12] some tweaks to hybrid ring filter --- src/kartograf/filters/ring_changes.py | 35 +++++++++++++++------------ 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index bac8c1f..b249b28 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -102,11 +102,14 @@ def filter_whole_rings_only( def filter_hybridization_rings( molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] ) -> dict[int, int]: - """Ensure that any mapped rings are either both aromatic or aliphatic - e.g. would unmap hexane to benzene type transformations""" + """Ensure that any mapped rings are either both aromatic or aliphatic - def get_atom_ring_hybridization_map(rdmol: Chem.Mol): + e.g. this filter would unmap hexane to benzene type transformations + """ + + def get_atom_ring_hybridization_map(rdmol: Chem.Mol) -> dict[int, bool]: """ - Helper function, getting molecule information about ring hybridizations. + For each atom, determines information about ring hybridization Parameters ---------- @@ -114,38 +117,40 @@ def get_atom_ring_hybridization_map(rdmol: Chem.Mol): Returns ------- - dict[int, list[bool]]: - returns a dict, that maps each atom to a list of ring - hybridizations it is in. (If True the ring is aromatic, if False - it is not entirely aromatic and therefore not necessarily - sterically restraint by a pi-orbital-system.) + dict[int, bool]: + returns a dict, that maps each atom's index to if it is always in aromatic rings + (If True this atom exists entirely in aromatic rings, if False it is + not entirely aromatic and therefore not necessarily sterically restraint + by a pi-orbital-system.) """ riInf = rdmol.GetRingInfo() # get_ring_hybridization + # for each ring, the ring is aromatic if all atoms within are aromatic + # maps ring index to aromaticity as bool is_ring_aromatic = {} for i, ring in enumerate(riInf.BondRings()): is_ring_aromatic[i] = all( rdmol.GetBondWithIdx(atomI).GetIsAromatic() for atomI in ring) - # map atoms to rings: + # first iterate over all rings and determine if they are aromatic + # map atoms to ring aromaticities atom_ring_map = defaultdict(list) - for ri, r in enumerate(riInf.AtomRings()): for a in r: - atom_ring_map[a].append(is_ring_aromatic[ri]) + atom_ring_map[a].append(is_ring_aromatic[ri]) + # then with all rings traversed, crush this information down to a single bool per atom + # maps atom index to all ring aromaticity atom_aromatic={} for a,v in atom_ring_map.items(): atom_aromatic[a] = all(v) - return atom_aromatic atomA_ring_hyb_map = get_atom_ring_hybridization_map(molA) - atomB_ring_hyb_map = get_atom_ring_hybridization_map( - molB) + atomB_ring_hyb_map = get_atom_ring_hybridization_map(molB) # Filtering Mapping filtered_mapping = {} @@ -153,7 +158,7 @@ def get_atom_ring_hybridization_map(rdmol: Chem.Mol): ai_only_arom_sys = atomA_ring_hyb_map[ai] aj_only_arom_sys = atomB_ring_hyb_map[aj] - if (not ai_only_arom_sys ^ aj_only_arom_sys): + if ai_only_arom_sys == aj_only_arom_sys: filtered_mapping[ai] = aj return filtered_mapping From 465f002905514699dc8808d4004f6e742d10752e Mon Sep 17 00:00:00 2001 From: Richard Gowers Date: Fri, 1 Mar 2024 16:23:21 +0000 Subject: [PATCH 10/12] fix up hybrid rings tests --- src/kartograf/tests/test_ring_filters.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/kartograf/tests/test_ring_filters.py b/src/kartograf/tests/test_ring_filters.py index 90abdc3..2e61cd2 100644 --- a/src/kartograf/tests/test_ring_filters.py +++ b/src/kartograf/tests/test_ring_filters.py @@ -87,7 +87,7 @@ def test_whole_rings_safe(): assert newmapping == mapping -@pytest.mark.parametrize('molA_B_exp_mapping', [ +@pytest.mark.parametrize('molA,molB,initial_mapping,expected_mapping', [ (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic {i: i for i in range(10)}, # initial_mapping @@ -95,27 +95,25 @@ def test_whole_rings_safe(): (Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic - {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(10)}, # initial_mapping {i: i for i in range(10)}), # expected: map all atoms (Chem.MolFromSmiles("C1CCCc2c1cccc2"), # 2rings: aliphatic/aromatic Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(10)}, # initial_mapping {i: i for i in range(6)}), # expected: map aliphatic rings onto each other (Chem.MolFromSmiles("C1CCCC2C1cccc2"), # 2rings: aliphatic/aromatic Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(10)}, # initial_mapping {i: i for i in range(10)}), # expected: map all atoms (Chem.MolFromSmiles("c1cccc2c1CCCC2"), # 2rings: aromatic/aliphatic Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - {i: i for i in range(molA.GetNumAtoms())}, # initial_mapping + {i: i for i in range(10)}, # initial_mapping {i: i for i in range(4,10)}), # expected: map the aliphatic rings ontoeach other ]) -def test_ring_hybridization(molA_B_exp_mapping): - molA, molB, initial_mapping, expected_mapping = molA_B_exp_mapping - +def test_ring_hybridization(molA, molB, initial_mapping, expected_mapping): newmapping = filters.filter_hybridization_rings(molA, molB, initial_mapping) assert newmapping != {} From ddb1958233f7aa5637c14d07022840b5f577fd78 Mon Sep 17 00:00:00 2001 From: riesben Date: Fri, 29 Mar 2024 00:46:24 +0100 Subject: [PATCH 11/12] formattin g for mypy --- src/kartograf/filters/ring_changes.py | 14 ++++---- src/kartograf/tests/test_ring_filters.py | 44 ++++++++++++------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/kartograf/filters/ring_changes.py b/src/kartograf/filters/ring_changes.py index b249b28..800d518 100644 --- a/src/kartograf/filters/ring_changes.py +++ b/src/kartograf/filters/ring_changes.py @@ -9,7 +9,7 @@ def filter_ringsize_changes( - molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] + molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] ) -> dict[int, int]: """Prevents mutating the size of rings in the mapping""" riA = molA.GetRingInfo() @@ -41,7 +41,7 @@ def filter_ringsize_changes( def filter_ringbreak_changes( - molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] + molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] ) -> dict[int, int]: """Prevent any ring cleaving transformations in the mapping @@ -61,7 +61,7 @@ def filter_ringbreak_changes( def filter_whole_rings_only( - molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] + molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] ) -> dict[int, int]: """Ensure that any mapped rings are wholly mapped""" proposed_mapping = {**mapping} @@ -100,7 +100,7 @@ def filter_whole_rings_only( def filter_hybridization_rings( - molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] + molA: Chem.Mol, molB: Chem.Mol, mapping: dict[int, int] ) -> dict[int, int]: """Ensure that any mapped rings are either both aromatic or aliphatic @@ -143,10 +143,10 @@ def get_atom_ring_hybridization_map(rdmol: Chem.Mol) -> dict[int, bool]: # then with all rings traversed, crush this information down to a single bool per atom # maps atom index to all ring aromaticity - atom_aromatic={} - for a,v in atom_ring_map.items(): + atom_aromatic = {} + for a, v in atom_ring_map.items(): atom_aromatic[a] = all(v) - + return atom_aromatic atomA_ring_hyb_map = get_atom_ring_hybridization_map(molA) diff --git a/src/kartograf/tests/test_ring_filters.py b/src/kartograf/tests/test_ring_filters.py index 2e61cd2..a79f2c3 100644 --- a/src/kartograf/tests/test_ring_filters.py +++ b/src/kartograf/tests/test_ring_filters.py @@ -88,30 +88,30 @@ def test_whole_rings_safe(): @pytest.mark.parametrize('molA,molB,initial_mapping,expected_mapping', [ - (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - {i: i for i in range(10)}, # initial_mapping - {i:i for i in range(10)}), # expected: map all atoms - + (Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(10)}, # initial_mapping + {i: i for i in range(10)}), # expected: map all atoms + (Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic - {i: i for i in range(10)}, # initial_mapping - {i: i for i in range(10)}), # expected: map all atoms - - (Chem.MolFromSmiles("C1CCCc2c1cccc2"), # 2rings: aliphatic/aromatic - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - {i: i for i in range(10)}, # initial_mapping - {i: i for i in range(6)}), # expected: map aliphatic rings onto each other - - (Chem.MolFromSmiles("C1CCCC2C1cccc2"), # 2rings: aliphatic/aromatic - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - {i: i for i in range(10)}, # initial_mapping - {i: i for i in range(10)}), # expected: map all atoms - - (Chem.MolFromSmiles("c1cccc2c1CCCC2"), # 2rings: aromatic/aliphatic - Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic - {i: i for i in range(10)}, # initial_mapping - {i: i for i in range(4,10)}), # expected: map the aliphatic rings ontoeach other + {i: i for i in range(10)}, # initial_mapping + {i: i for i in range(10)}), # expected: map all atoms + + (Chem.MolFromSmiles("C1CCCc2c1cccc2"), # 2rings: aliphatic/aromatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(10)}, # initial_mapping + {i: i for i in range(6)}), # expected: map aliphatic rings onto each other + + (Chem.MolFromSmiles("C1CCCC2C1cccc2"), # 2rings: aliphatic/aromatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(10)}, # initial_mapping + {i: i for i in range(10)}), # expected: map all atoms + + (Chem.MolFromSmiles("c1cccc2c1CCCC2"), # 2rings: aromatic/aliphatic + Chem.MolFromSmiles("C1CCCC2C1CCCC2"), # 2rings: aliphatic/aliphatic + {i: i for i in range(10)}, # initial_mapping + {i: i for i in range(4, 10)}), # expected: map the aliphatic rings ontoeach other ]) def test_ring_hybridization(molA, molB, initial_mapping, expected_mapping): newmapping = filters.filter_hybridization_rings(molA, molB, initial_mapping) From eb3987137eba009f33c0ba8b3d325b4fc36ca797 Mon Sep 17 00:00:00 2001 From: riesben Date: Fri, 29 Mar 2024 00:48:08 +0100 Subject: [PATCH 12/12] formattin g for mypy --- src/kartograf/tests/test_ring_filters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kartograf/tests/test_ring_filters.py b/src/kartograf/tests/test_ring_filters.py index a79f2c3..13a5c52 100644 --- a/src/kartograf/tests/test_ring_filters.py +++ b/src/kartograf/tests/test_ring_filters.py @@ -93,8 +93,8 @@ def test_whole_rings_safe(): {i: i for i in range(10)}, # initial_mapping {i: i for i in range(10)}), # expected: map all atoms - (Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic - Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic + (Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic + Chem.MolFromSmiles("c1cccc2c1cccc2"), # 2rings: aromatic/aromatic {i: i for i in range(10)}, # initial_mapping {i: i for i in range(10)}), # expected: map all atoms