
com.actelion.research.chem.TautomerHelper Maven / Gradle / Ivy
/*
* Copyright (c) 1997 - 2016
* Actelion Pharmaceuticals Ltd.
* Gewerbestrasse 16
* CH-4123 Allschwil, Switzerland
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package com.actelion.research.chem;
public class TautomerHelper {
private StereoMolecule mMol;
private int[] mChainAtom;
private int[] mChainBond;
private boolean[] mChainNeedsDoubleBond;
private boolean[] mChainNeedsDonorAtom;
private boolean[] mIsTautomerBond;
private int[] mRegionPiCount;
private int[] mRegionDCount;
private int[] mRegionTCount;
public TautomerHelper(StereoMolecule mol) {
mMol = mol;
mMol.ensureHelperArrays(Molecule.cHelperParities);
mChainAtom = new int[mMol.getAtoms()];
mChainBond = new int[mMol.getAtoms()];
mChainNeedsDoubleBond = new boolean[mMol.getAtoms()];
mChainNeedsDonorAtom = new boolean[mMol.getAtoms()];
mIsTautomerBond = new boolean[mMol.getBonds()];
}
/**
* Identifies connected tautomeric regions and assign region numbers to all atoms.
* Atoms sharing the same region share the same number.
* 0: not member of a tautomer region; 1 and above: region number
* @param atomRegionNo int[mol.getAtoms()] filled with 0
* @param keepStereoCenters
* @return region count
*/
public int getAtomRegionNumbers(int[] atomRegionNo, boolean keepStereoCenters) {
if (!findTautomericBonds(keepStereoCenters))
return 0;
int regionCount = assignRegionNumbers(atomRegionNo);
return regionCount;
}
/**
* If no tautomers can be formed then the original molecule is returned.
* Otherwise the original molecule is copied and normalized to create a
* generic tautomer structure without touching the original molecule.
* Different tautomers of the same molecule should always result in the same
* generic tautomer structure. A generic tautomer contains one or more regions
* indicated by bond query features cBondQFSingle & cBondQFDouble. Bond types
* of all bonds of any tautomer region are cBondTypeSingle.
* The highest ranking atom in every region carries a label defining the number
* of double bonds and D and T atoms. The returned molecule has the fragment bit set.
* Canonicalizing the returned molecule with Canonizer mode ENCODE_ATOM_CUSTOM_LABELS
* produces the same idcode from any tautomer.
* If keepStereoCenters is true, then stereo centers with parity 1 or 2, if they are
* absolute or if they are part of an AND/OR group with more than one member,
* are considered stable (non racemising) and, thus, their proton is not considered
* being able to take part in a tautomeric transition.
* @param keepStereoCenters if true, then defined (non-racemising) stereo centers cannot be part of tautomeric regions
* @return generic tautomer with normalized tautomer regions and custom label to encode pi,D,T counts
*/
public StereoMolecule createGenericTautomer(boolean keepStereoCenters) {
if (!findTautomericBonds(keepStereoCenters))
return mMol;
StereoMolecule genericTautomer = mMol.getCompactCopy();
genericTautomer.setFragment(true);
for (int bond=0; bond= 0) {
int currentAtom = mChainAtom[current];
if (forward)
connIndex[current] = mMol.getConnAtoms(currentAtom);
connIndex[current]--;
int desiredBondOrder = mChainNeedsDoubleBond[current] ? 2 : 1;
while (connIndex[current] >= 0) {
connAtom = mMol.getConnAtom(currentAtom, connIndex[current]);
connBond = mMol.getConnBond(currentAtom, connIndex[current]);
if (!isProtectedAtom[connAtom]
&& !isChainAtom[connAtom]) { // don't allow ring closures
if ((mMol.isDelocalizedBond(connBond) || mMol.getBondOrder(connBond) == desiredBondOrder)
&& (mMol.getAtomPi(connAtom) != 0
|| (mChainNeedsDonorAtom[current]) && isValidDonorAtom(connAtom))) {
// this is a continuation of the delocalized chain or may be an endo-donor as O=C-CHR-C=C
break;
}
}
connIndex[current]--;
}
if (connIndex[current] == -1) {
if (forward && (!mChainNeedsDonorAtom[0] || !mChainNeedsDonorAtom[current])) {
for (int i=current; i>highestValid; i--) {
mIsTautomerBond[mChainBond[i]] = true;
// find and flag exo-donor atoms as CH in NH-C(-CHR2)=C
if (!mChainNeedsDonorAtom[0] && mChainNeedsDoubleBond[i]) {
for (int j=0; j current)
highestValid = current;
continue;
}
current++;
forward = true;
mChainAtom[current] = connAtom;
mChainBond[current] = connBond;
mChainNeedsDoubleBond[current] = !mChainNeedsDoubleBond[current-1] && (mMol.getAtomPi(connAtom) != 0);
mChainNeedsDonorAtom[current] = mChainNeedsDonorAtom[current-1] && (mMol.getAtomPi(connAtom) != 0);
isChainAtom[connAtom] = true;
}
return tautomerBondsFound;
}
private boolean[] locateProtectedAtoms(boolean keepStereoCenters) {
boolean[] isProtectedAtom = new boolean[mMol.getAtoms()];
for (int atom=0; atom 3)
isProtectedAtom[atom] = true;
// protect stereo centers with defined parity
if (keepStereoCenters)
for (int atom=0; atom 2)
oddAndEvenSubstituentMask |= ((i & 1) != 0) ? 1 : 2;
for (int j=0; j
© 2015 - 2025 Weber Informatics LLC | Privacy Policy