$darkmode
DENOPTIM
CyclicGraphHandler.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.graph.rings;
20
21import java.util.ArrayList;
22import java.util.HashMap;
23import java.util.List;
24import java.util.Map;
25import java.util.logging.Level;
26import java.util.logging.Logger;
27
28import org.openscience.cdk.interfaces.IAtomContainer;
29import org.openscience.cdk.interfaces.IBond;
30
31import denoptim.constants.DENOPTIMConstants;
32import denoptim.exception.DENOPTIMException;
33import denoptim.graph.APClass;
34import denoptim.graph.AttachmentPoint;
35import denoptim.graph.DGraph;
36import denoptim.graph.Edge;
37import denoptim.graph.Edge.BondType;
38import denoptim.graph.Fragment;
39import denoptim.graph.Ring;
40import denoptim.graph.Vertex;
41import denoptim.graph.Vertex.BBType;
42import denoptim.fragspace.FragmentSpace;
43import denoptim.utils.ObjectPair;
44import denoptim.utils.RingClosingUtils;
45
46
61{
65 private int recCount = 0;
66 private int maxLng = 0;
67
72
77
81 private Logger logger;
82
86 private static final String NL = DENOPTIMConstants.EOL;
87
88//-----------------------------------------------------------------------------
89
99 {
100 this.settings = settings;
101 this.logger = settings.getLogger();
102 this.fragSpace = fragSpace;
103 }
104
105//-----------------------------------------------------------------------------
106
116 public List<Ring> getRandomCombinationOfRings(IAtomContainer inMol,
117 DGraph molGraph, int maxRingClosures) throws DENOPTIMException
118 {
120 molGraph, maxRingClosures, fragSpace, settings);
121 List<Ring> combOfRings = iter.next();
122 logger.log(Level.FINE,"Random combOfRings: "+combOfRings);
123 return combOfRings;
124 }
125
126//-----------------------------------------------------------------------------
127
136 //TODO: this should use most of the same code of RandomCombOfRingsIterator
137
138 public ArrayList<List<Ring>> getPossibleCombinationOfRings(
139 IAtomContainer mol, DGraph molGraph)
140 throws DENOPTIMException
141 {
142 // All the candidate paths
143 Map<ObjectPair,PathSubGraph> allGoodPaths =
144 new HashMap<ObjectPair,PathSubGraph>();
145 ArrayList<Vertex> rcaVertLst = molGraph.getFreeRCVertices();
146
147 // Get manager of ring size problems
149 rsm.initialize(mol, molGraph);
150
151 // identify compatible pairs of RCA vertices
152 Map<Vertex,ArrayList<Vertex>> compatMap =
153 new HashMap<Vertex,ArrayList<Vertex>>();
154 for (int i=0; i<rcaVertLst.size(); i++)
155 {
156 Vertex vI = rcaVertLst.get(i);
157 for (int j=i+1; j<rcaVertLst.size(); j++)
158 {
159 Vertex vJ = rcaVertLst.get(j);
160 if (!rsm.getCompatibilityOfPair(vI,vJ))
161 {
162 logger.log(Level.FINE, "Rejecting RC-incompatible pair "
163 + vI + " "+ vJ);
164 continue;
165 }
166
167 // make the new candidate RCA pair
168 PathSubGraph subGraph = new PathSubGraph(vI, vJ, molGraph);
169 logger.log(Level.FINE, "Evaluating closability of path "
170 + subGraph);
171 boolean keepRcaPair = PathClosabilityTools.isCloseable(subGraph,
172 mol, settings);
173
174 if (!keepRcaPair)
175 {
176 logger.log(Level.FINE, "Rejecting RCA pair");
177 continue;
178 }
179
180 // finally store this pair as a compatible pair
181 logger.log(Level.FINE, "All compatibility criteria satisfied: "
182 + "Storing verified RCA pair");
183
184 // Store the information that the two vertex are compatible
185 if (compatMap.containsKey(vI))
186 {
187 compatMap.get(vI).add(vJ);
188 }
189 else
190 {
191 ArrayList<Vertex> lst =
192 new ArrayList<Vertex>();
193 lst.add(vJ);
194 compatMap.put(vI,lst);
195 }
196 if (compatMap.containsKey(vJ))
197 {
198 compatMap.get(vJ).add(vI);
199 }
200 else
201 {
202 ArrayList<Vertex> lst =
203 new ArrayList<Vertex>();
204 lst.add(vI);
205 compatMap.put(vJ,lst);
206 }
207
208 // store the RCA pair for further use
209 ObjectPair compatPair;
210 if (vI.getVertexId() > vJ.getVertexId())
211 {
212 compatPair = new ObjectPair(vI,vJ);
213 }
214 else
215 {
216 compatPair = new ObjectPair(vJ,vI);
217 }
218 allGoodPaths.put(compatPair,subGraph);
219 }
220 }
221
222 logger.log(Level.FINE, "Compatibility Map for RCAs: "+NL+compatMap);
223
224 // Identify paths that share bonds (interdependent paths)
225 Map<IBond,List<PathSubGraph>> interdepPaths =
226 new HashMap<IBond,List<PathSubGraph>>();
228 {
229 for (PathSubGraph rpA : allGoodPaths.values())
230 {
231 for (PathSubGraph rpB : allGoodPaths.values())
232 {
233 if (rpA == rpB)
234 {
235 continue;
236 }
237
238 Vertex hA = rpA.getHeadVertex();
239 Vertex tA = rpA.getTailVertex();
240 Vertex hB = rpB.getHeadVertex();
241 Vertex tB = rpB.getTailVertex();
242
243 if ((hA == hB || hA == tB) || (tA == hB || tA == tB))
244 {
245 continue;
246 }
247
248 for (IBond bnd : rpA.getBondPath())
249 {
250 // ignore non-rotatable bonds
251 // NOTE: here we assume that rotatable bonds have been
252 // identified before.
253 Object rotFlg = bnd.getProperty(
255 if (rotFlg==null || !Boolean.valueOf(rotFlg.toString()))
256 {
257 continue;
258 }
259
260 if (rpB.getBondPath().contains(bnd))
261 {
262 if (interdepPaths.containsKey(bnd))
263 {
264 interdepPaths.get(bnd).add(rpA);
265 interdepPaths.get(bnd).add(rpB);
266 }
267 else
268 {
269 List<PathSubGraph> paths =
270 new ArrayList<PathSubGraph>();
271 paths.add(rpA);
272 paths.add(rpB);
273 interdepPaths.put(bnd,paths);
274 }
275 }
276 }
277 }
278 }
279 StringBuilder sb = new StringBuilder();
280 for (IBond bnd : interdepPaths.keySet())
281 {
282 sb.append("Interdependent paths for bond " + bnd);
283 List<PathSubGraph> sop = interdepPaths.get(bnd);
284 for (PathSubGraph p : sop)
285 {
286 sb.append(NL + " -> vA: "+p.getHeadVertex()
287 +" vB: "+p.getTailVertex());
288 }
289 }
290 logger.log(Level.FINE, sb.toString());
291 }
292
293 // Generate all combinations of compatible, closable paths
294 ArrayList<ObjectPair> lstPairs = new ArrayList<ObjectPair>();
295 ArrayList<Long> usedId = new ArrayList<Long>();
296 ArrayList<Vertex> sortedKeys = new ArrayList<Vertex>();
297 for (Vertex keyVert : compatMap.keySet())
298 {
299 sortedKeys.add(keyVert);
300 }
301
302 // All possible ring closing paths will be stored here
303 ArrayList<List<Ring>> allCombsOfRings =
304 new ArrayList<List<Ring>>();
306 sortedKeys,
307 compatMap,
308 lstPairs,
309 usedId,
310 allGoodPaths,
311 interdepPaths,
312 allCombsOfRings);
313 logger.log(Level.FINE, "All possible combination of rings: " +
314 allCombsOfRings);
315 return allCombsOfRings;
316 }
317
318//-----------------------------------------------------------------------------
319
324 private boolean combineCompatPathSubGraphs(int ii0,
325 ArrayList<Vertex> sortedKeys,
326 Map<Vertex,ArrayList<Vertex>> compatMap,
327 ArrayList<ObjectPair> lstPairs,
328 ArrayList<Long> usedId,
329 Map<ObjectPair,PathSubGraph> allGoodPaths,
330 Map<IBond,List<PathSubGraph>> interdepPaths,
331 ArrayList<List<Ring>> allCombsOfRings)
332 throws DENOPTIMException
333 {
334 int objId = this.hashCode();
335 String recLab = new String(new char[recCount]).replace("\0", "-");
336
337 StringBuilder sb = new StringBuilder();
338 sb.append(objId+"-"+recLab+"> Begin of new recursion: "+recCount+NL);
339 sb.append(objId+"-"+recLab+"> sortedKeys= "+sortedKeys+NL);
340 sb.append(objId+"-"+recLab+"> usedId= "+usedId+NL);
341 sb.append(objId+"-"+recLab+"> ii0= "+ii0+NL);
342 sb.append(objId+"-"+recLab+"> lstPairs= "+lstPairs+NL);
343 sb.append(objId+"-"+recLab+"> compatMap= "+compatMap+NL);
344 sb.append(objId+"-"+recLab+"> allCombsOfRings"+NL);
345 for (List<Ring> ringSet : allCombsOfRings)
346 {
347 sb.append(" "+ringSet+NL);
348 }
349 logger.log(Level.FINEST, sb.toString());
350
351 boolean inFound = false;
352 boolean addedNew = false;
353 for (int ii=ii0; ii<sortedKeys.size(); ii++)
354 {
355 Vertex vi = sortedKeys.get(ii);
356 long vIdI = vi.getVertexId();
357
358 logger.log(Level.FINEST, objId+"-"+recLab+"> vIdI= "+vIdI);
359
360 if (usedId.contains(vIdI))
361 {
362 continue;
363 }
364
365 for (Vertex vj : compatMap.get(vi))
366 {
367 long vIdJ = vj.getVertexId();
368
369 logger.log(Level.FINEST, objId+"-"+recLab+"> vIdJ= "+vIdJ);
370
371 if (usedId.contains(vIdJ) || usedId.contains(vIdI))
372 {
373 continue;
374 }
375
376 ObjectPair op;
377 if (vIdI > vIdJ)
378 {
379 op = new ObjectPair(vi,vj);
380 }
381 else
382 {
383 op = new ObjectPair(vj,vi);
384 }
385 lstPairs.add(op);
386 usedId.add(vIdI);
387 usedId.add(vIdJ);
388
389 if (lstPairs.size() > maxLng)
390 {
391 maxLng = lstPairs.size();
392 }
393 recCount++;
394 inFound = combineCompatPathSubGraphs(ii+1,
395 sortedKeys,
396 compatMap,
397 lstPairs,
398 usedId,
399 allGoodPaths,
400 interdepPaths,
401 allCombsOfRings);
402 recCount--;
403
404 logger.log(Level.FINEST, objId+"-"+recLab+"> lstPairs.size() "
405 + "& maxLng= "+lstPairs.size() +" " +maxLng);
406
407 if (!inFound && lstPairs.size() == maxLng)
408 {
409 logger.log(Level.FINEST, objId+"-"+recLab+"> in A");
410
411 boolean closable = true;
413 hasInterdependentPaths(lstPairs, interdepPaths))
414 {
416 lstPairs,
417 interdepPaths,
418 allGoodPaths);
419 }
420 if (closable)
421 {
422 logger.log(Level.FINEST, objId+"-"+recLab+"> in B");
423
424 List<Ring> ringsComb = new ArrayList<Ring>();
425 for (ObjectPair opFinal : lstPairs)
426 {
427 PathSubGraph path = allGoodPaths.get(opFinal);
428 ArrayList<Vertex> arrLst =
429 new ArrayList<Vertex>();
430 arrLst.addAll(path.getVertecesPath());
431
432 Ring ring = new Ring(arrLst);
433
434 List<Edge> es = path.getEdgesPath();
435 BondType btH = es.get(0).getBondType();
436 BondType btT = es.get(es.size()-1).getBondType();
437 if (btH != btT)
438 {
439 String s = "Attempt to close rings is not "
440 + "compatible to the different bond type "
441 + "specified by the head and tail APs: ("
442 + btH + "!=" + btT + " for vertices "
443 + path.getHeadVertex() + " "
444 + path.getTailVertex() + ")";
445 throw new DENOPTIMException(s);
446 }
447 ring.setBondType(btH);
448
449 ringsComb.add(ring);
450
451 logger.log(Level.FINEST, objId+"-"+recLab
452 +"> added ringComb: "+ring);
453 }
454
455 boolean notNewCmb = false;
456 for(List<Ring> oldCmb : allCombsOfRings)
457 {
458 StringBuilder sb2 = new StringBuilder();
459 sb2.append(objId+"-"+recLab
460 +"> Comparing ring sets: ");
461 sb2.append("o> old: "+oldCmb);
462 sb2.append("o> new: "+ringsComb);
463 logger.log(Level.FINEST, sb2.toString());
464
465 notNewCmb = RingClosingUtils.areSameRingsSet(oldCmb,
466 ringsComb);
467
468 logger.log(Level.FINEST,"o> result: "+notNewCmb);
469
470 if (notNewCmb)
471 {
472 break;
473 }
474 }
475
476 if (!notNewCmb)
477 {
478 logger.log(Level.FINEST, objId+"-"+recLab
479 +"> adding to all combs of ring.");
480 allCombsOfRings.add(ringsComb);
481 addedNew = true;
482 }
483 }
484 }
485 if (!inFound)
486 {
487 logger.log(Level.FINEST, objId+"-"+recLab+"> in C");
488
489 ArrayList<ObjectPair> toDel = new ArrayList<ObjectPair>();
490 for (int ir = recCount; ir<lstPairs.size(); ir++)
491 {
492 ObjectPair opToRemove = lstPairs.get(ir);
493 Vertex delVA = (Vertex) opToRemove.getFirst();
494 Vertex delVB = (Vertex) opToRemove.getSecond();
495 usedId.remove(usedId.indexOf(delVA.getVertexId()));
496 usedId.remove(usedId.indexOf(delVB.getVertexId()));
497 toDel.add(opToRemove);
498 }
499 lstPairs.removeAll(toDel);
500
501 logger.log(Level.FINEST, objId+"-"+recLab
502 +"> in C: after removal usedId: "+usedId+NL
503 +objId+"-"+recLab
504 +"> in C: after removal lstPairs: "+lstPairs);
505 }
506
507 if (lstPairs.contains(op))
508 {
509 logger.log(Level.FINEST, objId+"-"+recLab+"> in D");
510
511 lstPairs.remove(op);
512 usedId.remove(usedId.indexOf(vIdI));
513 usedId.remove(usedId.indexOf(vIdJ));
514
515 logger.log(Level.FINEST, objId+"-"+recLab
516 +"> in D: after removal usedId: "+usedId
517 +objId+"-"+recLab
518 +"> in D: after removal lstPairs: "+lstPairs);
519 }
520 }
521 }
522
523 logger.log(Level.FINEST, objId+"-"+recLab+"> returning= "+addedNew);
524
525 return addedNew;
526 }
527
528//-----------------------------------------------------------------------------
529
535 private boolean hasInterdependentPaths(ArrayList<ObjectPair> lstPairs,
536 Map<IBond,List<PathSubGraph>> interdepPaths)
537 {
538 boolean result = false;
539
540 for (IBond bnd : interdepPaths.keySet())
541 {
542 List<PathSubGraph> psgSet = interdepPaths.get(bnd);
543 for (PathSubGraph psg : psgSet)
544 {
545 Vertex va1 = psg.getHeadVertex();
546 Vertex va2 = psg.getTailVertex();
547
548 for (ObjectPair op : lstPairs)
549 {
550 Vertex vb1 = (Vertex) op.getFirst();
551 Vertex vb2 = (Vertex) op.getSecond();
552
553 if ((va1 == vb1 && va2 == vb2) ||
554 (va1 == vb2 && va2 == vb1))
555 {
556 result = true;
557 break;
558 }
559 }
560 if (result)
561 break;
562 }
563 if (result)
564 break;
565 }
566 return result;
567 }
568
569//-----------------------------------------------------------------------------
570
578 ArrayList<ObjectPair> lstPairs,
579 Map<IBond,List<PathSubGraph>> interdepPaths,
580 Map<ObjectPair,PathSubGraph> allGoodPaths)
581 {
582 // Identify the interdependent sets of paths
583 List<ArrayList<ObjectPair>> listOfIntrDepPaths =
584 new ArrayList<ArrayList<ObjectPair>>();
585 for (IBond bnd : interdepPaths.keySet())
586 {
587 ArrayList<ObjectPair> locSop = new ArrayList<ObjectPair>();
588 List<PathSubGraph> psgSet = interdepPaths.get(bnd);
589 for (PathSubGraph psg : psgSet)
590 {
591 Vertex va1 = psg.getHeadVertex();
592 Vertex va2 = psg.getTailVertex();
593
594 for (ObjectPair op : lstPairs)
595 {
596 Vertex vb1 = (Vertex) op.getFirst();
597 Vertex vb2 = (Vertex) op.getSecond();
598
599 if ((va1 == vb1 && va2 == vb2) ||
600 (va1 == vb2 && va2 == vb1))
601 {
602 locSop.add(op);
603 }
604 }
605 }
606 if (locSop.size() > 1)
607 {
608 listOfIntrDepPaths.add(locSop);
609 }
610 }
611
612 // Verify simultaneous closeness of each group of interdependent paths
613 boolean closable = true;
614 for (ArrayList<ObjectPair> grpIntrdepPaths : listOfIntrDepPaths)
615 {
616 // Per each closable conf. of the first path stores the paths
617 // that have a simultaneously closable conf.
618 Map<ClosableConf,List<ObjectPair>> mapOcPathsWithCC =
619 new HashMap<ClosableConf,List<ObjectPair>>();
620
621 // Per each closable conf. of a path lists the simultaneously
622 // closable confs of the other interdependent paths
623 Map<ClosableConf,List<ClosableConf>> mapOfClosableConfs =
624 new HashMap<ClosableConf,List<ClosableConf>>();
625
626 // For the first path just put all closable conf in the list
627 ObjectPair firstOp = grpIntrdepPaths.get(0);
628 PathSubGraph firstPsg = allGoodPaths.get(firstOp);
629 RingClosingConformations firstRcc = firstPsg.getRCC();
630
631 for (ArrayList<Double> ccAngls : firstRcc.getListOfConformations())
632 {
633 ClosableConf cc = new ClosableConf(firstPsg.getBondPath(),
634 ccAngls);
635 // Container for cc of other paths
636 List<ClosableConf> scc = new ArrayList<ClosableConf>();
637 mapOfClosableConfs.put(cc,scc);
638 // Container for other paths
639 List<ObjectPair> sop = new ArrayList<ObjectPair>();
640 sop.add(firstOp);
641 mapOcPathsWithCC.put(cc,sop);
642 }
643
644 // For other paths put only the closable confs (CC) that are
645 // simultaneously closable with previously listed CCs
646 for (int iOp=1; iOp<grpIntrdepPaths.size(); iOp++)
647 {
648 ObjectPair locOp = grpIntrdepPaths.get(iOp);
649 PathSubGraph locPath = allGoodPaths.get(locOp);
650 RingClosingConformations rccOfLocPath = locPath.getRCC();
651
652 // try with each closable conf of the local path
653 for (ArrayList<Double> ccAngles :
654 rccOfLocPath.getListOfConformations())
655 {
656 ClosableConf locCC = new ClosableConf(
657 locPath.getBondPath(), ccAngles);
658 // Compare the locCC with CC of the first path
659 for (ClosableConf frstCC : mapOfClosableConfs.keySet())
660 {
661 if (frstCC.shareBond(locCC) &&
662 frstCC.canCoexistWith(locCC))
663 {
664 // CC of loc path is simultaneously closable with
665 // this CC of first path (frstCC)
666 if (mapOfClosableConfs.get(frstCC).size() == 0)
667 {
668 // the list of CC simultaneously closable with
669 // the key CC (frstCC) is empty, so just
670 // add locCC for future needs
671 mapOfClosableConfs.get(frstCC).add(locCC);
672 // add to Set wont add if is already there
673 mapOcPathsWithCC.get(frstCC).add(locOp);
674 }
675 else
676 {
677 // the list of CC simultaneously closable with
678 // the key CC (frstCC) has already one or more
679 // entries: we need to compare this locCC with
680 // all these entries
681 boolean canCoexistWithAll = true;
682 for (ClosableConf lstCC :
683 mapOfClosableConfs.get(frstCC))
684 {
685 if (lstCC.shareBond(locCC) &&
686 !lstCC.canCoexistWith(locCC))
687 {
688 // Sorry, locCC cannot coexist
689 canCoexistWithAll = false;
690 break;
691 }
692 }
693 if (canCoexistWithAll)
694 {
695 mapOfClosableConfs.get(frstCC).add(locCC);
696 // add to Set wont add if is already there
697 mapOcPathsWithCC.get(frstCC).add(locOp);
698 }
699 }
700 }
701 }
702 }
703
704 boolean goon = true;
705 for (ClosableConf frstCC : mapOfClosableConfs.keySet())
706 {
707 if (!mapOcPathsWithCC.get(frstCC).contains(locOp))
708 {
709 goon = false;
710 break;
711 }
712 }
713 if (!goon)
714 {
715 break;
716 }
717 }
718
719 // Now check if there is at least one set of simultaneously
720 // closable conformations for all members of this group
721 // of interdependent paths
722 boolean foundOneSetFullyClosable = false;
723 for (ClosableConf cc : mapOfClosableConfs.keySet())
724 {
725 int numPathWithSimCC = mapOcPathsWithCC.get(cc).size();
726 int numInterdepPaths = grpIntrdepPaths.size();
727 if (numPathWithSimCC == numInterdepPaths)
728 {
729 foundOneSetFullyClosable = true;
730 break;
731 }
732 }
733 if (!foundOneSetFullyClosable)
734 {
735 closable = false;
736 break;
737 }
738 }
739
740 return closable;
741 }
742
743//-----------------------------------------------------------------------------
744
751 private class ClosableConf
752 {
753 private List<IBond> bonds;
754 private ArrayList<Double> angs;
755
756 //---------------------------------------------------------------------
757
758 public ClosableConf(List<IBond> bonds, ArrayList<Double> dihedrals)
759 {
760 this.bonds = bonds;
761 this.angs = dihedrals;
762 }
763
764 //---------------------------------------------------------------------
765
766 public boolean shareBond(ClosableConf other)
767 {
768 boolean shareBnd = false;
769 for (IBond tBnd : this.bonds)
770 {
771 if (other.bonds.contains(tBnd))
772 {
773 shareBnd = true;
774 break;
775 }
776 }
777 return shareBnd;
778 }
779
780 //---------------------------------------------------------------------
781 public boolean canCoexistWith(ClosableConf other)
782 {
783 boolean canCoexist = true;
784 double thrs = settings.getPathConfSearchStep() / 2.0;
785 for (int i=0; i<this.bonds.size(); i++)
786 {
787 IBond tBnd = this.bonds.get(i);
788 for (int j=0; j<other.bonds.size(); j++)
789 {
790 IBond oBnd = other.bonds.get(j);
791 if (tBnd == oBnd)
792 {
793 double diff = this.angs.get(i) - other.angs.get(j);
794 diff = Math.abs(diff);
795 if (diff > thrs)
796 {
797 canCoexist = false;
798 break;
799 }
800 }
801 }
802 if (!canCoexist)
803 break;
804 }
805
806 return canCoexist;
807 }
808
809 //---------------------------------------------------------------------
810 public String toString()
811 {
812 String s = " ClosableConf [nBonds: " + bonds.size()
813 + " bonds: ";
814 for (IBond bnd : bonds)
815 {
816 s = s + bnd.getAtom(0).getSymbol() + "-"
817 + bnd.getAtom(1).getSymbol() + " ";
818 }
819
820 s = s + " dihedrals: " + angs + "]";
821
822 return s;
823 }
824 }
825
826//-----------------------------------------------------------------------------
827
835 public boolean checkChelatesGraph(DGraph molGraph, List<Ring> ringsSet)
836 {
837 logger.log(Level.FINE, "Checking conditions for chelates");
838
839//TODO: here we assume that the scaffold is a metal and the first layer of
840// vertices (level = 0) are the coordinating atoms.
841// Also, the APclass of the ap connecting the candidate orphan is hard coded!
842// This is a temporary solution. Need a general approach and tunable by
843// options/parameters
844
845 for (Vertex vert : molGraph.getVertexList())
846 {
847 long vId = vert.getVertexId();
848
849 Fragment vertFrag = null;
850 if (vert instanceof Fragment)
851 vertFrag = (Fragment) vert;
852
853
854 // check for orphan coordinating atoms:
855 // they have RCAs but none of them is included in a rings
856 int levelOfVert = molGraph.getLevel(vert);
857 if (levelOfVert == 0
858 && vertFrag.getBuildingBlockType() == BBType.FRAGMENT)
859 {
860 Edge edgeToParnt = molGraph.getEdgeWithParent(vId);
861 APClass apClassToScaffold = edgeToParnt.getTrgAPClass();
863 apClassToScaffold))
864 {
865 continue;
866 }
867
868 boolean isOrphan = false;
869 for (Vertex cVrtx : vert.getChilddren())
870 {
871 if (cVrtx.isRCV() && !molGraph.isVertexInRing(cVrtx))
872 {
873 isOrphan = true;
874 break;
875 }
876 }
877 if (isOrphan)
878 {
879 logger.log(Level.FINE, "Found orphan: " + vert
880 + " RingSet: " + ringsSet);
881 return false;
882 }
883 }
884
885 // check for not fully coordinating multidentate bridges
886//TODO: make the full-denticity requirement optional for same/all APclasses
887 if (levelOfVert > 0)
888 {
889 Map<String,ArrayList<Vertex>> rcasOnThisVertex =
890 new HashMap<String,ArrayList<Vertex>>();
891 for (Vertex cVrtx : vert.getChilddren())
892 {
893 if (cVrtx.isRCV())
894 {
895 AttachmentPoint ap =
896 cVrtx.getAttachmentPoints().get(0);
897 String apCls = ap.getAPClass().toString();
898 if (rcasOnThisVertex.keySet().contains(apCls))
899 {
900 rcasOnThisVertex.get(apCls).add(cVrtx);
901 }
902 else
903 {
904 ArrayList<Vertex> sameClsRCA =
905 new ArrayList<Vertex>();
906 sameClsRCA.add(cVrtx);
907 rcasOnThisVertex.put(apCls,sameClsRCA);
908 }
909 }
910 }
911
912 for (String apCls : rcasOnThisVertex.keySet())
913 {
914 int usedDenticity = 0;
915 for (Vertex rcaVrtx : rcasOnThisVertex.get(apCls))
916 {
917 if (molGraph.isVertexInRing(rcaVrtx))
918 {
919 usedDenticity++;
920 }
921 }
922
923 if (usedDenticity < rcasOnThisVertex.get(apCls).size())
924 {
925 logger.log(Level.FINE, "Full-denticity is not "
926 + "satisfied for apclas: " + apCls
927 + "in vertex " + vert
928 + " with set of rings " + ringsSet
929 + "check graph: " + molGraph);
930 return false;
931 }
932 }
933 }
934 }
935
936 return true;
937 }
938
939//-----------------------------------------------------------------------------
940
941}
General set of constants used in DENOPTIM.
static final String EOL
new line character
static final String BONDPROPROTATABLE
String tag of Bond's property used to store the property of being rotatable.
Class defining a space of building blocks.
String toString()
Do not use this to make SDF representations.
Definition: APClass.java:380
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
APClass getAPClass()
Returns the Attachment Point class.
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
List< Vertex > getVertexList()
Definition: DGraph.java:947
int getLevel(Vertex v)
Calculates the level of a vertex in this graph.
Definition: DGraph.java:5555
boolean isVertexInRing(Vertex v)
Definition: DGraph.java:1168
Edge getEdgeWithParent(long l)
Looks for an edge that points to a vertex with the given vertex id.
Definition: DGraph.java:3502
This class represents the edge between two vertices.
Definition: Edge.java:38
APClass getTrgAPClass()
Definition: Edge.java:157
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
void setBondType(BondType bndType)
Set the bond type (i.e., bond order) of the chord connecting the head and the tail vertices.
Definition: Ring.java:158
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
Vertex.BBType getBuildingBlockType()
Definition: Vertex.java:318
ArrayList< Vertex > getChilddren()
Looks into the edges that use any of the APs that belong to this vertex and returns the list of verti...
Definition: Vertex.java:1172
Object getProperty(Object property)
Definition: Vertex.java:1223
Utility class to handle the simultaneous closeness condition.
ClosableConf(List< IBond > bonds, ArrayList< Double > dihedrals)
This is a tool to identify and manage vertices' connections not included in the DGraph,...
boolean hasInterdependentPaths(ArrayList< ObjectPair > lstPairs, Map< IBond, List< PathSubGraph > > interdepPaths)
Checks whether the combination of RCA's pairs leads to interdependent paths, that is,...
List< Ring > getRandomCombinationOfRings(IAtomContainer inMol, DGraph molGraph, int maxRingClosures)
Identifies a random combination of ring closing paths and returns it as list of DENOPTIMRings ready t...
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...
RingClosureParameters settings
Parameters.
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...
CyclicGraphHandler(RingClosureParameters settings, FragmentSpace fragSpace)
Constructor from data structure.
boolean combineCompatPathSubGraphs(int ii0, ArrayList< Vertex > sortedKeys, Map< Vertex, ArrayList< Vertex > > compatMap, ArrayList< ObjectPair > lstPairs, ArrayList< Long > usedId, Map< ObjectPair, PathSubGraph > allGoodPaths, Map< IBond, List< PathSubGraph > > interdepPaths, ArrayList< List< Ring > > allCombsOfRings)
Recursive method to identify all the combination of rings.
int recCount
variables needed by recursive methods
static final String NL
New line character.
boolean checkClosabilityOfInterdependentPaths(ArrayList< ObjectPair > lstPairs, Map< IBond, List< PathSubGraph > > interdepPaths, Map< ObjectPair, PathSubGraph > allGoodPaths)
This method checks whether the interdependent paths are simultaneously closable.
FragmentSpace fragSpace
Fragment space definition.
Tool box for determining whether a chain of atoms, i.e., a path, can be folded as to form a ring-clos...
static boolean isCloseable(PathSubGraph subGraph, IAtomContainer mol, RingClosureParameters settings)
Method to evaluate the closability of a single path in a graph.
This object represents a path in a DGraph.
List< IBond > getBondPath()
Returns the list of bonds in the path between the head and the tail.
RingClosingConformations getRCC()
Returns the ring closing conformations.
List< Vertex > getVertecesPath()
Returns the list of verteces involved.
Vertex getHeadVertex()
Returns the vertex representing the head of the chain.
Vertex getTailVertex()
Returns the vertex representing the tail of the chain.
List< Edge > getEdgesPath()
Returns the list of edges involved.
A class for iterating over sets of ring combinations generated by considering any constrain and setti...
Serializable object to store/get a list of conformations that allow to close a ring from an open chai...
ArrayList< ArrayList< Double > > getListOfConformations()
Parameters and setting related to handling ring closures.
Set< APClass > metalCoordinatingAPClasses
List of metal-coordinating APClasses.
Utility class to calculate and manage the alternative ring sizes achievable by formation of Rings.
boolean getCompatibilityOfPair(Vertex vI, Vertex vJ)
void initialize(IAtomContainer origMol, DGraph graph)
Makes this ring size manager work on a specific system that has a molecular representation and a DENO...
Logger getLogger()
Get the name of the program specific logger.
This class is the equivalent of the Pair data structure used in C++ Although AbstractMap....
Definition: ObjectPair.java:30
Toolbox useful when dealing with Ring Closing Attractors and ring closures.
static boolean areSameRingsSet(List< Ring > oldCmb, List< Ring > ringsComb)
Compares two combinations of DENOPTIMRingss and evaluates whether these correspond to the same combin...
Possible chemical bond types an edge can represent.
Definition: Edge.java:303
The type of building block.
Definition: Vertex.java:86