@@ -674,10 +674,10 @@ def test_roi_flex_align(protein_inputs):
674674def test_empty_custom_roi_mapping ():
675675 # mut contains a proline mutation at position 15
676676 wt = BSS .IO .readMolecules (
677- BSS .IO .expand (BSS .tutorialUrl (), f "1choFH_apo_wt_flare_processed.pdb" )
677+ BSS .IO .expand (BSS .tutorialUrl (), "1choFH_apo_wt_flare_processed.pdb" )
678678 )[0 ]
679679 mut = BSS .IO .readMolecules (
680- BSS .IO .expand (BSS .tutorialUrl (), f "1choFH_apo_mut_flare_processed.pdb" )
680+ BSS .IO .expand (BSS .tutorialUrl (), "1choFH_apo_mut_flare_processed.pdb" )
681681 )[0 ]
682682
683683 # use the custom_roi_map to specify that residue 15 in the WT protein should be
@@ -691,15 +691,16 @@ def test_empty_custom_roi_mapping():
691691 for atom_idx in roi_res_idx :
692692 assert atom_idx not in mapping .keys ()
693693
694+
694695@pytest .mark .skipif (has_amber is False , reason = "Requires AMBER to be installed." )
695696def test_custom_roi_ring_break_merge ():
696697 # wt contains a leucine at position 15
697698 # mut contains a proline at position 15
698699 wt = BSS .IO .readMolecules (
699- BSS .IO .expand (BSS .tutorialUrl (), f "1choFH_apo_wt_flare_processed.pdb" )
700+ BSS .IO .expand (BSS .tutorialUrl (), "1choFH_apo_wt_flare_processed.pdb" )
700701 )[0 ]
701702 mut = BSS .IO .readMolecules (
702- BSS .IO .expand (BSS .tutorialUrl (), f "1choFH_apo_mut_flare_processed.pdb" )
703+ BSS .IO .expand (BSS .tutorialUrl (), "1choFH_apo_mut_flare_processed.pdb" )
703704 )[0 ]
704705
705706 wt = BSS .Parameters .ff14SB (wt , ensure_compatible = False ).getMolecule ()
@@ -743,13 +744,14 @@ def test_custom_roi_ring_break_merge():
743744 assert n_bonds_created == 1
744745 assert n_bonds_annihilated == 0
745746
747+
746748@pytest .mark .skipif (has_amber is False , reason = "Requires AMBER to be installed." )
747749def test_custom_roi_map_invalid_outside_roi ():
748750 wt = BSS .IO .readMolecules (
749- BSS .IO .expand (BSS .tutorialUrl (), f "1choFH_apo_wt_flare_processed.pdb" )
751+ BSS .IO .expand (BSS .tutorialUrl (), "1choFH_apo_wt_flare_processed.pdb" )
750752 )[0 ]
751753 mut = BSS .IO .readMolecules (
752- BSS .IO .expand (BSS .tutorialUrl (), f "1choFH_apo_mut_flare_processed.pdb" )
754+ BSS .IO .expand (BSS .tutorialUrl (), "1choFH_apo_mut_flare_processed.pdb" )
753755 )[0 ]
754756
755757 wt = BSS .Parameters .ff14SB (wt , ensure_compatible = False ).getMolecule ()
@@ -761,7 +763,6 @@ def test_custom_roi_map_invalid_outside_roi():
761763 molecule0 = wt ,
762764 molecule1 = mut ,
763765 roi = [15 ],
764-
765766 custom_roi_map = {
766767 0 : 0 ,
767768 1 : 1 ,
@@ -1313,9 +1314,9 @@ def test_ring_breaking_cross_bond_cleanup():
13131314 mol_info .atom_idx (p .atom3 ()).value (),
13141315 }
13151316 for a , b in changing :
1316- assert not (
1317- a in atoms and b in atoms
1318- ), f"improper { suffix } spans absent bond ( { a } , { b } )"
1317+ assert not (a in atoms and b in atoms ), (
1318+ f"improper { suffix } spans absent bond ( { a } , { b } )"
1319+ )
13191320
13201321 # Check that the ring-breaking and ring-making bond properties are set.
13211322 def _read_pairs (prop_name ):
@@ -1326,9 +1327,73 @@ def _read_pairs(prop_name):
13261327
13271328 stored_breaking = _read_pairs ("ring_breaking_bonds" )
13281329 stored_making = _read_pairs ("ring_making_bonds" )
1329- assert (
1330- stored_breaking == ring_breaking
1331- ), f"ring_breaking_bonds property mismatch: { stored_breaking } != { ring_breaking } "
1332- assert (
1333- stored_making == ring_making
1334- ), f"ring_making_bonds property mismatch: { stored_making } != { ring_making } "
1330+ assert stored_breaking == ring_breaking , (
1331+ f"ring_breaking_bonds property mismatch: { stored_breaking } != { ring_breaking } "
1332+ )
1333+ assert stored_making == ring_making , (
1334+ f"ring_making_bonds property mismatch: { stored_making } != { ring_making } "
1335+ )
1336+
1337+
1338+ @pytest .fixture (scope = "session" )
1339+ def ejm31 ():
1340+ return BSS .IO .readMolecules (
1341+ [f"{ url } /lig_ejm31.prm7.bz2" , f"{ url } /lig_ejm31.rst7.bz2" ]
1342+ ).getMolecules ()[0 ]
1343+
1344+
1345+ @pytest .fixture (scope = "session" )
1346+ def jmc28 ():
1347+ return BSS .IO .readMolecules (
1348+ [f"{ url } /lig_jmc28.prm7.bz2" , f"{ url } /lig_jmc28.rst7.bz2" ]
1349+ ).getMolecules ()[0 ]
1350+
1351+
1352+ def test_default_mcs_options ():
1353+ # The MCS defaults should be discoverable, and ring matching is on.
1354+ options = BSS .Align .defaultMCSOptions ()
1355+ assert options ["ringMatchesRingOnly" ] is True
1356+ assert options ["completeRingsOnly" ] is True
1357+
1358+ # The returned dictionary is a copy, so mutating it has no side effects.
1359+ options ["ringMatchesRingOnly" ] = False
1360+ assert BSS .Align .defaultMCSOptions ()["ringMatchesRingOnly" ] is True
1361+
1362+
1363+ def test_mcs_kwargs_ring_matches_ring_only (ejm31 , jmc28 ):
1364+ # Perturbing a methyl to a 2-methylcyclopropyl. Atom 19 is the methyl
1365+ # carbon in ejm31 and the ring carbon bonded to the carbonyl in jmc28.
1366+
1367+ # By default an acyclic atom can't map onto a ring atom, so the whole
1368+ # substituent is unmapped.
1369+ mapping = BSS .Align .matchAtoms (ejm31 , jmc28 )
1370+ assert 19 not in mapping
1371+
1372+ # Allowing the match maps the two carbons onto each other, along with one
1373+ # of the methyl hydrogens.
1374+ mapping = BSS .Align .matchAtoms (
1375+ ejm31 , jmc28 , mcs_kwargs = {"ringMatchesRingOnly" : False }
1376+ )
1377+ assert mapping [19 ] == 19
1378+ assert len (mapping ) == 30
1379+
1380+ # Only two hydrogens are removed and the ring is grown from dummy atoms.
1381+ assert sorted (set (range (32 )) - set (mapping )) == [27 , 28 ]
1382+
1383+
1384+ def test_mcs_kwargs_merge (ejm31 , jmc28 ):
1385+ # The options are used when merge autogenerates a mapping.
1386+ merged = BSS .Align .merge (ejm31 , jmc28 , mcs_kwargs = {"ringMatchesRingOnly" : False })
1387+ sire_mol = merged ._sire_object
1388+
1389+ # A ring grown entirely from dummy atoms breaks no bond between mapped
1390+ # atoms, so the merge doesn't require 'allow_ring_breaking' and the end
1391+ # states have the same number of bonds.
1392+ assert sire_mol .num_atoms () == 41
1393+ assert len (sire_mol .property ("bond0" ).potentials ()) == len (
1394+ sire_mol .property ("bond1" ).potentials ()
1395+ )
1396+
1397+ # No ring is broken or made, so neither property is set.
1398+ assert not sire_mol .has_property ("ring_breaking_bonds" )
1399+ assert not sire_mol .has_property ("ring_making_bonds" )
0 commit comments