$darkmode
DENOPTIM
RandomCombOfRingIteratorTest.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2022 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 static org.junit.jupiter.api.Assertions.assertTrue;
22
23import java.io.File;
24import java.util.ArrayList;
25import java.util.HashMap;
26import java.util.HashSet;
27import java.util.List;
28import java.util.logging.Logger;
29
30import javax.vecmath.Point3d;
31
32import org.junit.jupiter.api.Test;
33import org.openscience.cdk.Atom;
34import org.openscience.cdk.PseudoAtom;
35import org.openscience.cdk.interfaces.IAtom;
36import org.openscience.cdk.interfaces.IAtomContainer;
37import org.openscience.cdk.interfaces.IChemObjectBuilder;
38import org.openscience.cdk.silent.SilentChemObjectBuilder;
39
40import denoptim.fragspace.FragmentSpace;
41import denoptim.fragspace.FragmentSpaceParameters;
42import denoptim.graph.APClass;
43import denoptim.graph.DGraph;
44import denoptim.graph.Fragment;
45import denoptim.graph.Ring;
46import denoptim.graph.Vertex;
47import denoptim.graph.Vertex.BBType;
48import denoptim.io.DenoptimIO;
49import denoptim.molecularmodeling.ThreeDimTreeBuilder;
50import denoptim.utils.Randomizer;
51
59{
60
61//------------------------------------------------------------------------------
62
63 @Test
64 public void testEvaluateConstitutionalClosability() throws Exception
65 {
66 /*
67 * Make the test graph (make it here so we have direct access to vertexes)
68 *
69 * RCV_P RCV_P RCV_M RCV_P RCV_M
70 * | | | | |
71 * RCV_M--[O]----[C]--[C]--[C]--[C]--[C]--[C]--[C]--[C]----[N]--RCV_M
72 * vO vC vC2 vC3 vC4 vC5 vC6 cV7 vC8 vN
73 * |
74 * RCV_P
75 */
76
77 APClass apc = APClass.make("A", 0);
78
79 IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
80
81 IAtomContainer iacO = builder.newAtomContainer();
82 IAtom aO = new Atom("O",new Point3d(0,0,0));
83 iacO.addAtom(aO);
84 Fragment vO = new Fragment(0, iacO,BBType.FRAGMENT);
85 vO.addAP(0, new Point3d(0,-1,0), apc);
86 vO.addAP(0, new Point3d(2,0,0), apc);
87 vO.addAP(0, new Point3d(0,1,0), apc);
88
89 IAtomContainer iacC = builder.newAtomContainer();
90 IAtom aC = new Atom("C",new Point3d(0,0,0));
91 iacC.addAtom(aC);
92 Fragment vC = new Fragment(1, iacC,BBType.FRAGMENT);
93 vC.addAP(0, new Point3d(0,-1,0), apc);
94 vC.addAP(0, new Point3d(2,0,0), apc);
95 vC.addAP(0, new Point3d(0,1,0), apc);
96
97 IAtomContainer iacCd = builder.newAtomContainer();
98 IAtom aCd = new Atom("C",new Point3d(0,0,0));
99 iacCd.addAtom(aCd);
100 Fragment vC2 = new Fragment(2, iacCd,BBType.FRAGMENT);
101 vC2.addAP(0, new Point3d(0,-1,0), apc);
102 vC2.addAP(0, new Point3d(0,1,0), apc);
103
104 Fragment vC3 = vC2.clone();
105 vC3.setVertexId(33);
106
107 Fragment vC4 = vC.clone();
108 vC4.setVertexId(34);
109
110 Fragment vC5 = vC.clone();
111 vC5.setVertexId(35);
112
113 Fragment vC6 = vC2.clone();
114 vC6.setVertexId(36);
115
116 Fragment vC7 = vC2.clone();
117 vC7.setVertexId(37);
118
119 Fragment vC8 = vC.clone();
120 vC8.setVertexId(3);
121
122 IAtomContainer iacN = builder.newAtomContainer();
123 IAtom aN = new Atom("N",new Point3d(0,0,0));
124 iacN.addAtom(aN);
125 Fragment vN = new Fragment(4, iacN,BBType.FRAGMENT);
126 vN.addAP(0, new Point3d(0,-1,0), apc);
127 vN.addAP(0, new Point3d(2,0,0), apc);
128 vN.addAP(0, new Point3d(0,1,0), apc);
129
130 APClass atMinus = APClass.RCACLASSMINUS;
131
132 IAtomContainer iacD = builder.newAtomContainer();
133 iacD.addAtom(new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(atMinus),
134 new Point3d(0,0,0)));
135 Fragment rcvM = new Fragment(5, iacD,BBType.FRAGMENT);
136 rcvM.addAP(0, new Point3d(-1,0,0), atMinus);
137 rcvM.setAsRCV(true);
138
139 Fragment rcvM2 = rcvM.clone();
140 rcvM2.setVertexId(6);
141
142 Fragment rcvM3 = rcvM.clone();
143 rcvM3.setVertexId(7);
144
145 Fragment rcvM4 = rcvM.clone();
146 rcvM4.setVertexId(11);
147
149
150 IAtomContainer iacE = builder.newAtomContainer();
151 iacE.addAtom(new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(atPlus),
152 new Point3d(0,0,0)));
153 Fragment rcvP = new Fragment(8, iacE,BBType.FRAGMENT);
154 rcvP.addAP(0, new Point3d(-1,0,0), atPlus);
155 rcvP.setAsRCV(true);
156
157 Fragment rcvP2 = rcvP.clone();
158 rcvP2.setVertexId(9);
159
160 Fragment rcvP3 = rcvP.clone();
161 rcvP3.setVertexId(10);
162
163 Fragment rcvP4 = rcvP.clone();
164 rcvP4.setVertexId(12);
165
166 DGraph graph = new DGraph();
167 graph.addVertex(vC);
168 graph.appendVertexOnAP(vC.getAP(0), vO.getAP(2));
169 graph.appendVertexOnAP(vO.getAP(0), rcvM.getAP(0));
170 graph.appendVertexOnAP(vO.getAP(1), rcvP.getAP(0));
171 graph.appendVertexOnAP(vC.getAP(1), rcvP2.getAP(0));
172 graph.appendVertexOnAP(vC.getAP(2), vC2.getAP(1));
173 graph.appendVertexOnAP(vC2.getAP(0), vC3.getAP(0));
174 graph.appendVertexOnAP(vC3.getAP(1), vC4.getAP(0));
175 graph.appendVertexOnAP(vC4.getAP(1), vC5.getAP(0));
176 graph.appendVertexOnAP(vC4.getAP(2), rcvM4.getAP(0));
177 graph.appendVertexOnAP(vC5.getAP(1), vC6.getAP(0));
178 graph.appendVertexOnAP(vC5.getAP(2), rcvP4.getAP(0));
179 graph.appendVertexOnAP(vC6.getAP(1), vC7.getAP(0));
180 graph.appendVertexOnAP(vC7.getAP(1), vC8.getAP(0));
181 graph.appendVertexOnAP(vC8.getAP(1), rcvP3.getAP(0));
182 graph.appendVertexOnAP(vC8.getAP(2), vN.getAP(0));
183 graph.appendVertexOnAP(vN.getAP(1), rcvM2.getAP(0));
184 graph.appendVertexOnAP(vN.getAP(2), rcvM3.getAP(0));
185
186 // Prepare all that it is needed to run a ring-size management case
187
188 Logger logger = Logger.getLogger("DummyLogger");
189 Randomizer rng = new Randomizer();
190
191 //DenoptimIO.writeGraphToSDF(new File("/tmp/graph.sdf"), graph, false, logger, rng);
192
193 ThreeDimTreeBuilder t3d = new ThreeDimTreeBuilder(logger, rng);
194 t3d.setAlignBBsIn3D(false); //3D not needed
195 IAtomContainer mol = t3d.convertGraphTo3DAtomContainer(graph, true);
196
197 // Fragment space allows all pairs of complementary RCVs to form chords
198 HashMap<APClass,ArrayList<APClass>> cpMap =
199 new HashMap<APClass,ArrayList<APClass>>();
200 ArrayList<APClass> lstA = new ArrayList<APClass>();
201 lstA.add(apc);
202 cpMap.put(apc, lstA);
204 FragmentSpace fs = new FragmentSpace(fsp,
205 new ArrayList<Vertex>(),
206 new ArrayList<Vertex>(),
207 new ArrayList<Vertex>(),
208 cpMap,
209 new HashMap<APClass,APClass>(),
210 new HashSet<APClass>(),
211 cpMap);
213
214 // Allow formation of 5- to 7-membered rings
216 List<Integer> biases = new ArrayList<Integer>();
217 for (int i=0; i<4; i++)
218 {
219 biases.add(0); // 0 means ring-closure not allowed
220 }
221 for (int i=4; i<8; i++)
222 {
223 biases.add(1); // 1 means ring-closure allow with weight = 1
224 }
225 for (int i=8; i<10; i++)
226 {
227 biases.add(0); // 0 means ring-closure not allowed
228 }
229 rcParams.setRingSizeBias(biases);
230
231 // uncomment to log on console
232 //rcParams.startConsoleLogger("logger");
233 //rcParams.setVerbosity(2);
234
236 graph,
237 6, // max number of rings we are allowed to close
238 fs, rcParams);
239
240 List<Integer> foundRingSizes = new ArrayList<Integer>();
241 int maxCheckedSize = 15;
242 for (int i=0; i<maxCheckedSize; i++)
243 {
244 foundRingSizes.add(0);
245 }
246 boolean log = false;
247 for (int i=0; i<50; i++)
248 {
249 List<Ring> rings = iter.next();
250 assertTrue(rings.size()>1);
251 for (Ring ring : rings)
252 {
253 foundRingSizes.set(ring.getSize(), foundRingSizes.get(ring.getSize())+1);
254 }
255
256 if (log)
257 {
258 System.out.println("Combination "+i);
259 for (Ring ring : rings)
260 {
261 System.out.println(" -> " + ring.getHeadVertex().getVertexId()
262 + "---" + ring.getTailVertex().getVertexId()
263 + " (" + ring.getSize() + ")");
264 }
265 System.out.println(" ");
266 }
267 }
268
269 if (log)
270 {
271 System.out.println("RingSizes");
272 for (int i=0; i<maxCheckedSize; i++)
273 System.out.println(" "+i+" = "+foundRingSizes.get(i));
274 }
275
276 // NB: the counts include the RCA atoms, so the actual ring size is N-2
277 for (int i=0; i<6; i++)
278 {
279 assertTrue(foundRingSizes.get(i) == 0);
280 }
281 assertTrue(foundRingSizes.get(6) > 0); // 4-membered rings
282 assertTrue(foundRingSizes.get(7) > 0);
283 assertTrue(foundRingSizes.get(8) > 0);
284 assertTrue(foundRingSizes.get(9) == 0);
285 assertTrue(foundRingSizes.get(10) == 0);
286 assertTrue(foundRingSizes.get(11) > 0);
287 assertTrue(foundRingSizes.get(12) > 0);
288 assertTrue(foundRingSizes.get(13) == 0);
289 assertTrue(foundRingSizes.get(14) == 0);
290 }
291
292//------------------------------------------------------------------------------
293
294}
Class defining a space of building blocks.
void setAPclassBasedApproach(boolean useAPC)
Set the fragment space to behave according to APClass-based approach.
Parameters defining the fragment space.
static final APClass RCACLASSPLUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:84
static final APClass RCACLASSMINUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:91
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
Definition: APClass.java:136
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
Definition: DGraph.java:1097
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,...
Definition: DGraph.java:5776
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
void addAP(int atomPositionNumber)
Adds an attachment point with a dummy APClass.
Definition: Fragment.java:343
Fragment clone()
Returns a deep copy of this fragments.
Definition: Fragment.java:733
This class represents the closure of a ring in a spanning tree.
Definition: Ring.java:40
void setVertexId(long vertexId2)
Definition: Vertex.java:261
void setAsRCV(boolean isRCV)
Definition: Vertex.java:254
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:920
Unit test for the iterator over random combination of rings.
A class for iterating over sets of ring combinations generated by considering any constrain and setti...
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final HashMap< APClass, String > RCALABELPERAPCLASS
Conventional labels for attractor pseudoatom.
Parameters and setting related to handling ring closures.
void setRingSizeBias(List< Integer > biases)
Sets the preference for certain ring sizes or the prohibition to generate certain rings (i....
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.
Tool to generate random numbers and random decisions.
Definition: Randomizer.java:35
The type of building block.
Definition: Vertex.java:86