$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.util.ArrayList;
24import java.util.HashMap;
25import java.util.HashSet;
26import java.util.List;
27import java.util.logging.Logger;
28
29import javax.vecmath.Point3d;
30
31import org.junit.jupiter.api.Test;
32import org.openscience.cdk.Atom;
33import org.openscience.cdk.PseudoAtom;
34import org.openscience.cdk.interfaces.IAtom;
35import org.openscience.cdk.interfaces.IAtomContainer;
36import org.openscience.cdk.interfaces.IChemObjectBuilder;
37import org.openscience.cdk.silent.SilentChemObjectBuilder;
38
39import denoptim.fragspace.FragmentSpace;
40import denoptim.fragspace.FragmentSpaceParameters;
41import denoptim.graph.APClass;
42import denoptim.graph.DGraph;
43import denoptim.graph.Fragment;
44import denoptim.graph.Ring;
45import denoptim.graph.Vertex;
46import denoptim.graph.Vertex.BBType;
47import denoptim.molecularmodeling.ThreeDimTreeBuilder;
48import denoptim.utils.Randomizer;
49
57{
58
59//------------------------------------------------------------------------------
60
61 @Test
62 public void testEvaluateConstitutionalClosability() throws Exception
63 {
64 /*
65 * Make the test graph (make it here so we have direct access to vertexes)
66 *
67 * RCV_P RCV_P RCV_M RCV_P RCV_M
68 * | | | | |
69 * RCV_M--[O]----[C]--[C]--[C]--[C]--[C]--[C]--[C]--[C]----[N]--RCV_M
70 * vO vC vC2 vC3 vC4 vC5 vC6 cV7 vC8 vN
71 * |
72 * RCV_P
73 */
74
75 APClass apc = APClass.make("A", 0);
76
77 IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
78
79 IAtomContainer iacO = builder.newAtomContainer();
80 IAtom aO = new Atom("O",new Point3d(0,0,0));
81 iacO.addAtom(aO);
82 Fragment vO = new Fragment(0, iacO,BBType.FRAGMENT);
83 vO.addAP(0, new Point3d(0,-1,0), apc);
84 vO.addAP(0, new Point3d(2,0,0), apc);
85 vO.addAP(0, new Point3d(0,1,0), apc);
86
87 IAtomContainer iacC = builder.newAtomContainer();
88 IAtom aC = new Atom("C",new Point3d(0,0,0));
89 iacC.addAtom(aC);
90 Fragment vC = new Fragment(1, iacC,BBType.FRAGMENT);
91 vC.addAP(0, new Point3d(0,-1,0), apc);
92 vC.addAP(0, new Point3d(2,0,0), apc);
93 vC.addAP(0, new Point3d(0,1,0), apc);
94
95 IAtomContainer iacCd = builder.newAtomContainer();
96 IAtom aCd = new Atom("C",new Point3d(0,0,0));
97 iacCd.addAtom(aCd);
98 Fragment vC2 = new Fragment(2, iacCd,BBType.FRAGMENT);
99 vC2.addAP(0, new Point3d(0,-1,0), apc);
100 vC2.addAP(0, new Point3d(0,1,0), apc);
101
102 Fragment vC3 = vC2.clone();
103 vC3.setVertexId(33);
104
105 Fragment vC4 = vC.clone();
106 vC4.setVertexId(34);
107
108 Fragment vC5 = vC.clone();
109 vC5.setVertexId(35);
110
111 Fragment vC6 = vC2.clone();
112 vC6.setVertexId(36);
113
114 Fragment vC7 = vC2.clone();
115 vC7.setVertexId(37);
116
117 Fragment vC8 = vC.clone();
118 vC8.setVertexId(3);
119
120 IAtomContainer iacN = builder.newAtomContainer();
121 IAtom aN = new Atom("N",new Point3d(0,0,0));
122 iacN.addAtom(aN);
123 Fragment vN = new Fragment(4, iacN,BBType.FRAGMENT);
124 vN.addAP(0, new Point3d(0,-1,0), apc);
125 vN.addAP(0, new Point3d(2,0,0), apc);
126 vN.addAP(0, new Point3d(0,1,0), apc);
127
128 APClass atMinus = APClass.RCACLASSMINUS;
129
130 IAtomContainer iacD = builder.newAtomContainer();
131 iacD.addAtom(new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(atMinus),
132 new Point3d(0,0,0)));
133 Fragment rcvM = new Fragment(5, iacD,BBType.FRAGMENT);
134 rcvM.addAP(0, new Point3d(-1,0,0), atMinus);
135 rcvM.setAsRCV(true);
136
137 Fragment rcvM2 = rcvM.clone();
138 rcvM2.setVertexId(6);
139
140 Fragment rcvM3 = rcvM.clone();
141 rcvM3.setVertexId(7);
142
143 Fragment rcvM4 = rcvM.clone();
144 rcvM4.setVertexId(11);
145
147
148 IAtomContainer iacE = builder.newAtomContainer();
149 iacE.addAtom(new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(atPlus),
150 new Point3d(0,0,0)));
151 Fragment rcvP = new Fragment(8, iacE,BBType.FRAGMENT);
152 rcvP.addAP(0, new Point3d(-1,0,0), atPlus);
153 rcvP.setAsRCV(true);
154
155 Fragment rcvP2 = rcvP.clone();
156 rcvP2.setVertexId(9);
157
158 Fragment rcvP3 = rcvP.clone();
159 rcvP3.setVertexId(10);
160
161 Fragment rcvP4 = rcvP.clone();
162 rcvP4.setVertexId(12);
163
164 DGraph graph = new DGraph();
165 graph.addVertex(vC);
166 graph.appendVertexOnAP(vC.getAP(0), vO.getAP(2));
167 graph.appendVertexOnAP(vO.getAP(0), rcvM.getAP(0));
168 graph.appendVertexOnAP(vO.getAP(1), rcvP.getAP(0));
169 graph.appendVertexOnAP(vC.getAP(1), rcvP2.getAP(0));
170 graph.appendVertexOnAP(vC.getAP(2), vC2.getAP(1));
171 graph.appendVertexOnAP(vC2.getAP(0), vC3.getAP(0));
172 graph.appendVertexOnAP(vC3.getAP(1), vC4.getAP(0));
173 graph.appendVertexOnAP(vC4.getAP(1), vC5.getAP(0));
174 graph.appendVertexOnAP(vC4.getAP(2), rcvM4.getAP(0));
175 graph.appendVertexOnAP(vC5.getAP(1), vC6.getAP(0));
176 graph.appendVertexOnAP(vC5.getAP(2), rcvP4.getAP(0));
177 graph.appendVertexOnAP(vC6.getAP(1), vC7.getAP(0));
178 graph.appendVertexOnAP(vC7.getAP(1), vC8.getAP(0));
179 graph.appendVertexOnAP(vC8.getAP(1), rcvP3.getAP(0));
180 graph.appendVertexOnAP(vC8.getAP(2), vN.getAP(0));
181 graph.appendVertexOnAP(vN.getAP(1), rcvM2.getAP(0));
182 graph.appendVertexOnAP(vN.getAP(2), rcvM3.getAP(0));
183
184 // Prepare all that it is needed to run a ring-size management case
185
186 Logger logger = Logger.getLogger("DummyLogger");
187 Randomizer rng = new Randomizer();
188
189 //DenoptimIO.writeGraphToSDF(new File("/tmp/graph.sdf"), graph, false, logger, rng);
190
191 ThreeDimTreeBuilder t3d = new ThreeDimTreeBuilder(logger, rng);
192 t3d.setAlignBBsIn3D(false); //3D not needed
193 IAtomContainer mol = t3d.convertGraphTo3DAtomContainer(graph, true);
194
195 // Fragment space allows all pairs of complementary RCVs to form chords
196 HashMap<APClass,ArrayList<APClass>> cpMap =
197 new HashMap<APClass,ArrayList<APClass>>();
198 ArrayList<APClass> lstA = new ArrayList<APClass>();
199 lstA.add(apc);
200 cpMap.put(apc, lstA);
202 FragmentSpace fs = new FragmentSpace(fsp,
203 new ArrayList<Vertex>(),
204 new ArrayList<Vertex>(),
205 new ArrayList<Vertex>(),
206 cpMap,
207 new HashMap<APClass,APClass>(),
208 new HashSet<APClass>(),
209 cpMap);
211
212 // Allow formation of 5- to 7-membered rings
214 List<Integer> biases = new ArrayList<Integer>();
215 for (int i=0; i<4; i++)
216 {
217 biases.add(0); // 0 means ring-closure not allowed
218 }
219 for (int i=4; i<8; i++)
220 {
221 biases.add(1); // 1 means ring-closure allow with weight = 1
222 }
223 for (int i=8; i<10; i++)
224 {
225 biases.add(0); // 0 means ring-closure not allowed
226 }
227 rcParams.setRingSizeBias(biases);
228
229 // uncomment to log on console
230 //rcParams.startConsoleLogger("logger");
231 //rcParams.setVerbosity(2);
232
234 graph,
235 6, // max number of rings we are allowed to close
236 fs, rcParams);
237
238 List<Integer> foundRingSizes = new ArrayList<Integer>();
239 int maxCheckedSize = 15;
240 for (int i=0; i<maxCheckedSize; i++)
241 {
242 foundRingSizes.add(0);
243 }
244 boolean log = false;
245 for (int i=0; i<50; i++)
246 {
247 List<Ring> rings = iter.next();
248 assertTrue(rings.size()>1);
249 for (Ring ring : rings)
250 {
251 foundRingSizes.set(ring.getSize(), foundRingSizes.get(ring.getSize())+1);
252 }
253
254 if (log)
255 {
256 System.out.println("Combination "+i);
257 for (Ring ring : rings)
258 {
259 System.out.println(" -> " + ring.getHeadVertex().getVertexId()
260 + "---" + ring.getTailVertex().getVertexId()
261 + " (" + ring.getSize() + ")");
262 }
263 System.out.println(" ");
264 }
265 }
266
267 if (log)
268 {
269 System.out.println("RingSizes");
270 for (int i=0; i<maxCheckedSize; i++)
271 System.out.println(" "+i+" = "+foundRingSizes.get(i));
272 }
273
274 // NB: the counts include the RCA atoms, so the actual ring size is N-2
275 for (int i=0; i<6; i++)
276 {
277 assertTrue(foundRingSizes.get(i) == 0);
278 }
279 assertTrue(foundRingSizes.get(6) > 0); // 4-membered rings
280 assertTrue(foundRingSizes.get(7) > 0);
281 assertTrue(foundRingSizes.get(8) > 0);
282 assertTrue(foundRingSizes.get(9) == 0);
283 assertTrue(foundRingSizes.get(10) == 0);
284 assertTrue(foundRingSizes.get(11) > 0);
285 assertTrue(foundRingSizes.get(12) > 0);
286 assertTrue(foundRingSizes.get(13) == 0);
287 assertTrue(foundRingSizes.get(14) == 0);
288 }
289
290//------------------------------------------------------------------------------
291
292}
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:85
static final APClass RCACLASSMINUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:92
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:164
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:1325
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:6005
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:281
void setAsRCV(boolean isRCV)
Definition: Vertex.java:274
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:1007
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