Skip to content

Commit 329cf76

Browse files
authored
Merge pull request #520 from OpenBioSim/fix_519
2 parents 9934335 + 8e9c6ba commit 329cf76

4 files changed

Lines changed: 91 additions & 73 deletions

File tree

nodes/playground/prepareFEP.ipynb

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -118,49 +118,7 @@
118118
"execution_count": null,
119119
"metadata": {},
120120
"outputs": [],
121-
"source": [
122-
"node.addInput(\"input1\", BSS.Gateway.FileSet(help=\"A topology and coordinates file\"))\n",
123-
"node.addInput(\"input2\", BSS.Gateway.FileSet(help=\"A topology and coordinates file\"))\n",
124-
"node.addInput(\n",
125-
" \"prematch\",\n",
126-
" BSS.Gateway.String(\n",
127-
" help=\"list of atom indices that are matched between input2 and input1. Syntax is of the format 1-3,4-8,9-11... Ignored if a mapping is provided\",\n",
128-
" default=\"\",\n",
129-
" ),\n",
130-
")\n",
131-
"node.addInput(\n",
132-
" \"mapping\",\n",
133-
" BSS.Gateway.File(\n",
134-
" help=\"csv file that contains atom indices in input1 mapped ot atom indices in input2\",\n",
135-
" optional=True,\n",
136-
" ),\n",
137-
")\n",
138-
"node.addInput(\n",
139-
" \"timeout\",\n",
140-
" BSS.Gateway.Time(\n",
141-
" help=\"The timeout for the maximum common substructure search\",\n",
142-
" default=10 * BSS.Units.Time.second,\n",
143-
" ),\n",
144-
")\n",
145-
"node.addInput(\n",
146-
" \"allow_ring_breaking\",\n",
147-
" BSS.Gateway.Boolean(\n",
148-
" help=\"Whether to allow opening/closing of rings during merge\", default=False\n",
149-
" ),\n",
150-
")\n",
151-
"node.addInput(\n",
152-
" \"allow_ring_size_change\",\n",
153-
" BSS.Gateway.Boolean(\n",
154-
" help=\"Whether to allow ring size changes during merge\", default=False\n",
155-
" ),\n",
156-
")\n",
157-
"node.addInput(\n",
158-
" \"output\",\n",
159-
" BSS.Gateway.String(\n",
160-
" help=\"The root name for the files describing the perturbation input1->input2.\"\n",
161-
" ),\n",
162-
")"
163-
]
121+
"source": "node.addInput(\"input1\", BSS.Gateway.FileSet(help=\"A topology and coordinates file\"))\nnode.addInput(\"input2\", BSS.Gateway.FileSet(help=\"A topology and coordinates file\"))\nnode.addInput(\n \"prematch\",\n BSS.Gateway.String(\n help=\"list of atom indices that are matched between input2 and input1. Syntax is of the format 1-3,4-8,9-11... Ignored if a mapping is provided\",\n default=\"\",\n ),\n)\nnode.addInput(\n \"mapping\",\n BSS.Gateway.File(\n help=\"csv file that contains atom indices in input1 mapped ot atom indices in input2\",\n optional=True,\n ),\n)\nnode.addInput(\n \"timeout\",\n BSS.Gateway.Time(\n help=\"The timeout for the maximum common substructure search\",\n default=10 * BSS.Units.Time.second,\n ),\n)\nnode.addInput(\n \"allow_ring_breaking\",\n BSS.Gateway.Boolean(\n help=\"Whether to allow opening/closing of rings during merge\", default=False\n ),\n)\nnode.addInput(\n \"allow_ring_size_change\",\n BSS.Gateway.Boolean(\n help=\"Whether to allow ring size changes during merge\", default=False\n ),\n)\nnode.addInput(\n \"max_path\",\n BSS.Gateway.Integer(\n help=\"Maximum path length used when searching for rings. Increase for very large macrocycles.\",\n default=50,\n minimum=1,\n ),\n)\nnode.addInput(\n \"max_ring_size\",\n BSS.Gateway.Integer(\n help=\"Maximum ring size considered when checking for ring size changes.\",\n default=24,\n minimum=1,\n ),\n)\nnode.addInput(\n \"output\",\n BSS.Gateway.String(\n help=\"The root name for the files describing the perturbation input1->input2.\"\n ),\n)"
164122
},
165123
{
166124
"cell_type": "code",
@@ -279,29 +237,7 @@
279237
"execution_count": null,
280238
"metadata": {},
281239
"outputs": [],
282-
"source": [
283-
"# Align lig2 to lig1 based on the best mapping (inverted). The molecule is aligned based\n",
284-
"# on a root mean squared displacement fit to find the optimal translation vector\n",
285-
"# (as opposed to merely taking the difference of centroids).\n",
286-
"lig2 = BSS.Align.rmsdAlign(lig2, lig1, inverted_mapping)\n",
287-
"\n",
288-
"# Merge the two ligands based on the mapping.\n",
289-
"merged = BSS.Align.merge(\n",
290-
" lig1,\n",
291-
" lig2,\n",
292-
" mapping,\n",
293-
" allow_ring_breaking=node.getInput(\"allow_ring_breaking\"),\n",
294-
" allow_ring_size_change=node.getInput(\"allow_ring_size_change\"),\n",
295-
")\n",
296-
"\n",
297-
"# Create a composite system\n",
298-
"system1.removeMolecules(lig1)\n",
299-
"system1.addMolecules(merged)\n",
300-
"\n",
301-
"# Make sure the box vectors are in reduced form.\n",
302-
"system1.reduceBoxVectors()\n",
303-
"system1.rotateBoxVectors()"
304-
]
240+
"source": "# Align lig2 to lig1 based on the best mapping (inverted). The molecule is aligned based\n# on a root mean squared displacement fit to find the optimal translation vector\n# (as opposed to merely taking the difference of centroids).\nlig2 = BSS.Align.rmsdAlign(lig2, lig1, inverted_mapping)\n\n# Merge the two ligands based on the mapping.\nmerged = BSS.Align.merge(\n lig1,\n lig2,\n mapping,\n allow_ring_breaking=node.getInput(\"allow_ring_breaking\"),\n allow_ring_size_change=node.getInput(\"allow_ring_size_change\"),\n max_path=node.getInput(\"max_path\"),\n max_ring_size=node.getInput(\"max_ring_size\"),\n)\n\n# Create a composite system\nsystem1.removeMolecules(lig1)\nsystem1.addMolecules(merged)\n\n# Make sure the box vectors are in reduced form.\nsystem1.reduceBoxVectors()\nsystem1.rotateBoxVectors()"
305241
},
306242
{
307243
"cell_type": "code",
@@ -421,4 +357,4 @@
421357
},
422358
"nbformat": 4,
423359
"nbformat_minor": 4
424-
}
360+
}

