
com.actelion.research.chem.reaction.ReactionIndexer Maven / Gradle / Ivy
/*
* Project: DD_core
* @(#)ReactionIndexer.java
*
* Copyright (c) 1997- 2014
* Actelion Pharmaceuticals Ltd.
* Gewerbestrasse 16
* CH-4123 Allschwil, Switzerland
*
* All Rights Reserved.
*
* This software is the proprietary information of Actelion Pharmaceuticals, Ltd.
* Use is subject to license terms.
*
* Author: Christian Rufener
*/
package com.actelion.research.chem.reaction;
import com.actelion.research.chem.ExtendedMolecule;
import com.actelion.research.chem.Molecule;
import com.actelion.research.chem.StereoMolecule;
import com.actelion.research.chem.io.RXNFileParser;
public class ReactionIndexer
{
private static boolean debug = false;
/*
public static final int BOND_BREAK_1 = 0x0001;
public static final int BOND_BREAK_2 = 0x0002;
public static final int BOND_BREAK_3 = 0x0004;
public static final int BOND_BREAK_M = 0x0008;
public static final int BOND_CREATE_1 = 0x0010;
public static final int BOND_CREATE_2 = 0x0020;
public static final int BOND_CREATE_3 = 0x0040;
public static final int BOND_CHANGE_13 = 0x0080;
public static final int BOND_CHANGE_12 = 0x0100;
public static final int BOND_CHANGE_21 = 0x0200;
public static final int BOND_CHANGE_23 = 0x0400;
public static final int BOND_CHANGE_32 = 0x0800;
public static final int BOND_CHANGE_31 = 0x1000;
public static final int BOND_CHANGE_A2 = 0x2000;
public static final int BOND_CHANGE_A1 = 0x4000;
public static final int BOND_CHANGE_O = 0x8000;
public static final int ATOM_C_C = 0x00010000;
public static final int ATOM_C_O = 0x00020000;
public static final int ATOM_C_N = 0x00040000;
public static final int ATOM_C_X = 0x00080000;
public static final int ATOM_C_M = 0x00100000;
*/
private static final byte CR_ONLY = 0;
// Carbon Create Keys
private static final byte CR_CC1 = 1;
private static final byte CR_CC2 = 2;
private static final byte CR_CC3 = 3;
private static final byte CR_CCA = 4;
private static final byte CR_CN1 = 5;
private static final byte CR_CN2 = 6;
private static final byte CR_CN3 = 7;
private static final byte CR_CO1 = 8;
private static final byte CR_CO2 = 9;
private static final byte CR_CCl = 10;
private static final byte CR_CX = 11;
// Nitrogen Create Keys
private static final byte CR_NN1 = 12;
private static final byte CR_NN2 = 13;
private static final byte CR_NO1 = 14;
private static final byte CR_NO2 = 15;
// Change Carbon Keys
private static final byte CH_CCSD = 16;
private static final byte CH_CCDS = 17;
private static final byte CH_CCST = 18;
private static final byte CH_CCTS = 19;
private static final byte CH_CCDT = 20;
private static final byte CH_CCTD = 21;
private static final byte CH_CCSA = 22;
private static final byte CH_CCAS = 23;
private static final byte CH_CCDA = 24;
private static final byte CH_CCAD = 25;
private static final byte CH_CCTA = 26;
private static final byte CH_CCAT = 27;
private static final byte CH_CNSD = 28;
private static final byte CH_CNDS = 29;
private static final byte CH_CNST = 30;
private static final byte CH_CNTS = 31;
private static final byte CH_CNDT = 32;
private static final byte CH_CNTD = 33;
private static final byte CH_CNSA = 34;
private static final byte CH_CNAS = 35;
private static final byte CH_CNDA = 36;
private static final byte CH_CNAD = 37;
private static final byte CH_COSD = 38;
private static final byte CH_CODS = 39;
private static final byte DEL_ONLY = 40;
private static final byte DEL_CCS = 41;
private static final byte DEL_CCD = 42;
private static final byte DEL_CCT = 43;
private static final byte DEL_CCA = 44;
private static final byte DEL_CNS = 45;
private static final byte DEL_CND = 46;
private static final byte DEL_CNT = 47;
private static final byte DEL_COS = 48;
private static final byte DEL_COT = 49;
private static final byte DEL_CF = 50;
private static final byte DEL_CCl = 51;
private static final byte DEL_CBR = 52;
private static final byte DEL_CX = 53;
// Nitrogen Create Keys
private static final byte DEL_NN1 = 54;
private static final byte DEL_NN2 = 55;
private static final byte DEL_NO1 = 56;
private static final byte DEL_NO2 = 57;
private static final byte CH_ONLY = 58;
public static final byte NUMKEYS = 1 + CH_ONLY;
public static final int NITROGEN = 7;
public static final int OXYGEN = 8;
public static final int FLUORINE = 9;
public static final int CHLORINE = 17;
public static final int BROMINE = 35;
public static final int IODINE = 53;
public static final int ASTATINE = 85;
private static final int CARBON = 6;
private static final String[] KEY_STRING = {
"CR_ONLY",
"CR_CC1",
"CR_CC2",
"CR_CC3",
"CR_CCA",
"CR_CN1",
"CR_CN2",
"CR_CN3",
"CR_CO1",
"CR_CO2",
"CR_CCl",
"CR_CX",
"CR_NN1",
"CR_NN2",
"CR_NO1",
"CR_NO2",
"CH_CCSD",
"CH_CCDS",
"CH_CCST",
"CH_CCTS",
"CH_CCDT",
"CH_CCTD",
"CH_CCSA",
"CH_CCAS",
"CH_CCDA",
"CH_CCAD",
"CH_CCTA",
"CH_CCAT",
"CH_CNSD",
"CH_CNDS",
"CH_CNST",
"CH_CNTS",
"CH_CNDT",
"CH_CNTD",
"CH_CNSA",
"CH_CNAS",
"CH_CNDA",
"CH_CNAD",
"CH_COSD",
"CH_CODS",
"DEL_ONLY",
"DEL_CC1",
"DEL_CC2",
"DEL_CC3",
"DEL_CCA",
"DEL_CN1",
"DEL_CN2",
"DEL_CN3",
"DEL_CO1",
"DEL_CO2",
"DEL_CF ",
"DEL_CCl",
"DEL_CBR",
"DEL_CX ",
"DEL_NN1",
"DEL_NN2",
"DEL_NO1",
"DEL_NO2",
"CH_ONLY",
};
private byte[] rxnKeys = null;
public ReactionIndexer(boolean debug)
{
this.debug = debug;
init();
}
public ReactionIndexer()
{
this(false);
}
private void init()
{
rxnKeys = new byte[NUMKEYS];
}
public String getKeysString(Reaction rxn)
{
init();
generateKeys(rxn);
return getKeysString();
}
public static String getKeyName(int key)
{
return KEY_STRING[key];
}
public byte[] getKeys(Reaction rxn)
{
init();
generateKeys(rxn);
byte[] ret = new byte[rxnKeys.length];
System.arraycopy(rxnKeys, 0, ret, 0, rxnKeys.length);
return ret;
}
public boolean hasKeys()
{
for (int k : rxnKeys) {
if (k != 0) {
return true;
}
}
return false;
}
private void addKey(int index)
{
if (index >= 0 && rxnKeys[index] < Byte.MAX_VALUE) {
rxnKeys[index]++;
}
}
private void initKeys()
{
init();
}
public String getFoundKeys()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < NUMKEYS; i++) {
if (rxnKeys[i] > 0) {
sb.append(String.format("%s (%d)\n",KEY_STRING[i],(int)rxnKeys[i]));
}
}
return sb.toString();
}
public static byte[] getKeysFromString(String s)
{
byte[] ret = new byte[NUMKEYS];
if (s != null) {
if (s.length() != NUMKEYS)
throw new RuntimeException("Invalid KeyString Length");
for (int i = 0; i < NUMKEYS; i++) {
ret[i] = (byte)(s.charAt(i)-'0');
}
}
return ret;
}
public static String getKeysString(byte[] keys)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < NUMKEYS; i++) {
sb.append(String.format("%1d", (int) keys[i]));
}
return sb.toString();
}
private String getKeysString()
{
return getKeysString(rxnKeys);
}
private int addCreateKey(int bondtype, int atomSymbol1, int atomSymbol2)
{
int key = CR_ONLY;
int a1 = atomSymbol1;
int a2 = atomSymbol2;
if (atomSymbol2 < atomSymbol1) {
a1 = atomSymbol2;
a2 = atomSymbol1;
}
switch (a1) {
case CARBON:
key = getCarbonCreateKey(bondtype, a2);
break;
case NITROGEN:
key = getNitroCreateKey(bondtype, a2);
break;
}
return key;
}
private int getCarbonCreateKey(int bondtype, int atomNo)
{
int key = CR_ONLY;
switch (atomNo) {
case CARBON:
key = getCreateCarbonCarbonKey(bondtype);
break;
case NITROGEN:
key = getCreateCarbonNitroKey(bondtype);
break;
case OXYGEN:
key = getCreateCarbonOxygenKey(bondtype);
break;
case CHLORINE:
key = CR_CCl;
break;
case FLUORINE:
case BROMINE:
case IODINE:
case ASTATINE:
key = CR_CX;
break;
}
return key;
}
private int getNitroCreateKey(int bondtype, int atomNo)
{
int key = CR_ONLY;
switch (atomNo) {
case NITROGEN:
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
key = CR_NN1;
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
key = CR_NN2;
}
break;
case OXYGEN:
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
key = CR_NO1;
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
key = CR_NO2;
}
break;
}
return key;
}
private int getCreateCarbonCarbonKey(int bondtype)
{
if (bondtype == Molecule.cBondTypeDelocalized) {
return CR_CCA;
} else if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
return CR_CC1;
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
return CR_CC2;
} else if ((bondtype & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
return CR_CC3;
}
return CR_ONLY;
}
private int getCreateCarbonNitroKey(int bondtype)
{
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
return CR_CN1;
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
return CR_CN2;
} else if ((bondtype & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
return CR_CN3;
}
return CR_ONLY;
}
private int getCreateCarbonOxygenKey(int bondtype)
{
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
return CR_CO1;
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
return CR_CO2;
}
return CR_ONLY;
}
///////// Change////////
private void addChangeKey(int atomNo1, int atomNo2, int bt1, int bt2)
{
addKey(CH_ONLY);
int a1 = atomNo1;
int a2 = atomNo2;
if (atomNo2 < atomNo1) {
a1 = atomNo2;
a2 = atomNo1;
}
switch (a1) {
case CARBON:
addCarbonChangeKey(a2, bt1, bt2);
break;
}
//return key;
}
private void addCarbonChangeKey(int atomNo, int bt1, int bt2)
{
int key = CH_ONLY;
switch (atomNo) {
case CARBON:
addChangeCarbonCarbonKey(bt1, bt2);
break;
case NITROGEN:
addChangeCarbonNitroKey(bt1, bt2);
break;
case OXYGEN:
addChangeCarbonOxygenKey(bt1, bt2);
break;
}
// return key;
}
private void addChangeCarbonCarbonKey(int bt1, int bt2)
{
// int key = CH_ONLY;
if (bt1 == Molecule.cBondTypeDelocalized) {
if ((bt2 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(CH_CCAS);
} else if ((bt2 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(CH_CCAD);
} else if ((bt2 & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
addKey(CH_CCAT);
}
} else if ((bt1 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_CCSA);
} else if ((bt2 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(CH_CCSD);
} else if ((bt2 & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
addKey(CH_CCST);
}
} else if ((bt1 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_CCDA);
} else if ((bt2 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(CH_CCDS);
} else if ((bt2 & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
addKey(CH_CCDT);
}
} else if ((bt1 & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_CCTA);
} else if ((bt2 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(CH_CCTS);
} else if ((bt2 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(CH_CCTD);
}
}
// return key;
}
private void addChangeCarbonNitroKey(int bt1, int bt2)
{
// int addKey(CH_ONLY;
if (bt1 == Molecule.cBondTypeDelocalized) {
if ((bt2 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(CH_CNAS);
} else if ((bt2 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(CH_CNAD);
}
} else if ((bt1 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_CNSA);
} else if ((bt2 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(CH_CNSD);
} else if ((bt2 & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
addKey(CH_CNST);
}
} else if ((bt1 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_CNDA);
} else if ((bt2 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(CH_CNDS);
} else if ((bt2 & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
addKey(CH_CNDT);
}
} else if ((bt1 & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
if ((bt2 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(CH_CNTS);
} else if ((bt2 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(CH_CNTD);
}
}
// return key;
}
private void addChangeCarbonOxygenKey(int bt1, int bt2)
{
// int addKey(CH_ONLY;
if ((bt1 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
if ((bt2 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(CH_COSD);
}
} else if ((bt1 & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
if ((bt2 & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(CH_CODS);
}
}
//return key;
}
/*
private int getChangeKey(int bt1, int bt2)
{
int addKey(-1;
if (bt1 == Molecule.cBondTypeDelocalized) {
if ((bt2 & Molecule.cBondTypeSingle) ==Molecule.cBondTypeSingle) {
addKey(CH_AS;
}else if ((bt2 & Molecule.cBondTypeDouble) ==Molecule.cBondTypeDouble) {
addKey(CH_AD;
}else if ((bt2 & Molecule.cBondTypeTriple) ==Molecule.cBondTypeTriple) {
addKey(CH_AT;
}
} else if ((bt1 & Molecule.cBondTypeSingle) ==Molecule.cBondTypeSingle) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_SA;
} else if ((bt2 & Molecule.cBondTypeDouble) ==Molecule.cBondTypeDouble) {
addKey(CH_SD;
}else if ((bt2 & Molecule.cBondTypeTriple) ==Molecule.cBondTypeTriple) {
addKey(CH_ST;
}
} else if ((bt1 & Molecule.cBondTypeDouble) ==Molecule.cBondTypeDouble) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_DA;
} else if ((bt2 & Molecule.cBondTypeSingle) ==Molecule.cBondTypeSingle) {
addKey(CH_DS;
}else if ((bt2 & Molecule.cBondTypeTriple) ==Molecule.cBondTypeTriple) {
addKey(CH_DT;
}
} else if ((bt1 & Molecule.cBondTypeTriple) ==Molecule.cBondTypeTriple) {
if (bt2 == Molecule.cBondTypeDelocalized) {
addKey(CH_TA;
} else if ((bt2 & Molecule.cBondTypeSingle) ==Molecule.cBondTypeSingle) {
addKey(CH_TS;
}else if ((bt2 & Molecule.cBondTypeDouble) ==Molecule.cBondTypeDouble) {
addKey(CH_TD;
}
}
return key;
}
*/
private void addDeleteKey(int bondtype, int atomNo1, int atomNo2)
{
addKey(DEL_ONLY);
int a1 = atomNo1;
int a2 = atomNo2;
if (atomNo2 < atomNo1) {
a1 = atomNo2;
a2 = atomNo1;
}
switch (a1) {
case CARBON:
addCarbonDeleteKey(bondtype, a2);
break;
case NITROGEN:
addNitroDeleteKey(bondtype, a2);
break;
}
}
private void addCarbonDeleteKey(int bondtype, int atomNo)
{
// int addKey(DEL_ONLY;
switch (atomNo) {
case CARBON:
addDeleteCarbonCarbonKey(bondtype);
break;
case NITROGEN:
addDeleteCarbonNitroKey(bondtype);
break;
case OXYGEN:
addDeleteCarbonOxygenKey(bondtype);
break;
case FLUORINE:
case CHLORINE:
case 35:
case IODINE:
addHalogenDeleteKey(atomNo);
break;
}
// addKey();
}
private void addDeleteCarbonCarbonKey(int bondtype)
{
if (bondtype == Molecule.cBondTypeDelocalized) {
addKey(DEL_CCA);
} else if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(DEL_CCS);
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(DEL_CCD);
} else if ((bondtype & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
addKey(DEL_CCT);
}
//addKey(DEL_ONLY;
}
private void addDeleteCarbonNitroKey(int bondtype)
{
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(DEL_CNS);
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(DEL_CND);
} else if ((bondtype & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
addKey(DEL_CNT);
}
//return DEL_ONLY;
}
private void addDeleteCarbonOxygenKey(int bondtype)
{
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(DEL_COS);
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(DEL_COT);
}
//return DEL_ONLY;
}
private void addNitroDeleteKey(int bondtype, int atomNo)
{
// int addKey(DEL_ONLY;
switch (atomNo) {
case NITROGEN:
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(DEL_NN1);
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(DEL_NN2);
}
break;
case 8:
if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
addKey(DEL_NO1);
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
addKey(DEL_NO2);
}
break;
}
// return key;
}
private void addHalogenDeleteKey(int atomNo)
{
addKey(DEL_CX);
switch (atomNo) {
case FLUORINE:
addKey(DEL_CF);
break;
case CHLORINE:
addKey(DEL_CCl);
break;
case BROMINE:
addKey(DEL_CBR);
break;
case IODINE:
break;
}
//return key;
}
/*
C1 C5 C1 C5
\ / \ /
C2-Cl N4 --> C2 - N4
/ \ / \
C3 C6 C3 C6
C1 C1
\ \
C2 = O3 --> C2 - 03
/ /
C3 C3
C1 C5 C1 C5
\ / \ /
C2 - N4 --> C2 N4
/ \ / \
C3 C6 C3 C6
C1 C C5 C1 C5
\ / / \ /
C2 - N N4 --> C2 - N4
/ \ \ / \
C3 C C6 C3 C6
*/
// C1 -> Map No = 1, pAtomNo = x, cConntectedAtoms = 1, pNumConnectedAtoms=1
// cBondAtom = (C2), bondType = 1, cOtherMapNo = 2, pBondType=1 = > NO CHANGE
// C2 -> Map No = 2, pAtomNo = x, cConntextedAtoms = 3, pNumConnectedAtoms = 3
// C1 == OK
// C3 == OK
// cBondAtom (Cl),cBondType=1,cOtherMapNo=0
//
/*
// For all atoms connected to Component Atoms (cAtomNo)
for (int cbi = 0; cbi < cNumConnectedAtoms; cbi++) {
// get the other atom at this bond
int cBondAtom = source.getConnAtom(cAtomNo, cbi);
// Get the bond index from these two atoms
int sourceBondIndex = source.getConnBond(cAtomNo, cbi);
if (cVisitedBonds[sourceBondIndex])
continue;
// Find the mapping number of the bond's other end
int cOtherMapNo = source.getAtomMapNo(cBondAtom);
// get the bond type of this atom
int cBondType = getBondType(source, sourceBondIndex);
////sb.append(String.format("Source Bond From %d(%d) - %d(%d) \n",cAtomNo,cMapNo,cBondAtom,cOtherMapNo));
cVisitedBonds[sourceBondIndex] = true;
// the other end is mapped
if (cOtherMapNo != 0) {
// find the cont type of the two mapped atoms on the preoduct
int pBondType = getMappedBondType(target, cMapNo, cOtherMapNo);
//sb.append(String.format("Proiduct Bond Type (%d) - (%d) = %d \n",cMapNo,cOtherMapNo,pBondType));
// If there's no bond, then the bond has been brokwn
if (pBondType == -1) {
if (!reverse) {
System.out.println(String.format("###BOND_BREAK(1) at %d-%d \n", cOtherMapNo, cMapNo));
int key = addDeleteKey(cBondType, source.getAtomicNo(cAtomNo), source.getAtomicNo(cBondAtom));
if (debug)
System.out.println("Delete Key is " + key);
addKey(key);
addKey(DEL_ONLY);
} else {
System.out.println(String.format("###BOND_CREATE(1) at %d-%d \n", cOtherMapNo, cMapNo));
int key = addCreateKey(cBondType, source.getAtomicNo(cAtomNo), source.getAtomicNo(cBondAtom));
addKey(key);
addKey(CR_ONLY);
}
if (debug)
sb.append(String.format("Bond %d %s-%s\n", sourceBondIndex, source.getAtomLabel(cAtomNo), source.getAtomLabel(cBondAtom)));
// BOND_BREAK;
// If the bond type is the same, nothing happend
} else if (cBondType == pBondType) {
;
// the bond type is different, so it's a change
} else {
if (!reverse) {
System.out.println(String.format("###BOND_CHANGE(1) Type=%d Map %d-%d \n", pBondType, cOtherMapNo, cMapNo));
int key = getChangeKey(source.getAtomicNo(cAtomNo), source.getAtomicNo(cBondAtom), cBondType, pBondType);
addKey(key);
addKey(CH_ONLY);
}
// BOND_CHANGE
}
} else {
System.out.println(String.format("not found other map no %d %d", listIndex, cMapNo));
//if (!cVisitedBonds[sourceBondIndex]) {
// System.out.println(String.format("## UNDEFINED",listIndex,cMapNo));
//}
// Does this bond break
}
}
if (!reverse) {
if (cNumConnectedAtoms < pNumConnectedAtoms) {
System.out.println(String.format("searching backward? %d/%d (%d)", cNumConnectedAtoms, pNumConnectedAtoms, cMapNo));
int bondIndex = findDeletedBond(target, pAtomNo, source, cAtomNo);
if (bondIndex != -1 && !cVisitedBonds[bondIndex]) {
int ba = target.getConnAtom(pAtomNo, bondIndex);
int type = target.getAtomicNo(ba);
int bt = getBondType(target, bondIndex);
System.out.println(String.format("### BOND_CREATE(2) at Target Atom %d(%d)[%d] from Source Atom %d(%d)", pAtomNo, cMapNo, type, cAtomNo, cMapNo));
// BOND_CREATE
int key = addCreateKey(bt, target.getAtomicNo(pAtomNo), target.getAtomicNo(ba));
addKey(key);
addKey(CR_ONLY);
}
} else if (cNumConnectedAtoms > pNumConnectedAtoms) {
System.out.println(String.format("searching forward? %d/%d (%d)", cNumConnectedAtoms, pNumConnectedAtoms, cMapNo));
int bondIndex = findDeletedBond(source, cAtomNo, target, pAtomNo);
if (bondIndex != -1 && !cVisitedBonds[bondIndex]) {
int ba = source.getConnAtom(cAtomNo, bondIndex);
int type = source.getAtomicNo(ba);
int bt = getBondType(target, bondIndex);
System.out.println(String.format("### BOND_DELETE(2) at Target Atom %d(%d)[%d] from Source Atom %d(%d)", pAtomNo, cMapNo, type, cAtomNo, cMapNo));
// BOND_CREATE
int key = addDeleteKey(bt, source.getAtomicNo(cAtomNo), source.getAtomicNo(ba));
addKey(key);
addKey(DEL_ONLY);
}
}
}
} else {
}
}
}
} else {
}
sb.append(getKeysString());
return sb.toString();
}
*/
private int findDeletedBond(ExtendedMolecule source, int sourceAtom, ExtendedMolecule target, int targetAtom)
{
int sourceNumConnectedAtoms = source.getConnAtoms(sourceAtom);
int originAtomType = source.getAtomicNo(sourceAtom);
int targetNumConnectedAtoms = target.getConnAtoms(targetAtom);
boolean visitedSourceBonds[] = new boolean[sourceNumConnectedAtoms];
if (sourceNumConnectedAtoms > targetNumConnectedAtoms) {
if (debug) {
System.out.println(String.format("findDeletedBond() walk source atom %d", sourceAtom));
}
// Walk all bonds at this atom
boolean visitedTargetBonds[] = new boolean[targetNumConnectedAtoms];
for (int i = 0; i < sourceNumConnectedAtoms; i++) {
if (!visitedSourceBonds[i]) {
// This is the atom of the bond
int sourceBondAtom = source.getConnAtom(sourceAtom, i);
// And this is the bond
int sourceBond = source.getConnBond(sourceAtom, i);
// The bond type
int sourceBondType = getBondType(source, sourceBond);
// The atom type
int sourceAtomType = source.getAtomicNo(sourceBondAtom);
if (debug) {
System.out.println(String.format("findDeletedBond() walk source bond atom %d bond %d type %d atomtype %d", sourceBondAtom, i, sourceBondType, sourceAtomType));
}
for (int j = 0; j < targetNumConnectedAtoms; j++) {
if (!visitedTargetBonds[j]) {
int bondAtom = target.getConnAtom(targetAtom, j);
int bond = target.getConnBond(targetAtom, j);
int targetBondType = getBondType(target, bond);
int targetAtomType = target.getAtomicNo(bondAtom);
if (debug) {
System.out.println(String.format("findDeletedBond() walk checking bond %d->%d (%d/%d) %d/%d", sourceAtomType, targetAtomType, i, j, sourceBondType, targetBondType));
}
if (sourceAtomType == targetAtomType && sourceBondType == targetBondType) {
visitedSourceBonds[i] = true;
visitedTargetBonds[j] = true;
System.out.println("Found Bond");
break;
}
}
}
if (!visitedSourceBonds[i]) {
if (debug) {
System.out.println(String.format("findDeletedBond() walk source bond not found atom %d bond %d type %d atomtype %d->%d",
sourceBondAtom, i, sourceBondType, originAtomType, sourceAtomType));
}
}
}
}
for (int i = 0; i < sourceNumConnectedAtoms; i++) {
if (!visitedSourceBonds[i]) {
if (debug) {
System.out.println(String.format("Did not find bond: %d(%d)", sourceAtom, i));
}
// this bond has not been seen, so it's breacking
return i;
}
}
}
return -1;
}
private boolean findBond(ExtendedMolecule mol, int atomIndex, int atomType, int bondType)
{
int pNumConnectedAtoms = mol.getConnAtoms(atomIndex);
return false;
}
/*
ExtendedMolecule findMappedAtomMol(int mapno)
{
ExtendedMolecule ret = null;
int prod = rxn.getProducts();
for (int i = 0; i < prod; i++) {
ExtendedMolecule m = rxn.getMolecule(i);
for (int a = 0; a < m.getAllAtoms(); a++) {
if (m.getAtomMapNo(a) == mapno) {
ret = m;
break;
}
}
}
return ret;
}
*/
int getMappedAtom(ExtendedMolecule m, int map1)
{
int a1 = -1;
for (int a = 0; a < m.getAllAtoms(); a++) {
if (m.getAtomMapNo(a) == map1) {
a1 = a;
break;
}
}
return a1;
}
int getMappedBondType(ExtendedMolecule m, int map1, int map2)
{
int ret = -1; // Bond Type
int bond = getMappedBond(m, map1, map2);
if (bond != -1) {
return getBondType(m, bond);
}
return ret;
}
private int getBondType(ExtendedMolecule m, int bond)
{
int ret = m.getBondType(bond);
if (m.isAromaticBond(bond) || m.isDelocalizedBond(bond)) {
ret = Molecule.cBondTypeDelocalized;
}
return getSimpleBondType(ret);
}
private int getSimpleBondType(int bondtype)
{
if (bondtype == Molecule.cBondTypeDelocalized) {
return Molecule.cBondTypeDelocalized;
} else if ((bondtype & Molecule.cBondTypeSingle) == Molecule.cBondTypeSingle) {
return Molecule.cBondTypeSingle;
} else if ((bondtype & Molecule.cBondTypeDouble) == Molecule.cBondTypeDouble) {
return Molecule.cBondTypeDouble;
} else if ((bondtype & Molecule.cBondTypeTriple) == Molecule.cBondTypeTriple) {
return bondtype & Molecule.cBondTypeTriple;
}
return bondtype;
}
int getMappedBond(ExtendedMolecule m, int map1, int map2)
{
int ret = -1; // Bond
int a1 = getMappedAtom(m, map1);
if (a1 != -1) {
int bcnt = m.getConnAtoms(a1);
for (int b = 0; b < bcnt; b++) {
int a2 = m.getConnAtom(a1, b);
// int a2 = m.getBondAtom(a1,b);
int mt = m.getAtomMapNo(a2);
if (debug) {
System.out.println(String.format("Checking Product bond %d-%d : Product Atom %d has map no %d", a1, a2, a2, mt));
}
if (mt == map2) {
ret = m.getConnBond(a1, b);
break;
}
}
}
return ret;
}
// public int getKey(ExtendedMolecule s, int a1, int a2, int bond)
// {
// return 0;
// }
private int getSameBond(ExtendedMolecule source, int cBondAtom, int cBondIndex, ExtendedMolecule target, int targetAtom)
{
int cAtomSymbol = source.getAtomicNo(cBondAtom);
int map = source.getAtomMapNo(cBondAtom);
// int cBondAtom = source.getConnAtom(sourceAtom,cbi);
// int cBondIndex = source.getConnBond(sourceAtom,cbi);
int cBondType = getBondType(source, cBondIndex);
int targetBondCount = target.getConnAtoms(targetAtom);
for (int tbi = 0; tbi < targetBondCount; tbi++) {
int tBondAtom = target.getConnAtom(targetAtom, tbi);
int tBondIndex = target.getConnBond(targetAtom, tbi);
int tBondType = getBondType(target, tBondIndex);
int tAtomSymbol = target.getAtomicNo(tBondAtom);
int tmap = target.getAtomMapNo(tBondAtom);
if (cAtomSymbol == tAtomSymbol && cBondType == tBondType && map == tmap) {
return tBondIndex;
}
}
return -1;
}
private int getBond(ExtendedMolecule mol, int atom1, int atom2)
{
int ret = -1;
int bondCount = mol.getConnAtoms(atom1);
for (int tbi = 0; tbi < bondCount; tbi++) {
int tBondAtom = mol.getConnAtom(atom1, tbi);
if (tBondAtom == atom2) {
ret = mol.getConnBond(atom1, tbi);
break;
}
}
return ret;
}
private int findMapAt(ExtendedMolecule mol, int atom, int map)
{
int ret = -1;
int bondCount = mol.getConnAtoms(atom);
int m = mol.getAtomMapNo(atom);
if (m == map) {
ret = atom;
}
if (ret == -1) {
for (int tbi = 0; tbi < bondCount; tbi++) {
int tBondAtom = mol.getConnAtom(atom, tbi);
m = mol.getAtomMapNo(tBondAtom);
if (m == map) {
ret = tBondAtom;
break;
}
}
}
return ret;
}
private void generateKeys(Reaction rxn)
{
// (1)
// FIND ATOM WITH MAP NO IN TARGET
// FOR ALL ATOMS ON TARGET
// IF MAP(ATOM)== MAP
// TATOM = ATOM
// END FOR
//(2)
// for all bonds at targetatom
// if map(atom)== map
// return atom
// end for
StringBuilder sb = new StringBuilder();
ExtendedMolecule m = new ExtendedMolecule();
initKeys();
if (debug) {
System.out.println(" " + m.toString());
}
int comp = rxn.getReactants();
int prod = rxn.getProducts();
int flags = Molecule.cHelperBitNeighbours | Molecule.cHelperBitRings;
if (comp != 0 && prod != 0) {
if (debug) {
System.out.println("RXNSearcher.search()");
}
ExtendedMolecule component = new StereoMolecule(rxn.getMolecule(0));
for (int c = 1; c < comp; c++) {
ExtendedMolecule mol = rxn.getMolecule(c);
component.addMolecule(mol);
}
component.ensureHelperArrays(flags);
//sb.append(String.format("Component has %d atoms\n",component.getAllAtoms()));
ExtendedMolecule product = new StereoMolecule(rxn.getProduct(0));
for (int c = 1; c < prod; c++) {
product.addMolecule(rxn.getProduct(c));
}
product.ensureHelperArrays(flags);
ExtendedMolecule source = component;
ExtendedMolecule target = product;
// All Mapped atom indizes
int mappedSourceAtoms[] = new int[source.getAllAtoms()];
int mappedTargetAtoms[] = new int[target.getAllAtoms()];
boolean cVisitedBonds[] = new boolean[source.getAllBonds()];
//sb.append(String.format("source has %d atoms\n",source.getAllAtoms()));
int noMappedSourceAtoms = 0;
for (int a = 0; a < source.getAllAtoms(); a++) {
int map = source.getAtomMapNo(a);
if (map > 0) {
mappedSourceAtoms[noMappedSourceAtoms++] = a;
}
}
int noMappedTargetAtoms = 0;
for (int a = 0; a < target.getAllAtoms(); a++) {
int map = target.getAtomMapNo(a);
if (map > 0) {
mappedTargetAtoms[noMappedTargetAtoms++] = a;
}
}
// setup SOURCEBOND and TARGETBOND ARRAY based on MAPPED ATOMS
boolean sourceBonds[] = new boolean[source.getAllBonds()];
boolean targetBonds[] = new boolean[target.getAllBonds()];
// for (int k = 0; k < idx; k++) {
//// System.out.printf("Map [%d] -> [%d]\n",k,source.getAtomMapNo(k));
// int s = source.getConnAtoms(k);
// for (int b = 0; b < s; b++) {
// int a2 = source.getConnAtom(k, b);
// System.out.printf("Map #[%d] -> M[%d] = #[%d] -> M[%d]\n",
// k,source.getAtomMapNo(k),a2,
// source.getAtomMapNo(a2));
// }
// }
// if (true)
// return "";
// for all mapped atoms
for (int k = 0; k < noMappedSourceAtoms; k++) {
// sourceAtom
int sourceAtom = mappedSourceAtoms[k];
int sourceMapNo = source.getAtomMapNo(sourceAtom);
// targetAtom = find atom with same map no as sourceAtom (1)
int targetAtom = getMappedAtom(target, sourceMapNo);
debug("Working on atom %d (%d) target atom is %d\n", sourceMapNo, sourceAtom, targetAtom);
// if not found
// break;
if (targetAtom == -1) {
break;
}
// debug("Map first (%d) (%d-%d)\n",sourceMapNo, sourceAtom,targetAtom);
// boundCounts at source and target atom
int sourceBondCount = source.getConnAtoms(sourceAtom);
int targetBondCount = target.getConnAtoms(targetAtom);
// for all bonds at source Atom
for (int cbi = 0; cbi < sourceBondCount; cbi++) {
int sourceBondConnectedAtom = source.getConnAtom(sourceAtom, cbi);
int sourceBondIndex = source.getConnBond(sourceAtom, cbi);
int sourceBondType = getBondType(source, sourceBondIndex);
// if sourceBond is not visited
if (!sourceBonds[sourceBondIndex]) {
// amap = map(bondAtom)
int sourceBondConnectedAtomMap = source.getAtomMapNo(sourceBondConnectedAtom);
debug("\tChecking Source Bond on atom %d (%d)\n",
sourceBondConnectedAtomMap, sourceBondConnectedAtom);
// if bondAtom is mapped
if (sourceBondConnectedAtomMap != 0) {
// find atom with amap as at targetAtom bonds
int targetBondAtom = findMapAt(target, targetAtom, sourceBondConnectedAtomMap);
// debug("Mapping source bond %d (%d-%d) (%d-%d)\n",
// cbi,
// sourceMapNo,
// sourceBondConnectedAtomMap,
// sourceAtom,
// sourceBondConnectedAtom
// );
// if same map is found
if (targetBondAtom != -1) {
int targetBondIndex = getBond(target, targetAtom, targetBondAtom);
// TARGETBOND is visited
targetBonds[targetBondIndex] = true;
// if bondtype differs
int targetBondType = getBondType(target, targetBondIndex);
// The bond types don't match
if (targetBondType != sourceBondType) {
// its a change
// sourceBond[i] is visited
if (debug) {
System.out.println(String.format("Map: %d-%d bond CHANGE %d/%d", sourceMapNo, sourceBondConnectedAtomMap, sourceBondType, targetBondType));
}
sourceBonds[sourceBondIndex] = true;
addChangeKey(source.getAtomicNo(sourceAtom), source.getAtomicNo(sourceBondConnectedAtom), sourceBondType, targetBondType);
//addKey(key);
//addKey(CH_ONLY);
// else
} else {
// sourceBond[i] is visited
sourceBonds[sourceBondIndex] = true;
// no change
// end if
}
// else (map not found)
} else {
// its a break;
// sourceBond[i] is visited
if (debug) {
System.out.println(String.format("Map: %d-%d bond BREAK %d", sourceMapNo, sourceBondConnectedAtomMap, sourceBondType));
}
sourceBonds[sourceBondIndex] = true;
addDeleteKey(sourceBondType, source.getAtomicNo(sourceAtom), source.getAtomicNo(sourceBondConnectedAtom));
// addKey(key);
// addKey(DEL_ONLY);
// ??? don't mark bond as visited we want to find the CREATE
// end if
}
} else {
;
// Not a mapped atom, we will deal with this in the next section
// System.out.println(String.format("Map: %d Not mapped atom", sourceMapNo));
// not mapped atom
// ignore
}
} // end if
} // end for
// Deal with the non-mapped atoms...
// for all bonds at source Atom
for (int cbi = 0; cbi < sourceBondCount; cbi++) {
int cBondAtom = source.getConnAtom(sourceAtom, cbi);
int cBondIndex = source.getConnBond(sourceAtom, cbi);
int cBondType = getBondType(source, cBondIndex);
// int cAtomSymbol = source.getAtomicNo(cBondAtom);
// if sourceBond is not visited
// System.out.println(String.format("Map %d running at atom %d map %d",sourceMapNo,cBondAtom,source.getAtomMapNo(cBondAtom)));
if (!sourceBonds[cBondIndex]) {
int cbMap = source.getAtomMapNo(cBondAtom);
// if bondAtom is not mapped
if (cbMap == 0) {
int tBondIndex = getSameBond(source, cBondAtom, cBondIndex, target, targetAtom);
if (tBondIndex != -1) {
// sourcebond is visited
// TARGETBOND IS VISITED
sourceBonds[cBondIndex] = true;
targetBonds[tBondIndex] = true;
// System.out.println(String.format("No Map/No change -> found bond index %d ", sourceMapNo));
// no change
// else
} else {
// BREAK_BOND
// sourcebond is visited
// if (debug)
// System.out.println(String.format("Map: %d (%d-%d) Atom Type: %d bond at atom " +
// "BREAK",
// sourceMapNo,
// sourceAtom,cBondAtom,
// source.getAtomicNo(cBondAtom)));
sourceBonds[cBondIndex] = true;
addDeleteKey(cBondType, source.getAtomicNo(sourceAtom), source.getAtomicNo(cBondAtom));
if (debug) {
System.out.println(String.format("Map: %d (%d-%d) Atom Type: %d bond at atom " +
"DELETE",
sourceMapNo,
sourceAtom, cBondAtom,
source.getAtomicNo(cBondAtom)));
}
// addKey(key);
//addKey(DEL_ONLY);
// end if
}
} else {
// This should not happen, since we dealt with this already before
if (debug) {
System.out.println(String.format("Map: %d Found SHOULD NOT", cbMap));
}
} // end if
} else {
// The bond has already been
// else
//???
}
// end if
// end for
}
// for all target bounds which have not yet been visited
// they might be created, however, we'd need to check whether there's a mapping
// if (sourceBondCount < targetBondCount) {
// for all bonds at target atom
for (int tbi = 0; tbi < targetBondCount; tbi++) {
int tBondIndex = target.getConnBond(targetAtom, tbi);
int tBondType = getBondType(target, tBondIndex);
int tAtom = target.getConnAtom(targetAtom, tbi);
int tmap = target.getAtomMapNo(tAtom);
int an = target.getAtomicNo(tAtom);
// if targetbond is not visited
if (!targetBonds[tBondIndex]) {
//those are CREATE_BONDS
if (debug) {
System.out.println(String.format("Map: %d-%d (%d) bond at atom CREATE_2", sourceMapNo, tmap, an));
}
targetBonds[tBondIndex] = true;
int key = addCreateKey(tBondType, target.getAtomicNo(targetAtom), target.getAtomicNo(tAtom));
addKey(key);
addKey(CR_ONLY);
} //endif
} // end for
// } //endif
} //end for all mapped atoms
}
}
public void debug(String format, Object... args)
{
if (debug)
System.out.printf(format, args);
}
public static void main(String args[])
{
ReactionIndexer rs = new ReactionIndexer();
try {
for (int i = 1; i <= 11; i++) {
RXNFileParser p = new RXNFileParser();
Reaction r = new Reaction();
p.parse(r, new java.io.File("RXN" + i + ".rxn"));
if (debug) {
System.out.println("RXN: " + r.getMolecules());
}
rs.getKeys(r);
}
} catch (Throwable e) {
System.err.println("Error parsing RDFILE " + e);
e.printStackTrace();
}
}
}
/*
class RDFileReader
{
BufferedReader rd = null;
StringBuilder rxn = null;
StringBuilder data = null;
public RDFileReader(InputStream is) throws IOException
{
rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String line;
line = rd.readLine();
if (line == null || !line.startsWith("$RDFILE "))
throw new IOException("Invalid File Header");
line = rd.readLine();
if (line == null)
throw new IOException("Invalid File Header");
line = rd.readLine();
if (line == null || !line.startsWith("$RFMT"))
throw new IOException("File is empty");
}
boolean hasNext()
{
boolean ret = false;
StringBuilder r = new StringBuilder();
StringBuilder d = new StringBuilder();
// The default buffer is the reaction buffer
StringBuilder sb = r;
String line;
try {
boolean eof = true;
while ((line = rd.readLine()) != null) {
eof = false;
if (line.startsWith("$RFMT")) {
// System.out.println("End of This RXN..." +line);
break;
}
// Switch the buffer to the data buffer
if (line.startsWith("$DTYPE")) {
// System.out.println("Switching To Data Buffer " + line);
sb = data;
}
sb.append(line);
sb.append("\n");
}
if (!eof) {
data = d;
rxn = r;
ret = true;
}
} catch (IOException e) {
ret = false;
}
return ret;
}
public Reaction getReaction()
{
Reaction r = new Reaction();
RXNFileParser p = new RXNFileParser();
try {
r = p.getReaction(rxn.toString());
} catch (Exception e) {
System.err.println("Error parsing reaction...");
r = null;
}
return r;
}
}
*/
© 2015 - 2025 Weber Informatics LLC | Privacy Policy