$darkmode
DENOPTIM
Vertex.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.graph;
21
22import java.lang.reflect.Type;
23import java.util.ArrayList;
24import java.util.Arrays;
25import java.util.Collection;
26import java.util.HashMap;
27import java.util.HashSet;
28import java.util.List;
29import java.util.Map;
30import java.util.Set;
31import java.util.logging.Level;
32import java.util.logging.Logger;
33
34import org.openscience.cdk.interfaces.IAtomContainer;
35
36import com.google.gson.Gson;
37import com.google.gson.JsonDeserializationContext;
38import com.google.gson.JsonDeserializer;
39import com.google.gson.JsonElement;
40import com.google.gson.JsonObject;
41import com.google.gson.JsonParseException;
42import com.google.gson.JsonSyntaxException;
43
44import denoptim.constants.DENOPTIMConstants;
45import denoptim.exception.DENOPTIMException;
46import denoptim.fragspace.FragmentSpace;
47import denoptim.graph.rings.RingClosingAttractor;
48import denoptim.json.DENOPTIMgson;
49import denoptim.logging.StaticLogger;
50import denoptim.utils.GraphUtils;
51import denoptim.utils.MutationType;
52import denoptim.utils.Randomizer;
53
61public abstract class Vertex implements Cloneable
62{
66 private DGraph owner;
67
71 private long vertexId;
72
77 protected int buildingBlockId = -99;
78
87 public enum BBType {
88 UNDEFINED, SCAFFOLD, FRAGMENT, CAP, NONE;
89
90 private int i = -99;
91
92 static {
93 NONE.i = -1;
94 SCAFFOLD.i = 0;
95 FRAGMENT.i = 1;
96 CAP.i = 2;
97 }
98
104 public static BBType parseInt(int i) {
105 BBType bbt;
106 switch (i)
107 {
108 case 0:
109 bbt = SCAFFOLD;
110 break;
111 case 1:
112 bbt = FRAGMENT;
113 break;
114 case 2:
115 bbt = CAP;
116 break;
117 default:
118 bbt = UNDEFINED;
119 break;
120 }
121 return bbt;
122 }
123
127 public int toOldInt()
128 {
129 return i;
130 }
131 }
132
133 /*
134 * Building block type distinguished among types of building blocks:
135 * scaffolds, fragments, and capping.
136 * Can be undefined, which is the default.
137 */
139
140 /*
141 * Flag indicating that this as a ring closing vertex
142 */
143 private boolean isRCV;
144
148 protected Map<Object, Object> properties;
149
155 protected Set<String> uniquefyingPropertyKeys = new HashSet<String>();
156
160 private List<MutationType> allowedMutationTypes =
161 new ArrayList<MutationType>(Arrays.asList(MutationType.values()));
162
167 protected final VertexType vertexType;
168
173 public enum VertexType {
177 }
178
179//------------------------------------------------------------------------------
180
185 {
186 this.vertexType = vertexType;
188 isRCV = false;
189 }
190
191//------------------------------------------------------------------------------
192
200 public Vertex(VertexType vertexType, long id)
201 {
202 this(vertexType);
203 vertexId = id;
204 }
205
206//------------------------------------------------------------------------------
207
215 public static Vertex newVertexFromLibrary(int bbId,
216 Vertex.BBType bbt, FragmentSpace fragSpace)
217 throws DENOPTIMException
218 {
220 fragSpace);
221 }
222
223//------------------------------------------------------------------------------
224
232 public static Vertex newVertexFromLibrary(long vertexId, int bbId,
233 Vertex.BBType bbt, FragmentSpace fragSpace)
234 throws DENOPTIMException
235 {
236 // The actual type of vertex
237 // returned by this method depends on the what we get from the
238 // FragmentSpace.getVertexFromLibrary call
239 Vertex v = fragSpace.getVertexFromLibrary(bbt,bbId);
241
242 v.setAsRCV(v.getNumberOfAPs() == 1
244 v.getAttachmentPoints().get(0).getAPClass()));
245
246 return v;
247 }
248
249//------------------------------------------------------------------------------
250
251 public abstract List<AttachmentPoint> getAttachmentPoints();
252
253//------------------------------------------------------------------------------
254
261 public List<AttachmentPoint> getAPsWithAPClassStartingWith(
262 String root)
263 {
264 List<AttachmentPoint> list = new ArrayList<AttachmentPoint>();
266 {
267 if (ap.getAPClass().toString().startsWith(root))
268 list.add(ap);
269 }
270 return list;
271 }
272
273//------------------------------------------------------------------------------
274
275 public void setAsRCV(boolean isRCV)
276 {
277 this.isRCV = isRCV;
278 }
279
280//------------------------------------------------------------------------------
281
282 public void setVertexId(long vertexId2)
283 {
284 this.vertexId = vertexId2;
285 }
286
287//------------------------------------------------------------------------------
288
289 public long getVertexId()
290 {
291 return vertexId;
292 }
293
294//------------------------------------------------------------------------------
295
306 {
307 return buildingBlockId;
308 }
309
310//------------------------------------------------------------------------------
311
313 {
314 this.buildingBlockId = buildingBlockId;
315 }
316
317//------------------------------------------------------------------------------
318
319 public Vertex.BBType getBuildingBlockType()
320 {
321 return buildingBlockType;
322 }
323
324//------------------------------------------------------------------------------
325
327 {
328 this.buildingBlockType = buildingBlockType;
329 }
330
331//------------------------------------------------------------------------------
332
333 protected abstract void setSymmetricAPSets(List<SymmetricAPs> sAPs);
334
335//------------------------------------------------------------------------------
336
337 protected abstract void addSymmetricAPSet(SymmetricAPs symAPs);
338
339//------------------------------------------------------------------------------
340
341 public abstract List<SymmetricAPs> getSymmetricAPSets();
342
343//------------------------------------------------------------------------------
344
355 {
356 for (SymmetricAPs symmetricSet : getSymmetricAPSets())
357 {
358 if (symmetricSet.contains(ap))
359 {
360 return symmetricSet;
361 }
362 }
363 return new SymmetricAPs();
364 }
365
366//------------------------------------------------------------------------------
367
368 public int getNumberOfAPs()
369 {
370 return getAttachmentPoints().size();
371 }
372
373//------------------------------------------------------------------------------
374
375 public int getFreeAPCount()
376 {
377 int n = 0;
379 {
380 if (ap.isAvailable())
381 n++;
382 }
383 return n;
384 }
385
386//------------------------------------------------------------------------------
387
403 public ArrayList<AttachmentPoint> getFreeAPThroughout()
404 {
405 ArrayList<AttachmentPoint> lst =
406 new ArrayList<AttachmentPoint>();
408 {
409 if (ap.isAvailableThroughout())
410 lst.add(ap);
411 }
412 return lst;
413 }
414
415//------------------------------------------------------------------------------
416
432 {
433 return getFreeAPThroughout().size();
434 }
435
436//------------------------------------------------------------------------------
437
449 public ArrayList<AttachmentPoint> getCappedAPs()
450 {
451 ArrayList<AttachmentPoint> lst =
452 new ArrayList<AttachmentPoint>();
454 {
455 if (!ap.isAvailable())
456 {
457 AttachmentPoint linkedAP = ap.getLinkedAP();
458 if (linkedAP.getOwner().getBuildingBlockType() == BBType.CAP)
459 lst.add(ap);
460 }
461 }
462 return lst;
463 }
464
465//------------------------------------------------------------------------------
466
483 public ArrayList<AttachmentPoint> getCappedAPsThroughout()
484 {
485 ArrayList<AttachmentPoint> lst =
486 new ArrayList<AttachmentPoint>();
488 {
489 if (!ap.isAvailableThroughout())
490 {
492 if (linkedAP.getOwner().getBuildingBlockType() == BBType.CAP)
493 lst.add(ap);
494 }
495 }
496 return lst;
497 }
498
499//------------------------------------------------------------------------------
500
515 {
516 return getCappedAPsThroughout().size();
517 }
518
519//------------------------------------------------------------------------------
520
521 public boolean hasFreeAP()
522 {
524 {
525 if (ap.isAvailableThroughout())
526 return true;
527 }
528 return false;
529 }
530
531//------------------------------------------------------------------------------
532
533 protected int getUniqueAPIndex()
534 {
535 if (owner == null)
536 {
537 return getNumberOfAPs();
538 } else {
539 return owner.getUniqueAPIndex();
540 }
541 }
542
543//------------------------------------------------------------------------------
544
550 public boolean isRCV()
551 {
552 return isRCV;
553 }
554
555//------------------------------------------------------------------------------
556
564 public boolean isAromaticBridge()
565 {
566 return getAllAPClasses()
567 .stream()
568 .anyMatch(apc -> APClass.APCAROMBRIDGES.contains(apc));
569 }
570
571//------------------------------------------------------------------------------
572
584 {
586 {
587 if (ap.isAvailableThroughout())
588 continue;
589
591 if (APClass.APCAROMBRIDGES.contains(linkedAp.getAPClass()))
592 return true;
593 Vertex rcv = linkedAp.getOwner();
594 if (rcv.isRCV)
595 {
596 if (getGraphOwner().getRingsInvolvingVertex(rcv).size()==0)
597 continue;
598 // Since it is an RCV, there can be only one ring involved.
602 }
603 }
604 return false;
605 }
606
607//------------------------------------------------------------------------------
608
614 public boolean hasSymmetricAP()
615 {
616 return !getSymmetricAPSets().isEmpty();
617 }
618
619//------------------------------------------------------------------------------
620
631 @Override
632 public String toString()
633 {
634 return vertexId + "_" + (buildingBlockId + 1) + "_"
636 }
637
638//------------------------------------------------------------------------------
639
640 public void cleanup()
641 {
642 if (getSymmetricAPSets() != null)
643 {
644 getSymmetricAPSets().clear();
645 }
646 if (getAttachmentPoints() != null)
647 {
648 getAttachmentPoints().clear();
649 }
650 }
651
652//------------------------------------------------------------------------------
653
659 @Override
660 public abstract Vertex clone();
661
662//------------------------------------------------------------------------------
663
670 public boolean sameAs(Vertex other)
671 {
672 return sameAs(other, new StringBuilder());
673 }
674
675//------------------------------------------------------------------------------
676
685 public boolean sameAs(Vertex other, StringBuilder reason)
686 {
687 if (this.getClass() == other.getClass())
688 {
689 if (this instanceof Fragment)
690 {
691 return ((Fragment) this).sameAs(
692 (Fragment) other, reason);
693 } else if (this instanceof EmptyVertex) {
694 return ((EmptyVertex) this).sameAs(
695 (EmptyVertex) other, reason);
696 } else if (this instanceof Template) {
697 return ((Template) this).sameAs(
698 (Template) other, reason);
699 } else {
700 System.err.println("WARNING: Unimplemented sameAs method for "
701 + "vertex subtype '" + this.getClass().getName() + "'");
702 }
703 }
704 return sameVertexFeatures(other, reason);
705 }
706
707//------------------------------------------------------------------------------
708
717 public boolean sameVertexFeatures(Vertex other, StringBuilder reason)
718 {
719 if (this.getBuildingBlockType() != other.getBuildingBlockType())
720 {
721 reason.append("Different building block type ("
722 + this.getBuildingBlockType()+":"
723 + other.getBuildingBlockType()+"); ");
724 return false;
725 }
726
727 if (this.getBuildingBlockId() != other.getBuildingBlockId())
728 {
729 reason.append("Different molID ("+this.getBuildingBlockId()+":"
730 + other.getBuildingBlockId()+"); ");
731 return false;
732 }
733
734 if (this.getNumberOfAPs() != other.getNumberOfAPs())
735 {
736 reason.append("Different number of APs ("
737 +this.getNumberOfAPs()+":"
738 +other.getNumberOfAPs()+"); ");
739 return false;
740 }
741
742 // Order of APs must be the same
743 for (int i=0; i<this.getNumberOfAPs(); i++)
744 {
745 AttachmentPoint apT = this.getAP(i);
746 AttachmentPoint apO = other.getAP(i);
747 if (!apT.sameAs(apO))
748 {
749 reason.append("Difference in AP "+i+": "+apT+" vs "+apO);
750 return false;
751 }
752 }
753
754 return true;
755 }
756
757//------------------------------------------------------------------------------
758
759 public abstract int getHeavyAtomsCount();
760
761//------------------------------------------------------------------------------
762
763 public abstract boolean containsAtoms();
764
765//------------------------------------------------------------------------------
766
767 public abstract IAtomContainer getIAtomContainer();
768
769//------------------------------------------------------------------------------
770
783 public abstract IAtomContainer getIAtomContainer(Logger logger,
784 Randomizer rng, boolean removeUsedRCAs, boolean rebuild);
785
786//-----------------------------------------------------------------------------
787
793 public ArrayList<APClass> getAllAPClasses()
794 {
795 ArrayList<APClass> lst = new ArrayList<APClass>();
797 {
798 APClass apCls = ap.getAPClass();
799 if (!lst.contains(apCls))
800 {
801 lst.add(apCls);
802 }
803 }
804 return lst;
805 }
806
807//-----------------------------------------------------------------------------
808
815 public ArrayList<APClass> getAllAvailableAPClasses()
816 {
817 ArrayList<APClass> lst = new ArrayList<APClass>();
819 {
820 if (!ap.isAvailable())
821 continue;
822
823 APClass apCls = ap.getAPClass();
824 if (!lst.contains(apCls))
825 {
826 lst.add(apCls);
827 }
828 }
829 return lst;
830 }
831
832//------------------------------------------------------------------------------
833
834 public void resetGraphOwner()
835 {
836 this.owner = null;
837 }
838
839//------------------------------------------------------------------------------
840
842 {
843 this.owner = owner;
844 }
845
846//------------------------------------------------------------------------------
847
853 {
854 return owner;
855 }
856
857//------------------------------------------------------------------------------
858
863 public List<Vertex> getMutationSites()
864 {
865 return getMutationSites(new ArrayList<MutationType>());
866 }
867
868//------------------------------------------------------------------------------
869
877 public abstract List<Vertex> getMutationSites(
878 List<MutationType> ignoredTypes);
879
880//------------------------------------------------------------------------------
881
882 public void setMutationTypes(List<MutationType> lst)
883 {
885 }
886
887//------------------------------------------------------------------------------
888
896 protected List<MutationType> getUnfilteredMutationTypes()
897 {
899 }
900
901//------------------------------------------------------------------------------
902
909 {
910 return allowedMutationTypes.remove(mt);
911 }
912
913//------------------------------------------------------------------------------
914
919 public List<MutationType> getMutationTypes()
920 {
921 return getMutationTypes(new ArrayList<MutationType>());
922 }
923
924//------------------------------------------------------------------------------
925
932 public List<MutationType> getMutationTypes(List<MutationType> excludedTypes)
933 {
934 List<MutationType> filteredTypes = new ArrayList<MutationType>(
936 if (owner != null)
937 {
938 // this vertex is part of a graph
939
940 // Cannot add/change link on vertex that is not linked
941 if (getChilddren().isEmpty())
942 {
943 filteredTypes.remove(MutationType.ADDLINK);
944 filteredTypes.remove(MutationType.CHANGELINK);
945 }
946
947 // Cannot extend vertex that has no truly free AP, but can do it
948 // on APs that are used by capping groups.
949 if ((getFreeAPCountThroughout() + getCappedAPs().size()) == 0)
950 {
951 filteredTypes.remove(MutationType.EXTEND);
952 filteredTypes.remove(MutationType.ADDRING);
953 filteredTypes.remove(MutationType.ADDFUSEDRING);
954 }
955
956 // Cannot remove the only vertex of a graph
957 if (owner.getVertexCount()==0)
958 filteredTypes.remove(MutationType.DELETE);
959
960 // Cannot start removal of chain from a branching vertex.
961 long nonCap = getAttachmentPoints().size()
964 if (nonCap > 2)
965 filteredTypes.remove(MutationType.DELETECHAIN);
966 }
967
969 {
970 // So far we do not do any check to ensure that
971 // A) the change/additions/removal of a link retains aromaticity,
972 // B) the other APs can be safely interchanged between links as long
973 // as the APClass compatibility is respected.
974 // Therefore, link editing is unsafe for building blocks of aromatic
975 // systems.
976 filteredTypes.remove(MutationType.ADDLINK);
977 filteredTypes.remove(MutationType.DELETELINK);
978 filteredTypes.remove(MutationType.CHANGELINK);
979 filteredTypes.remove(MutationType.CHANGEBRANCH);
980 }
981
983 {
984 filteredTypes.remove(MutationType.DELETELINK);
985 }
986
988 {
989 filteredTypes.remove(MutationType.DELETECHAIN);
990 filteredTypes.remove(MutationType.DELETELINK);
991 filteredTypes.remove(MutationType.CHANGELINK);
992 filteredTypes.remove(MutationType.CHANGEBRANCH);
993 filteredTypes.remove(MutationType.DELETE);
994 }
995
996 filteredTypes.removeAll(excludedTypes);
997
998 return filteredTypes;
999 }
1000
1001//------------------------------------------------------------------------------
1002
1008 public AttachmentPoint getAP(int i) {
1009 return getAttachmentPoints().get(i);
1010 }
1011
1012//------------------------------------------------------------------------------
1013
1020 {
1022 {
1023 if (ap.getID()==i)
1024 return ap;
1025 }
1026 return null;
1027 }
1028
1029//------------------------------------------------------------------------------
1030
1038 {
1039 for (int i=0; i<getAttachmentPoints().size(); i++)
1040 {
1041 AttachmentPoint candAp = getAttachmentPoints().get(i);
1042 if (candAp == ap)
1043 {
1044 return i;
1045 }
1046 }
1047 return -1;
1048 }
1049
1050//------------------------------------------------------------------------------
1051
1062 {
1063 Edge user = ap.getEdgeUser();
1064 if (user == null)
1065 continue;
1066
1067 if (ap == user.getTrgAP())
1068 {
1069 return user;
1070 }
1071 }
1072 return null;
1073 }
1074
1075//------------------------------------------------------------------------------
1076
1085 {
1087 {
1088 Edge user = ap.getEdgeUser();
1089 if (user == null)
1090 continue;
1091
1092 if (ap == user.getTrgAP())
1093 {
1094 return user.getSrcAP().getOwner();
1095 }
1096 }
1097 return null;
1098 }
1099
1100//------------------------------------------------------------------------------
1101
1114 public ArrayList<AttachmentPoint> getAPsFromChildren()
1115 {
1116 ArrayList<AttachmentPoint> apsOnChildren =
1117 new ArrayList<AttachmentPoint>();
1119 {
1120 Edge user = ap.getEdgeUserThroughout();
1121 if (user == null)
1122 continue;
1123
1124 if (ap == user.getSrcAPThroughout())
1125 {
1126 apsOnChildren.add(user.getTrgAPThroughout());
1127 }
1128 }
1129 return apsOnChildren;
1130 }
1131
1132//------------------------------------------------------------------------------
1133
1145 public ArrayList<Vertex> getChildrenThroughout()
1146 {
1147 ArrayList<Vertex> children = new ArrayList<Vertex>();
1149 {
1150 Edge user = ap.getEdgeUserThroughout();
1151 if (user == null)
1152 continue;
1153
1154 if (ap.isSrcInUserThroughout())
1155 {
1156 children.add(user.getTrgAP().getOwner());
1157 }
1158 }
1159 return children;
1160 }
1161
1162//------------------------------------------------------------------------------
1163
1173 public ArrayList<Vertex> getChilddren()
1174 {
1175 ArrayList<Vertex> children = new ArrayList<Vertex>();
1177 {
1178 // NB: this is meant to NOT cross template boundaries, so that all
1179 // children do belong to the same graph.
1180 Edge user = ap.getEdgeUser();
1181 if (user == null)
1182 continue;
1183
1184 if (ap == user.getSrcAP())
1185 {
1186 children.add(user.getTrgAP().getOwner());
1187 }
1188 }
1189 return children;
1190 }
1191
1192//------------------------------------------------------------------------------
1193
1200 public void setUniquefyingProperty(String key)
1201 {
1202 uniquefyingPropertyKeys.add(key);
1203 }
1204
1205//------------------------------------------------------------------------------
1206
1207 public Map<Object, Object> getProperties()
1208 {
1209 return properties;
1210 }
1211
1212//------------------------------------------------------------------------------
1213
1214 public boolean hasProperty(Object property)
1215 {
1216 if (properties==null)
1217 return false;
1218
1219 return properties.containsKey(property);
1220 }
1221
1222//------------------------------------------------------------------------------
1223
1224 public Object getProperty(Object property)
1225 {
1226 if (properties == null)
1227 {
1228 return null;
1229 } else {
1230 return properties.get(property);
1231 }
1232 }
1233
1234//-----------------------------------------------------------------------------
1235
1236 public void setProperty(Object key, Object property)
1237 {
1238 if (properties == null)
1239 {
1240 properties = new HashMap<Object, Object>();
1241 }
1242 properties.put(key, property);
1243 }
1244
1245//-----------------------------------------------------------------------------
1246
1247 public void removeProperty(Object key)
1248 {
1249 if (properties == null)
1250 return;
1251
1252 properties.remove(key);
1253 }
1254
1255//------------------------------------------------------------------------------
1256
1262 protected Map<Object, Object> copyStringBasedProperties()
1263 {
1264 if (properties==null)
1265 return null;
1266
1267 Map<Object, Object> copy = new HashMap<Object, Object>();
1268 for (Object k : properties.keySet())
1269 {
1270 Object v = properties.get(k);
1271 if ((k instanceof String && v instanceof String)
1272 || (uniquefyingPropertyKeys!=null
1273 && uniquefyingPropertyKeys.contains(k)))
1274 {
1275 copy.put(k,v);
1276 }
1277 }
1278 return copy;
1279 }
1280
1281//-----------------------------------------------------------------------------
1282
1283 public void setProperties(Map<Object, Object> properties)
1284 {
1285 this.properties = properties;
1286 }
1287
1288//------------------------------------------------------------------------------
1289
1290 public static Vertex fromJson(String json)
1291 {
1292 Gson gson = DENOPTIMgson.getReader();
1293 return gson.fromJson(json, Vertex.class);
1294 }
1295
1296//------------------------------------------------------------------------------
1297
1305 {
1306 return VertexType.valueOf(vertexType.name());
1307 }
1308
1309//------------------------------------------------------------------------------
1310
1311 public static class DENOPTIMVertexDeserializer
1312 implements JsonDeserializer<Vertex>
1313 {
1314 @Override
1315 public Vertex deserialize(JsonElement json, Type typeOfT,
1316 JsonDeserializationContext context) throws JsonParseException
1317 {
1318 JsonObject jsonObject = json.getAsJsonObject();
1319
1320 if (!jsonObject.has("vertexType"))
1321 {
1322 String msg = "Missing 'vertexType': found a "
1323 + "JSON string generated by a previous version and "
1324 + "that is no longer compatible. "
1325 + "Upgrade the JSON string by adding "
1326 + "the member 'vertexType', which can be any of these:";
1327 for (VertexType v : VertexType.values())
1328 msg = msg + " " + v;
1329 msg = msg + ". ";
1330 throw new JsonParseException(msg);
1331 }
1332
1333 // Deseralization differs for the types of vertices
1334 VertexType vt = context.deserialize(jsonObject.get("vertexType"),
1335 VertexType.class);
1336 Vertex v = null;
1337 switch (vt)
1338 {
1339 case Template:
1340 {
1341 v = Template.fromJson(jsonObject.toString());
1342 break;
1343 }
1344
1345 case MolecularFragment:
1346 {
1347 v = Fragment.fromJson(jsonObject.toString());
1348 break;
1349 }
1350
1351 case EmptyVertex:
1352 {
1353 v = EmptyVertex.fromJson(jsonObject.toString());
1354 break;
1355 }
1356
1357 default:
1358 {
1359 return null;
1360 }
1361 }
1362
1363 if (jsonObject.has("lstSymAPs"))
1364 {
1365 for (JsonElement elSet : jsonObject.get("lstSymAPs").getAsJsonArray())
1366 {
1367 List<AttachmentPoint> aps = new ArrayList<AttachmentPoint>();
1368 for (JsonElement elId : elSet.getAsJsonArray())
1369 {
1370 int id = context.deserialize(elId, Integer.class);
1371 AttachmentPoint ap = v.getAPWithId(id);
1372 if (ap==null)
1373 {
1374 String msg = "Failed to parse 'lstSymAPs'. It is "
1375 + "possible that the JSON input has been "
1376 + "writted by a previosu version of "
1377 + "DENOPTIM. If so, its syntax needs to be "
1378 + "upgraded.";
1379 throw new JsonParseException(msg);
1380 }
1381 aps.add(ap);
1382 }
1383 v.addSymmetricAPSet(new SymmetricAPs(aps));
1384 }
1385 }
1386
1387 return v;
1388 }
1389 }
1390
1391//------------------------------------------------------------------------------
1392
1403 public String[] getPathIDs(AttachmentPoint apA,
1404 AttachmentPoint apB)
1405 {
1406 String a2b = this.getBuildingBlockId() + "/"
1407 + this.getBuildingBlockType() + "/ap"
1408 + getIndexOfAP(apA) + "ap" + getIndexOfAP(apB) + "_";
1409 String b2a = this.getBuildingBlockId() + "/"
1410 + this.getBuildingBlockType() + "/ap"
1411 + getIndexOfAP(apB) + "ap" + getIndexOfAP(apA) + "_";
1412 String[] pair = {a2b,b2a};
1413 return pair;
1414 }
1415
1416//------------------------------------------------------------------------------
1417
1433 public static Vertex convertIACToVertex(IAtomContainer iac,
1434 Vertex.BBType bbt) throws DENOPTIMException
1435 {
1436 Vertex v = new Fragment(iac, bbt);
1437 v.setAsRCV(v.getNumberOfAPs() == 1
1439 v.getAttachmentPoints().get(0).getAPClass()));
1440 return v;
1441 }
1442
1443//------------------------------------------------------------------------------
1444
1454 public static Vertex parseVertexFromSDFFormat(IAtomContainer mol,
1455 Gson reader, BBType bbt) throws DENOPTIMException
1456 {
1457 Vertex v = null;
1458 try
1459 {
1460 Object json = mol.getProperty(DENOPTIMConstants.VERTEXJSONTAG);
1461 if (json != null) {
1462 v = reader.fromJson(json.toString(), Vertex.class);
1463 } else {
1465 if (json != null)
1466 {
1467 StaticLogger.appLogger.log(Level.WARNING, "Attempt to "
1468 + "read a vertex from "
1469 + "a SDF file that contains a JSON definition of a "
1470 + "graph. This should not be intentional, so we'll "
1471 + "read the atom container ignoring the JSON "
1472 + "definition of a graph.");
1473 }
1474 v = Vertex.convertIACToVertex(mol, bbt);
1475 }
1476 } catch (JsonSyntaxException | DENOPTIMException e)
1477 {
1478 throw new DENOPTIMException("Unable to parse IAtomContainer to "
1479 + "create vertex. ",e);
1480 }
1481 v.setBuildingBlockType(bbt);
1482 return v;
1483 }
1484
1485
1486//------------------------------------------------------------------------------
1487
1495 public boolean connectedTo(Vertex other)
1496 {
1497 return this.getParent() == other || this == other.getParent();
1498 }
1499
1500//------------------------------------------------------------------------------
1501
1508 {
1509 if (this.owner != null && other.owner !=null
1510 && this.owner == other.owner)
1511 {
1513 {
1514 AttachmentPoint linkedAp = ap.getLinkedAP();
1515 if (linkedAp == null)
1516 continue;
1517 if (linkedAp.getOwner()==other)
1518 return ap.getEdgeUser();
1519 }
1520 }
1521 return null;
1522 }
1523
1524//------------------------------------------------------------------------------
1525
1526}
General set of constants used in DENOPTIM.
static final String VERTEXJSONTAG
SDF tag containing vertex encoding in JSON format.
static final String GRAPHJSONTAG
SDF tag containing graph encoding in JSON format.
Class defining a space of building blocks.
static final Set< APClass > APCAROMBRIDGES
Conventional classes for of attachment points on aromatic-bridge vertexes.
Definition: APClass.java:126
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
AttachmentPoint getLinkedAP()
Gets the attachment point (AP) that is connected to this AP via the edge user.
APClass getAPClass()
Returns the Attachment Point class.
boolean sameAs(AttachmentPoint other)
Compares the features of this and another attachment point and decides if the two are same.
AttachmentPoint getLinkedAPThroughout()
Gets the attachment point (AP) that is connected to this AP via the edge user or in any edge user tha...
Edge getEdgeUser()
Gets the edge that is using this AP, or null if no edge is using this AP.
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
ArrayList< Ring > getRingsInvolvingVertex(Vertex v)
Returns the list of rings that include the given vertex in their fundamental cycle.
Definition: DGraph.java:1054
This class represents the edge between two vertices.
Definition: Edge.java:38
AttachmentPoint getSrcAPThroughout()
Definition: Edge.java:101
AttachmentPoint getTrgAP()
Definition: Edge.java:115
AttachmentPoint getSrcAP()
Definition: Edge.java:94
AttachmentPoint getTrgAPThroughout()
Definition: Edge.java:108
An empty vertex has the behaviors of a vertex, but has no molecular structure.
static EmptyVertex fromJson(String json)
Reads a JSON string and returns an instance of this class.
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
static Fragment fromJson(String json)
Reads a JSON string and returns an instance of this class.
Definition: Fragment.java:1228
This class represents the closure of a ring in a spanning tree.
Definition: Ring.java:40
Vertex getVertexAtPosition(int i)
Definition: Ring.java:107
A collection of AttachmentPoints that are related by a relation that we call "symmetry",...
static Template fromJson(String json)
Reads a JSON string and returns an instance of this class.
Definition: Template.java:1042
Vertex deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
Definition: Vertex.java:1315
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:62
ArrayList< Vertex > getChildrenThroughout()
Looks into the edges that use any of the APs that belong to this vertex and returns the list of verti...
Definition: Vertex.java:1145
boolean connectedTo(Vertex other)
Checks if this and another vertex are directly connected by an edge within the same graph recursion l...
Definition: Vertex.java:1495
abstract Vertex clone()
Returns a deep-copy of this vertex.
static Vertex parseVertexFromSDFFormat(IAtomContainer mol, Gson reader, BBType bbt)
Created a Vertex from the SDF representation, i.e., from an IAtomContainer.
Definition: Vertex.java:1454
Set< String > uniquefyingPropertyKeys
List of properties required to make Vertex#sameAs(Vertex, StringBuilder) method return false when pro...
Definition: Vertex.java:155
Map< Object, Object > properties
Map of customizable properties.
Definition: Vertex.java:148
void setMutationTypes(List< MutationType > lst)
Definition: Vertex.java:882
Map< Object, Object > getProperties()
Definition: Vertex.java:1207
List< MutationType > getMutationTypes()
Returns the list of mutation types.
Definition: Vertex.java:919
List< AttachmentPoint > getAPsWithAPClassStartingWith(String root)
Finds only APs that have APClass starting with the given string.
Definition: Vertex.java:261
void setProperties(Map< Object, Object > properties)
Definition: Vertex.java:1283
ArrayList< AttachmentPoint > getCappedAPs()
Gets attachment points that are used by capping groups.
Definition: Vertex.java:449
int getBuildingBlockId()
Returns the index of the building block that should correspond to the position of the building block ...
Definition: Vertex.java:305
static Vertex newVertexFromLibrary(long vertexId, int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Make a new vertex that is a copy of a vertex in the fragment space.
Definition: Vertex.java:232
abstract void setSymmetricAPSets(List< SymmetricAPs > sAPs)
abstract List< Vertex > getMutationSites(List< MutationType > ignoredTypes)
A list of mutation sites from within this vertex.
ArrayList< APClass > getAllAPClasses()
Returns the list of all APClasses present on this vertex.
Definition: Vertex.java:793
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:1060
void setVertexId(long vertexId2)
Definition: Vertex.java:282
ArrayList< AttachmentPoint > getCappedAPsThroughout()
Gets attachment points that are used by capping groups throughout the graph levels,...
Definition: Vertex.java:483
String[] getPathIDs(AttachmentPoint apA, AttachmentPoint apB)
Produces a pair of strings that identify the "path" between two given attachment points.
Definition: Vertex.java:1403
int getFreeAPCountThroughout()
Counts the number of attachment points that are availability throughout the graph level,...
Definition: Vertex.java:431
abstract boolean containsAtoms()
int getIndexOfAP(AttachmentPoint ap)
Returns the position of the given AP in the list of APs of this vertex.
Definition: Vertex.java:1037
void removeProperty(Object key)
Definition: Vertex.java:1247
String toString()
Produces a human readable, short string to represent the vertex by its vertex ID, building block ID (...
Definition: Vertex.java:632
Vertex(VertexType vertexType)
Constructor for an empty vertex.
Definition: Vertex.java:184
boolean hasSymmetricAP()
Definition: Vertex.java:614
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:1084
Vertex.BBType getBuildingBlockType()
Definition: Vertex.java:319
VertexType getVertexType()
Returns the value of the vertex type.
Definition: Vertex.java:1304
DGraph owner
Graph that includes this vertex.
Definition: Vertex.java:66
boolean isConnectedToAromaticBridge()
Checks if this vertex is connected to any vertex meant to be a piece of an aromatic system.
Definition: Vertex.java:583
List< MutationType > getUnfilteredMutationTypes()
Returns the mutation types that are constitutionally configures for this vertex irrespectively on the...
Definition: Vertex.java:896
List< Vertex > getMutationSites()
A list of mutation sites from within this vertex.
Definition: Vertex.java:863
List< MutationType > getMutationTypes(List< MutationType > excludedTypes)
Returns the list of mutation types.
Definition: Vertex.java:932
AttachmentPoint getAPWithId(int i)
Get attachment point that has the given identifier, or null.
Definition: Vertex.java:1019
void setAsRCV(boolean isRCV)
Definition: Vertex.java:275
void setGraphOwner(DGraph owner)
Definition: Vertex.java:841
DGraph getGraphOwner()
Returns the graph this vertex belongs to or null.
Definition: Vertex.java:852
int buildingBlockId
Index of this building block in the library of building blocks, or negative if this vertex is not par...
Definition: Vertex.java:77
BBType buildingBlockType
Definition: Vertex.java:138
Map< Object, Object > copyStringBasedProperties()
Copies all the string-based properties and properties defined in the Vertex#uniquefyingPropertyKeys s...
Definition: Vertex.java:1262
boolean isAromaticBridge()
Checks if this vertex is meant to be a piece of an aromatic system.
Definition: Vertex.java:564
boolean sameVertexFeatures(Vertex other, StringBuilder reason)
Compares this and another vertex ignoring vertex IDs.
Definition: Vertex.java:717
boolean sameAs(Vertex other, StringBuilder reason)
Compares this and another vertex ignoring vertex IDs.
Definition: Vertex.java:685
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:1173
ArrayList< APClass > getAllAvailableAPClasses()
Returns the list of all APClasses present on free attachment point on this vertex.
Definition: Vertex.java:815
abstract List< AttachmentPoint > getAttachmentPoints()
void setBuildingBlockId(int buildingBlockId)
Definition: Vertex.java:312
ArrayList< AttachmentPoint > getAPsFromChildren()
Looks into the edges that use any of the APs that belong to this vertex and returns the list of attac...
Definition: Vertex.java:1114
abstract List< SymmetricAPs > getSymmetricAPSets()
SymmetricAPs getSymmetricAPs(AttachmentPoint ap)
For the given attachment point index locate the symmetric partners i.e.
Definition: Vertex.java:354
Object getProperty(Object property)
Definition: Vertex.java:1224
abstract int getHeavyAtomsCount()
static Vertex convertIACToVertex(IAtomContainer iac, Vertex.BBType bbt)
Processes an IAtomContainer and builds a Vertex that is an instance of Fragment.
Definition: Vertex.java:1433
boolean hasProperty(Object property)
Definition: Vertex.java:1214
List< MutationType > allowedMutationTypes
List of mutations that we can perform on this vertex.
Definition: Vertex.java:160
static Vertex fromJson(String json)
Definition: Vertex.java:1290
void setUniquefyingProperty(String key)
Add the given key among the properties that are checked for equality when comparing vertices with the...
Definition: Vertex.java:1200
boolean removeMutationType(MutationType mt)
Removes the specified mutation type.
Definition: Vertex.java:908
boolean sameAs(Vertex other)
Compares this and another vertex ignoring vertex IDs.
Definition: Vertex.java:670
void setBuildingBlockType(Vertex.BBType buildingBlockType)
Definition: Vertex.java:326
int getCappedAPCountThroughout()
Counts the number of attachment points that are used by BBType#CAP vertex.
Definition: Vertex.java:514
abstract IAtomContainer getIAtomContainer(Logger logger, Randomizer rng, boolean removeUsedRCAs, boolean rebuild)
Method meant to trigger regeneration of the chemical representation, typically needed to drop a low q...
final VertexType vertexType
Field distinguishing implementations of Vertex when deserializing JSON representations.
Definition: Vertex.java:167
Vertex(VertexType vertexType, long id)
Constructor for an identified vertex without attachment points.
Definition: Vertex.java:200
abstract IAtomContainer getIAtomContainer()
boolean hasFreeAP()
Definition: Vertex.java:521
void setProperty(Object key, Object property)
Definition: Vertex.java:1236
long vertexId
Unique identifier associated with the vertex instance.
Definition: Vertex.java:71
ArrayList< AttachmentPoint > getFreeAPThroughout()
Gets attachment points that are availability throughout the graph level, i.e., checks also across the...
Definition: Vertex.java:403
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:1008
static Vertex newVertexFromLibrary(int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Builds a new molecular fragment kind of vertex.
Definition: Vertex.java:215
abstract void addSymmetricAPSet(SymmetricAPs symAPs)
Edge getEdgeWith(Vertex other)
Finds the edge between this and the other vertex, if it exists.
Definition: Vertex.java:1507
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final Set< APClass > RCAAPCLASSSET
Recognized APClass for RingClosingAttractor.
Class for de/serializing DENOPTIM graphs from/to JSON format.
Logger class for DENOPTIM.
static final Logger appLogger
Utilities for graphs.
Definition: GraphUtils.java:40
static synchronized long getUniqueVertexIndex()
Unique counter for the number of graph vertices generated.
Definition: GraphUtils.java:97
Tool to generate random numbers and random decisions.
Definition: Randomizer.java:35
The type of building block.
Definition: Vertex.java:87
static BBType parseInt(int i)
Translates the integer into the enum.
Definition: Vertex.java:104
Flag declaring the type of Vertex implementation.
Definition: Vertex.java:173
Types of mutation defined in relation to what happens to the target vertex (i.e., the actual mutation...
ADDFUSEDRING
Adds a subgraph that introduced a fused ring.
DELETE
Removes the target vertex and all child vertices.
DELETELINK
Removes a vertex from a tree and merges remaining branches into the remaining trunk.
CHANGELINK
Replace the target vertex keeping all the child structure.
EXTEND
append vertices on the target vertex according to substitution probability.
CHANGEBRANCH
Replace the target vertex and any of the child vertices.
ADDLINK
Adds a vertex between two previously connected vertexes.
ADDRING
Creates a ring-closure to add a ring.
DELETECHAIN
Removes a vertex and all its neighbors recursively until a branching point, i.e., until a vertex that...