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