nodes/playground/prepareFEP.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ def loadMapping(mapping_file):
127127
help="Whether to allow ring size changes during merge", default=False
128128
),
129129
)
130+
node.addInput(
131+
"max_path",
132+
BSS.Gateway.Integer(
133+
help="Maximum path length used when searching for rings. Increase for very large macrocycles.",
134+
default=50,
135+
minimum=1,
136+
),
137+
)
138+
node.addInput(
139+
"max_ring_size",
140+
BSS.Gateway.Integer(
141+
help="Maximum ring size considered when checking for ring size changes.",
142+
default=24,
143+
minimum=1,
144+
),
145+
)
130146
node.addInput(
131147
"output",
132148
BSS.Gateway.String(
@@ -235,6 +251,8 @@ def loadMapping(mapping_file):
235251
mapping,
236252
allow_ring_breaking=node.getInput("allow_ring_breaking"),
237253
allow_ring_size_change=node.getInput("allow_ring_size_change"),
254+
max_path=node.getInput("max_path"),
255+
max_ring_size=node.getInput("max_ring_size"),
238256
)
239257

240258
# Create a composite system

src/BioSimSpace/Align/_merge.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ def merge(
3636
fix_perturbable_zero_sigmas=True,
3737
force=False,
3838
roi=None,
39+
max_path=50,
40+
max_ring_size=24,
3941
property_map0={},
4042
property_map1={},
4143
**kwargs,
@@ -75,6 +77,16 @@ def merge(
7577
The region of interest to merge.
7678
Consists of a list of ROI residue indices.
7779
80+
max_path : int
81+
Maximum path length used when searching for rings. The default of
82+
50 covers typical macrocycles. Increase if larger rings need to be
83+
detected.
84+
85+
max_ring_size : int
86+
Maximum ring size considered when checking for ring size changes.
87+
The default of 24 covers most drug-like macrocycles. Rings larger
88+
than this threshold are not subject to ring-size-change detection.
89+
7890
property_map0 : dict
7991
A dictionary that maps "properties" in this molecule to their
8092
user defined values. This allows the user to refer to properties
@@ -136,6 +148,12 @@ def merge(
136148
if not isinstance(force, bool):
137149
raise TypeError("'force' must be of type 'bool'")
138150

151+
if not isinstance(max_path, int) or max_path < 1:
152+
raise TypeError("'max_path' must be a positive integer")
153+
154+
if not isinstance(max_ring_size, int) or max_ring_size < 1:
155+
raise TypeError("'max_ring_size' must be a positive integer")
156+
139157
if not isinstance(mapping, dict):
140158
raise TypeError("'mapping' must be of type 'dict'.")
141159
else:
@@ -1202,7 +1220,14 @@ def merge(
12021220

12031221
# Combined ring check — calls find_paths once per connectivity.
12041222
is_ring_broken, is_ring_size_change = _check_ring(
1205-
c0, conn1, idx, idy, idx_map, idy_map
1223+
c0,
1224+
conn1,
1225+
idx,
1226+
idy,
1227+
idx_map,
1228+
idy_map,
1229+
max_path=max_path,
1230+
max_ring_size=max_ring_size,
12061231
)
12071232

12081233
# A ring was broken and it is not allowed.
@@ -1268,7 +1293,14 @@ def merge(
12681293

12691294
# Combined ring check — calls find_paths once per connectivity.
12701295
is_ring_broken, is_ring_size_change = _check_ring(
1271-
c1, conn0, idx, idy, idx_map, idy_map
1296+
c1,
1297+
conn0,
1298+
idx,
1299+
idy,
1300+
idx_map,
1301+
idy_map,
1302+
max_path=max_path,
1303+
max_ring_size=max_ring_size,
12721304
)
12731305

12741306
# A ring was broken and it is not allowed.
@@ -1494,7 +1526,7 @@ def merge(
14941526
return mol
14951527

14961528

1497-
def _check_ring(conn0, conn1, idx0, idy0, idx1, idy1, max_path=50, max_ring_size=12):
1529+
def _check_ring(conn0, conn1, idx0, idy0, idx1, idy1, max_path=50, max_ring_size=24):
14981530
"""
14991531
Internal function to test whether a perturbation opens/closes a ring or
15001532
changes its size for a given pair of atoms.

src/BioSimSpace/Sandpit/Exscientia/Align/_merge.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ def merge(
3535
allow_ring_size_change=False,
3636
force=False,
3737
roi=None,
38+
max_path=50,
39+
max_ring_size=24,
3840
property_map0={},
3941
property_map1={},
4042
**kwargs,
@@ -70,6 +72,16 @@ def merge(
7072
roi : list
7173
The region of interest to merge. Consist of two lists of atom indices.
7274
75+
max_path : int
76+
Maximum path length used when searching for rings. The default of
77+
50 covers typical macrocycles. Increase if larger rings need to be
78+
detected.
79+
80+
max_ring_size : int
81+
Maximum ring size considered when checking for ring size changes.
82+
The default of 24 covers most drug-like macrocycles. Rings larger
83+
than this threshold are not subject to ring-size-change detection.
84+
7385
property_map0 : dict
7486
A dictionary that maps "properties" in this molecule to their
7587
user defined values. This allows the user to refer to properties
@@ -127,6 +139,12 @@ def merge(
127139
if not isinstance(force, bool):
128140
raise TypeError("'force' must be of type 'bool'")
129141

142+
if not isinstance(max_path, int) or max_path < 1:
143+
raise TypeError("'max_path' must be a positive integer")
144+
145+
if not isinstance(max_ring_size, int) or max_ring_size < 1:
146+
raise TypeError("'max_ring_size' must be a positive integer")
147+
130148
if not isinstance(mapping, dict):
131149
raise TypeError("'mapping' must be of type 'dict'.")
132150
else:
@@ -1194,7 +1212,14 @@ def merge(
11941212

11951213
# Combined ring check — calls find_paths once per connectivity.
11961214
is_ring_broken, is_ring_size_change = _check_ring(
1197-
c0, conn, idx, idy, idx_map, idy_map
1215+
c0,
1216+
conn,
1217+
idx,
1218+
idy,
1219+
idx_map,
1220+
idy_map,
1221+
max_path=max_path,
1222+
max_ring_size=max_ring_size,
11981223
)
11991224

12001225
# A ring was broken and it is not allowed.
@@ -1260,7 +1285,14 @@ def merge(
12601285

12611286
# Combined ring check — calls find_paths once per connectivity.
12621287
is_ring_broken, is_ring_size_change = _check_ring(
1263-
c1, conn, idx, idy, idx_map, idy_map
1288+
c1,
1289+
conn,
1290+
idx,
1291+
idy,
1292+
idx_map,
1293+
idy_map,
1294+
max_path=max_path,
1295+
max_ring_size=max_ring_size,
12641296
)
12651297

12661298
# A ring was broken and it is not allowed.
@@ -1360,7 +1392,7 @@ def merge(
13601392
return mol
13611393

13621394

1363-
def _check_ring(conn0, conn1, idx0, idy0, idx1, idy1, max_path=50, max_ring_size=12):
1395+
def _check_ring(conn0, conn1, idx0, idy0, idx1, idy1, max_path=50, max_ring_size=24):
13641396
"""
13651397
Internal function to test whether a perturbation opens/closes a ring or
13661398
changes its size for a given pair of atoms.

0 commit comments

Comments
 (0)