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

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

There is a newer version: 2024.12.1
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 java.util.ArrayList;
import java.util.Arrays;

import static com.actelion.research.chem.SSSearcher.cCountModeRigorous;
import static com.actelion.research.chem.SSSearcher.cDefaultMatchMode;

/**
 * The SRSearcher class handles reaction-sub-structure searches. Correctly, the class
 * should be named SuperReactionSearcher, because it is rather a search for super reactions
 * for a given query reaction. The query reaction may also be called transformation and
 * may contain atom or bond based query features.
 */
public class SRSearcher {
	private StereoMolecule mQueryReactantBuffer,mQueryProductBuffer,mReactantBuffer,mProductBuffer;
	private StereoMolecule mQueryReactant,mQueryProduct,mReactant,mProduct;
	private SSSearcher mReactantSearcher,mProductSearcher;
	private boolean mQueryIsPreprocessed,mReactionIsPreprocessed;
	private int mQueryMaxMapNo,mMaxMapNo;
	private byte[] mQueryCode,mQueryCoords,mQueryMapping,mReactionCode,mReactionCoords,mReactionMapping;
	private long[] mQueryReactantFFP,mQueryProductFFP,mReactantFFP,mProductFFP;
	private int[] mQueryReactantToProductAtom,mQueryReactantToProductBond,mReactantToProductAtom,mReactantToProductBond;
	private int[] mProductMatch,mQueryNeighborDelta,mNeighborDelta;

	public SRSearcher() {
		mReactantSearcher = new SSSearcher() {
			@Override public boolean areAtomsSimilar(int moleculeAtom, int fragmentAtom) {
				return super.areAtomsSimilar(moleculeAtom, fragmentAtom) && productAtomMatches(moleculeAtom, fragmentAtom);
				}
			@Override public boolean areBondsSimilar(int moleculeBond, int fragmentBond) {
				return super.areBondsSimilar(moleculeBond, fragmentBond) && productBondMatches(moleculeBond, fragmentBond);
				}
			};
		mProductSearcher = new SSSearcher() {
			@Override public boolean areAtomsSimilar(int moleculeAtom, int fragmentAtom) {
				return (mProductMatch == null || mProductMatch[fragmentAtom] == -1 || mProductMatch[fragmentAtom] == moleculeAtom)
					&& super.areAtomsSimilar(moleculeAtom, fragmentAtom);
				}
			};
		}

	public void setQuery(byte[] rxncode, byte[] rxnmapping, byte[] rxncoords, long[] reactantFFP, long[] productFFP) {
		mQueryCode = rxncode;
		mQueryMapping = rxnmapping;
		mQueryCoords = rxncoords;
		mQueryIsPreprocessed = false;
		mQueryReactant = null;
		mQueryReactantFFP = reactantFFP;
		mQueryProduct = null;
		mQueryProductFFP = productFFP;
		}

	public void setReaction(byte[] rxncode, byte[] rxnmapping, byte[] rxncoords, long[] reactantFFP, long[] productFFP) {
		mReactionCode = rxncode;
		mReactionMapping = rxnmapping;
		mReactionCoords = rxncoords;
		mReactionIsPreprocessed = false;
		mReactant = null;
		mReactantFFP = reactantFFP;
		mProduct = null;
		mProductFFP = productFFP;
		}

	/**
	 * This defines the query reaction (or transformation).
	 * Typically, this method is called once, while setReaction() is called many times,
	 * if a reaction collection is searched for hits. For acceleration through ffp based
	 * pre-screening, you should use this method to supply query ffps.
	 * If the query reaction contains multiple reactants or multiple products,
	 * these are merged into one molecule each.
	 * Thus, for a maximum of performance you may avoid this step by parsing a reaction
	 * that contains one reactant and one product only.
	 * @param query
	 * @param reactantFFP
	 * @param productFFP
	 */
	public void setQuery(Reaction query, long[] reactantFFP, long[] productFFP) {
		mQueryCode = null;
		mQueryReactantFFP = reactantFFP;
		mQueryProductFFP = productFFP;
		mQueryIsPreprocessed = false;
		if (query == null || query.getReactants() == 0 || query.getProducts() == 0) {
			mQueryReactant = null;
			mQueryProduct = null;
			return;
			}

		splitQuery(query);
		}

