$darkmode
DENOPTIM
FragmentSpace.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.fragspace;
21
22import java.io.File;
23import java.io.IOException;
24import java.util.ArrayList;
25import java.util.HashMap;
26import java.util.HashSet;
27import java.util.List;
28import java.util.Map;
29import java.util.Set;
30import java.util.logging.Level;
31
32import javax.vecmath.Point3d;
33
34import org.openscience.cdk.Atom;
35import org.openscience.cdk.PseudoAtom;
36import org.openscience.cdk.interfaces.IAtomContainer;
37
38import denoptim.constants.DENOPTIMConstants;
39import denoptim.exception.DENOPTIMException;
40import denoptim.files.UndetectedFileFormatException;
41import denoptim.graph.APClass;
42import denoptim.graph.APMapping;
43import denoptim.graph.AttachmentPoint;
44import denoptim.graph.Candidate;
45import denoptim.graph.DGraph;
46import denoptim.graph.Fragment;
47import denoptim.graph.GraphPattern;
48import denoptim.graph.Template;
49import denoptim.graph.Vertex;
50import denoptim.graph.Vertex.BBType;
51import denoptim.graph.rings.RingClosingAttractor;
52import denoptim.io.DenoptimIO;
53import denoptim.utils.GraphUtils;
54import denoptim.utils.MoleculeUtils;
55import denoptim.utils.Randomizer;
56
66public class FragmentSpace
67{
75 private ArrayList<Vertex> scaffoldLib = null;
76
84 private ArrayList<Vertex> fragmentLib = null;
85
94 private ArrayList<Vertex> cappingLib = null;
95
100 private HashMap<APClass, ArrayList<APClass>> apClassCompatibilityMatrix;
101
106 private ArrayList<Vertex> rcvs = new ArrayList<Vertex>();
107
112 private HashMap<APClass, ArrayList<APClass>> rcCompatMap;
113
118 private HashMap<APClass, APClass> cappingMap;
119
123 private Set<APClass> forbiddenEndList;
124
128 private HashMap<Integer, ArrayList<Integer>> fragPoolPerNumAP =
129 new HashMap<Integer,ArrayList<Integer>>();
130
134 private HashMap<Integer, ArrayList<APClass>> apClassesPerFrag =
135 new HashMap<Integer,ArrayList<APClass>>();
136
142 private HashMap<APClass, ArrayList<ArrayList<Integer>>> fragsApsPerApClass =
143 new HashMap<APClass,ArrayList<ArrayList<Integer>>>();
144
148 private final Object LOCK = new Object();
149
153 private HashMap<APClass, Double> symmConstraints;
154
158 private boolean apClassBasedApproch = false;
159
163 private boolean isValid = false;
164
170
171//------------------------------------------------------------------------------
172
180 {
181 fragmentLib = new ArrayList<Vertex>();
182 scaffoldLib = new ArrayList<Vertex>();
183 cappingLib = new ArrayList<Vertex>();
185 }
186
187//------------------------------------------------------------------------------
188
205 String fragFile, String capFile, String cpmFile)
206 throws DENOPTIMException
207 {
208 this(settings, scaffFile, fragFile, capFile, cpmFile, "",
209 new HashMap<APClass, Double>());
210 }
211
212//------------------------------------------------------------------------------
213
236 ArrayList<Vertex> scaffLib,
237 ArrayList<Vertex> fragLib,
238 ArrayList<Vertex> cappLib,
239 HashMap<APClass, ArrayList<APClass>> cpMap,
240 HashMap<APClass, APClass> capMap,
241 HashSet<APClass> forbEnds,
242 HashMap<APClass, ArrayList<APClass>> rcCpMap)
243 throws DENOPTIMException
244 {
245 define(settings, scaffLib, fragLib, cappLib, cpMap, capMap, forbEnds,
246 rcCpMap, null);
247 }
248
249//------------------------------------------------------------------------------
250
274 ArrayList<Vertex> scaffLib,
275 ArrayList<Vertex> fragLib,
276 ArrayList<Vertex> cappLib,
277 HashMap<APClass, ArrayList<APClass>> cpMap,
278 HashMap<APClass, APClass> capMap,
279 HashSet<APClass> forbEnds,
280 HashMap<APClass, ArrayList<APClass>> rcCpMap,
281 HashMap<APClass, Double> symCntrMap)
282 throws DENOPTIMException
283 {
284 define(settings, scaffLib, fragLib, cappLib, cpMap, capMap, forbEnds,
285 rcCpMap, symCntrMap);
286 }
287
288//------------------------------------------------------------------------------
289
310 String fragFile, String capFile, String cpmFile, String rcpmFile,
311 HashMap<APClass, Double> symCntrMap) throws DENOPTIMException
312 {
313 HashMap<APClass, ArrayList<APClass>> cpMap =
314 new HashMap<APClass, ArrayList<APClass>>();
315 HashMap<APClass, APClass> capMap = new HashMap<APClass, APClass>();
316 HashSet<APClass> forbEnds = new HashSet<APClass>();
317 if (cpmFile.length() > 0)
318 {
319 DenoptimIO.readCompatibilityMatrix(cpmFile, cpMap, capMap,
320 forbEnds);
321 }
322
323 HashMap<APClass, ArrayList<APClass>> rcCpMap =
324 new HashMap<APClass, ArrayList<APClass>>();
325 if (rcpmFile != null && rcpmFile.length() > 0)
326 {
327 DenoptimIO.readRCCompatibilityMatrix(rcpmFile, rcCpMap);
328 }
329
330 ArrayList<Vertex> cappLib = new ArrayList<Vertex>();
331 if (capFile.length() > 0)
332 {
333 try
334 {
335 cappLib = DenoptimIO.readVertexes(new File(capFile),
336 BBType.CAP);
337 for (int i=0; i<cappLib.size(); i++)
338 {
339 cappLib.get(i).setBuildingBlockId(i);
340 }
341 } catch (IllegalArgumentException | UndetectedFileFormatException
342 | IOException | DENOPTIMException e)
343 {
344 throw new DENOPTIMException("Cound not read library of capping "
345 + "groups from file '" + capFile + "'.", e);
346 }
347 }
348
349 ArrayList<Vertex> fragLib = new ArrayList<Vertex>();
350 if (fragFile != null && fragFile.length() > 0)
351 {
352 try
353 {
354 fragLib = DenoptimIO.readVertexes(new File(fragFile),
356 for (int i=0; i<fragLib.size(); i++)
357 {
358 fragLib.get(i).setBuildingBlockId(i);
359 }
360 } catch (IllegalArgumentException | UndetectedFileFormatException
361 | IOException | DENOPTIMException e)
362 {
363 throw new DENOPTIMException("Cound not read library of fragments "
364 + "from file '" + fragFile + "'.", e);
365 }
366 }
367
368 ArrayList<Vertex> scaffLib = new ArrayList<Vertex>();
369 if (scaffFile != null && scaffFile.length() > 0)
370 {
371 try
372 {
373 scaffLib = DenoptimIO.readVertexes(new File(scaffFile),
375 for (int i=0; i<scaffLib.size(); i++)
376 {
377 scaffLib.get(i).setBuildingBlockId(i);
378 }
379 } catch (IllegalArgumentException | UndetectedFileFormatException
380 | IOException | DENOPTIMException e)
381 {
382 throw new DENOPTIMException("Cound not read library of scaffolds "
383 + "from file '" + fragFile + "'.", e);
384 }
385 }
386
387 define(settings, scaffLib, fragLib, cappLib, cpMap, capMap, forbEnds,
388 rcCpMap, symCntrMap);
389 }
390
391//------------------------------------------------------------------------------
392
415 ArrayList<Vertex> scaffLib,
416 ArrayList<Vertex> fragLib,
417 ArrayList<Vertex> cappLib,
418 HashMap<APClass, ArrayList<APClass>> cpMap,
419 HashMap<APClass, APClass> capMap,
420 HashSet<APClass> forbEnds,
421 HashMap<APClass, ArrayList<APClass>> rcCpMap,
422 HashMap<APClass, Double> symCntrMap)
423 throws DENOPTIMException
424 {
425 this.settings = settings;
427
428 setScaffoldLibrary(scaffLib);
429 setFragmentLibrary(fragLib);
430 setCappingLibrary(cappLib);
432 apClassBasedApproch = (cpMap!=null && cpMap.size()>0)
433 || (rcCpMap!=null && rcCpMap.size()>0);
434 setCappingMap(capMap);
435 setForbiddenEndList(forbEnds);
437 setSymmConstraints(symCntrMap);
438
440
441 isValid = true;
442 }
443
444//------------------------------------------------------------------------------
445
450 public boolean isDefined()
451 {
452 return isValid;
453 }
454
455//------------------------------------------------------------------------------
456
463 {
464 return settings.getRandomizer();
465 }
466
467//------------------------------------------------------------------------------
468
472 public void setAPclassBasedApproach(boolean useAPC)
473 {
474 apClassBasedApproch = useAPC;
475 }
476
477//------------------------------------------------------------------------------
478
487 public boolean useAPclassBasedApproach()
488 {
489 return apClassBasedApproch;
490 }
491
492//------------------------------------------------------------------------------
493
502 {
503 APClass cls = null;
504 try
505 {
506 Vertex frg = this.getVertexFromLibrary(
507 apId.getVertexMolType(), apId.getVertexMolId());
508 cls = frg.getAttachmentPoints().get(apId.getApId()).getAPClass();
509 } catch (Throwable t)
510 {
511 cls = null;
512 }
513
514 return cls;
515 }
516
517//------------------------------------------------------------------------------
518
538 public Vertex getVertexFromLibrary(Vertex.BBType bbType, int bbIdx)
539 throws DENOPTIMException
540 {
541 String msg = "";
542 switch (bbType)
543 {
544 case SCAFFOLD:
545 if (scaffoldLib == null)
546 {
547 msg = "Cannot retrieve scaffolds before initialising the "
548 + "scaffold library.";
549 throw new DENOPTIMException(msg);
550 }
551 break;
552 case FRAGMENT:
553 if (fragmentLib == null)
554 {
555 msg = "Cannot retrieve fragments before initialising the "
556 + "fragment library.";
557 throw new DENOPTIMException(msg);
558 }
559 break;
560 case CAP:
561 if (cappingLib == null)
562 {
563 msg = "Cannot retrieve capping groups before initialising"
564 + "the library of capping groups.";
565 throw new DENOPTIMException(msg);
566 }
567 break;
568
569 default:
570 throw new DENOPTIMException("Cannot find building block of "
571 + "type '" + bbType + "' in the fragment space.");
572 }
573
574 Vertex originalVrtx = null;
575 switch (bbType)
576 {
577 case SCAFFOLD:
578 if (bbIdx >-1 && bbIdx < scaffoldLib.size())
579 {
580 originalVrtx = scaffoldLib.get(bbIdx);
581 }
582 else
583 {
584 msg = "Mismatch between scaffold bbIdx (" + bbIdx
585 + ") and size of the library (" + scaffoldLib.size()
586 + "). FragType: " + bbType;
587 settings.getLogger().log(Level.SEVERE, msg);
588 throw new DENOPTIMException(msg);
589 }
590 break;
591
592 case FRAGMENT:
593 if (bbIdx >-1 && bbIdx < fragmentLib.size())
594 {
595 originalVrtx = fragmentLib.get(bbIdx);
596 }
597 else
598 {
599 msg = "Mismatch between fragment bbIdx (" + bbIdx
600 + ") and size of the library (" + fragmentLib.size()
601 + "). FragType: " + bbType;
602 settings.getLogger().log(Level.SEVERE, msg);
603 throw new DENOPTIMException(msg);
604 }
605 break;
606
607 case CAP:
608 if (bbIdx >-1 && bbIdx < cappingLib.size())
609 {
610 originalVrtx = cappingLib.get(bbIdx);
611 }
612 else
613 {
614 msg = "Mismatch between capping group bbIdx " + bbIdx
615 + ") and size of the library (" + cappingLib.size()
616 + "). FragType: " + bbType;
617 settings.getLogger().log(Level.SEVERE, msg);
618 throw new DENOPTIMException(msg);
619 }
620 break;
621
622 case UNDEFINED:
623 msg = "Attempting to take UNDEFINED type of building block from "
624 + "fragment library.";
625 settings.getLogger().log(Level.WARNING, msg);
626 if (bbIdx < fragmentLib.size())
627 {
628 originalVrtx = fragmentLib.get(bbIdx);
629 }
630 else
631 {
632 msg = "Mismatch between fragment bbIdx (" + bbIdx
633 + ") and size of the library (" + fragmentLib.size()
634 + "). FragType: " + bbType;
635 settings.getLogger().log(Level.SEVERE, msg);
636 throw new DENOPTIMException(msg);
637 }
638 break;
639
640 default:
641 msg = "Unknown type of fragment '" + bbType + "'.";
642 settings.getLogger().log(Level.SEVERE, msg);
643 throw new DENOPTIMException(msg);
644 }
645 Vertex clone = originalVrtx.clone();
646
648
649 clone.setBuildingBlockId(bbIdx);
650 if (originalVrtx.getBuildingBlockId() != bbIdx)
651 {
652 settings.getLogger().log(Level.WARNING, "Mismatch between building "
653 + "block ID ("
654 + originalVrtx.getBuildingBlockId() + ") and position in "
655 + "the list of building blocks (" + bbIdx + ") for type "
656 + bbType + ".");
657 }
658 return clone;
659 }
660
661//------------------------------------------------------------------------------
662
669 public int getCappingFragment(APClass rcnCap)
670 {
671 if (rcnCap == null)
672 return -1;
673
674 ArrayList<Integer> reacFrags = getCompatibleCappingFragments(rcnCap);
675
676 int fapidx = -1;
677 if (reacFrags.size() > 0)
678 {
679 fapidx = settings.getRandomizer().randomlyChooseOne(reacFrags);
680 }
681
682 return fapidx;
683 }
684
685//------------------------------------------------------------------------------
686
693 public ArrayList<Integer> getCompatibleCappingFragments(
694 APClass cmpReac)
695 {
696 ArrayList<Integer> lstFragIdx = new ArrayList<>();
697 for (int i=0; i<cappingLib.size(); i++)
698 {
699 Vertex mol = getCappingLibrary().get(i);
700 ArrayList<APClass> lstRcn = mol.getAllAPClasses();
701 if (lstRcn.contains(cmpReac))
702 lstFragIdx.add(i);
703 }
704 return lstFragIdx;
705 }
706
707//------------------------------------------------------------------------------
708
715 {
716 int chosenIdx = settings.getRandomizer().nextInt(scaffoldLib.size());
717 Vertex scaffold = null;
718 try
719 {
720 scaffold = Vertex.newVertexFromLibrary(
721 GraphUtils.getUniqueVertexIndex(),chosenIdx,
722 BBType.SCAFFOLD, this);
723 } catch (DENOPTIMException e)
724 {
725 //This cannot happen!
726 }
727 return scaffold;
728 }
729
730//------------------------------------------------------------------------------
731
732 public ArrayList<Vertex> getScaffoldLibrary()
733 {
734 return scaffoldLib;
735 }
736
737//------------------------------------------------------------------------------
738
739 public ArrayList<Vertex> getFragmentLibrary()
740 {
741 return fragmentLib;
742 }
743
744//------------------------------------------------------------------------------
745
746 public ArrayList<Vertex> getCappingLibrary()
747 {
748 return cappingLib;
749 }
750
751//------------------------------------------------------------------------------
752
758 public ArrayList<Integer> getCappingGroupsWithAPClass(APClass capApCls)
759 {
760 ArrayList<Integer> selected = new ArrayList<>();
761 for (int i = 0; i < cappingLib.size(); i++)
762 {
763 APClass apc = cappingLib.get(i).getAP(0).getAPClass();
764 if (apc.equals(capApCls))
765 {
766 selected.add(i);
767 }
768 }
769 return selected;
770 }
771
772//------------------------------------------------------------------------------
773
782 {
783 for (int i = 0; i < cappingLib.size(); i++)
784 {
785 APClass apc = cappingLib.get(i).getAP(0).getAPClass();
786 if (apc.equals(capApCls))
787 {
788 try
789 {
791 } catch (DENOPTIMException e)
792 {
793 //This cannot happen
794 }
795 }
796 }
797 return null;
798 }
799
800//------------------------------------------------------------------------------
801
812 public void importCompatibilityMatrixFromFile(String inFile)
813 throws DENOPTIMException
814 {
815 setCompatibilityMatrix(new HashMap<APClass, ArrayList<APClass>>());
816 setCappingMap(new HashMap<APClass, APClass>());
817 setForbiddenEndList(new HashSet<APClass>());
820 }
821
822//------------------------------------------------------------------------------
823
831 public void importRCCompatibilityMatrixFromFile(String inFile)
832 throws DENOPTIMException
833 {
834 setRCCompatibilityMatrix(new HashMap<APClass, ArrayList<APClass>>());
836 }
837
838//------------------------------------------------------------------------------
839
840 public HashMap<APClass, ArrayList<APClass>> getCompatibilityMatrix()
841 {
843 }
844
845//------------------------------------------------------------------------------
846
853 public ArrayList<APClass> getCompatibleAPClasses(APClass apc)
854 {
855 if (apClassCompatibilityMatrix!= null && apClassCompatibilityMatrix.containsKey(apc))
856 {
857 return apClassCompatibilityMatrix.get(apc);
858 }
859 return new ArrayList<APClass>();
860 }
861
862//------------------------------------------------------------------------------
863
871 public HashMap<APClass, ArrayList<APClass>> getRCCompatibilityMatrix()
872 {
873 return rcCompatMap;
874 }
875
876//------------------------------------------------------------------------------
877
878 public HashMap<APClass, APClass> getCappingMap()
879 {
880 return cappingMap;
881 }
882
883//------------------------------------------------------------------------------
884
892 {
893 return cappingMap.get(srcApClass);
894 }
895
896//------------------------------------------------------------------------------
897
898 public Set<APClass> getForbiddenEndList()
899 {
900 return forbiddenEndList;
901 }
902
903//------------------------------------------------------------------------------
904
914 public Set<APClass> getAllAPClassesFromCPMap()
915 {
916 return apClassCompatibilityMatrix.keySet();
917 }
918
919//------------------------------------------------------------------------------
920
921 public HashMap<Integer, ArrayList<Integer>> getMapOfFragsPerNumAps()
922 {
923 return fragPoolPerNumAP;
924 }
925
926//------------------------------------------------------------------------------
927
935 public ArrayList<Integer> getFragsWithNumAps(int nAps)
936 {
937 ArrayList<Integer> lst = new ArrayList<>();
938 if (fragPoolPerNumAP.containsKey(nAps))
939 {
940 lst = fragPoolPerNumAP.get(nAps);
941 }
942 return lst;
943 }
944
945//------------------------------------------------------------------------------
946
954 public ArrayList<APClass> getAPClassesPerFragment(int fragId)
955 {
956 synchronized (LOCK)
957 {
958 return apClassesPerFrag.get(fragId);
959 }
960 }
961
962//------------------------------------------------------------------------------
963
974 public ArrayList<IdFragmentAndAP> getFragsWithAPClass(APClass apc)
975 {
976 ArrayList<IdFragmentAndAP> lst = new ArrayList<IdFragmentAndAP>();
977
978 synchronized (LOCK)
979 {
980 if (fragsApsPerApClass.containsKey(apc))
981 {
982 for (ArrayList<Integer> idxs : fragsApsPerApClass.get(apc))
983 {
984 IdFragmentAndAP apId = new IdFragmentAndAP(-1, // vertexId
985 idxs.get(0), // MolId,
986 BBType.FRAGMENT, idxs.get(1), // ApId
987 -1, // noVSym
988 -1);// noAPSym
989 lst.add(apId);
990 }
991 }
992 }
993 return lst;
994 }
995
996//------------------------------------------------------------------------------
997
1004 public ArrayList<Vertex> getVerticesWithAPClass(APClass apc)
1005 {
1006 ArrayList<Vertex> lst = new ArrayList<Vertex>();
1007
1008 synchronized (LOCK)
1009 {
1010 if (fragsApsPerApClass.containsKey(apc))
1011 {
1012 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1013 {
1014 Vertex v = fragmentLib.get(idxs.get(0));
1015 lst.add(v);
1016 }
1017 }
1018 }
1019 return lst;
1020 }
1021
1022//------------------------------------------------------------------------------
1023
1031 public List<Vertex> getVerticesWithAPClasses(Set<APClass> apcs)
1032 {
1033 List<Vertex> lst = new ArrayList<Vertex>();
1034
1035 synchronized (LOCK)
1036 {
1037 for (APClass apc : apcs)
1038 {
1039 if (!fragsApsPerApClass.containsKey(apc))
1040 {
1041 break;
1042 }
1043
1044 // NB: the list is over APs, so there can be duplicate vertexes
1045 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1046 {
1047 Vertex v = fragmentLib.get(idxs.get(0));
1048 if (!lst.contains(v) && v.getAllAPClasses().containsAll(apcs))
1049 lst.add(v);
1050 }
1051
1052 // NB: we mean to do only one loop
1053 break;
1054 }
1055 }
1056 return lst;
1057 }
1058
1059//------------------------------------------------------------------------------
1060
1069 public List<Vertex> getVerticesWithAPFingerprint(
1070 Map<APClass,Integer> apcCounts)
1071 {
1072 List<Vertex> matches = new ArrayList<Vertex>();
1073 for (Vertex candidate : getVerticesWithAPClasses(apcCounts.keySet()))
1074 {
1075 boolean isMatch = true;
1076 for (APClass apc : apcCounts.keySet())
1077 {
1078 if (apcCounts.get(apc) >
1079 candidate.getAttachmentPoints().stream().filter(
1080 ap -> ap.getAPClass().equals(apc)).count())
1081 {
1082 isMatch = false;
1083 break;
1084 }
1085 }
1086 if (isMatch)
1087 matches.add(candidate);
1088 }
1089 return matches;
1090 }
1091
1092//------------------------------------------------------------------------------
1093
1102 public List<Vertex> getVerticesWithAPClassStartingWith(String root)
1103 {
1104 List<Vertex> lst = new ArrayList<Vertex>();
1105 synchronized (LOCK)
1106 {
1107 for (APClass apc : fragsApsPerApClass.keySet())
1108 {
1109 if (!apc.toString().startsWith(root))
1110 continue;
1111 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1112 {
1113 Vertex v = fragmentLib.get(idxs.get(0));
1114 if (!lst.contains(v))
1115 lst.add(v);
1116 }
1117 }
1118 }
1119 return lst;
1120 }
1121
1122//------------------------------------------------------------------------------
1123
1132 public ArrayList<Vertex> getFragmentsCompatibleWithTheseAPs(
1133 ArrayList<IdFragmentAndAP> srcAPs)
1134 {
1135 // First we get all possible APs on any fragment
1136 ArrayList<IdFragmentAndAP> compatFragAps =
1138
1139 // then keep unique fragment identifiers, and store unique
1140 Set<Integer> compatFragIds = new HashSet<Integer>();
1141 for (IdFragmentAndAP apId : compatFragAps)
1142 {
1143 compatFragIds.add(apId.getVertexMolId());
1144 }
1145
1146 // Then we pack-up the selected list of fragments
1147 ArrayList<Vertex> compatFrags = new ArrayList<Vertex>();
1148 for (Integer fid : compatFragIds)
1149 {
1150 try {
1151 compatFrags.add(getVertexFromLibrary(BBType.FRAGMENT, fid));
1152 } catch (DENOPTIMException e) {
1153 settings.getLogger().log(Level.WARNING, "Exception while trying "
1154 + "to get fragment '" + fid + "'!");
1155 e.printStackTrace();
1156 }
1157 }
1158 return compatFrags;
1159 }
1160
1161//------------------------------------------------------------------------------
1162
1171 public List<Vertex> getRCVsWithAPClass(APClass apc)
1172 {
1173 List<Vertex> chosenRCVs = new ArrayList<Vertex>();
1174 for (Vertex rcv : getRCVs())
1175 {
1176 // NB: RCVs must have only one attachment point
1177 if (apc.equals(rcv.getAP(0).getAPClass()))
1178 {
1179 Vertex copyOfRCV = null;
1180 try
1181 {
1182 copyOfRCV = getVertexFromLibrary(rcv.getBuildingBlockType(),
1183 rcv.getBuildingBlockId());
1184 chosenRCVs.add(copyOfRCV);
1185 } catch (DENOPTIMException e)
1186 {
1187 // This should never happen because we have already taken
1188 // the BB from BBSpace.
1189 e.printStackTrace();
1190 }
1191 }
1192 }
1193 return chosenRCVs;
1194 }
1195
1196//------------------------------------------------------------------------------
1197
1206 public List<Vertex> getRCVsForAPClass(APClass apc)
1207 {
1208 List<Vertex> chosenRCVs = new ArrayList<Vertex>();
1209 if (!getCompatibilityMatrix().containsKey(apc))
1210 {
1211 return chosenRCVs;
1212 }
1213 List<APClass> apcsCompatWithSrcAP = getCompatibilityMatrix().get(apc);
1214 for (Vertex rcv : getRCVs())
1215 {
1216 // NB: RCVs must have only one attachment point
1217 if (apcsCompatWithSrcAP.contains(rcv.getAP(0).getAPClass()))
1218 {
1219 Vertex copyOfRCV = null;
1220 try
1221 {
1222 copyOfRCV = getVertexFromLibrary(rcv.getBuildingBlockType(),
1223 rcv.getBuildingBlockId());
1224 chosenRCVs.add(copyOfRCV);
1225 } catch (DENOPTIMException e)
1226 {
1227 // This should never happen because we have already taken
1228 // the BB from BBSpace.
1229 e.printStackTrace();
1230 }
1231 }
1232 }
1233 return chosenRCVs;
1234 }
1235
1236//------------------------------------------------------------------------------
1237
1246 public ArrayList<AttachmentPoint> getAPsCompatibleWithThese(
1247 ArrayList<AttachmentPoint> srcAPs)
1248 {
1249 ArrayList<AttachmentPoint> compAps =
1250 new ArrayList<AttachmentPoint>();
1251 boolean first = true;
1252 for (AttachmentPoint ap : srcAPs)
1253 {
1254 ArrayList<AttachmentPoint> compForOne =
1255 getAPsCompatibleWithClass(ap.getAPClass());
1256
1257 if (first)
1258 {
1259 compAps.addAll(compForOne);
1260 first = false;
1261 continue;
1262 }
1263
1264 ArrayList<AttachmentPoint> toKeep =
1265 new ArrayList<AttachmentPoint>();
1266 for (AttachmentPoint candAp : compAps)
1267 {
1268 for (AttachmentPoint newCand : compForOne)
1269 {
1270 if (newCand == candAp)
1271 {
1272 toKeep.add(candAp);
1273 break;
1274 }
1275 }
1276 }
1277
1278 compAps = toKeep;
1279
1280 if (compAps.size()==0)
1281 {
1282 break;
1283 }
1284 }
1285 return compAps;
1286 }
1287
1288//------------------------------------------------------------------------------
1289
1297 public ArrayList<IdFragmentAndAP> getFragAPsCompatibleWithTheseAPs(
1298 ArrayList<IdFragmentAndAP> srcAPs)
1299 {
1300 ArrayList<IdFragmentAndAP> compFrAps = new ArrayList<IdFragmentAndAP>();
1301 boolean first = true;
1302 for (IdFragmentAndAP apId : srcAPs)
1303 {
1304 APClass srcApCls = getAPClassForFragment(apId);
1305 ArrayList<IdFragmentAndAP> compForOne =
1307
1308 if (first)
1309 {
1310 compFrAps.addAll(compForOne);
1311 first = false;
1312 continue;
1313 }
1314
1315 ArrayList<IdFragmentAndAP> toKeep =
1316 new ArrayList<IdFragmentAndAP>();
1317 for (IdFragmentAndAP candAp : compFrAps)
1318 {
1319 for (IdFragmentAndAP newId : compForOne)
1320 {
1321 if (newId.sameFragAndAp(candAp))
1322 {
1323 toKeep.add(candAp);
1324 break;
1325 }
1326 }
1327 }
1328
1329 compFrAps = toKeep;
1330
1331 if (compFrAps.size() == 0)
1332 {
1333 break;
1334 }
1335 }
1336
1337 return compFrAps;
1338 }
1339
1340//------------------------------------------------------------------------------
1341
1350 public ArrayList<AttachmentPoint> getAPsCompatibleWithClass(
1351 APClass aPC1)
1352 {
1353 ArrayList<AttachmentPoint> compatAps =
1354 new ArrayList<AttachmentPoint>();
1355
1356 // Take the compatible AP classes
1357 ArrayList<APClass> compatApClasses = getCompatibleAPClasses(aPC1);
1358
1359 // Find all APs with a compatible class
1360 if (compatApClasses != null)
1361 {
1362 for (APClass klass : compatApClasses)
1363 {
1364 ArrayList<Vertex> vrtxs = getVerticesWithAPClass(klass);
1365 for (Vertex v : vrtxs)
1366 {
1367 for (AttachmentPoint ap : v.getAttachmentPoints())
1368 {
1369 if (ap.getAPClass() == klass)
1370 {
1371 compatAps.add(ap);
1372 }
1373 }
1374 }
1375 }
1376 }
1377
1378 if (compatAps.size()==0)
1379 {
1380 settings.getLogger().log(Level.WARNING,"No compatible "
1381 + "AP found in the fragment space for APClass '"
1382 + aPC1 + "'.");
1383 }
1384
1385 return compatAps;
1386 }
1387
1388//------------------------------------------------------------------------------
1389
1397 public ArrayList<IdFragmentAndAP> getFragAPsCompatibleWithClass(
1398 APClass aPC1)
1399 {
1400 ArrayList<IdFragmentAndAP> compatFragAps =
1401 new ArrayList<IdFragmentAndAP>();
1402
1403 // Take the compatible AP classes
1404 ArrayList<APClass> compatApClasses = getCompatibleAPClasses(aPC1);
1405
1406 // Find all APs with any compatible class
1407 if (compatApClasses != null)
1408 {
1409 for (APClass compClass : compatApClasses)
1410 {
1411 compatFragAps.addAll(getFragsWithAPClass(compClass));
1412 }
1413 }
1414 return compatFragAps;
1415 }
1416
1417//------------------------------------------------------------------------------
1418
1430 public boolean imposeSymmetryOnAPsOfClass(APClass apClass)
1431 {
1432 boolean res = true;
1433 if (hasSymmetryConstrain(apClass))
1434 {
1435 if (getSymmetryConstrain(apClass) < (1.0
1437 {
1438 res = false;
1439 }
1440 } else
1441 {
1443 {
1444 res = false;
1445 }
1446 }
1447 return res;
1448 }
1449
1450//------------------------------------------------------------------------------
1451
1461 public boolean hasSymmetryConstrain(APClass apClass)
1462 {
1463 if (symmConstraints==null)
1464 return false;
1465 return symmConstraints.containsKey(apClass);
1466 }
1467
1468//------------------------------------------------------------------------------
1469
1480 public double getSymmetryConstrain(APClass apClass)
1481 {
1482 return symmConstraints.get(apClass);
1483 }
1484
1485//------------------------------------------------------------------------------
1486
1487 public void setScaffoldLibrary(ArrayList<Vertex> lib)
1488 {
1489 scaffoldLib = new ArrayList<Vertex>();
1491 }
1492
1493 public void setFragmentLibrary(ArrayList<Vertex> lib)
1494 {
1495 fragmentLib = new ArrayList<Vertex>();
1497 }
1498
1499//------------------------------------------------------------------------------
1500
1501 public void setCappingLibrary(ArrayList<Vertex> lib)
1502 {
1503 cappingLib = new ArrayList<Vertex>();
1505 }
1506
1507//------------------------------------------------------------------------------
1508
1509 public void setCompatibilityMatrix(HashMap<APClass, ArrayList<APClass>> map)
1510 {
1512 }
1513
1514//------------------------------------------------------------------------------
1515
1516 public void setRCCompatibilityMatrix(HashMap<APClass,
1517 ArrayList<APClass>> map)
1518 {
1519 rcCompatMap = map;
1520 }
1521
1522//------------------------------------------------------------------------------
1523
1524 public void setCappingMap(HashMap<APClass, APClass> map)
1525 {
1526 cappingMap = map;
1527 }
1528
1529//------------------------------------------------------------------------------
1530
1531 public void setForbiddenEndList(Set<APClass> lst)
1532 {
1533 forbiddenEndList = lst;
1534 }
1535
1536//------------------------------------------------------------------------------
1537
1538 public void setSymmConstraints(HashMap<APClass, Double> map)
1539 {
1540 symmConstraints = map;
1541 }
1542
1543//------------------------------------------------------------------------------
1544
1549 public void clearAll()
1550 {
1551 scaffoldLib = null;
1552 fragmentLib = null;
1553 cappingLib = null;
1555 rcCompatMap = null;
1556 cappingMap = null;
1557 forbiddenEndList = null;
1558 fragPoolPerNumAP = new HashMap<Integer,ArrayList<Integer>>();
1559 apClassesPerFrag = new HashMap<Integer,ArrayList<APClass>>();
1560 fragsApsPerApClass = new HashMap<APClass,ArrayList<ArrayList<Integer>>>();
1561 symmConstraints = null;
1562 isValid = false;
1563 }
1564
1565//------------------------------------------------------------------------------
1566
1576 public void appendVerticesToLibrary(ArrayList<Vertex> list,
1577 Vertex.BBType bbt, ArrayList<Vertex> library)
1578 {
1579 for (Vertex v : list)
1580 {
1581 appendVertexToLibrary(v, bbt, library);
1582 }
1583 }
1584
1585//------------------------------------------------------------------------------
1586
1597 Vertex.BBType bbt, ArrayList<Vertex> library)
1598 {
1599 v.setBuildingBlockId(library.size());
1600 v.setBuildingBlockType(bbt);
1601 library.add(v);
1602 if (bbt == BBType.FRAGMENT)
1603 {
1604 classifyFragment(v, library.size()-1);
1605 }
1606 }
1607
1608//------------------------------------------------------------------------------
1609
1621 //TODO: need something to prevent memory overload:
1622 // -> keep only some templates?
1623 // -> remove those who did not lead to good population members?
1624 // -> remove redundant? The highest-simmetry principle (i.e., rather than
1625 // keeping a template as it is, we'd like to keep its highest symmetry
1626 // isomorphic) would be the first thing to do.
1627
1629 {
1630 addFusedRingsToFragmentLibrary(graph,true,true);
1631 }
1632
1633//------------------------------------------------------------------------------
1634
1648 boolean addIfScaffold, boolean addIfFragment)
1649 {
1650 addFusedRingsToFragmentLibrary(graph, addIfScaffold, addIfFragment, null);
1651 }
1652
1653//------------------------------------------------------------------------------
1654
1673 //TODO: need something to prevent memory overload:
1674 // -> keep only some templates?
1675 // -> remove those who did not lead to good population members?
1676 // -> remove redundant? The highest-symmetry principle (i.e., rather than
1677 // keeping a template as it is, we'd like to keep its highest symmetry
1678 // isomorphic) would be the first thing to do.
1679
1681 boolean addIfScaffold, boolean addIfFragment,
1682 IAtomContainer wholeMol)
1683 {
1684 List<DGraph> subgraphs = null;
1685 try
1686 {
1687 subgraphs = graph.extractPattern(GraphPattern.RING);
1688 } catch (DENOPTIMException e1)
1689 {
1690 settings.getLogger().log(Level.WARNING,"Failed to extract "
1691 + "fused ring patters.");
1692 e1.printStackTrace();
1693 }
1694
1695 for (DGraph g : subgraphs)
1696 {
1697 BBType type = g.hasScaffoldTypeVertex() ?
1698 BBType.SCAFFOLD :
1700
1701 if (!addIfFragment && type == BBType.FRAGMENT)
1702 {
1703 continue;
1704 }
1705 if (!addIfScaffold && type == BBType.SCAFFOLD)
1706 {
1707 continue;
1708 }
1709
1710 ArrayList<Vertex> library = type == BBType.FRAGMENT ?
1712
1713 synchronized (LOCK)
1714 {
1715 if (!hasIsomorph(g, type))
1716 {
1717 //TODO: try to transform the template into its isomorphic
1718 // with highest symmetry, and define the symmetric sets.
1719 // Such enhancement would facilitate the creation of
1720 // symmetric graphs from templates generated on the fly.
1721
1722 Template t = new Template(type);
1723 t.setInnerGraph(g);
1724
1725 boolean has3Dgeometry = false;
1726 IAtomContainer subIAC = null;
1727 if (wholeMol!=null)
1728 {
1729 try
1730 {
1732 wholeMol, g, graph, settings.getLogger(),
1734 t.setIAtomContainer(subIAC,true);
1735 has3Dgeometry = true;
1736 } catch (DENOPTIMException e1)
1737 {
1738 e1.printStackTrace();
1739 ArrayList<DGraph> lst = new ArrayList<>();
1740 lst.add(graph);
1741 lst.add(g);
1742 String forDebugFile = "failedExtractIAC_"
1743 + graph.getGraphId() + ".json";
1744 try
1745 {
1747 new File(forDebugFile), lst);
1748 settings.getLogger().log(Level.WARNING,
1749 "WARNING: failed to extract "
1750 + "molecular representation of graph. "
1751 + "See file '" + forDebugFile + "'.");
1752 } catch (DENOPTIMException e)
1753 {
1754 settings.getLogger().log(Level.WARNING,
1755 "WARNING: failed to extract "
1756 + "molecular representation of graph, "
1757 + "and failed to write graph to file.");
1758 }
1759 }
1760 }
1761
1762 String msg = "Adding new template (Inner Graph id: "
1763 + t.getInnerGraph().getGraphId() + ") to the "
1764 + "library of " + type + "s. The template is "
1765 + "generated from graph " + graph.getGraphId();
1766 Candidate source = graph.getCandidateOwner();
1767 if (source != null)
1768 msg = msg + " candidate " + source.getName();
1769 else
1770 msg = msg + ".";
1771 settings.getLogger().log(Level.INFO, msg);
1772
1773 appendVertexToLibrary(t, type, library);
1774 if (type == BBType.FRAGMENT)
1775 {
1776 classifyFragment(t,library.size()-1);
1777 }
1778
1779 String destFileName = type == BBType.FRAGMENT ?
1782 try
1783 {
1784 if (has3Dgeometry)
1785 {
1786 DenoptimIO.writeSDFFile(destFileName,subIAC,true);
1787 } else {
1788 DenoptimIO.writeGraphToSDF(new File(destFileName),
1789 g, true, false, settings.getLogger(),
1791 }
1792 } catch (DENOPTIMException e)
1793 {
1794 e.printStackTrace();
1795 settings.getLogger().log(Level.WARNING, "WARNING: "
1796 + "failed to write newly "
1797 + "generated " + type + " to file '"
1798 + destFileName + "'.");
1799 }
1800 }
1801 }
1802 }
1803 }
1804
1805//------------------------------------------------------------------------------
1806
1816 public boolean hasIsomorph(DGraph graph, BBType type) {
1817 return (type == BBType.SCAFFOLD ? scaffoldLib : fragmentLib)
1818 .stream()
1819 .filter(v -> v instanceof Template)
1820 .map(t -> (Template) t)
1822 .anyMatch(graph::isIsomorphicTo);
1823 }
1824
1825//------------------------------------------------------------------------------
1826
1832 public void registerRCV(Vertex v)
1833 {
1834 rcvs.add(v);
1835 }
1836
1837//------------------------------------------------------------------------------
1838
1843 public ArrayList<Vertex> getRCVs()
1844 {
1845 return rcvs;
1846 }
1847
1848//------------------------------------------------------------------------------
1849
1860 public List<APMapping> mapAPClassCompatibilities(
1861 List<AttachmentPoint> listA,
1862 List<AttachmentPoint> listB, int maxCombinations)
1863 {
1864 Map<AttachmentPoint,List<AttachmentPoint>> apCompatilities =
1865 new HashMap<AttachmentPoint,List<AttachmentPoint>>();
1866
1867 for (AttachmentPoint apA : listA)
1868 {
1869 for (AttachmentPoint apB : listB)
1870 {
1871 boolean compatible = false;
1873 {
1874 if (apA.getAPClass().isCPMapCompatibleWith(apB.getAPClass(),
1875 this))
1876 {
1877 compatible = true;
1878 }
1879 } else {
1880 compatible = true;
1881 }
1882 if (compatible)
1883 {
1884 if (apCompatilities.containsKey(apA))
1885 {
1886 apCompatilities.get(apA).add(apB);
1887 } else {
1888 List<AttachmentPoint> lst =
1889 new ArrayList<AttachmentPoint>();
1890 lst.add(apB);
1891 apCompatilities.put(apA,lst);
1892 }
1893 }
1894 }
1895 }
1896
1897 // This is used only to keep a sorted list of the map keys
1898 List<AttachmentPoint> keys =
1899 new ArrayList<AttachmentPoint>(
1900 apCompatilities.keySet());
1901
1902 // Get all possible combinations of compatible AP pairs
1903 List<APMapping> apMappings = new ArrayList<APMapping>();
1904 if (keys.size() > 0)
1905 {
1906 int currentKey = 0;
1907 APMapping currentMapping = new APMapping();
1908 FragmentSpaceUtils.recursiveCombiner(keys, currentKey,
1909 apCompatilities, currentMapping, apMappings, true,
1910 maxCombinations);
1911 }
1912
1913 return apMappings;
1914 }
1915
1916//------------------------------------------------------------------------------
1917
1926 public void classifyFragment(Vertex frg, int fragId)
1927 {
1928 // Classify according to number of APs
1929 int nAps = frg.getFreeAPCount();
1930 if (nAps != 0)
1931 {
1932 if (getMapOfFragsPerNumAps().containsKey(nAps))
1933 {
1934 getFragsWithNumAps(nAps).add(fragId);
1935 }
1936 else
1937 {
1938 ArrayList<Integer> lst = new ArrayList<>();
1939 lst.add(fragId);
1940 getMapOfFragsPerNumAps().put(nAps,lst);
1941 }
1942 }
1943
1945 {
1946 // Collect classes per fragment
1947 ArrayList<APClass> lstAPC = frg.getAllAPClasses();
1948 synchronized (LOCK)
1949 {
1950 apClassesPerFrag.put(fragId,lstAPC);
1951 }
1952
1953 // Classify according to AP-Classes
1954 List<AttachmentPoint> lstAPs = frg.getAttachmentPoints();
1955
1956 for (int j=0; j<lstAPs.size(); j++)
1957 {
1958 AttachmentPoint ap = lstAPs.get(j);
1959 ArrayList<Integer> apId = new ArrayList<Integer>();
1960 apId.add(fragId);
1961 apId.add(j);
1962 APClass cls = ap.getAPClass();
1963
1964 if (!ap.isAvailable())
1965 {
1966 continue;
1967 }
1968
1969 synchronized (LOCK)
1970 {
1971 if (fragsApsPerApClass.containsKey(cls))
1972 {
1973 fragsApsPerApClass.get(cls).add(apId);
1974 } else {
1975 ArrayList<ArrayList<Integer>> outLst =
1976 new ArrayList<ArrayList<Integer>>();
1977 outLst.add(apId);
1978 fragsApsPerApClass.put(cls,outLst);
1979 }
1980 }
1981 }
1982
1983 if (frg.isRCV())
1984 registerRCV(frg);
1985 }
1986 }
1987
1988//------------------------------------------------------------------------------
1989
1997 throws DENOPTIMException
1998 {
1999 for (int j=0; j<getFragmentLibrary().size(); j++)
2000 {
2001 Vertex frag = getFragmentLibrary().get(j);
2002 classifyFragment(frag,j);
2003 }
2004 }
2005
2006//------------------------------------------------------------------------------
2007
2016 public static Vertex getPolarizedRCV(boolean polarity)
2017 {
2019 if (!polarity)
2020 apc = APClass.RCACLASSMINUS;
2021
2022 Fragment rcv = new Fragment();
2023 Atom atom = new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(apc),
2024 new Point3d());
2025 rcv.addAtom(atom);
2026 rcv.addAP(0, new Point3d(1.5, 0.0, 0.0), apc);
2027 rcv.setAsRCV(true);
2028 return rcv;
2029 }
2030
2031//------------------------------------------------------------------------------
2032
2033}
General set of constants used in DENOPTIM.
static final double FLOATCOMPARISONTOLERANCE
Smallest difference for comparison of double and float numbers.
Exception thrown when the format of a file is not recognized.
Class defining a space of building blocks.
HashMap< APClass, ArrayList< APClass > > getCompatibilityMatrix()
ArrayList< Vertex > getFragmentsCompatibleWithTheseAPs(ArrayList< IdFragmentAndAP > srcAPs)
Searches for all building blocks that are compatible with the given list of APs.
boolean hasSymmetryConstrain(APClass apClass)
Checks if there is a constraint on the constitutional symmetry probability for the given AP class.
ArrayList< APClass > getAPClassesPerFragment(int fragId)
Returns the APclasses associated with a given fragment.
List< APMapping > mapAPClassCompatibilities(List< AttachmentPoint > listA, List< AttachmentPoint > listB, int maxCombinations)
Given two lists of APs this method maps the APClass-compatibilities from between the two lists consid...
void addFusedRingsToFragmentLibrary(DGraph graph, boolean addIfScaffold, boolean addIfFragment)
Extracts a system of one or more fused rings and adds them to the fragment space if not already prese...
void classifyFragment(Vertex frg, int fragId)
Classify a fragment in terms of the number of APs and possibly their type (AP-Class).
void registerRCV(Vertex v)
Adds the reference to a ring-closing vertex (RCV) to the quick-access list of RCVs known in this buil...
HashMap< APClass, APClass > cappingMap
Data structure that stores the AP-classes to be used to cap unused APS on the growing molecule.
boolean apClassBasedApproch
Flag defining use of AP class-based approach.
double getSymmetryConstrain(APClass apClass)
Return the constitutional symmetry constrain for the given APclass, or null.
FragmentSpace(FragmentSpaceParameters settings, ArrayList< Vertex > scaffLib, ArrayList< Vertex > fragLib, ArrayList< Vertex > cappLib, HashMap< APClass, ArrayList< APClass > > cpMap, HashMap< APClass, APClass > capMap, HashSet< APClass > forbEnds, HashMap< APClass, ArrayList< APClass > > rcCpMap, HashMap< APClass, Double > symCntrMap)
Define all components of a fragment space that implements the attachment point class-approach.
void setScaffoldLibrary(ArrayList< Vertex > lib)
void appendVertexToLibrary(Vertex v, Vertex.BBType bbt, ArrayList< Vertex > library)
Takes a vertex and add it to a given library.
ArrayList< IdFragmentAndAP > getFragAPsCompatibleWithTheseAPs(ArrayList< IdFragmentAndAP > srcAPs)
Searches for all APs that are compatible with the given list of APs.
void setCompatibilityMatrix(HashMap< APClass, ArrayList< APClass > > map)
FragmentSpaceParameters settings
Settings used to configure this fragment space.
void addFusedRingsToFragmentLibrary(DGraph graph, boolean addIfScaffold, boolean addIfFragment, IAtomContainer wholeMol)
Extracts a system of one or more fused rings and adds them to the fragment space if not already prese...
HashMap< APClass, ArrayList< APClass > > rcCompatMap
Data structure that stores compatible APclasses for joining APs in ring-closing bonds.
boolean isValid
Flag signaling that this fragment space was built and validated.
HashMap< Integer, ArrayList< Integer > > getMapOfFragsPerNumAps()
Randomizer getRandomizer()
Returns the program-specific randomizer that is associated with this program-specific fragment space.
void importRCCompatibilityMatrixFromFile(String inFile)
Load info for ring closures compatibilities from a compatibility matrix file.
ArrayList< AttachmentPoint > getAPsCompatibleWithClass(APClass aPC1)
Returns the list of attachment points found in the fragment space and that are compatible with a give...
FragmentSpace(FragmentSpaceParameters settings, String scaffFile, String fragFile, String capFile, String cpmFile, String rcpmFile, HashMap< APClass, Double > symCntrMap)
Define all components of a fragment space that implements the attachment point class-approach.
APClass getAPClassForFragment(IdFragmentAndAP apId)
Search for a specific AP on a specific fragment and finds out its class.
void define(FragmentSpaceParameters settings, ArrayList< Vertex > scaffLib, ArrayList< Vertex > fragLib, ArrayList< Vertex > cappLib, HashMap< APClass, ArrayList< APClass > > cpMap, HashMap< APClass, APClass > capMap, HashSet< APClass > forbEnds, HashMap< APClass, ArrayList< APClass > > rcCpMap, HashMap< APClass, Double > symCntrMap)
Define all components of this fragment space.
boolean useAPclassBasedApproach()
Check usage of APClass-based approach, i.e., uses attachment points with annotated data (i....
boolean isDefined()
Checks for valid definition of this fragment space.
Vertex getVertexFromLibrary(Vertex.BBType bbType, int bbIdx)
Returns a clone of the requested building block.
void importCompatibilityMatrixFromFile(String inFile)
Load info from a compatibility matrix file.
ArrayList< Vertex > cappingLib
Data structure containing the molecular representation of building blocks: capping group section - fr...
void setAPclassBasedApproach(boolean useAPC)
Set the fragment space to behave according to APClass-based approach.
ArrayList< IdFragmentAndAP > getFragsWithAPClass(APClass apc)
Returns the list of attachment points with the given class.
ArrayList< Integer > getCappingGroupsWithAPClass(APClass capApCls)
ArrayList< AttachmentPoint > getAPsCompatibleWithThese(ArrayList< AttachmentPoint > srcAPs)
Searches for all attachment points that are compatible with the given list of attachment points.
final Object LOCK
Lock for synchronizing tasks.
void groupAndClassifyFragments(boolean apClassBasedApproch)
Performs grouping and classification operations on the library of building blocks of BBType#FRAGMENT.
void appendVerticesToLibrary(ArrayList< Vertex > list, Vertex.BBType bbt, ArrayList< Vertex > library)
Takes a list of vertices and add them to a given library.
void clearAll()
Clears all settings of this fragment space.
HashMap< APClass, ArrayList< ArrayList< Integer > > > fragsApsPerApClass
Clusters of fragments'AP based on AP classes.
void setForbiddenEndList(Set< APClass > lst)
void setFragmentLibrary(ArrayList< Vertex > lib)
APClass getAPClassOfCappingVertex(APClass srcApClass)
List< Vertex > getVerticesWithAPClassStartingWith(String root)
Extracts vertexes from the collection of vertexes defined by this FragmentSpace.
ArrayList< Vertex > scaffoldLib
Data structure containing the molecular representation of building blocks: scaffolds section - fragme...
HashMap< APClass, ArrayList< APClass > > getRCCompatibilityMatrix()
Returns the compatibility matrix for ring closing fragment-fragment connections or null if not provid...
HashMap< APClass, ArrayList< APClass > > apClassCompatibilityMatrix
Data structure that stored the true entries of the attachment point classes compatibility matrix.
HashMap< Integer, ArrayList< APClass > > apClassesPerFrag
List of APClasses per each fragment.
HashMap< APClass, Double > symmConstraints
APclass-specific constraints to constitutional symmetry.
static Vertex getPolarizedRCV(boolean polarity)
Returns a newly-built vertex that can play the role of a ring-closing vertex even when working with 3...
ArrayList< Integer > getCompatibleCappingFragments(APClass cmpReac)
Retrieve a list of compatible capping groups.
void setCappingMap(HashMap< APClass, APClass > map)
Vertex makeRandomScaffold()
Randomly select a scaffold and return a fully configured clone of it.
ArrayList< Vertex > getRCVs()
Returns the list of registered ring-closing vertexes (RCVs).
boolean imposeSymmetryOnAPsOfClass(APClass apClass)
Checks if the symmetry settings impose use of symmetry on attachment points of the given AP class.
List< Vertex > getRCVsWithAPClass(APClass apc)
Searches for all building blocks that are ring-closing vertexes and hold an AP with the given class.
Set< APClass > getAllAPClassesFromCPMap()
Return the set of APClasses that used in the compatibility matrix for the growing graph APs.
boolean hasIsomorph(DGraph graph, BBType type)
Checks if a graph is isomorphic to another template's inner graph in its appropriate fragment space l...
Set< APClass > forbiddenEndList
Data structure that stores AP classes that cannot be held unused.
FragmentSpace(FragmentSpaceParameters settings, String scaffFile, String fragFile, String capFile, String cpmFile)
Define all components of a fragment space that implements the attachment point class-approach.
ArrayList< IdFragmentAndAP > getFragAPsCompatibleWithClass(APClass aPC1)
Returns the list of attachment points found in the fragment space and that are compatible with a give...
Vertex getCappingVertexWithAPClass(APClass capApCls)
void setCappingLibrary(ArrayList< Vertex > lib)
HashMap< Integer, ArrayList< Integer > > fragPoolPerNumAP
Clusters of fragments based on the number of APs.
ArrayList< Vertex > getCappingLibrary()
ArrayList< Vertex > rcvs
Store references to the Ring-Closing Vertexes found in the library of fragments.
ArrayList< Vertex > fragmentLib
Data structure containing the molecular representation of building blocks: fragment section - fragmen...
FragmentSpace(FragmentSpaceParameters settings, ArrayList< Vertex > scaffLib, ArrayList< Vertex > fragLib, ArrayList< Vertex > cappLib, HashMap< APClass, ArrayList< APClass > > cpMap, HashMap< APClass, APClass > capMap, HashSet< APClass > forbEnds, HashMap< APClass, ArrayList< APClass > > rcCpMap)
Define all components of a fragment space that implements the attachment point class-approach.
void addFusedRingsToFragmentLibrary(DGraph graph)
Extracts a system of one or more fused rings and adds them to the fragment space if not already prese...
ArrayList< Vertex > getVerticesWithAPClass(APClass apc)
Returns the list of vertexes with attachment points of the given class.
List< Vertex > getVerticesWithAPClasses(Set< APClass > apcs)
Returns the list of vertexes with at least one attachment point of each of the given classes.
HashMap< APClass, APClass > getCappingMap()
ArrayList< APClass > getCompatibleAPClasses(APClass apc)
Returns a list of APClasses compatible with the given APClass.
void setSymmConstraints(HashMap< APClass, Double > map)
ArrayList< Vertex > getScaffoldLibrary()
FragmentSpace()
Creates an empty fragment space, which is marked as invalid.
ArrayList< Integer > getFragsWithNumAps(int nAps)
Returns the list of fragments with given number of APs.
void setRCCompatibilityMatrix(HashMap< APClass, ArrayList< APClass > > map)
ArrayList< Vertex > getFragmentLibrary()
List< Vertex > getRCVsForAPClass(APClass apc)
Searches for all building blocks that are ring-closing vertexes and are compatible with the given AP.
int getCappingFragment(APClass rcnCap)
Select a compatible capping group for the given APClass.
List< Vertex > getVerticesWithAPFingerprint(Map< APClass, Integer > apcCounts)
Returns the list of vertexes that have the specified number of AttachmentPoints with the given APClas...
Parameters defining the fragment space.
boolean enforceSymmetry
Flag enforcing constitutional symmetry.
void setFragmentSpace(FragmentSpace fragmentSpace)
Sets the fragment space linked to these parameters.
Utility class for the fragment space.
static boolean recursiveCombiner(List< AttachmentPoint > keys, int currentKey, Map< AttachmentPoint, List< AttachmentPoint > > possibilities, APMapping combination, List< APMapping > completeCombinations, boolean screenAll, int maxCombs)
Search for all possible combinations of compatible APs.
Data structure containing information that identifies a single AP of a vertex/fragment.
static final APClass RCACLASSPLUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:85
boolean equals(Object o)
Definition: APClass.java:516
static final APClass RCACLASSMINUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:92
Class representing a mapping between attachment points (APs).
Definition: APMapping.java:42
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
APClass getAPClass()
Returns the Attachment Point class.
boolean isAvailable()
Check availability of this attachment point.
A candidate is the combination of a denoptim graph with molecular representation and may include also...
Definition: Candidate.java:40
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
List< DGraph > extractPattern(GraphPattern pattern)
Extracts subgraphs that match the provided pattern.
Definition: DGraph.java:4686
Candidate getCandidateOwner()
Returns the reference of the candidate item that is defined by this graph.
Definition: DGraph.java:257
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
void addAP(int atomPositionNumber)
Adds an attachment point with a dummy APClass.
Definition: Fragment.java:343
void addAtom(IAtom atom)
Definition: Fragment.java:836
void setInnerGraph(DGraph innerGraph)
Definition: Template.java:298
void setIAtomContainer(IAtomContainer mol, boolean updateAPsAccordingToIAC)
Attaches a molecular representation to this template.
Definition: Template.java:621
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
abstract Vertex clone()
Returns a deep-copy of this vertex.
int getBuildingBlockId()
Returns the index of the building block that should correspond to the position of the building block ...
Definition: Vertex.java:304
ArrayList< APClass > getAllAPClasses()
Returns the list of all APClasses present on this vertex.
Definition: Vertex.java:792
void setVertexId(long vertexId2)
Definition: Vertex.java:281
void setAsRCV(boolean isRCV)
Definition: Vertex.java:274
abstract List< AttachmentPoint > getAttachmentPoints()
void setBuildingBlockId(int buildingBlockId)
Definition: Vertex.java:311
void setBuildingBlockType(Vertex.BBType buildingBlockType)
Definition: Vertex.java:325
static Vertex newVertexFromLibrary(int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Builds a new molecular fragment kind of vertex.
Definition: Vertex.java:214
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final HashMap< APClass, String > RCALABELPERAPCLASS
Conventional labels for attractor pseudoatom.
Utility methods for input/output.
static void readRCCompatibilityMatrix(String fileName, HashMap< APClass, ArrayList< APClass > > rcCompatMap)
Reads the APclass compatibility matrix for ring-closing connections (the RC-CPMap).
static void writeSDFFile(String fileName, IAtomContainer mol)
Writes IAtomContainer to SDF file.
static void writeGraphToSDF(File file, DGraph graph, boolean append, boolean make3D, Logger logger, Randomizer randomizer)
Writes the graph to SDF file.
static void readCompatibilityMatrix(String fileName, HashMap< APClass, ArrayList< APClass > > compatMap, HashMap< APClass, APClass > cappingMap, Set< APClass > forbiddenEndList)
Read the APclass compatibility matrix data from file.
static ArrayList< Vertex > readVertexes(File file, Vertex.BBType bbt)
Reads Vertexes from any file that can contain such items.
static void writeGraphsToJSON(File file, List< DGraph > graphs)
Writes the graphs to JSON file.
Logger getLogger()
Get the name of the program specific logger.
Randomizer getRandomizer()
Returns the current program-specific randomizer.
Utilities for graphs.
Definition: GraphUtils.java:40
static synchronized long getUniqueVertexIndex()
Unique counter for the number of graph vertices generated.
Definition: GraphUtils.java:97
Utilities for molecule conversion.
static IAtomContainer extractIACForSubgraph(IAtomContainer wholeIAC, DGraph subGraph, DGraph wholeGraph, Logger logger, Randomizer randomizer)
Selects only the atoms that originate from a subgraph of a whole graph that originated the whole mole...
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.
int nextInt(int i)
Returns a pseudo-random, uniformly distributed int value between 0 (inclusive) and the specified valu...
The type of building block.
Definition: Vertex.java:86