$darkmode
DENOPTIM
AttachmentPoint.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Vishwesh Venkatraman <vishwesh.venkatraman@ntnu.no>
4 * and 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.util.HashMap;
23import java.util.LinkedHashMap;
24import java.util.List;
25import java.util.Map;
26import java.util.regex.Pattern;
27
28import javax.vecmath.Point3d;
29
30import org.openscience.cdk.interfaces.IAtom;
31
32import denoptim.constants.DENOPTIMConstants;
33import denoptim.exception.DENOPTIMException;
34import denoptim.graph.Edge.BondType;
35import denoptim.utils.GeneralUtils;
36
52public class AttachmentPoint implements Cloneable,Comparable<AttachmentPoint>
53{
57 private int id;
58
62 private int atomPositionNumber = -1;
63
68 private int atomPositionNumberInMol = -1;
69
74
78 private Point3d dirVec;
79
83 private Vertex owner;
84
88 private Edge user;
89
93 private int cutId;
94
98 private Map<Object, Object> properties;
99
100
101//------------------------------------------------------------------------------
102
108 {
109 this(owner, -1, null, null);
110 }
111
112//------------------------------------------------------------------------------
113
120 {
121 this(owner, atomPositionNumber, null, null);
122 }
123
124//------------------------------------------------------------------------------
125
134 Point3d dirVec)
135 {
136 this(owner, atomPositionNumber, dirVec, null);
137 }
138
139//------------------------------------------------------------------------------
140
149 //TODO: since APs can be on any vertex, and vertices are not required to
150 // contain atoms, the information of which atom is an AP rooted should be
151 // stored and managed by the implementation of vertex that do contain atoms.
152 // The DENOPTIMFragment should thus be charged with keeping the reference to
153 // the atom that holds the AP.
154
155
156 public AttachmentPoint(Vertex owner, int atomPosNum, APClass apClass)
157 {
158 this(owner, atomPosNum, null, apClass);
159 }
160
161//------------------------------------------------------------------------------
162
172 //TODO: since APs can be on any vertex, and vertices are not required to
173 // contain atoms, the information of which atom is an AP rooted should be
174 // stored and managed by the implementation of vertex that do contain atoms.
175 // The DENOPTIMFragment should thus be charged with keeping the reference to
176 // the atom that holds the AP.
177
178 public AttachmentPoint(Vertex owner, int atomPosNum, Point3d dirVec,
180 {
181 this.owner = owner;
182 id = owner.getUniqueAPIndex();
183 this.atomPositionNumber = atomPosNum;
184 this.apClass = apClass;
185 if (dirVec != null)
186 {
187 this.dirVec = new Point3d(dirVec.x, dirVec.y, dirVec.z);
188 }
189 }
190
191//------------------------------------------------------------------------------
192
200 public AttachmentPoint(Vertex owner, String str)
201 throws DENOPTIMException
202 {
203 this(owner);
204 Object[] features = processSdfString(str);
205 this.atomPositionNumber = (int) features[0];
206 this.apClass = (APClass) features[1];
207 this.dirVec = (Point3d) features[2];
208 }
209
210//-----------------------------------------------------------------------------
211
222 public static Object[] processSdfString(String str) throws DENOPTIMException
223 {
224 Object[] features = new Object[3];
225 try
226 {
227 String[] parts = str.split(
229
230 //WARNING here we convert from 1-based to 0-based index
231 features[0] = Integer.parseInt(parts[0])-1;
232
233 String[] details = parts[1].split(
235 switch (details.length)
236 {
237 case 2:
238 {
239 //OK, APClass:subclass but no direction vector and no bnd type
240 features[1] = APClass.make(details[0],Integer.parseInt(
241 details[1]));
242 break;
243 }
244
245 case 3:
246 {
247 //OK, APClass:subclass:direction_vector
248 // or APClass:subclass:BondType
249 features[1] = APClass.make(details[0],Integer.parseInt(
250 details[1]));
251
252 String[] coord = details[2].split(
253 Pattern.quote(DENOPTIMConstants.SEPARATORAPPROPXYZ));
254 switch (coord.length)
255 {
256 case 1:
257 // OK, APClass:subclass:BondType
258 features[1] = APClass.make(details[0],Integer.parseInt(
259 details[1]), BondType.valueOf(details[2]));
260 break;
261
262 case 3:
263 //OK, APClass:subclass:direction_vector
264 features[1] = APClass.make(details[0],Integer.parseInt(
265 details[1]));
266 features[2] = new Point3d(
267 Double.parseDouble(coord[0]),
268 Double.parseDouble(coord[1]),
269 Double.parseDouble(coord[2]));
270 break;
271 }
272 break;
273 }
274
275 case 4:
276 {
277 //OK, new format that includes bond type
278 features[1] = APClass.make(details[0],
279 Integer.parseInt(details[1]),
280 BondType.valueOf(details[2]));
281
282 String[] coord = details[3].split(
283 Pattern.quote(DENOPTIMConstants.SEPARATORAPPROPXYZ));
284
285 if (coord.length == 3)
286 {
287 features[2] = new Point3d(Double.parseDouble(coord[0]),
288 Double.parseDouble(coord[1]),
289 Double.parseDouble(coord[2]));
290 }
291 break;
292 }
293
294 default:
295 throw new DENOPTIMException("Unable to split APClass, "
296 + "subclass, and coordinates");
297 }
298 } catch (Throwable t) {
299 t.printStackTrace();
300 throw new DENOPTIMException("Cannot construct AP from string '"
301 + str + "'",t);
302 }
303 return features;
304 }
305
306//------------------------------------------------------------------------------
307
312 public int getID()
313 {
314 return id;
315 }
316
317//------------------------------------------------------------------------------
318
323 public void setID(int id)
324 {
325 this.id = id;
326 }
327
328//------------------------------------------------------------------------------
329
336 {
337 if (owner!=null && owner instanceof EmptyVertex)
338 return -1;
339 return atomPositionNumber;
340 }
341
342//------------------------------------------------------------------------------
343
350 {
351 this.atomPositionNumber = atomPositionNumber;
352 }
353
354//------------------------------------------------------------------------------
355
363 {
364 if (owner!=null && owner instanceof EmptyVertex)
365 return -1;
367 }
368
369//------------------------------------------------------------------------------
370
378 {
379 this.atomPositionNumberInMol = atomPositionNumberInMol;
380 }
381
382//------------------------------------------------------------------------------
383
391 {
392 if (apClass == null)
393 return APClass.DEFAULTBT;
394 else
395 return apClass.getBondType();
396 }
397
398//------------------------------------------------------------------------------
399
408 public void setDirectionVector(Point3d dirVec)
409 {
410 if (dirVec == null)
411 this.dirVec = null;
412 else
413 this.dirVec = new Point3d(dirVec.x, dirVec.y, dirVec.z);
414 }
415
416//------------------------------------------------------------------------------
417
424 public void setAPClass(String apClass) throws DENOPTIMException
425 {
426 this.apClass = APClass.make(apClass);
427 }
428
429//------------------------------------------------------------------------------
430
437 {
438 this.apClass = apClass;
439 }
440
441//------------------------------------------------------------------------------
442
448 {
449 return apClass;
450 }
451
452//------------------------------------------------------------------------------
453
459 public Point3d getDirectionVector()
460 {
461 return dirVec;
462 }
463
464//------------------------------------------------------------------------------
465
469 public int getCutId()
470 {
471 return cutId;
472 }
473
474//------------------------------------------------------------------------------
475
479 public void setCutId(int id)
480 {
481 this.cutId = id;
482 }
483
484//------------------------------------------------------------------------------
485
497 public boolean isAvailable()
498 {
499 return user == null;
500 }
501
502//------------------------------------------------------------------------------
503
518 public boolean isAvailableThroughout()
519 {
520 if (user == null)
521 {
522 if (owner != null && owner.getGraphOwner() != null
524 {
525 AttachmentPoint apProjOnTemplateSurface =
528 if (apProjOnTemplateSurface != null)
529 {
530 return apProjOnTemplateSurface.isAvailableThroughout();
531 } else {
532 throw new IllegalStateException("Available AP inside a"
533 + "template should have a projection on the "
534 + "surface of the template, "
535 + "but it has none. "
536 + "Please, report this to the authors.");
537 }
538 } else {
539 return true;
540 }
541 } else {
542 return false;
543 }
544 }
545
546//------------------------------------------------------------------------------
547
552 public boolean isClassEnabled()
553 {
554 return apClass != null;
555 }
556
557//------------------------------------------------------------------------------
558
566 @Override
567 public int compareTo(AttachmentPoint other)
568 {
569 return Integer.compare(this.getID(), other.getID());
570 }
571
572//------------------------------------------------------------------------------
573
582 {
583 final int BEFORE = -1;
584 final int EQUAL = 0;
585 final int AFTER = 1;
586
587 if (this == other)
588 return EQUAL;
589
590 if (this.sameAs(other))
591 return EQUAL;
592
593 //Compare source atom
594 if (this.getAtomPositionNumber() < other.getAtomPositionNumber())
595 return BEFORE;
596 else if (this.getAtomPositionNumber() > other.getAtomPositionNumber())
597 return AFTER;
598
599 //Compare APClass
600 if (this.getAPClass()!=null && other.getAPClass()!=null)
601 {
602 int res = this.apClass.compareTo(other.apClass);
603 if (res != 0)
604 return res;
605 }
606
607 //Compare Direction Vector if AtomID is equal
608 if (this.getDirectionVector() != null
609 && other.getDirectionVector() != null)
610 {
611 Point3d thisVec = this.getDirectionVector();
612 Point3d otherVec = other.getDirectionVector();
613
614 if (thisVec.x < otherVec.x)
615 {
616 return BEFORE;
617 } else if (thisVec.x > otherVec.x)
618 return AFTER;
619
620 if (thisVec.y < otherVec.y)
621 {
622 return BEFORE;
623
624 } else if (thisVec.y > otherVec.y)
625 return AFTER;
626
627 if (thisVec.z < otherVec.z)
628 {
629 return BEFORE;
630 } else if (thisVec.z > otherVec.z)
631 return AFTER;
632 }
633 else
634 {
635 if (this.getDirectionVector() != null)
636 {
637 return AFTER;
638 }
639 else
640 {
641 if (other.getDirectionVector() != null)
642 {
643 return BEFORE;
644 }
645 }
646 }
647
648 // We should have returned already
649 System.err.println("DENOPTIMAttachmentPoint.comparePropertiesTo "
650 + "inconsistent with sameAs. Please report this bug.");
651
652 return EQUAL;
653 }
654
655//------------------------------------------------------------------------------
656
664 public boolean sameAs(AttachmentPoint other)
665 {
666 return sameAs(other, new StringBuilder());
667 }
668
669//------------------------------------------------------------------------------
670
680 public boolean sameAs(AttachmentPoint other, StringBuilder reason)
681 {
682 if (this.getAtomPositionNumber() != other.getAtomPositionNumber())
683 {
684 reason.append("Different source atom for APs ("
685 + this.getAtomPositionNumber() + ","
686 + other.getAtomPositionNumber() + ");");
687 return false;
688 }
689
690 if (this.getIndexInOwner() != other.getIndexInOwner())
691 {
692 reason.append("Different index on list of APs ("
693 + this.getIndexInOwner() + ","
694 + other.getIndexInOwner() + ");");
695 return false;
696 }
697
698 if (this.getAPClass()!=null && other.getAPClass()!=null)
699 {
700 if (!this.getAPClass().equals(other.getAPClass()))
701 {
702 reason.append("Different APClass ("
703 + this.getAPClass() + ","
704 + other.getAPClass() + ");");
705 return false;
706 }
707 }
708
709 return true;
710 }
711
712//------------------------------------------------------------------------------
713
720 {
722 if (apClass == null)
723 {
724 if (dirVec == null)
725 {
726 ap =new AttachmentPoint(
727 getOwner(),
729 );
730 } else {
731 ap = new AttachmentPoint(
732 getOwner(),
734 dirVec
735 );
736 }
737 } else {
738 if (dirVec == null) {
739 ap = new AttachmentPoint(
740 getOwner(),
742 apClass.clone()
743 );
744 }
745 ap = new AttachmentPoint(
746 getOwner(),
748 dirVec,
749 apClass.clone());
750 }
751
752 if (properties != null)
753 {
754 for (Object key : properties.keySet())
755 {
756 Object value = properties.get(key);
757 if (!(key instanceof String) || !(value instanceof String))
758 {
759 throw new IllegalArgumentException("Unable to clone "
760 + "non-string "
761 + "property of attachment point (key: '" + key
762 + "'). Implement deep cloning of property "
763 + properties.get(key).getClass().getName());
764 }
765 String keyStr = ((String) key) + "";
766 String valueStr = ((String) value) + "";
767 ap.setProperty(keyStr, valueStr);
768 }
769 }
770 return ap;
771 }
772
773//------------------------------------------------------------------------------
774
789 public String getSingleAPStringSDF(boolean isFirst, int srcAtmID)
790 {
791 StringBuilder sb = new StringBuilder();
792 if (isFirst)
793 {
794 //WARNING! In the mol.property we use 1-to-n+1 instead of 0-to-n
795 int atmIdx = atomPositionNumber + 1;
796 if (srcAtmID>0)
797 {
798 atmIdx = srcAtmID;
799 }
800
801 sb.append(atmIdx);
803 }
804 sb.append(apClass.toSDFString());
805 if (dirVec != null)
806 {
808 sb.append(GeneralUtils.getEnglishFormattedDecimal("###.####",dirVec.x));
810 sb.append(GeneralUtils.getEnglishFormattedDecimal("###.####",dirVec.y));
812 sb.append(GeneralUtils.getEnglishFormattedDecimal("###.####",dirVec.z));
813 }
814 return sb.toString();
815 }
816
817//------------------------------------------------------------------------------
818
829 public String getSingleAPStringSDF(boolean isFirst)
830 {
831 return getSingleAPStringSDF(isFirst, -1);
832 }
833
834//------------------------------------------------------------------------------
835
841 public String toStringNoId()
842 {
843 Map<String,Object> pars = new HashMap<String,Object>();
844 pars.put("atomPositionNumber", atomPositionNumber);
845 if (apClass != null)
846 {
847 pars.put("apClass",apClass);
848 }
849 if (dirVec != null)
850 {
851 pars.put("dirVec.x",dirVec.x);
852 pars.put("dirVec.y",dirVec.y);
853 pars.put("dirVec.z",dirVec.z);
854 }
855
856 return pars.toString();
857 }
858
859//------------------------------------------------------------------------------
860
866 @Override
867 public String toString()
868 {
869 Map<String,Object> pars = new HashMap<String,Object>();
870 pars.put("atomPositionNumber", atomPositionNumber);
871 pars.put("id", id);
872 if (apClass != null)
873 {
874 pars.put("apClass",apClass);
875 }
876 if (dirVec != null)
877 {
878 pars.put("dirVec.x",dirVec.x);
879 pars.put("dirVec.y",dirVec.y);
880 pars.put("dirVec.z",dirVec.z);
881 }
882
883 return pars.toString();
884 }
885
886//-----------------------------------------------------------------------------
887
894 public void setOwner(Vertex owner) {
895 this.owner = owner;
896 }
897
898//-----------------------------------------------------------------------------
899
900 public Vertex getOwner() {
901 return owner;
902 }
903
904//-----------------------------------------------------------------------------
905
910 public void setUser(Edge edge) {
911 this.user = edge;
912 }
913
914//-----------------------------------------------------------------------------
915
929 public Edge getEdgeUser() {
930 return user;
931 }
932
933//------------------------------------------------------------------------------
934
949 {
950 if (user == null)
951 {
952 if (owner != null
953 && owner.getGraphOwner() != null
956 .getOuterAPFromInnerAP(this) != null)
957 {
960 }
961 }
962 return user;
963 }
964
965//-----------------------------------------------------------------------------
966
976 {
977 if (owner != null && owner instanceof Template)
978 {
979 AttachmentPoint embeddedAP =
980 ((Template)owner).getInnerAPFromOuterAP(this);
981 //NB: if embeddedAP has no further embedding it returns itself
982 return embeddedAP.getEmbeddedAP();
983 } else {
984 return this;
985 }
986 }
987
988//-----------------------------------------------------------------------------
989
996 {
997 if (user == null)
998 return null;
999
1000 if (user.getSrcAP() == this)
1001 {
1002 return user.getTrgAP();
1003 } else if (user.getTrgAP() == this)
1004 {
1005 return user.getSrcAP();
1006 }
1007 return null;
1008 }
1009
1010//-----------------------------------------------------------------------------
1011
1023 {
1025 if (user == null)
1026 {
1027 return null;
1028 }
1029 if (user.getSrcAPThroughout() == this.getEmbeddedAP()
1030 || user.getSrcAP() == this)
1031 {
1032 return user.getTrgAP();
1033 } else if (user.getTrgAPThroughout() == this.getEmbeddedAP()
1034 || user.getTrgAP() == this)
1035 {
1036 return user.getSrcAP();
1037 }
1038 return null;
1039 }
1040
1041//-----------------------------------------------------------------------------
1042
1052 public boolean isSrcInUserThroughout()
1053 {
1055 if (user == null)
1056 {
1057 return false;
1058 }
1059 return user.getSrcAPThroughout() == this || user.getSrcAP() == this;
1060 }
1061
1062//-----------------------------------------------------------------------------
1063
1071 public boolean isSrcInUser()
1072 {
1073 return user != null && user.getSrcAP() == this;
1074 }
1075
1076//-----------------------------------------------------------------------------
1077
1082 public int getIndexInOwner()
1083 {
1084 if (owner == null)
1085 {
1086 return -1;
1087 }
1088 return owner.getIndexOfAP(this);
1089 }
1090
1091//------------------------------------------------------------------------------
1092
1093 public boolean hasSameSrcAtom(AttachmentPoint other)
1094 {
1095 AttachmentPoint deepThis = getEmbeddedAP();
1096 AttachmentPoint deepOther = other.getEmbeddedAP();
1097 Vertex deepOwnerT = deepThis.getOwner();
1098 Vertex deepOwnerO = deepOther.getOwner();
1099
1100 if (deepOwnerT instanceof Fragment
1101 && deepOwnerO instanceof Fragment)
1102 {
1103 IAtom srcThis = ((Fragment) deepOwnerT).getAtomHoldingAP(
1104 deepThis);
1105 IAtom srcOther = ((Fragment) deepOwnerO).getAtomHoldingAP(
1106 deepOther);
1107
1108 if (srcThis == srcOther)
1109 {
1110 return true;
1111 }
1112 }
1113 return false;
1114 }
1115
1116//------------------------------------------------------------------------------
1117
1129 {
1130 AttachmentPoint deepThis = getEmbeddedAP();
1131 AttachmentPoint deepOther = other.getEmbeddedAP();
1132 Vertex deepOwnerT = deepThis.getOwner();
1133 Vertex deepOwnerO = deepOther.getOwner();
1134
1135 if (deepOwnerT instanceof Fragment
1136 && deepOwnerO instanceof Fragment)
1137 {
1138 IAtom srcThis = ((Fragment) deepOwnerT).getAtomHoldingAP(
1139 deepThis);
1140 IAtom srcOther = ((Fragment) deepOwnerO).getAtomHoldingAP(
1141 deepOther);
1142
1143 if (srcThis.getContainer() == srcOther.getContainer())
1144 {
1145 if (srcThis.getContainer().getConnectedAtomsList(srcThis)
1146 .contains(srcOther))
1147 {
1148 return true;
1149 }
1150 } else {
1151 // If the two atoms are not directly connected, they
1152 // might be connected via an edge in the graph.
1153 List<AttachmentPoint> apsOnSrcThis =
1154 ((Fragment)deepOwnerT).getAPsFromAtom(srcThis);
1155 List<AttachmentPoint> apsOnSrcOther =
1156 ((Fragment)deepOwnerT).getAPsFromAtom(srcOther);
1157 for (AttachmentPoint apOnSrcThis : apsOnSrcThis)
1158 {
1159 // We ignore the connection deepThis-to-deepOther
1160 if (apOnSrcThis.isAvailableThroughout()
1161 || apOnSrcThis==deepThis)
1162 continue;
1163
1164 AttachmentPoint linkedAP =
1165 apOnSrcThis.getLinkedAPThroughout().getEmbeddedAP();
1166 for (AttachmentPoint apOnSrcOther : apsOnSrcOther)
1167 {
1168 if (apOnSrcOther.isAvailableThroughout()
1169 || apOnSrcOther==deepOther)
1170 continue;
1171 if (linkedAP==apOnSrcOther)
1172 {
1173 return true;
1174 }
1175 }
1176 }
1177 }
1178 }
1179 return false;
1180 }
1181
1182//------------------------------------------------------------------------------
1183
1184 public Map<Object,Object> getProperties()
1185 {
1186 return properties;
1187 }
1188
1189//------------------------------------------------------------------------------
1190
1191 public Object getProperty(Object description)
1192 {
1193 if (properties == null)
1194 {
1195 return null;
1196 } else {
1197 return properties.get(description);
1198 }
1199 }
1200
1201//------------------------------------------------------------------------------
1202
1203 public void setProperty(Object key, Object property)
1204 {
1205 if (properties == null)
1206 {
1207 properties = new HashMap<Object, Object>();
1208 }
1209 properties.put(key, property);
1210 }
1211
1212//------------------------------------------------------------------------------
1213
1226 // WARNING: here is a place where we still assume a fixed order of APs
1227 // In fact, the order in which we process the keys is given by the comparable
1228 // class Integer, i.e., the APs are reported in SDF following the ordering
1229 // of the respective source atoms.
1230 // To solve the issue of ordering we could drop the format in which we
1231 // collect APs by source atom (i.e., 1#firstAP,second-AP) and allow for
1232 // a one-to-one (sorted) list of APs where "1#firstAP,second-AP" becomes
1233 // "1#firstAP 1#second-AP"
1234
1235 public static String getAPDefinitionsForSDF(
1236 LinkedHashMap<Integer, List<AttachmentPoint>> apsPerIndex)
1237 {
1238 String s = "";
1239 for (Integer ii : apsPerIndex.keySet())
1240 {
1241 //WARNING: here is the 1-based criterion implemented also for
1242 // fake atom IDs!
1243 int atmID = ii+1;
1244
1245 List<AttachmentPoint> apsOnAtm = apsPerIndex.get(ii);
1246
1247 boolean firstCL = true;
1248 for (int i = 0; i<apsOnAtm.size(); i++)
1249 {
1250 AttachmentPoint ap = apsOnAtm.get(i);
1251
1252 //Build SDF property DENOPTIMConstants.APCVTAG
1253 String stingAPP = ""; //String Attachment Point Property
1254 if (firstCL)
1255 {
1256 firstCL = false;
1257 stingAPP = ap.getSingleAPStringSDF(true,atmID);
1258 } else {
1259 stingAPP = DENOPTIMConstants.SEPARATORAPPROPAPS
1260 + ap.getSingleAPStringSDF(false,atmID);
1261 }
1262 s = s + stingAPP;
1263 }
1265 }
1266 return s;
1267 }
1268
1269//-----------------------------------------------------------------------------
1270
1271}
General set of constants used in DENOPTIM.
static final String SEPARATORAPPROPAAP
Separator between atom index and APClass in molecular property.
static final String SEPARATORAPPROPATMS
Separator between APs on different atoms in molecular property.
static final String SEPARATORAPPROPSCL
Separator between APClass and APSubClass and coordinates.
static final String SEPARATORAPPROPXYZ
Separator between coordinates.
APClass clone()
WARNING: this method does NOT clone! It just returns the reference to this.
Definition: APClass.java:481
int compareTo(APClass o)
Definition: APClass.java:463
BondType getBondType()
Definition: APClass.java:341
static final BondType DEFAULTBT
Default bond type for all but APClasses of RCVs.
Definition: APClass.java:109
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
Definition: APClass.java:136
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.
AttachmentPoint(Vertex owner)
Constructor for undefined DENOPTIMAttachmentPoint.
Map< Object, Object > properties
Map of customisable properties.
Object getProperty(Object description)
AttachmentPoint getEmbeddedAP()
For vertices that are templates this method returns the attachment point that is embedded in the temp...
void setAPClass(String apClass)
Set the Attachment Point class.
AttachmentPoint(Vertex owner, int atomPositionNumber)
Constructor.
Point3d dirVec
The direction vector representing the bond direction.
void setUser(Edge edge)
Sets the reference to the edge that is using this attachment point.
int comparePropertiesTo(AttachmentPoint other)
Compares this and given attachment point.
Vertex owner
The vertex to which this AP is attached to.
APClass getAPClass()
Returns the Attachment Point class.
Edge user
The edge that is using this AP, if any.
String toString()
Produces a string with the information included in this object.
int atomPositionNumber
The index of the source atom in the atom list of the fragment (0-based)
int cutId
Identifier of the cut operation that generated this AP.
boolean isClassEnabled()
Checks if this attachment point respects the APClass-based approach.
AttachmentPoint(Vertex owner, int atomPosNum, APClass apClass)
Constructor.
void setAtomPositionNumber(int atomPositionNumber)
Set the index of the source atom in the list of atoms of the fragment.
AttachmentPoint(Vertex owner, String str)
Construct an attachment point based on the formatted string representation.
void setDirectionVector(Point3d dirVec)
Sets the end of the 3D vector defining the direction of the AP in 3D.
int getID()
Returns a unique integer that is used to sort list of attachment points.
APClass apClass
The attachment point class.
void setOwner(Vertex owner)
Sets the reference to the vertex that owns this attachment point.
BondType getBondType()
Returns the bond type preferred by this attachment point as defined by the APClass,...
boolean isAvailable()
Check availability of this attachment point.
AttachmentPoint(Vertex owner, int atomPosNum, Point3d dirVec, APClass apClass)
Constructor.
int getAtomPositionNumberInMol()
The index of the source atom in the atom list of the entire molecule.
int getAtomPositionNumber()
The index of the source atom in the atom list of the fragment.
boolean isSrcInUserThroughout()
Checks the role of this AP in the user or in any user that might be external to the template embeddin...
static Object[] processSdfString(String str)
Parses the string format used to record one attachment point in SDF files.
void setAtomPositionNumberInMol(int atomPositionNumberInMol)
Set the index of the source atom in the list of atoms of the entire molecule.
int id
Index used to keep the order in a list of attachment points.
AttachmentPoint clone()
Returns a deep clone of this attachment point.
void setAPClass(APClass apClass)
Set the Attachment Point class.
void setID(int id)
Sets the unique integer that is used to sort list of attachment points.
boolean isAvailableThroughout()
Check availability of this attachment point throughout the graph level, i.e., check also across the i...
Point3d getDirectionVector()
Returns the end of the direction vector.
Edge getEdgeUserThroughout()
Gets the edge that is using this AP, or null if no edge is using this AP.
boolean hasConnectedSrcAtom(AttachmentPoint other)
Checks if this and another APs are rooted on atoms that are bonded in any way other than a possible c...
Map< Object, Object > getProperties()
boolean isSrcInUser()
Checks the role of this AP in the user.
boolean sameAs(AttachmentPoint other)
Compares the features of this and another attachment point and decides if the two are same.
AttachmentPoint(Vertex owner, int atomPositionNumber, Point3d dirVec)
Constructor.
boolean hasSameSrcAtom(AttachmentPoint other)
String getSingleAPStringSDF(boolean isFirst)
Prepare a string for writing this AP in a fragment SDF file.
static String getAPDefinitionsForSDF(LinkedHashMap< Integer, List< AttachmentPoint > > apsPerIndex)
Prepares the two strings that can be used to define AttachmentPoints in SDF files.
int atomPositionNumberInMol
The index of the source atom in the atom list of the entire molecule (0-based)
AttachmentPoint getLinkedAPThroughout()
Gets the attachment point (AP) that is connected to this AP via the edge user or in any edge user tha...
String getSingleAPStringSDF(boolean isFirst, int srcAtmID)
Prepare a string for writing this AP in a fragment SDF file.
int compareTo(AttachmentPoint other)
Compares this and another attachment points based on their unique identifier.
void setProperty(Object key, Object property)
Edge getEdgeUser()
Gets the edge that is using this AP, or null if no edge is using this AP.
String toStringNoId()
Produces a string with the information included in this object.
boolean sameAs(AttachmentPoint other, StringBuilder reason)
Compares the features of this and another attachment point and decides if the two are same.
Template templateJacket
Reference to the Template embedding this graph.
Definition: DGraph.java:149
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.
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
AttachmentPoint getOuterAPFromInnerAP(AttachmentPoint innerAP)
Definition: Template.java:828
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
int getIndexOfAP(AttachmentPoint ap)
Returns the position of the given AP in the list of APs of this vertex.
Definition: Vertex.java:949
DGraph getGraphOwner()
Returns the graph this vertex belongs to or null.
Definition: Vertex.java:779
static String getEnglishFormattedDecimal(String pattern, int decimals, double value)
Formats a decimal number using the given pattern but with English format as for separators.
Possible chemical bond types an edge can represent.
Definition: Edge.java:303