1 /* Copyright (C) 2009-2010 Syed Asad Rahman <asad@ebi.ac.uk> 2 * 3 * Contact: cdk-devel@lists.sourceforge.net 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public License 7 * as published by the Free Software Foundation; either version 2.1 8 * of the License, or (at your option) any later version. 9 * All we ask is that proper credit is given for our work, which includes 10 * - but is not limited to - adding the above copyright notice to the beginning 11 * of your container code files, and to any copyright notice that you may distribute 12 * with programs based on this work. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public 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 USA. 22 */ 23 package org.openscience.cdk.smsd.algorithm.mcgregor; 24 25 import java.io.IOException; 26 import java.util.ArrayList; 27 import java.util.List; 28 import java.util.Map; 29 import org.openscience.cdk.interfaces.IAtom; 30 import org.openscience.cdk.interfaces.IAtomContainer; 31 import org.openscience.cdk.interfaces.IBond; 32 import org.openscience.cdk.isomorphism.matchers.IQueryAtom; 33 import org.openscience.cdk.isomorphism.matchers.IQueryAtomContainer; 34 import org.openscience.cdk.isomorphism.matchers.IQueryBond; 35 import org.openscience.cdk.smsd.algorithm.matchers.AtomMatcher; 36 import org.openscience.cdk.smsd.algorithm.matchers.BondMatcher; 37 import org.openscience.cdk.smsd.algorithm.matchers.DefaultBondMatcher; 38 import org.openscience.cdk.smsd.algorithm.matchers.DefaultMCSPlusAtomMatcher; 39 import org.openscience.cdk.smsd.algorithm.matchers.DefaultMatcher; 40 import org.openscience.cdk.smsd.helper.BinaryTree; 41 42 /** 43 * Class to perform check/methods for McGregor class. 44 * @cdk.module smsd 45 * @cdk.githash 46 * @author Syed Asad Rahman <asad@ebi.ac.uk> 47 * @deprecated SMSD has been deprecated from the CDK with a newer, more recent 48 * version of SMSD is available at <a href="http://github.com/asad/smsd">http://github.com/asad/smsd</a>. 49 */ 50 @Deprecated 51 public class McGregorChecks { 52 53 /** 54 * 55 * @param source 56 * @param target 57 * @param neighborBondNumA 58 * @param neighborBondNumB 59 * @param iBondNeighborAtomsA 60 * @param iBondNeighborAtomsB 61 * @param cBondNeighborsA 62 * @param cBondNeighborsB 63 * @param shouldMatchBonds 64 * @return 65 */ isFurtherMappingPossible(IAtomContainer source, IAtomContainer target, int neighborBondNumA, int neighborBondNumB, List<Integer> iBondNeighborAtomsA, List<Integer> iBondNeighborAtomsB, List<String> cBondNeighborsA, List<String> cBondNeighborsB, boolean shouldMatchBonds)66 protected static boolean isFurtherMappingPossible(IAtomContainer source, IAtomContainer target, 67 int neighborBondNumA, int neighborBondNumB, List<Integer> iBondNeighborAtomsA, 68 List<Integer> iBondNeighborAtomsB, List<String> cBondNeighborsA, List<String> cBondNeighborsB, 69 boolean shouldMatchBonds) { 70 71 for (int row = 0; row < neighborBondNumA; row++) { 72 // System.out.println("i " + row); 73 String g1A = cBondNeighborsA.get(row * 4 + 0); 74 String g2a = cBondNeighborsA.get(row * 4 + 1); 75 76 for (int column = 0; column < neighborBondNumB; column++) { 77 78 String g1B = cBondNeighborsB.get(column * 4 + 0); 79 String g2B = cBondNeighborsB.get(column * 4 + 1); 80 81 if (isAtomMatch(g1A, g2a, g1B, g2B)) { 82 try { 83 84 int indexI = iBondNeighborAtomsA.get(row * 3 + 0); 85 int indexIPlus1 = iBondNeighborAtomsA.get(row * 3 + 1); 86 87 int indexJ = iBondNeighborAtomsB.get(column * 3 + 0); 88 int indexJPlus1 = iBondNeighborAtomsB.get(column * 3 + 1); 89 90 IAtom r1A = source.getAtom(indexI); 91 IAtom r2A = source.getAtom(indexIPlus1); 92 IBond reactantBond = source.getBond(r1A, r2A); 93 94 IAtom p1B = target.getAtom(indexJ); 95 IAtom p2B = target.getAtom(indexJPlus1); 96 IBond productBond = target.getBond(p1B, p2B); 97 98 if (isMatchFeasible(source, reactantBond, target, productBond, shouldMatchBonds)) { 99 return true; 100 } 101 } catch (Exception e) { 102 e.printStackTrace(); 103 } 104 } 105 } 106 } 107 108 return false; 109 } 110 isMatchFeasible(IAtomContainer ac1, IBond bondA1, IAtomContainer ac2, IBond bondA2, boolean shouldMatchBonds)111 protected static boolean isMatchFeasible(IAtomContainer ac1, IBond bondA1, IAtomContainer ac2, IBond bondA2, 112 boolean shouldMatchBonds) { 113 114 if (ac1 instanceof IQueryAtomContainer) { 115 if (((IQueryBond) bondA1).matches(bondA2)) { 116 IQueryAtom atom1 = (IQueryAtom) (bondA1.getBegin()); 117 IQueryAtom atom2 = (IQueryAtom) (bondA1.getEnd()); 118 // ok, bonds match 119 if (atom1.matches(bondA2.getBegin()) && atom2.matches(bondA2.getEnd()) 120 || atom1.matches(bondA2.getEnd()) && atom2.matches(bondA2.getBegin())) { 121 // ok, atoms match in either order 122 return true; 123 } 124 return false; 125 } 126 return false; 127 } else { 128 129 //Bond Matcher 130 BondMatcher bondMatcher = new DefaultBondMatcher(ac1, bondA1, shouldMatchBonds); 131 //Atom Matcher 132 AtomMatcher atomMatcher1 = new DefaultMCSPlusAtomMatcher(ac1, bondA1.getBegin(), shouldMatchBonds); 133 //Atom Matcher 134 AtomMatcher atomMatcher2 = new DefaultMCSPlusAtomMatcher(ac1, bondA1.getEnd(), shouldMatchBonds); 135 136 if (DefaultMatcher.isBondMatch(bondMatcher, ac2, bondA2, shouldMatchBonds) 137 && DefaultMatcher.isAtomMatch(atomMatcher1, atomMatcher2, ac2, bondA2, shouldMatchBonds)) { 138 return true; 139 } 140 return false; 141 } 142 } 143 144 /** 145 * 146 * @param mappedAtomsSize 147 * @param atomFromOtherMolecule 148 * @param molecule 149 * @param mappedAtomsOrg 150 * @return 151 */ searchCorrespondingAtom(int mappedAtomsSize, int atomFromOtherMolecule, int molecule, List<Integer> mappedAtomsOrg)152 protected static int searchCorrespondingAtom(int mappedAtomsSize, int atomFromOtherMolecule, int molecule, 153 List<Integer> mappedAtomsOrg) { 154 155 List<Integer> mappedAtoms = new ArrayList<Integer>(mappedAtomsOrg); 156 157 int correspondingAtom = 0; 158 for (int a = 0; a < mappedAtomsSize; a++) { 159 if ((molecule == 1) && (mappedAtoms.get(a * 2 + 0).intValue() == atomFromOtherMolecule)) { 160 correspondingAtom = mappedAtoms.get(a * 2 + 1); 161 } 162 if ((molecule == 2) && (mappedAtoms.get(a * 2 + 1).intValue() == atomFromOtherMolecule)) { 163 correspondingAtom = mappedAtoms.get(a * 2 + 0); 164 } 165 } 166 return correspondingAtom; 167 } 168 169 /** 170 * 171 * @param g1A 172 * @param g2A 173 * @param g1B 174 * @param g2B 175 * @return 176 */ isAtomMatch(String g1A, String g2A, String g1B, String g2B)177 protected static boolean isAtomMatch(String g1A, String g2A, String g1B, String g2B) { 178 if ((g1A.compareToIgnoreCase(g1B) == 0 && g2A.compareToIgnoreCase(g2B) == 0) 179 || (g1A.compareToIgnoreCase(g2B) == 0 && g2A.compareToIgnoreCase(g1B) == 0)) { 180 return true; 181 } 182 return false; 183 } 184 185 /* 186 * Modified function call by ASAD in Java have to check 187 */ removeTreeStructure(BinaryTree curStruc)188 protected static int removeTreeStructure(BinaryTree curStruc) { 189 190 BinaryTree equalStruc = curStruc.getEqual(); 191 BinaryTree notEqualStruc = curStruc.getNotEqual(); 192 curStruc = null; 193 194 if (equalStruc != null) { 195 removeTreeStructure(equalStruc); 196 } 197 198 if (notEqualStruc != null) { 199 removeTreeStructure(notEqualStruc); 200 } 201 202 return 0; 203 } 204 205 //Function compaires a structure array with itself. Sometimes a mapping occurs several times within the array. 206 //The function eliminates these recurring mappings. Function is called in function best_solution. 207 //The function is called by itself as long as the last list element is processed. 208 /** 209 * 210 * @param atomMapping 211 * @return 212 */ removeRecurringMappings(List<Integer> atomMapping)213 protected static List<Integer> removeRecurringMappings(List<Integer> atomMapping) { 214 215 boolean exist = true; 216 List<Integer> tempMap = new ArrayList<Integer>(); 217 int tempCounter = 0; 218 int atomMappingSize = atomMapping.size(); 219 for (int x = 0; x < atomMappingSize; x += 2) { 220 int atom = atomMapping.get(x); 221 for (int y = x + 2; y < atomMappingSize; y += 2) { 222 if (atom == atomMapping.get(y)) { 223 exist = false; 224 } 225 } 226 if (exist == true) { 227 tempMap.add(atomMapping.get(x + 0)); 228 tempMap.add(atomMapping.get(x + 1)); 229 tempCounter += 2; 230 } 231 232 exist = true; 233 } 234 235 return tempMap; 236 } 237 238 /** 239 * The function is called in function partsearch. The function is given a temporary matrix and a position (row/column) 240 * within this matrix. First the function sets all entries to zero, which can be exlcuded in respect to the current 241 * atom by atom matching. After this the function replaces all entries in the same row and column of the current 242 * position by zeros. Only the entry of the current position is set to one. 243 * Return value "count_arcsleft" counts the number of arcs, which are still in the matrix. 244 * @param row 245 * @param column 246 * @param marcs 247 * @param mcGregorHelper 248 */ removeRedundantArcs(int row, int column, List<Integer> marcs, McgregorHelper mcGregorHelper)249 protected static void removeRedundantArcs(int row, int column, List<Integer> marcs, McgregorHelper mcGregorHelper) { 250 int neighborBondNumA = mcGregorHelper.getNeighborBondNumA(); 251 int neighborBondNumB = mcGregorHelper.getNeighborBondNumB(); 252 List<Integer> iBondNeighborAtomsA = mcGregorHelper.getiBondNeighborAtomsA(); 253 List<Integer> iBondNeighborAtomsB = mcGregorHelper.getiBondNeighborAtomsB(); 254 int g1Atom = iBondNeighborAtomsA.get(row * 3 + 0); 255 int g2Atom = iBondNeighborAtomsA.get(row * 3 + 1); 256 int g3Atom = iBondNeighborAtomsB.get(column * 3 + 0); 257 int g4Atom = iBondNeighborAtomsB.get(column * 3 + 1); 258 259 for (int x = 0; x < neighborBondNumA; x++) { 260 int rowAtom1 = iBondNeighborAtomsA.get(x * 3 + 0); 261 int rowAtom2 = iBondNeighborAtomsA.get(x * 3 + 1); 262 263 for (int y = 0; y < neighborBondNumB; y++) { 264 int columnAtom3 = iBondNeighborAtomsB.get(y * 3 + 0); 265 int columnAtom4 = iBondNeighborAtomsB.get(y * 3 + 1); 266 267 if (McGregorChecks.cases(g1Atom, g2Atom, g3Atom, g4Atom, rowAtom1, rowAtom2, columnAtom3, 268 columnAtom4)) { 269 marcs.set(x * neighborBondNumB + y, 0); 270 } 271 272 } 273 } 274 275 for (int v = 0; v < neighborBondNumA; v++) { 276 marcs.set(v * neighborBondNumB + column, 0); 277 } 278 279 for (int w = 0; w < neighborBondNumB; w++) { 280 marcs.set(row * neighborBondNumB + w, 0); 281 } 282 283 marcs.set(row * neighborBondNumB + column, 1); 284 } 285 286 /** 287 * 288 * @param bondNumber 289 * @param cSet 290 * @return 291 */ generateCSetCopy(int bondNumber, List<String> cSet)292 protected static List<String> generateCSetCopy(int bondNumber, List<String> cSet) { 293 List<String> cTabCopy = new ArrayList<String>(); 294 for (int a = 0; a < bondNumber; a++) { 295 cTabCopy.add(cSet.get(a * 4 + 0)); 296 cTabCopy.add(cSet.get(a * 4 + 1)); 297 cTabCopy.add("X"); 298 cTabCopy.add("X"); 299 } 300 return cTabCopy; 301 } 302 303 /** 304 * 305 * @param atomContainer 306 * @return 307 * @throws IOException 308 */ generateCTabCopy(IAtomContainer atomContainer)309 protected static List<String> generateCTabCopy(IAtomContainer atomContainer) throws IOException { 310 List<String> cTabCopy = new ArrayList<String>(); 311 for (int a = 0; a < atomContainer.getBondCount(); a++) { 312 String atomI = atomContainer.getBond(a).getBegin().getSymbol(); 313 String atomJ = atomContainer.getBond(a).getEnd().getSymbol(); 314 cTabCopy.add(atomI); 315 cTabCopy.add(atomJ); 316 cTabCopy.add("X"); 317 cTabCopy.add("X"); 318 } 319 return cTabCopy; 320 } 321 322 /** 323 * 324 * @param g1Atom 325 * @param g3Atom 326 * @param g4Atom 327 * @param rowAtom1 328 * @param rowAtom2 329 * @param columnAtom3 330 * @param columnAtom4 331 * @return 332 */ case1(int g1Atom, int g3Atom, int g4Atom, int rowAtom1, int rowAtom2, int columnAtom3, int columnAtom4)333 protected static boolean case1(int g1Atom, int g3Atom, int g4Atom, int rowAtom1, int rowAtom2, 334 int columnAtom3, int columnAtom4) { 335 if (((g1Atom == rowAtom1) || (g1Atom == rowAtom2)) 336 && (!(((columnAtom3 == g3Atom) || (columnAtom4 == g3Atom)) || ((columnAtom3 == g4Atom) || (columnAtom4 == g4Atom))))) { 337 return true; 338 } 339 return false; 340 } 341 342 /** 343 * 344 * @param g2Atom 345 * @param g3Atom 346 * @param g4Atom 347 * @param rowAtom1 348 * @param rowAtom2 349 * @param columnAtom3 350 * @param columnAtom4 351 * @return 352 */ case2(int g2Atom, int g3Atom, int g4Atom, int rowAtom1, int rowAtom2, int columnAtom3, int columnAtom4)353 protected static boolean case2(int g2Atom, int g3Atom, int g4Atom, int rowAtom1, int rowAtom2, 354 int columnAtom3, int columnAtom4) { 355 if (((g2Atom == rowAtom1) || (g2Atom == rowAtom2)) 356 && (!(((columnAtom3 == g3Atom) || (columnAtom4 == g3Atom)) || ((columnAtom3 == g4Atom) || (columnAtom4 == g4Atom))))) { 357 return true; 358 } 359 return false; 360 } 361 362 /** 363 * 364 * @param g1Atom 365 * @param g3Atom 366 * @param g2Atom 367 * @param rowAtom1 368 * @param rowAtom2 369 * @param columnAtom3 370 * @param columnAtom4 371 * @return 372 */ case3(int g1Atom, int g3Atom, int g2Atom, int rowAtom1, int rowAtom2, int columnAtom3, int columnAtom4)373 protected static boolean case3(int g1Atom, int g3Atom, int g2Atom, int rowAtom1, int rowAtom2, 374 int columnAtom3, int columnAtom4) { 375 if (((g3Atom == columnAtom3) || (g3Atom == columnAtom4)) 376 && (!(((rowAtom1 == g1Atom) || (rowAtom2 == g1Atom)) || ((rowAtom1 == g2Atom) || (rowAtom2 == g2Atom))))) { 377 return true; 378 } 379 return false; 380 } 381 382 /** 383 * 384 * @param g1Atom 385 * @param g2Atom 386 * @param g4Atom 387 * @param rowAtom1 388 * @param rowAtom2 389 * @param columnAtom3 390 * @param columnAtom4 391 * @return 392 */ case4(int g1Atom, int g2Atom, int g4Atom, int rowAtom1, int rowAtom2, int columnAtom3, int columnAtom4)393 protected static boolean case4(int g1Atom, int g2Atom, int g4Atom, int rowAtom1, int rowAtom2, 394 int columnAtom3, int columnAtom4) { 395 if (((g4Atom == columnAtom3) || (g4Atom == columnAtom4)) 396 && (!(((rowAtom1 == g1Atom) || (rowAtom2 == g1Atom)) || ((rowAtom1 == g2Atom) || (rowAtom2 == g2Atom))))) { 397 return true; 398 } 399 return false; 400 } 401 402 /** 403 * 404 * @param g1Atom 405 * @param g2Atom 406 * @param g3Atom 407 * @param g4Atom 408 * @param rowAtom1 409 * @param rowAtom2 410 * @param columnAtom3 411 * @param columnAtom4 412 * @return 413 */ cases(int g1Atom, int g2Atom, int g3Atom, int g4Atom, int rowAtom1, int rowAtom2, int columnAtom3, int columnAtom4)414 protected static boolean cases(int g1Atom, int g2Atom, int g3Atom, int g4Atom, int rowAtom1, int rowAtom2, 415 int columnAtom3, int columnAtom4) { 416 if (case1(g1Atom, g3Atom, g4Atom, rowAtom1, rowAtom2, columnAtom3, columnAtom4) 417 || case2(g2Atom, g3Atom, g4Atom, rowAtom1, rowAtom2, columnAtom3, columnAtom4) 418 || case3(g1Atom, g3Atom, g2Atom, rowAtom1, rowAtom2, columnAtom3, columnAtom4) 419 || case4(g1Atom, g2Atom, g4Atom, rowAtom1, rowAtom2, columnAtom3, columnAtom4)) { 420 return true; 421 } 422 return false; 423 } 424 425 /** 426 * 427 * @param source 428 * @param target 429 * @param neighborBondNumA 430 * @param neighborBondNumB 431 * @param iBondNeighborAtomsA 432 * @param iBondNeighborAtomsB 433 * @param cBondNeighborsA 434 * @param cBondNeighborsB 435 * @param modifiedARCS 436 * @param shouldMatchBonds 437 * @return 438 */ setArcs(IAtomContainer source, IAtomContainer target, int neighborBondNumA, int neighborBondNumB, List<Integer> iBondNeighborAtomsA, List<Integer> iBondNeighborAtomsB, List<String> cBondNeighborsA, List<String> cBondNeighborsB, List<Integer> modifiedARCS, boolean shouldMatchBonds)439 protected static List<Integer> setArcs(IAtomContainer source, IAtomContainer target, int neighborBondNumA, 440 int neighborBondNumB, List<Integer> iBondNeighborAtomsA, List<Integer> iBondNeighborAtomsB, 441 List<String> cBondNeighborsA, List<String> cBondNeighborsB, List<Integer> modifiedARCS, 442 boolean shouldMatchBonds) { 443 444 for (int row = 0; row < neighborBondNumA; row++) { 445 for (int column = 0; column < neighborBondNumB; column++) { 446 447 String g1A = cBondNeighborsA.get(row * 4 + 0); 448 String g2A = cBondNeighborsA.get(row * 4 + 1); 449 String g1B = cBondNeighborsB.get(column * 4 + 0); 450 String g2B = cBondNeighborsB.get(column * 4 + 1); 451 452 if (McGregorChecks.isAtomMatch(g1A, g2A, g1B, g2B)) { 453 454 int indexI = iBondNeighborAtomsA.get(row * 3 + 0); 455 int indexIPlus1 = iBondNeighborAtomsA.get(row * 3 + 1); 456 457 IAtom r1A = source.getAtom(indexI); 458 IAtom r2A = source.getAtom(indexIPlus1); 459 IBond reactantBond = source.getBond(r1A, r2A); 460 461 int indexJ = iBondNeighborAtomsB.get(column * 3 + 0); 462 int indexJPlus1 = iBondNeighborAtomsB.get(column * 3 + 1); 463 464 IAtom p1B = target.getAtom(indexJ); 465 IAtom p2B = target.getAtom(indexJPlus1); 466 IBond productBond = target.getBond(p1B, p2B); 467 if (isMatchFeasible(source, reactantBond, target, productBond, shouldMatchBonds)) { 468 modifiedARCS.set(row * neighborBondNumB + column, 1); 469 } 470 } 471 } 472 } 473 return modifiedARCS; 474 } 475 476 /** 477 * 478 * @param tempmarcs 479 * @param neighborBondNumA 480 * @param neighborBondNumB 481 * @return 482 */ countArcsLeft(List<Integer> tempmarcs, int neighborBondNumA, int neighborBondNumB)483 protected static int countArcsLeft(List<Integer> tempmarcs, int neighborBondNumA, int neighborBondNumB) { 484 int arcsleft = 0; 485 486 for (int a = 0; a < neighborBondNumA; a++) { 487 for (int b = 0; b < neighborBondNumB; b++) { 488 489 if (tempmarcs.get(a * neighborBondNumB + b) == (1)) { 490 arcsleft++; 491 } 492 } 493 } 494 return arcsleft; 495 } 496 497 /** 498 * 499 * @param correspondingAtom 500 * @param newSymbol 501 * @param neighborBondNum 502 * @param atomContainer 503 * @param cBondNeighbors 504 * @return 505 */ changeCharBonds(int correspondingAtom, String newSymbol, int neighborBondNum, IAtomContainer atomContainer, List<String> cBondNeighbors)506 protected static int changeCharBonds(int correspondingAtom, String newSymbol, int neighborBondNum, 507 IAtomContainer atomContainer, List<String> cBondNeighbors) { 508 for (int atomIndex = 0; atomIndex < neighborBondNum; atomIndex++) { 509 IBond bond = atomContainer.getBond(atomIndex); 510 if ((atomContainer.indexOf(bond.getBegin()) == correspondingAtom) 511 && (cBondNeighbors.get(atomIndex * 4 + 2).compareToIgnoreCase("X") == 0)) { 512 cBondNeighbors.set(atomIndex * 4 + 2, cBondNeighbors.get(atomIndex * 4 + 0)); 513 cBondNeighbors.set(atomIndex * 4 + 0, newSymbol); 514 } 515 516 if ((atomContainer.indexOf(bond.getEnd()) == correspondingAtom) 517 && (cBondNeighbors.get(atomIndex * 4 + 3).compareToIgnoreCase("X") == 0)) { 518 cBondNeighbors.set(atomIndex * 4 + 3, cBondNeighbors.get(atomIndex * 4 + 1)); 519 cBondNeighbors.set(atomIndex * 4 + 1, newSymbol); 520 } 521 522 } 523 524 return 0; 525 } 526 527 /** 528 * 529 * @param correspondingAtom 530 * @param newSymbol 531 * @param neighborBondNum 532 * @param iBondNeighbors 533 * @param cBondNeighbors 534 * @return 535 */ changeCharBonds(int correspondingAtom, String newSymbol, int neighborBondNum, List<Integer> iBondNeighbors, List<String> cBondNeighbors)536 protected static int changeCharBonds(int correspondingAtom, String newSymbol, int neighborBondNum, 537 List<Integer> iBondNeighbors, List<String> cBondNeighbors) { 538 539 for (int atomIndex = 0; atomIndex < neighborBondNum; atomIndex++) { 540 if ((iBondNeighbors.get(atomIndex * 3 + 0) == (correspondingAtom)) 541 && (cBondNeighbors.get(atomIndex * 4 + 2).compareToIgnoreCase("X") == 0)) { 542 cBondNeighbors.set(atomIndex * 4 + 2, cBondNeighbors.get(atomIndex * 4 + 0)); 543 cBondNeighbors.set(atomIndex * 4 + 0, newSymbol); 544 } 545 546 if ((iBondNeighbors.get(atomIndex * 3 + 1) == (correspondingAtom)) 547 && (cBondNeighbors.get(atomIndex * 4 + 3).compareToIgnoreCase("X") == 0)) { 548 cBondNeighbors.set(atomIndex * 4 + 3, cBondNeighbors.get(atomIndex * 4 + 1)); 549 cBondNeighbors.set(atomIndex * 4 + 1, newSymbol); 550 } 551 552 } 553 554 return 0; 555 } 556 isFurtherMappingPossible(IAtomContainer source, IAtomContainer target, McgregorHelper mcGregorHelper, boolean shouldMatchBonds)557 static boolean isFurtherMappingPossible(IAtomContainer source, IAtomContainer target, 558 McgregorHelper mcGregorHelper, boolean shouldMatchBonds) { 559 560 int neighborBondNumA = mcGregorHelper.getNeighborBondNumA(); 561 int neighborBondNumB = mcGregorHelper.getNeighborBondNumB(); 562 List<Integer> iBondNeighborAtomsA = mcGregorHelper.getiBondNeighborAtomsA(); 563 List<Integer> iBondNeighborAtomsB = mcGregorHelper.getiBondNeighborAtomsB(); 564 List<String> cBondNeighborsA = mcGregorHelper.getcBondNeighborsA(); 565 List<String> cBondNeighborsB = mcGregorHelper.getcBondNeighborsB(); 566 567 for (int row = 0; row < neighborBondNumA; row++) { 568 // System.out.println("i " + row); 569 String g1A = cBondNeighborsA.get(row * 4 + 0); 570 String g2A = cBondNeighborsA.get(row * 4 + 1); 571 572 for (int column = 0; column < neighborBondNumB; column++) { 573 574 String g1B = cBondNeighborsB.get(column * 4 + 0); 575 String g2B = cBondNeighborsB.get(column * 4 + 1); 576 577 if (isAtomMatch(g1A, g2A, g1B, g2B)) { 578 try { 579 580 int indexI = iBondNeighborAtomsA.get(row * 3 + 0); 581 int indexIPlus1 = iBondNeighborAtomsA.get(row * 3 + 1); 582 583 int indexJ = iBondNeighborAtomsB.get(column * 3 + 0); 584 int indexJPlus1 = iBondNeighborAtomsB.get(column * 3 + 1); 585 586 IAtom r1A = source.getAtom(indexI); 587 IAtom r2A = source.getAtom(indexIPlus1); 588 IBond reactantBond = source.getBond(r1A, r2A); 589 590 IAtom p1B = target.getAtom(indexJ); 591 IAtom p2B = target.getAtom(indexJPlus1); 592 IBond productBond = target.getBond(p1B, p2B); 593 594 if (isMatchFeasible(source, reactantBond, target, productBond, shouldMatchBonds)) { 595 return true; 596 } 597 } catch (Exception e) { 598 e.printStackTrace(); 599 } 600 } 601 } 602 } 603 604 return false; 605 } 606 markUnMappedAtoms(boolean flag, IAtomContainer container, Map<Integer, Integer> presentMapping)607 static List<Integer> markUnMappedAtoms(boolean flag, IAtomContainer container, Map<Integer, Integer> presentMapping) { 608 List<Integer> unmappedMolAtoms = new ArrayList<Integer>(); 609 610 int unmappedNum = 0; 611 boolean atomIsUnmapped = true; 612 613 for (int a = 0; a < container.getAtomCount(); a++) { 614 //Atomic list are only numbers from 1 to atom_number1 615 if (flag && presentMapping.containsKey(a)) { 616 atomIsUnmapped = false; 617 } else if (!flag && presentMapping.containsValue(a)) { 618 atomIsUnmapped = false; 619 } 620 if (atomIsUnmapped) { 621 unmappedMolAtoms.add(unmappedNum++, a); 622 } 623 atomIsUnmapped = true; 624 } 625 return unmappedMolAtoms; 626 } 627 markUnMappedAtoms(boolean flag, IAtomContainer container, List<Integer> mappedAtoms, int cliqueSize)628 static List<Integer> markUnMappedAtoms(boolean flag, IAtomContainer container, List<Integer> mappedAtoms, 629 int cliqueSize) { 630 List<Integer> unmappedMolAtoms = new ArrayList<Integer>(); 631 int unmappedNum = 0; 632 boolean atomIsUnmapped = true; 633 for (int a = 0; a < container.getAtomCount(); a++) { 634 //Atomic list are only numbers from 1 to atom_number1 635 for (int b = 0; b < cliqueSize; b += 2) { 636 if (flag && mappedAtoms.get(b) == a) { 637 atomIsUnmapped = false; 638 } else if (!flag && mappedAtoms.get(b + 1) == a) { 639 atomIsUnmapped = false; 640 } 641 } 642 if (atomIsUnmapped) { 643 unmappedMolAtoms.add(unmappedNum++, a); 644 } 645 atomIsUnmapped = true; 646 } 647 return unmappedMolAtoms; 648 } 649 } 650