All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.actelion.research.chem.TautomerHelper Maven / Gradle / Ivy

There is a newer version: 2024.12.1
Show newest version
/*
* 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