com.actelion.research.chem.reaction.TransformerRule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
package com.actelion.research.chem.reaction;
import com.actelion.research.chem.Molecule;
import com.actelion.research.chem.StereoMolecule;
public class TransformerRule extends Object implements Comparable {
public enum TYPE { CREATE, CHANGE_DIF, CHANGE_ABS, REMOVE, NO_CHANGE, UNKNOWN };
private int mAtom1,mAtom2,mMapNo1,mMapNo2,mBondQFTypes,mTargetBondType,mTargetBondDif;
private TYPE mType;
public TransformerRule(StereoMolecule mol, int bond) {
mAtom1 = mol.getBondAtom(0, bond);
mAtom2 = mol.getBondAtom(1, bond);
int mapNo1 = mol.getAtomMapNo(mAtom1);
int mapNo2 = mol.getAtomMapNo(mAtom2);
if (mapNo1 < mapNo2) {
mMapNo1 = mapNo1;
mMapNo2 = mapNo2;
}
else {
mMapNo1 = mapNo2;
mMapNo2 = mapNo1;
}
mBondQFTypes = mol.getBondQueryFeatures(bond) & Molecule.cBondQFBondTypes;
// if (mol.getBondType(bond) == Molecule.cBondTypeDelocalized || mol.isDelocalizedBond(bond))
// mBondQFTypes |= Molecule.cBondQFDelocalized;
// else {
// int order = mol.getBondOrder(bond);
// if (order == 0)
// mBondQFTypes |= Molecule.cBondQFMetalLigand;
// else if (order == 1)
// mBondQFTypes |= Molecule.cBondQFSingle;
// else if (order == 2)
// mBondQFTypes |= Molecule.cBondQFDouble;
// else if (order == 3)
// mBondQFTypes |= Molecule.cBondQFTriple;
// }
// we don't use the delocalized type
int bondType = mol.getBondTypeSimple(bond);
if (bondType == Molecule.cBondTypeMetalLigand)
mBondQFTypes |= Molecule.cBondQFMetalLigand;
else if (bondType == Molecule.cBondTypeDouble)
mBondQFTypes |= Molecule.cBondQFDouble;
else if (bondType == Molecule.cBondTypeTriple)
mBondQFTypes |= Molecule.cBondQFTriple;
else
mBondQFTypes |= Molecule.cBondQFSingle;
mType = TYPE.UNKNOWN;
}
public int getAtom1() {
return mAtom1;
}
public int getAtom2() {
return mAtom2;
}
public TYPE getType() {
return mType;
}
@Override
public boolean equals(Object o) {
return mMapNo1 == ((TransformerRule)o).mMapNo1 && mMapNo2 == ((TransformerRule)o).mMapNo2;
}
@Override
public int compareTo(TransformerRule o) {
if (mMapNo1 != o.mMapNo1)
return mMapNo1 < o.mMapNo1 ? -1 : 1;
if (mMapNo2 != o.mMapNo2)
return mMapNo2 < o.mMapNo2 ? -1 : 1;
return 0;
}
public boolean isNoChange() {
return mType == TYPE.NO_CHANGE;
}
public boolean isFinished() {
return mType != TYPE.UNKNOWN;
}
public void finishWithProduct(TransformerRule productRule) {
if (mBondQFTypes == productRule.mBondQFTypes) {
mType = TYPE.NO_CHANGE;
}
else if (Integer.bitCount(productRule.mBondQFTypes) == 1) {
mTargetBondType = productRule.mBondQFTypes == Molecule.cBondQFSingle ? Molecule.cBondTypeSingle
: productRule.mBondQFTypes == Molecule.cBondQFDouble ? Molecule.cBondTypeCross
: productRule.mBondQFTypes == Molecule.cBondQFTriple ? Molecule.cBondTypeTriple
: productRule.mBondQFTypes == Molecule.cBondQFMetalLigand ? Molecule.cBondTypeMetalLigand
: Molecule.cBondTypeDelocalized;
mType = TYPE.CHANGE_ABS;
}
else {
int sourceBondOrder = (mBondQFTypes & Molecule.cBondQFMetalLigand) != 0 ? 0
: (mBondQFTypes & Molecule.cBondQFSingle) != 0 ? 1
: (mBondQFTypes & Molecule.cBondQFDouble) != 0 ? 2 : 3;
int targetBondOrder = (productRule.mBondQFTypes & Molecule.cBondQFMetalLigand) != 0 ? 0
: (productRule.mBondQFTypes & Molecule.cBondQFSingle) != 0 ? 1
: (productRule.mBondQFTypes & Molecule.cBondQFDouble) != 0 ? 2 : 3;
if (targetBondOrder == sourceBondOrder)
mType = TYPE.NO_CHANGE;
else {
mTargetBondDif = targetBondOrder - sourceBondOrder;
mType = TYPE.CHANGE_DIF;
}
}
}
public void finishProductOnly() {
mType = TYPE.CREATE;
}
public void finishNoProduct() {
mType = TYPE.REMOVE;
}
/**
* Make sure that the molecule's helper status is at least cHelperNeighbours
* @param mol
* @param matchAtom
* @return
*/
public boolean adaptBondOrder(StereoMolecule mol, int[] matchAtom) {
int atom1 = matchAtom[mAtom1];
int atom2 = matchAtom[mAtom2];
if (mType == TYPE.CREATE) {
// int bondOrder = mTargetBondType == Molecule.cBondTypeMetalLigand ? 0
// : mTargetBondType == Molecule.cBondTypeDouble ? 2
// : mTargetBondType == Molecule.cBondTypeTriple ? 3 : 1;
// if (mol.getFreeValence(atom1) < bondOrder
// || mol.getFreeValence(atom2) < bondOrder)
// return false;
mol.addBond(atom1, atom2, mTargetBondType);
return true;
}
else {
int bond = mol.getBond(atom1, atom2);
if (mType == TYPE.CHANGE_ABS) {
// int bondOrderChange = (mTargetBondType == Molecule.cBondTypeMetalLigand ? 0
// : mTargetBondType == Molecule.cBondTypeDouble ? 2
// : mTargetBondType == Molecule.cBondTypeTriple ? 3 : 1) - mol.getBondOrder(bond);
// if (mol.getFreeValence(atom1) < bondOrderChange
// || mol.getFreeValence(atom2) < bondOrderChange)
// return false;
mol.setBondType(bond, mTargetBondType);
return true;
}
else if (mType == TYPE.CHANGE_DIF) {
// if (mTargetBondDif > 0
// && (mol.getFreeValence(atom1) < mTargetBondDif
// || mol.getFreeValence(atom2) < mTargetBondDif))
// return false;
int targetBondOrder = mol.getBondOrder(bond) + mTargetBondDif;
if (targetBondOrder >= 0 && targetBondOrder <= 3) {
mol.setBondType(bond, Molecule.bondOrderToType(targetBondOrder, true));
return true;
}
}
else if (mType == TYPE.REMOVE) {
mol.markBondForDeletion(bond);
return true;
}
}
return false;
}
public int addBondCode(StereoMolecule mol, int[] matchAtom, boolean[] bondHandled) {
int atom1 = matchAtom[mAtom1];
int atom2 = matchAtom[mAtom2];
if (mType == TYPE.CREATE)
return getBondCode(atom1, atom2, Molecule.bondTypeToOrder(mTargetBondType));
int bond = mol.getBond(atom1, atom2);
if (mType == TYPE.CHANGE_ABS) {
bondHandled[bond] = true;
return getBondCode(atom1, atom2, Molecule.bondTypeToOrder(mTargetBondType));
}
if (mType == TYPE.CHANGE_DIF) {
int targetBondOrder = mol.getBondOrder(bond) + mTargetBondDif;
if (targetBondOrder >= 0 && targetBondOrder <= 3) {
bondHandled[bond] = true;
return getBondCode(atom1, atom2, targetBondOrder);
}
else {
return -1;
}
}
if (mType == TYPE.REMOVE) {
bondHandled[bond] = true;
return -1;
}
return -1;
}
public static int getBondCode(int atom1, int atom2, int bondOrder) {
return (atom1 < atom2) ?
(atom1 << 17) + (atom2 << 2) + bondOrder
: (atom2 << 17) + (atom1 << 2) + bondOrder;
}
}