	/**
	 * This defines the query reaction (or transformation).
	 * Typically, this method is called once, while setReaction() is called many times,
	 * if a reaction collection is searched for hits. For acceleration through ffp based
	 * pre-screening, you should use this method to supply query ffps.
	 * If the query reaction contains multiple reactants or multiple products,
	 * these are merged into one molecule each.
	 * Thus, for a maximum of performance you may avoid this step by parsing a reaction
	 * that contains one reactant and one product only.
	 * @param reaction
	 * @param reactantFFP
	 * @param productFFP
	 */
	public void setReaction(Reaction reaction, long[] reactantFFP, long[] productFFP) {
		mReactionCode = null;
		mReactantFFP = reactantFFP;
		mProductFFP = productFFP;
		mReactionIsPreprocessed = false;
		if (reaction == null || reaction.getReactants() == 0 || reaction.getProducts() == 0) {
			mReactant = null;
			mProduct = null;
			return;
		}

		splitReaction(reaction);
	}

	/**
	 * This defines the query reaction (or transformation).
	 * Typically, this method is called once, while setReaction() is called many times,
	 * if a reaction collection is searched for hits.
	 * If the query reaction contains multiple reactants or multiple products,
	 * these are merged into one molecule each.
	 * Thus, for a maximum of performance you may avoid this step by parsing a reaction
	 * that contains one reactant and one product only.
	 * @param query
	 */
	public void setQuery(Reaction query) {
		mQueryCode = null;
		mQueryReactantFFP = null;
		mQueryProductFFP = null;
		mQueryIsPreprocessed = false;
		if (query == null || query.getReactants() == 0 || query.getProducts() == 0) {
			mQueryReactant = null;
			mQueryProduct = null;
			return;
			}

//		if (!query.isPerfectlyMapped())
//			return;

		splitQuery(query);
		}

	public void setReaction(Reaction reaction) {
		mReactionCode = null;
		mReactantFFP = null;
		mProductFFP = null;
		mReactionIsPreprocessed = false;
		if (reaction == null || reaction.getReactants() == 0 || reaction.getProducts() == 0) {
			mReactant = null;
			mProduct = null;
			return;
			}

		splitReaction(reaction);
		}

	private void preprocessQuery() {
		if (!mQueryIsPreprocessed) {
			mQueryMaxMapNo = getHighestMapNo(mQueryReactant, mQueryProduct);
			mReactantSearcher.setFragment(mQueryReactant);
			mProductSearcher.setFragment(mQueryProduct);

			if (mQueryReactant != null && mQueryProduct != null) {
				mQueryReactantToProductAtom = createReactantToProductAtomMap(mQueryReactant, mQueryProduct, mQueryMaxMapNo);
				mQueryReactantToProductBond = createReactantToProductBondMap(mQueryReactant, mQueryProduct, mQueryReactantToProductAtom);
				mQueryNeighborDelta = createMappedAtomNeighborDeltas(mQueryReactant, mQueryProduct, mQueryReactantToProductAtom);
				}

			mQueryIsPreprocessed = true;
			}
		}

	private void preprocessReaction() {
		if (!mReactionIsPreprocessed) {
			mMaxMapNo = getHighestMapNo(mReactant, mProduct);
			mReactantSearcher.setMolecule(mReactant);
			mProductSearcher.setMolecule(mProduct);

			if (mReactant != null && mProduct != null) {
				mReactantToProductAtom = createReactantToProductAtomMap(mReactant, mProduct, mMaxMapNo);
				mReactantToProductBond = createReactantToProductBondMap(mReactant, mProduct, mReactantToProductAtom);
				mNeighborDelta = createMappedAtomNeighborDeltas(mReactant, mProduct, mReactantToProductAtom);
				}

			mReactionIsPreprocessed = true;
			}
		}

	private int getHighestMapNo(StereoMolecule reactant, StereoMolecule product) {
		int maxMapNo = 0;
		for (int atom=0; atom matchList = mReactantSearcher.getMatchList();
		for (int[] match:matchList) {
			Arrays.fill(mProductMatch, -1);
			for (int i=0; i 1) {
			if (mQueryReactantBuffer == null)
				mQueryReactantBuffer = new StereoMolecule();
			mQueryReactant = mQueryReactantBuffer;

			query.getReactant(0).copyMolecule(mQueryReactant);
			for (int i=1; i 1) {
			if (mReactantBuffer == null)
				mReactantBuffer = new StereoMolecule();
			mReactant = mReactantBuffer;

			reaction.getReactant(0).copyMolecule(mReactant);
			for (int i=1; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy