/
misc.py
203 lines (161 loc) · 4.92 KB
/
misc.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
"""
Misc. functions
"""
import numpy as np
# default tolerences
RTOL = 1.001e-01
ATOL = 1.001e-01
DTOL = 1.001e-01
def pair_similar(dic1, data1, dic2, data2, verb=False, atol=ATOL, rtol=RTOL,
dtol=DTOL):
"""
Check a dic, data pair against a second dic, data pair for differences.
Parameters
----------
dic1 : dict
First dictionary of NMR parameters.
data1 : ndarray
First array of NMR data
dic2 : dict
Second dictionary of NMR parameters
data2 : ndarray
Second array of NMR data
verb : bool, optional
Set True for verbose reporting.
atol : float, optional
The absolute tolerent parameter to pass to numpy.allclose.
rtol : float, optional
The relative tolenance parameter to pass to numpy.allclose.
Returns
-------
r1 : bool
True is data1 and data2 are similar, False if they differ.
r2 : bool
True is dic1 and dic2 are similar, False if they differ.
"""
r1 = isdatasimilar(data1, data2, verb, atol, rtol)
r2 = isdicsimilar(dict(dic1), dict(dic2), verb, dtol)
return r1, r2
def isdatasimilar(data1, data2, verb=False, atol=ATOL, rtol=RTOL):
"""
Check that two sets of NMR data are equal within a tolerance.
Parameters
----------
data1 : ndarray
First array of NMR data
data2 : ndarray
Second array of NMR data
verb : bool, optional
Set True for verbose reporting.
atol : float, optional
The absolute tolerent parameter to pass to numpy.allclose.
rtol : float, optional
The relative tolenance parameter to pass to numpy.allclose.
Returns
-------
r1 : bool
True is data1 and data2 are similar, False if they differ.
"""
r = True
if data1.dtype != data2.dtype:
r = False
if verb:
print "Dtypes do not match:", data1.dtype, data2.dtype
if data1.shape != data2.shape:
r = False
if verb:
print "Shapes do not match:", data1.shape, data2.shape
if np.allclose(data1, data2, rtol=rtol, atol=atol) == False:
r = False
if verb:
print "Data does not match"
return r
def isitemsimilar(v1, v2, verb=False, dtol=DTOL):
"""
Compare two values for differences
See :py:func:`isdicsimilar` for Parameters.
"""
r = True
# type checking
if type(v1) != type(v2):
r = False
if verb:
print "Item has different type", type(v1), type(v2)
# iterable checking
elif isinstance(v1, dict):
r = r and isdicsimilar(v1, v2, verb=verb, dtol=dtol)
elif isinstance(v1, list):
r = r and islistsimilar(v1, v2, verb=verb, dtol=dtol)
# numeric type
elif isinstance(v1, (int, float)):
if abs(v1 - v2) > dtol:
r = False
if verb:
print "Key mismatch:", v1, v2
# all other types: just check if equal
else:
if v1 != v2:
r = False
if verb:
print "Key mismatch:", v1, v2
return r
def isdicsimilar(dic1, dic2, verb=False, dtol=DTOL):
"""
Compare two dictionaries for differences
Float and int types compared within dtol. Lists and dictionaries are
checked recursively all other checked by simple equivalence
Parameters
----------
dic1 : dict
First dictionary of NMR parameters.
dic2 : dict
Second dictionary of NMR parameters
verb : bool, optional
Set True for verbose reporting.
dtol : float, optional
Maximum allowable difference between int and float elements if dic1
and dic2.
Returns
-------
r1 : bool
True is dic1 and dic2 are similar, False if they differ.
"""
# create copies of the two dictionaries
dic1 = dict(dic1)
dic2 = dict(dic2)
# set return value to True
r = True
# create sets
kset1 = set(dic1.keys())
kset2 = set(dic2.keys())
dset = set.difference(kset1, kset2)
iset = set.intersection(kset1, kset2)
# print out any keys not in both dictionaries
if len(dset) != 0:
r = False
if verb:
print "Keys not in both dictionaries:", dset
# loop over keys in both sets
for k in iset:
v1, v2 = dic1[k], dic2[k]
if not isitemsimilar(v1, v2, verb=verb, dtol=dtol):
print "For key:", k
r = False
return r
def islistsimilar(l1, l2, verb=False, dtol=DTOL):
"""
Compare two lists (or iterable) for differences
See :py:func:`isdicsimilar` for Parameters.
"""
# set return value to True
r = True
# print out any keys not in both dictionaries
if len(l1) != len(l2):
r = False
if verb:
print "Lists not of same length:", len(l1), len(l2)
# loop over keys in both sets
for v1, v2 in zip(l1, l2):
if not isitemsimilar(v1, v2, verb=verb, dtol=dtol):
r = False
return r