forked from duartegroup/autodE
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconstraints.py
91 lines (66 loc) · 2.54 KB
/
constraints.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from typing import Optional, Dict, List
from autode.log import logger
class Constraints:
def __str__(self):
"""String of constraints"""
string = ''
if self.cartesian is not None:
string += str(self.cartesian)
if self.distance is not None:
string += str({key: round(val, 3)
for key, val in self.distance.items()})
return f'Constraints({string})'
def __repr__(self):
return self.__str__()
@staticmethod
def _init_distance(dist_constraints: Dict):
"""Initialise the distance constraints"""
assert type(dist_constraints) is dict
distance = {}
for key, val in dist_constraints.items():
if len(set(key)) != 2:
logger.warning('Can only set distance constraints between '
f'two distinct atoms. Had {key} - skipping')
continue
if float(val) < 0:
raise ValueError('Negative distances are not valid'
' constraints!')
distance[tuple(sorted(key))] = float(val)
return distance
@property
def distance(self) -> Optional[dict]:
return None if len(self._distance) == 0 else self._distance
@property
def cartesian(self) -> list:
return None if len(self._cartesian) == 0 else list(set(self._cartesian))
@property
def any(self):
"""Are there any constraints?"""
return self.distance is not None or self.cartesian is not None
def update(self,
distance: Optional[Dict] = None,
cartesian: Optional[List] = None) -> None:
"""
Update the current set of constraints with a new distance and or
Cartesian set
Arguments:
distance (dict):
cartesian (list):
"""
if distance is not None:
self._distance.update(self._init_distance(distance))
if cartesian is not None:
self._cartesian += cartesian
return None
def __init__(self,
distance: Optional[Dict] = None,
cartesian: Optional[List] = None):
"""
Arguments:
distance (dict | None): Keys of: tuple(int) for two atom indexes
and values of the distance in Å, or None
cartesian (list(int) | None): List of atom indexes or None
"""
self._distance = {}
self._cartesian = []
self.update(distance, cartesian)