/* $RCSfile$
* $Revision$ $Author$ $Date$
*
* Copyright (C) 2004-2008 The Chemistry Development Kit (CDK) project
*
* Contact: cdk-devel@list.sourceforge.net
*
* 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.
*
* 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.charges;
import java.util.Map;
import java.util.List;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IMolecule;
import org.openscience.cdk.modeling.builder3d.ForceFieldConfigurator;
/**
* The calculation of the MMFF94 partial charges.
* Charges are stored as atom properties:
* for an AtomContainer ac, values are calculated with:
* <pre>
* HydrogenAdder hAdder = new HydrogenAdder();
* SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
* IAtomContainer ac = sp.parseSmiles("CC");
* hAdder.addExplicitHydrogensToSatisfyValency((Molecule)ac);
* MMFF94PartialCharges mmff = new MMFF94PartialCharges();
* mmff.assignMMFF94PartialCharges(ac);
* </pre>
* and for each atom, the value is given by:
* <pre>
* ( (Double)atom.getProperty("MMFF94charge") ).doubleValue().
* </pre>
*
* @author mfe4
* @author chhoppe
* @cdk.created 2004-11-03
* @cdk.module forcefield
* @cdk.githash
*/
public class MMFF94PartialCharges implements IChargeCalculator {
/**
* Constructor for the MMFF94PartialCharges object
*/
public MMFF94PartialCharges() { }
/**
* Main method which assigns MMFF94 partial charges
*
*@param ac AtomContainer
*@return AtomContainer with MMFF94 partial charges as atom properties
*@exception Exception Possible Exceptions
*/
public IAtomContainer assignMMFF94PartialCharges(IAtomContainer ac) throws Exception {
ForceFieldConfigurator ffc = new ForceFieldConfigurator();
ffc.setForceFieldConfigurator("mmff94");
ffc.assignAtomTyps((IMolecule)ac);
Map<String,Object> parameterSet = ffc.getParameterSet();
// for this calculation,
// we need some values stored in the vector "data" in the
// hashtable of these atomTypes:
double charge = 0;
double formalCharge = 0;
double formalChargeNeigh = 0;
double theta = 0;
double sumOfFormalCharges = 0;
double sumOfBondIncrements = 0;
IAtom thisAtom = null;
List<IAtom> neighboors;
Object data = null;
Object bondData = null;
Object dataNeigh = null;
java.util.Iterator<IAtom> atoms = ac.atoms().iterator();
while(atoms.hasNext()) {
//logger.debug("ATOM "+i+ " " +atoms[i].getSymbol());
thisAtom = atoms.next();
data = parameterSet.get("data"+thisAtom.getAtomTypeName());
neighboors = ac.getConnectedAtomsList(thisAtom);
formalCharge = thisAtom.getCharge();
theta = (Double)((List)data).get(5);
charge = formalCharge * (1 - (neighboors.size() * theta));
sumOfFormalCharges = 0;
sumOfBondIncrements = 0;
for (IAtom neighboor : neighboors) {
IAtom neighbour = (IAtom) neighboor;
dataNeigh = parameterSet.get("data" + neighbour.getAtomTypeName());
if (parameterSet.containsKey("bond" + thisAtom.getAtomTypeName() + ";" + neighbour.getAtomTypeName())) {
bondData = parameterSet.get("bond" + thisAtom.getAtomTypeName() + ";" + neighbour.getAtomTypeName());
sumOfBondIncrements -= (Double) ((List)bondData).get(4);
} else
if (parameterSet.containsKey("bond" + neighbour.getAtomTypeName() + ";" + thisAtom.getAtomTypeName())) {
bondData = parameterSet.get("bond" + neighbour.getAtomTypeName() + ";" + thisAtom.getAtomTypeName());
sumOfBondIncrements += (Double) ((List)bondData).get(4);
} else {
// Maybe not all bonds have pbci in mmff94.prm, i.e. C-N
sumOfBondIncrements += (theta - (Double) ((List)dataNeigh).get(5));
}
dataNeigh = parameterSet.get("data" + neighbour.getID());
formalChargeNeigh = neighbour.getCharge();
sumOfFormalCharges += formalChargeNeigh;
}
charge += sumOfFormalCharges * theta;
charge += sumOfBondIncrements;
thisAtom.setProperty("MMFF94charge", charge);
//logger.debug( "CHARGE :"+thisAtom.getProperty("MMFF94charge") );
}
return ac;
}
public void calculateCharges(IAtomContainer container) throws CDKException {
try {
assignMMFF94PartialCharges(container);
} catch (Exception exception) {
throw new CDKException(
"Could not calculate MMFF94 partial charges: " +
exception.getMessage(), exception
);
}
}
}