$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;
31import java.util.logging.Logger;
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
474 public Logger getLogger()
475 {
476 return settings.getLogger();
477 }
478
479//------------------------------------------------------------------------------
480
484 public void setAPclassBasedApproach(boolean useAPC)
485 {
486 apClassBasedApproch = useAPC;
487 }
488
489//------------------------------------------------------------------------------
490
499 public boolean useAPclassBasedApproach()
500 {
501 return apClassBasedApproch;
502 }
503
504//------------------------------------------------------------------------------
505
514 {
515 APClass cls = null;
516 try
517 {
518 Vertex frg = this.getVertexFromLibrary(
519 apId.getVertexMolType(), apId.getVertexMolId());
520 cls = frg.getAttachmentPoints().get(apId.getApId()).getAPClass();
521 } catch (Throwable t)
522 {
523 cls = null;
524 }
525
526 return cls;
527 }
528
529//------------------------------------------------------------------------------
530
550 public Vertex getVertexFromLibrary(Vertex.BBType bbType, int bbIdx)
551 throws DENOPTIMException
552 {
553 String msg = "";
554 switch (bbType)
555 {
556 case SCAFFOLD:
557 if (scaffoldLib == null)
558 {
559 msg = "Cannot retrieve scaffolds before initialising the "
560 + "scaffold library.";
561 throw new DENOPTIMException(msg);
562 }
563 break;
564 case FRAGMENT:
565 if (fragmentLib == null)
566 {
567 msg = "Cannot retrieve fragments before initialising the "
568 + "fragment library.";
569 throw new DENOPTIMException(msg);
570 }
571 break;
572 case CAP:
573 if (cappingLib == null)
574 {
575 msg = "Cannot retrieve capping groups before initialising"
576 + "the library of capping groups.";
577 throw new DENOPTIMException(msg);
578 }
579 break;
580
581 default:
582 throw new DENOPTIMException("Cannot find building block of "
583 + "type '" + bbType + "' in the fragment space.");
584 }
585
586 Vertex originalVrtx = null;
587 switch (bbType)
588 {
589 case SCAFFOLD:
590 if (bbIdx >-1 && bbIdx < scaffoldLib.size())
591 {
592 originalVrtx = scaffoldLib.get(bbIdx);
593 }
594 else
595 {
596 msg = "Mismatch between scaffold bbIdx (" + bbIdx
597 + ") and size of the library (" + scaffoldLib.size()
598 + "). FragType: " + bbType;
599 settings.getLogger().log(Level.SEVERE, msg);
600 throw new DENOPTIMException(msg);
601 }
602 break;
603
604 case FRAGMENT:
605 if (bbIdx >-1 && bbIdx < fragmentLib.size())
606 {
607 originalVrtx = fragmentLib.get(bbIdx);
608 }
609 else
610 {
611 msg = "Mismatch between fragment bbIdx (" + bbIdx
612 + ") and size of the library (" + fragmentLib.size()
613 + "). FragType: " + bbType;
614 settings.getLogger().log(Level.SEVERE, msg);
615 throw new DENOPTIMException(msg);
616 }
617 break;
618
619 case CAP:
620 if (bbIdx >-1 && bbIdx < cappingLib.size())
621 {
622 originalVrtx = cappingLib.get(bbIdx);
623 }
624 else
625 {
626 msg = "Mismatch between capping group bbIdx " + bbIdx
627 + ") and size of the library (" + cappingLib.size()
628 + "). FragType: " + bbType;
629 settings.getLogger().log(Level.SEVERE, msg);
630 throw new DENOPTIMException(msg);
631 }
632 break;
633
634 case UNDEFINED:
635 msg = "Attempting to take UNDEFINED type of building block from "
636 + "fragment library.";
637 settings.getLogger().log(Level.WARNING, msg);
638 if (bbIdx < fragmentLib.size())
639 {
640 originalVrtx = fragmentLib.get(bbIdx);
641 }
642 else
643 {
644 msg = "Mismatch between fragment bbIdx (" + bbIdx
645 + ") and size of the library (" + fragmentLib.size()
646 + "). FragType: " + bbType;
647 settings.getLogger().log(Level.SEVERE, msg);
648 throw new DENOPTIMException(msg);
649 }
650 break;
651
652 default:
653 msg = "Unknown type of fragment '" + bbType + "'.";
654 settings.getLogger().log(Level.SEVERE, msg);
655 throw new DENOPTIMException(msg);
656 }
657 Vertex clone = originalVrtx.clone();
658
660
661 clone.setBuildingBlockId(bbIdx);
662 if (originalVrtx.getBuildingBlockId() != bbIdx)
663 {
664 settings.getLogger().log(Level.WARNING, "Mismatch between building "
665 + "block ID ("
666 + originalVrtx.getBuildingBlockId() + ") and position in "
667 + "the list of building blocks (" + bbIdx + ") for type "
668 + bbType + ".");
669 }
670 return clone;
671 }
672
673//------------------------------------------------------------------------------
674
681 public int getCappingFragment(APClass rcnCap)
682 {
683 if (rcnCap == null)
684 return -1;
685
686 ArrayList<Integer> reacFrags = getCompatibleCappingFragments(rcnCap);
687
688 int fapidx = -1;
689 if (reacFrags.size() > 0)
690 {
691 fapidx = settings.getRandomizer().randomlyChooseOne(reacFrags);
692 }
693
694 return fapidx;
695 }
696
697//------------------------------------------------------------------------------
698
705 public ArrayList<Integer> getCompatibleCappingFragments(
706 APClass cmpReac)
707 {
708 ArrayList<Integer> lstFragIdx = new ArrayList<>();
709 for (int i=0; i<cappingLib.size(); i++)
710 {
711 Vertex mol = getCappingLibrary().get(i);
712 ArrayList<APClass> lstRcn = mol.getAllAPClasses();
713 if (lstRcn.contains(cmpReac))
714 lstFragIdx.add(i);
715 }
716 return lstFragIdx;
717 }
718
719//------------------------------------------------------------------------------
720
727 {
728 int chosenIdx = settings.getRandomizer().nextInt(scaffoldLib.size());
729 Vertex scaffold = null;
730 try
731 {
732 scaffold = Vertex.newVertexFromLibrary(
733 GraphUtils.getUniqueVertexIndex(),chosenIdx,
734 BBType.SCAFFOLD, this);
735 } catch (DENOPTIMException e)
736 {
737 //This cannot happen!
738 }
739 return scaffold;
740 }
741
742//------------------------------------------------------------------------------
743
744 public ArrayList<Vertex> getScaffoldLibrary()
745 {
746 return scaffoldLib;
747 }
748
749//------------------------------------------------------------------------------
750
751 public ArrayList<Vertex> getFragmentLibrary()
752 {
753 return fragmentLib;
754 }
755
756//------------------------------------------------------------------------------
757
758 public ArrayList<Vertex> getCappingLibrary()
759 {
760 return cappingLib;
761 }
762
763//------------------------------------------------------------------------------
764
770 public ArrayList<Integer> getCappingGroupsWithAPClass(APClass capApCls)
771 {
772 ArrayList<Integer> selected = new ArrayList<>();
773 for (int i = 0; i < cappingLib.size(); i++)
774 {
775 APClass apc = cappingLib.get(i).getAP(0).getAPClass();
776 if (apc.equals(capApCls))
777 {
778 selected.add(i);
779 }
780 }
781 return selected;
782 }
783
784//------------------------------------------------------------------------------
785
794 {
795 for (int i = 0; i < cappingLib.size(); i++)
796 {
797 APClass apc = cappingLib.get(i).getAP(0).getAPClass();
798 if (apc.equals(capApCls))
799 {
800 try
801 {
803 } catch (DENOPTIMException e)
804 {
805 //This cannot happen
806 }
807 }
808 }
809 return null;
810 }
811
812//------------------------------------------------------------------------------
813
824 public void importCompatibilityMatrixFromFile(String inFile)
825 throws DENOPTIMException
826 {
827 setCompatibilityMatrix(new HashMap<APClass, ArrayList<APClass>>());
828 setCappingMap(new HashMap<APClass, APClass>());
829 setForbiddenEndList(new HashSet<APClass>());
832 }
833
834//------------------------------------------------------------------------------
835
843 public void importRCCompatibilityMatrixFromFile(String inFile)
844 throws DENOPTIMException
845 {
846 setRCCompatibilityMatrix(new HashMap<APClass, ArrayList<APClass>>());
848 }
849
850//------------------------------------------------------------------------------
851
852 public HashMap<APClass, ArrayList<APClass>> getCompatibilityMatrix()
853 {
855 }
856
857//------------------------------------------------------------------------------
858
865 public ArrayList<APClass> getCompatibleAPClasses(APClass apc)
866 {
867 if (apClassCompatibilityMatrix!= null && apClassCompatibilityMatrix.containsKey(apc))
868 {
869 return apClassCompatibilityMatrix.get(apc);
870 }
871 return new ArrayList<APClass>();
872 }
873
874//------------------------------------------------------------------------------
875
883 public HashMap<APClass, ArrayList<APClass>> getRCCompatibilityMatrix()
884 {
885 return rcCompatMap;
886 }
887
888//------------------------------------------------------------------------------
889
890 public HashMap<APClass, APClass> getCappingMap()
891 {
892 return cappingMap;
893 }
894
895//------------------------------------------------------------------------------
896
904 {
905 return cappingMap.get(srcApClass);
906 }
907
908//------------------------------------------------------------------------------
909
910 public Set<APClass> getForbiddenEndList()
911 {
912 return forbiddenEndList;
913 }
914
915//------------------------------------------------------------------------------
916
926 public Set<APClass> getAllAPClassesFromCPMap()
927 {
928 return apClassCompatibilityMatrix.keySet();
929 }
930
931//------------------------------------------------------------------------------
932
933 public HashMap<Integer, ArrayList<Integer>> getMapOfFragsPerNumAps()
934 {
935 return fragPoolPerNumAP;
936 }
937
938//------------------------------------------------------------------------------
939
947 public ArrayList<Integer> getFragsWithNumAps(int nAps)
948 {
949 ArrayList<Integer> lst = new ArrayList<>();
950 if (fragPoolPerNumAP.containsKey(nAps))
951 {
952 lst = fragPoolPerNumAP.get(nAps);
953 }
954 return lst;
955 }
956
957//------------------------------------------------------------------------------
958
966 public ArrayList<APClass> getAPClassesPerFragment(int fragId)
967 {
968 synchronized (LOCK)
969 {
970 return apClassesPerFrag.get(fragId);
971 }
972 }
973
974//------------------------------------------------------------------------------
975
986 public ArrayList<IdFragmentAndAP> getFragsWithAPClass(APClass apc)
987 {
988 ArrayList<IdFragmentAndAP> lst = new ArrayList<IdFragmentAndAP>();
989
990 synchronized (LOCK)
991 {
992 if (fragsApsPerApClass.containsKey(apc))
993 {
994 for (ArrayList<Integer> idxs : fragsApsPerApClass.get(apc))
995 {
996 IdFragmentAndAP apId = new IdFragmentAndAP(-1, // vertexId
997 idxs.get(0), // MolId,
998 BBType.FRAGMENT, idxs.get(1), // ApId
999 -1, // noVSym
1000 -1);// noAPSym
1001 lst.add(apId);
1002 }
1003 }
1004 }
1005 return lst;
1006 }
1007
1008//------------------------------------------------------------------------------
1009
1016 public ArrayList<Vertex> getVerticesWithAPClass(APClass apc)
1017 {
1018 ArrayList<Vertex> lst = new ArrayList<Vertex>();
1019
1020 synchronized (LOCK)
1021 {
1022 if (fragsApsPerApClass.containsKey(apc))
1023 {
1024 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1025 {
1026 Vertex v = fragmentLib.get(idxs.get(0));
1027 lst.add(v);
1028 }
1029 }
1030 }
1031 return lst;
1032 }
1033
1034//------------------------------------------------------------------------------
1035
1043 public List<Vertex> getVerticesWithAPClasses(Set<APClass> apcs)
1044 {
1045 List<Vertex> lst = new ArrayList<Vertex>();
1046
1047 synchronized (LOCK)
1048 {
1049 for (APClass apc : apcs)
1050 {
1051 if (!fragsApsPerApClass.containsKey(apc))
1052 {
1053 break;
1054 }
1055
1056 // NB: the list is over APs, so there can be duplicate vertexes
1057 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1058 {
1059 Vertex v = fragmentLib.get(idxs.get(0));
1060 if (!lst.contains(v) && v.getAllAPClasses().containsAll(apcs))
1061 lst.add(v);
1062 }
1063
1064 // NB: we mean to do only one loop
1065 break;
1066 }
1067 }
1068 return lst;
1069 }
1070
1071//------------------------------------------------------------------------------
1072
1081 public List<Vertex> getVerticesWithAPFingerprint(
1082 Map<APClass,Integer> apcCounts)
1083 {
1084 List<Vertex> matches = new ArrayList<Vertex>();
1085 for (Vertex candidate : getVerticesWithAPClasses(apcCounts.keySet()))
1086 {
1087 boolean isMatch = true;
1088 for (APClass apc : apcCounts.keySet())
1089 {
1090 if (apcCounts.get(apc) >
1091 candidate.getAttachmentPoints().stream().filter(
1092 ap -> ap.getAPClass().equals(apc)).count())
1093 {
1094 isMatch = false;
1095 break;
1096 }
1097 }
1098 if (isMatch)
1099 matches.add(candidate);
1100 }
1101 return matches;
1102 }
1103
1104//------------------------------------------------------------------------------
1105
1114 public List<Vertex> getVerticesWithAPClassStartingWith(String root)
1115 {
1116 List<Vertex> lst = new ArrayList<Vertex>();
1117 synchronized (LOCK)
1118 {
1119 for (APClass apc : fragsApsPerApClass.keySet())
1120 {
1121 if (!apc.toString().startsWith(root))
1122 continue;
1123 for (List<Integer> idxs : fragsApsPerApClass.get(apc))
1124 {
1125 Vertex v = fragmentLib.get(idxs.get(0));
1126 if (!lst.contains(v))
1127 lst.add(v);
1128 }
1129 }
1130 }
1131 return lst;
1132 }
1133
1134//------------------------------------------------------------------------------
1135
1144 public ArrayList<Vertex> getFragmentsCompatibleWithTheseAPs(
1145 ArrayList<IdFragmentAndAP> srcAPs)
1146 {
1147 // First we get all possible APs on any fragment
1148 ArrayList<IdFragmentAndAP> compatFragAps =
1150
1151 // then keep unique fragment identifiers, and store unique
1152 Set<Integer> compatFragIds = new HashSet<Integer>();
1153 for (IdFragmentAndAP apId : compatFragAps)
1154 {
1155 compatFragIds.add(apId.getVertexMolId());
1156 }
1157
1158 // Then we pack-up the selected list of fragments
1159 ArrayList<Vertex> compatFrags = new ArrayList<Vertex>();
1160 for (Integer fid : compatFragIds)
1161 {
1162 try {
1163 compatFrags.add(getVertexFromLibrary(BBType.FRAGMENT, fid));
1164 } catch (DENOPTIMException e) {
1165 settings.getLogger().log(Level.WARNING, "Exception while trying "
1166 + "to get fragment '" + fid + "'!");
1167 e.printStackTrace();
1168 }
1169 }
1170 return compatFrags;
1171 }
1172
1173//------------------------------------------------------------------------------
1174
1183 public List<Vertex> getRCVsWithAPClass(APClass apc)
1184 {
1185 List<Vertex> chosenRCVs = new ArrayList<Vertex>();
1186 for (Vertex rcv : getRCVs())
1187 {
1188 // NB: RCVs must have only one attachment point
1189 if (apc.equals(rcv.getAP(0).getAPClass()))
1190 {
1191 Vertex copyOfRCV = null;
1192 try
1193 {
1194 copyOfRCV = getVertexFromLibrary(rcv.getBuildingBlockType(),
1195 rcv.getBuildingBlockId());
1196 chosenRCVs.add(copyOfRCV);
1197 } catch (DENOPTIMException e)
1198 {
1199 // This should never happen because we have already taken
1200 // the BB from BBSpace.
1201 e.printStackTrace();
1202 }
1203 }
1204 }
1205 return chosenRCVs;
1206 }
1207
1208//------------------------------------------------------------------------------
1209
1218 public List<Vertex> getRCVsForAPClass(APClass apc)
1219 {
1220 List<Vertex> chosenRCVs = new ArrayList<Vertex>();
1221 if (!getCompatibilityMatrix().containsKey(apc))
1222 {
1223 return chosenRCVs;
1224 }
1225 List<APClass> apcsCompatWithSrcAP = getCompatibilityMatrix().get(apc);
1226 for (Vertex rcv : getRCVs())
1227 {
1228 // NB: RCVs must have only one attachment point
1229 if (apcsCompatWithSrcAP.contains(rcv.getAP(0).getAPClass()))
1230 {
1231 Vertex copyOfRCV = null;
1232 try
1233 {
1234 copyOfRCV = getVertexFromLibrary(rcv.getBuildingBlockType(),
1235 rcv.getBuildingBlockId());
1236 chosenRCVs.add(copyOfRCV);
1237 } catch (DENOPTIMException e)
1238 {
1239 // This should never happen because we have already taken
1240 // the BB from BBSpace.
1241 e.printStackTrace();
1242 }
1243 }
1244 }
1245 return chosenRCVs;
1246 }
1247
1248//------------------------------------------------------------------------------
1249
1258 public ArrayList<AttachmentPoint> getAPsCompatibleWithThese(
1259 ArrayList<AttachmentPoint> srcAPs)
1260 {
1261 ArrayList<AttachmentPoint> compAps =
1262 new ArrayList<AttachmentPoint>();
1263 boolean first = true;
1264 for (AttachmentPoint ap : srcAPs)
1265 {
1266 ArrayList<AttachmentPoint> compForOne =
1267 getAPsCompatibleWithClass(ap.getAPClass());
1268
1269 if (first)
1270 {
1271 compAps.addAll(compForOne);
1272 first = false;
1273 continue;
1274 }
1275
1276 ArrayList<AttachmentPoint> toKeep =
1277 new ArrayList<AttachmentPoint>();
1278 for (AttachmentPoint candAp : compAps)
1279 {
1280 for (AttachmentPoint newCand : compForOne)
1281 {
1282 if (newCand == candAp)
1283 {
1284 toKeep.add(candAp);
1285 break;
1286 }
1287 }
1288 }
1289
1290 compAps = toKeep;
1291
1292 if (compAps.size()==0)
1293 {
1294 break;
1295 }
1296 }
1297 return compAps;
1298 }
1299
1300//------------------------------------------------------------------------------
1301
1309 public ArrayList<IdFragmentAndAP> getFragAPsCompatibleWithTheseAPs(
1310 ArrayList<IdFragmentAndAP> srcAPs)
1311 {
1312 ArrayList<IdFragmentAndAP> compFrAps = new ArrayList<IdFragmentAndAP>();
1313 boolean first = true;
1314 for (IdFragmentAndAP apId : srcAPs)
1315 {
1316 APClass srcApCls = getAPClassForFragment(apId);
1317 ArrayList<IdFragmentAndAP> compForOne =
1319
1320 if (first)
1321 {
1322 compFrAps.addAll(compForOne);
1323 first = false;
1324 continue;
1325 }
1326
1327 ArrayList<IdFragmentAndAP> toKeep =
1328 new ArrayList<IdFragmentAndAP>();
1329 for (IdFragmentAndAP candAp : compFrAps)
1330 {
1331 for (IdFragmentAndAP newId : compForOne)
1332 {
1333 if (newId.sameFragAndAp(candAp))
1334 {
1335 toKeep.add(candAp);
1336 break;
1337 }
1338 }
1339 }
1340
1341 compFrAps = toKeep;
1342
1343 if (compFrAps.size() == 0)
1344 {
1345 break;
1346 }
1347 }
1348
1349 return compFrAps;
1350 }
1351
1352//------------------------------------------------------------------------------
1353
1362 public ArrayList<AttachmentPoint> getAPsCompatibleWithClass(
1363 APClass aPC1)
1364 {
1365 ArrayList<AttachmentPoint> compatAps =
1366 new ArrayList<AttachmentPoint>();
1367
1368 // Take the compatible AP classes
1369 ArrayList<APClass> compatApClasses = getCompatibleAPClasses(aPC1);
1370
1371 // Find all APs with a compatible class
1372 if (compatApClasses != null)
1373 {
1374 for (APClass klass : compatApClasses)
1375 {
1376 ArrayList<Vertex> vrtxs = getVerticesWithAPClass(klass);
1377 for (Vertex v : vrtxs)
1378 {
1379 for (AttachmentPoint ap : v.getAttachmentPoints())
1380 {
1381 if (ap.getAPClass() == klass)
1382 {
1383 compatAps.add(ap);
1384 }
1385 }
1386 }
1387 }
1388 }
1389
1390 if (compatAps.size()==0)
1391 {
1392 settings.getLogger().log(Level.WARNING,"No compatible "
1393 + "AP found in the fragment space for APClass '"
1394 + aPC1 + "'.");
1395 }
1396
1397 return compatAps;
1398 }
1399
1400//------------------------------------------------------------------------------
1401
1409 public ArrayList<IdFragmentAndAP> getFragAPsCompatibleWithClass(
1410 APClass aPC1)
1411 {
1412 ArrayList<IdFragmentAndAP> compatFragAps =
1413 new ArrayList<IdFragmentAndAP>();
1414
1415 // Take the compatible AP classes
1416 ArrayList<APClass> compatApClasses = getCompatibleAPClasses(aPC1);
1417
1418 // Find all APs with any compatible class
1419 if (compatApClasses != null)
1420 {
1421 for (APClass compClass : compatApClasses)
1422 {
1423 compatFragAps.addAll(getFragsWithAPClass(compClass));
1424 }
1425 }
1426 return compatFragAps;
1427 }
1428
1429//------------------------------------------------------------------------------
1430
1442 public boolean imposeSymmetryOnAPsOfClass(APClass apClass)
1443 {
1444 boolean res = true;
1445 if (hasSymmetryConstrain(apClass))
1446 {
1447 if (getSymmetryConstrain(apClass) < (1.0
1449 {
1450 res = false;
1451 }
1452 } else
1453 {
1455 {
1456 res = false;
1457 }
1458 }
1459 return res;
1460 }
1461
1462//------------------------------------------------------------------------------
1463
1473 public boolean hasSymmetryConstrain(APClass apClass)
1474 {
1475 if (symmConstraints==null)
1476 return false;
1477 return symmConstraints.containsKey(apClass);
1478 }
1479
1480//------------------------------------------------------------------------------
1481
1492 public double getSymmetryConstrain(APClass apClass)
1493 {
1494 return symmConstraints.get(apClass);
1495 }
1496
1497//------------------------------------------------------------------------------
1498
1499 public void setScaffoldLibrary(ArrayList<Vertex> lib)
1500 {
1501 scaffoldLib = new ArrayList<Vertex>();
1503 }
1504
1505 public void setFragmentLibrary(ArrayList<Vertex> lib)
1506 {
1507 fragmentLib = new ArrayList<Vertex>();
1509 }
1510
1511//------------------------------------------------------------------------------
1512
1513 public void setCappingLibrary(ArrayList<Vertex> lib)
1514 {
1515 cappingLib = new ArrayList<Vertex>();
1517 }
1518
1519//------------------------------------------------------------------------------
1520
1521 public void setCompatibilityMatrix(HashMap<APClass, ArrayList<APClass>> map)
1522 {
1524 }
1525
1526//------------------------------------------------------------------------------
1527
1528 public void setRCCompatibilityMatrix(HashMap<APClass,
1529 ArrayList<APClass>> map)
1530 {
1531 rcCompatMap = map;
1532 }
1533
1534//------------------------------------------------------------------------------
1535
1536 public void setCappingMap(HashMap<APClass, APClass> map)
1537 {
1538 cappingMap = map;
1539 }
1540
1541//------------------------------------------------------------------------------
1542
1543 public void setForbiddenEndList(Set<APClass> lst)
1544 {
1545 forbiddenEndList = lst;
1546 }
1547
1548//------------------------------------------------------------------------------
1549
1550 public void setSymmConstraints(HashMap<APClass, Double> map)
1551 {
1552 symmConstraints = map;
1553 }
1554
1555//------------------------------------------------------------------------------
1556
1561 public void clearAll()
1562 {
1563 scaffoldLib = null;
1564 fragmentLib = null;
1565 cappingLib = null;
1567 rcCompatMap = null;
1568 cappingMap = null;
1569 forbiddenEndList = null;
1570 fragPoolPerNumAP = new HashMap<Integer,ArrayList<Integer>>();
1571 apClassesPerFrag = new HashMap<Integer,ArrayList<APClass>>();
1572 fragsApsPerApClass = new HashMap<APClass,ArrayList<ArrayList<Integer>>>();
1573 symmConstraints = null;
1574 isValid = false;
1575 }
1576
1577//------------------------------------------------------------------------------
1578
1588 public void appendVerticesToLibrary(ArrayList<Vertex> list,
1589 Vertex.BBType bbt, ArrayList<Vertex> library)
1590 {
1591 for (Vertex v : list)
1592 {
1593 appendVertexToLibrary(v, bbt, library);
1594 }
1595 }
1596
1597//------------------------------------------------------------------------------
1598
1609 Vertex.BBType bbt, ArrayList<Vertex> library)
1610 {
1611 v.setBuildingBlockId(library.size());
1612 v.setBuildingBlockType(bbt);
1613 library.add(v);
1614 if (bbt == BBType.FRAGMENT)
1615 {
1616 classifyFragment(v, library.size()-1);
1617 }
1618 }
1619
1620//------------------------------------------------------------------------------
1621
1633 //TODO: need something to prevent memory overload:
1634 // -> keep only some templates?
1635 // -> remove those who did not lead to good population members?
1636 // -> remove redundant? The highest-simmetry principle (i.e., rather than
1637 // keeping a template as it is, we'd like to keep its highest symmetry
1638 // isomorphic) would be the first thing to do.
1639
1641 {
1642 addFusedRingsToFragmentLibrary(graph,true,true);
1643 }
1644
1645//------------------------------------------------------------------------------
1646
1660 boolean addIfScaffold, boolean addIfFragment)
1661 {
1662 addFusedRingsToFragmentLibrary(graph, addIfScaffold, addIfFragment, null);
1663 }
1664
1665//------------------------------------------------------------------------------
1666
1685 //TODO: need something to prevent memory overload:
1686 // -> keep only some templates?
1687 // -> remove those who did not lead to good population members?
1688 // -> remove redundant? The highest-symmetry principle (i.e., rather than
1689 // keeping a template as it is, we'd like to keep its highest symmetry
1690 // isomorphic) would be the first thing to do.
1691
1693 boolean addIfScaffold, boolean addIfFragment,
1694 IAtomContainer wholeMol)
1695 {
1696 List<DGraph> subgraphs = null;
1697 try
1698 {
1699 subgraphs = graph.extractPattern(GraphPattern.RING);
1700 } catch (DENOPTIMException e1)
1701 {
1702 settings.getLogger().log(Level.WARNING,"Failed to extract "
1703 + "fused ring patters.");
1704 e1.printStackTrace();
1705 }
1706
1707 for (DGraph g : subgraphs)
1708 {
1709 BBType type = g.hasScaffoldTypeVertex() ?
1710 BBType.SCAFFOLD :
1712
1713 if (!addIfFragment && type == BBType.FRAGMENT)
1714 {
1715 continue;
1716 }
1717 if (!addIfScaffold && type == BBType.SCAFFOLD)
1718 {
1719 continue;
1720 }
1721
1722 ArrayList<Vertex> library = type == BBType.FRAGMENT ?
1724
1725 synchronized (LOCK)
1726 {
1727 if (!hasIsomorph(g, type))
1728 {
1729 //TODO: try to transform the template into its isomorphic
1730 // with highest symmetry, and define the symmetric sets.
1731 // Such enhancement would facilitate the creation of
1732 // symmetric graphs from templates generated on the fly.
1733
1734 Template t = new Template(type);
1735 t.setInnerGraph(g);
1736
1737 boolean has3Dgeometry = false;
1738 IAtomContainer subIAC = null;
1739 if (wholeMol!=null)
1740 {
1741 try
1742 {
1744 wholeMol, g, graph, settings.getLogger(),
1746 t.setIAtomContainer(subIAC,true);
1747 has3Dgeometry = true;
1748 } catch (DENOPTIMException e1)
1749 {
1750 e1.printStackTrace();
1751 ArrayList<DGraph> lst = new ArrayList<>();
1752 lst.add(graph);
1753 lst.add(g);
1754 String forDebugFile = "failedExtractIAC_"
1755 + graph.getGraphId() + ".json";
1756 try
1757 {
1759 new File(forDebugFile), lst);
1760 settings.getLogger().log(Level.WARNING,
1761 "WARNING: failed to extract "
1762 + "molecular representation of graph. "
1763 + "See file '" + forDebugFile + "'.");
1764 } catch (DENOPTIMException e)
1765 {
1766 settings.getLogger().log(Level.WARNING,
1767 "WARNING: failed to extract "
1768 + "molecular representation of graph, "
1769 + "and failed to write graph to file.");
1770 }
1771 }
1772 }
1773
1774 String msg = "Adding new template (Inner Graph id: "
1775 + t.getInnerGraph().getGraphId() + ") to the "
1776 + "library of " + type + "s. The template is "
1777 + "generated from graph " + graph.getGraphId();
1778 Candidate source = graph.getCandidateOwner();
1779 if (source != null)
1780 msg = msg + " candidate " + source.getName();
1781 else
1782 msg = msg + ".";
1783 settings.getLogger().log(Level.INFO, msg);
1784
1785 appendVertexToLibrary(t, type, library);
1786 if (type == BBType.FRAGMENT)
1787 {
1788 classifyFragment(t,library.size()-1);
1789 }
1790
1791 String destFileName = type == BBType.FRAGMENT ?
1794 try
1795 {
1796 if (has3Dgeometry)
1797 {
1798 DenoptimIO.writeSDFFile(destFileName,subIAC,true);
1799 } else {
1800 DenoptimIO.writeGraphToSDF(new File(destFileName),
1801 g, true, false, settings.getLogger(),
1803 }
1804 } catch (DENOPTIMException e)
1805 {
1806 e.printStackTrace();
1807 settings.getLogger().log(Level.WARNING, "WARNING: "
1808 + "failed to write newly "
1809 + "generated " + type + " to file '"
1810 + destFileName + "'.");
1811 }
1812 }
1813 }
1814 }
1815 }
1816
1817//------------------------------------------------------------------------------
1818
1828 public boolean hasIsomorph(DGraph graph, BBType type) {
1829 return (type == BBType.SCAFFOLD ? scaffoldLib : fragmentLib)
1830 .stream()
1831 .filter(v -> v instanceof Template)
1832 .map(t -> (Template) t)
1834 .anyMatch(graph::isIsomorphicTo);
1835 }
1836
1837//------------------------------------------------------------------------------
1838
1844 public void registerRCV(Vertex v)
1845 {
1846 rcvs.add(v);
1847 }
1848
1849//------------------------------------------------------------------------------
1850
1855 public ArrayList<Vertex> getRCVs()
1856 {
1857 return rcvs;
1858 }
1859
1860//------------------------------------------------------------------------------
1861
1872 public List<APMapping> mapAPClassCompatibilities(
1873 List<AttachmentPoint> listA,
1874 List<AttachmentPoint> listB, int maxCombinations)
1875 {
1876 Map<AttachmentPoint,List<AttachmentPoint>> apCompatilities =
1877 new HashMap<AttachmentPoint,List<AttachmentPoint>>();
1878
1879 for (AttachmentPoint apA : listA)
1880 {
1881 for (AttachmentPoint apB : listB)
1882 {
1883 boolean compatible = false;
1885 {
1886 if (apA.getAPClass().isCPMapCompatibleWith(apB.getAPClass(),
1887 this))
1888 {
1889 compatible = true;
1890 }
1891 } else {
1892 compatible = true;
1893 }
1894 if (compatible)
1895 {
1896 if (apCompatilities.containsKey(apA))
1897 {
1898 apCompatilities.get(apA).add(apB);
1899 } else {
1900 List<AttachmentPoint> lst =
1901 new ArrayList<AttachmentPoint>();
1902 lst.add(apB);
1903 apCompatilities.put(apA,lst);
1904 }
1905 }
1906 }
1907 }
1908
1909 // This is used only to keep a sorted list of the map keys
1910 List<AttachmentPoint> keys =
1911 new ArrayList<AttachmentPoint>(
1912 apCompatilities.keySet());
1913
1914 // Get all possible combinations of compatible AP pairs
1915 List<APMapping> apMappings = new ArrayList<APMapping>();
1916 if (keys.size() > 0)
1917 {
1918 int currentKey = 0;
1919 APMapping currentMapping = new APMapping();
1920 FragmentSpaceUtils.recursiveCombiner(keys, currentKey,
1921 apCompatilities, currentMapping, apMappings, true,
1922 maxCombinations);
1923 }
1924
1925 return apMappings;
1926 }
1927
1928//------------------------------------------------------------------------------
1929
1938 public void classifyFragment(Vertex frg, int fragId)
1939 {
1940 // Classify according to number of APs
1941 int nAps = frg.getFreeAPCount();
1942 if (nAps != 0)
1943 {
1944 if (getMapOfFragsPerNumAps().containsKey(nAps))
1945 {
1946 getFragsWithNumAps(nAps).add(fragId);
1947 }
1948 else
1949 {
1950 ArrayList<Integer> lst = new ArrayList<>();
1951 lst.add(fragId);
1952 getMapOfFragsPerNumAps().put(nAps,lst);
1953 }
1954 }
1955
1957 {
1958 // Collect classes per fragment
1959 ArrayList<APClass> lstAPC = frg.getAllAPClasses();
1960 synchronized (LOCK)
1961 {
1962 apClassesPerFrag.put(fragId,lstAPC);
1963 }
1964
1965 // Classify according to AP-Classes
1966 List<AttachmentPoint> lstAPs = frg.getAttachmentPoints();
1967
1968 for (int j=0; j<lstAPs.size(); j++)
1969 {
1970 AttachmentPoint ap = lstAPs.get(j);
1971 ArrayList<Integer> apId = new ArrayList<Integer>();
1972 apId.add(fragId);
1973 apId.add(j);
1974 APClass cls = ap.getAPClass();
1975
1976 if (!ap.isAvailable())
1977 {
1978 continue;
1979 }
1980
1981 synchronized (LOCK)
1982 {
1983 if (fragsApsPerApClass.containsKey(cls))
1984 {
1985 fragsApsPerApClass.get(cls).add(apId);
1986 } else {
1987 ArrayList<ArrayList<Integer>> outLst =
1988 new ArrayList<ArrayList<Integer>>();
1989 outLst.add(apId);
1990 fragsApsPerApClass.put(cls,outLst);
1991 }
1992 }
1993 }
1994
1995 if (frg.isRCV())
1996 registerRCV(frg);
1997 }
1998 }
1999
2000//------------------------------------------------------------------------------
2001
2009 throws DENOPTIMException
2010 {
2011 for (int j=0; j<getFragmentLibrary().size(); j++)
2012 {
2013 Vertex frag = getFragmentLibrary().get(j);
2014 classifyFragment(frag,j);
2015 }
2016 }
2017
2018//------------------------------------------------------------------------------
2019
2028 public static Vertex getPolarizedRCV(boolean polarity)
2029 {
2031 if (!polarity)
2032 apc = APClass.RCACLASSMINUS;
2033
2034 Fragment rcv = new Fragment();
2035 Atom atom = new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(apc),
2036 new Point3d());
2037 rcv.addAtom(atom);
2038 rcv.addAP(0, new Point3d(1.5, 0.0, 0.0), apc);
2039 rcv.setAsRCV(true);
2040 return rcv;
2041 }
2042
2043//------------------------------------------------------------------------------
2044
2045}
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.
Logger getLogger()
Returns the logger associated with this fragment space's parameters.
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:104
List< DGraph > extractPattern(GraphPattern pattern)
Extracts subgraphs that match the provided pattern.
Definition: DGraph.java:5157
Candidate getCandidateOwner()
Returns the reference of the candidate item that is defined by this graph.
Definition: DGraph.java:259
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:36
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