$darkmode
DENOPTIM
Candidate.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Vishwesh Venkatraman <vishwesh.venkatraman@ntnu.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.graph;
20
21import java.io.File;
22
23import org.openscience.cdk.CDKConstants;
24import org.openscience.cdk.interfaces.IAtomContainer;
25import org.openscience.cdk.interfaces.IChemObjectBuilder;
26import org.openscience.cdk.silent.SilentChemObjectBuilder;
27
28import denoptim.constants.DENOPTIMConstants;
29import denoptim.exception.DENOPTIMException;
30import denoptim.io.DenoptimIO;
31import denoptim.utils.MoleculeUtils;
32
33
39public class Candidate implements Comparable<Candidate>, Cloneable
40{
44 private String uid;
45
49 private DGraph graph;
50
54 private IAtomContainer iac;
55
59 private String smiles;
60
64 private double fitness;
65
69 private String sdfFile;
70
74 private String imgFile;
75
79 private String comment;
80
84 private String error;
85
89 private boolean hasFitness;
90
95 private int generationId = -1;
96
100 private String name;
101
105 private int level;
106
107
108//------------------------------------------------------------------------------
109
110 public Candidate()
111 {
112 name = "noname";
113 uid = "UNDEFINED";
114 smiles = "UNDEFINED";
115 hasFitness = false;
116 }
117
118//------------------------------------------------------------------------------
119
121 {
122 this();
123 this.graph = graph;
125 uid = "UNDEFINED";
126 smiles = "UNDEFINED";
127 hasFitness = false;
128 }
129
130//------------------------------------------------------------------------------
131
132 public Candidate(String name, DGraph graph)
133 {
134 this();
135 this.name = name;
136 this.graph = graph;
138 uid = "UNDEFINED";
139 smiles = "UNDEFINED";
140 hasFitness = false;
141 }
142
143//------------------------------------------------------------------------------
144
145 public Candidate(String name, DGraph graph, double fitness,
146 String uid, String smiles)
147 {
148 this();
149 this.name = name;
150 this.graph = graph;
152 this.uid = uid;
153 this.smiles = smiles;
154 this.fitness = fitness;
155 hasFitness = true;
156 }
157
158//------------------------------------------------------------------------------
159
160 private Candidate(String name, DGraph graph,
161 String uid, String smiles, String molFile, String imgFile,
162 String comment, int generationId, int level)
163 {
164 this();
165 this.name = name;
166 this.graph = graph;
168 this.uid = uid;
169 this.smiles = smiles;
170 this.sdfFile = molFile;
171 this.imgFile = imgFile;
172 this.comment = comment;
173 this.generationId = generationId;
174 this.level = level;
175 }
176
177//------------------------------------------------------------------------------
178
193 public Candidate(IAtomContainer iac, boolean useFragSpace)
194 throws DENOPTIMException
195 {
196 this(iac, useFragSpace, false);
197 }
198
199//------------------------------------------------------------------------------
200
217 public Candidate(IAtomContainer iac, boolean useFragSpace,
218 boolean allowNoUID) throws DENOPTIMException
219 {
220 this.uid = "UNDEFINED";
221 this.smiles = "UNDEFINED";
222 this.hasFitness = false;
223
224 this.iac = MoleculeUtils.makeSameAs(iac);
225
226 if (iac.getProperty(CDKConstants.TITLE) != null)
227 {
228 this.name = iac.getProperty(CDKConstants.TITLE).toString();
229 }
230
231 if (iac.getProperty(DENOPTIMConstants.MOLERRORTAG) != null)
232 {
233 this.error = iac.getProperty(
234 DENOPTIMConstants.MOLERRORTAG).toString();
235 }
236
237 if (iac.getProperty(DENOPTIMConstants.FITNESSTAG) != null)
238 {
239 String fitprp = iac.getProperty(
240 DENOPTIMConstants.FITNESSTAG).toString();
241 double fitVal = Double.parseDouble(fitprp);
242 if (Double.isNaN(fitVal))
243 {
244 String msg = "Cannot build Candidate from "
245 + "IAtomContainer: Fitness value is NaN!";
246 throw new DENOPTIMException(msg);
247 }
248 this.fitness = fitVal;
249 this.hasFitness = true;
250 }
251
252 if (iac.getProperty(DENOPTIMConstants.GRAPHLEVELTAG) != null)
253 {
254 this.level = Integer.parseInt(iac.getProperty(
255 DENOPTIMConstants.GRAPHLEVELTAG).toString());
256 }
257
258 if (iac.getProperty(DENOPTIMConstants.SMILESTAG) != null)
259 {
260 this.smiles = iac.getProperty(
261 DENOPTIMConstants.SMILESTAG).toString();
262 }
263
264 try
265 {
266 this.uid = iac.getProperty(
267 DENOPTIMConstants.UNIQUEIDTAG).toString();
268 } catch (Exception e) {
269 if (allowNoUID)
270 {
271 this.uid = "noUID";
272 } else {
273 throw new DENOPTIMException("Could not read UID to make "
274 + "Candidate.", e);
275 }
276 }
277
278 if (iac.getProperty(DENOPTIMConstants.PROVENANCE) != null)
279 {
280 this.comment = iac.getProperty(
281 DENOPTIMConstants.PROVENANCE).toString();
282 }
283
285 this.graph.setCandidateOwner(this);
286 }
287
288//------------------------------------------------------------------------------
289
301 public static Candidate fromAtomContainerNoGraph(IAtomContainer iac,
302 boolean allowNoUID) throws DENOPTIMException
303 {
304 Candidate cand = new Candidate();
305
306 cand.iac = MoleculeUtils.makeSameAs(iac);
307
308 if (iac.getProperty(CDKConstants.TITLE) != null)
309 {
310 cand.name = iac.getProperty(CDKConstants.TITLE).toString();
311 }
312
313 if (iac.getProperty(DENOPTIMConstants.MOLERRORTAG) != null)
314 {
315 cand.error = iac.getProperty(
316 DENOPTIMConstants.MOLERRORTAG).toString();
317 }
318
319 if (iac.getProperty(DENOPTIMConstants.FITNESSTAG) != null)
320 {
321 String fitprp = iac.getProperty(
322 DENOPTIMConstants.FITNESSTAG).toString();
323 double fitVal = Double.parseDouble(fitprp);
324 if (Double.isNaN(fitVal))
325 {
326 String msg = "Cannot build Candidate from "
327 + "IAtomContainer: Fitness value is NaN!";
328 throw new DENOPTIMException(msg);
329 }
330 cand.fitness = fitVal;
331 cand.hasFitness = true;
332 }
333
334 if (iac.getProperty(DENOPTIMConstants.GRAPHLEVELTAG) != null)
335 {
336 cand.level = Integer.parseInt(iac.getProperty(
337 DENOPTIMConstants.GRAPHLEVELTAG).toString());
338 }
339
340 if (iac.getProperty(DENOPTIMConstants.SMILESTAG) != null)
341 {
342 cand.smiles = iac.getProperty(
343 DENOPTIMConstants.SMILESTAG).toString();
344 }
345
346 try {
347 cand.uid = iac.getProperty(DENOPTIMConstants.UNIQUEIDTAG).toString();
348 } catch (Exception e) {
349 if (allowNoUID)
350 {
351 cand.uid = "noUID";
352 } else {
353 throw new DENOPTIMException("Could not read UID to make "
354 + "Candidate. No property '"
356 + "' in the atom container.", e);
357 }
358 }
359
360 if (iac.getProperty(DENOPTIMConstants.PROVENANCE) != null)
361 {
362 cand.comment = iac.getProperty(
363 DENOPTIMConstants.PROVENANCE).toString();
364 }
365
366 return cand;
367 }
368
369//------------------------------------------------------------------------------
370
378 public void setChemicalRepresentation(IAtomContainer iac)
379 {
380 this.iac = iac;
381 }
382
383//------------------------------------------------------------------------------
384
389 public IAtomContainer getChemicalRepresentation()
390 {
391 return iac;
392 }
393
394//------------------------------------------------------------------------------
395
403 {
404 IAtomContainer iacForFitFile = iac;
405 if (iacForFitFile==null)
406 {
407 IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
408 iacForFitFile = builder.newAtomContainer();
409 }
410 iacForFitFile.setProperty(CDKConstants.TITLE, name);
411 iacForFitFile.setProperty(DENOPTIMConstants.GCODETAG, graph.getGraphId());
412 iacForFitFile.setProperty(DENOPTIMConstants.GRAPHTAG, graph.toString());
413 iacForFitFile.setProperty(DENOPTIMConstants.GRAPHJSONTAG, graph.toJson());
414 if (graph.getLocalMsg() != null && !graph.getLocalMsg().equals(""))
415 {
416 iacForFitFile.setProperty(DENOPTIMConstants.PROVENANCE, graph.getLocalMsg());
417 }
418 iacForFitFile.setProperty(DENOPTIMConstants.SMILESTAG, smiles);
419 iacForFitFile.setProperty(DENOPTIMConstants.UNIQUEIDTAG, uid);
420 if (hasFitness)
421 {
422 iacForFitFile.setProperty(DENOPTIMConstants.FITNESSTAG, fitness);
423 } else {
424 iacForFitFile.setProperty(DENOPTIMConstants.MOLERRORTAG, error);
425 }
426 return iacForFitFile;
427 }
428
429//------------------------------------------------------------------------------
430
431 public void setComments(String str)
432 {
433 this.comment = str;
434 }
435
436//------------------------------------------------------------------------------
437
438 public String getComments()
439 {
440 return comment;
441 }
442
443//------------------------------------------------------------------------------
444
445 public void setSDFFile(String molFile)
446 {
447 this.sdfFile = molFile;
448 }
449
450//------------------------------------------------------------------------------
451
452 public void setImageFile(String imgFile)
453 {
454 this.imgFile = imgFile;
455 }
456
457//------------------------------------------------------------------------------
458
459 public void setGraph(DGraph graph)
460 {
461 this.graph = graph;
462 }
463
464//------------------------------------------------------------------------------
465
466 public void setUID(String uid)
467 {
468 this.uid = uid;
469 }
470
471//------------------------------------------------------------------------------
472
473 public void setSmiles(String smiles)
474 {
475 this.smiles = smiles;
476 }
477
478//------------------------------------------------------------------------------
479
480 public void setFitness(double fitness)
481 {
482 this.fitness = fitness;
483 this.hasFitness = true;
484 }
485
486//------------------------------------------------------------------------------
487
488 public void setError(String error)
489 {
490 this.error = error;
491 }
492
493//------------------------------------------------------------------------------
494
495 public void setName(String name)
496 {
497 this.name = name;
498 }
499
500//------------------------------------------------------------------------------
501
502 public String getName()
503 {
504 return name;
505 }
506
507//------------------------------------------------------------------------------
508
509 public String getError()
510 {
511 return error;
512 }
513
514//------------------------------------------------------------------------------
515
516 public String getUID()
517 {
518 return uid;
519 }
520
521//------------------------------------------------------------------------------
522
523 public String getSmiles()
524 {
525 return smiles;
526 }
527
528//------------------------------------------------------------------------------
529
530 public String getSDFFile()
531 {
532 return sdfFile;
533 }
534
535//------------------------------------------------------------------------------
536
537 public String getImageFile()
538 {
539 return imgFile;
540 }
541
542//------------------------------------------------------------------------------
543
545 {
546 return graph;
547 }
548
549//------------------------------------------------------------------------------
550
551 public double getFitness()
552 {
553 return fitness;
554 }
555
556//------------------------------------------------------------------------------
557
558 public boolean hasFitness()
559 {
560 return hasFitness;
561 }
562
563//------------------------------------------------------------------------------
564
565 public void setGeneration(int genId)
566 {
567 generationId = genId;
568 }
569
570//------------------------------------------------------------------------------
571
578 public int getGeneration()
579 {
580 return generationId;
581 }
582
583//------------------------------------------------------------------------------
584
590 public void setLevel(int lev)
591 {
592 level = lev;
593 }
594
595//------------------------------------------------------------------------------
596
603 public int getLevel()
604 {
605 return level;
606 }
607
608//------------------------------------------------------------------------------
609
616 //TODO: this comparator is meant for specific uses like sorting the
617 // population according to fitness, and it should thus be a
618 // specific comparator, not here determining the natural ordering.
619
620 @Override
621 public int compareTo(Candidate other)
622 {
623 if (!hasFitness && !other.hasFitness)
624 {
625 return 0;
626 } else if (!hasFitness && other.hasFitness) {
627 return -1;
628 } else if (hasFitness && !other.hasFitness) {
629 return 1;
630 }
631
632 if (this.fitness > other.fitness)
633 return 1;
634 else if (this.fitness < other.fitness)
635 return -1;
636
637 if (this.graph.graphId < other.graph.graphId)
638 return 1;
639 else if (this.graph.graphId > other.graph.graphId)
640 return -1;
641 return 0;
642 }
643
644//------------------------------------------------------------------------------
645
646 /* TODO: change this method! Now it writes a string that is formatted
647 * only for logging needs not really a good toString string.
648 */
649 @Override
650 public String toString()
651 {
652 StringBuilder sb = new StringBuilder(16);
653 if (sdfFile != null && name == null)
654 name = new File(sdfFile).getName();
655 if (name != null)
656 sb.append(String.format("%-20s", name));
657
658 sb.append(String.format("%-20s", this.graph.getGraphId()));
659 sb.append(String.format("%-30s", uid));
660 sb.append(String.format("%12.3f", fitness));
661
662 return sb.toString();
663 }
664
665//------------------------------------------------------------------------------
666
670 public void cleanup()
671 {
672 if (graph != null)
673 graph.cleanup();
674 }
675
676//------------------------------------------------------------------------------
677
679 {
682
683 if (hasFitness)
684 {
686 }
687
688 if (error!=null)
689 {
690 c.setError(error);
691 }
692
693 if (this.iac != null)
694 {
695 try
696 {
698 this.iac));
699 } catch (DENOPTIMException e)
700 {
701 e.printStackTrace();
703 }
704 }
705 return c;
706 }
707
708//------------------------------------------------------------------------------
709
710}
General set of constants used in DENOPTIM.
static final String GRAPHTAG
SDF tag containing graph encoding.
static final String PROVENANCE
SDF tag containing provenance data for a graph.
static final String GRAPHLEVELTAG
SDF tag defining the graph generating level in an FSE run.
static final String GCODETAG
SDF tag containing graph ID.
static final String UNIQUEIDTAG
SDF tag containing the unique identifier of a candidate.
static final String GRAPHJSONTAG
SDF tag containing graph encoding in JSON format.
static final String MOLERRORTAG
SDF tag containing errors during execution of molecule specific tasks.
static final String SMILESTAG
SDF tag containing the SMILES of a candidate.
static final String FITNESSTAG
SDF tag containing the fitness of a candidate.
A candidate is the combination of a denoptim graph with molecular representation and may include also...
Definition: Candidate.java:40
String sdfFile
Pathname to SDF file.
Definition: Candidate.java:69
void setLevel(int lev)
Sets level that generated this graph in a fragment space exploration experiment.
Definition: Candidate.java:590
Candidate(String name, DGraph graph, double fitness, String uid, String smiles)
Definition: Candidate.java:145
int getLevel()
Returns the level that generated this graph in a fragment space exploration experiment.
Definition: Candidate.java:603
boolean hasFitness
Flag signaling the presence of a fitness value associated.
Definition: Candidate.java:89
void setSDFFile(String molFile)
Definition: Candidate.java:445
int compareTo(Candidate other)
Definition: Candidate.java:621
void cleanup()
Clear the graph describing this candidate.
Definition: Candidate.java:670
void setGeneration(int genId)
Definition: Candidate.java:565
String uid
Unique identifier of this candidate.
Definition: Candidate.java:44
Candidate(IAtomContainer iac, boolean useFragSpace)
Builds a candidate from the SDF representation of an atom container.
Definition: Candidate.java:193
int level
Level that generated this graph in fragment space exploration.
Definition: Candidate.java:105
Candidate(IAtomContainer iac, boolean useFragSpace, boolean allowNoUID)
Builds a candidate from the SDF representation of an atom container.
Definition: Candidate.java:217
void setSmiles(String smiles)
Definition: Candidate.java:473
String smiles
SMILES representation.
Definition: Candidate.java:59
void setImageFile(String imgFile)
Definition: Candidate.java:452
String error
Error that prevented calculation of the fitness.
Definition: Candidate.java:84
IAtomContainer iac
Chemical object representation.
Definition: Candidate.java:54
String imgFile
Pathname to an image (i.e., PNG file)
Definition: Candidate.java:74
DGraph graph
Graph representation.
Definition: Candidate.java:49
Candidate(String name, DGraph graph)
Definition: Candidate.java:132
void setFitness(double fitness)
Definition: Candidate.java:480
void setGraph(DGraph graph)
Definition: Candidate.java:459
void setUID(String uid)
Definition: Candidate.java:466
void setComments(String str)
Definition: Candidate.java:431
int generationId
ID of the generation at which this candidate was generated.
Definition: Candidate.java:95
static Candidate fromAtomContainerNoGraph(IAtomContainer iac, boolean allowNoUID)
Wraps an atom container as a candidate even if a graph is not available.
Definition: Candidate.java:301
Candidate(DGraph graph)
Definition: Candidate.java:120
int getGeneration()
The generation this candidate belong to is that in which it was generated.
Definition: Candidate.java:578
String comment
Any comments.
Definition: Candidate.java:79
void setError(String error)
Definition: Candidate.java:488
void setName(String name)
Definition: Candidate.java:495
IAtomContainer getFitnessProviderOutputRepresentation()
Returns an atom container representing this item in a way that is compatible for writing this item to...
Definition: Candidate.java:402
void setChemicalRepresentation(IAtomContainer iac)
Just place the argument in the IAtomContainer field of this object.
Definition: Candidate.java:378
String name
Name of this candidate (not guaranteed to be unique)
Definition: Candidate.java:100
IAtomContainer getChemicalRepresentation()
Returns the atom container representing this candidate.
Definition: Candidate.java:389
Candidate(String name, DGraph graph, String uid, String smiles, String molFile, String imgFile, String comment, int generationId, int level)
Definition: Candidate.java:160
double fitness
fitness value
Definition: Candidate.java:64
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
String toJson()
Produces a string that represents this graph and that adheres to the JSON format.
Definition: DGraph.java:6660
String getLocalMsg()
Definition: DGraph.java:279
void setCandidateOwner(Candidate candidate)
Sets the reference to the candidate item that is defined by this graph.
Definition: DGraph.java:239
DGraph clone()
Returns almost "deep-copy" of this graph.
Definition: DGraph.java:3186
void cleanup()
Wipes the data in this graph.
Definition: DGraph.java:3368
Utility methods for input/output.
static DGraph readGraphFromSDFileIAC(IAtomContainer mol)
Converts an atom container read in from an SDF file into a graph, if possible.
Utilities for molecule conversion.
static IAtomContainer makeSameAs(IAtomContainer mol)
Constructs a copy of an atom container, i.e., a molecule that reflects the one given in the input arg...