20package denoptim.graph;
24import java.lang.reflect.Type;
25import java.util.ArrayDeque;
26import java.util.ArrayList;
27import java.util.Arrays;
28import java.util.Collection;
29import java.util.Collections;
30import java.util.Comparator;
31import java.util.HashMap;
32import java.util.HashSet;
33import java.util.Iterator;
34import java.util.LinkedHashMap;
37import java.util.Map.Entry;
38import java.util.Queue;
40import java.util.concurrent.atomic.AtomicInteger;
41import java.util.function.Function;
42import java.util.logging.Level;
43import java.util.logging.Logger;
44import java.util.stream.Collectors;
45import java.util.stream.Stream;
47import org.jgrapht.alg.isomorphism.VF2GraphIsomorphismInspector;
48import org.jgrapht.graph.DefaultUndirectedGraph;
49import org.openscience.cdk.graph.ConnectivityChecker;
50import org.openscience.cdk.interfaces.IAtom;
51import org.openscience.cdk.interfaces.IAtomContainer;
53import com.google.gson.Gson;
54import com.google.gson.GsonBuilder;
55import com.google.gson.JsonArray;
56import com.google.gson.JsonDeserializationContext;
57import com.google.gson.JsonDeserializer;
58import com.google.gson.JsonElement;
59import com.google.gson.JsonObject;
60import com.google.gson.JsonParseException;
61import com.google.gson.JsonSerializationContext;
62import com.google.gson.JsonSerializer;
64import denoptim.constants.DENOPTIMConstants;
65import denoptim.exception.DENOPTIMException;
66import denoptim.fragspace.FragmentSpace;
67import denoptim.fragspace.FragmentSpaceParameters;
68import denoptim.graph.APClass.APClassDeserializer;
69import denoptim.graph.Edge.BondType;
70import denoptim.graph.Template.ContractLevel;
71import denoptim.graph.Vertex.BBType;
72import denoptim.graph.Vertex.DENOPTIMVertexDeserializer;
73import denoptim.graph.rings.ClosableChain;
74import denoptim.graph.rings.CyclicGraphHandler;
75import denoptim.graph.rings.PathSubGraph;
76import denoptim.graph.rings.RingClosingAttractor;
77import denoptim.graph.rings.RingClosureParameters;
78import denoptim.graph.simplified.Node;
79import denoptim.graph.simplified.NodeConnection;
80import denoptim.graph.simplified.UndirectedEdge;
81import denoptim.io.DenoptimIO;
82import denoptim.json.DENOPTIMgson;
83import denoptim.json.DENOPTIMgson.DENOPTIMExclusionStrategyNoAPMap;
84import denoptim.molecularmodeling.ThreeDimTreeBuilder;
85import denoptim.programs.RunTimeParameters;
86import denoptim.programs.RunTimeParameters.ParametersType;
87import denoptim.utils.GeneralUtils;
88import denoptim.utils.GraphConversionTool;
89import denoptim.utils.GraphEdit;
90import denoptim.utils.GraphUtils;
91import denoptim.utils.MoleculeUtils;
92import denoptim.utils.MutationType;
93import denoptim.utils.ObjectPair;
94import denoptim.utils.Randomizer;
95import denoptim.utils.RotationalSpaceUtils;
157 private DefaultUndirectedGraph<Vertex, UndirectedEdge>
163 private DefaultUndirectedGraph<Node, NodeConnection>
180 private static final String
SYM_ID =
"symmetryKey";
187 for (
Vertex v : this.gVertices)
188 v.setGraphOwner(
this);
190 gRings =
new ArrayList<>();
210 List<SymmetricVertexes> symSets)
214 this.symVertices = symSets;
234 gEdges =
new ArrayList<>();
235 gRings =
new ArrayList<>();
347 List<Vertex> lst =
new ArrayList<Vertex>();
352 ss.stream().forEach(i -> lst.add((
Vertex) i));
373 List<Vertex> uniqueVertices =
new ArrayList<>();
374 Map<String, List<Vertex>> pathMap =
new HashMap<>();
375 Set<Vertex> visited =
new HashSet<>();
378 AtomicInteger vrtxIdCounter =
new AtomicInteger();
379 AtomicInteger apIdCounter =
new AtomicInteger();
384 if (scaffold ==
null) scaffold = vertex;
386 boolean isVertexNew =
true;
387 Vertex matchedVertex =
null;
390 for (
Vertex uniqueVertex : uniqueVertices)
393 if (vertex.sameAs(uniqueVertex))
396 matchedVertex = uniqueVertex;
403 int vertexKey = vrtxIdCounter.getAndIncrement();
406 Map<AttachmentPoint, Integer> apKeys =
new HashMap<>();
411 if (!symAPs.isEmpty())
413 Integer sharedKey = apKeys.get(symAPs.get(0));
415 if (sharedKey ==
null) {
416 sharedKey = apIdCounter.getAndIncrement();
417 apKeys.put(symAPs.get(0), sharedKey);
420 symAp.setProperty(
SYM_ID, sharedKey);
425 int apKey = apIdCounter.getAndIncrement();
426 ap.setProperty(
SYM_ID, apKey);
431 uniqueVertices.
add(vertex);
441 for (
int i = 0; i < vertex.getAttachmentPoints().size(); i++) {
443 vertex.getAttachmentPoints().get(i);
452 if (scaffold ==
null) {
460 for (Map.Entry<String, List<Vertex>> entry : pathMap.entrySet()) {
494 if (visited.contains(current))
498 visited.add(current);
500 Integer vertexKey = (Integer) current.getProperty(
SYM_ID);
501 currentPath += vertexKey.toString();
504 pathMap.computeIfAbsent(currentPath, k ->
new ArrayList<>()).add(current);
510 if (ap.getEdgeUser()!=
null &&
511 !visited.contains(ap.getEdgeUser().getTrgAP().getOwner()))
513 Edge edge = ap.getEdgeUser();
879 this.symVertices.clear();
896 if (!Collections.disjoint(oldSS, symSet))
899 +
"there is already one that contains some of the same "
955 List<Vertex> list =
new ArrayList<Vertex>();
1008 if (e.getTrgAP().getOwner() == v0)
1010 ArrayList<Vertex> parentTree =
new ArrayList<>();
1012 return parentTree.get(parentTree.size()-1);
1042 List<Edge> edges =
new ArrayList<Edge>();
1045 if (e.getSrcAP().getOwner() == v)
1063 List<Edge> edges =
new ArrayList<Edge>();
1066 if (e.getTrgAP().getOwner() == v)
1084 ArrayList<Ring> rings =
new ArrayList<Ring>();
1105 ArrayList<Ring> rings =
new ArrayList<Ring>();
1108 boolean matchesAll =
true;
1109 for (
int i=0; i<vs.length; i++)
1111 if (!r.contains(vs[i]))
1129 ArrayList<Ring> rings =
new ArrayList<Ring>();
1132 if (r.containsID(vid))
1150 return gRings.size() > 0;
1168 return visited.size() ==
gVertices.size();
1200 boolean result =
false;
1203 if (r.containsID(vid))
1216 boolean result =
false;
1238 ArrayList<Vertex> rcvLst =
new ArrayList<Vertex>();
1261 ArrayList<Vertex> free =
new ArrayList<Vertex>();
1283 ArrayList<Vertex> used =
new ArrayList<Vertex>();
1326 BondType bndTypI = vI.getEdgeToParent().getBondType();
1327 BondType bndTypJ = vJ.getEdgeToParent().getBondType();
1341 if (bndTypI != bndTypJ)
1343 String s =
"Attempt to close rings is not compatible "
1344 +
"to the different bond type specified by the "
1345 +
"head and tail APs: (" + bndTypI +
"!="
1346 + bndTypJ +
" for vertices " + vI +
" "
1370 e.printStackTrace();
1372 ArrayList<Vertex> arrLst =
new ArrayList<Vertex>();
1395 +
"unique within the graph. VertexID '"
1396 + vertex.getVertexId()+
"' already present in graph "
1398 vertex.setGraphOwner(
this);
1427 for (
Ring r : rToRm)
1434 ArrayList<Edge> eToDel =
new ArrayList<>();
1435 for (
int i=0; i<
gEdges.size(); i++)
1448 for (
Edge e : eToDel)
1454 List<SymmetricVertexes> ssToRemove =
new ArrayList<SymmetricVertexes>();
1457 if (ss.contains(vertex))
1498 if (symSites.size() == 0)
1500 symSites.add(vertex);
1504 for (
Vertex oldLink : symSites)
1521 .getSrcAPThroughout();
1523 .getSrcAPThroughout();
1554 boolean foundLinkToParent =
false;
1557 if (ap.isAvailable() && !ap.isAvailableThroughout())
1559 if (!ap.isSrcInUserThroughout())
1560 foundLinkToParent =
true;
1563 if (!foundLinkToParent)
1576 ArrayList<AttachmentPoint> needyAPsOnChildren =
1577 new ArrayList<AttachmentPoint>();
1579 ArrayList<AttachmentPoint> freeAPsOnParent =
1580 new ArrayList<AttachmentPoint>();
1582 Map<AttachmentPoint,AttachmentPoint> apOnOldToNeedyAP =
1583 new HashMap<AttachmentPoint,AttachmentPoint>();
1586 if (!apOnOld.isAvailableThroughout())
1588 if (apOnOld.isSrcInUserThroughout())
1595 needyAPsOnChildren.add(needyAP);
1596 apOnOldToNeedyAP.put(apOnOld, needyAP);
1602 freeAPsOnParent.add(apOnParent);
1603 freeAPsOnParent.addAll(apOnParent.
getOwner()
1610 List<APMapping> mappings = fragSpace.mapAPClassCompatibilities(
1611 freeAPsOnParent, needyAPsOnChildren, 500);
1612 if (mappings.size() == 0)
1621 List<Integer> preferences =
new ArrayList<Integer>();
1623 for (
int i=0; i<needyAPsOnChildren.size(); i++)
1633 Vertex lastBeforeOwnerOfNeedy =
1635 if (r.contains(lastBeforeOwnerOfNeedy))
1637 preferences.set(i, preferences.get(i) + 1);
1643 int maxScore = Integer.MIN_VALUE;
1650 score = score + preferences.get(needyAPsOnChildren.indexOf(ap));
1652 if (score > maxScore)
1655 bestScoringMapping = apm;
1660 for (Entry<AttachmentPoint, AttachmentPoint> e :
1661 bestScoringMapping.entrySet())
1663 bestScoringMappingReverse.put(e.getValue(), e.getKey());
1668 ArrayList<Ring> ringsToRemove =
new ArrayList<Ring>();
1669 for (
Ring r : rToEdit)
1671 r.removeVertex(vertex);
1672 if (r.getSize() < 3)
1673 ringsToRemove.add(r);
1675 for (
Ring r : ringsToRemove)
1682 LinkedHashMap<AttachmentPoint,AttachmentPoint> newInReplaceOldInInTmpl =
1683 new LinkedHashMap<AttachmentPoint,AttachmentPoint>();
1684 List<AttachmentPoint> oldAPToRemoveFromTmpl =
1685 new ArrayList<AttachmentPoint>();
1688 if (oldAP.isAvailable())
1696 if (!oldAP.isAvailableThroughout())
1700 if (bestScoringMapping.keySet().contains(lAP))
1702 newInReplaceOldInInTmpl.put(
1703 bestScoringMapping.get(lAP), oldAP);
1704 }
else if (bestScoringMapping.values().contains(lAP))
1706 newInReplaceOldInInTmpl.put(
1707 bestScoringMappingReverse.get(lAP), oldAP);
1709 oldAPToRemoveFromTmpl.add(oldAP);
1712 oldAPToRemoveFromTmpl.add(oldAP);
1724 List<SymmetricVertexes> ssToRemove =
new ArrayList<SymmetricVertexes>();
1726 while (ssIter.hasNext())
1729 if (ss.contains(vertex))
1740 vertex.resetGraphOwner();
1743 List<AttachmentPoint> reconnettedApsOnChilds =
1744 new ArrayList<AttachmentPoint>();
1745 for (Entry<AttachmentPoint,AttachmentPoint> e :
1746 bestScoringMapping.entrySet())
1753 Edge edge =
new Edge(apOnParent,apOnChild,
1756 reconnettedApsOnChilds.add(apOnChild);
1763 newInReplaceOldInInTmpl.get(apOnParent),
1765 reconnettedApsOnChilds.add(apOnChild);
1770 newInReplaceOldInInTmpl.get(apOnChild),
1772 reconnettedApsOnChilds.add(apOnChild);
1779 + apOnChild +
"' seems connected to a template, "
1780 +
"no template was found. Possible bug!");
1799 if (!reconnettedApsOnChilds.contains(apOnChild))
1849 List<Vertex> rcvToReplace =
new ArrayList<Vertex>();
1850 List<AttachmentPoint> apToCap =
new ArrayList<AttachmentPoint>();
1854 && v.getEdgeToParent()!=
null)
1856 rcvToReplace.add(v);
1857 apToCap.add(v.getEdgeToParent().getSrcAP());
1860 for (
int i=0; i<rcvToReplace.size(); i++)
1862 Vertex v = rcvToReplace.get(i);
1866 APClass cappAPClass = fragSpace.getAPClassOfCappingVertex(
1869 if (cappAPClass !=
null)
1871 Vertex capVrt = fragSpace.getCappingVertexWithAPClass(
1896 while (ssIter.hasNext())
1899 String symmLabel = ss.hashCode() +
"-" + i;
1922 Map<String,List<Vertex>> collectedLabels =
new HashMap<>();
1927 String label = v.getProperty(
1929 if (collectedLabels.containsKey(label))
1931 collectedLabels.get(label).add(v);
1933 List<Vertex> lst =
new ArrayList<Vertex>();
1935 collectedLabels.put(label, lst);
1941 for (String label : collectedLabels.keySet())
1943 List<Vertex> symmvertices = collectedLabels.get(label);
1945 if (symmvertices.size()>1)
1948 for (
Vertex v : symmvertices)
1959 for (
Vertex v : symmvertices)
1964 for (
Vertex v : symmvertices)
2004 LinkedHashMap<AttachmentPoint,AttachmentPoint> apMap,
2007 for (
Vertex vToRemove : subGrpVrtxs)
2016 subGrpVrtxs.stream().filter(v -> v.getBuildingBlockType()==
BBType.
CAP)
2018 subGrpVrtxs.removeIf(v -> v.getBuildingBlockType()==
BBType.
CAP);
2019 if (subGrpVrtxs.size() == 0)
2022 +
"vertex in a subgraph to replace.");
2027 incomingGraph.reassignSymmetricLabels();
2034 List<List<Vertex>> compatibleSymSubGrps =
new ArrayList<List<Vertex>>();
2037 boolean skip =
false;
2038 for (
int iv=0; iv<subGrpVrtxs.size(); iv++)
2042 Vertex oriVs = subGrpVrtxs.get(iv);
2043 Vertex symVs = symmetricSubGrpVrtx.get(iv);
2050 oriVsChildren.removeIf(v -> v.getBuildingBlockType()==
BBType.
CAP);
2051 symVsChildren.removeIf(v -> v.getBuildingBlockType()==
BBType.
CAP);
2052 if (oriVsChildren.size()!=symVsChildren.size())
2058 for (
int ic=0; ic<oriVsChildren.size(); ic++)
2063 if (subGrpVrtxs.contains(oriVsChildren.get(ic)))
2070 if (oriVsChildren.get(ic).getBuildingBlockType()
2071 != symVsChildren.get(ic).getBuildingBlockType())
2079 compatibleSymSubGrps.add(symmetricSubGrpVrtx);
2081 if (compatibleSymSubGrps.size()==0)
2084 for (List<Vertex> verticesToRemove : compatibleSymSubGrps)
2089 List<Vertex> vertexAddedToThis =
new ArrayList<Vertex>(
2101 int vrtPosOnOld = subGrpVrtxs.indexOf(e.getKey().getOwner());
2102 int apPosOnOld = e.getKey().getIndexInOwner();
2104 vrtPosOnOld).getAP(apPosOnOld);
2106 int vrtPosOnNew = incomingGraph.indexOf(e.getValue().getOwner());
2109 vrtPosOnNew).
getAP(apPosOnNew);
2110 localApMap.put(apOnOld,apOnNew);
2140 if (subGrpVrtxs.stream().anyMatch(v -> v.getBuildingBlockType()==
BBType.
CAP))
2142 +
"symmetric subgraphs");
2144 List<List<Vertex>> symSites =
new ArrayList<List<Vertex>>();
2146 if (subGrpVrtxs.size()==1)
2150 ArrayList<Vertex> lst =
new ArrayList<Vertex>();
2154 if (symSites.size()==0)
2156 symSites.add(subGrpVrtxs);
2162 List<Vertex> thoseWithoutParent =
new ArrayList<Vertex>();
2163 for (
Vertex v : subGrpVrtxs)
2165 if (!subGrpVrtxs.contains(v.getParent()))
2166 thoseWithoutParent.add(v);
2168 if (thoseWithoutParent.size()!=1)
2173 Vertex sourceOfSubGraph = thoseWithoutParent.get(0);
2175 if (numSymmetricSubGraphs==0)
2177 symSites.add(subGrpVrtxs);
2182 List<Vertex> thoseWithoutChildren =
new ArrayList<Vertex>();
2183 for (
Vertex v : subGrpVrtxs)
2185 if (Collections.disjoint(v.getChilddren(),subGrpVrtxs))
2186 thoseWithoutChildren.add(v);
2194 Set<Vertex> upperLimits =
new HashSet<Vertex>();
2195 Set<Vertex> doneBySymmetry =
new HashSet<Vertex>();
2196 for (
Vertex upperLimit : thoseWithoutChildren)
2200 int numInSubGraphReplicas = 1;
2202 if (doneBySymmetry.contains(upperLimit))
2206 Set<Vertex> symmSitesOnBranch =
new HashSet<Vertex>(
2208 symmSitesOnBranch.retainAll(subGrpVrtxs);
2209 if (symmSitesOnBranch.size()>0)
2211 numInSubGraphReplicas = symmSitesOnBranch.size();
2212 doneBySymmetry.addAll(symmSitesOnBranch);
2216 if (lst.size() != numInSubGraphReplicas*numSymmetricSubGraphs)
2219 symSites.add(subGrpVrtxs);
2222 upperLimits.addAll(lst);
2227 List<Vertex> symSubGraph =
new ArrayList<Vertex>();
2229 symSubGraph.add(symSources);
2232 symSubGraph.removeIf(v -> v.getBuildingBlockType()==
BBType.
CAP);
2233 if (symSubGraph.size()!=subGrpVrtxs.size())
2235 symSites =
new ArrayList<List<Vertex>>();
2236 symSites.add(subGrpVrtxs);
2239 symSites.add(symSubGraph);
2304 DGraph receivingGraph =
null;
2305 DGraph incomingGraph =
null;
2306 Set<Vertex> vertexesOfReceivingGraphToConnectToIncomingGraph =
new HashSet<>();
2307 Set<Vertex> vertexesOfIncomingGraphToConnectToReceivingGraph =
new HashSet<>();
2314 if (receivingGraph ==
null)
2320 + apOnFirtsGraph.
getID() +
" is not the same of the other key APs.");
2322 if (incomingGraph ==
null)
2328 +
"for all incoming attachment points.");
2334 vertexesOfReceivingGraphToConnectToIncomingGraph.add(
2339 vertexesOfIncomingGraphToConnectToReceivingGraph.add(
2343 if (receivingGraph ==
null)
2347 if (incomingGraph ==
null)
2354 +
"This is not supported.");
2358 Set<Vertex> verticesToRemoveFromReceivingGraph =
new HashSet<>();
2359 Set<Vertex> verticesToRemoveFromIncomingGraph =
new HashSet<>();
2367 verticesToRemoveFromReceivingGraph.add(vToDelOnRecGraph);
2369 vertexesOfReceivingGraphToConnectToIncomingGraph,
2370 verticesToRemoveFromReceivingGraph);
2376 verticesToRemoveFromIncomingGraph.add(vToRemoveOnIncoming);
2378 vertexesOfIncomingGraphToConnectToReceivingGraph,
2379 verticesToRemoveFromIncomingGraph);
2385 for (
Vertex vToDelOnRecGraph : verticesToRemoveFromReceivingGraph)
2391 if (!ap.isAvailable())
2393 if (vertexesOfReceivingGraphToConnectToIncomingGraph.contains(
2394 ap.getLinkedAP().getOwner()))
2396 if (!apMapping.keySet().contains(ap))
2399 "The AP mapping does not define confined subgraphs "
2400 +
"for receiving graph " + receivingGraph.
getGraphId()+
".");
2406 for (
Vertex vToDelOnIncGraph : verticesToRemoveFromIncomingGraph)
2412 if (!ap.isAvailable())
2414 if (vertexesOfIncomingGraphToConnectToReceivingGraph.contains(
2415 ap.getLinkedAP().getOwner()))
2417 if (!apMapping.values().contains(ap.getLinkedAP()))
2420 "The AP mapping does not define confined subgraphs "
2421 +
"for incoming graph " + incomingGraph.
getGraphId()+
".");
2430 LinkedHashMap<AttachmentPoint,AttachmentPoint> linksToCreate =
new LinkedHashMap<>();
2431 LinkedHashMap<AttachmentPoint,BondType> linkTypesToCreate =
new LinkedHashMap<>();
2432 LinkedHashMap<AttachmentPoint,Boolean> linkDirectionToCreate =
new LinkedHashMap<>();
2443 BondType bondTypeOnRecGraph =
null;
2444 Boolean directionIsThisToIncoming =
true;
2448 directionIsThisToIncoming = !apOnReceivingGraph.
isSrcInUser();
2450 BondType bondTypeOnIncoming =
null;
2455 if (bondTypeOnRecGraph !=
null && bondTypeOnIncoming !=
null
2456 && bondTypeOnRecGraph != bondTypeOnIncoming)
2459 +
"between the two subgraphs is not the : "
2460 + bondTypeOnRecGraph +
" != " + bondTypeOnIncoming +
".");
2462 linkTypesToCreate.put(apOnIncomingGraph, bondTypeOnRecGraph);
2463 linksToCreate.put(apOnIncomingGraph,apOnReceivingGraph.
getLinkedAP());
2464 linkDirectionToCreate.put(apOnIncomingGraph,directionIsThisToIncoming);
2468 List<Ring> ringFromReceivingGraph =
new ArrayList<Ring>();
2471 if (verticesToRemoveFromReceivingGraph.contains(ring.getHeadVertex())
2472 || verticesToRemoveFromReceivingGraph.contains(ring.getTailVertex()))
2476 ringFromReceivingGraph.add(ring);
2478 List<Ring> ringFromIncomingGraph =
new ArrayList<Ring>();
2481 if (verticesToRemoveFromIncomingGraph.contains(ring.getHeadVertex())
2482 || verticesToRemoveFromIncomingGraph.contains(ring.getTailVertex()))
2486 ringFromIncomingGraph.add(ring);
2492 List<AttachmentPoint> interfaceApsOnReceivingGraph =
new ArrayList<AttachmentPoint>();
2493 for (
Vertex vToDelOnReceivingGraph : verticesToRemoveFromReceivingGraph)
2495 for (
AttachmentPoint ap : vToDelOnReceivingGraph.getAttachmentPoints())
2497 if (ap.isAvailable())
2501 interfaceApsOnReceivingGraph.add(ap);
2503 Vertex user = ap.getLinkedAP().getOwner();
2504 if (!verticesToRemoveFromReceivingGraph.contains(user))
2508 interfaceApsOnReceivingGraph.add(ap);
2513 List<AttachmentPoint> interfaceApsOnIncomingGraph =
new ArrayList<AttachmentPoint>();
2516 if (verticesToRemoveFromIncomingGraph.contains(vFromIncomingGraph))
2522 if (ap.isAvailable())
2526 interfaceApsOnIncomingGraph.add(ap);
2528 Vertex user = ap.getLinkedAP().getOwner();
2529 if (verticesToRemoveFromIncomingGraph.contains(user))
2531 interfaceApsOnIncomingGraph.add(ap);
2539 LinkedHashMap<AttachmentPoint,AttachmentPoint>
2540 inToOutAPForTemplateOnReceivingGraph =
new LinkedHashMap<>();
2541 List<AttachmentPoint> oldAPToRemoveFromTmplOfReceivingGraph =
new ArrayList<>();
2542 for (
AttachmentPoint intphAPOnReceivingGraph : interfaceApsOnReceivingGraph)
2544 if (intphAPOnReceivingGraph.isAvailable())
2550 if (intphAPOnReceivingGraph.isAvailableThroughout())
2552 if (!apMapping.containsKey(intphAPOnReceivingGraph))
2556 oldAPToRemoveFromTmplOfReceivingGraph.add(intphAPOnReceivingGraph);
2560 inToOutAPForTemplateOnReceivingGraph.put(
2561 apMapping.get(intphAPOnReceivingGraph),intphAPOnReceivingGraph);
2564 if (!apMapping.containsKey(intphAPOnReceivingGraph))
2567 +
"if a used AP has no mapping.");
2571 inToOutAPForTemplateOnReceivingGraph.put(
2572 apMapping.get(intphAPOnReceivingGraph),intphAPOnReceivingGraph);
2580 for (
Vertex v : verticesToRemoveFromReceivingGraph)
2584 for (
Vertex v : verticesToRemoveFromIncomingGraph)
2601 receivingGraph.
addEdge(incomingEdge);
2613 for (
Ring ring : ringFromReceivingGraph)
2619 List<AttachmentPoint> doneApsOnNew =
new ArrayList<AttachmentPoint>();
2622 AttachmentPoint apOnReceivingGraph = linksToCreate.get(apOnIncomingGraph);
2623 boolean directionIsThisToIncoming = linkDirectionToCreate.get(
2627 if (!directionIsThisToIncoming)
2629 srcAP = apOnIncomingGraph;
2630 trgAP = apOnReceivingGraph;
2637 throw new IllegalArgumentException(
"Two RCV vertices cannot "
2638 +
"be both the source and the target of an edge. See RCVs "
2646 boolean makeLinkAsRing =
false;
2657 makeLinkAsRing =
false;
2666 makeLinkAsRing =
false;
2673 makeLinkAsRing =
true;
2679 Vertex rcvToSrcAP =
null;
2680 List<Vertex> candidateRCVsSrc = fragSpace.getRCVsForAPClass(srcAP.
getAPClass());
2681 if (candidateRCVsSrc.size()>0)
2689 Vertex rcvToTrgAP =
null;
2690 List<Vertex> candidateRCVsTrg = fragSpace.getRCVsForAPClass(trgAP.
getAPClass());
2691 if (candidateRCVsTrg.size()>0)
2699 receivingGraph.
addRing(rcvToSrcAP, rcvToTrgAP,
2700 linkTypesToCreate.get(apOnIncomingGraph));
2703 linkTypesToCreate.get(apOnIncomingGraph));
2706 doneApsOnNew.add(apOnIncomingGraph);
2713 List<Ring> doneRings =
new ArrayList<Ring>();
2714 List<Ring> allRings =
new ArrayList<>();
2715 allRings.addAll(ringFromReceivingGraph);
2716 allRings.addAll(ringFromIncomingGraph);
2717 for (
Ring ring : allRings)
2719 Vertex head = ring.getHeadVertex();
2720 Vertex tail = ring.getTailVertex();
2733 receivingGraph.
addRing(head,tail);
2736 doneRings.add(ring);
2738 for (
Ring ring : doneRings) {
2739 allRings.remove(ring);
2740 ringFromReceivingGraph.remove(ring);
2741 ringFromIncomingGraph.remove(ring);
2746 for (
Ring ring : allRings)
2748 if (doneRings.contains(ring))
2755 Map<Vertex, List<Vertex>> adjacencyFromRingChords =
new HashMap<>();
2756 for (
Ring stillMissingRing : Stream.concat(
2757 ringFromReceivingGraph.stream(),
2758 ringFromIncomingGraph.stream()).toList())
2760 Vertex head = stillMissingRing.getHeadVertex();
2761 Vertex tail = stillMissingRing.getTailVertex();
2762 adjacencyFromRingChords.computeIfAbsent(head, k ->
new ArrayList<Vertex>()).add(tail);
2763 adjacencyFromRingChords.computeIfAbsent(tail, k ->
new ArrayList<Vertex>()).add(head);
2766 Vertex head = ring.getHeadVertex();
2767 Vertex tail = ring.getTailVertex();
2770 path =
new PathSubGraph(head, tail, adjacencyFromRingChords);
2776 ringFromReceivingGraph.remove(ring);
2777 ringFromIncomingGraph.remove(ring);
2789 for (
Ring redundantRing : allRings)
2791 Vertex redHead = redundantRing.getHeadVertex();
2792 Vertex redTail = redundantRing.getTailVertex();
2793 if (redHead == v || redTail == v)
2801 receivingGraph.
addEdge(
new Edge(apOnRedHead, apOnRedTail,
2803 doneRings.add(redundantRing);
2805 ringFromReceivingGraph.remove(ring);
2806 ringFromIncomingGraph.remove(ring);
2813 receivingGraph.
addRing(head,tail);
2816 doneRings.add(ring);
2818 for (
Ring ring : doneRings) {
2819 allRings.remove(ring);
2826 for (
AttachmentPoint apOnReceivingGraph : inToOutAPForTemplateOnReceivingGraph.keySet())
2829 inToOutAPForTemplateOnReceivingGraph.get(apOnReceivingGraph),apOnReceivingGraph);
2830 doneApsOnNew.add(apOnReceivingGraph);
2836 if (!doneApsOnNew.contains(apOnIncGraph))
2849 receivingGraph.jGraph =
null;
2850 receivingGraph.jGraphKernel =
null;
2854 Vertex vrtxTakenFromIncGraph = apOnIncGraph.getOwner();
2876 throw new IllegalArgumentException(
"The two RCV to be converted "
2877 +
"into an Edge must belong to the same graph.");
2909 LinkedHashMap<Integer, Integer> apIdMap,
FragmentSpace fragSpace)
2912 return replaceVertex(vertex, bbId, bbt, apIdMap,
true, fragSpace);
2933 LinkedHashMap<Integer, Integer> apIdMap,
boolean symmetry,
2942 List<Vertex> symSites =
new ArrayList<Vertex>();
2947 if (symSites.size() == 0)
2949 symSites.add(vertex);
2959 for (
Vertex oldLink : symSites)
2963 oldLink.getUnfilteredMutationTypes());
2966 ArrayList<Vertex> oldVertex =
new ArrayList<Vertex>();
2967 oldVertex.add(oldLink);
2969 for (Map.Entry<Integer,Integer> e : apIdMap.entrySet())
2971 apMap.put(oldLink.getAP(e.getKey()),
3010 LinkedHashMap<AttachmentPoint,Integer> apMap,
3014 if (!
gEdges.contains(edge))
3019 List<Edge> symSites =
new ArrayList<Edge> ();
3020 List<LinkedHashMap<AttachmentPoint,Integer>> symApMaps =
3021 new ArrayList<LinkedHashMap<AttachmentPoint,Integer>>();
3023 edge.getTrgAP().getOwner());
3024 if (symTrgvertices.size() == 0)
3027 symApMaps.add(apMap);
3029 for (
Vertex trgVrtx : symTrgvertices)
3031 Edge symEdge = trgVrtx.getEdgeToParent();
3032 symSites.add(symEdge);
3034 LinkedHashMap<AttachmentPoint,Integer> locApMap =
new
3035 LinkedHashMap<AttachmentPoint,Integer>();
3036 locApMap.put(symEdge.
getSrcAP(), apMap.get(edge.getSrcAP()));
3037 locApMap.put(symEdge.
getTrgAP(), apMap.get(edge.getTrgAP()));
3038 symApMaps.add(locApMap);
3043 for (
int i=0; i<symSites.size(); i++)
3045 Edge symEdge = symSites.get(i);
3046 LinkedHashMap<AttachmentPoint,Integer> locApMap = symApMaps.get(i);
3052 LinkedHashMap<AttachmentPoint,AttachmentPoint> apToApMap =
3053 new LinkedHashMap<AttachmentPoint,AttachmentPoint>();
3056 apToApMap.put(apOnGraph, newLink.
getAP(locApMap.get(apOnGraph)));
3090 LinkedHashMap<AttachmentPoint,AttachmentPoint> apMap)
3116 Edge eSrcToLink =
new Edge(orisEdgeSrc,
3119 Edge eLinkToTrg =
new Edge(apMap.get(orisEdgeTrg),
3126 ArrayList<Ring> rToEdit =
new ArrayList<Ring>();
3129 for (
Ring r : rToEdit)
3131 r.insertVertex(newLink,srcVrtx,trgVrtx);
3142 if (ap.isAvailable())
3165 return ((pos >=
gVertices.size()) || pos < 0) ? null :
3271 if (
gEdges.contains(edge))
3288 if (
gRings.contains(ring))
3300 if ((pos >=
gEdges.size()) || pos < 0)
3331 StringBuilder sb =
new StringBuilder(512);
3333 sb.append(
graphId).append(
" ");
3337 sb.append(
gVertices.get(i).toString()).append(
",");
3342 for (
int i=0; i<
gEdges.size(); i++)
3344 sb.append(
gEdges.get(i).toString()).append(
",");
3349 for (
int i=0; i<
gRings.size(); i++)
3351 sb.append(
gRings.get(i).toString()).append(
" ");
3356 sb.append(
symVertices.get(i).toString()).append(
" ");
3359 return sb.toString();
3378 for (
int i = 0; i < n; i++)
3389 && dap_idx_v1 == dapidx)
3430 if (!children.contains(child))
3432 children.add(child);
3455 boolean markBranches)
3463 AtomicInteger branchIdGenerator =
new AtomicInteger(0);
3464 List<Integer> thisBranchId =
new ArrayList<Integer>();
3465 thisBranchId.add(branchIdGenerator.getAndIncrement());
3476 if (!children.contains(child))
3478 children.add(child);
3486 List<Integer> newBranchId =
new ArrayList<>(thisBranchId);
3487 newBranchId.add(branchIdGenerator.getAndIncrement());
3512 AtomicInteger branchIdGenerator, List<Integer> prevBranchId)
3521 if (!children.contains(child))
3523 children.add(child);
3531 List<Integer> newBranchId =
new ArrayList<>(prevBranchId);
3532 newBranchId.add(branchIdGenerator.getAndIncrement());
3557 List<Vertex> children,
int numLayers,
boolean stopBeforeRCVs)
3570 if (children.contains(child))
3573 if (stopBeforeRCVs && child.isRCV())
3576 children.add(child);
3607 @SuppressWarnings(
"unchecked")
3632 for (Integer i : lst)
3654 if (bIdSrc==
null || bIdTrg==
null)
3656 if (bIdSrc.size()>bIdTrg.size())
3658 int sharedSubBranches = 0;
3659 for (
int i=0; i<bIdSrc.size(); i++)
3661 if (bIdSrc.get(i)==bIdTrg.get(i))
3662 sharedSubBranches++;
3664 return sharedSubBranches==bIdSrc.size();
3679 List<Vertex> children,
boolean stopBeforeRCVs)
3688 if (children.contains(child))
3691 if (stopBeforeRCVs && child.isRCV())
3694 children.add(child);
3711 List<Vertex> children, Set<Vertex> limits)
3720 if (!children.contains(child))
3722 children.add(child);
3723 if (!limits.contains(child))
3743 List<Vertex> children, List<Vertex> limitsInClone,
3744 boolean stopBeforeRCVs)
3753 if (children.contains(child))
3756 if (stopBeforeRCVs && child.isRCV())
3759 children.add(child);
3760 if (!limitsInClone.contains(child))
3776 int shortest = Integer.MAX_VALUE;
3777 for (
Vertex vertex : list)
3779 List<Vertex> parentTree =
new ArrayList<Vertex>();
3781 if (parentTree.size()<shortest)
3783 shortest = parentTree.size();
3800 List<Vertex> parentTree)
3807 if (parentTree.contains(parent))
3810 throw new IllegalArgumentException();
3812 parentTree.add(parent);
3840 ArrayList<Vertex> cListVrtx =
new ArrayList<>();
3841 Map<Long, Vertex> vidsInClone =
new HashMap<Long, Vertex>();
3845 cListVrtx.add(vClone);
3849 ArrayList<Edge> cListEdges =
new ArrayList<>();
3852 long srcVrtxId = e.getSrcVertex();
3856 long trgVrtxId = e.getTrgVertex();
3861 srcVrtxId).getAP(srcApId);
3863 trgVrtxId).getAP(trgApId);
3865 cListEdges.add(
new Edge(srcAPClone, trgAPClone,
3872 ArrayList<Ring> cListRings =
new ArrayList<>();
3876 for (
int iv=0; iv<ring.getSize(); iv++)
3878 Vertex origVrtx = ring.getVertexAtPosition(iv);
3883 cListRings.add(cRing);
3888 ArrayList<ClosableChain> cListClosableChains =
3892 cListClosableChains.add(cc.clone());
3897 List<SymmetricVertexes> cSymVertices =
new ArrayList<>();
3901 for (
Vertex origVrt : ss)
3905 cSymVertices.add(clonedSS);
3943 ArrayList<Integer> lstEdges =
new ArrayList<>();
3966 ArrayList<Edge> lstEdges =
new ArrayList<>();
3986 long mval = Long.MIN_VALUE;
3988 mval = Math.max(mval, v.getVertexId());
4001 boolean result =
false;
4004 if (l == v.getVertexId())
4108 if (other.
jGraph ==
null)
4130 Comparator<Vertex> vComp =
new Comparator<Vertex>() {
4132 Map<Vertex,Set<Vertex>> symmetryShortCuts =
4133 new HashMap<Vertex,Set<Vertex>>();
4139 if (symmetryShortCuts.containsKey(v1)
4140 && symmetryShortCuts.get(v1).contains(v2))
4147 StringBuilder sb =
new StringBuilder();
4150 Set<Vertex> symToV2 =
new HashSet<Vertex>();
4152 Set<Vertex> symToV1 =
new HashSet<Vertex>();
4154 for (
Vertex v1s : symToV1)
4156 if (symmetryShortCuts.containsKey(v1s))
4158 symmetryShortCuts.get(v1s).addAll(symToV2);
4160 symmetryShortCuts.put(v1s,symToV2);
4170 if (Integer.compare(v1.hashCode(),
4172 return Integer.compare(v1.hashCode(),
4180 Comparator<UndirectedEdge> eComp =
4206 VF2GraphIsomorphismInspector<Vertex, UndirectedEdge> vf2 =
4207 new VF2GraphIsomorphismInspector<>(this.
jGraph, other.
jGraph,
4210 return vf2.isomorphismExists();
4240 Comparator<Node> vComp =
new Comparator<Node>() {
4242 Map<Node,Set<Node>> symmetryShortCuts =
4243 new HashMap<Node,Set<Node>>();
4246 public int compare(
Node v1,
Node v2) {
4249 if (symmetryShortCuts.containsKey(v1)
4250 && symmetryShortCuts.get(v1).contains(v2))
4260 if (dv1==
null && dv2==
null)
4265 Set<Node> symToV2 =
new HashSet<Node>();
4268 symToV2.add((
Node) sv.getProperty(
4272 Set<Node> symToV1 =
new HashSet<Node>();
4275 symToV1.add((
Node) sv.getProperty(
4279 for (
Node v1s : symToV1)
4281 if (symmetryShortCuts.containsKey(v1s))
4283 symmetryShortCuts.get(v1s).addAll(symToV2);
4285 symmetryShortCuts.put(v1s,symToV2);
4296 VF2GraphIsomorphismInspector<Node, NodeConnection> vf2 =
4300 return vf2.isomorphismExists();
4319 reason.append(
"Different number of edges ("+this.
getEdgeCount()+
":"
4326 reason.append(
"Different number of vertices ("+this.
getVertexCount()+
":"
4333 reason.append(
"Different number of symmetric sets ("
4341 reason.append(
"Different number of Rings ("+this.
getRingCount()+
":"
4347 Map<Vertex,Vertex> vertexMap =
4348 new HashMap<Vertex,Vertex>();
4363 e.printStackTrace();
4364 reason.append(
"Exception");
4370 while (ssIter.hasNext())
4375 vertexMap.get(ssT.get(0)));
4376 if (ssO.size() == 0)
4381 reason.append(
"Symmetric set not found for vertex ("
4382 + ssT.get(0) +
")");
4386 if (ssT.size() != ssO.size())
4388 reason.append(
"Different number of symmetric sets on vertex "
4389 + ssT.get(0) +
"("+ssT.size()+
":"+ssO.size()+
")");
4393 Set<Vertex> mappedVrtxFromThis =
new HashSet<>();
4394 ssT.stream().forEach(v -> mappedVrtxFromThis.add(vertexMap.get(v)));
4396 Set<Vertex> vrtxFromOther =
new HashSet<>();
4397 ssO.stream().forEach(v -> vrtxFromOther.add(v));
4398 if (!vrtxFromOther.equals(mappedVrtxFromThis))
4400 reason.append(
"Difference in symmetric set " + ssT +
" vs " + ssO);
4408 Vertex vhT = rT.getHeadVertex();
4409 Vertex vtT = rT.getTailVertex();
4410 boolean hasRing = other
4413 .anyMatch(rO ->
sameAsRings(reason, vertexMap, rT, vhT,
4429 reason.append(
"Different ring size (").append(rT.
getSize())
4430 .append(
":").append(rO.
getSize()).append(
")");
4436 for (
int i = 1; i < rT.
getSize(); i++) {
4439 reason.append(
"Rings differ (A) (").append(rT).append(
":")
4440 .append(rO).append(
")");
4446 for (
int i = 1; i < rT.
getSize(); i++) {
4450 reason.append(
"Rings differ (B) (").append(rT).append(
":")
4451 .append(rO).append(
")");
4456 reason.append(
"Rings differ (C) (").append(rT).append(
":")
4457 .append(rO).append(
")");
4480 Map<Vertex, Vertex> map =
new HashMap<>();
4481 map.put(thisV, otherV);
4483 new StringBuilder());
4501 Map<Vertex,Vertex> vertexMap, StringBuilder reason)
4504 if (!seedOnA.sameAs(seedOnB, reason))
4506 reason.append(
"Different vertex ("+seedOnA+
":"+seedOnB+
")");
4510 List<Edge> edgesFromThis = gA.getEdgesWithSrc(seedOnA);
4511 List<Edge> edgesFromOther = gB.getEdgesWithSrc(seedOnB);
4512 if (edgesFromThis.size() != edgesFromOther.size())
4514 reason.append(
"Different number of edges from vertex "+seedOnA+
" ("
4515 +edgesFromThis.size()+
":"
4516 +edgesFromOther.size()+
")");
4521 ArrayList<Vertex[]> pairs =
new ArrayList<Vertex[]>();
4523 for (
Edge et : edgesFromThis)
4525 boolean found =
false;
4527 StringBuilder innerSb =
new StringBuilder();
4529 for (
Edge e : edgesFromOther)
4531 innerSb.append(
" Edge"+otherEdgeI+
":");
4532 if (et.sameAs(e,innerSb))
4541 reason.append(
"Edge not found in other("+et+
"). "
4542 +
"Edges in othes: "+innerSb.toString());
4547 if (vertexMap.keySet().contains(
4548 gA.getVertexWithId(et.getTrgVertex())))
4552 vertexMap.put(gA.getVertexWithId(et.getTrgVertex()),
4556 gA.getVertexWithId(et.getTrgVertex()),
4562 for (
Vertex[] pair : pairs)
4589 if (v.containsAtoms())
4608 n += v.getHeavyAtomsCount();
4622 ArrayList<AttachmentPoint> lstAPs =
4623 new ArrayList<AttachmentPoint>();
4626 lstAPs.addAll(v.getAttachmentPoints());
4640 ArrayList<AttachmentPoint> lstFreeAPs =
4641 new ArrayList<AttachmentPoint>();
4644 if (ap.isAvailable())
4663 ArrayList<AttachmentPoint> lstFreeAPs =
4664 new ArrayList<AttachmentPoint>();
4667 if (ap.isAvailableThroughout())
4690 if (apCand.getID() ==
id)
4719 ap.getAPClass()) !=
null
4736 ArrayList<Vertex> toDel =
new ArrayList<Vertex>();
4739 if (vtx instanceof
Fragment ==
false)
4766 List<Long> rvids =
new ArrayList<>();
4767 for (
int i=0; i<lstVerts.size(); i++)
4769 Vertex vtx = lstVerts.get(i);
4770 if (vtx instanceof
Fragment ==
false)
4783 for (
int i=0; i<rvids.size(); i++)
4785 long vid = rvids.get(i);
4794 for (
Vertex v : lstVerts)
4821 if (!fragSpace.useAPclassBasedApproach())
4845 if (!fragSpace.useAPclassBasedApproach())
4848 for (
Vertex curVertex : vertexAddedToThis)
4860 if (curDap.isAvailableThroughout())
4862 APClass apcCap = fragSpace.getAPClassOfCappingVertex(
4863 curDap.getAPClass());
4866 int bbIdCap = fragSpace.getCappingFragment(apcCap);
4873 DGraph molGraph = curDap.getOwner()
4875 if (molGraph ==
null)
4876 throw new Error(
"Cannot add capping "
4877 +
"groups to a vertex that does not "
4878 +
"belong to a graph.");
4883 String msg =
"Capping is required but no proper "
4884 +
"capping fragment found with APCalss "
4886 throw new Error(msg);
4956 if (!this.gVertices.contains(seed))
4959 +
"a seed vertex that is not contained in this graph.");
4965 ArrayList<Vertex> subGrpVrtxs =
new ArrayList<Vertex>();
4966 subGrpVrtxs.add(seedClone);
4967 subGraph.
getChildrenTree(seedClone, subGrpVrtxs, numLayers, stopBeforeRCVs);
4968 ArrayList<Vertex> toRemove =
new ArrayList<Vertex>();
4971 if (!subGrpVrtxs.contains(v))
4977 for (
Vertex v : toRemove)
5005 List<Vertex> limits,
boolean stopBeforeRCVs)
5008 if (!this.gVertices.contains(seed))
5011 +
"a seed vertex that is not contained in this graph.");
5014 if (limits.size()==0)
5023 List<Vertex> limitsInClone =
new ArrayList<Vertex>();
5027 ArrayList<Vertex> subGrpVrtxs =
new ArrayList<Vertex>();
5028 subGrpVrtxs.add(seedClone);
5032 ArrayList<Vertex> toRemove =
new ArrayList<Vertex>();
5035 if (!subGrpVrtxs.contains(v))
5040 for (
Vertex v : toRemove)
5058 Set<Vertex> limits, Set<Vertex> visited)
5066 if (limits.contains(userVertex))
5070 if (!visited.contains(userVertex))
5072 visited.add(userVertex);
5092 Set<Vertex> visitedVertexes =
new HashSet<Vertex>();
5093 visitedVertexes.add(seed);
5095 return visitedVertexes;
5117 if (!this.gVertices.contains(seed))
5120 +
"a seed vertex that is not contained in this graph.");
5127 ArrayList<Vertex> subGrpVrtxs =
new ArrayList<Vertex>();
5128 subGrpVrtxs.add(seedClone);
5131 ArrayList<Vertex> toRemove =
new ArrayList<Vertex>();
5134 if (!subGrpVrtxs.contains(v))
5139 for (
Vertex v : toRemove)
5161 Collectors.toList());
5192 throw new IllegalArgumentException(
"Graph pattern " + pattern +
5196 List<Set<Vertex>> disjointMultiCycleVertices =
this
5201 .collect(Collectors.toList());
5205 Map<DGraph,ObjectPair> subGraphsAndConnections =
new LinkedHashMap<>();
5206 for (Set<Vertex> fusedRing : disjointMultiCycleVertices) {
5207 if (recordConnectivity)
5209 Set<Edge> connectionToSubgraph =
new HashSet<Edge>();
5210 Set<Edge> connectionFromSubgraph =
new HashSet<Edge>();
5212 connectionFromSubgraph);
5214 connectionFromSubgraph);
5215 subGraphsAndConnections.put(subGraph, connections);
5218 subGraphsAndConnections.put(subGraph,
null);
5222 for (
DGraph g : subGraphsAndConnections.keySet()) {
5223 g.storeCurrentVertexIDs();
5224 g.renumberGraphVertices();
5228 return subGraphsAndConnections;
5259 Set<Edge> connectionToSubgraph,
5260 Set<Edge> connectionFromSubgraph)
5265 Set<Vertex> complement = subgraph
5268 .filter(u -> definedOn
5270 .allMatch(v -> v.getVertexId() != u.getVertexId())
5271 ).collect(Collectors.toSet());
5273 Set<Long> vrtxIDsInComplement = complement.stream()
5274 .map(v -> v.getVertexId())
5275 .collect(Collectors.toSet());
5277 if (connectionToSubgraph!=
null && connectionFromSubgraph!=
null)
5279 for (
Vertex v : definedOn)
5283 if (e.getSrcAP().getOwner() == v &&
5284 vrtxIDsInComplement.contains(e.getTrgVertex()))
5286 connectionFromSubgraph.add(e);
5289 if (e.getTrgAP().getOwner() == v &&
5290 vrtxIDsInComplement.contains(e.getSrcVertex()))
5292 connectionToSubgraph.add(e);
5298 for (
Vertex v : complement) {
5356 DGraph subGraph = entry.getKey();
5368 LinkedHashMap<AttachmentPoint, AttachmentPoint> apMapOrigToTmpl =
5369 new LinkedHashMap<AttachmentPoint, AttachmentPoint>();
5370 @SuppressWarnings(
"unchecked")
5371 Set<Edge> edsToSubgrph = (Set<Edge>) entry.getValue().getFirst();
5372 for (
Edge e : edsToSubgrph)
5377 apMapOrigToTmpl.put(apOnOrig, apOnTmpl);
5379 @SuppressWarnings(
"unchecked")
5380 Set<Edge> edsFromSubGrph = (Set<Edge>) entry.getValue().getSecond();
5381 for (
Edge e : edsFromSubGrph)
5386 apMapOrigToTmpl.put(apOnOrig, apOnTmpl);
5390 List<Vertex> toReplaceByTemplate =
new ArrayList<>();
5402 apMapOrigToTmpl, fragSpace);
5420 if (newScaffold ==
null) {
5449 int visitedVertexEncounters = 0;
5455 boolean srcIsVisited = srcVertex != v.
getVertexId()
5456 && visited.contains(srcVertex);
5458 visitedVertexEncounters += srcIsVisited ? 1 : 0;
5459 if (visitedVertexEncounters >= 2) {
5460 throw new IllegalArgumentException(
"Invalid graph. "
5461 +
"Contains a cycle.");
5466 if (edgeIsWrongWay) {
5469 if (!srcIsVisited) {
5524 Edge edgeToParent = v.getEdgeToParent();
5525 if (edgeToParent !=
null)
5551 ArrayList<Vertex> children =
new ArrayList<Vertex>();
5555 for (
Vertex c : children) {
5582 if (rings.isEmpty())
5593 int minDist = Integer.MAX_VALUE;
5595 for (
Ring r : rings)
5597 int dist = Math.min(r.getDistance(r.getHeadVertex(),v),
5598 r.getDistance(r.getTailVertex(),v));
5603 replacedByEdge[0] = r.getHeadVertex();
5604 replacedByEdge[1] = r.getTailVertex();
5605 bt = r.getBondType();
5610 boolean frameHasBranching =
false;
5611 List<Integer> branchingPositions =
new ArrayList<Integer>();
5613 for (
int i=0; i<frame.
getSize(); i++)
5619 branchingPositions.add(i);
5627 branchingPositions.add(i);
5628 frameHasBranching =
true;
5633 if (rings.size()==1 && !frameHasBranching)
5641 int branchingDownstreamId = -1;
5642 for (
int i=0; i<frame.
getSize(); i++)
5644 int iTranslated = i + posOfFocusVrtInRing;
5645 if (iTranslated >= frame.
getSize())
5646 iTranslated = iTranslated - frame.
getSize();
5647 if (branchingPositions.contains(iTranslated))
5649 branchingDownstreamId = iTranslated;
5653 int branchingUpstreamId = -1;
5654 for (
int i=(frame.
getSize()-1); i>-1; i--)
5656 int iTranslated = i + posOfFocusVrtInRing;
5657 if (iTranslated >= frame.
getSize())
5658 iTranslated = iTranslated - frame.
getSize();
5659 if (branchingPositions.contains(iTranslated))
5661 branchingUpstreamId = iTranslated;
5669 List<Vertex> remainingChain =
new ArrayList<Vertex>();
5670 for (
int i=0; i<frame.
getSize(); i++)
5672 int iTranslated = i + branchingDownstreamId;
5673 if (iTranslated >= frame.
getSize())
5674 iTranslated = iTranslated - frame.
getSize();
5676 if (iTranslated == branchingUpstreamId)
5681 List<Vertex> toRemoveChain =
new ArrayList<Vertex>();
5682 for (
int i=0; i<frame.
getSize(); i++)
5684 int iTranslated = i + branchingUpstreamId + 1;
5685 if (iTranslated >= frame.
getSize())
5686 iTranslated = iTranslated - frame.
getSize();
5688 if (iTranslated == (branchingDownstreamId - 1))
5698 if (toRemoveChain.size() == 2)
5700 int countOrRCVs = 0;
5701 for (
Vertex vtr : toRemoveChain)
5706 if (countOrRCVs == 2)
5714 int deepestLevel = Integer.MAX_VALUE;
5715 Vertex deepestVrtRemainingChain =
null;
5716 for (
Vertex vint : remainingChain)
5719 if (lvl < deepestLevel)
5722 deepestVrtRemainingChain = vint;
5730 if (remainingChain.contains(replacedByEdge[0]))
5739 remainingChain.remove(replacedByEdge[0]);
5741 remainingChain.remove(replacedByEdge[1]);
5749 addEdge(
new Edge(apSrcOfNewEdge, apTrgOfNewEdge, bt));
5758 List<Vertex> chainToReverseA =
new ArrayList<Vertex>();
5759 List<Vertex> chainToReverseB =
new ArrayList<Vertex>();
5760 for (
int i=(remainingChain.indexOf(deepestVrtRemainingChain)+1);
5761 i<remainingChain.size(); i++)
5763 Vertex vPrev = remainingChain.get(i-1);
5764 Vertex vHere = remainingChain.get(i);
5769 if (chainToReverseA.size()==0)
5770 chainToReverseA.add(vPrev);
5771 chainToReverseA.add(vHere);
5774 for (
int i=(remainingChain.indexOf(deepestVrtRemainingChain)-1);i>-1;i--)
5776 Vertex vPrev = remainingChain.get(i+1);
5777 Vertex vHere = remainingChain.get(i);
5780 if (chainToReverseB.size()==0)
5781 chainToReverseB.add(vPrev);
5782 chainToReverseB.add(vHere);
5787 LinkedHashMap<Vertex,Vertex> chordsToRecreate =
5788 new LinkedHashMap<Vertex,Vertex>();
5789 LinkedHashMap<Vertex,BondType> chordsToRecreateBB =
5790 new LinkedHashMap<Vertex,BondType>();
5794 if (chainToReverseA.size()+chainToReverseB.size() > 1)
5796 List<Vertex> chainToWorkOn =
null;
5797 for (
int ic=0; ic<2; ic++)
5800 chainToWorkOn = chainToReverseA;
5802 chainToWorkOn = chainToReverseB;
5804 for (
int i=1; i<chainToWorkOn.size(); i++)
5806 Vertex vHere = chainToWorkOn.get(i);
5807 Vertex vPrev = chainToWorkOn.get(i-1);
5808 List<Ring> ringsToRecreate =
new ArrayList<>();
5811 ringsToRecreate.add(r);
5812 chordsToRecreate.put(r.getHeadVertex(),
5814 chordsToRecreateBB.put(r.getHeadVertex(),
5817 for (
Ring r : ringsToRecreate)
5823 if (edgeToPrevious ==
null)
5827 String debugFile =
"debug_"+v.getVertexId()+
".json";
5832 +
"removal of " + v +
" from ring " + frame
5833 +
" in graph " +
this.getGraphId()
5834 +
". See graph in " + debugFile);
5863 for (
Vertex vtr : toRemoveChain)
5868 if (remainingChain.contains(child)
5869 || toRemoveChain.contains(child))
5871 DGraph ownerOfChild = child.getGraphOwner();
5876 List<AttachmentPoint> apProjectionsToRemove =
5877 new ArrayList<AttachmentPoint>();
5885 apProjectionsToRemove.add(innerAP);
5895 for (
Vertex h : chordsToRecreate.keySet())
5897 addRing(h, chordsToRecreate.get(h), chordsToRecreateBB.get(h));
5909 List<SymmetricVertexes> ssToRemove =
new ArrayList<SymmetricVertexes>();
5911 while (ssIter.hasNext())
5954 HashMap<Long, Long> nmap =
new HashMap<>();
5959 nmap.put(vid, nvid);
5998 Map<Long, Long> nmap =
new HashMap<>();
6007 nmap.put(vid, nvid);
6028 ArrayList<Vertex> parentTree =
new ArrayList<>();
6030 return parentTree.size() - 1;
6102 settings.getRandomizer());
6107 String msg =
"Evaluation of graph: graph-to-mol returned null!"
6109 settings.getLogger().log(Level.FINE, msg);
6114 boolean isConnected = ConnectivityChecker.isConnected(mol);
6117 String msg =
"Evaluation of graph: Not all connected"
6119 settings.getLogger().log(Level.FINE, msg);
6124 String smiles =
null;
6128 String msg =
"Evaluation of graph: SMILES is null! "
6130 settings.getLogger().log(Level.FINE, msg);
6131 smiles =
"FAIL: NO SMILES GENERATED";
6134 if (smiles.contains(
".") && !permissive)
6136 String msg =
"Evaluation of graph: SMILES contains \".\"" + smiles;
6137 settings.getLogger().log(Level.FINE, msg);
6148 String msg =
"Evaluation of graph: Max atoms constraint "
6149 +
" violated: " + smiles;
6150 settings.getLogger().log(Level.FINE, msg);
6157 if (fsSettings.
getMaxMW()>0 && !permissive)
6161 String msg =
"Evaluation of graph: Molecular weight "
6162 +
"constraint violated: " + smiles +
" | MW: " + mw;
6163 settings.getLogger().log(Level.FINE, msg);
6167 mol.setProperty(
"MOL_WT", mw);
6175 String msg =
"Evaluation of graph: Max rotatable bonds "
6176 +
"constraint violated: "+ smiles;
6177 settings.getLogger().log(Level.FINE, msg);
6181 mol.setProperty(
"ROT_BND", nrot);
6188 String msg =
"Evaluation of graph: forbidden end in graph!";
6189 settings.getLogger().log(Level.FINE, msg);
6199 Set<String> doneType =
new HashSet<>();
6201 for (String rcaTyp : rcaTypes.keySet())
6203 if (doneType.contains(rcaTyp))
6212 if (v.containsAtoms())
6214 IAtom atm = v.getIAtomContainer().getAtom(0);
6219 rcaTypes.get(rcaTyp)))
6223 if (rcaTyp.equals(rcaTypes.get(rcaTyp)))
6234 String msg =
"Evaluation of graph: too many RCAs! "
6235 + rcaTyp +
":" + nThisType +
" "
6236 + rcaTypes.get(rcaTyp) +
":" + nCompType;
6237 settings.getLogger().log(Level.FINE, msg);
6243 String msg =
"Evaluation of graph: too few RCAs! "
6244 + rcaTyp +
":" + nThisType +
" "
6245 + rcaTypes.get(rcaTyp) +
":" + nCompType;
6246 settings.getLogger().log(Level.FINE, msg);
6250 nPossRings = nPossRings + Math.min(nThisType, nCompType);
6251 doneType.add(rcaTyp);
6252 doneType.add(rcaTypes.get(rcaTyp));
6256 String msg =
"Evaluation of graph: too few ring candidates";
6257 settings.getLogger().log(Level.FINE, msg);
6264 settings.getLogger());
6265 if (inchiKey ==
null)
6267 String msg =
"Evaluation of graph: InChI Key is null!";
6268 settings.getLogger().log(Level.WARNING, msg);
6269 inchiKey =
"UNDEFINED_INCHI";
6272 Object[] res =
new Object[3];
6305 ArrayList<DGraph> lstGraphs =
new ArrayList<>();
6318 settings.getRandomizer());
6325 settings.getLogger());
6330 ArrayList<List<Ring>> allCombsOfRings =
6336 ArrayList<List<Ring>> toRemove =
new ArrayList<>();
6337 for (List<Ring>
setRings : allCombsOfRings)
6344 allCombsOfRings.removeAll(toRemove);
6348 for (List<Ring> ringSet : allCombsOfRings)
6357 for (
Ring oldRing : ringSet)
6360 for (
int i=0; i<oldRing.getSize(); i++)
6362 long oldVId = oldRing.getVertexAtPosition(i).getVertexId();
6363 long newVId = vRenum.get(oldVId);
6371 lstGraphs.add(newGraph);
6389 Set<APClass> classOfForbEnds =
6391 boolean found =
false;
6392 for (
Vertex vtx : vertices)
6394 List<AttachmentPoint> daps = vtx.getAttachmentPoints();
6397 if (dp.isAvailable())
6399 APClass apClass = dp.getAPClass();
6400 if (classOfForbEnds.contains(apClass))
6403 String msg =
"Forbidden free AP for Vertex: "
6404 + vtx.getVertexId() +
" "
6406 +
"\n"+
this +
" \n "
6407 +
" AP class: " + apClass;
6408 fsSettings.
getLogger().log(Level.WARNING, msg);
6444 List<Integer> parentAPIdx,
6446 Vertex childVertex,
int childAPIdx,
6447 BondType bndType,
boolean onAllSymmAPs)
6451 Map<Vertex, SymmetricVertexes> newSymSets =
new HashMap<>();
6454 for (
int i=0; i<parentVertices.size(); i++)
6457 subGraph, childVertex, childAPIdx, bndType,
6458 newSymSets, onAllSymmAPs);
6479 if (!srcAP.isAvailable())
6482 +
"attachment point " + srcAP +
" on vertex "
6483 + srcAP.getOwner().getVertexId() +
" as srcAP.");
6485 if ( !trgAP.isAvailable())
6488 +
"attachment point " + trgAP +
" on vertex "
6489 + trgAP.getOwner().getVertexId() +
" as trgAP.");
6492 BondType btSrc = srcAP.getBondType();
6493 BondType btTrg = trgAP.getBondType();
6511 Edge edge =
new Edge(srcAP,trgAP, bndTyp);
6530 DGraph incomingGraph = apOnIncomingGraph.getOwner().getGraphOwner();
6533 Edge edge =
new Edge(apOnThisGraph, apOnIncomingGraph,
6582 Vertex childVertex,
int childAPIdx,
6584 Map<Vertex, SymmetricVertexes> newSymSets)
6591 childVertex.getVertexId());
6594 Edge edge =
new Edge(parentVertex.getAP(parentAPIdx),
6595 cvClone.
getAP(childAPIdx), bndType);
6602 Vertex origV = subGraph.getVertexList().get(i);
6610 if (subGraph.hasSymmetryInvolvingVertex(origV))
6612 if (newSymSets.containsKey(origV))
6614 newSymSets.get(origV).add(clonV);
6623 if (newSymSets.containsKey(origV))
6625 newSymSets.get(origV).add(clonV);
6631 newSymSets.put(origV, ss);
6636 for (
int i=0; i<sgClone.
getEdgeList().size(); i++)
6641 for (
int i=0; i<sgClone.
getRings().size(); i++)
6647 Set<SymmetricVertexes> doneTmpSymSets =
new HashSet<SymmetricVertexes>();
6651 if (doneTmpSymSets.contains(tmpSS))
6655 doneTmpSymSets.
add(tmpSS);
6656 boolean done =
false;
6660 while (iter.hasNext())
6662 oldSS = iter.next();
6663 if (oldSS.contains(tmpSS.get(0)))
6665 oldSS.addAll(tmpSS);
6672 if (tmpSS.size() <= 1)
6679 newSS.addAll(tmpSS);
6706 int parentAPIdx,
DGraph subGraph,
6707 Vertex childVertex,
int childAPIdx,
6709 Map<Vertex, SymmetricVertexes> newSymSets,
6710 boolean onAllSymmAPs)
6714 parentVertex.getAP(parentAPIdx));
6715 if (symAPs.size()!=0 && onAllSymmAPs)
6719 if (!symAP.isAvailable())
6724 subGraph, childVertex,
6725 childAPIdx, bndType, newSymSets);
6729 childAPIdx, bndType, newSymSets);
6743 List<AttachmentPointQuery> apQueries, Logger logger)
6745 List<List<AttachmentPoint>> result =
new ArrayList<>();
6748 result.add(
findAPs(apQuery, logger));
6766 List<AttachmentPoint> matches =
new ArrayList<>();
6775 logger.log(Level.FINE,
"AP matches: " + matches);
6790 List<Long> matches =
new ArrayList<>();
6793 matches.add(v.getVertexId());
6826 boolean purgeSym, Logger logger)
6830 List<Vertex> matches =
new ArrayList<>();
6839 logger.log(Level.FINE,
"Matches: " + matches);
6846 logger.log(Level.FINE,
"Final Matches (after symmetry): " + matches);
6861 ArrayList<Edge> matches =
new ArrayList<>(
getEdgeList());
6862 logger.log(Level.FINE,
"Edge candidates: " + matches);
6864 if (edgeQuery ==
null)
6869 ArrayList<Edge> newLst =
new ArrayList<>();
6870 for (
Edge e : matches)
6877 logger.log(Level.FINE,
"Edge matches: " + newLst);
6905 List<Edge> edges =
new ArrayList<Edge>();
6909 if (eToParent !=
null)
6910 edges.add(eToParent);
6914 if (!ap.isAvailable() && ap.isSrcInUser())
6916 edges.add(ap.getEdgeUser());
6934 List<Vertex> symRedundant =
new ArrayList<>();
6936 while (itSymm.hasNext())
6941 if (symRedundant.contains(v))
6947 symRedundant.addAll(ss);
6948 symRedundant.remove(v);
6952 for (
Vertex v : symRedundant)
6967 ArrayList<Vertex> vList =
new ArrayList<>();
6968 for (
long vid : list) {
6974 list.add(v.getVertexId());
7001 logger.log(Level.FINE,
"Graph edit task: " + edit.getType());
7003 switch (edit.getType())
7007 DGraph inGraph = edit.getIncomingGraph();
7009 int idAPOnInGraph = -1;
7010 Vertex rootOfInGraph =
null;
7011 if (edit.getIncomingAPId() !=
null)
7014 edit.getIncomingAPId().intValue());
7017 String msg =
"Skipping " + edit.getType() +
" on "
7019 +
" graph has no AP with ID = "
7020 + edit.getIncomingAPId() +
". The IDs of "
7024 msg = msg +
" " + freeAP.getID();
7027 +
"Please, use one of those values in "
7028 +
"'idAPOnIncomingGraph'.";
7029 logger.log(Level.WARNING, msg);
7034 ArrayList<AttachmentPoint> freeAPs =
7036 if (freeAPs.size()==1)
7042 String geClsName =
GraphEdit.class.getSimpleName();
7043 String msg =
"Skipping " + edit.
getType() +
" on "
7045 +
" graph has more than one free AP ("
7046 + freeAPs.size() +
") and "
7047 +
"the " + geClsName +
" "
7048 +
"does not provide sufficient information "
7049 +
"to unambiguously choose one AP. "
7050 +
"Please, add 'idAPOnIncomingGraph' in "
7051 +
"the definition of " + geClsName +
".";
7052 logger.log(Level.WARNING, msg);
7058 for (
Vertex vertexToReplace : matches)
7060 Edge edgeToParent = vertexToReplace.getEdgeToParent();
7061 if (edgeToParent ==
null)
7077 rootOfInGraph, idAPOnInGraph, bondType,
7078 new HashMap<Vertex, SymmetricVertexes>(), symmetry);
7085 if (edit.getIncomingBBId() > -1
7086 && edit.getIncomingBBType() !=
null
7087 && edit.getIncomingGraph() ==
null)
7090 edit.getVertexQuery(),
false, logger);
7091 for (
Vertex vertexToChange : matches)
7095 DGraph graph = vertexToChange.getGraphOwner();
7097 edit.getIncomingBBId(),
7098 edit.getIncomingBBType(),
7106 if (edit.getIncomingGraph() !=
null
7107 && edit.getIncomingBBType() ==
null)
7113 edit.getVertexQuery(),
false, logger);
7115 for (
Vertex vertexToChange : matches)
7121 for (Map.Entry<Integer,Integer> e :
7122 edit.getAPMappig().entrySet())
7124 apMap.put(vertexToChange.getAP(e.getKey()),
7129 List<Vertex> oldSubG =
new ArrayList<Vertex>();
7130 oldSubG.add(vertexToChange);
7137 case CHANGESUBGRAPH:
7140 List<List<AttachmentPoint>> apMatchesOnGraph = modGraph.
findAPs(
7141 edit.getTargetGraphAPQueries(), logger);
7142 for (List<AttachmentPoint> aps : apMatchesOnGraph)
7146 throw new IllegalStateException(
7147 "No APs found for the target graph. "
7148 +
"Cannot perform " + edit.getType() +
".");
7149 }
else if (aps.size() > 1)
7151 throw new IllegalStateException(
7152 "Expected 1 AP matching the query on the target "
7153 +
"graph, but found " + aps.size()
7154 +
". Cannot perform " + edit.getType() +
".");
7159 DGraph incomingGraph = edit.getIncomingGraph();
7160 if (incomingGraph ==
null)
7162 String pathName = edit.getIncomingGraphPathname();
7163 if (pathName ==
null)
7165 throw new IllegalStateException(
7166 "The incoming graph pathname is null. "
7167 +
"Cannot perform " + edit.getType() +
".");
7171 new File(pathName)).get(0);
7172 }
catch (Exception e) {
7173 throw new IllegalStateException(
7174 "Error reading the incoming graph from file " + pathName +
". "
7175 +
"Cannot perform " + edit.getType() +
".", e);
7178 List<List<AttachmentPoint>> apMatchesOnIncomingGraph = incomingGraph.
findAPs(
7179 edit.getIncomingGraphAPQueries(), logger);
7180 for (List<AttachmentPoint> aps : apMatchesOnIncomingGraph)
7182 if (aps.size() == 0)
7184 throw new IllegalStateException(
7185 "No APs found for the incoming graph. "
7186 +
"Cannot perform " + edit.getType() +
".");
7187 }
else if (aps.size() > 1)
7189 throw new IllegalStateException(
7190 "Expected 1 AP matching the query on the incoming "
7191 +
"graph, but found " + aps.size()
7192 +
". Cannot perform " + edit.getType() +
".");
7196 if (apMatchesOnGraph.get(0).size()
7197 != apMatchesOnIncomingGraph.get(0).size())
7199 throw new IllegalStateException(
7200 "The number of APs on the target graph and the incoming "
7201 +
"graph do not match. Cannot perform " + edit.getType() +
".");
7205 for (
int i = 0; i < apMatchesOnGraph.size(); i++)
7208 apMapping.put(apMatchesOnGraph.get(i).get(0),
7209 apMatchesOnIncomingGraph.get(i).get(0));
7219 edit.getVertexQuery(),
false, logger);
7220 for (
Vertex vertexToRemove : matches)
7231 edit.getVertexQuery(),
false, logger);
7232 for (
Vertex vertexToRemove : matches)
7245 logger.log(Level.WARNING,
"The graph after editing is empty. "
7246 +
"This will likely trigger an error in subsequent steps.");
7264 List<Vertex> mutableSites =
new ArrayList<Vertex>();
7267 mutableSites.addAll(v.getMutationSites(
7268 new ArrayList<MutationType>()));
7270 return mutableSites;
7288 List<Vertex> mutableSites =
new ArrayList<Vertex>();
7291 mutableSites.addAll(v.getMutationSites(ignoredTypes));
7293 return mutableSites;
7311 List<Vertex> mutableSites =
new ArrayList<Vertex>();
7314 v.getMutationSites()
7316 .filter(vrt -> vrt.getMutationTypes().contains(requestedType))
7317 .forEach(vrt -> mutableSites.add(vrt));
7319 return mutableSites;
7333 String jsonOutput = gson.toJson(
this);
7383 implements JsonSerializer<DGraph>
7387 JsonSerializationContext context)
7389 boolean regenerateVrtxID =
false;
7390 boolean regenerateAP =
false;
7391 Set<Long> unqVrtxIDs =
new HashSet<Long>();
7392 Set<Integer> unqApIDs =
new HashSet<Integer>();
7395 if (!unqVrtxIDs.add(v.getVertexId()))
7397 regenerateVrtxID =
true;
7401 if (!unqApIDs.add(ap.getID()))
7403 regenerateAP =
true;
7408 if (regenerateVrtxID)
7417 JsonObject jsonObject =
new JsonObject();
7418 jsonObject.addProperty(
"graphId", g.
graphId);
7419 jsonObject.add(
"gVertices", context.serialize(g.
gVertices));
7420 jsonObject.add(
"gEdges", context.serialize(g.
gEdges));
7421 jsonObject.add(
"gRings", context.serialize(g.
gRings));
7422 jsonObject.add(
"symVertices", context.serialize(g.
symVertices));
7430 implements JsonDeserializer<DGraph>
7434 JsonDeserializationContext context)
throws JsonParseException
7436 JsonObject jsonObject = json.getAsJsonObject();
7439 JsonObject partialJsonObj =
new JsonObject();
7440 partialJsonObj.add(
"graphId", jsonObject.get(
"graphId"));
7441 partialJsonObj.add(
"gVertices", jsonObject.get(
"gVertices"));
7443 Gson gson =
new GsonBuilder()
7445 .registerTypeAdapter(
Vertex.class,
7448 .setPrettyPrinting()
7457 v.setGraphOwner(graph);
7468 JsonArray edgeArr = jsonObject.get(
"gEdges").getAsJsonArray();
7469 for (JsonElement e : edgeArr)
7471 JsonObject o = e.getAsJsonObject();
7473 o.get(
"srcAPID").getAsInt());
7475 o.get(
"trgAPID").getAsInt());
7478 context.deserialize(o.get(
"bondType"),
BondType.class));
7483 JsonArray ringArr = jsonObject.get(
"gRings").getAsJsonArray();
7484 for (JsonElement e : ringArr)
7486 JsonObject o = e.getAsJsonObject();
7488 for (JsonElement re : o.get(
"vertices").getAsJsonArray())
7492 ring.
setBondType(context.deserialize(o.get(
"bndTyp"),
7498 if (jsonObject.has(
"symVertices"))
7500 for (JsonElement elSet : jsonObject.get(
"symVertices").getAsJsonArray())
7503 for (JsonElement elId : elSet.getAsJsonArray())
7505 int id = context.deserialize(elId, Integer.class);
7513 e1.printStackTrace();
7514 throw new Error(
"Vertex listed in multiple symmetric "
7515 +
"sets. Check this: " + elSet);
7534 ArrayList<Vertex> newVertexList =
new ArrayList<>();
7536 Set<Long> visited =
new HashSet<>();
7537 Queue<Vertex> currLevel =
new ArrayDeque<>();
7538 Queue<Vertex> nextLevel =
new ArrayDeque<>();
7541 while (!currLevel.isEmpty()) {
7542 Vertex currVertex = currLevel.poll();
7545 if (!visited.contains(currId)) {
7546 visited.add(currId);
7548 newVertexList.add(currVertex);
7550 Iterable<Vertex> neighbors = currVertex
7554 .filter(e -> e !=
null)
7555 .map(e -> e.getSrcVertex() == currId ?
7556 e.getTrgAP() : e.getSrcAP())
7558 .collect(Collectors.toList());
7559 for (
Vertex adj : neighbors) {
7564 if (currLevel.isEmpty()) {
7565 currLevel = nextLevel;
7566 nextLevel =
new ArrayDeque<>();
7594 this.templateJacket =
template;
7637 List<Template> path =
new ArrayList<Template>();
7679 if ( v1==
null || v2 ==
null)
7728 if (!e.getTrgAPClass().isCPMapCompatibleWith(e.getSrcAPClass(),
7756 DGraph graphB, List<Template> path)
7760 Template currentLevelVertex =
null;
7761 DGraph currentLevelGraphEmdInB = graphB;
7762 DGraph currentLevelGraphEmbInY = graphY;
7765 currentLevelVertex = (
Template) currentLevelGraphEmbInY
7767 currentLevelGraphEmdInB = t.getInnerGraph();
7768 currentLevelGraphEmbInY = currentLevelVertex.
getInnerGraph();
7785 List<AttachmentPoint> interfaceAPs =
new ArrayList<AttachmentPoint>();
7786 for (
Vertex v : subGraphB)
7790 if (ap.isAvailableThroughout())
7792 if (ap.isAvailable())
7795 interfaceAPs.add(ap);
7797 Vertex user = ap.getLinkedAP().getOwner();
7798 if (!subGraphB.contains(user))
7801 interfaceAPs.add(ap);
7806 return interfaceAPs;
7819 List<Vertex> subGraphB)
7821 List<AttachmentPoint> aps =
new ArrayList<AttachmentPoint>();
7822 for (
Vertex v : subGraphB)
7826 if (ap.isAvailable())
7831 Vertex user = ap.getLinkedAP().getOwner();
7832 if (!subGraphB.contains(user))
General set of constants used in DENOPTIM.
static final Object GRAPHBRANCHID
Property of Vertex used to record the identity of the graph branch holding that Vertex.
static final Object STOREDVID
Key of the property remembering vertex IDs.
static final Object VRTSYMMSETID
Property of Vertex used to keep mark symmetric vertexes during graph operations and before defining t...
Class defining a space of building blocks.
boolean useAPclassBasedApproach()
Check usage of APClass-based approach, i.e., uses attachment points with annotated data (i....
Set< APClass > getForbiddenEndList()
APClass getAPClassOfCappingVertex(APClass srcApClass)
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...
Parameters defining the fragment space.
FragmentSpace getFragmentSpace()
int getMaxRotatableBond()
String getRotSpaceDefFile()
boolean isCPMapCompatibleWith(APClass other, FragmentSpace fragSpace)
Check compatibility as defined in the compatibility matrix considering this AP as source and the othe...
String toString()
Do not use this to make SDF representations.
Class representing a mapping between attachment points (APs).
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
AttachmentPoint getLinkedAP()
Gets the attachment point (AP) that is connected to this AP via the edge user.
Object getProperty(Object description)
void setUser(Edge edge)
Sets the reference to the edge that is using this attachment point.
APClass getAPClass()
Returns the Attachment Point class.
int getID()
Returns a unique integer that is used to sort list of attachment points.
BondType getBondType()
Returns the bond type preferred by this attachment point as defined by the APClass,...
boolean isAvailable()
Check availability of this attachment point.
boolean hasConnectedSrcAtom(AttachmentPoint other)
Checks if this and another APs are rooted on atoms that are bonded in any way other than a possible c...
boolean isSrcInUser()
Checks the role of this AP in the user.
boolean hasSameSrcAtom(AttachmentPoint other)
AttachmentPoint getLinkedAPThroughout()
Gets the attachment point (AP) that is connected to this AP via the edge user or in any edge user tha...
void setProperty(Object key, Object property)
Edge getEdgeUser()
Gets the edge that is using this AP, or null if no edge is using this AP.
Query for searching AttachmentPoints.
boolean matches(AttachmentPoint ap)
Tests whether the given attachment point satisfies all non-null criteria in this query.
A candidate is the combination of a denoptim graph with molecular representation and may include also...
DGraph deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
We expect unique IDs for vertices.
JsonElement serialize(DGraph g, Type typeOfSrc, JsonSerializationContext context)
Utility to make selection of edges to a vertex tunable by a parameter.
List< Edge > apply(Vertex v)
Container for the list of vertices and the edges that connect them.
boolean removeVertexAndWeld(Vertex vertex, FragmentSpace fragSpace)
Remove a given vertex belonging to this graph and re-connects the resulting graph branches as much as...
List< ClosableChain > getClosableChains()
void getChildrenTree(Vertex vertex, List< Vertex > children, int numLayers, boolean stopBeforeRCVs)
Gets all the children of the current vertex recursively.
void setTemplateJacket(Template template)
Sets the reference to a template that embeds this graph, i.e., this graph's "jacket" template.
void setVertexList(ArrayList< Vertex > vertices)
String toJson()
Produces a string that represents this graph and that adheres to the JSON format.
void getChildTreeLimited(Vertex vertex, List< Vertex > children, Set< Vertex > limits)
Gets all the children of the current vertex recursively until it finds one of the vertices listed as ...
ArrayList< Integer > getIndexOfEdgesWithChild(int vid)
Candidate candidate
Reference to the candidate entity owning this graph, or null.
boolean replaceVertex(Vertex vertex, int bbId, BBType bbt, LinkedHashMap< Integer, Integer > apIdMap, FragmentSpace fragSpace)
Replaced a given vertex belonging to this graph with a new vertex generated specifically for this pur...
AttachmentPoint getAPOnLeftVertexID(long nbrVid, long vid)
Finds the AP that is on the first given parameter and that is used to make a connection to the second...
Vertex getVertexWithId(long vid)
Searches for a vertex with the given identifier.
int getSymmetricSetCount()
Returns the number of symmetric sets of vertices.
Vertex getSourceVertex()
Identifies and return the vertex from which the spanning tree originates.
List< Integer > getBranchIdOfVertex(Vertex v)
Returns the branch identifier.
Edge getEdgeAtPosition(int pos)
void getChildrenTree(Vertex vertex, List< Vertex > children, boolean markBranches)
Gets all the children of the current vertex recursively.
DGraph embedPatternsInTemplates(GraphPattern pattern, FragmentSpace fragSpace, ContractLevel contract)
Searches for the given pattern type and generated a new graph where each set of (clones of) vertexes ...
DGraph extractSubgraph(int index)
Creates a new graph that corresponds to the subgraph of this graph when exploring the spanning tree f...
void removeRing(Ring ring)
ArrayList< AttachmentPoint > getAttachmentPoints()
Returns the list of all attachment points contained in this graph.
boolean containsVertexID(long l)
Checks if a number is already used as VertexIDs within the graph.
boolean containsVertex(Vertex v)
Check if this graph contains the specified vertex.
List< Vertex > findVertices(VertexQuery vrtxQuery, Logger logger)
Filters a list of vertices according to a query.
boolean isIsomorphicTo(DGraph other)
Checks if this graph is "DENOPTIM-isomorphic" to the other one given.
ArrayList< AttachmentPoint > getAvailableAPs()
Returns the list of available attachment points contained in this graph.
void setCandidateClosableChains(ArrayList< ClosableChain > closableChains)
ArrayList< Ring > getRingsInvolvingVertex(Vertex v)
Returns the list of rings that include the given vertex in their fundamental cycle.
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
ArrayList< Ring > getRingsInvolvingVertexID(int vid)
int indexOfVertexWithID(long vid)
Returns the position of the first vertex that has the given ID.
boolean removeSingleVertexAndWeld(Vertex vertex, FragmentSpace fragSpace)
Remove a given vertex belonging to this graph and re-connects the resulting graph branches as much as...
List< ClosableChain > closableChains
The potentially closable chains of vertices.
DefaultUndirectedGraph< Vertex, UndirectedEdge > jGraph
JGraph representation used to detect DENOPTIM-isomorphism.
DGraph embedPatternsInTemplates(GraphPattern pattern, FragmentSpace fragSpace)
Searches for the given pattern type and generated a new graph where each set of (clones of) vertexes ...
DGraph(List< Vertex > gVertices, List< Edge > gEdges)
void getChildrenTree(Vertex vertex, List< Vertex > children)
Gets all the children of the current vertex recursively.
boolean graphNeedsCappingGroups(FragmentSpace fragSpace)
Checks the graph for unused APs that need to be capped.
AttachmentPoint getAPWithId(int id)
Returns the attachment point with the given identifier, or null if no AP is found with the given iden...
void removeVertex(Vertex vertex)
Remove a vertex from this graph.
Iterator< SymmetricVertexes > getSymSetsIterator()
Get an iterator for the sets of symmetrically related vertices.
void removeSymmetryRedundance(List< Vertex > list)
Remove all but one of the symmetry-related partners in a list of vertices.
static void reorderVertexList(DGraph g)
Sets the vertex at the lowest level as the scaffold, changes the directions of edges so that the sc...
DGraph extractSubgraph(Vertex seed)
Creates a new graph that corresponds to the subgraph of this graph when exploring the spanning tree f...
ArrayList< Vertex > getRCVertices()
Search for ring closing vertices: vertices that contain only a RingClosingAttractor
ArrayList< Vertex > getFreeRCVertices()
Search for unused ring closing vertices: vertices that contain only a RingClosingAttractor and are no...
void setCandidateOwner(Candidate candidate)
Sets the reference to the candidate item that is defined by this graph.
List< List< Vertex > > getSymmetricSubGraphs(List< Vertex > subGrpVrtxs)
We assume that the subgraph is a continuously connected, directed graph.
DGraph extractSubgraph(Vertex seed, int numLayers, boolean stopBeforeRCVs)
Creates a new graph that corresponds to the subgraph of this graph when exploring the spanning tree f...
int indexOf(Vertex v)
Returns the index of a vertex in the list of vertices of this graph.
DGraph editGraph(ArrayList< GraphEdit > edits, boolean symmetry, FragmentSpace fragSpace, Logger logger)
Edit this graph according to a given list of edit tasks.
List< Vertex > gVertices
The vertices belonging to this graph.
boolean hasScaffoldTypeVertex()
Checks if this graph contains a scaffold vertex.
void setRings(ArrayList< Ring > rings)
Object[] checkConsistency(RunTimeParameters settings)
Peeks into this graph to derive a preliminary chemical representation with SMILES and InChIKey.
Vertex getVertexAtPosition(int pos)
Returns the vertex that is in the given position of the list of vertices belonging to this graph.
boolean containsAtoms()
Returns true if this graph has any vertex that contains atoms.
List< Edge > getEdgesWithTrg(Vertex v)
Returns the list of edges that arrive from the given vertex, i.e., edges where the trgAP is owned by ...
static DGraph getEmbeddedGraphInClone(DGraph graphY, DGraph graphB, List< Template > path)
Searches for a graphs (X) embedded at any level in a graph (Y) by knowing.
List< Ring > gRings
The rings defined in this graph.
int getBondingAPIndex(Vertex srcVert, int dapidx, Vertex dstVert)
void setSymmetricVertexSets(List< SymmetricVertexes > symVertices)
AtomicInteger apCounter
Generator of unique AP identifiers within this graph.
Vertex getDeepestAmongThese(List< Vertex > list)
Identify the oldest ancestor (i.e., most great grandparent) in the given collection.
void appendGraphOnAP(AttachmentPoint apOnThisGraph, AttachmentPoint apOnIncomingGraph, BondType bndType)
Appends a graph onto this graph.
static boolean replaceSingleSubGraph(APMapping apMapping, FragmentSpace fragSpace)
Replaced the subgraph defined by a set of Attachment Points that belong to a graph (ie....
static void setScaffold(Vertex v)
Update the graph so that the vertex argument is at the scaffold level i.e.
Map< DGraph, ObjectPair > extractPattern(GraphPattern pattern, boolean recordConnectivity)
Extracts subgraphs that match the provided pattern.
boolean isReversible(FragmentSpace fragSpace)
Checks is the every edge in the graph can be defined in the opposite direction according to the APCla...
String getBranchIdOfVertexAsStr(Vertex v)
Returns the branch identifier as a literal string.
List< AttachmentPoint > getAvailableAPsThroughout()
Returns the list of attachment points contained in this graph that are available throughout the templ...
boolean directedPathExists(Vertex src, Vertex trg)
Uses branch identifiers to define is two vertices are in such a relation that allows the drawing of a...
void appendVertexOnAP(AttachmentPoint srcAP, AttachmentPoint trgAP)
Append a vertex to this graph: adds the new vertex to the list of vertices belonging to the graph,...
List< Vertex > getVertexList()
Returns the list of vertexes without entering Templates.
boolean removeBranchStartingAt(Vertex v)
Deletes the branch, i.e., the specified vertex and its children.
static boolean compareGraphNodes(Vertex thisV, DGraph thisG, Vertex otherV, DGraph otherG)
Compares graphs by spanning vertices starting from the given vertex and following the direction of ed...
void convertSymmetricLabelsToSymmetricSets()
Looks for any symmetric labels, creates symmetric sets that collect the same information,...
DGraph(List< Vertex > gVertices, List< Edge > gEdges, List< Ring > gRings, List< ClosableChain > closableChains, List< SymmetricVertexes > symVertices)
List< AttachmentPoint > getInterfaceAPs(List< Vertex > subGraphB)
Searches for all AttachmentPoints that represent the interface between a subgraph,...
DGraph clone()
Returns almost "deep-copy" of this graph.
boolean hasForbiddenEnd(FragmentSpaceParameters fsSettings)
Check if there are forbidden ends: free attachment points that are not suitable for capping and not a...
List< DGraph > extractPattern(GraphPattern pattern)
Extracts subgraphs that match the provided pattern.
void removeCappingGroups(List< Vertex > lstVerts)
Remove capping groups that belong to this graph and are in the given list.
ArrayList< Vertex > getChildVertices(Vertex vertex)
boolean sameAsRings(StringBuilder reason, Map< Vertex, Vertex > vertexMap, Ring rT, Vertex vhT, Vertex vtT, Ring rO)
DGraph extractSubgraph(Vertex seed, boolean stopBeforeRCVs)
Creates a new graph that corresponds to the subgraph of this graph when exploring the spanning tree f...
void renumberGraphVertices()
Reassign vertex IDs to all vertices of this graph.
boolean containsOrEmbedsVertex(Vertex v)
Check if the specified vertex is contained in this graph as a node or in any inner graphs that may be...
ArrayList< DGraph > makeAllGraphsWithDifferentRingSets(RunTimeParameters settings)
Evaluates the possibility of closing rings in this graph and generates all alternative graphs resulti...
static DGraph fromJson(Reader reader)
Reads a JSON string and returns an instance of this class.
void addRing(Vertex vI, Vertex vJ, BondType bndTyp)
Adds a chord between the given vertices, thus adding a ring in this graph.
List< Vertex > getSymVerticesForVertex(Vertex v)
static final String SYM_ID
Key used to uniquely identify vertices and attachment points for symmetry detection.
boolean replaceSubGraph(List< Vertex > subGrpVrtxs, DGraph incomingGraph, LinkedHashMap< AttachmentPoint, AttachmentPoint > apMap, FragmentSpace fragSpace)
Replaced the subgraph represented by a given collection of vertices that belong to this graph.
static Set< Vertex > exploreGraph(Vertex seed, Set< Vertex > limits)
Navigates vertexes starting from a given seed vertex, and stopping the exploration at any of the give...
void changeSignOfVertexID()
Change all vertex IDs to the corresponding negative value.
static boolean compareGraphNodes(Vertex seedOnA, DGraph gA, Vertex seedOnB, DGraph gB, Map< Vertex, Vertex > vertexMap, StringBuilder reason)
Compares graphs by spanning vertices starting from the given vertex and following the direction of ed...
boolean insertSingleVertex(Edge edge, Vertex newLink, LinkedHashMap< AttachmentPoint, AttachmentPoint > apMap)
Inserts a given vertex in between two vertices connected by the given edge.
void getChildTreeLimited(Vertex vertex, List< Vertex > children, List< Vertex > limitsInClone, boolean stopBeforeRCVs)
Gets all the children of the current vertex recursively until it finds one of the vertices listed as ...
void reassignSymmetricLabels()
Marks the vertices of this graph with a string that is consistent for all vertices that belong to sym...
List< Edge > findEdges(EdgeQuery edgeQuery, Logger logger)
Search this graph for edges that match the criteria defined in a query.
void removeVertexAndSymmetricOnes(Vertex v, boolean symmetry)
Deletes a vertex and, optionally, its symmetric couinterparts.
List< Edge > gEdges
The edges belonging to this graph.
void replaceUnusedRCVsWithCapps(FragmentSpace fragSpace)
Removes unused ring-closing vertices.
void appendGraphOnGraph(List< Vertex > parentVertices, List< Integer > parentAPIdx, DGraph subGraph, Vertex childVertex, int childAPIdx, BondType bndType, boolean onAllSymmAPs)
Append a graph (incoming=I) onto this (receiving=R).
void setEdgeList(ArrayList< Edge > edges)
boolean sameAs(DGraph other, StringBuilder reason)
Compare this and another graph ignoring the vertex IDs.
int getLevel(Vertex v)
Calculates the level of a vertex in this graph.
Vertex getParent(Vertex v)
void removeSymmetryRedundantIds(ArrayList< Long > list)
Remove all but one of the symmetry-related partners in a given list of vertex IDs.
static void exploreGraph(Vertex seed, Set< Vertex > limits, Set< Vertex > visited)
Depth-first exploration of graphs.
void removeSymmetrySet(SymmetricVertexes ss)
Tries to determine the set of symmetric vertices in this graph based on finding compatible Vertexes t...
void storeCurrentVertexIDs()
Copies the current vertexID of each vertex into a property of the vertex itself.
void appendGraphOnAP(Vertex parentVertex, int parentAPIdx, DGraph subGraph, Vertex childVertex, int childAPIdx, BondType bndType, Map< Vertex, SymmetricVertexes > newSymSets)
Append a subgraph (I) to this graph (R) specifying which vertex and attachment point to use for the c...
static void fixEdgeDirections(DGraph graph)
Flips edges in the graph so that the scaffold is the only source vertex.
DGraph getOutermostGraphOwner()
List< List< AttachmentPoint > > findAPs(List< AttachmentPointQuery > apQueries, Logger logger)
Search the graph for AttachmentPoints that match the criteria defined in a list of queries.
void removeCappingGroupsOn(Vertex vertex)
Remove capping groups on the given vertex of this graph.
List< Long > findVerticesIds(VertexQuery query, Logger logger)
Search a graph for vertices that match the criteria defined in a query vertex.
static DGraph fromJson(String json)
Reads a JSON string and returns an instance of this class.
List< Edge > getEdgesWithSrc(Vertex v)
Returns the list of edges that depart from the given vertex, i.e., edges where the srcAP is owned by ...
void addRing(Vertex vI, Vertex vJ)
Adds a chord between the given vertices, thus adding a ring in this graph.
DGraph extractSubgraph(Collection< Vertex > definedOn, Set< Edge > connectionToSubgraph, Set< Edge > connectionFromSubgraph)
Returns a clone of the subgraph defined by the a collection of vertices belonging to this graph.
List< Vertex > findVertices(VertexQuery vrtxQuery, boolean purgeSym, Logger logger)
Filters a list of vertices according to a query.
boolean isVertexIDInRing(int vid)
void addSymmetricSetOfVertices(SymmetricVertexes symSet)
Adds a symmetric set of vertices to this graph.
SymmetricVertexes getSymSetForVertex(Vertex v)
Returns the set of vertexes symmetric to the given one.
void getParentTree(Vertex vertex, List< Vertex > parentTree)
Traverse the graph until it identifies the source of the directed path reachable from the given verte...
void addCappingGroups(FragmentSpace fragSpace)
Add a capping groups on free unused attachment points.
DGraph(List< Vertex > gVertices, List< Edge > gEdges, List< Ring > gRings)
List< Edge > getEdgeList()
DGraph(List< Vertex > gVertices, List< Edge > gEdges, List< Ring > gRings, List< SymmetricVertexes > symSets)
void removeCappingGroups()
Remove all capping groups on this graph.
void cleanup()
Wipes the data in this graph.
boolean hasRings()
Check for rings in this graph.
List< AttachmentPoint > findAPs(AttachmentPointQuery apQuery, Logger logger)
Search the graph for AttachmentPoints that match the criteria defined in a query.
List< Vertex > getVertexAnyLevel()
Returns the list of vertexes at any level in the graph.
void removeCappingGroupsFromChilds(List< Vertex > lstVerts)
Object[] checkConsistency(RunTimeParameters settings, boolean permissive)
Peeks into this graph to derive a preliminary chemical representation with SMILES and InChIKey.
List< Vertex > getMutableSites(List< MutationType > ignoredTypes)
A list of mutation sites from within this graph.
DefaultUndirectedGraph< Node, NodeConnection > jGraphKernel
JGraph representation used to detect DENOPTIM-isostructural graphs.
ArrayList< Edge > getEdgesWithChild(int vid)
boolean isVertexInRing(Vertex v)
List< AttachmentPoint > getSubgraphAPs(List< Vertex > subGraphB)
Searches for all AttachmentPoints that are owned by vertices in a subgraph but either available or us...
boolean isConnected()
Check if this graph is connected, i.e., there is at least one path between any two vertices.
Candidate getCandidateOwner()
Returns the reference of the candidate item that is defined by this graph.
List< SymmetricVertexes > symVertices
ArrayList< Ring > getRingsInvolvingVertex(Vertex[] vs)
Returns the list of rings that include the given list of vertices in their fundamental cycle.
Map< Long, Long > renumberVerticesGetMap()
Reassign vertex IDs to a graph.
static void replaceChordWithEdge(Ring chord)
We assume that the two vertexes belong to the same graph.
boolean hasSymmetryInvolvingVertex(Vertex v)
static void fixEdgeDirections(Vertex v, Set< Long > visited)
Recursive utility method for fixEdgeDirections(graph).
boolean replaceVertex(Vertex vertex, int bbId, BBType bbt, LinkedHashMap< Integer, Integer > apIdMap, boolean symmetry, FragmentSpace fragSpace)
Replaced a given vertex belonging to this graph with a new vertex generated specifically for this pur...
ArrayList< Vertex > getUsedRCVertices()
Search for used ring closing vertices: vertices that contain only a RingClosingAttractor and are part...
boolean insertVertex(Edge edge, int bbId, BBType bbt, LinkedHashMap< AttachmentPoint, Integer > apMap, FragmentSpace fragSpace)
Inserts a given vertex in between two vertices connected by the given edge.
Edge getEdgeWithParent(long l)
Looks for an edge that points to a vertex with the given vertex id.
void getChildrenTree(Vertex vertex, List< Vertex > children, AtomicInteger branchIdGenerator, List< Integer > prevBranchId)
Gets all the children of the current vertex recursively.
void removeEdge(Edge edge)
Removes an edge and update the free valences of the attachment points that were originally involved i...
void getChildTreeLimited(Vertex vertex, List< Vertex > children, boolean stopBeforeRCVs)
Gets all the children of the current vertex recursively.
Template templateJacket
Reference to the Template embedding this graph.
boolean removeBranchStartingAt(Vertex v, boolean symmetry)
Deletes the branch, i.e., the specified vertex and its children.
int getHeavyAtomsCount()
Calculate the number of atoms from the graph representation.
DGraph extractSubgraph(Collection< Vertex > definedOn)
Returns a clone of the subgraph defined by the a collection of vertices belonging to this graph.
boolean removeOrphanBranchStartingAt(Vertex v)
Deletes the branch, i.e., the specified vertex and its children.
List< Vertex > getMutableSites()
A list of mutation sites from within this graph.
String localMsg
A free-format string used to record simple properties in the graph.
void addEdge(Edge edge)
Adds the edge to the list of edges belonging to this graph.
List< Template > getEmbeddingPath()
Find the path that one has to traverse to reach this graph from any template-embedding structure.
void addCappingGroups(List< Vertex > vertexAddedToThis, FragmentSpace fragSpace)
Add a capping group on the given vertices, if needed.
Template getTemplateJacket()
boolean removeChainUpToBranching(Vertex v, FragmentSpace fragSpace)
Mutates the graph by removing the chain where a given vertex is located up to the first branching (i....
List< Integer > getBranchIdOfVertexAtPosition(int i)
Returns the branch identifier.
void setLocalMsg(String msg)
List< Vertex > getSelectedMutableSites(MutationType requestedType)
A list of mutation sites from within this graph.
void appendGraphOnGraph(Vertex parentVertex, int parentAPIdx, DGraph subGraph, Vertex childVertex, int childAPIdx, BondType bndType, Map< Vertex, SymmetricVertexes > newSymSets, boolean onAllSymmAPs)
Append a graph (incoming=I) onto this graph (receiving=R).
boolean isIsostructuralTo(DGraph other)
Checks if this graph is "DENOPTIM-isostructural" to the other one given.
DGraph extractSubgraph(Vertex seed, List< Vertex > limits, boolean stopBeforeRCVs)
Creates a new graph that corresponds to the subgraph of this graph when exploring the spanning tree f...
boolean hasOrEmbedsRings()
Check for rings in this graph and in any graph that is embedded at any level in any vertex of this gr...
void dfsEncodePaths(Vertex current, String currentPath, Set< Vertex > visited, Map< String, List< Vertex > > pathMap)
Performs a depth-first search (DFS) starting from a given Vertex to encode paths in the graph.
boolean detectSymVertexSets()
Detects and groups symmetric sets of Vertexes in the graph based on unique identification and path en...
This class represents the edge between two vertices.
AttachmentPoint getTrgAP()
void flipEdge()
Exchanges source and target vertices and respective APs of this edge.
AttachmentPoint getSrcAP()
A query for edges: a list of properties that target edges should possess in order to match this query...
boolean matches(Edge e)
Tests whether the given edge satisfies this query.
Class representing a continuously connected portion of chemical object holding attachment points.
This class represents the closure of a ring in a spanning tree.
int getPositionOf(Vertex v)
void addVertex(Vertex v)
Append a Vertex to the list.
Vertex getVertexAtPosition(int i)
void setBondType(BondType bndType)
Set the bond type (i.e., bond order) of the chord connecting the head and the tail vertices.
List< Vertex > getVertices()
A collection of AttachmentPoints that are related by a relation that we call "symmetry",...
boolean add(T item)
Adds an item to this list, if not already present.
A collection of Vertexs that are related by a relation that we call "symmetry", even though this clas...
void removeProjectionOfInnerAP(AttachmentPoint oldInnerAP)
Removes the mapping of the given inner AP from this template's surface, if such mapping exists.
void setInnerGraph(DGraph innerGraph)
void updateInnerApID(AttachmentPoint oldInnerAP, AttachmentPoint newInnerAP)
Replaces a given link between APs on the surface of this template (i.e., outerAP) and the correspondi...
void addInnerToOuterAPMapping(AttachmentPoint newInnerAP)
Adds the projection of an AP in the template's inner graph (i.e., innerAP) to the list of APs visible...
ArrayList< AttachmentPoint > getAttachmentPoints()
Return the list of attachment points visible from outside the template, i.e., the so-called outer APs...
void clearIAtomContainer()
Removes the molecular representation.
void setContractLevel(ContractLevel contract)
Imposes the given contract to this template.
AttachmentPoint getOuterAPFromInnerAP(AttachmentPoint innerAP)
AttachmentPoint getInnerAPFromOuterAP(AttachmentPoint outerAP)
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
ArrayList< Vertex > getChildrenThroughout()
Looks into the edges that use any of the APs that belong to this vertex and returns the list of verti...
abstract Vertex clone()
Returns a deep-copy of this vertex.
void setMutationTypes(List< MutationType > lst)
int getBuildingBlockId()
Returns the index of the building block that should correspond to the position of the building block ...
Edge getEdgeToParent()
Looks into the edges that use any of the APs that belong to this vertex and returns the edge that has...
void setVertexId(long vertexId2)
int getFreeAPCountThroughout()
Counts the number of attachment points that are availability throughout the graph level,...
int getIndexOfAP(AttachmentPoint ap)
Returns the position of the given AP in the list of APs of this vertex.
String toString()
Produces a human readable, short string to represent the vertex by its vertex ID, building block ID (...
Vertex getParent()
Looks into the edges that use any of the APs that belong to this vertex and returns the vertex which ...
Vertex.BBType getBuildingBlockType()
DGraph getGraphOwner()
Returns the graph this vertex belongs to or null.
ArrayList< Vertex > getChilddren()
Looks into the edges that use any of the APs that belong to this vertex and returns the list of verti...
abstract List< AttachmentPoint > getAttachmentPoints()
Object getProperty(Object property)
boolean sameAs(Vertex other)
Compares this and another vertex ignoring vertex IDs.
int getCappedAPCountThroughout()
Counts the number of attachment points that are used by BBType#CAP vertex.
void setProperty(Object key, Object property)
ArrayList< AttachmentPoint > getFreeAPThroughout()
Gets attachment points that are availability throughout the graph level, i.e., checks also across the...
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
static Vertex newVertexFromLibrary(int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Builds a new molecular fragment kind of vertex.
Edge getEdgeWith(Vertex other)
Finds the edge between this and the other vertex, if it exists.
Query for searching vertices.
boolean matches(Vertex v)
Tests whether the given vertex satisfies all non-null criteria in this query.
ClosableChain represents a chain of fragments (chain links) that is closable (or candidate closable).
This is a tool to identify and manage vertices' connections not included in the DGraph,...
boolean checkChelatesGraph(DGraph molGraph, List< Ring > ringsSet)
Evaluates the combination of a DENOPTIMGraph and a set of DENOPTIMRings and decides whether it's a pr...
ArrayList< List< Ring > > getPossibleCombinationOfRings(IAtomContainer mol, DGraph molGraph)
Identifies all possible ring closing paths and returns them as list of DENOPTIMRings ready to be appe...
This object represents a path in a DGraph.
List< Vertex > getVertecesPath()
Returns the list of verteces involved.
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final Map< String, String > RCATYPEMAP
Recognized types of RingClosingAttractor and compatible types.
Parameters and setting related to handling ring closures.
int getMaxRcaPerType(String type)
int getMinRcaPerType(String type)
boolean buildChelatesMode
Flag activating procedures favoring formation of chelates.
void allowRingClosures(boolean value)
int compare(NodeConnection other)
This class represents a subgraph feature that defined the structure of a graph.
static final String REFTOVERTEXKERNEL
Property if Vertex used to store the reference to the corresponding Node.
int compare(UndirectedEdge other)
Utility methods for input/output.
static ArrayList< DGraph > readDENOPTIMGraphsFromFile(File inFile)
Reads a list of DGraphs from file.
static void writeGraphToJSON(File file, DGraph graph)
Writes the graph to JSON file.
Class for de/serializing DENOPTIM graphs from/to JSON format.
Tool to build build three-dimensional (3D) tree-like molecular structures from DGraph.
void setAlignBBsIn3D(boolean align)
Sets the flag that controls whether building blocks have to be aligned according to the AP vectors or...
IAtomContainer convertGraphTo3DAtomContainer(DGraph graph)
Created a three-dimensional molecular representation from a given DGraph.
Collection of parameters controlling the behavior of the software.
RunTimeParameters getParameters(ParametersType type)
Logger getLogger()
Get the name of the program specific logger.
static< T > void unionOfIntersectingSets(List< Set< T > > list)
Takes the union of any two sets in this list that intersect.
Definition of a graph editing task.
static synchronized void ensureVertexIDConsistency(long l)
Method used to ensure consistency between internal atomic integer and vertex id from imported graphs.
static synchronized long getUniqueVertexIndex()
Unique counter for the number of graph vertices generated.
static synchronized int getUniqueGraphIndex()
Unique counter for the number of graphs generated.
Utilities for molecule conversion.
static String getInChIKeyForMolecule(IAtomContainer mol, Logger logger)
Generates the InChI key for the given atom container.
static int getNumberOfRotatableBonds(IAtomContainer mol)
Count number of rotatable bonds.
static String getSMILESForMolecule(IAtomContainer mol, Logger logger)
Returns the SMILES representation of the molecule.
static double getMolecularWeight(IAtomContainer mol)
static String getSymbolOrLabel(IAtom atm)
Gets either the elemental symbol (for standard atoms) of the label (for pseudo-atoms).
static int getHeavyAtomCount(IAtomContainer mol)
The heavy atom count.
This class is the equivalent of the Pair data structure used in C++ Although AbstractMap....
Tool to generate random numbers and random decisions.
public< T > T randomlyChooseOne(Collection< T > c)
Chooses one member among the given collection.
Tool box for definition and management of the rotational space, which is given by the list of rotatab...
static ArrayList< ObjectPair > defineRotatableBonds(IAtomContainer mol, String defRotBndsFile, boolean addIterfragBonds, boolean excludeRings, Logger logger)
Define the rotational space (a.k.a.
Possible chemical bond types an edge can represent.
Enum specifying to what extent the template's inner graph can be changed.
FREE
Inner graphs are free to change within the confines of the required AttachmentPoints.
The type of building block.
Identifier of the type of parameters.
FS_PARAMS
Parameters pertaining the definition of the fragment space.
RC_PARAMS
Parameters pertaining to ring closures in graphs.
Types of mutation defined in relation to what happens to the target vertex (i.e., the actual mutation...