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

com.actelion.research.chem.reaction.Transformer Maven / Gradle / Ivy

There is a newer version: 2024.11.2
Show newest version
package com.actelion.research.chem.reaction;

import com.actelion.research.chem.Molecule;
import com.actelion.research.chem.SSSearcher;
import com.actelion.research.chem.StereoMolecule;
import com.actelion.research.util.SortedList;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * Like a Reactor, a Transformer uses a transformation rule (passed as generic Reaction) to apply defined
 * bond changes to one or more real world molecules. It is much faster than a Reactor, but requires the given
 * transformation to consist of one reactant and one product only. It also requires all atoms to be mapped.
 * During Transformer construction the given Reaction is translated into rule list of bond changes.
 * When a molecule is given with setMolecule(), then substructure search is performed to determine all
 * possible matches of the transformation reactant. Matches, which would exceed an atom valence when applying the
 * transformation, are sorted out. applyTransformation() can be called then up to the number of valid matches to
 * construct transformed molecules.
 */
public class Transformer {
	private SortedList mRuleList;
	private int[] mMinFreeValence;	// minimum required free valence on reactant atoms
	private int mBondGain;
	private StereoMolecule mReactant,mTargetMolecule;
	private SSSearcher mSSSearcher;
	private ArrayList mMatchList;
	private String mName;

	public Transformer(StereoMolecule reactant, StereoMolecule product, String name) {
		mName = name;
		reactant.ensureHelperArrays(Molecule.cHelperRings);
		product.ensureHelperArrays(Molecule.cHelperRings);
		mBondGain = product.getBonds() - reactant.getBonds();
		mReactant = reactant;
		mRuleList = new SortedList<>();
		for (int bond=0; bond=0; i--) {
			TransformerRule rule = mRuleList.get(i);
			if (!rule.isFinished())
				rule.finishNoProduct();
			else if (mRuleList.get(i).isNoChange())
				mRuleList.remove(i);
			}

		// calculate minimum free valence of reactant atoms
		mMinFreeValence = new int[reactant.getAtoms()];
		for (int i=0; i 0) ? dif : 0;
					break;
					}
				}
			}

		mSSSearcher = new SSSearcher();
		}

	/**
	 * Use this method before calling applyTransformation() to actually perform the bond changes.
	 * This runs a substructure search of the transformation's reactant on the passed molecule
	 * to determine all possible matches and, thus, the number of possible transformations that
	 * can be applied on the molecule without causing a valence problem.
	 * @param molecule
	 * @param countMode one of SSSearch.cCountMode...
	 * @return number of valid transformation to be applied to this molecule
	 */
	public int setMolecule(StereoMolecule molecule, int countMode) {
		mTargetMolecule = molecule;

		mSSSearcher.setMol(mReactant, mTargetMolecule);
		int matchMode = SSSearcher.cDefaultMatchMode;
		if (mSSSearcher.findFragmentInMolecule(countMode, matchMode) == 0) {
			mMatchList = null;
			return 0;
			}

		// eliminate matches where reaction would exceed an atom valence
		mMatchList = mSSSearcher.getMatchList();
		for (int j=mMatchList.size()-1; j>=0; j--) {
			int[] matchingAtom = mMatchList.get(j);
			for (int k=0; k 0
					 && mMinFreeValence[k] > mTargetMolecule.getFreeValence(matchingAtom[k])) {
						mMatchList.remove(j);
						break;
					}
				}
			}
		}

		return mMatchList.size();
		}

	/**
	 * Creates a canonical representation of the bond state after the transformation
	 * without actually touching the molecule itself.
	 * Together with a history of created bonds states, this can be used to avoid
	 * transformations that lead to products that have been seen before.
	 * @return
	 */
	public int[] getTransformedBondList(StereoMolecule mol, int matchNo) {
		mol.ensureHelperArrays(Molecule.cHelperNeighbours);

		int[] buffer = new int[mol.getBonds()+mBondGain];
		int index = 0;

		int[] matchAtom = mMatchList.get(matchNo);
		boolean[] bondHandled = new boolean[mol.getBonds()];
		for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy