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

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

There is a newer version: 2024.11.2
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.
 *
 * @author Thomas Sander
 */

package com.actelion.research.chem.reaction;

import com.actelion.research.chem.DrawingObjectList;
import com.actelion.research.chem.Molecule;
import com.actelion.research.chem.StereoMolecule;
import com.actelion.research.gui.generic.GenericRectangle;

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

public class Reaction implements java.io.Serializable {
	private static final long serialVersionUID = 0x2006CAFE;

	private final ArrayList mReactant;
	private final ArrayList mProduct;
	private final ArrayList mCatalyst;
	private DrawingObjectList mDrawingObjectList;
	private String mName;
	private int mMaxMapNo;
	private boolean mIsFragment;	// if there are molecules, then there fragment status takes precedence over this flag

	public Reaction() {
		mReactant = new ArrayList<>();
		mProduct = new ArrayList<>();
		mCatalyst = new ArrayList<>();
		mMaxMapNo = -1;
		mIsFragment = false;
		}

	public Reaction(String name) {
		this();
		mName = name;
		}

	public void clear() {
		mReactant.clear();
		mProduct.clear();
		mCatalyst.clear();
		mDrawingObjectList = null;
		mMaxMapNo = -1;
		}

	public void removeCatalysts() {
		mCatalyst.clear();
		}

	public void removeAtomMapping(boolean keepManualMapping) {
		for (StereoMolecule mol:mReactant)
			mol.removeAtomMapping(keepManualMapping);
		for (StereoMolecule mol:mProduct)
			mol.removeAtomMapping(keepManualMapping);
		}

	public void removeDrawingObjects() {
		mDrawingObjectList = null;
		}

	/**
	 * @return true, if neither of reactants, products, or catalysts contain any atoms
	 */
	public boolean isEmpty() {
		for (StereoMolecule mol:mReactant)
			if (mol.getAllAtoms() != 0)
				return false;

		for (StereoMolecule mol:mProduct)
			if (mol.getAllAtoms() != 0)
				return false;

		for (StereoMolecule mol:mCatalyst)
			if (mol.getAllAtoms() != 0)
				return false;

		return true;
		}

	/**
	 * Sets all reactants and products of this reaction to the given fragment state, i.e. whether they are considered
	 * molecules with all valences satisfied with hydrogens or whether they are substructure fragments that can have query features.
	 * @param f
	 */
	public void setFragment(boolean f) {
		mIsFragment = f;

		for (StereoMolecule mol:mReactant)
			mol.setFragment(f);

		for (StereoMolecule mol:mProduct)
			mol.setFragment(f);
		}

	/**
	 * The naming of this method is in analogy to the corresponding method of the Molecule class.
	 * Returns whether at least one of the reactants or products is marked as substructure fragment.
	 * Only if there are no molecules, then the reaction's explicit fragment status is returned.
	 * @return fragment status of molecules or reaction
	 */
	public boolean isFragment() {
		return mIsFragment || determineFragment();
		}

	/**
	 * @return whether at least one of the reactants or products is marked as substructure fragment.
	 */
	private boolean determineFragment() {
		for (StereoMolecule mol:mReactant)
			if (mol.isFragment())
				return true;
		for (StereoMolecule mol:mProduct)
			if (mol.isFragment())
				return true;

		return false;
		}

	public Reaction(Reaction rxn) {
		this();
		int r = (rxn == null) ? 0 : (rxn.mReactant == null ? 0 : rxn.mReactant.size());
		int p = (rxn == null) ? 0 : (rxn.mProduct == null ? 0 : rxn.mProduct.size());
		int c = (rxn == null) ? 0 : (rxn.mCatalyst == null ? 0 : rxn.mCatalyst.size());
		for (int i = 0; i < r; i++)
			mReactant.add(new StereoMolecule(rxn.getReactant(i)));
		for (int i = 0; i < p; i++)
			mProduct.add(new StereoMolecule(rxn.getProduct(i)));
		for (int i = 0; i < c; i++)
			mCatalyst.add(new StereoMolecule(rxn.getCatalyst(i)));
		mDrawingObjectList = new DrawingObjectList(rxn.getDrawingObjects());
		if (rxn.mName != null)
			mName = rxn.mName;
		mIsFragment = rxn.isFragment();
		}

