$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.Collection;
26import java.util.HashMap;
27import java.util.HashSet;
28import java.util.List;
29import java.util.Map;
30import java.util.Set;
31import java.util.logging.Level;
32
33import javax.vecmath.Point3d;
34
35import org.openscience.cdk.Atom;
36import org.openscience.cdk.PseudoAtom;
37import org.openscience.cdk.interfaces.IAtomContainer;
38
39import denoptim.constants.DENOPTIMConstants;
40import denoptim.exception.DENOPTIMException;
41import denoptim.files.UndetectedFileFormatException;
42import denoptim.graph.APClass;
43import denoptim.graph.APMapping;
44import denoptim.graph.AttachmentPoint;
45import denoptim.graph.Candidate;
46import denoptim.graph.DGraph;
47import denoptim.graph.Fragment;
48import denoptim.graph.GraphPattern;
49import denoptim.graph.Template;
50import denoptim.graph.Vertex;
51import denoptim.graph.Vertex.BBType;
52import denoptim.graph.rings.RingClosingAttractor;
53import denoptim.io.DenoptimIO;
54import denoptim.utils.GraphUtils;
55import denoptim.utils.MoleculeUtils;
56import denoptim.utils.Randomizer;
57
67public class FragmentSpace
68{
76 private ArrayList<Vertex> scaffoldLib = null;
77
85 private ArrayList<Vertex> fragmentLib = null;
86
95 private ArrayList<Vertex> cappingLib = null;
96
101 private HashMap<APClass, ArrayList<APClass>> apClassCompatibilityMatrix;
102
107 private ArrayList<Vertex> rcvs = new ArrayList<Vertex>();
108
113 private HashMap<APClass, ArrayList<APClass>> rcCompatMap;
114
119 private HashMap<APClass, APClass> cappingMap;
120
124 private Set<APClass> forbiddenEndList;
125
129 private HashMap<Integer, ArrayList<Integer>> fragPoolPerNumAP =
130 new HashMap<Integer,ArrayList<Integer>>();
131
135 private HashMap<Integer, ArrayList<APClass>> apClassesPerFrag =
136 new HashMap<Integer,ArrayList<APClass>>();
137
143 private HashMap<APClass, ArrayList<ArrayList<Integer>>> fragsApsPerApClass =
144 new HashMap<APClass,ArrayList<ArrayList<Integer>>>();
145
149 private final Object LOCK = new Object();
150
154 private HashMap<APClass, Double> symmConstraints;
155
159 private boolean apClassBasedApproch = false;
160
164 private boolean isValid = false;
165
171
172//------------------------------------------------------------------------------
173
181 {
182 fragmentLib = new ArrayList<Vertex>();
183 scaffoldLib = new ArrayList<Vertex>();
184 cappingLib = new ArrayList<Vertex>();
186 }
187
188//------------------------------------------------------------------------------
189
206 String fragFile, String capFile, String cpmFile)
207 throws DENOPTIMException
208 {
209 this(settings, scaffFile, fragFile, capFile, cpmFile, "",
210 new HashMap<APClass, Double>());
211 }
212
213//------------------------------------------------------------------------------
214
237 ArrayList<Vertex> scaffLib,
238 ArrayList<Vertex> fragLib,
239 ArrayList<Vertex> cappLib,
240 HashMap<APClass, ArrayList<APClass>> cpMap,
241 HashMap<APClass, APClass> capMap,
242 HashSet<APClass> forbEnds,
243 HashMap<APClass, ArrayList<APClass>> rcCpMap)
244 throws DENOPTIMException
245 {
246 define(settings, scaffLib, fragLib, cappLib, cpMap, capMap, forbEnds,
247 rcCpMap, null);
248 }
249
250//------------------------------------------------------------------------------
251
275 ArrayList<Vertex> scaffLib,
276 ArrayList<Vertex> fragLib,
277 ArrayList<Vertex> cappLib,
278 HashMap<APClass, ArrayList<APClass>> cpMap,
279 HashMap<APClass, APClass> capMap,
280 HashSet<APClass> forbEnds,
281 HashMap<APClass, ArrayList<APClass>> rcCpMap,
282 HashMap<APClass, Double> symCntrMap)
283 throws DENOPTIMException
284 {
285 define(settings, scaffLib, fragLib, cappLib, cpMap, capMap, forbEnds,
286 rcCpMap, symCntrMap);
287 }
288
289//------------------------------------------------------------------------------
290
311 String fragFile, String capFile, String cpmFile, String rcpmFile,
312 HashMap<APClass, Double> symCntrMap) throws DENOPTIMException
313 {
314 HashMap<APClass, ArrayList<APClass>> cpMap =
315 new HashMap<APClass, ArrayList<APClass>>();
316 HashMap<APClass, APClass> capMap = new HashMap<APClass, APClass>();
317 HashSet<APClass> forbEnds = new HashSet<APClass>();
318 if (cpmFile.length() > 0)
319 {
320 DenoptimIO.readCompatibilityMatrix(cpmFile, cpMap, capMap,
321 forbEnds);
322 }
323
324 HashMap<APClass, ArrayList<APClass>> rcCpMap =
325 new HashMap<APClass, ArrayList<APClass>>();
326 if (rcpmFile != null && rcpmFile.length() > 0)
327 {
328 DenoptimIO.readRCCompatibilityMatrix(rcpmFile, rcCpMap);
329 }
330
331 ArrayList<Vertex> cappLib = new ArrayList<Vertex>();
332 if (capFile.length() > 0)
333 {
334 try
335 {
336 cappLib = DenoptimIO.readVertexes(new File(capFile),
337 BBType.CAP);
338 for (int i=0; i<cappLib.size(); i++)
339 {
340 cappLib.get(i).setBuildingBlockId(i);
341 }
342 } catch (IllegalArgumentException | UndetectedFileFormatException
343 | IOException | DENOPTIMException e)
344 {
345 throw new DENOPTIMException("Cound not read library of capping "
346 + "groups from file '" + capFile + "'.", e);
347 }
348 }
349
350 ArrayList<Vertex> fragLib = new ArrayList<Vertex>();
351 if (fragFile != null && fragFile.length() > 0)
352 {
353 try
354 {
355 fragLib = DenoptimIO.readVertexes(new File(fragFile),
357 for (int i=0; i<fragLib.size(); i++)
358 {
359 fragLib.get(i).setBuildingBlockId(i);
360 }
361 } catch (IllegalArgumentException | UndetectedFileFormatException
362 | IOException | DENOPTIMException e)
363 {
364 throw new DENOPTIMException("Cound not read library of fragments "
365 + "from file '" + fragFile + "'.", e);
366 }
367 }
368
369 ArrayList<Vertex> scaffLib = new ArrayList<Vertex>();
370 if (scaffFile != null && scaffFile.length() > 0)
371 {
372 try
373 {
374 scaffLib = DenoptimIO.readVertexes(new File(scaffFile),
376 for (int i=0; i<scaffLib.size(); i++)
377 {
378 scaffLib.get(i).setBuildingBlockId(i);
379 }
380 } catch (IllegalArgumentException | UndetectedFileFormatException
381 | IOException | DENOPTIMException e)
382 {
383 throw new DENOPTIMException("Cound not read library of scaffolds "
384 + "from file '" + fragFile + "'.", e);
385 }
386 }
387
388 define(settings, scaffLib, fragLib, cappLib, cpMap, capMap, forbEnds,
389 rcCpMap, symCntrMap);
390 }
391
392//------------------------------------------------------------------------------
393
416 ArrayList<Vertex> scaffLib,
417 ArrayList<Vertex> fragLib,
418 ArrayList<Vertex> cappLib,
419 HashMap<APClass, ArrayList<APClass>> cpMap,
420 HashMap<APClass, APClass> capMap,
421 HashSet<APClass> forbEnds,
422 HashMap<APClass, ArrayList<APClass>> rcCpMap,
423 HashMap<APClass, Double> symCntrMap)
424 throws DENOPTIMException
425 {
426 this.settings = settings;
428
429 setScaffoldLibrary(scaffLib);
430 setFragmentLibrary(fragLib);
431 setCappingLibrary(cappLib);
433 apClassBasedApproch = (cpMap!=null && cpMap.size()>0)
434 || (rcCpMap!=null && rcCpMap.size()>0);
435 setCappingMap(capMap);
436 setForbiddenEndList(forbEnds);
438 setSymmConstraints(symCntrMap);
439
441
442 isValid = true;
443 }
444
445//------------------------------------------------------------------------------
446
451 public boolean isDefined()
452 {
453 return isValid;
454 }
455
456//------------------------------------------------------------------------------
457
464 {
465 return settings.getRandomizer();
466 }
467
468//------------------------------------------------------------------------------
469
473 public void setAPclassBasedApproach(boolean useAPC)
474 {
475 apClassBasedApproch = useAPC;
476 }
477
478//------------------------------------------------------------------------------
479
488 public boolean useAPclassBasedApproach()
489 {
490 return apClassBasedApproch;
491 }
492
493//------------------------------------------------------------------------------
494
503 {
504 APClass cls = null;
505 try
506 {
507 Vertex frg = this.getVertexFromLibrary(
508 apId.getVertexMolType(), apId.getVertexMolId());
509 cls = frg.getAttachmentPoints().get(apId.getApId()).getAPClass();
510 } catch (Throwable t)
511 {
512 cls = null;
513 }
514
515 return cls;
516 }
517
518//------------------------------------------------------------------------------
519
539 public Vertex getVertexFromLibrary(Vertex.BBType bbType, int bbIdx)
540 throws DENOPTIMException
541 {
542 String msg = "";
543 switch (bbType)
544 {
545 case SCAFFOLD:
546 if (scaffoldLib == null)
547 {
548 msg = "Cannot retrieve scaffolds before initialising the "
549 + "scaffold library.";
550 throw new DENOPTIMException(msg);
551 }
552 break;
553 case FRAGMENT:
554 if (fragmentLib == null)
555 {
556 msg = "Cannot retrieve fragments before initialising the "
557 + "fragment library.";
558 throw new DENOPTIMException(msg);
559 }
560 break;
561 case CAP:
562 if (cappingLib == null)
563 {
564 msg = "Cannot retrieve capping groups before initialising"
565 + "the library of capping groups.";
566 throw new DENOPTIMException(msg);
567 }
568 break;
569
570 default:
571 throw new DENOPTIMException("Cannot find building block of "
572 + "type '" + bbType + "' in the fragment space.");
573 }
574
575 Vertex originalVrtx = null;
576 switch (bbType)
577 {
578 case SCAFFOLD:
579 if (bbIdx >-1 && bbIdx < scaffoldLib.size())
580 {
581 originalVrtx = scaffoldLib.get(bbIdx);
582 }
583 else
584 {
585 msg = "Mismatch between scaffold bbIdx (" + bbIdx
586 + ") and size of the library (" + scaffoldLib.size()
587 + "). FragType: " + bbType;
588 settings.getLogger().log(Level.SEVERE, msg);
589 throw new DENOPTIMException(msg);
590 }
591 break;
592
593 case FRAGMENT:
594 if (bbIdx >-1 && bbIdx < fragmentLib.size())
595 {
596 originalVrtx = fragmentLib.get(bbIdx);
597 }
598 else
599 {
600 msg = "Mismatch between fragment bbIdx (" + bbIdx
601 + ") and size of the library (" + fragmentLib.size()
602 + "). FragType: " + bbType;
603 settings.getLogger().log(Level.SEVERE, msg);
604 throw new DENOPTIMException(msg);
605 }
606 break;
607
608 case CAP:
609 if (bbIdx >-1 && bbIdx < cappingLib.size())
610 {
611 originalVrtx = cappingLib.get(bbIdx);
612 }
613 else
614 {
615 msg = "Mismatch between capping group bbIdx " + bbIdx
616 + ") and size of the library (" + cappingLib.size()
617 + "). FragType: " + bbType;
618 settings.getLogger().log(Level.SEVERE, msg);
619 throw new DENOPTIMException(msg);
620 }
621 break;
622
623 case UNDEFINED:
624 msg = "Attempting to take UNDEFINED type of building block from "
625 + "fragment library.";
626 settings.getLogger().log(Level.WARNING, msg);
627 if (bbIdx < fragmentLib.size())
628 {
629 originalVrtx = fragmentLib.get(bbIdx);
630 }
631 else
632 {
633 msg = "Mismatch between fragment bbIdx (" + bbIdx
634 + ") and size of the library (" + fragmentLib.size()
635 + "). FragType: " + bbType;
636 settings.getLogger().log(Level.SEVERE, msg);
637 throw new DENOPTIMException(msg);
638 }
639 break;
640
641 default:
642 msg = "Unknown type of fragment '" + bbType + "'.";
643 settings.getLogger().log(Level.SEVERE, msg);
644 throw new DENOPTIMException(msg);
645 }
646 Vertex clone = originalVrtx.clone();
647
649
650 clone.setBuildingBlockId(bbIdx);
651 if (originalVrtx.getBuildingBlockId() != bbIdx)
652 {
653 settings.getLogger().log(Level.WARNING, "Mismatch between building "
654 + "block ID ("
655 + originalVrtx.getBuildingBlockId() + ") and position in "
656 + "the list of building blocks (" + bbIdx + ") for type "
657 + bbType + ".");
658 }
659 return clone;
660 }
661
662//------------------------------------------------------------------------------
663
670 public int getCappingFragment(APClass rcnCap)
671 {
672 if (rcnCap == null)
673 return -1;
674
675 ArrayList<Integer> reacFrags = getCompatibleCappingFragments(rcnCap);
676
677 int fapidx = -1;
678 if (reacFrags.size() > 0)
679 {
680 fapidx = settings.getRandomizer().randomlyChooseOne(reacFrags);
681 }
682
683 return fapidx;
684 }
685
686//------------------------------------------------------------------------------
687
694 public ArrayList<Integer> getCompatibleCappingFragments(
695 APClass cmpReac)
696 {
697 ArrayList<Integer> lstFragIdx = new ArrayList<>();
698 for (int i=0; i<cappingLib.size(); i++)
699 {
700 Vertex mol = getCappingLibrary().get(i);
701 ArrayList<APClass> lstRcn = mol.getAllAPClasses();
702 if (lstRcn.contains(cmpReac))
703 lstFragIdx.add(i);
704 }
705 return lstFragIdx;
706 }
707
708//------------------------------------------------------------------------------
709
716 {
717 int chosenIdx = settings.getRandomizer().nextInt(scaffoldLib.size());
718 Vertex scaffold = null;
719 try
720 {
721 scaffold = Vertex.newVertexFromLibrary(
722 GraphUtils.getUniqueVertexIndex(),chosenIdx,
723 BBType.SCAFFOLD, this);
724 } catch (DENOPTIMException e)
725 {
726 //This cannot happen!
727 }
728 return scaffold;
729 }
730
731//------------------------------------------------------------------------------
732
733 public ArrayList<Vertex> getScaffoldLibrary()
734 {
735 return scaffoldLib;
736 }
737
738//------------------------------------------------------------------------------
739
740 public ArrayList<Vertex> getFragmentLibrary()
741 {
742 return fragmentLib;
743 }
744
745//------------------------------------------------------------------------------
746
747 public ArrayList<Vertex> getCappingLibrary()
748 {
749 return cappingLib;
750 }
751
752//------------------------------------------------------------------------------
753
759 public ArrayList<Integer> getCappingGroupsWithAPClass(APClass capApCls)
760 {
761 ArrayList<Integer> selected = new ArrayList<>();
762 for (int i = 0; i < cappingLib.size(); i++)
763 {
764 APClass apc = cappingLib.get(i).getAP(0).getAPClass();
765 if (apc.equals(capApCls))
766 {
767 selected.add(i);
768 }
769 }
770 return selected;
771 }
772
773//------------------------------------------------------------------------------
774
783 {
784 for (int i = 0; i < cappingLib.size(); i++)
785 {
786 APClass apc = cappingLib.get(i).getAP(0).getAPClass();
787 if (apc.equals(capApCls))
788 {
789 try
790 {
792 } catch (DENOPTIMException e)
793 {
794 //This cannot happen
795 }
796 }
797 }
798 return null;
799 }
800
801//------------------------------------------------------------------------------
802
813 public void importCompatibilityMatrixFromFile(String inFile)
814 throws DENOPTIMException
815 {
816 setCompatibilityMatrix(new HashMap<APClass, ArrayList<APClass>>());
817 setCappingMap(new HashMap<APClass, APClass>());
818 setForbiddenEndList(new HashSet<APClass>());
821 }
822
823//------------------------------------------------------------------------------
824
832 public void importRCCompatibilityMatrixFromFile(String inFile)
833 throws DENOPTIMException
834 {
835 setRCCompatibilityMatrix(new HashMap<APClass, ArrayList<APClass>>());
837 }
838
839//------------------------------------------------------------------------------
840
841 public HashMap<APClass, ArrayList<APClass>> getCompatibilityMatrix()
842 {
844 }
845
846//------------------------------------------------------------------------------
847
854 public ArrayList<APClass> getCompatibleAPClasses(APClass apc)
855 {
856 if (apClassCompatibilityMatrix!= null && apClassCompatibilityMatrix.containsKey(apc))
857 {
858 return apClassCompatibilityMatrix.get(apc);
859 }
860 return new ArrayList<APClass>();
861 }
862
863//------------------------------------------------------------------------------
864
872 public HashMap<APClass, ArrayList<APClass>> getRCCompatibilityMatrix()
873 {
874 return rcCompatMap;
875 }
876
877//------------------------------------------------------------------------------
878
879 public HashMap<APClass, APClass> getCappingMap()
880 {
881 return cappingMap;
882 }
883
884//------------------------------------------------------------------------------
885
893 {
894 return cappingMap.get(srcApClass);
895 }
896
897//------------------------------------------------------------------------------
898
899 public Set<APClass> getForbiddenEndList()
900 {
901 return forbiddenEndList;
902 }
903
904//------------------------------------------------------------------------------
905
915 public Set<APClass> getAllAPClassesFromCPMap()
916 {
917 return apClassCompatibilityMatrix.keySet();
918 }
919
920//------------------------------------------------------------------------------
921
922 public HashMap<Integer, ArrayList<Integer>> getMapOfFragsPerNumAps()
923 {
924 return fragPoolPerNumAP;
925 }
926
927//------------------------------------------------------------------------------
928
936 public ArrayList<Integer> getFragsWithNumAps(int nAps)
937 {
938 ArrayList<Integer> lst = new ArrayList<>();
939 if (fragPoolPerNumAP.containsKey(nAps))
940 {
941 lst = fragPoolPerNumAP.get(nAps);
942 }
943 return lst;
944 }
945
946//------------------------------------------------------------------------------
947
955 public ArrayList<APClass> getAPClassesPerFragment(int fragId)
956 {
957 synchronized (LOCK)
958 {
959 return apClassesPerFrag.get(fragId);
960 }
961 }
962
963//------------------------------------------------------------------------------
964
975 public ArrayList<IdFragmentAndAP> getFragsWithAPClass(APClass apc)
976 {
977 ArrayList<IdFragmentAndAP> lst = new ArrayList<IdFragmentAndAP>();
978
979 synchronized (LOCK)
980 {
981 if (fragsApsPerApClass.containsKey(apc))
982 {
983 for (ArrayList<Integer> idxs : fragsApsPerApClass.get(apc))
984 {
985 IdFragmentAndAP apId = new IdFragmentAndAP(-1, // vertexId
986 idxs.get(0), // MolId,
987 BBType.FRAGMENT, idxs.get(1), // ApId
988 -1, // noVSym
989 -1);// noAPSym
990 lst.add(apId);
991 }
992 }
993 }
994 return lst;
995 }
996
997//------------------------------------------------------------------------------
998
1005 public ArrayList<Vertex> getVerticesWithAPClass(APClass apc)
1006 {
1007 ArrayList<Vertex> lst = new ArrayList<Vertex>();
1008
1009 synchronized (LOCK)
1010 {
1011 if (fragsApsPerApClass.containsKey(apc))
1012 {
1013 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1014 {
1015 Vertex v = fragmentLib.get(idxs.get(0));
1016 lst.add(v);
1017 }
1018 }
1019 }
1020 return lst;
1021 }
1022
1023//------------------------------------------------------------------------------
1024
1032 public List<Vertex> getVerticesWithAPClasses(Set<APClass> apcs)
1033 {
1034 List<Vertex> lst = new ArrayList<Vertex>();
1035
1036 synchronized (LOCK)
1037 {
1038 for (APClass apc : apcs)
1039 {
1040 if (!fragsApsPerApClass.containsKey(apc))
1041 {
1042 break;
1043 }
1044
1045 // NB: the list is over APs, so there can be duplicate vertexes
1046 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1047 {
1048 Vertex v = fragmentLib.get(idxs.get(0));
1049 if (!lst.contains(v) && v.getAllAPClasses().containsAll(apcs))
1050 lst.add(v);
1051 }
1052
1053 // NB: we mean to do only one loop
1054 break;
1055 }
1056 }
1057 return lst;
1058 }
1059
1060//------------------------------------------------------------------------------
1061
1070 public List<Vertex> getVerticesWithAPFingerprint(
1071 Map<APClass,Integer> apcCounts)
1072 {
1073 List<Vertex> matches = new ArrayList<Vertex>();
1074 for (Vertex candidate : getVerticesWithAPClasses(apcCounts.keySet()))
1075 {
1076 boolean isMatch = true;
1077 for (APClass apc : apcCounts.keySet())
1078 {
1079 if (apcCounts.get(apc) >
1080 candidate.getAttachmentPoints().stream().filter(
1081 ap -> ap.getAPClass().equals(apc)).count())
1082 {
1083 isMatch = false;
1084 break;
1085 }
1086 }
1087 if (isMatch)
1088 matches.add(candidate);
1089 }
1090 return matches;
1091 }
1092
1093//------------------------------------------------------------------------------
1094
1103 public List<Vertex> getVerticesWithAPClassStartingWith(String root)
1104 {
1105 List<Vertex> lst = new ArrayList<Vertex>();
1106 synchronized (LOCK)
1107 {
1108 for (APClass apc : fragsApsPerApClass.keySet())
1109 {
1110 if (!apc.toString().startsWith(root))
1111 continue;
1112 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1113 {
1114 Vertex v = fragmentLib.get(idxs.get(0));
1115 if (!lst.contains(v))
1116 lst.add(v);
1117 }
1118 }
1119 }
1120 return lst;
1121 }
1122
1123//------------------------------------------------------------------------------
1124
1133 public ArrayList<Vertex> getFragmentsCompatibleWithTheseAPs(
1134 ArrayList<IdFragmentAndAP> srcAPs)
1135 {
1136 // First we get all possible APs on any fragment
1137 ArrayList<IdFragmentAndAP> compatFragAps =
1139
1140 // then keep unique fragment identifiers, and store unique
1141 Set<Integer> compatFragIds = new HashSet<Integer>();
1142 for (IdFragmentAndAP apId : compatFragAps)
1143 {
1144 compatFragIds.add(apId.getVertexMolId());
1145 }
1146
1147 // Then we pack-up the selected list of fragments
1148 ArrayList<Vertex> compatFrags = new ArrayList<Vertex>();
1149 for (Integer fid : compatFragIds)
1150 {
1151 try {
1152 compatFrags.add(getVertexFromLibrary(BBType.FRAGMENT, fid));
1153 } catch (DENOPTIMException e) {
1154 settings.getLogger().log(Level.WARNING, "Exception while trying "
1155 + "to get fragment '" + fid + "'!");
1156 e.printStackTrace();
1157 }
1158 }
1159 return compatFrags;
1160 }
1161
1162//------------------------------------------------------------------------------
1163
1172 public List<Vertex> getRCVsWithAPClass(APClass apc)
1173 {
1174 List<Vertex> chosenRCVs = new ArrayList<Vertex>();
1175 for (Vertex rcv : getRCVs())
1176 {
1177 // NB: RCVs must have only one attachment point
1178 if (apc.equals(rcv.getAP(0).getAPClass()))
1179 {
1180 Vertex copyOfRCV = null;
1181 try
1182 {
1183 copyOfRCV = getVertexFromLibrary(rcv.getBuildingBlockType(),
1184 rcv.getBuildingBlockId());
1185 chosenRCVs.add(copyOfRCV);
1186 } catch (DENOPTIMException e)
1187 {
1188 // This should never happen because we have already taken
1189 // the BB from BBSpace.
1190 e.printStackTrace();
1191 }
1192 }
1193 }
1194 return chosenRCVs;
1195 }
1196
1197//------------------------------------------------------------------------------
1198
1207 public List<Vertex> getRCVsForAPClass(APClass apc)
1208 {
1209 List<Vertex> chosenRCVs = new ArrayList<Vertex>();
1210 if (!getCompatibilityMatrix().containsKey(apc))
1211 {
1212 return chosenRCVs;
1213 }
1214 List<APClass> apcsCompatWithSrcAP = getCompatibilityMatrix().get(apc);
1215 for (Vertex rcv : getRCVs())
1216 {
1217 // NB: RCVs must have only one attachment point
1218 if (apcsCompatWithSrcAP.contains(rcv.getAP(0).getAPClass()))
1219 {
1220 Vertex copyOfRCV = null;
1221 try
1222 {
1223 copyOfRCV = getVertexFromLibrary(rcv.getBuildingBlockType(),
1224 rcv.getBuildingBlockId());
1225 chosenRCVs.add(copyOfRCV);
1226 } catch (DENOPTIMException e)
1227 {
1228 // This should never happen because we have already taken
1229 // the BB from BBSpace.
1230 e.printStackTrace();
1231 }
1232 }
1233 }
1234 return chosenRCVs;
1235 }
1236
1237//------------------------------------------------------------------------------
1238
1247 public ArrayList<AttachmentPoint> getAPsCompatibleWithThese(
1248 ArrayList<AttachmentPoint> srcAPs)
1249 {
1250 ArrayList<AttachmentPoint> compAps =
1251 new ArrayList<AttachmentPoint>();
1252 boolean first = true;
1253 for (AttachmentPoint ap : srcAPs)
1254 {
1255 ArrayList<AttachmentPoint> compForOne =
1256 getAPsCompatibleWithClass(ap.getAPClass());
1257
1258 if (first)
1259 {
1260 compAps.addAll(compForOne);
1261 first = false;
1262 continue;
1263 }
1264
1265 ArrayList<AttachmentPoint> toKeep =
1266 new ArrayList<AttachmentPoint>();
1267 for (AttachmentPoint candAp : compAps)
1268 {
1269 for (AttachmentPoint newCand : compForOne)
1270 {
1271 if (newCand == candAp)
1272 {
1273 toKeep.add(candAp);
1274 break;
1275 }
1276 }
1277 }
1278
1279 compAps = toKeep;
1280
1281 if (compAps.size()==0)
1282 {
1283 break;
1284 }
1285 }
1286 return compAps;
1287 }
1288
1289//------------------------------------------------------------------------------
1290
1298 public ArrayList<IdFragmentAndAP> getFragAPsCompatibleWithTheseAPs(
1299 ArrayList<IdFragmentAndAP> srcAPs)
1300 {
1301 ArrayList<IdFragmentAndAP> compFrAps = new ArrayList<IdFragmentAndAP>();
1302 boolean first = true;
1303 for (IdFragmentAndAP apId : srcAPs)
1304 {
1305 APClass srcApCls = getAPClassForFragment(apId);
1306 ArrayList<IdFragmentAndAP> compForOne =
1308
1309 if (first)
1310 {
1311 compFrAps.addAll(compForOne);
1312 first = false;
1313 continue;
1314 }
1315
1316 ArrayList<IdFragmentAndAP> toKeep =
1317 new ArrayList<IdFragmentAndAP>();
1318 for (IdFragmentAndAP candAp : compFrAps)
1319 {
1320 for (IdFragmentAndAP newId : compForOne)
1321 {
1322 if (newId.sameFragAndAp(candAp))
1323 {
1324 toKeep.add(candAp);
1325 break;
1326 }
1327 }
1328 }
1329
1330 compFrAps = toKeep;
1331
1332 if (compFrAps.size() == 0)
1333 {
1334 break;
1335 }
1336 }
1337
1338 return compFrAps;
1339 }
1340
1341//------------------------------------------------------------------------------
1342
1351 public ArrayList<AttachmentPoint> getAPsCompatibleWithClass(
1352 APClass aPC1)
1353 {
1354 ArrayList<AttachmentPoint> compatAps =
1355 new ArrayList<AttachmentPoint>();
1356
1357 // Take the compatible AP classes
1358 ArrayList<APClass> compatApClasses = getCompatibleAPClasses(aPC1);
1359
1360 // Find all APs with a compatible class
1361 if (compatApClasses != null)
1362 {
1363 for (APClass klass : compatApClasses)
1364 {
1365 ArrayList<Vertex> vrtxs = getVerticesWithAPClass(klass);
1366 for (Vertex v : vrtxs)
1367 {
1368 for (AttachmentPoint ap : v.getAttachmentPoints())
1369 {
1370 if (ap.getAPClass() == klass)
1371 {
1372 compatAps.add(ap);
1373 }
1374 }
1375 }
1376 }
1377 }
1378
1379 if (compatAps.size()==0)
1380 {
1381 settings.getLogger().log(Level.WARNING,"No compatible "
1382 + "AP found in the fragment space for APClass '"
1383 + aPC1 + "'.");
1384 }
1385
1386 return compatAps;
1387 }
1388
1389//------------------------------------------------------------------------------
1390
1398 public ArrayList<IdFragmentAndAP> getFragAPsCompatibleWithClass(
1399 APClass aPC1)
1400 {
1401 ArrayList<IdFragmentAndAP> compatFragAps =
1402 new ArrayList<IdFragmentAndAP>();
1403
1404 // Take the compatible AP classes
1405 ArrayList<APClass> compatApClasses = getCompatibleAPClasses(aPC1);
1406
1407 // Find all APs with any compatible class
1408 if (compatApClasses != null)
1409 {
1410 for (APClass compClass : compatApClasses)
1411 {
1412 compatFragAps.addAll(getFragsWithAPClass(compClass));
1413 }
1414 }
1415 return compatFragAps;
1416 }
1417
1418//------------------------------------------------------------------------------
1419
1431 public boolean imposeSymmetryOnAPsOfClass(APClass apClass)
1432 {
1433 boolean res = true;
1434 if (hasSymmetryConstrain(apClass))
1435 {
1436 if (getSymmetryConstrain(apClass) < (1.0
1438 {
1439 res = false;
1440 }
1441 } else
1442 {
1444 {
1445 res = false;
1446 }
1447 }
1448 return res;
1449 }
1450
1451//------------------------------------------------------------------------------
1452
1462 public boolean hasSymmetryConstrain(APClass apClass)
1463 {
1464 if (symmConstraints==null)
1465 return false;
1466 return symmConstraints.containsKey(apClass);
1467 }
1468
1469//------------------------------------------------------------------------------
1470
1481 public double getSymmetryConstrain(APClass apClass)
1482 {
1483 return symmConstraints.get(apClass);
1484 }
1485
1486//------------------------------------------------------------------------------
1487
1488 public void setScaffoldLibrary(ArrayList<Vertex> lib)
1489 {
1490 scaffoldLib = new ArrayList<Vertex>();
1492 }
1493
1494 public void setFragmentLibrary(ArrayList<Vertex> lib)
1495 {
1496 fragmentLib = new ArrayList<Vertex>();
1498 }
1499
1500//------------------------------------------------------------------------------
1501
1502 public void setCappingLibrary(ArrayList<Vertex> lib)
1503 {
1504 cappingLib = new ArrayList<Vertex>();
1506 }
1507
1508//------------------------------------------------------------------------------
1509
1510 public void setCompatibilityMatrix(HashMap<APClass, ArrayList<APClass>> map)
1511 {
1513 }
1514
1515//------------------------------------------------------------------------------
1516
1517 public void setRCCompatibilityMatrix(HashMap<APClass,
1518 ArrayList<APClass>> map)
1519 {
1520 rcCompatMap = map;
1521 }
1522
1523//------------------------------------------------------------------------------
1524
1525 public void setCappingMap(HashMap<APClass, APClass> map)
1526 {
1527 cappingMap = map;
1528 }
1529
1530//------------------------------------------------------------------------------
1531
1532 public void setForbiddenEndList(Set<APClass> lst)
1533 {
1534 forbiddenEndList = lst;
1535 }
1536
1537//------------------------------------------------------------------------------
1538
1539 public void setSymmConstraints(HashMap<APClass, Double> map)
1540 {
1541 symmConstraints = map;
1542 }
1543
1544//------------------------------------------------------------------------------
1545
1550 public void clearAll()
1551 {
1552 scaffoldLib = null;
1553 fragmentLib = null;
1554 cappingLib = null;
1556 rcCompatMap = null;
1557 cappingMap = null;
1558 forbiddenEndList = null;
1559 fragPoolPerNumAP = new HashMap<Integer,ArrayList<Integer>>();
1560 apClassesPerFrag = new HashMap<Integer,ArrayList<APClass>>();
1561 fragsApsPerApClass = new HashMap<APClass,ArrayList<ArrayList<Integer>>>();
1562 symmConstraints = null;
1563 isValid = false;
1564 }
1565
1566//------------------------------------------------------------------------------
1567
1577 public void appendVerticesToLibrary(ArrayList<Vertex> list,
1578 Vertex.BBType bbt, ArrayList<Vertex> library)
1579 {
1580 for (Vertex v : list)
1581 {
1582 appendVertexToLibrary(v, bbt, library);
1583 }
1584 }
1585
1586//------------------------------------------------------------------------------
1587
1598 Vertex.BBType bbt, ArrayList<Vertex> library)
1599 {
1600 v.setBuildingBlockId(library.size());
1601 v.setBuildingBlockType(bbt);
1602 library.add(v);
1603 if (bbt == BBType.FRAGMENT)
1604 {
1605 classifyFragment(v, library.size()-1);
1606 }
1607 }
1608
1609//------------------------------------------------------------------------------
1610
1622 //TODO: need something to prevent memory overload:
1623 // -> keep only some templates?
1624 // -> remove those who did not lead to good population members?
1625 // -> remove redundant? The highest-simmetry principle (i.e., rather than
1626 // keeping a template as it is, we'd like to keep its highest symmetry
1627 // isomorphic) would be the first thing to do.
1628
1630 {
1631 addFusedRingsToFragmentLibrary(graph,true,true);
1632 }
1633
1634//------------------------------------------------------------------------------
1635
1649 boolean addIfScaffold, boolean addIfFragment)
1650 {
1651 addFusedRingsToFragmentLibrary(graph, addIfScaffold, addIfFragment, null);
1652 }
1653
1654//------------------------------------------------------------------------------
1655
1674 //TODO: need something to prevent memory overload:
1675 // -> keep only some templates?
1676 // -> remove those who did not lead to good population members?
1677 // -> remove redundant? The highest-symmetry principle (i.e., rather than
1678 // keeping a template as it is, we'd like to keep its highest symmetry
1679 // isomorphic) would be the first thing to do.
1680
1682 boolean addIfScaffold, boolean addIfFragment,
1683 IAtomContainer wholeMol)
1684 {
1685 List<DGraph> subgraphs = null;
1686 try
1687 {
1688 subgraphs = graph.extractPattern(GraphPattern.RING);
1689 } catch (DENOPTIMException e1)
1690 {
1691 settings.getLogger().log(Level.WARNING,"Failed to extract "
1692 + "fused ring patters.");
1693 e1.printStackTrace();
1694 }
1695
1696 for (DGraph g : subgraphs)
1697 {
1698 BBType type = g.hasScaffoldTypeVertex() ?
1699 BBType.SCAFFOLD :
1701
1702 if (!addIfFragment && type == BBType.FRAGMENT)
1703 {
1704 continue;
1705 }
1706 if (!addIfScaffold && type == BBType.SCAFFOLD)
1707 {
1708 continue;
1709 }
1710
1711 ArrayList<Vertex> library = type == BBType.FRAGMENT ?
1713
1714 synchronized (LOCK)
1715 {
1716 if (!hasIsomorph(g, type))
1717 {
1718 //TODO: try to transform the template into its isomorphic
1719 // with highest symmetry, and define the symmetric sets.
1720 // Such enhancement would facilitate the creation of
1721 // symmetric graphs from templates generated on the fly.
1722
1723 Template t = new Template(type);
1724 t.setInnerGraph(g);
1725
1726 boolean has3Dgeometry = false;
1727 IAtomContainer subIAC = null;
1728 if (wholeMol!=null)
1729 {
1730 try
1731 {
1733 wholeMol, g, graph, settings.getLogger(),
1735 t.setIAtomContainer(subIAC,true);
1736 has3Dgeometry = true;
1737 } catch (DENOPTIMException e1)
1738 {
1739 e1.printStackTrace();
1740 ArrayList<DGraph> lst = new ArrayList<>();
1741 lst.add(graph);
1742 lst.add(g);
1743 String forDebugFile = "failedExtractIAC_"
1744 + graph.getGraphId() + ".json";
1745 try
1746 {
1748 new File(forDebugFile), lst);
1749 settings.getLogger().log(Level.WARNING,
1750 "WARNING: failed to extract "
1751 + "molecular representation of graph. "
1752 + "See file '" + forDebugFile + "'.");
1753 } catch (DENOPTIMException e)
1754 {
1755 settings.getLogger().log(Level.WARNING,
1756 "WARNING: failed to extract "
1757 + "molecular representation of graph, "
1758 + "and failed to write graph to file.");
1759 }
1760 }
1761 }
1762
1763 String msg = "Adding new template (Inner Graph id: "
1764 + t.getInnerGraph().getGraphId() + ") to the "
1765 + "library of " + type + "s. The template is "
1766 + "generated from graph " + graph.getGraphId();
1767 Candidate source = graph.getCandidateOwner();
1768 if (source != null)
1769 msg = msg + " candidate " + source.getName();
1770 else
1771 msg = msg + ".";
1772 settings.getLogger().log(Level.INFO, msg);
1773
1774 appendVertexToLibrary(t, type, library);
1775 if (type == BBType.FRAGMENT)
1776 {
1777 classifyFragment(t,library.size()-1);
1778 }
1779
1780 String destFileName = type == BBType.FRAGMENT ?
1783 try
1784 {
1785 if (has3Dgeometry)
1786 {
1787 DenoptimIO.writeSDFFile(destFileName,subIAC,true);
1788 } else {
1789 DenoptimIO.writeGraphToSDF(new File(destFileName),
1790 g, true, false, settings.getLogger(),
1792 }
1793 } catch (DENOPTIMException e)
1794 {
1795 e.printStackTrace();
1796 settings.getLogger().log(Level.WARNING, "WARNING: "
1797 + "failed to write newly "
1798 + "generated " + type + " to file '"
1799 + destFileName + "'.");
1800 }
1801 }
1802 }
1803 }
1804 }
1805
1806//------------------------------------------------------------------------------
1807
1817 public boolean hasIsomorph(DGraph graph, BBType type) {
1818 return (type == BBType.SCAFFOLD ? scaffoldLib : fragmentLib)
1819 .stream()
1820 .filter(v -> v instanceof Template)
1821 .map(t -> (Template) t)
1823 .anyMatch(graph::isIsomorphicTo);
1824 }
1825
1826//------------------------------------------------------------------------------
1827
1833 public void registerRCV(Vertex v)
1834 {
1835 rcvs.add(v);
1836 }
1837
1838//------------------------------------------------------------------------------
1839
1844 public ArrayList<Vertex> getRCVs()
1845 {
1846 return rcvs;
1847 }
1848
1849//------------------------------------------------------------------------------
1850
1861 public List<APMapping> mapAPClassCompatibilities(
1862 List<AttachmentPoint> listA,
1863 List<AttachmentPoint> listB, int maxCombinations)
1864 {
1865 Map<AttachmentPoint,List<AttachmentPoint>> apCompatilities =
1866 new HashMap<AttachmentPoint,List<AttachmentPoint>>();
1867
1868 for (AttachmentPoint apA : listA)
1869 {
1870 for (AttachmentPoint apB : listB)
1871 {
1872 boolean compatible = false;
1874 {
1875 if (apA.getAPClass().isCPMapCompatibleWith(apB.getAPClass(),
1876 this))
1877 {
1878 compatible = true;
1879 }
1880 } else {
1881 compatible = true;
1882 }
1883 if (compatible)
1884 {
1885 if (apCompatilities.containsKey(apA))
1886 {
1887 apCompatilities.get(apA).add(apB);
1888 } else {
1889 List<AttachmentPoint> lst =
1890 new ArrayList<AttachmentPoint>();
1891 lst.add(apB);
1892 apCompatilities.put(apA,lst);
1893 }
1894 }
1895 }
1896 }
1897
1898 // This is used only to keep a sorted list of the map keys
1899 List<AttachmentPoint> keys =
1900 new ArrayList<AttachmentPoint>(
1901 apCompatilities.keySet());
1902
1903 // Get all possible combinations of compatible AP pairs
1904 List<APMapping> apMappings = new ArrayList<APMapping>();
1905 if (keys.size() > 0)
1906 {
1907 int currentKey = 0;
1908 APMapping currentMapping = new APMapping();
1909 FragmentSpaceUtils.recursiveCombiner(keys, currentKey,
1910 apCompatilities, currentMapping, apMappings, true,
1911 maxCombinations);
1912 }
1913
1914 return apMappings;
1915 }
1916
1917//------------------------------------------------------------------------------
1918
1927 public void classifyFragment(Vertex frg, int fragId)
1928 {
1929 // Classify according to number of APs
1930 int nAps = frg.getFreeAPCount();
1931 if (nAps != 0)
1932 {
1933 if (getMapOfFragsPerNumAps().containsKey(nAps))
1934 {
1935 getFragsWithNumAps(nAps).add(fragId);
1936 }
1937 else
1938 {
1939 ArrayList<Integer> lst = new ArrayList<>();
1940 lst.add(fragId);
1941 getMapOfFragsPerNumAps().put(nAps,lst);
1942 }
1943 }
1944
1946 {
1947 // Collect classes per fragment
1948 ArrayList<APClass> lstAPC = frg.getAllAPClasses();
1949 synchronized (LOCK)
1950 {
1951 apClassesPerFrag.put(fragId,lstAPC);
1952 }
1953
1954 // Classify according to AP-Classes
1955 List<AttachmentPoint> lstAPs = frg.getAttachmentPoints();
1956
1957 for (int j=0; j<lstAPs.size(); j++)
1958 {
1959 AttachmentPoint ap = lstAPs.get(j);
1960 ArrayList<Integer> apId = new ArrayList<Integer>();
1961 apId.add(fragId);
1962 apId.add(j);
1963 APClass cls = ap.getAPClass();
1964
1965 if (!ap.isAvailable())
1966 {
1967 continue;
1968 }
1969
1970 synchronized (LOCK)
1971 {
1972 if (fragsApsPerApClass.containsKey(cls))
1973 {
1974 fragsApsPerApClass.get(cls).add(apId);
1975 } else {
1976 ArrayList<ArrayList<Integer>> outLst =
1977 new ArrayList<ArrayList<Integer>>();
1978 outLst.add(apId);
1979 fragsApsPerApClass.put(cls,outLst);
1980 }
1981 }
1982 }
1983
1984 if (frg.isRCV())
1985 registerRCV(frg);
1986 }
1987 }
1988
1989//------------------------------------------------------------------------------
1990
1998 throws DENOPTIMException
1999 {
2000 for (int j=0; j<getFragmentLibrary().size(); j++)
2001 {
2002 Vertex frag = getFragmentLibrary().get(j);
2003 classifyFragment(frag,j);
2004 }
2005 }
2006
2007//------------------------------------------------------------------------------
2008
2017 public static Vertex getPolarizedRCV(boolean polarity)
2018 {
2020 if (!polarity)
2021 apc = APClass.RCACLASSMINUS;
2022
2023 Fragment rcv = new Fragment();
2024 Atom atom = new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(apc),
2025 new Point3d());
2026 rcv.addAtom(atom);
2027 rcv.addAP(0, new Point3d(1.5, 0.0, 0.0), apc);
2028 rcv.setAsRCV(true);
2029 return rcv;
2030 }
2031
2032//------------------------------------------------------------------------------
2033
2034}
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:62
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:305
ArrayList< APClass > getAllAPClasses()
Returns the list of all APClasses present on this vertex.
Definition: Vertex.java:793
void setVertexId(long vertexId2)
Definition: Vertex.java:282
void setAsRCV(boolean isRCV)
Definition: Vertex.java:275
abstract List< AttachmentPoint > getAttachmentPoints()
void setBuildingBlockId(int buildingBlockId)
Definition: Vertex.java:312
void setBuildingBlockType(Vertex.BBType buildingBlockType)
Definition: Vertex.java:326
static Vertex newVertexFromLibrary(int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Builds a new molecular fragment kind of vertex.
Definition: Vertex.java:215
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:87