com.actelion.research.chem.reaction.Reaction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
/*
* 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);
}
}
}*/
}