	public Reaction(StereoMolecule[] mol, int reactantCount) {
		this();
		if (mol != null) {
			mReactant.addAll(Arrays.asList(mol).subList(0, reactantCount));
			mProduct.addAll(Arrays.asList(mol).subList(reactantCount, mol.length));
			}
		mIsFragment = determineFragment();
		}

	public StereoMolecule getReactant(int no) {
		return mReactant.get(no);
		}

	public int getReactants() {
		return mReactant.size();
		}

	public StereoMolecule getProduct(int no) {
		return mProduct.get(no);
		}

	public int getProducts() {
		return mProduct.size();
		}

	public StereoMolecule getCatalyst(int no) {
		return mCatalyst.get(no);
	}

	public int getCatalysts() {
		return mCatalyst.size();
	}

	/**
	 * @return count of reactants and products
	 */
	public int getMolecules() {
		return mReactant.size() + mProduct.size();
		}

	public StereoMolecule getMolecule(int no) {
		return (no < mReactant.size()) ?
			mReactant.get(no)
			: mProduct.get(no - mReactant.size());
		}

	public void addReactant(StereoMolecule reactant) {
		mReactant.add(reactant);
		mMaxMapNo = -1;
		}

	public void addReactant(StereoMolecule reactant, int position) {
		mReactant.add(position, reactant);
		mMaxMapNo = -1;
		}

	public void addProduct(StereoMolecule product) {
		mProduct.add(product);
		mMaxMapNo = -1;
		}

	public void addProduct(StereoMolecule product, int position) {
		mProduct.add(position, product);
		mMaxMapNo = -1;
		}

	public void addCatalyst(StereoMolecule catalyst) {
		mCatalyst.add(catalyst);
	}

	public void addCatalyst(StereoMolecule catalyst, int position) {
		mCatalyst.add(position, catalyst);
	}

	public String getName() {
		return (mName == null) ? "" : mName;
		}

	public void setName(String name) {
		mName = name;
		}

	public DrawingObjectList getDrawingObjects() {
		return mDrawingObjectList;
		}

	public void setDrawingObjects(DrawingObjectList l) {
		mDrawingObjectList = l;
		}

	public double getAverageBondLength() {
		int bondCount = 0;
		double avbl = 0.0;
		for (int i=0; i= r[j].x && r[i].x <= r[j].x + r[j].width)
							return true;
						if (r[i].y + r[i].height >= r[j].y && r[i].y <= r[j].y + r[j].height)
							return true;
						}
					}

				// make new layout, molecule bounds are unreasonably far from each other
				if (i != 0 && r[i-1] != null) {
					if (r[i].x - r[i-1].x - r[i].width > 5 * avbl)
						return true;
					if (r[i].y - r[i-1].y - r[i].height > 5 * avbl)
						return true;
					}
				}
			}

		return false;
		}

	/**
	 * Checks, whether some(!) non-hydrogen and non-exclude-group atoms are mapped,
	 * and whether every mapped reactant atom has exactly one assigned product atom.
	 * @return
	 */
	public boolean isMapped() {
		int maxMapNo = getHighestMapNo();
		boolean[] isUsed = new boolean[maxMapNo+1];

		int mapNoCount = 0;
		for (StereoMolecule reactant:mReactant) {
			for (int atom=0; atom= maxMapNo || !isUsed[mapNo])
						return false;
					isUsed[mapNo] = false;
					}
				}
			}

		return true;
		}

	public int getHighestMapNo() {
		if (mMaxMapNo != -1)
			return mMaxMapNo;

		mMaxMapNo = 0;
		for (int i=0; i= 0; i--) {
			StereoMolecule mol = mReactant.get(i);
			if (mol.getAllAtoms() == 0) {
				mReactant.remove(i);
				}
			}
		size = mProduct.size();
		for (int i = size-1; i >= 0; i--) {
			StereoMolecule mol = mProduct.get(i);
			if (mol.getAllAtoms() == 0) {
				mProduct.remove(i);
				}
			}
		}*/
	}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy