$darkmode
DENOPTIM
TanimotoMolSimilarity.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2022 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (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 Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.fitness.descriptors;
20
21import java.lang.reflect.Constructor;
22
23import org.openscience.cdk.DefaultChemObjectBuilder;
24import org.openscience.cdk.exception.CDKException;
25import org.openscience.cdk.fingerprint.IBitFingerprint;
26import org.openscience.cdk.fingerprint.IFingerprinter;
27import org.openscience.cdk.fingerprint.ShortestPathFingerprinter;
28import org.openscience.cdk.interfaces.IAtomContainer;
29import org.openscience.cdk.interfaces.IChemObjectBuilder;
30import org.openscience.cdk.qsar.AbstractMolecularDescriptor;
31import org.openscience.cdk.qsar.DescriptorSpecification;
32import org.openscience.cdk.qsar.DescriptorValue;
33import org.openscience.cdk.qsar.IMolecularDescriptor;
34import org.openscience.cdk.qsar.result.DoubleResult;
35import org.openscience.cdk.qsar.result.DoubleResultType;
36import org.openscience.cdk.qsar.result.IDescriptorResult;
37import org.openscience.cdk.similarity.Tanimoto;
38import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
39
40import denoptim.fitness.IDenoptimDescriptor;
41
42
48public class TanimotoMolSimilarity extends AbstractMolecularDescriptor
49implements IMolecularDescriptor, IDenoptimDescriptor
50{
51 //private static ILoggingTool logger = LoggingToolFactory.createLoggingTool(
52 // TanimotoMolSimilarity.class);
53 private IBitFingerprint referenceFingerprint;
54 private IFingerprinter fingerprinter;
55 private String fingerprinterName = "none";
56 private static final String[] PARAMNAMES = new String[] {
57 "fingerprinterImplementation","referenceFingerprint"};
58
59 private static final String[] NAMES = {"TanimotoSimilarity"};
60
64 private static IChemObjectBuilder cdkBuilder =
65 DefaultChemObjectBuilder.getInstance();
66
67//------------------------------------------------------------------------------
68
73
74//------------------------------------------------------------------------------
75
85 @Override
86 public DescriptorSpecification getSpecification()
87 {
88 String paramID = "";
89 if (fingerprinter!=null && referenceFingerprint!=null)
90 {
91 paramID = "" + fingerprinterName + referenceFingerprint.hashCode();
92 }
93 return new DescriptorSpecification("Denoptim source code",
94 this.getClass().getName(), paramID, "DENOPTIM project");
95 }
96
97//------------------------------------------------------------------------------
98
103 @Override
104 public String[] getParameterNames() {
105 return PARAMNAMES;
106 }
107
108//------------------------------------------------------------------------------
109
111 @Override
112 public Object getParameterType(String name)
113 {
114 if (name.equals(PARAMNAMES[1]))
115 {
116 return IBitFingerprint.class;
117 } else if (name.equals(PARAMNAMES[0])) {
118 return "";
119 } else {
120 throw new IllegalArgumentException("No parameter for name: "+name);
121 }
122 }
123
124//------------------------------------------------------------------------------
125
133 @Override
134 public void setParameters(Object[] params) throws CDKException
135 {
136 if (params.length != 2)
137 {
138 throw new IllegalArgumentException("TanimotoMolSimilarity only "
139 + "expects two parameter");
140 }
141 if (!(params[1] instanceof IBitFingerprint))
142 {
143 throw new IllegalArgumentException("Parameter does not implemet "
144 + "IBitFingerprint.");
145 }
146 if (!(params[0] instanceof String))
147 {
148 throw new IllegalArgumentException("Parameter is not String ("
149 + params[0].getClass().getName() + ").");
150 }
151
152 fingerprinterName = params[0].toString();
154 referenceFingerprint = (IBitFingerprint) params[1];
155 }
156
157//------------------------------------------------------------------------------
158
159 /*
160 * ASSUMPTION: implementation from package org.openscience.cdk.fingerprint
161 */
162 public static IFingerprinter makeIFingerprinter(String classShortName)
163 throws CDKException
164 {
165 IFingerprinter fp = null;
166 try
167 {
168 Class<?> cl = Class.forName("org.openscience.cdk.fingerprint."
169 + classShortName);
170 for (Constructor<?> constructor : cl.getConstructors())
171 {
172 Class<?>[] params = constructor.getParameterTypes();
173 if (params.length == 0)
174 {
175 fp = (IFingerprinter) constructor.newInstance();
176 } else if (params.length == 1 && params[0].equals(
177 IChemObjectBuilder.class))
178 {
179 //NB potential source of ambiguity on the builder class
180 fp = (IFingerprinter) constructor.newInstance(cdkBuilder);
181 }
182 // NB: we know there are constuctors that take more, for example
183 // that of PubchemFingerprinter, but those
184 // exist to enable backwards compatibility
185 if (fp!=null)
186 break;
187 }
188 } catch (Throwable t)
189 {
190 throw new CDKException("Could not make new instance of '"
191 + classShortName + "'.", t);
192 }
193 if (fp == null)
194 {
195 throw new CDKException("Could not make new instance of '"
196 + classShortName + "'. No suitable constructor found.");
197 }
198 return fp;
199 }
200
201//------------------------------------------------------------------------------
202
204 @Override
205 public Object[] getParameters()
206 {
207 Object[] params = new Object[2];
208 params[1] = referenceFingerprint;
209 params[0] = fingerprinterName;
210 return params;
211 }
212
213//------------------------------------------------------------------------------
214
216 @Override
217 public String[] getDescriptorNames()
218 {
219 return NAMES;
220 }
221
222//------------------------------------------------------------------------------
223
225 @Override
226 public DescriptorValue calculate(IAtomContainer mol)
227 {
228 if (fingerprinter instanceof ShortestPathFingerprinter)
229 {
230 try
231 {
232 AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol);
233 } catch (CDKException e1)
234 {
235 throw new IllegalStateException("Could not assign atom types "
236 + "to calculate fingerprint of input molecule.",
237 e1);
238 }
239 }
240
241 DoubleResult result;
242 if (referenceFingerprint==null)
243 {
244 throw new IllegalStateException("Reference fingerprint not set. "
245 + "Cannot calculate Tanimoto similarity.");
246 }
247 if (fingerprinter==null)
248 {
249 throw new IllegalStateException("Fingerprinter not set. "
250 + "Cannot calculate Tanimoto similarity.");
251 }
252
253 try
254 {
255 result = new DoubleResult(Tanimoto.calculate(referenceFingerprint,
256 fingerprinter.getBitFingerprint(mol)));
257 } catch (IllegalArgumentException e)
258 {
259 e.printStackTrace();
260 result = new DoubleResult(Double.NaN);
261 } catch (CDKException e)
262 {
263 e.printStackTrace();
264 result = new DoubleResult(Double.NaN);
265 }
266
267 return new DescriptorValue(getSpecification(),
270 result,
272 }
273
274//------------------------------------------------------------------------------
275
277 @Override
278 public IDescriptorResult getDescriptorResultType()
279 {
280 return new DoubleResultType();
281 }
282
283//------------------------------------------------------------------------------
284
286 @Override
287 public String getDictionaryTitle()
288 {
289 return "Tanimoto Molecular Similarity";
290 }
291
292//------------------------------------------------------------------------------
293
295 @Override
297 {
298 return "The Tanimoto Molecular Similarity is calculated between the "
299 + "reference fingerprint given upon definition of the "
300 + "descriptor (see parameters), and a molecule given as "
301 + "argument when calculating the value of the descriptor. "
302 + "Fingerprints are obtained from a new instance of"
303 + "<code>IFingerprinter</code>, which is created according to "
304 + "the parameter <code>" + PARAMNAMES[0] + "</code>, "
305 + "and take the form of "
306 + "<code>IFingerprinter.getBitFingerprint(mol)</code>";
307 }
308
309//------------------------------------------------------------------------------
310
312 @Override
313 public String[] getDictionaryClass()
314 {
315 return new String[] {"molecular"};
316 }
317
318//------------------------------------------------------------------------------
319
320}
Calculates the molecular similarity against a target compound the fingerprint of which is given as pa...
void setParameters(Object[] params)
Set the parameters attribute of TanimotoMolSimilarity object.
String getDictionaryDefinition()
Get a string that describes the descriptor in detail.Might contain mathematical formulation....
static IFingerprinter makeIFingerprinter(String classShortName)
DescriptorSpecification getSpecification()
Get the specification attribute of Tanimoto molecular similarity.
String[] getParameterNames()
Gets the parameterNames attribute of the TanimotoMolSimilarity object.
TanimotoMolSimilarity()
Constructor for a TanimotoMolSimilarity object.
static IChemObjectBuilder cdkBuilder
Utility for constructing CDK objects.
String[] getDictionaryClass()
Get the classification of this descriptor.A descriptor can belong to one or more classes simultaneous...
String getDictionaryTitle()
Gets the title of this descriptor as it should be in the dictionary.the title
This interface forces descriptors that are not defined in the CDK ontology to provide information tha...