19package denoptim.graph.rings;
21import java.util.ArrayList;
22import java.util.Arrays;
23import java.util.Collections;
24import java.util.HashMap;
25import java.util.HashSet;
26import java.util.Iterator;
27import java.util.LinkedList;
31import java.util.logging.Logger;
33import javax.vecmath.Point3d;
35import org.openscience.cdk.graph.ShortestPaths;
36import org.openscience.cdk.interfaces.IAtom;
37import org.openscience.cdk.interfaces.IAtomContainer;
38import org.openscience.cdk.interfaces.IBond;
40import denoptim.constants.DENOPTIMConstants;
41import denoptim.exception.DENOPTIMException;
42import denoptim.graph.AttachmentPoint;
43import denoptim.graph.DGraph;
44import denoptim.graph.Edge;
45import denoptim.graph.Vertex;
46import denoptim.io.DenoptimIO;
47import denoptim.molecularmodeling.ThreeDimTreeBuilder;
48import denoptim.utils.Randomizer;
147 this(
vA,
vB,
new HashMap<Vertex, List<Vertex>>());
167 this(
vA,
vB, adjacency,
true);
190 if (
vA ==
null ||
vB ==
null)
192 throw new IllegalArgumentException(
"Null vertex cannot be used to build a "
193 + this.getClass().getSimpleName() +
" object.");
197 if (graphA ==
null || graphB ==
null)
199 Vertex noGraphVertex =
null;
206 throw new IllegalArgumentException(
"Vertex " + noGraphVertex.
getVertexId()
207 +
" is not in a graph. "
208 +
"Cannot build a " +
this.getClass().getSimpleName() +
" object.");
210 if (graphA != graphB)
212 throw new IllegalArgumentException(
"Vertices " +
vA.
getVertexId() +
" and "
214 +
"Cannot build a " +
this.getClass().getSimpleName() +
" object.");
220 if (combineAdjacencyAndActualEdges)
223 for (Map.Entry<
Vertex, List<Vertex>> entry : adjacencyFromEdges.entrySet())
225 Vertex vertex = entry.getKey();
226 List<Vertex> neighbors = entry.getValue();
227 for (
Vertex neighbor : neighbors) {
228 adjacency.computeIfAbsent(vertex, k ->
new ArrayList<Vertex>()).add(neighbor);
229 adjacency.computeIfAbsent(neighbor, k ->
new ArrayList<Vertex>()).add(vertex);
273 Map<Vertex, List<Vertex>> adjacency =
new HashMap<Vertex, List<Vertex>>();
276 Vertex srcVertex = e.getSrcAP().getOwner();
277 Vertex trgVertex = e.getTrgAP().getOwner();
278 adjacency.computeIfAbsent(srcVertex, k ->
new ArrayList<Vertex>())
280 adjacency.computeIfAbsent(trgVertex, k ->
new ArrayList<Vertex>())
298 Map<
Vertex, List<Vertex>> neighbours)
302 return new ArrayList<Vertex>(Arrays.asList(
vA));
305 Map<Vertex, Vertex> parent =
new HashMap<Vertex, Vertex>();
306 Set<Long> visited =
new HashSet<Long>();
307 List<Vertex> queue =
new ArrayList<Vertex>();
311 parent.put(
vA,
null);
313 while (!queue.isEmpty())
315 Vertex current = queue.remove(0);
322 List<Vertex> neighbors = neighbours.get(current);
323 if (neighbors ==
null)
328 for (
Vertex neighbor : neighbors)
330 if (visited.add(neighbor.getVertexId()))
332 parent.put(neighbor, current);
342 return new ArrayList<Vertex>();
356 Map<Vertex, Vertex> parent)
359 LinkedList<Vertex> path =
new LinkedList<Vertex>();
360 for (
Vertex node =
vB; node !=
null; node = parent.get(node))
377 ArrayList<Vertex> gVertices =
new ArrayList<Vertex>();
378 ArrayList<Edge> gEdges =
new ArrayList<Edge>();
391 if (edgeToBack!=
null)
395 apHereToBack = edgeToBack.
getSrcAP();
396 apBackToHere = edgeToBack.
getTrgAP();
398 apHereToBack = edgeToBack.
getTrgAP();
399 apBackToHere = edgeToBack.
getSrcAP();
402 if (edgeToFrnt!=
null)
406 apHereToFrnt = edgeToFrnt.
getSrcAP();
407 apFrntToHere = edgeToFrnt.
getTrgAP();
409 apHereToFrnt = edgeToFrnt.
getTrgAP();
410 apFrntToHere = edgeToFrnt.
getSrcAP();
424 String[] ids = vertHere.
getPathIDs(apHereToBack, apHereToFrnt);
443 gVertices.add(cloneVertBack);
448 cloneVertBack = gVertices.get(gVertices.size()-1);
450 gVertices.add(cloneVertHere);
451 if (edgeToBack!=
null) {
458 gVertices.add(cloneVertFrnt);
459 if (edgeToFrnt!=
null) {
468 this.graph =
new DGraph(gVertices,gEdges);
471 String[] pA =
chainID.split(
"_");
473 for (
int i=1; i<pA.length; i++)
477 for (
int j=0; j<pA.length; j++)
479 if ((i+j) < pA.length)
481 altrnA = altrnA + pA[i+j] +
"_";
482 altrnB = altrnB + pB[i+j] +
"_";
484 altrnA = altrnA + pA[i+j-pA.length] +
"_";
485 altrnB = altrnB + pB[i+j-pA.length] +
"_";
513 Iterator<AttachmentPoint> path =
findPath(from, to,
514 new HashSet<>()).iterator();
516 if (!path.hasNext()) {
532 while (path.hasNext()) {
533 srcAP = path.next().
clone();
537 trgAP = path.next().
clone();
564 if (visited.contains(fromId)) {
565 return new ArrayList<>();
570 Edge e = fromAP.getEdgeUser();
576 return Arrays.asList(fromAP, adjAP);
579 Iterable<AttachmentPoint> path =
findPath(adj, to, visited);
581 if (path.iterator().hasNext()) {
582 List<AttachmentPoint> extendedPath =
583 new ArrayList<AttachmentPoint>(Arrays.asList(
585 path.iterator().forEachRemaining(extendedPath::add);
590 return Collections.emptyList();
611 Map<IAtom,ArrayList<AttachmentPoint>> apsPerAtom =
613 Map<IBond,ArrayList<AttachmentPoint>> apsPerBond =
618 String f =
"/tmp/pathSubGraph.sdf";
619 System.out.println(
"Find SDF representation of path in: " + f);
623 }
catch (Throwable t) {
624 throw new Error(
"Could not save debug file '" + f +
"'.");
637 for (IAtom atm : mol.atoms())
639 long vrtId = (Long) atm.getProperty(
647 if (e0 !=
null && e1 !=
null)
650 List<IAtom> ends =
new ArrayList<IAtom>();
662 List<IAtom> pathInFullMol =
new ArrayList<IAtom>();
664 IAtom currentAtm =
null;
665 long prevAtmInPathVID = -1;
666 long currAtmInPathVID = -1;
667 long nextAtmInPathVID = -1;
668 List<IAtom> candidates =
new ArrayList<IAtom>();
674 currentAtm = ends.get(0);
675 pathInFullMol.add(currentAtm);
676 candidates.addAll(mol.getConnectedAtomsList(currentAtm));
679 pathInFullMol.add(ends.get(1));
688 if (prevAtmInPathVID != currAtmInPathVID)
690 for (IAtom c : candidates)
695 pathInFullMol.add(currentAtm);
698 for (IAtom c2 : mol.getConnectedAtomsList(c))
700 if (!pathInFullMol.contains(c2))
709 List<IAtom> newCandidates =
new ArrayList<IAtom>();
710 for (IAtom nbr : candidates)
712 boolean foundNextLevel =
false;
713 for (IAtom nbrNbr : mol.getConnectedAtomsList(nbr))
715 if (pathInFullMol.contains(nbrNbr)
716 || candidates.contains(nbrNbr))
720 if (vid == nextAtmInPathVID
721 && currAtmInPathVID!=nextAtmInPathVID)
723 ShortestPaths sp =
new ShortestPaths(mol,
725 List<IAtom> itnraVertPath =
new ArrayList<IAtom>(
726 Arrays.asList(sp.atomsTo(nbr)));
729 for (
int j=1; j<itnraVertPath.size(); j++)
730 pathInFullMol.add(itnraVertPath.get(j));
733 newCandidates.clear();
734 newCandidates.add(nbrNbr);
735 foundNextLevel =
true;
738 if (vid == currAtmInPathVID)
740 newCandidates.add(nbrNbr);
748 candidates.addAll(newCandidates);
754 throw new IllegalStateException(
"Paths have different size! "
756 +
"proceed in the evaluation of ring closability. "
757 +
"Please report this to the author.");
765 for (
int i=0; i < pathInFullMol.size()-1; i++)
767 IBond bnd = mol.getBond(pathInFullMol.get(i),
768 pathInFullMol.get(i+1));
778 ArrayList<Point3d> fourPoints =
new ArrayList<Point3d>();
787 long vIdA0 = a0.getProperty(keyPropVrtID);
788 long vIdA1 = a1.getProperty(keyPropVrtID);
789 long vIdA2 = a2.getProperty(keyPropVrtID);
790 long vIdA3 = a3.getProperty(keyPropVrtID);
794 p0 = a0.getPoint3d();
795 p1 = a1.getPoint3d();
796 p2 = a2.getPoint3d();
797 p3 = a3.getPoint3d();
807 if (apsPerBond.keySet().contains(bndA1A2))
809 if (apsPerBond.get(bndA1A2).contains(ap))
814 p0 =
new Point3d(ap.getDirectionVector());
822 List<IAtom> nbrsOfA1 =
iacPathVAVB.getConnectedAtomsList(a1);
823 int lowIDs = 10000000;
824 for (IAtom nbrOfA1 : nbrsOfA1)
836 p0 =
new Point3d(
iacPathVAVB.getAtom(lowIDs).getPoint3d());
847 if (apsPerBond.keySet().contains(bndA1A2))
849 if (apsPerBond.get(bndA1A2).contains(ap))
854 p3 =
new Point3d(ap.getDirectionVector());
862 List<IAtom> nbrsOfA2 =
iacPathVAVB.getConnectedAtomsList(a2);
863 int lowIDs = 10000000;
864 for (IAtom nbrOfA2 : nbrsOfA2)
876 p3 =
new Point3d(
iacPathVAVB.getAtom(lowIDs).getPoint3d());
889 System.out.println(
"Points for dihedral angle definition: ");
894 System.out.println(
" "+p);
896 System.out.println(
" ");
915 IAtom head = iac.getAtom(0);
916 IAtom tail = iac.getAtom(iac.getAtomCount()-1);
917 ShortestPaths sp =
new ShortestPaths(iac, head);
918 List<IAtom> path =
new ArrayList<IAtom>(Arrays.asList(
1113 StringBuilder sb =
new StringBuilder();
1114 boolean first =
true;
1121 sb.append(v.getVertexId());
1124 return sb.toString();
General set of constants used in DENOPTIM.
static final Object MOLPROPAPxBOND
Key for IAtomContainer property containing the map of AttachmentPoints per atom.
static final String ATMPROPVERTEXID
String tag of Atom property used to store the unique ID of the Vertex corresponding to the molecular ...
static final Object MOLPROPAPxATOM
Key for IAtomContainer property containing the map of AttachmentPoints per vertex ID.
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
void setOwner(Vertex owner)
Sets the reference to the vertex that owns this attachment point.
AttachmentPoint clone()
Returns a deep clone of this attachment point.
Container for the list of vertices and the edges that connect them.
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
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< Edge > getEdgeList()
This class represents the edge between two vertices.
AttachmentPoint getTrgAP()
AttachmentPoint getSrcAP()
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
abstract Vertex clone()
Returns a deep-copy of this vertex.
int getBuildingBlockId()
Returns the index of the building block that should correspond to the position of the building block ...
String[] getPathIDs(AttachmentPoint apA, AttachmentPoint apB)
Produces a pair of strings that identify the "path" between two given attachment points.
int getIndexOfAP(AttachmentPoint ap)
Returns the position of the given AP in the list of APs of this vertex.
Vertex.BBType getBuildingBlockType()
DGraph getGraphOwner()
Returns the graph this vertex belongs to or null.
abstract List< AttachmentPoint > getAttachmentPoints()
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Edge getEdgeWith(Vertex other)
Finds the edge between this and the other vertex, if it exists.
This object represents a path in a DGraph.
PathSubGraph(Vertex vA, Vertex vB, Map< Vertex, List< Vertex > > adjacency, boolean combineAdjacencyAndActualEdges)
Constructs a new path sub graph specifying the first and last vertex of the path.
RingClosingConformations rcc
The list of closable conformations, if any is found.
boolean hasMolRepr
The flag defining whether this object has already a molecular representation or not.
String getAtomRefStr()
Returns the string with atom symbols and number for an easy identification of the path in a molecular...
static Iterable< AttachmentPoint > findPath(Vertex from, Vertex to, Set< Long > visited)
Returns a sequence of APs that is the path from vertex from to vertex to.
List< IBond > getBondPath()
Returns the list of bonds in the path between the head and the tail.
RingClosingConformations getRCC()
Returns the ring closing conformations.
String atmNumStr
The string of atoms involved (atom numbers from full molecule list)
int getPathLength()
Returns the length of the list of edges involved in this path.
void makeMolecularRepresentation(IAtomContainer mol, boolean make3D, Logger logger, Randomizer randomizer)
Creates the molecular representation, list of atoms and bonds involved in the path between the head a...
List< Vertex > getVertecesPath()
Returns the list of verteces involved.
Vertex vA
The vertex representing the first RCA: head of the path.
IAtomContainer getMolecularRepresentation()
Returns the molecular representation.
PathSubGraph(Vertex vA, Vertex vB, Map< Vertex, List< Vertex > > adjacency)
Constructs a new path sub graph specifying the first and last vertex of the path.
String chainID
The string identifier of this path.
String getChainID()
Returns the string representation of the path.
Vertex vB
The vertex representing the second RCA: the tail of the path.
static List< Vertex > reconstructVertexPath(Vertex vA, Vertex vB, Map< Vertex, Vertex > parent)
Reconstructs the vertex path from the parent map.
List< IBond > bondsPathVAVB
The list of bonds in the shortest path.
IAtomContainer iacPathVAVB
The molecular representation of the fragment in the path.
List< IAtom > getAtomPath()
Returns the list of atoms in the path between the head and the tail.
boolean hasMolecularRepresentation()
Returns true if the molecular representation has been set.
static List< Vertex > findShortestPath(Vertex vA, Vertex vB, Map< Vertex, List< Vertex > > neighbours)
Finds the shortest vertex path from vA to vB using BFS.
List< Edge > edgesPathVAVB
The list of edges of the original graph and involved in the path.
static Map< Vertex, List< Vertex > > buildAdjacencyFromGraph(DGraph graph)
Builds an adjacency map from a graph.
Vertex getHeadVertex()
Returns the vertex representing the head of the chain.
List< IAtom > atomsPathVAVB
The list of atoms in the shortest path.
ArrayList< ArrayList< Point3d > > dihedralRefPts
Per each bond the pair of point used to define the torsion.
static List< IAtom > findAtomPath(IAtomContainer iac)
Finds the shortest path of atoms between the first and last atom in the given atom container.
PathSubGraph(Vertex vA, Vertex vB)
Constructs a new path sub graph specifying the first and last vertex of the path.
void setGraphAndChainIDs()
Sets the graph and chain IDs for the path sub graph.
ArrayList< ArrayList< Point3d > > getDihedralRefPoints()
Returns the list of point to be used to define the torsion of a bond uniquely (independently on the s...
Vertex getTailVertex()
Returns the vertex representing the tail of the chain.
List< Vertex > vertPathVAVB
The list of vertices of the original graph and involved in the path.
static DGraph findPath(Vertex from, Vertex to)
Returns a path subgraph from the first given vertex to the second one.
List< Edge > getEdgesPath()
Returns the list of edges involved, if any.
ArrayList< String > allPossibleChainIDs
void setRCC(RingClosingConformations rcc)
Set the ring closing conformations to this object.
long getVertexIdInPath(IAtom a)
DGraph graph
The graph representation of this path.
List< String > getAllAlternativeChainIDs()
Returns all the possible IDs for this chain.
Utility methods for input/output.
static void writeSDFFile(String fileName, IAtomContainer mol)
Writes IAtomContainer to SDF file.
Tool to build build three-dimensional (3D) tree-like molecular structures from DGraph.
IAtomContainer convertGraphTo3DAtomContainer(DGraph graph)
Created a three-dimensional molecular representation from a given DGraph.
Tool to generate random numbers and random decisions.