2525__email__ = "lester.hedges@gmail.com"
2626
2727__all__ = [
28+ "defaultMCSOptions" ,
2829 "generateNetwork" ,
2930 "matchAtoms" ,
3031 "viewMapping" ,
@@ -702,6 +703,29 @@ def generateNetwork(
702703 return edges , scores
703704
704705
706+ def defaultMCSOptions ():
707+ """
708+ Return the default options used for the RDKit maximum common substructure
709+ search. These can be overridden using the 'mcs_kwargs' argument of
710+ :class:`matchAtoms <BioSimSpace.Align.matchAtoms>`.
711+
712+ Returns
713+ -------
714+
715+ options : dict
716+ The default RDKit MCS options.
717+ """
718+ return {
719+ "atomCompare" : _rdFMCS .AtomCompare .CompareAny ,
720+ "bondCompare" : _rdFMCS .BondCompare .CompareAny ,
721+ "completeRingsOnly" : True ,
722+ "ringMatchesRingOnly" : True ,
723+ "matchChiralTag" : False ,
724+ "matchValences" : False ,
725+ "maximizeBonds" : False ,
726+ }
727+
728+
705729def matchAtoms (
706730 molecule0 ,
707731 molecule1 ,
@@ -719,6 +743,7 @@ def matchAtoms(
719743 prune_atom_types = False ,
720744 property_map0 = {},
721745 property_map1 = {},
746+ mcs_kwargs = {},
722747):
723748 """
724749 Find mappings between atom indices in molecule0 to those in molecule1.
@@ -775,6 +800,11 @@ def matchAtoms(
775800 option is only relevant to MCS performed using RDKit and will be
776801 ignored when falling back on Sire.
777802
803+ mcs_kwargs : dict
804+ A dictionary of keyword arguments used to override the defaults
805+ passed to the RDKit MCS search. This option is only relevant to MCS
806+ performed using RDKit and will be ignored when falling back on Sire.
807+
778808 roi : list
779809 The region of interest to match.
780810 Consists of a list of ROI residue indices.
@@ -881,6 +911,7 @@ def matchAtoms(
881911 prune_atom_types = prune_atom_types ,
882912 property_map0 = property_map0 ,
883913 property_map1 = property_map1 ,
914+ mcs_kwargs = mcs_kwargs ,
884915 )
885916 else :
886917 return _roiMatch (
@@ -912,6 +943,7 @@ def _matchAtoms(
912943 prune_atom_types = False ,
913944 property_map0 = {},
914945 property_map1 = {},
946+ mcs_kwargs = {},
915947):
916948 import sys as _sys
917949
@@ -975,6 +1007,9 @@ def _matchAtoms(
9751007 if not isinstance (complete_rings_only , bool ):
9761008 raise TypeError ("'complete_rings_only' must be of type 'bool'" )
9771009
1010+ if not isinstance (mcs_kwargs , dict ):
1011+ raise TypeError ("'mcs_kwargs' must be of type 'dict'" )
1012+
9781013 if type (max_scoring_matches ) is not int :
9791014 raise TypeError ("'max_scoring_matches' must be of type 'int'" )
9801015
@@ -1012,24 +1047,21 @@ def _matchAtoms(
10121047 _Convert .toRDKit (mol1 , property_map = property_map1 ),
10131048 ]
10141049
1050+ # Default MCS options, overridden by anything in 'mcs_kwargs'. The
1051+ # timeout is applied last so that it can't be overridden.
1052+ mcs_options = defaultMCSOptions ()
1053+ mcs_options ["completeRingsOnly" ] = complete_rings_only
1054+ mcs_options .update (mcs_kwargs )
1055+ mcs_options ["timeout" ] = timeout
1056+
10151057 # Generate the MCS match.
1016- mcs = _rdFMCS .FindMCS (
1017- mols ,
1018- atomCompare = _rdFMCS .AtomCompare .CompareAny ,
1019- bondCompare = _rdFMCS .BondCompare .CompareAny ,
1020- completeRingsOnly = complete_rings_only ,
1021- ringMatchesRingOnly = True ,
1022- matchChiralTag = False ,
1023- matchValences = False ,
1024- maximizeBonds = False ,
1025- timeout = timeout ,
1026- )
1058+ mcs = _rdFMCS .FindMCS (mols , ** mcs_options )
10271059
10281060 # Get the common substructure as a SMARTS string.
10291061 mcs_smarts = _Chem .MolFromSmarts (mcs .smartsString )
10301062
1031- except :
1032- raise RuntimeError ("RDKit MCS mapping failed! " )
1063+ except Exception as e :
1064+ raise RuntimeError (f "RDKit MCS mapping failed: { e } " )
10331065
10341066 # Score the mappings and return them in sorted order (best to worst).
10351067 mappings , scores = _score_rdkit_mappings (
@@ -1066,6 +1098,9 @@ def _matchAtoms(
10661098 "Using Sire MCS. Ignoring unsupported 'complete_rings_only' option!"
10671099 )
10681100
1101+ if mcs_kwargs :
1102+ _warnings .warn ("Using Sire MCS. Ignoring unsupported 'mcs_kwargs' options!" )
1103+
10691104 # Convert timeout to a Sire Unit.
10701105 timeout = timeout * _SireUnits .second
10711106
@@ -2079,6 +2114,7 @@ def merge(
20792114 roi = None ,
20802115 property_map0 = {},
20812116 property_map1 = {},
2117+ mcs_kwargs = {},
20822118 ** kwargs ,
20832119):
20842120 """
@@ -2130,6 +2166,11 @@ def merge(
21302166 A dictionary that maps "properties" in molecule1 to their user
21312167 defined values.
21322168
2169+ mcs_kwargs : dict
2170+ A dictionary of keyword arguments used to override the defaults
2171+ passed to the RDKit MCS search. This is only used when 'mapping'
2172+ is None, i.e. when a mapping is autogenerated.
2173+
21332174 Returns
21342175 -------
21352176
@@ -2208,6 +2249,7 @@ def merge(
22082249 molecule1 ,
22092250 property_map0 = property_map0 ,
22102251 property_map1 = property_map1 ,
2252+ mcs_kwargs = mcs_kwargs ,
22112253 )
22122254 molecule0 = rmsdAlign (molecule0 , molecule1 , mapping )
22132255
0 commit comments