7
* Copyright (C) 2007 Andreas Schueller <archvile18@users.sf.net>
9
* Contact: cdk-devel@lists.sourceforge.net
11
* This program is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU Lesser General Public License
13
* as published by the Free Software Foundation; either version 2.1
14
* of the License, or (at your option) any later version.
15
* All we ask is that proper credit is given for our work, which includes
16
* - but is not limited to - adding the above copyright notice to the beginning
17
* of your source code files, and to any copyright notice that you may distribute
18
* with programs based on this work.
20
* This program is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU Lesser General Public License for more details.
25
* You should have received a copy of the GNU Lesser General Public License
26
* along with this program; if not, write to the Free Software
27
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29
package org.openscience.cdk.tools.manipulator;
31
import java.io.IOException;
32
import java.util.Comparator;
33
import java.util.Iterator;
34
import org.openscience.cdk.config.IsotopeFactory;
35
import org.openscience.cdk.exception.CDKException;
36
import org.openscience.cdk.interfaces.IAtom;
37
import org.openscience.cdk.interfaces.IAtomContainer;
38
import org.openscience.cdk.interfaces.IBond;
39
import org.openscience.cdk.tools.LoggingTool;
42
* <p>Compares two IAtomContainers for order with the following criteria with decreasing priority:</p>
44
* <li>Compare atom count
45
* <li>Compare molecular weight (heavy atoms only)
46
* <li>Compare bond count
47
* <li>Compare sum of bond orders (heavy atoms only)
49
* <p>If no difference can be found with the above criteria, the IAtomContainers are
50
* considered equal.</p>
52
* @author Andreas Schueller
53
* @cdk.created 2007-09-05
54
* @cdk.module standard
56
public class AtomContainerComparator implements Comparator {
58
/** Configure LoggingTool */
59
private LoggingTool logger = new LoggingTool(AtomContainerComparator.class);
61
/** Creates a new instance of AtomContainerComparator */
62
public AtomContainerComparator() {
66
* <p>Compares two IAtomContainers for order with the following criteria with decreasing priority:</p>
68
* <li>Compare atom count
69
* <li>Compare molecular weight (heavy atoms only)
70
* <li>Compare bond count
71
* <li>Compare sum of bond orders (heavy atoms only)
73
* <p>If no difference can be found with the above criteria, the IAtomContainers are
74
* considered equal.</p>
75
* <p>Returns a negative integer, zero, or a positive integer as the first argument is less than,
76
* equal to, or greater than the second.</p>
77
* <p>This method is null safe.</p>
79
* @param o1 the first IAtomContainer
80
* @param o2 the second IAtomContainer
81
* @return a negative integer, zero, or a positive integer as the first argument is less than, equal
82
* to, or greater than the second.
84
public int compare(Object o1, Object o2) {
86
if (o1 == null && o2 == null)
93
// Check for correct instances
94
if (!(o1 instanceof IAtomContainer) && !(o2 instanceof IAtomContainer))
96
if (!(o1 instanceof IAtomContainer))
98
if (!(o2 instanceof IAtomContainer))
101
IAtomContainer atomContainer1 = (IAtomContainer) o1;
102
IAtomContainer atomContainer2 = (IAtomContainer) o2;
104
// 1. Compare atom count
105
if (atomContainer1.getAtomCount() > atomContainer2.getAtomCount())
107
else if (atomContainer1.getAtomCount() < atomContainer2.getAtomCount())
110
// 2. Atom count equal, compare molecular weight (heavy atoms only)
114
mw1 = getMolecularWeight(atomContainer1);
115
mw2 = getMolecularWeight(atomContainer2);
116
} catch (CDKException e) {
117
logger.warn("Exception in molecular mass calculation.");
125
// 3. Molecular weight equal, compare bond count
126
if (atomContainer1.getBondCount() > atomContainer2.getBondCount())
128
else if (atomContainer1.getBondCount() < atomContainer2.getBondCount())
131
// 4. Bond count equal, compare sum of bond orders (heavy atoms only)
132
double bondOrderSum1 = getBondOrderSum(atomContainer1);
133
double bondOrderSum2 = getBondOrderSum(atomContainer2);
134
if (bondOrderSum1 > bondOrderSum2)
136
else if (bondOrderSum1 < bondOrderSum2)
142
// AtomContainers are equal in terms of this comparator
147
* Returns the molecular weight (exact mass) of the major isotopes
148
* of all heavy atoms of the given IAtomContainer.
149
* @param atomContainer an IAtomContainer to calculate the mocular weight for
150
* @throws org.openscience.cdk.exception.CDKException if an error occurs with the IsotopeFactory
151
* @return the molecularweight (exact mass) of the major isotopes
152
* of all heavy atoms of the given IAtomContainer
154
private double getMolecularWeight(IAtomContainer atomContainer) throws CDKException {
156
Iterator iterator = atomContainer.atoms();
158
while (iterator.hasNext()) {
159
IAtom atom = ((IAtom) iterator.next());
160
if (!atom.getSymbol().equals("H"))
161
mw += IsotopeFactory.getInstance(atomContainer.getBuilder()).getMajorIsotope(atom.getSymbol()).getExactMass();
163
} catch (IOException e) {
164
throw new CDKException(e.getMessage(), e);
170
* Returns the sum of all bond orders of all bonds connecting
171
* heavy atoms only for the given IAtomContainer.
172
* @param atomContainer an IAtomContainer to return the bond order sum from
173
* @return the sum of all bond orders of all bonds connecting
174
* heavy atoms only for the given IAtomContainer.
176
private double getBondOrderSum(IAtomContainer atomContainer) {
177
double bondOrderSum = 0.0;
178
Iterator iterator = atomContainer.bonds();
179
while (iterator.hasNext()) {
180
IBond bond = ((IBond) iterator.next());
181
if (!bond.getAtom(0).getSymbol().equals("H") && !bond.getAtom(1).getSymbol().equals("H"))
182
bondOrderSum += bond.getOrder();