$darkmode
DENOPTIM
DescriptorUtils.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;
20
21import java.io.File;
22import java.io.IOException;
23import java.net.URL;
24import java.util.ArrayList;
25import java.util.Arrays;
26import java.util.Enumeration;
27import java.util.HashMap;
28import java.util.List;
29import java.util.Map;
30import java.util.Set;
31import java.util.TreeSet;
32import java.util.jar.JarEntry;
33import java.util.jar.JarFile;
34
35import org.openscience.cdk.IImplementationSpecification;
36import org.openscience.cdk.qsar.DescriptorEngine;
37import org.openscience.cdk.qsar.IDescriptor;
38
39import com.google.common.io.Files;
40
41import denoptim.exception.DENOPTIMException;
42
43public class DescriptorUtils
44{
45 private static final String FS = System.getProperty("file.separator");
46
51 private static List<String> rejectedDescriptors = Arrays.asList(
52 new String[]{"JPLogP"});
53
54//------------------------------------------------------------------------------
55
64 public static List<String> getAllClassNamesInPackage(String packageName,
65 String jarFileWildQuery)
66 {
67 String pkgPath = packageName.replace(".", FS);
68 List<String> jarPathNames = new ArrayList<String>();
69 String classPath = System.getProperty("java.class.path");
70 String[] jarsAndDirs = classPath.split(File.pathSeparator);
71 for (int i = 0; i < jarsAndDirs.length; i++)
72 {
73 String pathName = jarsAndDirs[i];
74 if (!pathName.endsWith(".jar"))
75 {
76 continue;
77 }
78
79 JarFile jarFile;
80 try {
81 jarFile = new JarFile(pathName);
82 Enumeration<JarEntry> enumeration = jarFile.entries();
83 while (enumeration.hasMoreElements()) {
84 JarEntry jarEntry = enumeration.nextElement();
85
86 if (jarEntry.toString().replace("/", FS).replace("\\", FS)
87 .contains(pkgPath))
88 {
89 jarPathNames.add(pathName);
90 break;
91 }
92 }
93 } catch (IOException e) {
94 e.printStackTrace();
95 }
96 }
97
98 List<String> classNames = new ArrayList<String>();
99 if (jarPathNames.size()>0)
100 {
101 for (String jarPathName : jarPathNames)
102 {
103 classNames.addAll(DescriptorEngine
104 .getDescriptorClassNameByPackage(packageName,
105 new String[]{jarPathName}));
106 }
107 }
108
109 ClassLoader cl = new ClassLoader() {};
110 Enumeration<URL> roots = null;
111 try
112 {
113 roots = cl.getResources("");
114 while (roots.hasMoreElements())
115 {
116 URL url = roots.nextElement();
117 File root = new File(url.getPath());
118 for (File f : Files.fileTraverser().breadthFirst(root))
119 {
120 if (!f.isDirectory() && f.getPath().contains(pkgPath))
121 {
122 String tmp = f.getPath()
123 .substring(f.toString().indexOf(pkgPath))
124 .replace(File.separator, ".")
125 .replace(".class", "");
126 if (tmp.indexOf('$') != -1) continue;
127 if (tmp.indexOf("Test") != -1) continue;
128 if (!classNames.contains(tmp)) classNames.add(tmp);
129 }
130 }
131 }
132 } catch (IOException e)
133 {
134 e.printStackTrace();
135 }
136
137 return classNames;
138 }
139
140//------------------------------------------------------------------------------
141
142 public static List<String> getClassNamesToDenoptimDescriptors()
143 {
144 return getAllClassNamesInPackage("denoptim.fitness.descriptors",
145 "DENOPTIM*.jar");
146 }
147
148//------------------------------------------------------------------------------
149
150 public static List<String> getClassNamesToCDKDescriptors()
151 {
152 return getAllClassNamesInPackage("org.openscience.cdk.qsar.descriptors",
153 "cdk*.jar");
154 }
155
156//------------------------------------------------------------------------------
157
162 public static DescriptorEngine getCDKDescriptorEngine()
163 {
164 return new DescriptorEngine(getClassNamesToCDKDescriptors(), null);
165 }
166
167//------------------------------------------------------------------------------
168
179 public static List<DescriptorForFitness> findAllCDKDescriptors(
180 Set<String> requiredDescriptors) throws DENOPTIMException
181 {
182 List<String> classNames = new ArrayList<String>();
183 classNames.addAll(getClassNamesToCDKDescriptors());
184 return findDescriptorImplementations(requiredDescriptors, classNames);
185 }
186
187//------------------------------------------------------------------------------
188
199 public static List<DescriptorForFitness> findAllDENOPTIMDescriptors(
200 Set<String> requiredDescriptors) throws DENOPTIMException
201 {
202 List<String> classNames = new ArrayList<String>();
203 classNames.addAll(getClassNamesToDenoptimDescriptors());
204 return findDescriptorImplementations(requiredDescriptors, classNames);
205 }
206//------------------------------------------------------------------------------
207
219 public static List<DescriptorForFitness> findAllDescriptorImplementations(
220 Set<String> requiredDescriptors) throws DENOPTIMException
221 {
222 List<String> classNames = new ArrayList<String>();
223 classNames.addAll(getClassNamesToCDKDescriptors());
224 classNames.addAll(getClassNamesToDenoptimDescriptors());
225 return findDescriptorImplementations(requiredDescriptors, classNames);
226 }
227
228//------------------------------------------------------------------------------
229
240 public static List<DescriptorForFitness> findDescriptorImplementations(
241 Set<String> requiredDescriptors, List<String> classNames)
242 throws DENOPTIMException
243 {
244 //We use the engine to get the instances of descriptors calculators
245 DescriptorEngine engine = new DescriptorEngine(classNames, null);
246 List<IDescriptor> iDescs = engine.instantiateDescriptors(classNames);
247
248 List<DescriptorForFitness> chosenOnes =
249 new ArrayList<DescriptorForFitness>();
250 Set<String> chosenOnesShortNames = new TreeSet<String>();
251 // NB: Descriptors names are supposed to be unique in CDK, but we check
252 // for duplicates. This, in case of additional descriptors that do not
253 // belong to CDK and are added to the list.
254 Map<String,String> unq = new HashMap<String,String>();
255 for (int i=0; i<classNames.size(); i++)
256 {
257 String className = classNames.get(i);
258 String[] descrNames = iDescs.get(i).getDescriptorNames();
259 String simpleName = iDescs.get(i).getClass().getSimpleName();
260
261 if (descrNames != null)
262 {
263 for (int j=0; j<descrNames.length;j++)
264 {
265 String descName = descrNames[j];
266
267 if (unq.containsKey(descName))
268 {
269 String msg = "Descriptor '" + descName + "' in part of "
270 + simpleName
271 + " but its name was already used in "
272 + unq.get(descName);
273 throw new DENOPTIMException(msg);
274 }
275 unq.put(descName,simpleName);
276 boolean isChosen = false;
277 if (requiredDescriptors == null)
278 {
279 isChosen = true;
280 } else {
281 for (String requiredDescName : requiredDescriptors)
282 {
283 if (descName.equals(requiredDescName))
284 {
285 isChosen = true;
286 break;
287 }
288 }
289 }
290
291 // We reject selected descriptor implementations that might
292 // have shown to be unreliable
293 for (String rejectedDescName : rejectedDescriptors)
294 {
295 if (descName.equals(rejectedDescName))
296 {
297 isChosen = false;
298 break;
299 }
300 }
301
302 if (isChosen)
303 {
304 chosenOnesShortNames.add(simpleName);
305 IDescriptor impl = iDescs.get(i);
306 IImplementationSpecification implSpec =
307 impl.getSpecification();
308 DescriptorForFitness d = null;
309 if (impl instanceof IDenoptimDescriptor)
310 {
311 IDenoptimDescriptor dnpDescImpl =
312 (IDenoptimDescriptor) impl;
313 d = new DescriptorForFitness(
314 descName, className,impl, j,
315 dnpDescImpl.getDictionaryClass(),
316 dnpDescImpl.getDictionaryDefinition(),
317 dnpDescImpl.getDictionaryTitle());
318 } else {
319 d = new DescriptorForFitness(
320 descName, className,impl, j,
321 engine.getDictionaryClass(implSpec),
322 engine.getDictionaryDefinition(
323 implSpec.getSpecificationReference()),
324 engine.getDictionaryTitle(
325 implSpec.getSpecificationReference()));
326 }
327 chosenOnes.add(d);
328 }
329 }
330 }
331 }
332 return chosenOnes;
333 }
334
335//------------------------------------------------------------------------------
336
337}
This is a reference to a specific descriptor value.
static DescriptorEngine getCDKDescriptorEngine()
Makes an engine using CDK descriptors.
static List< String > getClassNamesToCDKDescriptors()
static List< DescriptorForFitness > findAllCDKDescriptors(Set< String > requiredDescriptors)
Searches for descriptor implementations in the CDK packages.
static List< DescriptorForFitness > findAllDescriptorImplementations(Set< String > requiredDescriptors)
Searches for descriptor implementations.
static List< String > getAllClassNamesInPackage(String packageName, String jarFileWildQuery)
Search for packages in the class path and in the appended archives.
static List< DescriptorForFitness > findAllDENOPTIMDescriptors(Set< String > requiredDescriptors)
Searches for descriptor implementations in the DENOPTIM packages.
static List< String > rejectedDescriptors
List of descriptor names that are excluded from default import because they have been shown to contai...
static List< DescriptorForFitness > findDescriptorImplementations(Set< String > requiredDescriptors, List< String > classNames)
Searches for descriptor implementations.
static List< String > getClassNamesToDenoptimDescriptors()
This interface forces descriptors that are not defined in the CDK ontology to provide information tha...
String[] getDictionaryClass()
Get the classification of this descriptor.
String getDictionaryTitle()
Gets the title of this descriptor as it should be in the dictionary.
String getDictionaryDefinition()
Get a string that describes the descriptor in detail.