1 /* Copyright (C) 2004-2007  Matteo Floris <mfe4@users.sf.net>
2  *
3  *  Contact: cdk-devel@lists.sourceforge.net
4  *
5  *  This program is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public License
7  *  as published by the Free Software Foundation; either version 2.1
8  *  of the License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 package org.openscience.cdk.qsar.descriptors.molecular;
20 
21 import org.openscience.cdk.exception.CDKException;
22 import org.openscience.cdk.interfaces.IAtomContainer;
23 import org.openscience.cdk.interfaces.IBond;
24 import org.openscience.cdk.interfaces.IBond.Order;
25 import org.openscience.cdk.qsar.AbstractMolecularDescriptor;
26 import org.openscience.cdk.qsar.DescriptorSpecification;
27 import org.openscience.cdk.qsar.DescriptorValue;
28 import org.openscience.cdk.qsar.IMolecularDescriptor;
29 import org.openscience.cdk.qsar.result.IDescriptorResult;
30 import org.openscience.cdk.qsar.result.IntegerResult;
31 
32 /**
33  *  IDescriptor based on the number of bonds of a certain bond order.
34  *
35  * <table border="1"><caption>Parameters for this descriptor:</caption>
36  *   <tr>
37  *     <td>Name</td>
38  *     <td>Default</td>
39  *     <td>Description</td>
40  *   </tr>
41  *   <tr>
42  *     <td>order</td>
43  *     <td>""</td>
44  *     <td>The bond order</td>
45  *   </tr>
46  * </table>
47  *
48  * Returns a single value with name <i>nBX</i> where <i>X</i> can be
49  * <ul>
50  * <li>s for single bonds
51  * <li>d for double bonds
52  * <li>t for triple bonds
53  * <li>a for aromatic bonds
54  * <li>"" for all bonds
55  * </ul>
56  *
57  * Note that the descriptor does not consider bonds to H's.
58  *
59  * @author      mfe4
60  * @cdk.created 2004-11-13
61  * @cdk.module  qsarmolecular
62  * @cdk.githash
63  * @cdk.dictref qsar-descriptors:bondCount
64  */
65 public class BondCountDescriptor extends AbstractMolecularDescriptor implements IMolecularDescriptor {
66 
67     /** defaults to UNSET, which means: count all bonds **/
68     private String order = "";
69 
70     /**
71      *  Constructor for the BondCountDescriptor object
72      */
BondCountDescriptor()73     public BondCountDescriptor() {}
74 
75     /**
76      *  Gets the specification attribute of the BondCountDescriptor object
77      *
78      *@return    The specification value
79      */
80     @Override
getSpecification()81     public DescriptorSpecification getSpecification() {
82         return new DescriptorSpecification(
83                 "http://www.blueobelisk.org/ontologies/chemoinformatics-algorithms/#bondCount", this.getClass()
84                         .getName(), "The Chemistry Development Kit");
85     }
86 
87     /**
88      *  Sets the parameters attribute of the BondCountDescriptor object
89      *
90      *@param  params            The new parameters value
91      *@exception  CDKException  Description of the Exception
92      */
93     @Override
setParameters(Object[] params)94     public void setParameters(Object[] params) throws CDKException {
95         if (params.length > 1) {
96             throw new CDKException("BondCount only expects one parameter");
97         }
98         if (!(params[0] instanceof String)) {
99             throw new CDKException("The parameter must be of type IBond.Order");
100         }
101         String bondType = (String) params[0];
102         if (bondType.length() > 1 || !"sdtq".contains(bondType)) {
103             throw new CDKException("The only allowed values for this parameter are 's', 'd', 't', 'q' and ''.");
104         }
105         // ok, all should be fine
106         order = bondType;
107     }
108 
109     /**
110      *  Gets the parameters attribute of the BondCountDescriptor object
111      *
112      *@return    The parameters value
113      */
114     @Override
getParameters()115     public Object[] getParameters() {
116         // return the parameters as used for the descriptor calculation
117         Object[] params = new Object[1];
118         params[0] = order;
119         return params;
120     }
121 
122     @Override
getDescriptorNames()123     public String[] getDescriptorNames() {
124         if (order.equals(""))
125             return new String[]{"nB"};
126         else
127             return new String[]{"nB" + order};
128     }
129 
130     /**
131      *  This method calculate the number of bonds of a given type in an atomContainer
132      *
133      *@param  container  AtomContainer
134      *@return            The number of bonds of a certain type.
135      */
136     @Override
calculate(IAtomContainer container)137     public DescriptorValue calculate(IAtomContainer container) {
138         if (order.equals("")) {
139             int bondCount = 0;
140             for (IBond bond : container.bonds()) {
141                 boolean hasHydrogen = false;
142                 for (int i = 0; i < bond.getAtomCount(); i++) {
143                     if (bond.getAtom(i).getSymbol().equals("H")) {
144                         hasHydrogen = true;
145                         break;
146                     }
147                 }
148                 if (!hasHydrogen) bondCount++;
149 
150             }
151             return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
152                     bondCount), getDescriptorNames(), null);
153         }
154 
155         int bondCount = 0;
156         for (IBond bond : container.bonds()) {
157             if (bondMatch(bond.getOrder(), order)) {
158                 bondCount += 1;
159             }
160         }
161 
162         return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
163                 bondCount), getDescriptorNames());
164     }
165 
bondMatch(Order order, String orderString)166     private boolean bondMatch(Order order, String orderString) {
167         if (order == Order.SINGLE && "s".equals(orderString))
168             return true;
169         else if (order == Order.DOUBLE && "d".equals(orderString))
170             return true;
171         else if (order == Order.TRIPLE && "t".equals(orderString))
172             return true;
173         else
174             return (order == Order.QUADRUPLE && "q".equals(orderString));
175     }
176 
177     /**
178      * Returns the specific type of the DescriptorResult object.
179      *
180      * The return value from this method really indicates what type of result will
181      * be obtained from the {@link org.openscience.cdk.qsar.DescriptorValue} object. Note that the same result
182      * can be achieved by interrogating the {@link org.openscience.cdk.qsar.DescriptorValue} object; this method
183      * allows you to do the same thing, without actually calculating the descriptor.
184      *
185      * @return an object that implements the {@link org.openscience.cdk.qsar.result.IDescriptorResult} interface indicating
186      *         the actual type of values returned by the descriptor in the {@link org.openscience.cdk.qsar.DescriptorValue} object
187      */
188     @Override
getDescriptorResultType()189     public IDescriptorResult getDescriptorResultType() {
190         return new IntegerResult(1);
191     }
192 
193     /**
194      *  Gets the parameterNames attribute of the BondCountDescriptor object
195      *
196      *@return    The parameterNames value
197      */
198     @Override
getParameterNames()199     public String[] getParameterNames() {
200         String[] params = new String[1];
201         params[0] = "order";
202         return params;
203     }
204 
205     /**
206      *  Gets the parameterType attribute of the BondCountDescriptor object
207      *
208      *@param  name  Description of the Parameter
209      *@return       The parameterType value
210      */
211     @Override
getParameterType(String name)212     public Object getParameterType(String name) {
213         if ("order".equals(name)) return "";
214         return null;
215     }
216 }
217