$darkmode
DENOPTIM
APClass.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2022 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.graph;
20
21import java.lang.reflect.Type;
22import java.util.ArrayList;
23import java.util.Collections;
24import java.util.HashSet;
25import java.util.List;
26import java.util.Set;
27
28import com.google.gson.JsonDeserializationContext;
29import com.google.gson.JsonDeserializer;
30import com.google.gson.JsonElement;
31import com.google.gson.JsonObject;
32import com.google.gson.JsonParseException;
33
34import denoptim.constants.DENOPTIMConstants;
35import denoptim.exception.DENOPTIMException;
36import denoptim.fragspace.FragmentSpace;
37import denoptim.graph.Edge.BondType;
38import denoptim.graph.rings.RingClosingAttractor;
39
40public class APClass implements Cloneable,Comparable<APClass>
41{
46 private String rule;
47
52 private int subClass;
53
57 public static Set<APClass> uniqueAPClasses = new HashSet<APClass>();
58
63 private final static Object uniqueAPClassesLock = new Object();
64
68 public static final String ATPLUS = "ATplus";
69
73 public static final String ATMINUS = "ATminus";
74
78 public static final String ATNEUTRAL = "ATneutral";
79
84 public static final APClass RCACLASSPLUS = getUnique(ATPLUS, 0,
86
91 public static final APClass RCACLASSMINUS = getUnique(ATMINUS, 0,
93
98 public static final APClass RCACLASSNEUTRAL = getUnique(ATNEUTRAL, 0,
100
105
109 public static final BondType DEFAULTBT = BondType.SINGLE;
110
111//------------------------------------------------------------------------------
112
116 public APClass()
117 {}
118
119//------------------------------------------------------------------------------
120
136 public static APClass make(String ruleAndSubclass) throws DENOPTIMException
137 {
138 if (!isValidAPClassString(ruleAndSubclass))
139 {
140 throw new DENOPTIMException("Attempt to use APClass '"
141 + ruleAndSubclass
142 + "' that does not respect syntax <rule>"
143 + DENOPTIMConstants.SEPARATORAPPROPSCL + "<subClass>.");
144 }
145 String[] parts = ruleAndSubclass.split(
147 return make(parts[0], Integer.parseInt(parts[1]));
148 }
149
150//------------------------------------------------------------------------------
151
169 public static APClass make(String rule, int subClass)
170 throws DENOPTIMException
171 {
172 return make(rule, subClass, DEFAULTBT);
173 }
174
175 //------------------------------------------------------------------------------
176
191 public static APClass make(String ruleAndSubclass, BondType bt)
192 throws DENOPTIMException
193 {
194 if (!isValidAPClassString(ruleAndSubclass))
195 {
196 throw new DENOPTIMException("Attempt to use APClass '"
197 + ruleAndSubclass
198 + "' that does not respect syntax <rule>"
199 + DENOPTIMConstants.SEPARATORAPPROPSCL + "<subClass>.");
200 }
201 String[] parts = ruleAndSubclass.split(
203 return make(parts[0], Integer.parseInt(parts[1]), bt);
204 }
205
206//------------------------------------------------------------------------------
207
221 public static APClass make(String rule, int subClass, BondType bt)
222 throws DENOPTIMException
223 {
225 return getUnique(rule, subClass, bt);
226 } else {
227 throw new DENOPTIMException("Invalid sttempt to make APClass out "
228 + "of '" + rule + "' and '" + subClass + "'.");
229 }
230 }
231
232//------------------------------------------------------------------------------
233
242 private static APClass getUnique(String rule, int subClass, BondType bt)
243 {
244 APClass newApc = new APClass();
245 synchronized (uniqueAPClassesLock)
246 {
247 boolean found = false;
248 for (APClass existingApc : uniqueAPClasses)
249 {
250 if (existingApc.getRule().equals(rule)
251 && existingApc.getSubClass()==subClass)
252 {
253 newApc = existingApc;
254 found = true;
255 break;
256 }
257 }
258 if (!found)
259 {
260 newApc.setRule(rule);
261 newApc.setSubClass(subClass);
262 newApc.setBondType(bt);
263 } else {
264 // NB: the default bond type for RCAs must not be changed, but
265 // For non-RCA APClasses we do update the bond type.
266 if (bt != newApc.bndTyp && !RingClosingAttractor.RCAAPCLASSSET.contains(newApc))
267 {
268 System.err.println("WARNING! Changing bond order of "
269 + "APClass " + newApc + ": " + newApc.bndTyp
270 + " -> " + bt);
271 newApc.setBondType(bt);
272 }
273 }
274 uniqueAPClasses.add(newApc);
275 }
276 return newApc;
277 }
278
279//------------------------------------------------------------------------------
280
281 private void setBondType(BondType bt) {
282 this.bndTyp = bt;
283 }
284
285//------------------------------------------------------------------------------
286
287 private void setRule(String rule) {
288 this.rule = rule;
289 }
290
291//------------------------------------------------------------------------------
292
293 private void setSubClass(int sumClass) {
294 this.subClass = sumClass;
295 }
296
297//------------------------------------------------------------------------------
298
303 public static List<String> getAllAPClassesAsString()
304 {
305 List<String> names = new ArrayList<String>();
306 for (APClass apc : uniqueAPClasses)
307 {
308 names.add(apc.toString());
309 }
310 Collections.sort(names);
311 return names;
312 }
313
314//------------------------------------------------------------------------------
315
321 public String getRule() {
322 return rule;
323 }
324
325//------------------------------------------------------------------------------
326
332 public int getSubClass() {
333 return subClass;
334 }
335
336//------------------------------------------------------------------------------
337
342 return bndTyp;
343 }
344
345//------------------------------------------------------------------------------
346
352 public String toString() {
353 return rule + DENOPTIMConstants.SEPARATORAPPROPSCL
354 + Integer.toString(subClass);
355 }
356
357//------------------------------------------------------------------------------
358
364 public String toSDFString() {
365 return rule + DENOPTIMConstants.SEPARATORAPPROPSCL
366 + Integer.toString(subClass)
367 + DENOPTIMConstants.SEPARATORAPPROPSCL
368 + bndTyp;
369 }
370
371//------------------------------------------------------------------------------
372
381 public static boolean isValidAPSubCLassString(String s)
382 {
383 return s.matches("^[0-9]*$");
384 }
385
386//------------------------------------------------------------------------------
387
396 public static boolean isValidAPRuleString(String s)
397 {
398 if (s == null)
399 return false;
400 return s.matches("^[a-zA-Z0-9_-]+$");
401 }
402
403//------------------------------------------------------------------------------
404
412 public static boolean isValidAPClassString(String s)
413 {
414 if (!s.matches("^[a-z,A-Z,0-9].*"))
415 return false;
416
417 if (!s.matches(".*[0-9]$"))
418 return false;
419
420 if (s.contains(" "))
421 return false;
422
423 if (!s.contains(DENOPTIMConstants.SEPARATORAPPROPSCL))
424 return false;
425
426 int numSep = 0;
427 for (int i=0; i<s.length(); i++)
428 {
429 if (s.charAt(i) == DENOPTIMConstants.SEPARATORAPPROPSCL.charAt(0))
430 {
431 numSep++;
432 }
433 }
434 if (numSep != 1)
435 return false;
436
437 String apRule = s.split(DENOPTIMConstants.SEPARATORAPPROPSCL)[0];
438 String sub = s.split(DENOPTIMConstants.SEPARATORAPPROPSCL)[1];
439
440 return APClass.isValidAPRuleString(apRule)
442 }
443
444//------------------------------------------------------------------------------
445
455 public boolean isCPMapCompatibleWith(APClass other, FragmentSpace fragSpace)
456 {
457 return fragSpace.getCompatibleAPClasses(this).contains(other);
458 }
459
460//------------------------------------------------------------------------------
461
462 @Override
463 public int compareTo(APClass o)
464 {
465 int ruleComparison = this.rule.compareTo(o.rule);
466 if (ruleComparison == 0) {
467 return Integer.compare(this.subClass, o.subClass);
468 } else {
469 return ruleComparison;
470 }
471 }
472
473//------------------------------------------------------------------------------
474
480 @Override
481 public APClass clone() {
482 return this;
483 }
484
485//------------------------------------------------------------------------------
486
487 @Override
488 public boolean equals(Object o) {
489 if (!(o instanceof APClass)) {
490 return false;
491 }
492 return this.hashCode() == o.hashCode();
493 }
494
495//------------------------------------------------------------------------------
496
497 public static class APClassDeserializer
498 implements JsonDeserializer<APClass>
499 {
500 @Override
501 public APClass deserialize(JsonElement json, Type typeOfT,
502 JsonDeserializationContext context) throws JsonParseException
503 {
504 JsonObject jo = json.getAsJsonObject();
505 APClass apc = null;
506 if (jo.has("bndTyp"))
507 {
508 apc = getUnique(jo.get("rule").getAsString(),
509 jo.get("subClass").getAsInt(),
510 context.deserialize(jo.get("bndTyp"),BondType.class));
511 } else {
512 //Only for conversion to V3
513 String rule = jo.get("rule").getAsString();
514 int subClass = jo.get("subClass").getAsInt();
515 boolean found = false;
516 for (APClass existingApc : uniqueAPClasses)
517 {
518 if (existingApc.getRule().equals(rule)
519 && existingApc.getSubClass()==subClass)
520 {
521 apc = existingApc;
522 found = true;
523 break;
524 }
525 }
526 if (!found)
527 {
528 System.out.println("WARNING! Setting " + DEFAULTBT
529 + " for "+rule+":"+subClass);
530 apc = getUnique(jo.get("rule").getAsString(),
531 jo.get("subClass").getAsInt(), DEFAULTBT);
532 }
533 }
534 return apc;
535 }
536 }
537
538//------------------------------------------------------------------------------
539
540}
541
General set of constants used in DENOPTIM.
static final String SEPARATORAPPROPSCL
Separator between APClass and APSubClass and coordinates.
Class defining a space of building blocks.
ArrayList< APClass > getCompatibleAPClasses(APClass apc)
Returns a list of APClasses compatible with the given APClass.
APClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
Definition: APClass.java:501
static List< String > getAllAPClassesAsString()
Returns the list of the names of all APClasses.
Definition: APClass.java:303
boolean isCPMapCompatibleWith(APClass other, FragmentSpace fragSpace)
Check compatibility as defined in the compatibility matrix considering this AP as source and the othe...
Definition: APClass.java:455
APClass clone()
WARNING: this method does NOT clone! It just returns the reference to this.
Definition: APClass.java:481
static final APClass RCACLASSPLUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:84
static APClass make(String rule, int subClass)
Constructor for an APClass with default bond type (i.e., BondType#DEFAULTBT).
Definition: APClass.java:169
static final String ATNEUTRAL
String defining a conventional APClass.
Definition: APClass.java:78
static APClass make(String ruleAndSubclass, BondType bt)
Constructor for a fully defined APClass.
Definition: APClass.java:191
static APClass make(String rule, int subClass, BondType bt)
Constructor for a fully defined APClass.
Definition: APClass.java:221
boolean equals(Object o)
Definition: APClass.java:488
static final Object uniqueAPClassesLock
Synchronization lock.
Definition: APClass.java:63
BondType bndTyp
Bond type to use when converting edge users into formal bonds.
Definition: APClass.java:104
static final APClass RCACLASSMINUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:91
int compareTo(APClass o)
Definition: APClass.java:463
static boolean isValidAPClassString(String s)
Evaluate is a candidate string can be used as APClass.
Definition: APClass.java:412
static boolean isValidAPRuleString(String s)
Evaluates the given string as a candidate attachment point rule, i.e., as name of a fragmentation rul...
Definition: APClass.java:396
static final String ATMINUS
String defining a conventional APClass.
Definition: APClass.java:73
String rule
The main feature of the APClass.
Definition: APClass.java:46
BondType getBondType()
Definition: APClass.java:341
static final BondType DEFAULTBT
Default bond type for all but APClasses of RCVs.
Definition: APClass.java:109
void setBondType(BondType bt)
Definition: APClass.java:281
static final String ATPLUS
String defining a conventional APClass.
Definition: APClass.java:68
APClass()
Constructor for an empty APClass.
Definition: APClass.java:116
void setSubClass(int sumClass)
Definition: APClass.java:293
static boolean isValidAPSubCLassString(String s)
Evaluate the given string as a candidate for attachment point subclass, i.e., the attachment point cl...
Definition: APClass.java:381
int subClass
The secondary feature of the APClass.
Definition: APClass.java:52
String toString()
Do not use this to make SDF representations.
Definition: APClass.java:352
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
static final APClass RCACLASSNEUTRAL
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:98
void setRule(String rule)
Definition: APClass.java:287
static Set< APClass > uniqueAPClasses
Set unique APClasses.
Definition: APClass.java:57
static APClass getUnique(String rule, int subClass, BondType bt)
Checks if there is already a instance with the given members, if not it created one.
Definition: APClass.java:242
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final Set< APClass > RCAAPCLASSSET
Recognized APClass for RingClosingAttractor.
Possible chemical bond types an edge can represent.
Definition: Edge.java:303