1 /* 2 * Copyright (c) 2015 John May <jwmay@users.sf.net> 3 * 4 * Contact: cdk-devel@lists.sourceforge.net 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation; either version 2.1 of the License, or (at 9 * your option) any later version. All we ask is that proper credit is given 10 * for our work, which includes - but is not limited to - adding the above 11 * copyright notice to the beginning of your source code files, and to any 12 * copyright notice that you may distribute with programs based on this work. 13 * 14 * This program is distributed in the hope that it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17 * License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 U 22 */ 23 package org.openscience.cdk.forcefield.mmff; 24 25 import org.junit.AfterClass; 26 import org.junit.BeforeClass; 27 import org.junit.Test; 28 import org.openscience.cdk.exception.InvalidSmilesException; 29 import org.openscience.cdk.interfaces.IAtomContainer; 30 import org.openscience.cdk.silent.SilentChemObjectBuilder; 31 import org.openscience.cdk.smiles.SmilesParser; 32 import org.openscience.cdk.tools.manipulator.AtomContainerManipulator; 33 34 import static org.hamcrest.CoreMatchers.is; 35 import static org.hamcrest.MatcherAssert.assertThat; 36 import static org.junit.Assert.assertArrayEquals; 37 import static org.junit.Assert.assertEquals; 38 import static org.junit.Assert.assertFalse; 39 import static org.junit.Assert.assertTrue; 40 41 /** 42 * @author John May 43 */ 44 public class MmffTest { 45 46 private static SmilesParser smipar = null; 47 private static Mmff mmff = null; 48 setUp()49 @BeforeClass public static void setUp() { 50 smipar = new SmilesParser(SilentChemObjectBuilder.getInstance()); 51 mmff = new Mmff(); 52 } 53 tearDown()54 @AfterClass public static void tearDown() { 55 smipar = null; 56 mmff = null; 57 } 58 tetrazoleAnion()59 @Test public void tetrazoleAnion() throws InvalidSmilesException { 60 IAtomContainer mol = loadSmi("[N-]1N=CN=N1"); 61 assertTrue(mmff.assignAtomTypes(mol)); 62 assertAtomTypes(mol, "N5M", "N5M", "C5", "N5M", "N5M", "HC"); 63 assertTrue(mmff.partialCharges(mol)); 64 assertPartialCharges(mol, -0.25, -0.5875, 0.525, -0.5875, -0.25, 0.15); 65 assertPartialChargeSum(mol, -1); 66 } 67 tetrazole()68 @Test public void tetrazole() throws InvalidSmilesException { 69 IAtomContainer mol = loadSmi("N1N=CN=N1"); 70 assertTrue(mmff.assignAtomTypes(mol)); 71 assertAtomTypes(mol, "NPYL", "N5A", "C5B", "N5B", "N5A", "HPYL", "HC"); 72 assertTrue(mmff.partialCharges(mol)); 73 assertPartialCharges(mol, 0.566, -0.7068, 0.366, -0.2272, -0.418, 0.27, 0.15); 74 assertPartialChargeSum(mol, 0); 75 } 76 untypedAtom()77 @Test public void untypedAtom() throws InvalidSmilesException { 78 IAtomContainer mol = loadSmi("[Se]C1C=CC=C1"); 79 assertFalse(mmff.assignAtomTypes(mol)); 80 assertAtomTypes(mol, "UNK", "CR", "C=C", "C=C", "C=C", "C=C", "HC", "HC", "HC", "HC", "HC"); 81 assertTrue(mmff.partialCharges(mol)); 82 assertPartialCharges(mol, 0.0, 0.2764, -0.2882, -0.15, -0.15, -0.2882, 0.0, 0.15, 0.15, 0.15, 0.15); 83 assertPartialChargeSum(mol, 0); 84 } 85 clearProps()86 @Test public void clearProps() throws InvalidSmilesException { 87 IAtomContainer mol = loadSmi("o1cccc1"); 88 int sizeBefore = mol.getProperties().size(); 89 assertTrue(mmff.assignAtomTypes(mol)); 90 assertTrue(mmff.partialCharges(mol)); 91 mmff.clearProps(mol); 92 assertThat(mol.getProperties().size(), is(sizeBefore)); 93 } 94 nitrobenzeneCovalent()95 @Test public void nitrobenzeneCovalent() throws InvalidSmilesException { 96 IAtomContainer mol = loadSmi("c1ccccc1N(=O)=O"); 97 assertTrue(mmff.assignAtomTypes(mol)); 98 assertAtomTypes(mol, "CB", "CB", "CB", "CB", "CB", "CB", "NO2", "O2N", "O2N", "HC", "HC", "HC", "HC", "HC"); 99 assertTrue(mmff.partialCharges(mol)); 100 assertPartialCharges(mol, -0.15, -0.15, -0.15, -0.15, -0.15, 0.133, 0.907, -0.52, -0.52, 0.15, 0.15, 0.15, 0.15, 0.15); 101 assertPartialChargeSum(mol, 0); 102 } 103 nitrobenzeneChargeSeparated()104 @Test public void nitrobenzeneChargeSeparated() throws InvalidSmilesException { 105 IAtomContainer mol = loadSmi("c1ccccc1[N+](-[O-])=O"); 106 assertTrue(mmff.assignAtomTypes(mol)); 107 assertAtomTypes(mol, "CB", "CB", "CB", "CB", "CB", "CB", "NO2", "O2N", "O2N", "HC", "HC", "HC", "HC", "HC"); 108 assertTrue(mmff.partialCharges(mol)); 109 assertPartialCharges(mol, -0.15, -0.15, -0.15, -0.15, -0.15, 0.133, 0.907, -0.52, -0.52, 0.15, 0.15, 0.15, 0.15, 0.15); 110 assertPartialChargeSum(mol, 0); 111 } 112 113 /* TABLE V - CH3OH */ methanol()114 @Test public void methanol() throws Exception { 115 IAtomContainer mol = loadSmi("CO"); 116 assertTrue(mmff.assignAtomTypes(mol)); 117 assertTrue(mmff.partialCharges(mol)); 118 assertPartialCharges(mol, 119 0.28, -0.68, 0.0, 0.0, 0.0, 0.4); 120 assertPartialChargeSum(mol, 0); 121 } 122 123 /* TABLE V - CH3NH2 */ methylamine()124 @Test public void methylamine() throws Exception { 125 IAtomContainer mol = loadSmi("CN"); 126 assertTrue(mmff.assignAtomTypes(mol)); 127 assertTrue(mmff.partialCharges(mol)); 128 assertPartialCharges(mol, 129 0.27, -0.99, 0.0, 0.0, 0.0, 0.36, 0.36); 130 assertPartialChargeSum(mol, 0); 131 } 132 133 /* TABLE V - CH3CN */ acetonitrile()134 @Test public void acetonitrile() throws Exception { 135 IAtomContainer mol = loadSmi("CC#N"); 136 assertTrue(mmff.assignAtomTypes(mol)); 137 assertTrue(mmff.partialCharges(mol)); 138 assertPartialCharges(mol, 139 0.2, 0.357, -0.557, 0.0, 0.0, 0.0); 140 assertPartialChargeSum(mol, 0); 141 } 142 143 /* TABLE V - CH3OCH3 */ dimethylether()144 @Test public void dimethylether() throws Exception { 145 IAtomContainer mol = loadSmi("COC"); 146 assertTrue(mmff.assignAtomTypes(mol)); 147 assertTrue(mmff.partialCharges(mol)); 148 assertPartialCharges(mol, 149 0.28, -0.56, 0.28, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 150 assertPartialChargeSum(mol, 0); 151 } 152 153 /* TABLE V - CH3SH */ methanethiol()154 @Test public void methanethiol() throws Exception { 155 IAtomContainer mol = loadSmi("CS"); 156 assertTrue(mmff.assignAtomTypes(mol)); 157 assertTrue(mmff.partialCharges(mol)); 158 assertPartialCharges(mol, 159 0.23, -0.41, 0.0, 0.0, 0.0, 0.18); 160 assertPartialChargeSum(mol, 0); 161 } 162 163 /* TABLE V - CH3Cl */ chloromethane()164 @Test public void chloromethane() throws Exception { 165 IAtomContainer mol = loadSmi("CCl"); 166 assertTrue(mmff.assignAtomTypes(mol)); 167 assertTrue(mmff.partialCharges(mol)); 168 assertPartialCharges(mol, 169 0.29, -0.29, 0.0, 0.0, 0.0); 170 assertPartialChargeSum(mol, 0); 171 } 172 173 /* TABLE V - C2H6 */ ethane()174 @Test public void ethane() throws Exception { 175 IAtomContainer mol = loadSmi("CC"); 176 assertTrue(mmff.assignAtomTypes(mol)); 177 assertTrue(mmff.partialCharges(mol)); 178 assertPartialCharges(mol, 179 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 180 assertPartialChargeSum(mol, 0); 181 } 182 183 /* TABLE V - CH3CONH2 (note wrong formula) */ acetamide()184 @Test public void acetamide() throws Exception { 185 IAtomContainer mol = loadSmi("O=C(N)C"); 186 assertTrue(mmff.assignAtomTypes(mol)); 187 assertTrue(mmff.partialCharges(mol)); 188 assertPartialCharges(mol, 189 -0.57, 0.569, -0.8, 0.061, 0.37, 0.37, 0.0, 0.0, 0.0); 190 assertPartialChargeSum(mol, 0); 191 } 192 193 /* TABLE V - CH3COOH */ aceticAcid()194 @Test public void aceticAcid() throws Exception { 195 IAtomContainer mol = loadSmi("CC(O)=O"); 196 assertTrue(mmff.assignAtomTypes(mol)); 197 assertTrue(mmff.partialCharges(mol)); 198 assertPartialCharges(mol, 199 0.061, 0.659, -0.65, -0.57, 0.0, 0.0, 0.0, 0.5); 200 assertPartialChargeSum(mol, 0); 201 } 202 203 /* TABLE V - (CH3)2CO */ acetone()204 @Test public void acetone() throws Exception { 205 IAtomContainer mol = loadSmi("CC(=O)C"); 206 assertTrue(mmff.assignAtomTypes(mol)); 207 assertTrue(mmff.partialCharges(mol)); 208 assertPartialCharges(mol, 209 0.061, 0.447, -0.57, 0.061, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 210 assertPartialChargeSum(mol, 0); 211 } 212 213 /* TABLE V - CH3COOCH3 */ methylacetate()214 @Test public void methylacetate() throws Exception { 215 IAtomContainer mol = loadSmi("O=C(OC)C"); 216 assertTrue(mmff.assignAtomTypes(mol)); 217 assertTrue(mmff.partialCharges(mol)); 218 assertPartialCharges(mol, 219 -0.57, 0.659, -0.43, 0.28, 0.061, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 220 assertPartialChargeSum(mol, 0); 221 } 222 223 /* TABLE V - C6H6 */ benzene()224 @Test public void benzene() throws Exception { 225 IAtomContainer mol = loadSmi("c1ccccc1"); 226 assertTrue(mmff.assignAtomTypes(mol)); 227 assertTrue(mmff.partialCharges(mol)); 228 assertPartialCharges(mol, 229 -0.15, -0.15, -0.15, -0.15, -0.15, -0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15); 230 assertPartialChargeSum(mol, 0); 231 } 232 233 /* TABLE V - C5H5N */ pyridine()234 @Test public void pyridine() throws Exception { 235 IAtomContainer mol = loadSmi("C1=CC=NC=C1"); 236 assertTrue(mmff.assignAtomTypes(mol)); 237 assertTrue(mmff.partialCharges(mol)); 238 assertPartialCharges(mol, 239 -0.15, -0.15, 0.16, -0.62, 0.16, -0.15, 0.15, 0.15, 0.15, 0.15, 0.15); 240 assertPartialChargeSum(mol, 0); 241 } 242 243 /* TABLE V - C6H5NH2 */ aniline()244 @Test public void aniline() throws Exception { 245 IAtomContainer mol = loadSmi("C1=CC=C(N)C=C1"); 246 assertTrue(mmff.assignAtomTypes(mol)); 247 assertTrue(mmff.partialCharges(mol)); 248 assertPartialCharges(mol, 249 -0.15, -0.15, -0.15, 0.1, -0.9, -0.15, -0.15, 0.15, 0.15, 0.15, 0.4, 0.4, 0.15, 0.15); 250 assertPartialChargeSum(mol, 0); 251 } 252 253 /* TABLE V - imidazole */ imidazole()254 @Test public void imidazole() throws Exception { 255 IAtomContainer mol = loadSmi("C=1NC=NC1"); 256 assertTrue(mmff.assignAtomTypes(mol)); 257 assertTrue(mmff.partialCharges(mol)); 258 assertPartialCharges(mol, 259 -0.3016, 0.0332, 0.0365, -0.5653, 0.0772, 0.15, 0.27, 0.15, 0.15); 260 assertPartialChargeSum(mol, 0); 261 } 262 263 /* TABLE V - H2O */ water()264 @Test public void water() throws Exception { 265 IAtomContainer mol = loadSmi("O"); 266 assertTrue(mmff.assignAtomTypes(mol)); 267 assertTrue(mmff.partialCharges(mol)); 268 assertPartialCharges(mol, 269 -0.86, 0.43, 0.43); 270 assertPartialChargeSum(mol, 0); 271 } 272 273 /* TABLE V - CH3CO2- */ acetate()274 @Test public void acetate() throws Exception { 275 IAtomContainer mol = loadSmi("CC([O-])=O"); 276 assertTrue(mmff.assignAtomTypes(mol)); 277 assertTrue(mmff.partialCharges(mol)); 278 assertPartialCharges(mol, 279 -0.106, 0.906, -0.9, -0.9, 0.0, 0.0, 0.0); 280 assertPartialChargeSum(mol, -1); 281 } 282 283 /* TABLE V - CH3NH3(+) */ methanaminium()284 @Test public void methanaminium() throws Exception { 285 IAtomContainer mol = loadSmi("C[NH3+]"); 286 assertTrue(mmff.assignAtomTypes(mol)); 287 assertTrue(mmff.partialCharges(mol)); 288 assertPartialCharges(mol, 289 0.503, -0.853, 0.0, 0.0, 0.0, 0.45, 0.45, 0.45); 290 assertPartialChargeSum(mol, +1); 291 } 292 293 /* TABLE V - Imidazolium(+) */ imidazolium()294 @Test public void imidazolium() throws Exception { 295 IAtomContainer mol = loadSmi("[nH+]1c[nH]cc1"); 296 assertTrue(mmff.assignAtomTypes(mol)); 297 assertTrue(mmff.partialCharges(mol)); 298 assertPartialCharges(mol, 299 -0.7, 0.65, -0.7, 0.2, 0.2, 0.45, 0.15, 0.45, 0.15, 0.15); 300 assertPartialChargeSum(mol, +1); 301 } 302 303 /* TABLE V - (-)O2C(CH2)6NH3(+) */ _7aminoheptanoicAcid()304 @Test public void _7aminoheptanoicAcid() throws Exception { 305 IAtomContainer mol = loadSmi("[NH3+]CCCCCCC([O-])=O"); 306 assertTrue(mmff.assignAtomTypes(mol)); 307 assertTrue(mmff.partialCharges(mol)); 308 assertPartialCharges(mol, 309 -0.853, 0.503, 0.0, 0.0, 0.0, 0.0, -0.106, 0.906, -0.9, -0.9, 0.45, 0.45, 0.45, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 310 assertPartialChargeSum(mol, 0); 311 } 312 ethoxyethane()313 @Test public void ethoxyethane() throws Exception { 314 IAtomContainer mol = loadSmi("CCOCC"); 315 assertTrue(mmff.assignAtomTypes(mol)); 316 assertTrue(mmff.partialCharges(mol)); 317 assertPartialCharges(mol, 318 0.0, 0.28, -0.56, 0.28, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 319 assertPartialChargeSum(mol, 0); 320 } 321 loadSmi(String smi)322 private IAtomContainer loadSmi(String smi) throws InvalidSmilesException { 323 IAtomContainer mol = smipar.parseSmiles(smi); 324 AtomContainerManipulator.convertImplicitToExplicitHydrogens(mol); 325 return mol; 326 } 327 328 /* [PO4]3- */ phosphate()329 @Test public void phosphate() throws Exception { 330 IAtomContainer mol = loadSmi("[O-]P([O-])([O-])=O"); 331 assertTrue(mmff.assignAtomTypes(mol)); 332 assertTrue(mmff.partialCharges(mol)); 333 assertPartialCharges(mol, 334 -1.075, 1.3, -1.075, -1.075, -1.075); 335 } 336 337 /* [HOPO3]2- */ hydrogenPhosphate()338 @Test public void hydrogenPhosphate() throws Exception { 339 IAtomContainer mol = loadSmi("OP([O-])([O-])=O"); 340 assertTrue(mmff.assignAtomTypes(mol)); 341 assertTrue(mmff.partialCharges(mol)); 342 assertPartialCharges(mol, 343 -0.7712, 1.3712, -1.033, -1.033, -1.033, 0.5); 344 } 345 346 /* [H2OPO3]- */ dihydrogenPhosphate()347 @Test public void dihydrogenPhosphate() throws Exception { 348 IAtomContainer mol = loadSmi("OP([O-])(O)=O"); 349 assertTrue(mmff.assignAtomTypes(mol)); 350 assertTrue(mmff.partialCharges(mol)); 351 assertPartialCharges(mol, 352 -0.7712, 1.4424, -0.95, -0.7712, -0.95, 0.5, 0.5); 353 } 354 355 /* H3OPO3 */ phosphoricAcid()356 @Test public void phosphoricAcid() throws Exception { 357 IAtomContainer mol = loadSmi("OP(O)(O)=O"); 358 assertTrue(mmff.assignAtomTypes(mol)); 359 assertTrue(mmff.partialCharges(mol)); 360 assertPartialCharges(mol, 361 -0.7712, 1.514, -0.7712, -0.7712, -0.7, 0.5, 0.5, 0.5); 362 } 363 364 /* SEYWUO - validation suite showing positive charge charging */ SEYWUO()365 @Test public void SEYWUO() throws Exception { 366 IAtomContainer mol = loadSmi("[H]OC(=S)[N-][N+]1=C(N([H])[H])C([H])([H])N([H])C1=O"); 367 assertTrue(mmff.assignAtomTypes(mol)); 368 assertAtomTypes(mol, 369 "HOCS", "OC=S", "C=S", "S=C", "NM", "NCN+", "CNN+", "NCN+", "HNN+", "HNN+", "CR", "HC", "HC", "NC=O", "HNCO", "CONN", "O=CN"); 370 assertTrue(mmff.effectiveCharges(mol)); 371 assertPartialCharges(mol, 372 0.0, 0.0, -0.25, 0.0, -0.5, 0.25, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 373 assertTrue(mmff.partialCharges(mol)); 374 assertPartialCharges(mol, 375 0.4, -0.55, 0.31, -0.38, -0.179, -0.8364, 0.6038, -0.7544, 0.45, 0.45, 0.4051, 0.0, 0.0, -0.7301, 0.37, 1.011, -0.57); 376 } 377 assertAtomTypes(IAtomContainer mol, String... expected)378 private void assertAtomTypes(IAtomContainer mol, String... expected) { 379 String[] actual = new String[mol.getAtomCount()]; 380 for (int i = 0; i < mol.getAtomCount(); i++) 381 actual[i] = mol.getAtom(i).getAtomTypeName(); 382 assertArrayEquals(expected, actual); 383 } 384 assertPartialCharges(IAtomContainer mol, double... expected)385 private void assertPartialCharges(IAtomContainer mol, double... expected) { 386 double[] actual = new double[mol.getAtomCount()]; 387 for (int i = 0; i < mol.getAtomCount(); i++) 388 actual[i] = mol.getAtom(i).getCharge(); 389 assertArrayEquals(expected, actual, 0.001); 390 } 391 assertPartialChargeSum(IAtomContainer mol, double expected)392 private void assertPartialChargeSum(IAtomContainer mol, double expected) { 393 double actual = 0; 394 for (int i = 0; i < mol.getAtomCount(); i++) 395 actual += mol.getAtom(i).getCharge(); 396 assertEquals("Unexpected partial charge sum", 397 expected, actual, 0.001); 398 } 399 } 400