|
4 | 4 | package com.bioinceptionlabs.aamtool; |
5 | 5 |
|
6 | 6 | import static org.junit.Assert.assertEquals; |
| 7 | +import static org.junit.Assert.assertNotNull; |
7 | 8 | import static org.junit.Assert.assertTrue; |
8 | 9 | import org.junit.Test; |
9 | 10 | import org.openscience.cdk.exception.InvalidSmilesException; |
@@ -1076,6 +1077,96 @@ public void testLeberAcetyltransferase() throws Exception { |
1076 | 1077 | .getFormedCleavedWFingerprint().getFeatureCount() > 0); |
1077 | 1078 | } |
1078 | 1079 |
|
| 1080 | + // ---- USPTO failure cases: multi-reagent reactions where MCS can mismap ---- |
| 1081 | + |
| 1082 | + /** |
| 1083 | + * Reductive amination: cyclobutanone + aminothiophene ester → amine product. |
| 1084 | + * NaBH(OAc)₃ reducing agent (not shown). Expected: 1 bond change (C-N formed, |
| 1085 | + * C=O cleaved → C-OH or C-N). The mapper should identify the new C-N bond. |
| 1086 | + */ |
| 1087 | + @Test |
| 1088 | + public void testReductiveAmination() throws Exception { |
| 1089 | + String smiles = "O=C1CCC1.COC(=O)c1sccc1N>>COC(=O)c1sccc1NC1CCC1"; |
| 1090 | + ReactionMechanismTool rmt = performAtomAtomMapping( |
| 1091 | + new SmilesParser(SilentChemObjectBuilder.getInstance()).parseReactionSmiles(smiles), |
| 1092 | + "ReductiveAmination"); |
| 1093 | + assertNotNull("Should produce a mapping", rmt.getSelectedSolution()); |
| 1094 | + int changes = rmt.getSelectedSolution().getBondChangeCalculator() |
| 1095 | + .getFormedCleavedWFingerprint().getFeatureCount(); |
| 1096 | + assertTrue("Reductive amination should have ≤3 bond changes (C=O→C-N), got " + changes, |
| 1097 | + changes <= 3); |
| 1098 | + } |
| 1099 | + |
| 1100 | + /** |
| 1101 | + * O-alkylation: piperazine chloroalkyl + phenol → ether product. |
| 1102 | + * Expected: 1 bond change (C-O formed, C-Cl cleaved). |
| 1103 | + * Challenge: MCS must map piperazine correctly to avoid false positives. |
| 1104 | + */ |
| 1105 | + @Test |
| 1106 | + public void testOAlkylation() throws Exception { |
| 1107 | + String smiles = "ClCCCN1CCN(Cc2ccc(Cl)cc2)CC1.Oc1ccc2oc3ccccc3c2c1>>c1ccc2c(c1)c1cc(OCCCN3CCN(Cc4ccc(Cl)cc4)CC3)ccc1o2"; |
| 1108 | + ReactionMechanismTool rmt = performAtomAtomMapping( |
| 1109 | + new SmilesParser(SilentChemObjectBuilder.getInstance()).parseReactionSmiles(smiles), |
| 1110 | + "OAlkylation"); |
| 1111 | + assertNotNull("Should produce a mapping", rmt.getSelectedSolution()); |
| 1112 | + int changes = rmt.getSelectedSolution().getBondChangeCalculator() |
| 1113 | + .getFormedCleavedWFingerprint().getFeatureCount(); |
| 1114 | + assertTrue("O-alkylation should have ≤3 bond changes (C-Cl→C-O), got " + changes, |
| 1115 | + changes <= 3); |
| 1116 | + } |
| 1117 | + |
| 1118 | + /** |
| 1119 | + * N-alkylation: benzyl chloride + indole → N-benzylindole. |
| 1120 | + * Expected: 1 bond change (C-N formed, C-Cl cleaved). |
| 1121 | + * Challenge: MCS must orient benzyl group correctly. |
| 1122 | + */ |
| 1123 | + @Test |
| 1124 | + public void testNAlkylation() throws Exception { |
| 1125 | + String smiles = "N#Cc1ccccc1CCl.c1ccc2[nH]ccc2c1>>N#Cc1ccccc1Cn1ccc2ccccc21"; |
| 1126 | + ReactionMechanismTool rmt = performAtomAtomMapping( |
| 1127 | + new SmilesParser(SilentChemObjectBuilder.getInstance()).parseReactionSmiles(smiles), |
| 1128 | + "NAlkylation"); |
| 1129 | + assertNotNull("Should produce a mapping", rmt.getSelectedSolution()); |
| 1130 | + int changes = rmt.getSelectedSolution().getBondChangeCalculator() |
| 1131 | + .getFormedCleavedWFingerprint().getFeatureCount(); |
| 1132 | + assertTrue("N-alkylation should have ≤3 bond changes (C-Cl→C-N), got " + changes, |
| 1133 | + changes <= 3); |
| 1134 | + } |
| 1135 | + |
| 1136 | + /** |
| 1137 | + * Reductive amination #2: pyrrolidinone + aminopyridine → aminopyrrolidine. |
| 1138 | + * NaBH₄ reduction (not shown). Expected: ~2 bond changes. |
| 1139 | + */ |
| 1140 | + @Test |
| 1141 | + public void testReductiveAmination2() throws Exception { |
| 1142 | + String smiles = "O=C1CCN(Cc2ccccc2)C1.Cc1cc(C)nc(N)c1>>Cc1cc(C)nc(NC2CCN(Cc3ccccc3)C2)c1"; |
| 1143 | + ReactionMechanismTool rmt = performAtomAtomMapping( |
| 1144 | + new SmilesParser(SilentChemObjectBuilder.getInstance()).parseReactionSmiles(smiles), |
| 1145 | + "ReductiveAmination2"); |
| 1146 | + assertNotNull("Should produce a mapping", rmt.getSelectedSolution()); |
| 1147 | + int changes = rmt.getSelectedSolution().getBondChangeCalculator() |
| 1148 | + .getFormedCleavedWFingerprint().getFeatureCount(); |
| 1149 | + assertTrue("Reductive amination should have ≤4 bond changes, got " + changes, |
| 1150 | + changes <= 4); |
| 1151 | + } |
| 1152 | + |
| 1153 | + /** |
| 1154 | + * Friedel-Crafts acylation: acetic anhydride + indole → 3-acetylindole. |
| 1155 | + * AlCl₃ catalyst (not shown). Expected: 1-2 bond changes. |
| 1156 | + */ |
| 1157 | + @Test |
| 1158 | + public void testFriedelCraftsAcylation() throws Exception { |
| 1159 | + String smiles = "CC(=O)OC(C)=O.c1ccc2[nH]ccc2c1>>CC(=O)c1c[nH]c2ccccc12"; |
| 1160 | + ReactionMechanismTool rmt = performAtomAtomMapping( |
| 1161 | + new SmilesParser(SilentChemObjectBuilder.getInstance()).parseReactionSmiles(smiles), |
| 1162 | + "FriedelCrafts"); |
| 1163 | + assertNotNull("Should produce a mapping", rmt.getSelectedSolution()); |
| 1164 | + int changes = rmt.getSelectedSolution().getBondChangeCalculator() |
| 1165 | + .getFormedCleavedWFingerprint().getFeatureCount(); |
| 1166 | + assertTrue("Friedel-Crafts should have ≤4 bond changes, got " + changes, |
| 1167 | + changes <= 4); |
| 1168 | + } |
| 1169 | + |
1079 | 1170 | @Test |
1080 | 1171 | public void testCanonicalHashDeterminism() { |
1081 | 1172 | // Same reaction must produce identical canonical hash |
|
0 commit comments