$darkmode
DENOPTIM
EAUtils.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Vishwesh Venkatraman <vishwesh.venkatraman@ntnu.no> and
4 * Marco Foscato <marco.foscato@uib.no>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20package denoptim.ga;
21
22import java.io.File;
23import java.io.IOException;
24import java.nio.file.Path;
25import java.text.DecimalFormat;
26import java.text.NumberFormat;
27import java.util.ArrayList;
28import java.util.Arrays;
29import java.util.Comparator;
30import java.util.HashMap;
31import java.util.HashSet;
32import java.util.Iterator;
33import java.util.List;
34import java.util.Locale;
35import java.util.Set;
36import java.util.concurrent.atomic.AtomicInteger;
37import java.util.logging.Level;
38import java.util.logging.Logger;
39
40import org.apache.commons.io.FileUtils;
41import org.apache.commons.io.FilenameUtils;
42import org.openscience.cdk.interfaces.IAtom;
43import org.openscience.cdk.interfaces.IAtomContainer;
44
45import denoptim.constants.DENOPTIMConstants;
46import denoptim.exception.DENOPTIMException;
47import denoptim.fitness.FitnessParameters;
48import denoptim.fragmenter.FragmenterTools;
49import denoptim.fragmenter.ScaffoldingPolicy;
50import denoptim.fragspace.FragmentSpace;
51import denoptim.fragspace.FragmentSpaceParameters;
52import denoptim.graph.APClass;
53import denoptim.graph.AttachmentPoint;
54import denoptim.graph.Candidate;
55import denoptim.graph.DGraph;
56import denoptim.graph.Edge.BondType;
57import denoptim.graph.EmptyVertex;
58import denoptim.graph.Fragment;
59import denoptim.graph.GraphPattern;
60import denoptim.graph.Ring;
61import denoptim.graph.SymmetricAPs;
62import denoptim.graph.Template;
63import denoptim.graph.Template.ContractLevel;
64import denoptim.graph.Vertex;
65import denoptim.graph.Vertex.BBType;
66import denoptim.graph.rings.CyclicGraphHandler;
67import denoptim.graph.rings.RingClosureParameters;
68import denoptim.graph.rings.RingClosuresArchive;
69import denoptim.io.DenoptimIO;
70import denoptim.logging.CounterID;
71import denoptim.logging.Monitor;
72import denoptim.molecularmodeling.ThreeDimTreeBuilder;
73import denoptim.programs.RunTimeParameters.ParametersType;
74import denoptim.programs.denovo.GAParameters;
75import denoptim.programs.fragmenter.CuttingRule;
76import denoptim.programs.fragmenter.FragmenterParameters;
77import denoptim.utils.DummyAtomHandler;
78import denoptim.utils.GeneralUtils;
79import denoptim.utils.GraphUtils;
80import denoptim.utils.MoleculeUtils;
81import denoptim.utils.Randomizer;
82import denoptim.utils.RotationalSpaceUtils;
83import denoptim.utils.SizeControlledSet;
84import denoptim.utils.StatUtils;
85
86
92public class EAUtils
93{
94 // cluster the fragments based on their #APs
95 protected static HashMap<Integer, ArrayList<Integer>> fragmentPool;
96
100 private static Locale enUsLocale = new Locale("en", "US");
101
105 private static DecimalFormat df = initialiseFormatter();
106 private static DecimalFormat initialiseFormatter() {
107 DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(
108 enUsLocale);
109 df.setGroupingUsed(false);
110 return df;
111 }
112
113 // for each fragment store the reactions associated with it
114 protected static HashMap<Integer, ArrayList<String>> lstFragmentClass;
115
119 public enum CandidateSource {
120 CROSSOVER, MUTATION, CONSTRUCTION, MANUAL;
121 }
122
123 private static final String NL =System.getProperty("line.separator");
124 private static final String FSEP = System.getProperty("file.separator");
125
126//------------------------------------------------------------------------------
127
134 protected static void createFolderForGeneration(int genId,
135 GAParameters settings)
136 {
137 denoptim.files.FileUtils.createDirectory(
138 EAUtils.getPathNameToGenerationFolder(genId, settings));
139 }
140
141//------------------------------------------------------------------------------
142
149 SizeControlledSet uniqueIDsSet, GAParameters settings)
150 throws DENOPTIMException, IOException
151 {
152 Population population = new Population(settings);
153
154 // Read existing or previously visited UIDs
155 HashSet<String> lstUID = new HashSet<>(1024);
156 if (!settings.getUIDFileIn().equals(""))
157 {
158 EAUtils.readUID(settings.getUIDFileIn(),lstUID);
159 for (String uid : lstUID)
160 {
161 uniqueIDsSet.addNewUniqueEntry(uid);
162 }
163 settings.getLogger().log(Level.INFO, "Read " + lstUID.size()
164 + " known UIDs from " + settings.getUIDFileIn());
165 }
166
167 // Read existing graphs
168 int numFromInitGraphs = 0;
169 String initPopFile = settings.getInitialPopulationFile();
170 if (initPopFile.length() > 0)
171 {
172 EAUtils.getPopulationFromFile(initPopFile, population, uniqueIDsSet,
174 settings);
175 numFromInitGraphs = population.size();
176 settings.getLogger().log(Level.INFO, "Imported " + numFromInitGraphs
177 + " candidates (as graphs) from " + initPopFile);
178 }
179
180 return population;
181 }
182
183//------------------------------------------------------------------------------
184
194 {
196 settings.getCrossoverWeight(),
197 settings.getMutationWeight(),
198 settings.getConstructionWeight(),
199 settings.getRandomizer());
200 }
201
202//------------------------------------------------------------------------------
203
210 public static int chooseNumberOfSitesToMutate(double[] multiSiteMutationProb,
211 double hit)
212 {
213 double tot = 0;
214 for (int i=0; i<multiSiteMutationProb.length; i++)
215 tot = tot + multiSiteMutationProb[i];
216
217 double scaledHit = hit * tot;
218
219 double min = 0;
220 double max = 0;
221 int choice = 0;
222 for (int i=0; i<multiSiteMutationProb.length; i++)
223 {
224 max = max + multiSiteMutationProb[i];
225 if (min < scaledHit && scaledHit <= max)
226 {
227 choice = i;
228 break;
229 }
230 min = Math.max(min,min+multiSiteMutationProb[i]);
231 }
232 return choice;
233 }
234
235//------------------------------------------------------------------------------
236
250 double xoverWeight, double mutWeight, double newWeight,
251 Randomizer randomizer)
252 {
253 double hit = randomizer.nextDouble()
254 * (xoverWeight + mutWeight + newWeight);
255 if (hit <= xoverWeight)
256 {
258 } else if (xoverWeight < hit && hit <= (mutWeight+xoverWeight))
259 {
261 } else {
263 }
264 }
265
266//------------------------------------------------------------------------------
267
279 protected static List<Candidate> buildCandidatesByXOver(
280 List<Candidate> eligibleParents, Population population,
281 Monitor mnt, GAParameters settings) throws DENOPTIMException
282 {
283 return buildCandidatesByXOver(eligibleParents, population, mnt,
284 null, -1, -1, settings, settings.maxOffsprintFromXover());
285 }
286
287//------------------------------------------------------------------------------
288
300 List<Candidate> eligibleParents, Population population,
301 Monitor mnt, GAParameters settings) throws DENOPTIMException
302 {
303 return buildCandidateByXOver(eligibleParents, population, mnt,
304 null, -1, -1, settings);
305 }
306
307//------------------------------------------------------------------------------
308
334 List<Candidate> eligibleParents, Population population,
335 Monitor mnt, int[] choiceOfParents, int choiceOfXOverSites,
336 int choiceOfOffstring, GAParameters settings)
337 throws DENOPTIMException
338 {
339 List<Candidate> cands = buildCandidatesByXOver(eligibleParents,
340 population, mnt,
341 choiceOfParents, choiceOfXOverSites, choiceOfOffstring,
342 settings, 1);
343 if (cands.size()>0)
344 return cands.get(0);
345 else
346 return null;
347 }
348
349//------------------------------------------------------------------------------
350
378 protected static List<Candidate> buildCandidatesByXOver(
379 List<Candidate> eligibleParents, Population population,
380 Monitor mnt, int[] choiceOfParents, int choiceOfXOverSites,
381 int choiceOfOffstring, GAParameters settings,
382 int maxCandidatesToReturn) throws DENOPTIMException
383 {
385 if (settings.containsParameters(ParametersType.FS_PARAMS))
386 {
387 fsParams = (FragmentSpaceParameters)settings.getParameters(
389 }
390 FragmentSpace fragSpace = fsParams.getFragmentSpace();
391
392 mnt.increase(CounterID.XOVERATTEMPTS);
393 mnt.increase(CounterID.NEWCANDIDATEATTEMPTS);
394
395 int numatt = 1;
396
397 // Identify a pair of parents that can do crossover, and a pair of
398 // vertexes from which we can define a subgraph (or a branch) to swap
399 XoverSite xos = null;
400 boolean foundPars = false;
401 while (numatt < settings.getMaxGeneticOpAttempts())
402 {
403 if (fragSpace.useAPclassBasedApproach())
404 {
405 xos = EAUtils.performFBCC(eligibleParents,
406 population, choiceOfParents, choiceOfXOverSites,
407 settings);
408 if (xos == null)
409 {
410 numatt++;
411 continue;
412 }
413 } else {
414 //TODO: make it reproducible using choiceOfParents and choiceOfXOverSites
416 eligibleParents, 2, settings);
417 if (parents[0] == null || parents[1] == null)
418 {
419 numatt++;
420 continue;
421 }
422 //NB: this does not go into templates!
423 DGraph gpA = parents[0].getGraph();
424 List<Vertex> subGraphA = new ArrayList<Vertex>();
426 gpA, settings.getRandomizer()),subGraphA);
427
428 DGraph gpB = parents[1].getGraph();
429 List<Vertex> subGraphB = new ArrayList<Vertex>();
431 gpB, settings.getRandomizer()),subGraphB);
432 }
433 foundPars = true;
434 break;
435 }
436 mnt.increaseBy(CounterID.XOVERPARENTSEARCH, numatt);
437
438 if (!foundPars)
439 {
441 mnt.increase(CounterID.FAILEDXOVERATTEMPTS);
442 return new ArrayList<Candidate>();
443 }
444
445 Candidate cA = null, cB = null;
446 Vertex vA = null, vB = null;
447 vA = xos.getA().get(0);
448 vB = xos.getB().get(0);
449 DGraph gA = vA.getGraphOwner();
451 DGraph gB = vB.getGraphOwner();
453
454 String candIdA = cA.getName();
455 String candIdB = cB.getName();
456 int gid1 = gA.getGraphId();
457 int gid2 = gB.getGraphId();
458
459 // Start building the offspring
460 XoverSite xosOnClones = xos.projectToClonedGraphs();
461 DGraph gAClone = xosOnClones.getA().get(0).getGraphOwner();
462 DGraph gBClone = xosOnClones.getB().get(0).getGraphOwner();
463
464 try
465 {
466 if (!GraphOperations.performCrossover(xosOnClones,fragSpace))
467 {
469 mnt.increase(CounterID.FAILEDXOVERATTEMPTS);
470 return new ArrayList<Candidate>();
471 }
472 } catch (Throwable t) {
473 if (!settings.xoverFailureTolerant)
474 {
475 t.printStackTrace();
476 ArrayList<DGraph> parents = new ArrayList<DGraph>();
477 parents.add(gA);
478 parents.add(gB);
479 DenoptimIO.writeGraphsToSDF(new File(settings.getDataDirectory()
480 + "_failed_xover.sdf"), parents, true,
481 settings.getLogger(), settings.getRandomizer());
482 throw new DENOPTIMException("Error while performing crossover! "+NL
483 + "XOverSite: " + xos.toString() + NL
484 + "XOverSite(C): " + xosOnClones.toString() + NL
485 + " Please, report this to the authors ",t);
486 }
488 mnt.increase(CounterID.FAILEDXOVERATTEMPTS);
489 return new ArrayList<Candidate>();
490 }
493 String lstIdVA = "";
494 for (Vertex v : xos.getA())
495 lstIdVA = lstIdVA + "_" + v.getVertexId();
496 String lstIdVB = "";
497 for (Vertex v : xos.getB())
498 lstIdVB = lstIdVB + "_" + v.getVertexId();
499 String[] msgs = new String[2];
500 msgs[0] = "Xover: "
501 + "Gen:" + cA.getGeneration() + " Cand:" + candIdA
502 + "|" + gid1 + "|" + lstIdVA
503 + " X "
504 + "Gen:" + cB.getGeneration() + " Cand:" + candIdB
505 + "|" + gid2 + "|" + lstIdVB;
506 msgs[1] = "Xover: "
507 + "Gen:" + cB.getGeneration() + " Cand:" + candIdB
508 + "|" + gid2 + "|" + lstIdVB
509 + " X "
510 + "Gen:" + cA.getGeneration() + " Cand:" + candIdA
511 + "|" + gid1 + "|" + lstIdVA;
512
513 DGraph[] graphsAffectedByXover = new DGraph[2];
514 graphsAffectedByXover[0] = gAClone;
515 graphsAffectedByXover[1] = gBClone;
516
517 List<Candidate> validOffspring = new Population(settings);
518 for (int ig=0; ig<graphsAffectedByXover.length; ig++)
519 {
520 DGraph g = graphsAffectedByXover[ig];
521
522 // It makes sense to do this on the possibly embedded graph and not
523 // on their embedding owners because there cannot be any new cycle
524 // affecting the latter, but there can be ones affecting the first.
525 if (!EAUtils.setupRings(null, g, settings))
526 {
528 continue;
529 }
530
531 // Finalize the graph that is at the outermost level
532 DGraph gOutermost = g.getOutermostGraphOwner();
533 gOutermost.addCappingGroups(fragSpace);
534 gOutermost.renumberGraphVertices();
535 gOutermost.setLocalMsg(msgs[ig]);
536
537 // Consider if the result can be used to define a new candidate
538 Object[] res = null;
539 try
540 {
541 res = gOutermost.checkConsistency(settings);
542 } catch (NullPointerException|IllegalArgumentException e)
543 {
544 if (!settings.xoverGraphFailedEvalTolerant)
545 {
546 ArrayList<DGraph> parents = new ArrayList<DGraph>();
547 parents.add(gA);
548 parents.add(gB);
549 parents.add(gAClone);
550 parents.add(gBClone);
551 DenoptimIO.writeGraphsToSDF(new File(settings.getDataDirectory()
552 + "_failed_xover-ed_check.sdf"), parents, true,
553 settings.getLogger(), settings.getRandomizer());
554 throw e;
555 } else {
556 res = null;
557 }
558 }
559 if (res != null)
560 {
561 if (!EAUtils.setupRings(res, gOutermost, settings))
562 {
564 res = null;
565 }
566 } else {
568 }
569
570 // Check if the chosen combination gives rise to forbidden ends
571 for (Vertex rcv : gOutermost.getFreeRCVertices())
572 {
573 APClass apc = rcv.getEdgeToParent().getSrcAP().getAPClass();
574 if (fragSpace.getCappingMap().get(apc)==null
575 && fragSpace.getForbiddenEndList().contains(apc))
576 {
578 res = null;
579 }
580 }
581 if (res == null)
582 {
583 gOutermost.cleanup();
584 gOutermost = null;
585 continue;
586 }
587
588 // OK: we can now use it to make a new candidate
589 Candidate offspring = new Candidate(gOutermost);
590 offspring.setUID(res[0].toString().trim());
591 offspring.setSmiles(res[1].toString().trim());
592 offspring.setChemicalRepresentation((IAtomContainer) res[2]);
593
594 validOffspring.add(offspring);
595 }
596
597 if (validOffspring.size() == 0)
598 {
599 mnt.increase(CounterID.FAILEDXOVERATTEMPTS);
600 return new ArrayList<Candidate>();
601 }
602
603 if (maxCandidatesToReturn==1)
604 {
605 Candidate chosenOffspring = null;
606 if (choiceOfOffstring<0)
607 {
608 chosenOffspring = settings.getRandomizer().randomlyChooseOne(
609 validOffspring);
610 chosenOffspring.setName("M" + GeneralUtils.getPaddedString(
613 } else {
614 chosenOffspring = validOffspring.get(choiceOfOffstring);
615 }
616 validOffspring.retainAll(Arrays.asList(chosenOffspring));
617 } else {
618 for (Candidate cand : validOffspring)
619 {
623 }
624 }
625 return validOffspring;
626 }
627
628//------------------------------------------------------------------------------
629
631 List<Candidate> eligibleParents, Monitor mnt,
632 GAParameters settings) throws DENOPTIMException
633 {
635 if (settings.containsParameters(ParametersType.FS_PARAMS))
636 {
637 fsParams = (FragmentSpaceParameters)settings.getParameters(
639 }
640 FragmentSpace fragSpace = fsParams.getFragmentSpace();
641
642 mnt.increase(CounterID.MUTATTEMPTS);
643 mnt.increase(CounterID.NEWCANDIDATEATTEMPTS);
644
645 int numatt = 0;
646 Candidate parent = null;
647 while (numatt < settings.getMaxGeneticOpAttempts())
648 {
649 parent = EAUtils.selectBasedOnFitness(eligibleParents,1, settings)[0];
650 if (parent == null)
651 {
652 numatt++;
653 continue;
654 }
655 break;
656 }
657 mnt.increaseBy(CounterID.MUTPARENTSEARCH,numatt);
658 if (parent == null)
659 {
660 mnt.increase(CounterID.FAILEDMUTATTEMTS);
661 return null;
662 }
663
664 DGraph graph = parent.getGraph().clone();
665 graph.renumberGraphVertices();
666
667 String parentMolName = FilenameUtils.getBaseName(parent.getSDFFile());
668 int parentGraphId = parent.getGraph().getGraphId();
669 graph.setLocalMsg("Mutation:"
670 + " Gen:" + parent.getGeneration() + " Cand:" + parentMolName
671 + "|" + parentGraphId);
672
673 if (!GraphOperations.performMutation(graph,mnt,settings))
674 {
676 mnt.increase(CounterID.FAILEDMUTATTEMTS);
677 return null;
678 }
679
681
682 graph.addCappingGroups(fragSpace);
683
684 Object[] res = null;
685 try
686 {
687 res = graph.checkConsistency(settings);
688 } catch (NullPointerException|IllegalArgumentException e)
689 {
690 if (!settings.mutatedGraphFailedEvalTolerant)
691 {
692 settings.getLogger().log(Level.INFO, "WRITING DEBUG FILE for "
693 + graph.getLocalMsg());
694 DenoptimIO.writeGraphToSDF(new File("debug_evalGrp_parent.sdf"),
695 parent.getGraph(),false, settings.getLogger(),
696 settings.getRandomizer());
697 DenoptimIO.writeGraphToSDF(new File("debug_evalGrp_curr.sdf"),
698 graph,false, settings.getLogger(),
699 settings.getRandomizer());
700 throw e;
701 } else {
702 res = null;
703 mnt.increase(CounterID.FAILEDMUTATTEMTS_EVAL);
704 }
705 }
706
707 if (res != null)
708 {
709 if (!EAUtils.setupRings(res,graph,settings))
710 {
711 res = null;
713 }
714 } else {
715 mnt.increase(CounterID.FAILEDMUTATTEMTS_EVAL);
716 }
717
718 // Check if the chosen combination gives rise to forbidden ends
719 //TODO this should be considered already when making the list of
720 // possible combination of rings
721 for (Vertex rcv : graph.getFreeRCVertices())
722 {
723 APClass apc = rcv.getEdgeToParent().getSrcAP().getAPClass();
724 if (fragSpace.getCappingMap().get(apc)==null
725 && fragSpace.getForbiddenEndList().contains(apc))
726 {
727 res = null;
729 }
730 }
731
732 if (res == null)
733 {
734 graph.cleanup();
735 graph = null;
736 mnt.increase(CounterID.FAILEDMUTATTEMTS);
737 return null;
738 }
739
740 Candidate offspring = new Candidate(graph);
741 offspring.setUID(res[0].toString().trim());
742 offspring.setSmiles(res[1].toString().trim());
743 offspring.setChemicalRepresentation((IAtomContainer) res[2]);
744 offspring.setName("M" + GeneralUtils.getPaddedString(
747
748 return offspring;
749 }
750
751//------------------------------------------------------------------------------
752
753 //TODO: move to IO class
754 protected static Candidate readCandidateFromFile(File srcFile, Monitor mnt,
755 GAParameters settings) throws DENOPTIMException
756 {
757 mnt.increase(CounterID.MANUALADDATTEMPTS);
758 mnt.increase(CounterID.NEWCANDIDATEATTEMPTS);
759
760 ArrayList<DGraph> graphs;
761 try
762 {
763 graphs = DenoptimIO.readDENOPTIMGraphsFromFile(srcFile);
764 } catch (Exception e)
765 {
766 e.printStackTrace();
768 String msg = "Could not read graphs from file " + srcFile
769 + ". No candidate generated!";
770 settings.getLogger().log(Level.SEVERE, msg);
771 return null;
772 }
773 if (graphs.size() == 0 || graphs.size() > 1)
774 {
776 String msg = "Found " + graphs.size() + " graphs in file " + srcFile
777 + ". I expect one and only one graph. "
778 + "No candidate generated!";
779 settings.getLogger().log(Level.SEVERE, msg);
780 return null;
781 }
782
783 DGraph graph = graphs.get(0);
784 if (graph == null)
785 {
787 String msg = "Null graph from file " + srcFile
788 + ". Expected one and only one graph. "
789 + "No candidate generated!";
790 settings.getLogger().log(Level.SEVERE, msg);
791 return null;
792 }
793 graph.setLocalMsg("MANUAL_ADD");
794
795 // We expect users to know what they ask for. Therefore, we do
796 // evaluate the graph, but in a permissive manner, meaning that
797 // several filters are disabled to permit the introduction of graphs
798 // that cannot be generated automatically.
799 Object[] res = graph.checkConsistency(settings, true);
800
801 if (res == null)
802 {
803 graph.cleanup();
806 return null;
807 }
808
809 Candidate candidate = new Candidate(graph);
810 candidate.setUID(res[0].toString().trim());
811 candidate.setSmiles(res[1].toString().trim());
812 candidate.setChemicalRepresentation((IAtomContainer) res[2]);
813
814 candidate.setName("M" + GeneralUtils.getPaddedString(
817
818 String msg = "Candidate " + candidate.getName() + " is imported from "
819 + srcFile;
820 settings.getLogger().log(Level.INFO, msg);
821
822 return candidate;
823 }
824
825//------------------------------------------------------------------------------
826
828 GAParameters settings)
829 throws DENOPTIMException
830 {
832 if (settings.containsParameters(ParametersType.FS_PARAMS))
833 {
834 fsParams = (FragmentSpaceParameters)settings.getParameters(
836 }
837 FragmentSpace fragSpace = fsParams.getFragmentSpace();
838
839 mnt.increase(CounterID.BUILDANEWATTEMPTS);
840 mnt.increase(CounterID.NEWCANDIDATEATTEMPTS);
841
842 DGraph graph = EAUtils.buildGraph(settings);
843 if (graph == null)
844 {
846 mnt.increase(CounterID.FAILEDBUILDATTEMPTS);
847 return null;
848 }
849 graph.setLocalMsg("NEW");
850
851 Object[] res = graph.checkConsistency(settings);
852
853 if (res != null)
854 {
855 if (!EAUtils.setupRings(res,graph, settings))
856 {
857 graph.cleanup();
859 mnt.increase(CounterID.FAILEDBUILDATTEMPTS);
860 return null;
861 }
862 } else {
863 graph.cleanup();
865 mnt.increase(CounterID.FAILEDBUILDATTEMPTS);
866 return null;
867 }
868
869 // Check if the chosen combination gives rise to forbidden ends
870 //TODO: this should be considered already when making the list of
871 // possible combination of rings
872 for (Vertex rcv : graph.getFreeRCVertices())
873 {
874 // Also exclude any RCV that is not bound to anything?
875 if (rcv.getEdgeToParent() == null)
876 {
877 res = null;
879 }
880 if (rcv.getEdgeToParent() == null)
881 {
882 // RCV as scaffold! Ignore special case
883 continue;
884 }
885 APClass apc = rcv.getEdgeToParent().getSrcAP().getAPClass();
886 if (fragSpace.getCappingMap().get(apc)==null
887 && fragSpace.getForbiddenEndList().contains(apc))
888 {
889 res = null;
891 }
892 }
893
894 if (res == null)
895 {
896 graph.cleanup();
897 mnt.increase(CounterID.FAILEDBUILDATTEMPTS);
898 return null;
899 }
900
901 Candidate candidate = new Candidate(graph);
902 candidate.setUID(res[0].toString().trim());
903 candidate.setSmiles(res[1].toString().trim());
904 candidate.setChemicalRepresentation((IAtomContainer) res[2]);
905
906 candidate.setName("M" + GeneralUtils.getPaddedString(
909
910 return candidate;
911 }
912
913//------------------------------------------------------------------------------
914
928 public static Candidate buildCandidateByFragmentingMolecule(IAtomContainer mol,
929 Monitor mnt, GAParameters settings, int index) throws DENOPTIMException
930 {
932 if (settings.containsParameters(ParametersType.FS_PARAMS))
933 {
934 fsParams = (FragmentSpaceParameters) settings.getParameters(
936 }
937 FragmentSpace fragSpace = fsParams.getFragmentSpace();
938
940 if (settings.containsParameters(ParametersType.FRG_PARAMS))
941 {
942 frgParams = (FragmenterParameters) settings.getParameters(
944 }
945
946 if (frgParams.getCuttingRules()==null
947 || frgParams.getCuttingRules().isEmpty())
948 {
949 throw new DENOPTIMException("Request to generate candidates by "
950 + "fragmentation but no cutting rules provided. Please,"
951 + "add FRG-CUTTINGRULESFILE=path/to/your/file to the "
952 + "input.");
953 }
954 mnt.increase(CounterID.CONVERTBYFRAGATTEMPTS);
955 mnt.increase(CounterID.NEWCANDIDATEATTEMPTS);
956
957 // Adjust molecular representation to our settings
958 if (!FragmenterTools.prepareMolToFragmentation(mol, frgParams, index))
959 return null;
960
961 // Do actual fragmentation
962 DGraph graph = null;
963 try {
965 frgParams.getCuttingRules(), settings.getLogger(),
966 frgParams.getScaffoldingPolicy(),
967 frgParams.getLinearAngleLimit());
968 } catch (DENOPTIMException de)
969 {
970 String msg = "Unable to convert molecule (" + mol.getAtomCount()
971 + " atoms) to DENPTIM graph. " + de.getMessage();
972 settings.getLogger().log(Level.WARNING, msg);
973 }
974 if (graph == null)
975 {
978 return null;
979 }
980
981 if (frgParams.embedRingsInTemplate())
982 {
983 try {
985 fragSpace, frgParams.getEmbeddedRingsContract());
986 } catch (DENOPTIMException e) {
987 graph.cleanup();
989 return null;
990 }
991 }
992
993 graph.setLocalMsg("INITIAL_MOL_FRAGMENTED");
994
995 Object[] res = graph.checkConsistency(settings);
996 if (res == null)
997 {
998 graph.cleanup();
1000 return null;
1001 }
1002
1003 Candidate candidate = new Candidate(graph);
1004 candidate.setUID(res[0].toString().trim());
1005 candidate.setSmiles(res[1].toString().trim());
1006 candidate.setChemicalRepresentation((IAtomContainer) res[2]);
1007
1008 candidate.setName("M" + GeneralUtils.getPaddedString(
1011
1012 return candidate;
1013 }
1014
1015//------------------------------------------------------------------------------
1016
1028 public static DGraph makeGraphFromFragmentationOfMol(IAtomContainer mol,
1029 List<CuttingRule> cuttingRules, Logger logger,
1030 ScaffoldingPolicy scaffoldingPolicy)
1031 throws DENOPTIMException
1032 {
1033 return makeGraphFromFragmentationOfMol(mol, cuttingRules, logger,
1034 scaffoldingPolicy, 190);
1035 // NB: and angle of 190 means we are not adding Du on linearities
1036 }
1037
1038//------------------------------------------------------------------------------
1039
1053 public static DGraph makeGraphFromFragmentationOfMol(IAtomContainer mol,
1054 List<CuttingRule> cuttingRules, Logger logger,
1055 ScaffoldingPolicy scaffoldingPolicy, double linearAngleLimit)
1056 throws DENOPTIMException
1057 {
1058 // We expect only Fragments here.
1059 List<Vertex> fragments = FragmenterTools.fragmentation(mol,
1060 cuttingRules, logger);
1061 for (Vertex v : fragments)
1062 {
1063 Fragment frag = (Fragment) v;
1064
1065 // This is done to set the symmetry relations in each vertex
1066 frag.updateAPs();
1067
1068 // Add linearity-breaking dummy atoms
1069 DummyAtomHandler.addDummiesOnLinearities(frag, linearAngleLimit);
1070 }
1071 if (fragments.size()==0)
1072 {
1073 throw new DENOPTIMException("Fragmentation of molecule with "
1074 + mol.getAtomCount() + " atoms produced 0 fragments.");
1075 }
1076
1077 // Define which fragment is the scaffold
1078 Vertex scaffold = null;
1079 switch (scaffoldingPolicy)
1080 {
1081 case ELEMENT:
1082 {
1083 for (Vertex v : fragments)
1084 {
1085 if (v instanceof Fragment)
1086 {
1087 boolean setAsScaffold = false;
1088 IAtomContainer iac = v.getIAtomContainer();
1089 for (IAtom atm : iac.atoms())
1090 {
1091 if (scaffoldingPolicy.label.equals(
1093 {
1094 setAsScaffold = true;
1095 break;
1096 }
1097 }
1098 if (setAsScaffold)
1099 {
1100 scaffold = v;
1101 break;
1102 }
1103 }
1104 }
1105 break;
1106 }
1107
1108 default:
1109 case LARGEST_FRAGMENT:
1110 {
1111 try {
1112 scaffold = fragments.stream()
1113 .max(Comparator.comparing(
1115 .get();
1116 } catch (Exception e)
1117 {
1118 throw new DENOPTIMException("Cannot get largest fragment "
1119 + "among " + fragments.size() + " fragments.", e);
1120 }
1121 break;
1122 }
1123 }
1124 if (scaffold==null)
1125 {
1126 throw new DENOPTIMException("No fragment matches criteria to be "
1127 + "identified as the "
1128 + BBType.SCAFFOLD.toString().toLowerCase() + ".");
1129 }
1130 scaffold.setVertexId(0);
1132
1133 // Build the graph
1134 DGraph graph = new DGraph();
1135 graph.addVertex(scaffold);
1136 AtomicInteger vId = new AtomicInteger(1);
1137 for (int i=1; i<fragments.size(); i++)
1138 {
1139 appendVertexesToGraphFollowingEdges(graph, vId, fragments);
1140 }
1141
1142 // Set symmetry relations: these depend on which scaffold we have chosen
1143 graph.detectSymVertexSets();
1144
1145 return graph;
1146 }
1147
1148//------------------------------------------------------------------------------
1149
1151 AtomicInteger vId, List<Vertex> vertexes) throws DENOPTIMException
1152 {
1153 // We seek for the last and non-RCV vertex added to the graph
1154 Vertex lastlyAdded = null;
1155 for (int i=-1; i>-4; i--)
1156 {
1157 lastlyAdded = graph.getVertexList().get(
1158 graph.getVertexList().size()+i);
1159 if (!lastlyAdded.isRCV())
1160 break;
1161 }
1162 for (AttachmentPoint apI : lastlyAdded.getAttachmentPoints())
1163 {
1164 if (!apI.isAvailable())
1165 continue;
1166
1167 for (int j=0; j<vertexes.size(); j++)
1168 {
1169 Vertex fragJ = vertexes.get(j);
1170
1171 boolean ringClosure = false;
1172 if (graph.containsVertex(fragJ))
1173 {
1174 ringClosure = true;
1175 }
1176 for (AttachmentPoint apJ : fragJ.getAttachmentPoints())
1177 {
1178 if (apI==apJ)
1179 continue;
1180
1181 if (apI.getCutId()==apJ.getCutId())
1182 {
1183 if (ringClosure)
1184 {
1187 BondType.ANY));
1189 rcvI.setVertexId(vId.getAndIncrement());
1190 graph.appendVertexOnAP(apI, rcvI.getAP(0));
1191
1195 rcvJ.setVertexId(vId.getAndIncrement());
1196 graph.appendVertexOnAP(apJ, rcvJ.getAP(0));
1197 graph.addRing(rcvI, rcvJ);
1198 } else {
1200 fragJ.setVertexId(vId.getAndIncrement());
1201 graph.appendVertexOnAP(apI, apJ);
1202
1203 // Recursion into the branch of the graph that is
1204 // rooted onto the lastly added vertex
1206 vertexes);
1207 }
1208 }
1209 }
1210 }
1211 }
1212 }
1213
1214//------------------------------------------------------------------------------
1215
1226 public static void outputPopulationDetails(Population population,
1227 String filename, GAParameters settings, boolean printpathNames)
1228 throws DENOPTIMException
1229 {
1230 StringBuilder sb = new StringBuilder(512);
1232 sb.append(NL);
1233
1234 df.setMaximumFractionDigits(settings.getPrecisionLevel());
1235 df.setMinimumFractionDigits(settings.getPrecisionLevel());
1236
1237 // NB: we consider the configured size of the population, not the actual
1238 // size of list representing the population.
1239 String stats = "";
1240 synchronized (population)
1241 {
1242 List<Candidate> popMembers = new ArrayList<Candidate>();
1243 for (int i=0; i<settings.getPopulationSize(); i++)
1244 {
1245 Candidate mol = population.get(i);
1246 popMembers.add(mol);
1247 if (mol != null)
1248 {
1249 String mname = new File(mol.getSDFFile()).getName();
1250 if (mname != null)
1251 sb.append(String.format("%-20s", mname));
1252
1253 sb.append(String.format("%-20s",
1254 mol.getGraph().getGraphId()));
1255 sb.append(String.format("%-30s", mol.getUID()));
1256 sb.append(df.format(mol.getFitness()));
1257
1258 if (printpathNames)
1259 {
1260 sb.append(" ").append(mol.getSDFFile());
1261 }
1262
1263 sb.append(System.getProperty("line.separator"));
1264 }
1265 }
1266
1267 // calculate descriptive statistics for the population
1268 stats = getSummaryStatistics(population, settings);
1269
1270 if (settings.savePopFile())
1271 {
1272 File dest = new File(filename.replaceAll("\\.txt$", ".sdf"));
1273 DenoptimIO.writeCandidatesToFile(dest, popMembers, false);
1274 }
1275 }
1276 if (stats.trim().length() > 0)
1277 sb.append(stats);
1278 DenoptimIO.writeData(filename, sb.toString(), false);
1279
1280 sb.setLength(0);
1281 }
1282
1283//------------------------------------------------------------------------------
1284
1285 private static String getSummaryStatistics(Population popln,
1286 GAParameters settings)
1287 {
1288 double[] fitness = getFitnesses(popln);
1289 double sdev = StatUtils.stddev(fitness, true);
1290 String res = "";
1291 df.setMaximumFractionDigits(settings.getPrecisionLevel());
1292
1293 StringBuilder sb = new StringBuilder(128);
1294 sb.append(NL+NL+"#####POPULATION SUMMARY#####"+NL);
1295 int n = popln.size();
1296 sb.append(String.format("%-30s", "SIZE:"));
1297 sb.append(String.format("%12s", n));
1298 sb.append(NL);
1299 double f;
1300 f = StatUtils.max(fitness);
1301 sb.append(String.format("%-30s", "MAX:")).append(df.format(f));
1302 sb.append(NL);
1303 f = StatUtils.min(fitness);
1304 sb.append(String.format("%-30s", "MIN:")).append(df.format(f));
1305 sb.append(NL);
1306 f = StatUtils.mean(fitness);
1307 sb.append(String.format("%-30s", "MEAN:")).append(df.format(f));
1308 sb.append(NL);
1309 f = StatUtils.median(fitness);
1310 sb.append(String.format("%-30s", "MEDIAN:")).append(df.format(f));
1311 sb.append(NL);
1312 f = StatUtils.stddev(fitness, true);
1313 sb.append(String.format("%-30s", "STDDEV:")).append(df.format(f));
1314 sb.append(NL);
1315 if (sdev > 0.0001)
1316 {
1317 f = StatUtils.skewness(fitness, true);
1318 sb.append(String.format("%-30s", "SKEW:")).append(df.format(f));
1319 sb.append(NL);
1320 } else {
1321 sb.append(String.format("%-30s", "SKEW:")).append(" NaN (sdev too small)");
1322 sb.append(NL);
1323 }
1324
1325 res = sb.toString();
1326 sb.setLength(0);
1327
1328 return res;
1329 }
1330
1331//------------------------------------------------------------------------------
1332
1343 List<Candidate> eligibleParents, int number, GAParameters settings)
1344 {
1345 Candidate[] mates = new Candidate[number];
1346 switch (settings.getSelectionStrategyType())
1347 {
1348 case 1:
1349 mates = SelectionHelper.performTournamentSelection(eligibleParents,
1350 number, settings);
1351 break;
1352 case 2:
1353 mates = SelectionHelper.performRWS(eligibleParents, number, settings);
1354 break;
1355 case 3:
1356 mates = SelectionHelper.performSUS(eligibleParents, number, settings);
1357 break;
1358 case 4:
1359 mates = SelectionHelper.performRandomSelection(eligibleParents, number,
1360 settings);
1361 break;
1362 }
1363 return mates;
1364 }
1365
1366//------------------------------------------------------------------------------
1367
1372 Randomizer randomizer)
1373 {
1374 List<Vertex> candidates = new ArrayList<Vertex>(
1375 g.getVertexList());
1376 candidates.removeIf(v ->
1377 v.getBuildingBlockType() == BBType.SCAFFOLD
1378 || v.getBuildingBlockType() == BBType.CAP);
1379 return randomizer.randomlyChooseOne(candidates);
1380 }
1381
1382//------------------------------------------------------------------------------
1383
1399 protected static XoverSite performFBCC(
1400 List<Candidate> eligibleParents, Population population,
1401 int[] choiceOfParents, int choiceOfXOverSites, GAParameters settings)
1402 {
1403 Candidate parentA = null;
1404 if (choiceOfParents==null)
1405 parentA = selectBasedOnFitness(eligibleParents, 1, settings)[0];
1406 else
1407 parentA = eligibleParents.get(choiceOfParents[0]);
1408
1409 if (parentA == null)
1410 return null;
1411
1414 {
1415 fsParams = (FragmentSpaceParameters)settings.getParameters(
1417 }
1418 FragmentSpace fragSpace = fsParams.getFragmentSpace();
1419 List<Candidate> matesCompatibleWithFirst = population.getXoverPartners(
1420 parentA, eligibleParents, fragSpace);
1421 if (matesCompatibleWithFirst.size() == 0)
1422 return null;
1423
1424 Candidate parentB = null;
1425 if (choiceOfParents==null)
1426 {
1427 parentB = selectBasedOnFitness(matesCompatibleWithFirst, 1,
1428 settings)[0];
1429 } else {
1430 parentB = eligibleParents.get(choiceOfParents[1]);
1431 }
1432 if (parentB == null)
1433 return null;
1434
1435 XoverSite result = null;
1436 if (choiceOfXOverSites<0)
1437 {
1438 result = settings.getRandomizer().randomlyChooseOne(
1439 population.getXoverSites(parentA, parentB));
1440 } else {
1441 result = population.getXoverSites(parentA, parentB).get(
1442 choiceOfXOverSites);
1443 }
1444 return result;
1445 }
1446
1447//------------------------------------------------------------------------------
1448
1449 public static String getPathNameToGenerationFolder(int genID,
1450 GAParameters settings)
1451 {
1452 StringBuilder sb = new StringBuilder(32);
1453
1454 int ndigits = String.valueOf(settings.getNumberOfGenerations()).length();
1455
1456 sb.append(settings.getDataDirectory()).append(FSEP).append(
1458 .append(GeneralUtils.getPaddedString(ndigits, genID));
1459
1460 return sb.toString();
1461 }
1462
1463//------------------------------------------------------------------------------
1464
1465 public static String getPathNameToGenerationDetailsFile(int genID,
1466 GAParameters settings)
1467 {
1468 StringBuilder sb = new StringBuilder(32);
1469
1470 int ndigits = String.valueOf(settings.getNumberOfGenerations()).length();
1471
1472 sb.append(settings.getDataDirectory()).append(FSEP)
1474 .append(GeneralUtils.getPaddedString(ndigits, genID))
1475 .append(FSEP)
1477 .append(GeneralUtils.getPaddedString(ndigits, genID))
1478 .append(".txt");
1479
1480 return sb.toString();
1481 }
1482
1483//------------------------------------------------------------------------------
1484
1486 {
1487 StringBuilder sb = new StringBuilder(32);
1488 sb.append(settings.getDataDirectory()).append(FSEP).append("Final");
1489 return sb.toString();
1490 }
1491
1492//------------------------------------------------------------------------------
1493
1495 GAParameters settings)
1496 {
1497 StringBuilder sb = new StringBuilder(32);
1498 sb.append(settings.getDataDirectory()).append(FSEP).append("Final")
1499 .append(FSEP).append("Final.txt");
1500 return sb.toString();
1501 }
1502
1503//------------------------------------------------------------------------------
1504
1515 protected static void outputFinalResults(Population popln,
1516 GAParameters settings) throws DENOPTIMException
1517 {
1518 String dirName = EAUtils.getPathNameToFinalPopulationFolder(settings);
1519 denoptim.files.FileUtils.createDirectory(dirName);
1520 File fileDir = new File(dirName);
1521
1522 boolean intermediateCandidatesAreOnDisk =
1523 ((FitnessParameters) settings.getParameters(
1524 ParametersType.FIT_PARAMS)).writeCandidatesOnDisk();
1525
1526 for (int i=0; i<popln.size(); i++)
1527 {
1528 Candidate c = popln.get(i);
1529 String sdfile = c.getSDFFile();
1530 String imgfile = c.getImageFile();
1531
1532 try {
1533 if (intermediateCandidatesAreOnDisk && sdfile!=null)
1534 {
1535 FileUtils.copyFileToDirectory(new File(sdfile), fileDir);
1536 } else {
1537 File candFile = new File(fileDir, c.getName()
1539 c.setSDFFile(candFile.getAbsolutePath());
1540 DenoptimIO.writeCandidateToFile(candFile, c, false);
1541 }
1542 } catch (IOException ioe) {
1543 throw new DENOPTIMException("Failed to copy file '"
1544 + sdfile + "' to '" + fileDir + "' for candidate "
1545 + c.getName(), ioe);
1546 }
1547 if (imgfile != null && intermediateCandidatesAreOnDisk)
1548 {
1549 try {
1550 FileUtils.copyFileToDirectory(new File(imgfile), fileDir);
1551 } catch (IOException ioe) {
1552 throw new DENOPTIMException("Failed to copy file '"
1553 + imgfile + "' to '" + fileDir + "' for candidate "
1554 + c.getName(), ioe);
1555 }
1556 }
1557 }
1560 settings, true);
1561 }
1562
1563//------------------------------------------------------------------------------
1564
1573 protected static void getPopulationFromFile(String filename,
1574 Population population, SizeControlledSet uniqueIDsSet,
1575 String genDir, GAParameters settings)
1576 throws DENOPTIMException, IOException
1577 {
1578 List<Candidate> candidates = DenoptimIO.readCandidates(
1579 new File(filename), true);
1580 if (candidates.size() == 0)
1581 {
1582 String msg = "Found 0 candidates in file " + filename;
1583 settings.getLogger().log(Level.SEVERE, msg);
1584 throw new DENOPTIMException(msg);
1585 }
1586
1587 for (Candidate candidate : candidates)
1588 {
1589 if (uniqueIDsSet.addNewUniqueEntry(candidate.getUID()))
1590 {
1592 int gctr = GraphUtils.getUniqueGraphIndex();
1593
1594 String molName = "M" + GeneralUtils.getPaddedString(8, ctr);
1595 candidate.setName(molName);
1596 candidate.getGraph().setGraphId(gctr);
1597 candidate.getGraph().setLocalMsg("INITIAL_POPULATION");
1598 String sdfPathName = genDir + System.getProperty("file.separator")
1600 candidate.setSDFFile(sdfPathName);
1601 candidate.setImageFile(null);
1602
1603 // Write the candidate to file as if it had been processed by fitness provider
1604 DenoptimIO.writeCandidateToFile(new File(sdfPathName),
1605 candidate, false);
1606
1607 population.add(candidate);
1608 }
1609 }
1610
1611 if (population.isEmpty())
1612 {
1613 String msg = "Population is still empty after having processes "
1614 + candidates.size() + " candidates from file " + filename;
1615 settings.getLogger().log(Level.SEVERE, msg);
1616 throw new DENOPTIMException(msg);
1617 }
1618
1619 setVertexCounterValue(population);
1620 }
1621
1622//------------------------------------------------------------------------------
1623
1624 protected static void writeUID(String outfile, HashSet<String> lstInchi,
1625 boolean append) throws DENOPTIMException
1626 {
1627 StringBuilder sb = new StringBuilder(256);
1628 Iterator<String> iter = lstInchi.iterator();
1629
1630 boolean first = true;
1631 while(iter.hasNext())
1632 {
1633 if (first)
1634 {
1635 sb.append(iter.next());
1636 first = false;
1637 }
1638 else
1639 {
1640 sb.append(NL).append(iter.next());
1641 }
1642 }
1643
1644 DenoptimIO.writeData(outfile, sb.toString(), append);
1645 sb.setLength(0);
1646 }
1647
1648//------------------------------------------------------------------------------
1649
1657 protected static void setVertexCounterValue(Population population)
1658 throws DENOPTIMException
1659 {
1660 long val = Long.MIN_VALUE;
1661 for (Candidate popln1 : population)
1662 {
1663 DGraph g = popln1.getGraph();
1664 val = Math.max(val, g.getMaxVertexId());
1665 }
1667 }
1668
1669//------------------------------------------------------------------------------
1670
1678 protected static DGraph buildGraph(GAParameters settings)
1679 throws DENOPTIMException
1680 {
1682 if (settings.containsParameters(ParametersType.FS_PARAMS))
1683 {
1684 fsParams = (FragmentSpaceParameters)settings.getParameters(
1686 }
1687 FragmentSpace fragSpace = fsParams.getFragmentSpace();
1688
1689 DGraph graph = new DGraph();
1691
1692 // building a molecule starts by selecting a random scaffold
1693 Vertex scafVertex = fragSpace.makeRandomScaffold();
1694
1695 // add the scaffold as a vertex
1696 graph.addVertex(scafVertex);
1697 graph.setLocalMsg("NEW");
1698
1699 if (scafVertex instanceof Template
1700 && !((Template) scafVertex).getContractLevel().equals(
1702 {
1703 Monitor mnt = new Monitor();
1704 mnt.name = "IntraTemplateBuild";
1705 List<Vertex> initialMutableSites = graph.getMutableSites(
1706 settings.getExcludedMutationTypes());
1707 for (Vertex mutableSite : initialMutableSites)
1708 {
1709 // This accounts for the possibility that a mutation changes a
1710 // branch of the initial graph or deletes vertexes.
1711 if (!graph.containsOrEmbedsVertex(mutableSite))
1712 continue;
1713
1714 // TODO: need to discriminate between EmptyVertexes that
1715 // represent placeholders and those that represent property carriers
1716 // The first should always be mutated (as it happens now), but
1717 // the latter should be kept intact.
1718 // Possibly this is a case for subclassing the EmptyVertex.
1719
1720 if (!GraphOperations.performMutation(mutableSite, mnt,
1721 settings))
1722 {
1725 return null;
1726 }
1727 }
1728 }
1729
1730 // get settings //TODO: this should happen inside RunTimeParameters
1732 if (settings.containsParameters(ParametersType.RC_PARAMS))
1733 {
1734 rcParams = (RingClosureParameters)settings.getParameters(
1736 }
1737//TODO this works only for scaffolds at the moment. make the preference for
1738// fragments that lead to known closable chains operate also when fragments are
1739// the "turning point".
1742 scafVertex.getBuildingBlockId()));
1743
1744 if (scafVertex.hasFreeAP())
1745 {
1746 GraphOperations.extendGraph(scafVertex, true, false, settings);
1747 }
1748
1749 if (!(scafVertex instanceof Template)
1750 && graph.getVertexCount() == 0)
1751 {
1752 return null;
1753 }
1754
1755 graph.addCappingGroups(fragSpace);
1756 return graph;
1757 }
1758
1759//------------------------------------------------------------------------------
1760
1773 protected static boolean setupRings(Object[] res, DGraph molGraph,
1774 GAParameters settings) throws DENOPTIMException
1775 {
1776 // get settings //TODO: this should happen inside RunTimeParameters
1778 if (settings.containsParameters(ParametersType.RC_PARAMS))
1779 {
1780 rcParams = (RingClosureParameters)settings.getParameters(
1782 }
1784 if (settings.containsParameters(ParametersType.FS_PARAMS))
1785 {
1786 fsParams = (FragmentSpaceParameters)settings.getParameters(
1788 }
1789 FragmentSpace fragSpace = fsParams.getFragmentSpace();
1790
1791 if (!fragSpace.useAPclassBasedApproach())
1792 return true;
1793
1794 if (!rcParams.allowRingClosures())
1795 return true;
1796
1797 // get a atoms/bonds molecular representation (no 3D needed)
1798 ThreeDimTreeBuilder t3d = new ThreeDimTreeBuilder(settings.getLogger(),
1799 settings.getRandomizer());
1800 t3d.setAlignBBsIn3D(false);
1801 IAtomContainer mol = t3d.convertGraphTo3DAtomContainer(molGraph,true);
1802
1803 // Set rotatability property as property of IBond
1804 String rotoSpaceFile = "";
1805 if (settings.containsParameters(ParametersType.FS_PARAMS))
1806 {
1807 rotoSpaceFile = ((FragmentSpaceParameters) settings.getParameters(
1808 ParametersType.FS_PARAMS)).getRotSpaceDefFile();
1809 }
1810 RotationalSpaceUtils.defineRotatableBonds(mol, rotoSpaceFile, true,
1811 true, settings.getLogger());
1812
1813 // get the set of possible RCA combinations = ring closures
1814 CyclicGraphHandler cgh = new CyclicGraphHandler(rcParams,fragSpace);
1815
1816 //TODO: remove hard-coded variable that exclude considering all
1817 // combination of rings
1818 boolean onlyRandomCombOfRings = true;
1819
1820 if (onlyRandomCombOfRings)
1821 {
1822 List<Ring> combsOfRings = cgh.getRandomCombinationOfRings(
1823 mol, molGraph, rcParams.getMaxRingClosures());
1824 if (combsOfRings.size() > 0)
1825 {
1826 for (Ring ring : combsOfRings)
1827 {
1828 // Consider the crowding probability
1829 double shot = settings.getRandomizer().nextDouble();
1830 int crowdOnH = EAUtils.getCrowdedness(
1831 ring.getHeadVertex().getEdgeToParent().getSrcAP(),
1832 true);
1833 int crowdOnT = EAUtils.getCrowdedness(
1834 ring.getTailVertex().getEdgeToParent().getSrcAP(),
1835 true);
1836 double crowdProbH = EAUtils.getCrowdingProbability(crowdOnH,
1837 settings);
1838 double crowdProbT = EAUtils.getCrowdingProbability(crowdOnT,
1839 settings);
1840
1841 if (shot < crowdProbH && shot < crowdProbT)
1842 {
1843 molGraph.addRing(ring);
1844 }
1845 }
1846 }
1847 }
1848 else
1849 {
1850 ArrayList<List<Ring>> allCombsOfRings =
1851 cgh.getPossibleCombinationOfRings(mol, molGraph);
1852
1853 // Keep closable chains that are relevant for chelate formation
1854 if (rcParams.buildChelatesMode())
1855 {
1856 ArrayList<List<Ring>> toRemove = new ArrayList<>();
1857 for (List<Ring> setRings : allCombsOfRings)
1858 {
1859 if (!cgh.checkChelatesGraph(molGraph,setRings))
1860 {
1861 toRemove.add(setRings);
1862 }
1863 }
1864
1865 allCombsOfRings.removeAll(toRemove);
1866 if (allCombsOfRings.isEmpty())
1867 {
1868 String msg = "Setup Rings: no combination of rings.";
1869 settings.getLogger().log(Level.INFO, msg);
1870 return false;
1871 }
1872 }
1873
1874 // Select a combination, if any still available
1875 int sz = allCombsOfRings.size();
1876 if (sz > 0)
1877 {
1878 List<Ring> selected = new ArrayList<>();
1879 if (sz == 1)
1880 {
1881 selected = allCombsOfRings.get(0);
1882 }
1883 else
1884 {
1885 int selId = settings.getRandomizer().nextInt(sz);
1886 selected = allCombsOfRings.get(selId);
1887 }
1888
1889 // append new rings to existing list of rings in graph
1890 for (Ring ring : selected)
1891 {
1892 molGraph.addRing(ring);
1893 }
1894 }
1895 }
1896
1897 // Update the IAtomContainer representation
1898 //DENOPTIMMoleculeUtils.removeUsedRCA(mol,molGraph);
1899 // Done already at t3d.convertGraphTo3DAtomContainer
1900 if (res!=null)
1901 {
1902 res[2] = mol;
1903 }
1904 // Update the SMILES representation
1905 if (res!=null)
1906 {
1907 String molsmiles = MoleculeUtils.getSMILESForMolecule(mol,
1908 settings.getLogger());
1909 if (molsmiles == null)
1910 {
1911 String msg = "Evaluation of graph: SMILES is null! "
1912 + molGraph.toString();
1913 settings.getLogger().log(Level.INFO, msg);
1914 molsmiles = "FAIL: NO SMILES GENERATED";
1915 }
1916 res[1] = molsmiles;
1917 }
1918
1919 // Update the INCHI key representation
1920 if (res!=null)
1921 {
1922 String inchikey = MoleculeUtils.getInChIKeyForMolecule(mol,
1923 settings.getLogger());
1924 if (inchikey == null)
1925 {
1926 String msg = "Evaluation of graph: INCHI is null!";
1927 settings.getLogger().log(Level.INFO, msg);
1928 inchikey = "UNDEFINED";
1929 }
1930 res[0] = inchikey;
1931 }
1932
1933 return true;
1934 }
1935
1936//------------------------------------------------------------------------------
1937
1945 protected static boolean containsMolecule(Population mols, String molcode)
1946 {
1947 if(mols.isEmpty())
1948 return false;
1949
1950 for (Candidate mol : mols)
1951 {
1952 if (mol.getUID().compareToIgnoreCase(molcode) == 0)
1953 {
1954 return true;
1955 }
1956 }
1957 return false;
1958 }
1959
1960//------------------------------------------------------------------------------
1961
1968 protected static double[] getFitnesses(Population mols)
1969 {
1970 int k = mols.size();
1971 double[] arr = new double[k];
1972
1973 for (int i=0; i<k; i++)
1974 {
1975 arr[i] = mols.get(i).getFitness();
1976 }
1977 return arr;
1978 }
1979
1980//------------------------------------------------------------------------------
1981
1989 protected static double getPopulationSD(Population molPopulation)
1990 {
1991 double[] fitvals = getFitnesses(molPopulation);
1992 return StatUtils.stddev(fitvals, true);
1993 }
1994
1995//------------------------------------------------------------------------------
1996
2009 public static double getGrowthProbabilityAtLevel(int level, int scheme,
2010 double lambda, double sigmaOne, double sigmaTwo)
2011 {
2012 return getProbability(level, scheme, lambda, sigmaOne, sigmaTwo);
2013 }
2014
2015//------------------------------------------------------------------------------
2016
2029 public static double getMolSizeProbability(DGraph graph,
2030 GAParameters settings)
2031 {
2032 if (!settings.useMolSizeBasedProb())
2033 return 1.0;
2034 int scheme = settings.getMolGrowthProbabilityScheme();
2035 double lambda =settings.getMolGrowthMultiplier();
2036 double sigmaOne = settings.getMolGrowthFactorSteepSigma();
2037 double sigmaTwo = settings.getMolGrowthFactorMiddleSigma();
2038 return getMolSizeProbability(graph, scheme, lambda, sigmaOne, sigmaTwo);
2039 }
2040
2041//------------------------------------------------------------------------------
2042
2055 public static double getMolSizeProbability(DGraph graph,
2056 int scheme, double lambda, double sigmaOne, double sigmaTwo)
2057 {
2058 return getProbability(graph.getHeavyAtomsCount(), scheme, lambda,
2059 sigmaOne, sigmaTwo);
2060 }
2061
2062//------------------------------------------------------------------------------
2063
2074 public static double getProbability(double value,
2075 int scheme, double lambda, double sigmaOne, double sigmaTwo)
2076 {
2077 double prob = 1.0;
2078 if (scheme == 0)
2079 {
2080 double f = Math.exp(-1.0 * value * lambda);
2081 prob = 1 - ((1-f)/(1+f));
2082 }
2083 else if (scheme == 1)
2084 {
2085 prob = 1.0 - Math.tanh(lambda * value);
2086 }
2087 else if (scheme == 2)
2088 {
2089 prob = 1.0-1.0/(1.0 + Math.exp(-sigmaOne * (value - sigmaTwo)));
2090 }
2091 else if (scheme == 3)
2092 {
2093 prob = 1.0;
2094 }
2095 return prob;
2096 }
2097
2098//------------------------------------------------------------------------------
2099
2106 public static double getGrowthByLevelProbability(int level,
2107 GAParameters settings)
2108 {
2109 if (!settings.useLevelBasedProb())
2110 return 1.0;
2111 int scheme = settings.getGrowthProbabilityScheme();
2112 double lambda =settings.getGrowthMultiplier();
2113 double sigmaOne = settings.getGrowthFactorSteepSigma();
2114 double sigmaTwo = settings.getGrowthFactorMiddleSigma();
2115 return getGrowthProbabilityAtLevel(level, scheme, lambda, sigmaOne,
2116 sigmaTwo);
2117 }
2118
2119//------------------------------------------------------------------------------
2120
2130 GAParameters settings)
2131 {
2132 int scheme = settings.getCrowdingProbabilityScheme();
2133 double lambda =settings.getCrowdingMultiplier();
2134 double sigmaOne = settings.getCrowdingFactorSteepSigma();
2135 double sigmaTwo = settings.getCrowdingFactorMiddleSigma();
2136 return getCrowdingProbability(ap, scheme, lambda, sigmaOne, sigmaTwo);
2137 }
2138
2139//------------------------------------------------------------------------------
2140
2154 public static double getCrowdingProbability(int crowdedness,
2155 GAParameters settings)
2156 {
2157 int scheme = settings.getCrowdingProbabilityScheme();
2158 double lambda =settings.getCrowdingMultiplier();
2159 double sigmaOne = settings.getCrowdingFactorSteepSigma();
2160 double sigmaTwo = settings.getCrowdingFactorMiddleSigma();
2161 return getCrowdingProbabilityForCrowdedness(crowdedness, scheme, lambda,
2162 sigmaOne, sigmaTwo);
2163 }
2164
2165//------------------------------------------------------------------------------
2166
2174 public static int getCrowdedness(AttachmentPoint ap)
2175 {
2176 return getCrowdedness(ap,false);
2177 }
2178
2179//------------------------------------------------------------------------------
2180
2190 public static int getCrowdedness(AttachmentPoint ap,
2191 boolean ignoreFreeRCVs)
2192 {
2193 if (ap.getOwner() instanceof EmptyVertex)
2194 {
2195 return 0;
2196 }
2197 int crowdness = 0;
2198 DGraph g = ap.getOwner().getGraphOwner();
2200 {
2201 if (oap.getAtomPositionNumber() == ap.getAtomPositionNumber()
2202 && !oap.isAvailableThroughout()
2203 && oap.getLinkedAP().getOwner()
2204 .getBuildingBlockType() != BBType.CAP)
2205 {
2206 if (ignoreFreeRCVs && oap.getLinkedAP().getOwner().isRCV())
2207 {
2208 if (g.getUsedRCVertices().contains(oap.getLinkedAP().getOwner()))
2209 crowdness = crowdness + 1;
2210 } else {
2211 crowdness = crowdness + 1;
2212 }
2213 }
2214 }
2215 return crowdness;
2216 }
2217
2218//------------------------------------------------------------------------------
2219
2232 public static double getCrowdingProbability(AttachmentPoint ap,
2233 int scheme,
2234 double lambda, double sigmaOne, double sigmaTwo)
2235 {
2236 //Applies only to molecular fragments
2237 if (ap.getOwner() instanceof Fragment == false)
2238 {
2239 return 1.0;
2240 }
2241 int crowdness = getCrowdedness(ap);
2242 return getCrowdingProbabilityForCrowdedness(crowdness, scheme, lambda,
2243 sigmaOne, sigmaTwo);
2244 }
2245
2246//------------------------------------------------------------------------------
2247
2257 public static double getCrowdingProbabilityForCrowdedness(int crowdedness,
2258 int scheme,
2259 double lambda, double sigmaOne, double sigmaTwo)
2260 {
2261 return getProbability(crowdedness, scheme, lambda, sigmaOne, sigmaTwo);
2262 }
2263
2264//------------------------------------------------------------------------------
2265
2274 protected static boolean foundForbiddenEnd(DGraph molGraph,
2275 FragmentSpaceParameters fsParams)
2276 {
2277 List<Vertex> vertices = molGraph.getVertexList();
2278 Set<APClass> classOfForbEnds = fsParams.getFragmentSpace()
2280 for (Vertex vtx : vertices)
2281 {
2282 List<AttachmentPoint> daps = vtx.getAttachmentPoints();
2283 for (AttachmentPoint dp : daps)
2284 {
2285 if (dp.isAvailable())
2286 {
2287 APClass apClass = dp.getAPClass();
2288 if (classOfForbEnds.contains(apClass))
2289 {
2290 String msg = "Forbidden free AP for Vertex: "
2291 + vtx.getVertexId()
2292 + " MolId: " + (vtx.getBuildingBlockId() + 1)
2293 + " Ftype: " + vtx.getBuildingBlockType()
2294 + "\n"+ molGraph+" \n "
2295 + " AP class: " + apClass;
2296 fsParams.getLogger().log(Level.WARNING, msg);
2297 return true;
2298 }
2299 }
2300 }
2301 }
2302 return false;
2303 }
2304
2305//------------------------------------------------------------------------------
2306
2307 protected static void readUID(String infile, HashSet<String> lstInchi)
2308 throws DENOPTIMException
2309 {
2310 ArrayList<String> lst = DenoptimIO.readList(infile);
2311 for (String str:lst)
2312 lstInchi.add(str);
2313 lst.clear();
2314 }
2315
2316//------------------------------------------------------------------------------
2317
2319 AttachmentPoint apA, SymmetricAPs symAPsA, GAParameters settings)
2320 {
2321
2322 // TODO Auto-generated method stub
2323 return null;
2324 }
2325
2326//------------------------------------------------------------------------------
2327}
General set of constants used in DENOPTIM.
static final String GAGENSUMMARYHEADER
Header of text files collection generation details.
static final String GAGENDIRNAMEROOT
Prefix for generation folders.
static final String FITFILENAMEEXTOUT
Ending and extension of output file of external fitness provider.
Settings defining the calculation of fitness.
static Vertex getRCPForAP(AttachmentPoint ap, APClass rcvApClass)
static boolean prepareMolToFragmentation(IAtomContainer mol, FragmenterParameters settings, int index)
Do any pre-processing on a IAtomContainer meant to be fragmented.
static boolean fragmentation(File input, FragmenterParameters settings, File output, Logger logger)
Performs fragmentation according to the given cutting rules.
Class defining a space of building blocks.
boolean useAPclassBasedApproach()
Check usage of APClass-based approach, i.e., uses attachment points with annotated data (i....
Vertex makeRandomScaffold()
Randomly select a scaffold and return a fully configured clone of it.
HashMap< APClass, APClass > getCappingMap()
Parameters defining the fragment space.
Helper methods for the genetic algorithm.
Definition: EAUtils.java:93
static void outputFinalResults(Population popln, GAParameters settings)
Saves the final results to disk.
Definition: EAUtils.java:1515
static List< Candidate > buildCandidatesByXOver(List< Candidate > eligibleParents, Population population, Monitor mnt, int[] choiceOfParents, int choiceOfXOverSites, int choiceOfOffstring, GAParameters settings, int maxCandidatesToReturn)
Generates up to a pair of new offspring by performing a crossover operation.
Definition: EAUtils.java:378
static CandidateSource pickNewCandidateGenerationMode(double xoverWeight, double mutWeight, double newWeight, Randomizer randomizer)
Takes a decision on which CandidateSource method to use for generating a new Candidate.
Definition: EAUtils.java:249
static double getGrowthByLevelProbability(int level, GAParameters settings)
Calculates the probability of adding a fragment to the given level.
Definition: EAUtils.java:2106
static double getCrowdingProbability(int crowdedness, GAParameters settings)
Calculated the probability of using and attachment point rooted on an atom that is holding other atta...
Definition: EAUtils.java:2154
static int chooseNumberOfSitesToMutate(double[] multiSiteMutationProb, double hit)
Takes a decision on how many sites to mutate on a candidate.
Definition: EAUtils.java:210
static void appendVertexesToGraphFollowingEdges(DGraph graph, AtomicInteger vId, List< Vertex > vertexes)
Definition: EAUtils.java:1150
static Candidate readCandidateFromFile(File srcFile, Monitor mnt, GAParameters settings)
Definition: EAUtils.java:754
static Candidate[] selectBasedOnFitness(List< Candidate > eligibleParents, int number, GAParameters settings)
Selects a number of members from the given population.
Definition: EAUtils.java:1342
static DGraph makeGraphFromFragmentationOfMol(IAtomContainer mol, List< CuttingRule > cuttingRules, Logger logger, ScaffoldingPolicy scaffoldingPolicy, double linearAngleLimit)
Converts a molecule into a DGraph by fragmentation and re-assembling of the fragments.
Definition: EAUtils.java:1053
static boolean setupRings(Object[] res, DGraph molGraph, GAParameters settings)
Evaluates the possibility of closing rings in a given graph and if any ring can be closed,...
Definition: EAUtils.java:1773
static Candidate buildCandidateByXOver(List< Candidate > eligibleParents, Population population, Monitor mnt, GAParameters settings)
Generates a new offspring by performing a crossover operation.
Definition: EAUtils.java:299
static List< Candidate > buildCandidatesByXOver(List< Candidate > eligibleParents, Population population, Monitor mnt, GAParameters settings)
Generates a pair of new offspring by performing a crossover operation.
Definition: EAUtils.java:279
static final String NL
Definition: EAUtils.java:123
static void getPopulationFromFile(String filename, Population population, SizeControlledSet uniqueIDsSet, String genDir, GAParameters settings)
Reconstruct the molecular population from the file.
Definition: EAUtils.java:1573
static void writeUID(String outfile, HashSet< String > lstInchi, boolean append)
Definition: EAUtils.java:1624
static HashMap< Integer, ArrayList< String > > lstFragmentClass
Definition: EAUtils.java:114
static double getGrowthProbabilityAtLevel(int level, int scheme, double lambda, double sigmaOne, double sigmaTwo)
Calculates the probability of adding a fragment to the given level.
Definition: EAUtils.java:2009
static DGraph makeGraphFromFragmentationOfMol(IAtomContainer mol, List< CuttingRule > cuttingRules, Logger logger, ScaffoldingPolicy scaffoldingPolicy)
Converts a molecule into a DGraph by fragmentation and re-assembling of the fragments.
Definition: EAUtils.java:1028
static double getProbability(double value, int scheme, double lambda, double sigmaOne, double sigmaTwo)
Calculated a probability given parameters defining the shape of the probability function and a single...
Definition: EAUtils.java:2074
static XoverSite performFBCC(List< Candidate > eligibleParents, Population population, int[] choiceOfParents, int choiceOfXOverSites, GAParameters settings)
Perform fitness-based, class-compatible selection of parents that can do crossover operations.
Definition: EAUtils.java:1399
static String getPathNameToFinalPopulationFolder(GAParameters settings)
Definition: EAUtils.java:1485
static CandidateSource chooseGenerationMethod(GAParameters settings)
Choose one of the methods to make new Candidates.
Definition: EAUtils.java:193
static Locale enUsLocale
Locale used to write reports.
Definition: EAUtils.java:100
static double getCrowdingProbability(AttachmentPoint ap, GAParameters settings)
Calculated the probability of using and attachment point rooted on an atom that is holding other atta...
Definition: EAUtils.java:2129
static boolean foundForbiddenEnd(DGraph molGraph, FragmentSpaceParameters fsParams)
Check if there are forbidden ends: free attachment points that are not suitable for capping and not a...
Definition: EAUtils.java:2274
static void setVertexCounterValue(Population population)
Set the Vertex counter value according to the largest value found in the given population.
Definition: EAUtils.java:1657
static Candidate buildCandidateByMutation(List< Candidate > eligibleParents, Monitor mnt, GAParameters settings)
Definition: EAUtils.java:630
static Candidate buildCandidateByFragmentingMolecule(IAtomContainer mol, Monitor mnt, GAParameters settings, int index)
Generates a candidate by fragmenting a molecule and generating the graph that reconnects all fragment...
Definition: EAUtils.java:928
static DGraph buildGraph(GAParameters settings)
Graph construction starts with selecting a random core/scaffold.
Definition: EAUtils.java:1678
static Candidate buildCandidateByXOver(List< Candidate > eligibleParents, Population population, Monitor mnt, int[] choiceOfParents, int choiceOfXOverSites, int choiceOfOffstring, GAParameters settings)
Generates a new offspring by performing a crossover operation.
Definition: EAUtils.java:333
static double[] getFitnesses(Population mols)
Get the fitness values for the list of molecules.
Definition: EAUtils.java:1968
static String getSummaryStatistics(Population popln, GAParameters settings)
Definition: EAUtils.java:1285
static void createFolderForGeneration(int genId, GAParameters settings)
Creates a folder meant to hold all the data generated during a generation.
Definition: EAUtils.java:134
static double getMolSizeProbability(DGraph graph, int scheme, double lambda, double sigmaOne, double sigmaTwo)
Calculated the probability of extending a graph based on the current size of the molecular representa...
Definition: EAUtils.java:2055
static DecimalFormat initialiseFormatter()
Definition: EAUtils.java:106
static int getCrowdedness(AttachmentPoint ap)
Calculate the current crowdedness of the given attachment point.
Definition: EAUtils.java:2174
static int getCrowdedness(AttachmentPoint ap, boolean ignoreFreeRCVs)
Calculate the current crowdedness of the given attachment point.
Definition: EAUtils.java:2190
static HashMap< Integer, ArrayList< Integer > > fragmentPool
Definition: EAUtils.java:95
static void outputPopulationDetails(Population population, String filename, GAParameters settings, boolean printpathNames)
Write out summary for the current GA population.
Definition: EAUtils.java:1226
static Vertex selectNonScaffoldNonCapVertex(DGraph g, Randomizer randomizer)
Chose randomly a vertex that is neither scaffold or capping group.
Definition: EAUtils.java:1371
static double getCrowdingProbabilityForCrowdedness(int crowdedness, int scheme, double lambda, double sigmaOne, double sigmaTwo)
Calculated the crowding probability for a given level of crowdedness.
Definition: EAUtils.java:2257
static String getPathNameToGenerationFolder(int genID, GAParameters settings)
Definition: EAUtils.java:1449
static double getPopulationSD(Population molPopulation)
Check if fitness values have significant standard deviation.
Definition: EAUtils.java:1989
static String getPathNameToFinalPopulationDetailsFile(GAParameters settings)
Definition: EAUtils.java:1494
static Candidate buildCandidateFromScratch(Monitor mnt, GAParameters settings)
Definition: EAUtils.java:827
static double getCrowdingProbability(AttachmentPoint ap, int scheme, double lambda, double sigmaOne, double sigmaTwo)
Calculated the probability of using and attachment point rooted on an atom that is holding other atta...
Definition: EAUtils.java:2232
static boolean containsMolecule(Population mols, String molcode)
Check if the population contains the specified InChi code.
Definition: EAUtils.java:1945
static AttachmentPoint searchForApSuitableToRingClosure(AttachmentPoint apA, SymmetricAPs symAPsA, GAParameters settings)
Definition: EAUtils.java:2318
static DecimalFormat df
Format for decimal fitness numbers that overwrites Locale to en_US.
Definition: EAUtils.java:105
static void readUID(String infile, HashSet< String > lstInchi)
Definition: EAUtils.java:2307
static final String FSEP
Definition: EAUtils.java:124
static String getPathNameToGenerationDetailsFile(int genID, GAParameters settings)
Definition: EAUtils.java:1465
static double getMolSizeProbability(DGraph graph, GAParameters settings)
Calculated the probability of extending a graph based on the current size of the molecular representa...
Definition: EAUtils.java:2029
static Population importInitialPopulation(SizeControlledSet uniqueIDsSet, GAParameters settings)
Reads unique identifiers and initial population file according to the GAParameters.
Definition: EAUtils.java:148
Collection of operators meant to alter graphs and associated utilities.
static boolean extendGraph(Vertex curVertex, boolean extend, boolean symmetryOnAps, GAParameters settings)
function that will keep extending the graph according to the growth/substitution probability.
static boolean performMutation(DGraph graph, Monitor mnt, GAParameters settings)
Tries to do mutate the given graph.
static boolean performCrossover(XoverSite site, FragmentSpace fragSpace)
Performs the crossover that swaps the two subgraphs defining the given XoverSite.
A collection of candidates.
Definition: Population.java:48
List< XoverSite > getXoverSites(Candidate parentA, Candidate parentB)
Returns a list of crossover sites between the two given parents.
List< Candidate > getXoverPartners(Candidate memberA, List< Candidate > eligibleParents, FragmentSpace fragSpace)
Returns a list of population members that can do crossover with the specified member.
Class that offers methods to performs fitness-driven selection of candidates.
static Candidate[] performRandomSelection(List< Candidate > population, int sz, RunTimeParameters settings)
Randomly select k individuals from the population.
static Candidate[] performTournamentSelection(List< Candidate > eligibleParents, int sz, RunTimeParameters settings)
Select p individuals at random.
static Candidate[] performRWS(List< Candidate > population, int sz, RunTimeParameters settings)
Roulette wheel selection is implemented as follows:
static Candidate[] performSUS(List< Candidate > population, int sz, RunTimeParameters settings)
Stochastic Uniform Sampling Note: this implementation is based on the WATCHMAKER framework http://wat...
This class collects the data identifying the subgraphs that would be swapped by a crossover event.
Definition: XoverSite.java:36
XoverSite projectToClonedGraphs()
Creates a new instance of this class that contains the list of vertexes that correspond to those cont...
Definition: XoverSite.java:275
String toString()
Produced a string for showing what this object is.
Definition: XoverSite.java:349
List< Vertex > getA()
Returns the collection of vertexes belonging to the first subgraph.
Definition: XoverSite.java:187
List< Vertex > getB()
Returns the collection of vertexes belonging to the second subgraph.
Definition: XoverSite.java:198
static final APClass RCACLASSMINUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:91
static final String ATPLUS
String defining a conventional APClass.
Definition: APClass.java:68
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
Definition: APClass.java:136
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
int getAtomPositionNumber()
The index of the source atom in the atom list of the fragment.
A candidate is the combination of a denoptim graph with molecular representation and may include also...
Definition: Candidate.java:40
void setSDFFile(String molFile)
Definition: Candidate.java:445
void setSmiles(String smiles)
Definition: Candidate.java:473
void setUID(String uid)
Definition: Candidate.java:466
int getGeneration()
The generation this candidate belong to is that in which it was generated.
Definition: Candidate.java:578
void setName(String name)
Definition: Candidate.java:495
void setChemicalRepresentation(IAtomContainer iac)
Just place the argument in the IAtomContainer field of this object.
Definition: Candidate.java:378
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
void setCandidateClosableChains(ArrayList< ClosableChain > closableChains)
Definition: DGraph.java:705
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
Definition: DGraph.java:1097
DGraph embedPatternsInTemplates(GraphPattern pattern, FragmentSpace fragSpace)
Searches for the given pattern type and generated a new graph where each set of (clones of) vertexes ...
Definition: DGraph.java:4616
void getChildrenTree(Vertex vertex, List< Vertex > children)
Gets all the children of the current vertex recursively.
Definition: DGraph.java:2771
String getLocalMsg()
Definition: DGraph.java:279
void setGraphId(int id)
Definition: DGraph.java:258
ArrayList< Vertex > getFreeRCVertices()
Search for unused ring closing vertices: vertices that contain only a RingClosingAttractor and are no...
Definition: DGraph.java:984
Object[] checkConsistency(RunTimeParameters settings)
Peeks into this graph to derive a preliminary chemical representation with SMILES and InChIKey.
Definition: DGraph.java:5353
List< Vertex > getVertexList()
Definition: DGraph.java:719
DGraph clone()
Returns almost "deep-copy" of this graph.
Definition: DGraph.java:3186
void renumberGraphVertices()
Reassign vertex IDs to all vertices of this graph.
Definition: DGraph.java:5283
boolean containsOrEmbedsVertex(Vertex v)
Check if the specified vertex is contained in this graph as a node or in any inner graphs that may be...
Definition: DGraph.java:2530
DGraph getOutermostGraphOwner()
Definition: DGraph.java:6943
void addCappingGroups(FragmentSpace fragSpace)
Add a capping groups on free unused attachment points.
Definition: DGraph.java:4169
void cleanup()
Wipes the data in this graph.
Definition: DGraph.java:3368
Candidate getCandidateOwner()
Returns the reference of the candidate item that is defined by this graph.
Definition: DGraph.java:251
ArrayList< Vertex > getUsedRCVertices()
Search for used ring closing vertices: vertices that contain only a RingClosingAttractor and are part...
Definition: DGraph.java:1007
int getHeavyAtomsCount()
Calculate the number of atoms from the graph representation.
Definition: DGraph.java:3953
List< Vertex > getMutableSites()
A list of mutation sites from within this graph.
Definition: DGraph.java:6622
void setLocalMsg(String msg)
Definition: DGraph.java:272
boolean detectSymVertexSets()
Tries to determine the set of symmetric vertices in this graph based on finding compatible Vertexes t...
Definition: DGraph.java:372
An empty vertex has the behaviors of a vertex, but has no molecular structure.
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
void updateAPs()
Changes the properties of each APs as to reflect the current atom list.
Definition: Fragment.java:511
This class represents the closure of a ring in a spanning tree.
Definition: Ring.java:40
A collection of AttachmentPoints that are related by a relation that we call "symmetry",...
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
int getBuildingBlockId()
Returns the index of the building block that should correspond to the position of the building block ...
Definition: Vertex.java:284
void setVertexId(long vertexId2)
Definition: Vertex.java:261
DGraph getGraphOwner()
Returns the graph this vertex belongs to or null.
Definition: Vertex.java:779
abstract List< AttachmentPoint > getAttachmentPoints()
abstract int getHeavyAtomsCount()
void setBuildingBlockType(Vertex.BBType buildingBlockType)
Definition: Vertex.java:305
abstract IAtomContainer getIAtomContainer()
boolean hasFreeAP()
Definition: Vertex.java:500
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:920
This is a tool to identify and manage vertices' connections not included in the DGraph,...
List< Ring > getRandomCombinationOfRings(IAtomContainer inMol, DGraph molGraph, int maxRingClosures)
Identifies a random combination of ring closing paths and returns it as list of DENOPTIMRings ready t...
boolean checkChelatesGraph(DGraph molGraph, List< Ring > ringsSet)
Evaluates the combination of a DENOPTIMGraph and a set of DENOPTIMRings and decides whether it's a pr...
ArrayList< List< Ring > > getPossibleCombinationOfRings(IAtomContainer mol, DGraph molGraph)
Identifies all possible ring closing paths and returns them as list of DENOPTIMRings ready to be appe...
Parameters and setting related to handling ring closures.
boolean buildChelatesMode
Flag activating procedures favoring formation of chelates.
Data structure to store and handle information about sub-structures (i.e., chains of fragments) and r...
ArrayList< ClosableChain > getCCFromTurningPointId(int tpId)
Returns the library of closable chains having the given turning point (i.e., the fragments involved i...
Utility methods for input/output.
static ArrayList< Candidate > readCandidates(File file)
Reads SDF files that represent one or more tested candidates.
static void writeGraphsToSDF(File file, List< DGraph > graphs, Logger logger, Randomizer randomizer)
Writes the graphs to SDF file.
static void writeCandidateToFile(File file, Candidate candidate, boolean append)
Writes one candidate item to file.
static void writeGraphToSDF(File file, DGraph graph, boolean append, boolean make3D, Logger logger, Randomizer randomizer)
Writes the graph to SDF file.
static ArrayList< DGraph > readDENOPTIMGraphsFromFile(File inFile)
Reads a list of <DGraphs from file.
static ArrayList< String > readList(String fileName)
Read list of data as text.
static void writeData(String fileName, String data, boolean append)
Write text-like data file.
static void writeCandidatesToFile(File file, List< Candidate > popMembers, boolean append)
Writes candidate items to file.
A collection of counters user to count actions taken by the evolutionary algorithm.
Definition: Monitor.java:37
void increase(CounterID cid)
Definition: Monitor.java:149
Tool to build build three-dimensional (3D) tree-like molecular structures from DGraph.
void setAlignBBsIn3D(boolean align)
Sets the flag that controls whether building blocks have to be aligned according to the AP vectors or...
IAtomContainer convertGraphTo3DAtomContainer(DGraph graph)
Created a three-dimensional molecular representation from a given DGraph.
boolean containsParameters(ParametersType type)
RunTimeParameters getParameters(ParametersType type)
Logger getLogger()
Get the name of the program specific logger.
Randomizer getRandomizer()
Returns the current program-specific randomizer.
Parameters for genetic algorithm.
boolean useMolSizeBasedProb
Flag recording the intention to use molecular size-controlled graph extension probability.
boolean useLevelBasedProb
Flag recording the intention to use level-controlled graph extension probability.
Parameters controlling execution of the fragmenter.
boolean embedRingsInTemplate
Flag that enables the embedding of rings in templates upon conversion of molecules into DGraph.
Toll to add/remove dummy atoms from linearities or multi-hapto sites.
static void addDummiesOnLinearities(Fragment frag, double angLim)
Append dummy atoms on otherwise linear arrangements of atoms.
static String getPaddedString(int count, int number)
returns the padded string with zeroes placed to the left of 'number' up to reach the desired number o...
Utilities for graphs.
Definition: GraphUtils.java:40
static synchronized void ensureVertexIDConsistency(long l)
Method used to ensure consistency between internal atomic integer and vertex id from imported graphs.
Definition: GraphUtils.java:55
static synchronized int getUniqueMoleculeIndex()
Unique counter for the number of molecules generated.
static synchronized int getUniqueGraphIndex()
Unique counter for the number of graphs generated.
Utilities for molecule conversion.
static String getInChIKeyForMolecule(IAtomContainer mol, Logger logger)
Generates the InChI key for the given atom container.
static String getSMILESForMolecule(IAtomContainer mol, Logger logger)
Returns the SMILES representation of the molecule.
static String getSymbolOrLabel(IAtom atm)
Gets either the elemental symbol (for standard atoms) of the label (for pseudo-atoms).
Tool to generate random numbers and random decisions.
Definition: Randomizer.java:35
public< T > T randomlyChooseOne(Collection< T > c)
Chooses one member among the given collection.
double nextDouble()
Returns the next pseudo-random, uniformly distributed double value between 0.0 and 1....
Tool box for definition and management of the rotational space, which is given by the list of rotatab...
static ArrayList< ObjectPair > defineRotatableBonds(IAtomContainer mol, String defRotBndsFile, boolean addIterfragBonds, boolean excludeRings, Logger logger)
Define the rotational space (also torsional space) for a given molecule.
Class meant to collect unique strings without leading to memory overflow.
Utilities for calculating basic statistics.
Definition: StatUtils.java:26
static double mean(double[] numbers)
Returns the mean number in the numbers list.
Definition: StatUtils.java:53
static double stddev(double[] numbers, boolean biasCorrected)
Returns the standard deviation of the numbers.
Definition: StatUtils.java:107
static double skewness(double[] m, boolean biasCorrected)
Computes the skewness of the available values.
Definition: StatUtils.java:246
static double median(double[] m)
Calculates median value of a sorted list.
Definition: StatUtils.java:172
static double min(double[] numbers)
Returns the minimum value among the numbers .
Definition: StatUtils.java:67
static double max(double[] numbers)
Returns the maximum value among the numbers .
Definition: StatUtils.java:85
Defines how to define the scaffold vertex of a graph.
A chosen method for generation of new Candidates.
Definition: EAUtils.java:119
Possible chemical bond types an edge can represent.
Definition: Edge.java:303
Enum specifying to what extent the template's inner graph can be changed.
Definition: Template.java:104
FIXED
Inner graphs are effectively equivalent to the Fragment class, as no change in the inner structure is...
Definition: Template.java:116
The type of building block.
Definition: Vertex.java:86
Identifier of a counter.
Definition: CounterID.java:29
FS_PARAMS
Parameters pertaining the definition of the fragment space.
FRG_PARAMS
Parameters controlling the fragmenter.
FIT_PARAMS
Parameters pertaining the calculation of fitness (i.e., the fitness provider).
RC_PARAMS
Parameters pertaining to ring closures in graphs.