/* $Revision$ $Author$ $Date$
*
* Copyright (C) 2002-2007 Stefan Kuhn <shk3@users.sf.net>
*
* Contact: cdk-devel@lists.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.
* 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.fingerprint;
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IRingSet;
import org.openscience.cdk.ringsearch.RingPartitioner;
import org.openscience.cdk.ringsearch.SSSRFinder;
import org.openscience.cdk.tools.manipulator.MolecularFormulaManipulator;
import java.util.BitSet;
import java.util.List;
/**
* Generates an extended fingerprint for a given {@link IAtomContainer}, that
* extends the {@link Fingerprinter} with additional bits describing ring
* features.
*
* @author shk3
* @cdk.created 2006-01-13
* @cdk.keyword fingerprint
* @cdk.keyword similarity
* @cdk.module fingerprint
* @cdk.githash
*
* @see org.openscience.cdk.fingerprint.Fingerprinter
*/
@TestClass("org.openscience.cdk.fingerprint.ExtendedFingerprinterTest")
public class ExtendedFingerprinter implements IFingerprinter {
private final int RESERVED_BITS = 25;
private Fingerprinter fingerprinter = null;
/**
* Creates a fingerprint generator of length <code>DEFAULT_SIZE</code>
* and with a search depth of <code>DEFAULT_SEARCH_DEPTH</code>.
*/
public ExtendedFingerprinter() {
this(Fingerprinter.DEFAULT_SIZE,
Fingerprinter.DEFAULT_SEARCH_DEPTH);
}
public ExtendedFingerprinter(int size) {
this(size, Fingerprinter.DEFAULT_SEARCH_DEPTH);
}
/**
* Constructs a fingerprint generator that creates fingerprints of
* the given size, using a generation algorithm with the given search
* depth.
*
* @param size The desired size of the fingerprint
* @param searchDepth The desired depth of search
*/
public ExtendedFingerprinter(int size, int searchDepth) {
this.fingerprinter
= new Fingerprinter(size-RESERVED_BITS, searchDepth);
}
/**
* Generates a fingerprint of the default size for the given
* AtomContainer, using path and ring metrics. It contains the
* informations from getFingerprint() and bits which tell if the structure
* has 0 rings, 1 or less rings, 2 or less rings ... 10 or less rings
* (referring to smallest set of smallest rings) and bits which tell if
* there is a fused ring system with 1,2...8 or more rings in it
*
*@param container The AtomContainer for which a Fingerprint is generated
*/
@TestMethod("testGetFingerprint_IAtomContainer")
public BitSet getFingerprint(IAtomContainer container)
throws CDKException {
return this.getFingerprint(container,null,null);
}
/**
* Generates a fingerprint of the default size for the given
* AtomContainer, using path and ring metrics. It contains the
* informations from getFingerprint() and bits which tell if the structure
* has 0 rings, 1 or less rings, 2 or less rings ... 10 or less rings and
* bits which tell if there is a fused ring system with 1,2...8 or more
* rings in it. The RingSet used is passed via rs parameter. This must be
* a smallesSetOfSmallestRings. The List must be a list of all ring
* systems in the molecule.
*
* @param atomContainer The AtomContainer for which a Fingerprint is
* generated
* @param ringSet An SSSR RingSet of ac (if not available, use
* getExtendedFingerprint(AtomContainer ac),
* which does the calculation)
* @param rslist A list of all ring systems in ac
* @exception CDKException Description of the Exception
* @return a BitSet representing the fingerprint
*/
@TestMethod("testGetFingerprint_IAtomContainer_IRingSet_List")
public BitSet getFingerprint(IAtomContainer atomContainer,
IRingSet ringSet,
List<IRingSet> rslist) throws CDKException {
IAtomContainer container;
try {
container = (IAtomContainer) atomContainer.clone();
} catch (CloneNotSupportedException e) {
throw new CDKException("Could not clone input");
}
BitSet bitSet = fingerprinter.getFingerprint(container);
int size = this.getSize();
double weight
= MolecularFormulaManipulator.getTotalNaturalAbundance(
MolecularFormulaManipulator.getMolecularFormula(container));
for(int i=1;i<11;i++){
if(weight>(100*i))
bitSet.set(size-26+i); // 26 := RESERVED_BITS+1
}
if(ringSet==null){
ringSet=new SSSRFinder(container).findSSSR();
rslist=RingPartitioner.partitionRings(ringSet);
}
for(int i=0;i<7;i++){
if(ringSet.getAtomContainerCount()>i)
bitSet.set(size-15+i); // 15 := RESERVED_BITS+1+10 mass bits
}
int maximumringsystemsize=0;
for(int i=0;i<rslist.size();i++){
if ( ((IRingSet)rslist.get(i)).getAtomContainerCount()
>
maximumringsystemsize )
maximumringsystemsize
= ( (IRingSet)rslist.get(i) ).getAtomContainerCount();
}
for(int i=0;i<maximumringsystemsize && i<9;i++){
bitSet.set(size-8+i-3);
}
return bitSet;
}
@TestMethod("testGetSize")
public int getSize() {
return fingerprinter.getSize()+RESERVED_BITS;
}
}