$darkmode
DENOPTIM
GraphConversionTool.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Vishwesh Venkatraman <vishwesh.venkatraman@ntnu.no> and
4 * Marco Foscato <marco.foscato@uib.no>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20package denoptim.utils;
21
22import java.util.ArrayList;
23import java.util.HashMap;
24import java.util.List;
25import java.util.Map;
26
27import org.jgrapht.graph.DefaultUndirectedGraph;
28
29import denoptim.exception.DENOPTIMException;
30import denoptim.fragspace.FragmentSpace;
31import denoptim.graph.AttachmentPoint;
32import denoptim.graph.DGraph;
33import denoptim.graph.Edge;
34import denoptim.graph.Edge.BondType;
35import denoptim.graph.EmptyVertex;
36import denoptim.graph.Fragment;
37import denoptim.graph.Ring;
38import denoptim.graph.SymmetricVertexes;
39import denoptim.graph.Template;
40import denoptim.graph.Vertex;
41import denoptim.graph.simplified.Node;
42import denoptim.graph.simplified.NodeConnection;
43import denoptim.graph.simplified.UndirectedEdge;
44
45
54{
55
56//------------------------------------------------------------------------------
57
72 public static DGraph getGraphFromString(String strGraph,
73 FragmentSpace fragSpace) throws DENOPTIMException
74 {
75 return getGraphFromString(strGraph, true, fragSpace);
76 }
77
78//------------------------------------------------------------------------------
79
99 @Deprecated
100 public static DGraph getGraphFromString(String strGraph,
101 boolean useMolInfo, FragmentSpace fragSpace) throws DENOPTIMException
102 {
103 // get the main blocks to parse: graphID, vertices, edges, rings, symSet
104 String[] s1 = strGraph.split("\\s+");
105 int gcode = Integer.parseInt(s1[0]);
106 String vStr = s1[1];
107 String eStr = "";
108 if (s1.length > 2)
109 {
110 eStr= s1[2];
111 }
112 String oStr = "";
113 for (int i=3; i<s1.length; i++)
114 {
115 oStr = oStr + " " + s1[i];
116 }
117 String rStr = "";
118 String sStr = "";
119 int beginningOfSymSets = oStr.indexOf("SymmetricSet");
120 if (beginningOfSymSets == -1)
121 {
122 rStr = oStr;
123 }
124 else
125 {
126 rStr = oStr.substring(0,beginningOfSymSets);
127 sStr = oStr.substring(beginningOfSymSets);
128 }
129
130 // split vertices on the comma
131 String[] s2 = vStr.split(",");
132
133 ArrayList<Vertex> vertices = new ArrayList<>();
134
135 // for each vertex
136 for (int i=0; i<s2.length; i++)
137 {
138 String[] s3 = s2[i].split("_");
139
140 // vertex id
141 int vid = Integer.parseInt(s3[0]);
142 // molid
143 int molid = Integer.parseInt(s3[1]) - 1;
144 // fragment/scaffold
145 Vertex.BBType fragtype = Vertex.BBType.parseInt(
146 Integer.parseInt(s3[2]));
147
148 Vertex dv;
149 if (fragSpace.isDefined())
150 {
151 dv = Vertex.newVertexFromLibrary(vid, molid, fragtype,
152 fragSpace);
153 } else {
154 // WARNING: in this case we cannot know the exact number of
155 // attachment points, so we will add as many as needed to
156 // build the graph.
157 dv = new EmptyVertex(vid);
158 }
159 vertices.add(dv);
160 }
161
162 ArrayList<Edge> edges = new ArrayList<>();
163
164 // split edges on the comma
165 if (eStr.contains(","))
166 {
167 s2 = eStr.split(",");
168 for (int i=0; i<s2.length; i++)
169 {
170 String[] s4 = s2[i].split("_");
171 int srcVrtxID = Integer.parseInt(s4[0]);
172
173 int srcAPID = Integer.parseInt(s4[1]);
174
175 int trgVrtxID = Integer.parseInt(s4[2]);
176
177 int trgAPID = Integer.parseInt(s4[3]);
178
179 BondType btype = BondType.parseStr(s4[4]);
180
181 /* Find source and target attachment points of edge */
182 EmptyVertex dummy = new EmptyVertex();
183 dummy.addAP();
184 dummy.addAP();
185 AttachmentPoint srcAP = dummy.getAP(0);
186 AttachmentPoint trgAP = dummy.getAP(1);
187
188 try {
189 for (int j = 0, apsFound = 0; apsFound < 2; j++) {
190 Vertex vertex = vertices.get(j);
191 if (vertex.getVertexId() == srcVrtxID) {
192 // WARNING!
193 // When we import graphs without a definition of the
194 // fragment space we can only guess how many APs
195 // there are on a vertex. Here we add as many as
196 // needed to allow formation of the edge.
197 // Currently we cannot know the index of the src
198 // atom, so we simply put this index to 0.
199 for (int k = vertex.getNumberOfAPs(); k<(srcAPID+1);
200 k++)
201 {
202 if (vertex instanceof EmptyVertex)
203 ((EmptyVertex)vertex).addAP();
204 if (vertex instanceof Fragment)
205 ((Fragment)vertex).addAP(0);
206 }
207
208 srcAP = vertex.getAP(srcAPID);
209 if (s4.length > 5) {
210 srcAP.setAPClass(s4[5]);
211 }
212 apsFound++;
213 } else if (vertex.getVertexId() == trgVrtxID) {
214 // WARNING!
215 // When we import graphs without a definition of the
216 // fragment space we can only guess how many APs
217 // there are on a vertex. Here we add as many as
218 // needed to allow formation of the edge.
219 // Currently we cannot know the index of the src
220 // atom, so we simply put this index to 0.
221 for (int k = vertex.getNumberOfAPs(); k<(trgAPID+1);
222 k++)
223 {
224 if (vertex instanceof EmptyVertex)
225 ((EmptyVertex)vertex).addAP();
226 if (vertex instanceof Fragment)
227 ((Fragment)vertex).addAP(0);
228 }
229
230 trgAP = vertex.getAP(trgAPID);
231 if (s4.length > 5) {
232 trgAP.setAPClass(s4[6]);
233 }
234 apsFound++;
235 }
236 }
237 } catch (IndexOutOfBoundsException e) {
238 throw new IllegalStateException("Searching for srcVrtxID:"
239 + srcVrtxID + ", srcAPID:"
240 + srcAPID + ", trgVrtxID:"
241 + trgVrtxID + ", trgAPID:"
242 + trgAPID + ", but source or target " +
243 "attachment point not present on source or target" +
244 " vertex. "+strGraph, e);
245 }
246
247 Edge ne = new Edge(srcAP, trgAP, btype);
248 edges.add(ne);
249 }
250 }
251
252 // collect Rings
253 ArrayList<Ring> rings = new ArrayList<>();
254 String[] sr2 = rStr.split("DENOPTIMRing ");
255 for (int i=1; i<sr2.length; i++)
256 {
257 String sr4 = sr2[i];
258 String sr5 = sr4.substring(sr4.indexOf("=") + 1).trim();
259 sr5 = sr5.substring(1,sr5.length()-2);
260 String[] sr6 = sr5.split(",\\s");
261 ArrayList<Vertex> lstVerteces =
262 new ArrayList<Vertex>();
263 for (int j=0; j<sr6.length; j++)
264 {
265 String sr7[] = sr6[j].split("_");
266
267 // vertex id
268 int vid = Integer.parseInt(sr7[0]);
269
270 for (Vertex v : vertices)
271 {
272 if (v.getVertexId() == vid)
273 {
274 lstVerteces.add(v);
275 break;
276 }
277 }
278 }
279
280 Ring r = new Ring(lstVerteces);
281 rings.add(r);
282 }
283
284 // collect map of symmetric vertices
285 List<SymmetricVertexes> symSets = new ArrayList<SymmetricVertexes>();
286 String[] ss8 = sStr.split("SymmetricSet ");
287 for (int i=1; i<ss8.length; i++)
288 {
289 String ss4 = ss8[i];
290 String ss5 = ss4.substring(ss4.indexOf("=") + 1).trim();
291 ss5 = ss5.substring(1,ss5.length()-2);
292 String[] ss6 = ss5.split(",\\s");
293 ArrayList<Integer> symVrtxIds = new ArrayList<Integer>();
294 for (int j=0; j<ss6.length; j++)
295 {
296 symVrtxIds.add(Integer.parseInt(ss6[j]));
297 }
298
300 for (Integer vid : symVrtxIds)
301 {
302 vertices.stream()
303 .filter(v -> v.getVertexId()==vid)
304 .forEach(v -> ss.add(v));
305 }
306 symSets.add(ss);
307 }
308
309 DGraph g = new DGraph(vertices, edges, rings, symSets);
310
311 // update bond type of chords
312 for (Ring r : rings)
313 {
314 long vid = r.getHeadVertex().getVertexId();
315 for (Edge e : edges)
316 {
317 if (e.getTrgVertex() == vid || e.getSrcVertex() == vid)
318 {
319 r.setBondType(e.getBondType());
320 break;
321 }
322 }
323 }
324
325 g.setGraphId(gcode);
326
327 return g;
328 }
329
330//------------------------------------------------------------------------------
331
346 public static DefaultUndirectedGraph<Vertex, UndirectedEdge>
348 {
349 DefaultUndirectedGraph<Vertex, UndirectedEdge> g =
350 new DefaultUndirectedGraph<>(UndirectedEdge.class);
351 Map<Vertex,Integer> vis = new HashMap<Vertex,Integer>();
352 int i = 0;
353 for (Vertex v : dg.getVertexList())
354 {
355 vis.put(v, i);
356 i += 1;
357 if (v.isRCV())
358 {
359 if (!dg.isVertexInRing(v))
360 {
361 g.addVertex(v);
362 }
363 } else {
364 g.addVertex(v);
365 }
366 }
367
368 for (Edge e : dg.getEdgeList())
369 {
370 Vertex vA = e.getSrcAP().getOwner();
371 Vertex vB = e.getTrgAP().getOwner();
372 if (!vA.isRCV() && !vB.isRCV())
373 {
374 g.addEdge(vA, vB, new UndirectedEdge(e.getSrcAP(),
375 e.getTrgAP(), e.getBondType()));
376 }
377 }
378
379 for (Ring r : dg.getRings())
380 {
381 Vertex vA = r.getHeadVertex();
382 Vertex vB = r.getTailVertex();
383 Vertex pA = vA.getParent();
384 Vertex pB = vB.getParent();
385
386 g.addEdge(pA, pB, new UndirectedEdge(
389 }
390 return g;
391 }
392
393//------------------------------------------------------------------------------
394
408 public static DefaultUndirectedGraph<Node, NodeConnection>
410 {
411 DefaultUndirectedGraph<Node, NodeConnection> g =
412 new DefaultUndirectedGraph<>(NodeConnection.class);
413 for (Vertex v : dg.getVertexList())
414 {
415 if (v.isRCV())
416 {
417 if (!dg.isVertexInRing(v))
418 {
419 g.addVertex(new Node(v));
420 }
421 } else {
422 g.addVertex(new Node(v));
423 }
424 }
425
426 for (Edge e : dg.getEdgeList())
427 {
428 Vertex vA = e.getSrcAP().getOwner();
429 Vertex vB = e.getTrgAP().getOwner();
430 if (!vA.isRCV() && !vB.isRCV())
431 {
432 Node vkA = (Node) vA.getProperty(
434 Node vkB = (Node) vB.getProperty(
436 g.addEdge(vkA, vkB, new NodeConnection(e.getBondType()));
437 }
438 }
439
440 for (Ring r : dg.getRings())
441 {
442 Vertex vA = r.getHeadVertex();
443 Vertex vB = r.getTailVertex();
444 Vertex pA = vA.getParent();
445 Vertex pB = vB.getParent();
446 Node pvkA = (Node) pA.getProperty(
448 Node pvkB = (Node) pB.getProperty(
450 g.addEdge(pvkA, pvkB, new NodeConnection(r.getBondType()));
451 }
452
453 for (AttachmentPoint ap : dg.getAvailableAPs())
454 {
455 Node vap = new Node(ap);
456 Vertex srcVrtx = ap.getOwner();
457 Node pSrcVrtx = (Node) srcVrtx.getProperty(
459 g.addVertex(vap);
460 g.addEdge(pSrcVrtx, vap, new NodeConnection(ap.getBondType()));
461 }
462
463 // Cleanup
464 for (Vertex v : dg.getVertexList())
465 {
466 v.removeProperty(Node.REFTOVERTEXKERNEL);
467 }
468
469 return g;
470 }
471
472//------------------------------------------------------------------------------
473
474}
Class defining a space of building blocks.
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
void setAPClass(String apClass)
Set the Attachment Point class.
BondType getBondType()
Returns the bond type preferred by this attachment point as defined by the APClass,...
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
ArrayList< AttachmentPoint > getAvailableAPs()
Returns the list of available attachment points contained in this graph.
Definition: DGraph.java:3988
void setGraphId(int id)
Definition: DGraph.java:258
List< Vertex > getVertexList()
Definition: DGraph.java:719
List< Ring > getRings()
Definition: DGraph.java:771
List< Edge > getEdgeList()
Definition: DGraph.java:764
boolean isVertexInRing(Vertex v)
Definition: DGraph.java:940
This class represents the edge between two vertices.
Definition: Edge.java:38
AttachmentPoint getSrcAP()
Definition: Edge.java:94
An empty vertex has the behaviors of a vertex, but has no molecular structure.
void addAP()
Adds an attachment point with no APClass or other attribute.
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
This class represents the closure of a ring in a spanning tree.
Definition: Ring.java:40
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...
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
Edge getEdgeToParent()
Looks into the edges that use any of the APs that belong to this vertex and returns the edge that has...
Definition: Vertex.java:972
Vertex getParent()
Looks into the edges that use any of the APs that belong to this vertex and returns the vertex which ...
Definition: Vertex.java:996
Object getProperty(Object property)
Definition: Vertex.java:1136
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:920
static Vertex newVertexFromLibrary(int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Builds a new molecular fragment kind of vertex.
Definition: Vertex.java:214
This class represents an edge that is undirected and ignores attachment points.
This class represents a subgraph feature that defined the structure of a graph.
Definition: Node.java:32
static final String REFTOVERTEXKERNEL
Property if Vertex used to store the reference to the corresponding Node.
Definition: Node.java:47
This class represents an undirected version of the edge between two vertices.
Tool to convert string into graphs and into molecular representation.
static DefaultUndirectedGraph< Vertex, UndirectedEdge > getJGraphFromGraph(DGraph dg)
Converts a DGraph into a simplified JGraphT DefaultUndirectedGraph.
static DGraph getGraphFromString(String strGraph, FragmentSpace fragSpace)
Given a formatted string-like representation of a DENOPTIM graph create the corresponding DENOPTIMGra...
static DGraph getGraphFromString(String strGraph, boolean useMolInfo, FragmentSpace fragSpace)
Given a formatted string-like representation of a DENOPTIM graph create the corresponding DENOPTIMGra...
static DefaultUndirectedGraph< Node, NodeConnection > getJGraphKernelFromGraph(DGraph dg)
Converts a DGraph into a simplified JGraphT DefaultUndirectedGraph.
Possible chemical bond types an edge can represent.
Definition: Edge.java:303
static BondType parseStr(String string)
Definition: Edge.java:369
The type of building block.
Definition: Vertex.java:86
static BBType parseInt(int i)
Translates the integer into the enum.
Definition: Vertex.java:103