@@ -1103,6 +1103,7 @@ def interface(
1103
1103
topology = None ,
1104
1104
frag_idxs_group_1 = None ,
1105
1105
frag_idxs_group_2 = None ,
1106
+ AA_selection = None ,
1106
1107
GPCR_UniProt = "None" ,
1107
1108
CGN_UniProt = "None" ,
1108
1109
KLIFS_string = None ,
@@ -1161,26 +1162,27 @@ def interface(
1161
1162
in a receptor--G-protein complex, one partner is
1162
1163
the receptor and the other partner is the G-protein.
1163
1164
1164
- By default, mdciao.cli.interface doesn't allow interface
1165
- members to share residues. However, sometimes it's
1165
+ This is why mdciao.cli.interface doesn't allow interface
1166
+ members to share residues by default . However, sometimes it's
1166
1167
useful to allow it because the contacts of one fragment
1167
- with itself (the self-contacts) are also important.
1168
- E.g. the C-terminus of a receptor interfacing with
1169
- the entire receptor, **including the C-terminus**.
1168
+ with itself are also important. E.g. the
1169
+ C-terminus of a receptor interfacing with
1170
+ the entire receptor, **including the C-terminus itself **.
1170
1171
To allow for this behaviour, use `self_interface` = True,
1171
1172
and possibly increase `n_nearest`, since otherwise
1172
1173
neighboring residues of the shared set (e.g. C-terminus)
1173
1174
will always appear as formed.
1174
1175
1175
1176
Finally, the interface strength, defined as the
1176
1177
per-residue sum of contacts participating in
1177
- the interface, is written as the `bfactor <http://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#ATOM>`_
1178
+ the interface, is written as the
1179
+ `bfactor <http://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#ATOM>`_
1178
1180
in a .pdb file called (for the default `ctc_cutoff_Ang`=4)
1179
1181
'[email protected] _Ang.as_bfactors.pdb'. You
1180
1182
can see an example of how to use this file (e.g. with
1181
1183
VMD) in the online documentation. The structures, i.e.
1182
1184
frames, in that .pdb-file are chosen using the
1183
- method :obj:`mdciao.contacts.ContactGroup.n_repframes` .
1185
+ method :obj:`mdciao.contacts.ContactGroup.repframes` .
1184
1186
See below the parameter `n_repframes` for more info.
1185
1187
1186
1188
Parameters
@@ -1216,6 +1218,37 @@ def interface(
1216
1218
Defaults to None which will prompt the user of
1217
1219
information, except when only two fragments are
1218
1220
present. Then it defaults to [1]
1221
+ AA_selection : str or list, default is None
1222
+ Whatever the fragment definition and fragment selection
1223
+ has been, one can further refine the list of
1224
+ potential residue pairs by making a per aminoacid (AA)
1225
+ selection here. E.g., if one has selected the interface
1226
+ to be "TM3" vs "TM2", but wants to select only some
1227
+ regions of those helices, one can pass here an `AA_selection`.
1228
+ This can be a string or a list of len two:
1229
+
1230
+ * A string leads to a boolean "or" selection, i.e. keep
1231
+ residue pair [ii,jj] if either ii **or** jj
1232
+ match `AA_selection`. E.g.
1233
+
1234
+ >>> AA_selection = "3.45-3.55"
1235
+
1236
+ is equivalent of "3.45-3.55" vs "TM2" contacts
1237
+ * A list of len two leads to a boolean "and" selection, i.e. keep
1238
+ residue pair [ii,jj] if ii **and** jj
1239
+ match `AA_selection`. E.g.
1240
+
1241
+ >>> AA_selection = ["3.45-3.55","2.45-2.55"]
1242
+
1243
+ is equivalent of "3.45-3.55" vs "2.45-2.55" contacts
1244
+
1245
+ In principle, one could use
1246
+
1247
+ >>> fragments = ["3.45-3.55","2.45-2.55"]
1248
+
1249
+ and get the same contacts, but this would then exclude all other
1250
+ residues of the topology from being tagged with fragment
1251
+ and or consensus labels.
1219
1252
GPCR_UniProt : str or :obj:`mdciao.nomenclature.LabelerGPCR`, default is None
1220
1253
For GPCR nomenclature. If str, e.g. "adrb2_human".
1221
1254
will try to locate a local filename or do a web lookup in the GPCRdb.
@@ -1481,6 +1514,25 @@ def interface(
1481
1514
print ("\n Will look for contacts in the interface between fragments\n %s\n and\n %s. " %
1482
1515
('\n ' .join (_twrap (', ' .join (['%s' % gg for gg in intf_frags_as_str_or_keys [0 ]]))),
1483
1516
'\n ' .join (_twrap (', ' .join (['%s' % gg for gg in intf_frags_as_str_or_keys [1 ]])))))
1517
+
1518
+ # Sub-select at the AA-level #TODO consider making method out of this
1519
+ if AA_selection is not None :
1520
+ if isinstance (AA_selection , str ):
1521
+ lambda_sel = lambda pair , sel : _np .in1d (pair , sel ).any ()
1522
+ elif isinstance (AA_selection , list ) and len (AA_selection )== 2 :
1523
+ lambda_sel = lambda pair , sel : _np .in1d (pair , sel ).all ()
1524
+ AA_selection = "," .join (AA_selection )
1525
+ else :
1526
+ raise ValueError (f"'AA_selection' as to be a sting or a list of len 2, "
1527
+ f"but your input is a { type (AA_selection ).__name__ } of len { len (AA_selection )} ." )
1528
+ sel = _mdcu .residue_and_atom .rangeexpand_residues2residxs (AA_selection ,
1529
+ fragments_as_residue_idxs ,
1530
+ refgeom .top ,
1531
+ fragment_names = fragment_names ,
1532
+ additional_resnaming_dicts = consensus_maps )
1533
+ print (f"Excluding residue pairs not involving residues '{ AA_selection } ' ({ len (sel )} AAs)." )
1534
+ ctc_idxs = [pair for pair in ctc_idxs if lambda_sel (pair , sel )]
1535
+
1484
1536
print (f"Performing a first pass on the { len (ctc_idxs )} group_1-group_2 residue pairs to compute lower bounds "
1485
1537
f"on residue-residue distances via residue-COM distances." )
1486
1538
lb_cutoff_buffer_Ang = 2.5
0 commit comments