/*
* Copyright (c) 2003-2012 Fred Hutchinson Cancer Research Center
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fhcrc.cpl.viewer.metabologna;
import org.fhcrc.cpl.toolbox.chem.*;
import org.fhcrc.cpl.toolbox.ApplicationContext;
import org.openscience.cdk.interfaces.*;
import org.openscience.cdk.nonotify.NoNotificationChemObjectBuilder;
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
import org.openscience.cdk.tools.LonePairElectronChecker;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.isomorphism.UniversalIsomorphismTester;
import org.openscience.cdk.isomorphism.mcss.RMap;
import org.openscience.cdk.isomorphism.matchers.IQueryAtomContainer;
import org.openscience.cdk.DefaultChemObjectBuilder;
import org.openscience.cdk.Atom;
import org.openscience.cdk.CDKConstants;
import org.openscience.cdk.smiles.SmilesParser;
import org.openscience.cdk.reaction.IReactionProcess;
import org.openscience.cdk.reaction.type.AdductionProtonPBReaction;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
/**
* Represents the reduction of any double bond between two Carbons and addition of hydrogens.
* Checks if formula has a double bond somewhere.
*
* Triple, quadruple bonds not supported.
*
*/
public class ReduceDoubleBondAdd2HMod implements ChemicalModification
{
//C=C
public static IMolecule cDoubleBondC;
static
{
try
{
SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
cDoubleBondC = sp.parseSmiles("C=C");
AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(cDoubleBondC);
LonePairElectronChecker lpcheck = new LonePairElectronChecker();
lpcheck.saturate(cDoubleBondC);
}
catch (CDKException e)
{
e.printStackTrace(System.err);
}
}
public ReduceDoubleBondAdd2HMod()
{
}
public static void unsetAtomProperties(IAtom atom)
{
//Remove properties from the atom so that they can be inferred
//Not all of these are necessary
atom.setAtomTypeName((String) CDKConstants.UNSET);
atom.setMaxBondOrder((IBond.Order) CDKConstants.UNSET);
atom.setBondOrderSum((Double) CDKConstants.UNSET);
atom.setCovalentRadius((Double) CDKConstants.UNSET);
atom.setValency((Integer) CDKConstants.UNSET);
atom.setFormalCharge((Integer) CDKConstants.UNSET);
atom.setHybridization((IAtomType.Hybridization) CDKConstants.UNSET);
atom.setFormalNeighbourCount((Integer) CDKConstants.UNSET);
atom.setFlag(CDKConstants.IS_HYDROGENBOND_ACCEPTOR, false);
atom.setFlag(CDKConstants.IS_HYDROGENBOND_DONOR, false);
atom.setFlag(CDKConstants.ISAROMATIC, false);
}
/**
*
* @param adduct
* @return
*/
public void perform(Adduct adduct)
{
IMolecule cdkMolecule = adduct.getMolecule();
try
{
List<List<RMap>> bondMappings = UniversalIsomorphismTester.getSubgraphMaps(cdkMolecule, cDoubleBondC);
int bondIdInMolecule = bondMappings.get(0).get(0).getId1();
IBond bondInMolecule = cdkMolecule.getBond(bondIdInMolecule);
bondInMolecule.setOrder(IBond.Order.SINGLE);
for (int i=0; i<=1; i++)
{
IAtom atom = bondInMolecule.getAtom(i);
IAtom newHydrogen = cdkMolecule.getBuilder().newAtom("H");
cdkMolecule.addAtom(newHydrogen);
IBond newBond = cdkMolecule.getBuilder().newBond(atom, newHydrogen, IBond.Order.SINGLE);
cdkMolecule.addBond(newBond);
unsetAtomProperties(atom);
}
AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(cdkMolecule);
adduct.updateFormula();
adduct.getModifications().add(this);
}
catch (CDKException e)
{
ApplicationContext.errorMessage("Reaction failure",e);
}
/*
//assume cdkMolecule not null, i.e., canPerform has returned true
setOfReactants.addMolecule(cdkMolecule);
IReactionProcess rectionProcess = new AdductionProtonPBReaction();
try
{
IReactionSet setOfReactions = rectionProcess.initiate(setOfReactants, null);
IChemObjectBuilder builder = NoNotificationChemObjectBuilder.getInstance();
//todo: fix this. Applying all reactions
for (IReaction reaction : setOfReactions.reactions())
{
IMoleculeSet products = reaction.getProducts();
//only one product for this reaction, guaranteed
IMolecule product = products.getMolecule(0);
for (int i=0; i<product.getAtomCount(); i++)
{
IAtom atom = product.getAtom(i);
if (atom.getFlag(CDKConstants.REACTIVE_CENTER))
{
IAtom newHydrogen = builder.newAtom("H");
product.addAtom(newHydrogen);
IBond newBond = product.getBuilder().newBond(atom, newHydrogen, IBond.Order.SINGLE);
product.addBond(newBond);
//Remove properties from the atom so that they can be inferred
//Not all of these are necessary
atom.setAtomTypeName((String) CDKConstants.UNSET);
atom.setMaxBondOrder((IBond.Order) CDKConstants.UNSET);
atom.setBondOrderSum((Double) CDKConstants.UNSET);
atom.setCovalentRadius((Double) CDKConstants.UNSET);
atom.setValency((Integer) CDKConstants.UNSET);
atom.setFormalCharge((Integer) CDKConstants.UNSET);
atom.setHybridization((IAtomType.Hybridization) CDKConstants.UNSET);
atom.setFormalNeighbourCount((Integer) CDKConstants.UNSET);
atom.setFlag(CDKConstants.IS_HYDROGENBOND_ACCEPTOR, false);
atom.setFlag(CDKConstants.IS_HYDROGENBOND_DONOR, false);
atom.setFlag(CDKConstants.ISAROMATIC, false);
break;
}
}
// AtomContainerManipulator.clearAtomConfigurations(product);
AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(product);
adduct.setMolecule(product);
}
}
catch (CDKException e)
{
ApplicationContext.errorMessage("Reaction failure",e);
}
// adduct.setFormula(adduct.getFormula().createFormulaWithAddition(formulaToAdd));
// adduct.getModifications().add(this);
*/
}
/**
* Just checks whether there's a double bond to reduce.
* @param adduct
* @return
*/
public boolean canPerform(Adduct adduct)
{
//if we don't have a molecule, fail
IMolecule molecule = adduct.getMolecule();
if (molecule == null)
return false;
boolean canPerform = false;
try
{
//if this fails in some way, we can't perform the modification
canPerform = UniversalIsomorphismTester.isSubgraph(molecule, cDoubleBondC);
}
catch (CDKException e)
{}
return canPerform;
}
public String getSymbol()
{
return "+ H2";
}
public String getName()
{
return "DoubleBondReduction2HAddition";
}
}