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

org.openscience.cdk.Reaction Maven / Gradle / Ivy

/* Copyright (C) 2003-2008  Egon Willighagen 
 *
 * Contact: [email protected]
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 * All we ask is that proper credit is given for our work, which includes
 * - but is not limited to - adding the above copyright notice to the beginning
 * of your source code files, and to any copyright notice that you may distribute
 * with programs based on this work.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
package org.openscience.cdk;

import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IAtomContainerSet;
import org.openscience.cdk.interfaces.IMapping;
import org.openscience.cdk.interfaces.IReaction;

import java.io.Serializable;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

/**
 * Represents the idea of a chemical reaction. The reaction consists of
 * a set of reactants and a set of products.
 *
 * 

The class mostly represents abstract reactions, such as 2D diagrams, * and is not intended to represent reaction trajectories. Such can better * be represented with a ChemSequence. * * @cdk.module data * @cdk.githash * * @author Egon Willighagen <[email protected]> * @cdk.created 2003-02-13 * @cdk.keyword reaction */ public class Reaction extends ChemObject implements Serializable, IReaction, Cloneable { /** * Determines if a de-serialized object is compatible with this class. * * This value must only be changed if and only if the new version * of this class is incompatible with the old version. See Sun docs * for details. */ private static final long serialVersionUID = -554752558363533678L; protected int growArraySize = 3; protected IAtomContainerSet reactants; protected IAtomContainerSet products; /** These are the used solvent, catalysts etc that normally appear above the reaction arrow */ protected IAtomContainerSet agents; protected IMapping[] map; protected int mappingCount; private IReaction.Direction reactionDirection; /** * Constructs an empty, forward reaction. */ public Reaction() { this.reactants = getBuilder().newInstance(IAtomContainerSet.class); this.products = getBuilder().newInstance(IAtomContainerSet.class); this.agents = getBuilder().newInstance(IAtomContainerSet.class); this.map = new Mapping[growArraySize]; mappingCount = 0; reactionDirection = IReaction.Direction.FORWARD; } /** * Returns the number of reactants in this reaction. * * @return The number of reactants in this reaction */ @Override public int getReactantCount() { return reactants.getAtomContainerCount(); } /** * Returns the number of products in this reaction. * * @return The number of products in this reaction */ @Override public int getProductCount() { return products.getAtomContainerCount(); } /** * Returns a MoleculeSet containing the reactants in this reaction. * * @return A MoleculeSet containing the reactants in this reaction * @see org.openscience.cdk.interfaces.IReaction#setReactants */ @Override public IAtomContainerSet getReactants() { return reactants; } /** * Assigns a MoleculeSet to the reactants in this reaction. * * * @param setOfMolecules The new set of reactants * @see #getReactants */ @Override public void setReactants(IAtomContainerSet setOfMolecules) { reactants = setOfMolecules; notifyChanged(); } /** * Returns a MoleculeSet containing the products of this reaction. * * @return A MoleculeSet containing the products in this reaction * @see org.openscience.cdk.interfaces.IReaction#setProducts */ @Override public IAtomContainerSet getProducts() { return products; } /** * Assigns a MoleculeSet to the products of this reaction. * * * @param setOfMolecules The new set of products * @see #getProducts */ @Override public void setProducts(IAtomContainerSet setOfMolecules) { products = setOfMolecules; notifyChanged(); } /** * Returns a MoleculeSet containing the agents in this reaction. * * @return A MoleculeSet containing the agents in this reaction * @see #addAgent */ @Override public IAtomContainerSet getAgents() { return agents; } /** * Returns the mappings between the reactant and the product side. * * @return An Iterator to the Mappings. * @see #addMapping */ @Override public Iterable mappings() { return new Iterable() { @Override public Iterator iterator() { return new MappingIterator(); } }; } /** * The inner Mapping Iterator class. * */ private class MappingIterator implements Iterator { private int pointer = 0; @Override public boolean hasNext() { return pointer < mappingCount; } @Override public IMapping next() { return map[pointer++]; } @Override public void remove() { removeMapping(--pointer); } } /** * Adds a reactant to this reaction. * * @param reactant Molecule added as reactant to this reaction * @see #getReactants */ @Override public void addReactant(IAtomContainer reactant) { addReactant(reactant, 1.0); /* * notifyChanged() is called by addReactant(Molecule reactant, double * coefficient) */ } /** * Adds an agent to this reaction. * * @param agent Molecule added as agent to this reaction * @see #getAgents */ @Override public void addAgent(IAtomContainer agent) { agents.addAtomContainer(agent); notifyChanged(); } /** * Adds a reactant to this reaction with a stoichiometry coefficient. * * @param reactant Molecule added as reactant to this reaction * @param coefficient Stoichiometry coefficient for this molecule * @see #getReactants */ @Override public void addReactant(IAtomContainer reactant, Double coefficient) { reactants.addAtomContainer(reactant, coefficient); notifyChanged(); } /** * Adds a product to this reaction. * * @param product Molecule added as product to this reaction * @see #getProducts */ @Override public void addProduct(IAtomContainer product) { this.addProduct(product, 1.0); /* * notifyChanged() is called by addProduct(Molecule product, double * coefficient) */ } /** * Adds a product to this reaction. * * @param product Molecule added as product to this reaction * @param coefficient Stoichiometry coefficient for this molecule * @see #getProducts */ @Override public void addProduct(IAtomContainer product, Double coefficient) { products.addAtomContainer(product, coefficient); /* * notifyChanged() is called by addReactant(Molecule reactant, double * coefficient) */ } /** * Returns the stoichiometry coefficient of the given reactant. * * @param reactant Reactant for which the coefficient is returned. * @return -1, if the given molecule is not a product in this Reaction * @see #setReactantCoefficient */ @Override public Double getReactantCoefficient(IAtomContainer reactant) { return reactants.getMultiplier(reactant); } /** * Returns the stoichiometry coefficient of the given product. * * @param product Product for which the coefficient is returned. * @return -1, if the given molecule is not a product in this Reaction * @see #setProductCoefficient */ @Override public Double getProductCoefficient(IAtomContainer product) { return products.getMultiplier(product); } /** * Sets the coefficient of a a reactant to a given value. * * @param reactant Reactant for which the coefficient is set * @param coefficient The new coefficient for the given reactant * @return true if Molecule has been found and stoichiometry has been set. * @see #getReactantCoefficient */ @Override public boolean setReactantCoefficient(IAtomContainer reactant, Double coefficient) { boolean result = reactants.setMultiplier(reactant, coefficient); notifyChanged(); return result; } /** * Sets the coefficient of a a product to a given value. * * @param product Product for which the coefficient is set * @param coefficient The new coefficient for the given product * @return true if Molecule has been found and stoichiometry has been set. * @see #getProductCoefficient */ @Override public boolean setProductCoefficient(IAtomContainer product, Double coefficient) { boolean result = products.setMultiplier(product, coefficient); notifyChanged(); return result; } /** * Returns an array of double with the stoichiometric coefficients * of the reactants. * * @return An array of double's containing the coefficients of the reactants * @see #setReactantCoefficients */ @Override public Double[] getReactantCoefficients() { return reactants.getMultipliers(); } /** * Returns an array of double with the stoichiometric coefficients * of the products. * * @return An array of double's containing the coefficients of the products * @see #setProductCoefficients */ @Override public Double[] getProductCoefficients() { return products.getMultipliers(); } /** * Sets the coefficients of the reactants. * * @param coefficients An array of double's containing the coefficients of the reactants * @return true if coefficients have been set. * @see #getReactantCoefficients */ @Override public boolean setReactantCoefficients(Double[] coefficients) { boolean result = reactants.setMultipliers(coefficients); notifyChanged(); return result; } /** * Sets the coefficient of the products. * * @param coefficients An array of double's containing the coefficients of the products * @return true if coefficients have been set. * @see #getProductCoefficients */ @Override public boolean setProductCoefficients(Double[] coefficients) { boolean result = products.setMultipliers(coefficients); notifyChanged(); return result; } /** * Sets the direction of the reaction. * * @param direction The new reaction direction * @see #getDirection */ @Override public void setDirection(IReaction.Direction direction) { reactionDirection = direction; notifyChanged(); } /** * Returns the direction of the reaction. * * @return The direction of this reaction (FORWARD, BACKWARD or BIDIRECTIONAL). * @see org.openscience.cdk.interfaces.IReaction.Direction * @see #setDirection */ @Override public IReaction.Direction getDirection() { return reactionDirection; } /** * Adds a mapping between the reactant and product side to this * Reaction. * * @param mapping Mapping to add. * @see #mappings */ @Override public void addMapping(IMapping mapping) { if (mappingCount + 1 >= map.length) growMappingArray(); map[mappingCount] = mapping; mappingCount++; notifyChanged(); } /** * Removes a mapping between the reactant and product side to this * Reaction. * * @param pos Position of the Mapping to remove. * @see #mappings */ @Override public void removeMapping(int pos) { for (int i = pos; i < mappingCount - 1; i++) { map[i] = map[i + 1]; } map[mappingCount - 1] = null; mappingCount--; notifyChanged(); } /** * Retrieves a mapping between the reactant and product side to this * Reaction. * * @param pos Position of Mapping to get. */ @Override public IMapping getMapping(int pos) { return map[pos]; } /** * Get the number of mappings between the reactant and product side to this * Reaction. * * @return Number of stored Mappings. */ @Override public int getMappingCount() { return mappingCount; } private void growMappingArray() { Mapping[] newMap = new Mapping[map.length + growArraySize]; System.arraycopy(map, 0, newMap, 0, map.length); map = newMap; } /** * Returns a one line string representation of this Atom. * Methods is conform RFC #9. * * @return The string representation of this Atom */ @Override public String toString() { StringBuffer description = new StringBuffer(64); description.append("Reaction("); description.append(getID()); description.append(", #M:").append(mappingCount); description.append(", reactants=").append(reactants.toString()); description.append(", products=").append(products.toString()); description.append(", agents=").append(agents.toString()); description.append(')'); return description.toString(); } /** * Clones this Reaction and its content. * * @return The cloned object */ @Override public Object clone() throws CloneNotSupportedException { Reaction clone = (Reaction) super.clone(); // clone the reactants, products and agents clone.reactants = (IAtomContainerSet) reactants.clone(); clone.agents = (IAtomContainerSet) agents.clone(); clone.products = (IAtomContainerSet) products.clone(); // create a Map of corresponding atoms for molecules (key: original Atom, // value: clone Atom) Map atomatom = new Hashtable(); for (int i = 0; i < reactants.getAtomContainerCount(); ++i) { IAtomContainer mol = reactants.getAtomContainer(i); IAtomContainer mol2 = clone.reactants.getAtomContainer(i); for (int j = 0; j < mol.getAtomCount(); ++j) atomatom.put(mol.getAtom(j), mol2.getAtom(j)); } // clone the maps clone.map = new Mapping[map.length]; for (int f = 0; f < mappingCount; f++) { clone.map[f] = new Mapping(atomatom.get(map[f].getChemObject(0)), atomatom.get(map[f].getChemObject(1))); } return clone; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy