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

com.actelion.research.chem.reaction.Reactor 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.reaction;

import java.util.ArrayList;

import com.actelion.research.chem.Canonizer;
import com.actelion.research.chem.coords.CoordinateInventor;
import com.actelion.research.chem.Molecule;
import com.actelion.research.chem.SSSearcher;
import com.actelion.research.chem.SortedStringList;
import com.actelion.research.chem.StereoMolecule;

public class Reactor {
	private Reaction			mGenericReaction;
	private SSSearcher			mSSSearcher;
	private	StereoMolecule[]	mReactant;
	private int[][]				mMinFreeValence;	// minimum required free valence on reactant atoms
	private boolean[][]			mIsReactionCenter;	// reaction center flags on product atoms
	private boolean				mRetainCoordinates,mFullyMapReactions,mUniqueProductsOnly;
	private int					mMaxGenericMapNo,mMaxCount,mReactantMatchCombinationCount;
	private ArrayList[]	mMatchList;
	private int[][][]			mReactantMapNo;	// Reactant mapNos of the real reactant change with every reactant substructure match
	private StereoMolecule[][]	mProduct;
	private String[][]			mIDCode;
	private boolean[]			mIsDuplicate;

	/**
	 * Constructs a Reactor that is able to construct products from a generic reaction (transformation)
	 * and a list of real world reactants. Reactors built with this constructor will not use product
	 * atom coordinates from the generic products, nor will they be able to generate fully mapped reactions.
	 * They will produce and return all unique products or reactions.
	 * @param reaction generic reactions consisting of reactant substructures with optional query features
	 */
	public Reactor(Reaction reaction) {
		this(reaction, false, false, Integer.MAX_VALUE, true);
		}

	/**
	 * Constructs a Reactor that is able to construct products from a generic reaction (transformation)
	 * and a list of real world reactants. Reactors built with this constructor will be able to generate
	 * fully mapped reactions, They will produce and return all unique products or reactions.
	 * @param reaction generic reactions consisting of reactant substructures with optional query features
	 * @param retainCoordinates if true, then atom coordinates from the generic products are taken into the real world products
	 */
	public Reactor(Reaction reaction, boolean retainCoordinates) {
		this(reaction, retainCoordinates, false, Integer.MAX_VALUE, true);
		}

	/**
	 * Constructs a Reactor that is able to construct products from a generic reaction (transformation)
	 * and a list of real world reactants. The reactor may or may not use atoms coordinates from the generic
	 * products, when generating clean product atom coordinates.
	 * @param reaction generic reactions consisting of reactant substructures with optional query features
	 * @param retainCoordinates if true, then atom coordinates from the generic products are taken into the real world products
	 * @param fullyMapReactions if true, then real world reactants and products will have valid mapping numbers after product generation
	 * @param maxProducts maximum number of products/reactions to be enumerated
	 * @param uniqueOnly whether to skip duplicate products/reactions because of starting material symmetry
	 */
	public Reactor(Reaction reaction, boolean retainCoordinates, boolean fullyMapReactions, int maxProducts, boolean uniqueOnly) {
		// If retainCoordinates is true, then the relative orientation of the
		// generic product's atom coordinates are retained in the real products.
		mGenericReaction = reaction;
		mRetainCoordinates = retainCoordinates;
		mFullyMapReactions = fullyMapReactions;
		mReactant = new StereoMolecule[reaction.getReactants()];
		mMaxCount = maxProducts;
		mUniqueProductsOnly = uniqueOnly;

					// for sub-structure-search all generic reactants must be fragments
		for (int i=0; i 0) ? dif : 0;
								}
							}
						}
					}
				}
			}

					// mark all reaction center atoms in product
		mIsReactionCenter = new boolean[reaction.getProducts()][];
		for (int i=0; i neighbourMapNo) {
												minNeighbourMapNo = neighbourMapNo;
												minNeighbourIndex = n;
												}
											}
										}
									neighbourHandled[minNeighbourIndex] = true;
									pruductNeighbours <<= 10;
									pruductNeighbours += minNeighbourMapNo;
									}

					// get sorted list of mapping no's of attached atoms in reactant
								long reactantNeighbours = 0;
								neighbourHandled = new boolean[reactant.getConnAtoms(l)];
								for (int m=0; m neighbourMapNo) {
												minNeighbourMapNo = neighbourMapNo;
												minNeighbourIndex = n;
												}
											}
										}
									neighbourHandled[minNeighbourIndex] = true;
									reactantNeighbours <<= 10;
									reactantNeighbours += minNeighbourMapNo;
									}

								if (pruductNeighbours != reactantNeighbours)
									mIsReactionCenter[i][j] = true;
								}
							}
						}
					}
				}
			}

		mSSSearcher = new SSSearcher();
		mMatchList = new ArrayList[mReactant.length];
		}

	/**
	 * Removes unmatched mapping numbers and mapping numbers on exclude atoms
	 * @param rxn
	 */
	private void removeMappingErrors(Reaction rxn) {
		mMaxGenericMapNo = 0;
		for (int i=0; i();
			mReactantMatchCombinationCount = 0;
			return;
			}

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

		mReactantMatchCombinationCount = 1;
		for (int i=0; i 0 && count > mMaxCount)
			count = mMaxCount;

		return count;
		}


	/**
	 * After instantiating the Reactor with fullyMappedReaction==true and after supplying real reactants,
	 * this method may be used to construct the fully mapped reaction. If one or more reactants have multiple
	 * matches of their generic reactants, then multiple reactions leading to isomeric products are returned.
	 * After calling this method, one or more new real reactants may provided with setReactant()
	 * before calling this method again.
	 * @return array with one or more reactions
	 */
	public Reaction[] getFullyMappedReactions() {
		ensureProducts();

		Reaction[] reaction = new Reaction[getProductCount()];

		int count = 0;
		int index = 0;
		int[] matchIndex = new int[mReactant.length];
		do {
			if (!mIsDuplicate[index] || !mUniqueProductsOnly) {
				reaction[count] = new Reaction();
				for (int i=0; i[] matchList, int[] matchListIndex, int genericProductNo) {
			// currently only support for first product of generic reaction
		StereoMolecule genericProduct = mGenericReaction.getProduct(genericProductNo);

		StereoMolecule product = new StereoMolecule();

		int esrGroupCountAND = 0;
		int esrGroupCountOR = 0;
		for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy