Total Complexity | 49 |
Total Lines | 310 |
Duplicated Lines | 23.87 % |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like test_features often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | import diff_classifier.features as ft |
||
2 | import diff_classifier.msd as msd |
||
3 | import numpy.testing as npt |
||
4 | import pandas.util.testing as pdt |
||
5 | import numpy as np |
||
6 | import pandas as pd |
||
7 | import math |
||
8 | |||
9 | |||
10 | def test_make_xyarray(): |
||
11 | d = {'Frame': [0, 1, 2, 3, 4, 0, 1, 2, 3, 4], |
||
12 | 'Track_ID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], |
||
13 | 'X': [np.nan, 6, 7, 8, 9, 1, 2, 3, 4, np.nan], |
||
14 | 'Y': [np.nan, 7, 8, 9, 10, 2, 3, 4, 5, np.nan]} |
||
15 | df = pd.DataFrame(data=d) |
||
16 | cols = ['Frame', 'Track_ID', 'X', 'Y', 'MSDs', 'Gauss'] |
||
17 | length = max(df['Frame']) + 1 |
||
18 | m_df = msd.all_msds2(df, frames=length)[cols] |
||
19 | |||
20 | dt = {'Frame': [float(i) for i in[0, 1, 2, 3]], |
||
21 | 'Track_ID': [float(i) for i in[2, 2, 2, 2]], |
||
22 | 'X': [float(i) for i in[1, 2, 3, 4]], |
||
23 | 'Y': [float(i) for i in[2, 3, 4, 5]], |
||
24 | 'MSDs': [float(i) for i in[0, 2, 8, 18]], |
||
25 | 'Gauss': [float(i) for i in[0, 0.25, 0.25, 0.25]]} |
||
26 | dft = pd.DataFrame(data=dt) |
||
27 | |||
28 | pdt.assert_frame_equal(ft.unmask_track(m_df[m_df['Track_ID']==2]), dft) |
||
29 | |||
30 | View Code Duplication | def test_alpha_calc(): |
|
|
|||
31 | frames = 5 |
||
32 | d = {'Frame': np.linspace(0, frames, frames), |
||
33 | 'X': np.linspace(0, frames, frames)+5, |
||
34 | 'Y': np.linspace(0, frames, frames)+3, |
||
35 | 'Track_ID': np.ones(frames)} |
||
36 | df = pd.DataFrame(data=d) |
||
37 | df = msd.all_msds2(df, frames=frames+1) |
||
38 | assert ft.alpha_calc(df) == (2.0000000000000004, 0.4999999999999998) |
||
39 | |||
40 | frames = 10 |
||
41 | d = {'Frame': np.linspace(0, frames, frames), |
||
42 | 'X': np.sin(np.linspace(0, frames, frames)+5), |
||
43 | 'Y': np.cos(np.linspace(0, frames, frames)+3), |
||
44 | 'Track_ID': np.ones(frames)} |
||
45 | df = pd.DataFrame(data=d) |
||
46 | df = msd.all_msds2(df, frames=frames+1) |
||
47 | assert ft.alpha_calc(df) == (0.8201034110620524, 0.1494342948594476) |
||
48 | |||
49 | |||
50 | def test_gyration_tensor(): |
||
51 | frames = 6 |
||
52 | d = {'Frame': np.linspace(0, frames, frames), |
||
53 | 'X': np.linspace(0, frames, frames)+5, |
||
54 | 'Y': np.linspace(0, frames, frames)+3, |
||
55 | 'Track_ID': np.ones(frames)} |
||
56 | df = pd.DataFrame(data=d) |
||
57 | df = msd.all_msds2(df, frames=frames+1) |
||
58 | o1, o2, o3, o4 = (8.0, 0.0, np.array([ 0.70710678, -0.70710678]), np.array([0.70710678, 0.70710678])) |
||
59 | d1, d2, d3, d4 = ft.gyration_tensor(df) |
||
60 | |||
61 | assert d1 == o1 |
||
62 | assert d2 == o2 |
||
63 | npt.assert_almost_equal(o3, d3) |
||
64 | npt.assert_almost_equal(o4, d4) |
||
65 | |||
66 | frames = 10 |
||
67 | d = {'Frame': np.linspace(0, frames, frames), |
||
68 | 'X': np.sin(np.linspace(0, frames, frames)+5), |
||
69 | 'Y': np.cos(np.linspace(0, frames, frames)+5), |
||
70 | 'Track_ID': np.ones(frames)} |
||
71 | df = pd.DataFrame(data=d) |
||
72 | df = msd.all_msds2(df, frames=frames+1) |
||
73 | o1, o2, o3, o4 = (0.47248734315843355, 0.3447097846562249, np.array([0.83907153, 0.54402111]), |
||
74 | np.array([-0.54402111, 0.83907153])) |
||
75 | d1, d2, d3, d4 = ft.gyration_tensor(df) |
||
76 | |||
77 | assert d1 == o1 |
||
78 | assert d2 == o2 |
||
79 | npt.assert_almost_equal(o3, d3) |
||
80 | npt.assert_almost_equal(o4, d4) |
||
81 | |||
82 | |||
83 | View Code Duplication | def test_kurtosis(): |
|
84 | frames = 5 |
||
85 | d = {'Frame': np.linspace(0, frames, frames), |
||
86 | 'X': np.linspace(0, frames, frames)+5, |
||
87 | 'Y': np.linspace(0, frames, frames)+3, |
||
88 | 'Track_ID': np.ones(frames)} |
||
89 | df = pd.DataFrame(data=d) |
||
90 | df = msd.all_msds2(df, frames=frames+1) |
||
91 | assert ft.kurtosis(df) == 4.079999999999999 |
||
92 | |||
93 | frames = 10 |
||
94 | d = {'Frame': np.linspace(0, frames, frames), |
||
95 | 'X': np.sin(np.linspace(0, frames, frames)+3), |
||
96 | 'Y': np.cos(np.linspace(0, frames, frames)+3), |
||
97 | 'Track_ID': np.ones(frames)} |
||
98 | df = pd.DataFrame(data=d) |
||
99 | df = msd.all_msds2(df, frames=frames+1) |
||
100 | assert ft.kurtosis(df) == 1.4759027695843443 |
||
101 | |||
102 | |||
103 | def test_asymmetry(): |
||
104 | frames = 10 |
||
105 | d = {'Frame': np.linspace(0, frames, frames), |
||
106 | 'X': np.linspace(0, frames, frames)+5, |
||
107 | 'Y': np.linspace(0, frames, frames)+3, |
||
108 | 'Track_ID': np.ones(frames)} |
||
109 | df = pd.DataFrame(data=d) |
||
110 | df = msd.all_msds2(df, frames=frames+1) |
||
111 | |||
112 | o1, o2, o3, o4, o5 = (20.0, 0.0, 1.0, 0.0, 0.69314718) |
||
113 | d1, d2, d3, d4, d5 = ft.asymmetry(df) |
||
114 | assert math.isclose(o1, d1, abs_tol=1e-10) |
||
115 | assert math.isclose(o2, d2, abs_tol=1e-10) |
||
116 | assert math.isclose(o3, d3, abs_tol=1e-10) |
||
117 | assert math.isclose(o4, d4, abs_tol=1e-10) |
||
118 | assert math.isclose(o5, d5, abs_tol=1e-10) |
||
119 | |||
120 | frames = 100 |
||
121 | d = {'Frame': np.linspace(0, frames, frames), |
||
122 | 'X': np.sin(np.linspace(0, frames, frames)+3), |
||
123 | 'Y': np.cos(np.linspace(0, frames, frames)+3), |
||
124 | 'Track_ID': np.ones(frames)} |
||
125 | df = pd.DataFrame(data=d) |
||
126 | df = msd.all_msds2(df, frames=frames+1) |
||
127 | |||
128 | o1, o2, o3, o4, o5 = (0.4254120816156, 0.42004967815488, 0.0001609000151811, 0.9873948021401, 2.0114322402896e-05) |
||
129 | d1, d2, d3, d4, d5 = ft.asymmetry(df) |
||
130 | assert math.isclose(o1, d1) |
||
131 | assert math.isclose(o2, d2) |
||
132 | assert math.isclose(o3, d3) |
||
133 | assert math.isclose(o4, d4) |
||
134 | assert math.isclose(o5, d5) |
||
135 | |||
136 | |||
137 | def test_minBoundingRect(): |
||
138 | frames = 10 |
||
139 | d = {'Frame': np.linspace(0, frames, frames), |
||
140 | 'X': np.linspace(0, frames, frames)+5, |
||
141 | 'Y': np.linspace(0, frames, frames)+3, |
||
142 | 'Track_ID': np.ones(frames)} |
||
143 | df = pd.DataFrame(data=d) |
||
144 | df = msd.all_msds2(df, frames=frames+1) |
||
145 | |||
146 | d1, d2, d3, d4, d5, d6 = ft.minBoundingRect(df) |
||
147 | o1, o2, o3, o4 = (-2.356194490192, 0, 14.142135623730, 0) |
||
148 | o5 = np.array([10, 8]) |
||
149 | o6 = np.array([[5., 3.], [15., 13.], [15., 13.], [5., 3.]]) |
||
150 | |||
151 | #assert math.isclose(d1, o1, abs_tol=1e-10) |
||
152 | assert math.isclose(d2, o2, abs_tol=1e-10) |
||
153 | assert math.isclose(d3, o3, abs_tol=1e-10) |
||
154 | assert math.isclose(d4, o4, abs_tol=1e-10) |
||
155 | npt.assert_almost_equal(d5, o5) |
||
156 | #npt.assert_almost_equal(d6, o6) |
||
157 | |||
158 | frames = 100 |
||
159 | d = {'Frame': np.linspace(0, frames, frames), |
||
160 | 'X': np.sin(np.linspace(0, frames, frames)+3), |
||
161 | 'Y': np.cos(np.linspace(0, frames, frames)+3), |
||
162 | 'Track_ID': np.ones(frames)} |
||
163 | df = pd.DataFrame(data=d) |
||
164 | df = msd.all_msds2(df, frames=frames+1) |
||
165 | |||
166 | d1, d2, d3, d4, d5, d6 = ft.minBoundingRect(df) |
||
167 | o1, o2, o3, o4 = (-2.7345175425633, 3.7067697307443, 1.899593160348, 1.951349272106) |
||
168 | o5 = np.array([-0.00098312, 0.00228019]) |
||
169 | o6 = np.array([[-1.2594591, 0.52217706], |
||
170 | [0.4849046, 1.27427376], |
||
171 | [1.25749286, -0.51761668], |
||
172 | [-0.48687084, -1.26971339]]) |
||
173 | |||
174 | #assert math.isclose(d1, o1, abs_tol=1e-10) |
||
175 | assert math.isclose(d2, o2, abs_tol=1e-10) |
||
176 | assert math.isclose(d3, o3, abs_tol=1e-10) |
||
177 | assert math.isclose(d4, o4, abs_tol=1e-10) |
||
178 | npt.assert_almost_equal(d5, o5) |
||
179 | #npt.assert_almost_equal(d6, o6) |
||
180 | |||
181 | def test_aspectratio(): |
||
182 | frames = 6 |
||
183 | d = {'Frame': np.linspace(0, frames, frames), |
||
184 | 'X': [0, 1, 1, 2, 2, 3], |
||
185 | 'Y': [0, 0, 1, 1, 2, 2], |
||
186 | 'Track_ID': np.ones(frames)} |
||
187 | df = pd.DataFrame(data=d) |
||
188 | df = msd.all_msds2(df, frames=frames+1) |
||
189 | assert ft.aspectratio(df)[0:2] == (3.9000000000000026, 0.7435897435897438) |
||
190 | npt.assert_almost_equal(ft.aspectratio(df)[2], np.array([1.5, 1. ])) |
||
191 | |||
192 | |||
193 | View Code Duplication | def test_boundedness(): |
|
194 | frames = 100 |
||
195 | d = {'Frame': np.linspace(0, frames, frames), |
||
196 | 'X': np.sin(np.linspace(0, frames, frames)+3), |
||
197 | 'Y': np.cos(np.linspace(0, frames, frames)+3), |
||
198 | 'Track_ID': np.ones(frames)} |
||
199 | df = pd.DataFrame(data=d) |
||
200 | df = msd.all_msds2(df, frames=frames+1) |
||
201 | assert ft.boundedness(df) == (0.607673328076712, 5.674370543833708, -0.0535555587618044) |
||
202 | |||
203 | frames = 10 |
||
204 | d = {'Frame': np.linspace(0, frames, frames), |
||
205 | 'X': np.linspace(0, frames, frames)+5, |
||
206 | 'Y': np.linspace(0, frames, frames)+3, |
||
207 | 'Track_ID': np.ones(frames)} |
||
208 | df = pd.DataFrame(data=d) |
||
209 | df = msd.all_msds2(df, frames=frames+1) |
||
210 | assert ft.boundedness(df) == (0.039999999999999994, 1.0, -0.21501108474766228) |
||
211 | |||
212 | |||
213 | View Code Duplication | def test_efficiency(): |
|
214 | frames = 100 |
||
215 | d = {'Frame': np.linspace(0, frames, frames), |
||
216 | 'X': np.sin(np.linspace(0, frames, frames)+3), |
||
217 | 'Y': np.cos(np.linspace(0, frames, frames)+3), |
||
218 | 'Track_ID': np.ones(frames)} |
||
219 | df = pd.DataFrame(data=d) |
||
220 | df = msd.all_msds2(df, frames=frames+1) |
||
221 | |||
222 | assert ft.efficiency(df) == (0.003548421265914009, 0.0059620286331768385) |
||
223 | |||
224 | frames = 10 |
||
225 | d = {'Frame': np.linspace(0, frames, frames), |
||
226 | 'X': np.linspace(0, frames, frames)+5, |
||
227 | 'Y': np.linspace(0, frames, frames)+3, |
||
228 | 'Track_ID': np.ones(frames)} |
||
229 | df = pd.DataFrame(data=d) |
||
230 | df = msd.all_msds2(df, frames=frames+1) |
||
231 | |||
232 | assert ft.efficiency(df) == (10.0, 1.0) |
||
233 | |||
234 | def test_msd_ratio(): |
||
235 | frames = 10 |
||
236 | d = {'Frame': np.linspace(0, frames, frames), |
||
237 | 'X': np.sin(np.linspace(0, frames, frames)+3), |
||
238 | 'Y': np.cos(np.linspace(0, frames, frames)+3), |
||
239 | 'Track_ID': np.ones(frames)} |
||
240 | df = pd.DataFrame(data=d) |
||
241 | df = msd.all_msds2(df, frames=frames+1) |
||
242 | |||
243 | assert ft.msd_ratio(df, 1, 9) == 0.09708430006771959 |
||
244 | |||
245 | frames = 10 |
||
246 | d = {'Frame': np.linspace(0, frames, frames), |
||
247 | 'X': np.linspace(0, frames, frames)+5, |
||
248 | 'Y': np.linspace(0, frames, frames)+3, |
||
249 | 'Track_ID': np.ones(frames)} |
||
250 | df = pd.DataFrame(data=d) |
||
251 | df = msd.all_msds2(df, frames=frames+1) |
||
252 | |||
253 | assert ft.msd_ratio(df, 1, 9) == -0.09876543209876543 |
||
254 | |||
255 | def test_calculate_features(): |
||
256 | d = {'Frame': [0, 1, 2, 3, 4, 0, 1, 2, 3, 4], |
||
257 | 'Track_ID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], |
||
258 | 'X': [0, 0, 1, 1, 2, 1, 1, 2, 2, 3], |
||
259 | 'Y': [0, 1, 1, 2, 2, 0, 1, 1, 2, 2]} |
||
260 | df = pd.DataFrame(data=d) |
||
261 | dfi = msd.all_msds2(df, frames = 5) |
||
262 | feat = ft.calculate_features(dfi) |
||
263 | |||
264 | d = {'AR': np.ones(2)*3.9999999999999996, |
||
265 | 'D_fit': np.ones(2)*0.1705189932550273, |
||
266 | 'MSD_ratio': np.ones(2)*-0.2666666666666666, |
||
267 | 'X': [0.75, 1.75], |
||
268 | 'Y': [1.25, 1.25], |
||
269 | 'Track_ID': [1.0, 2.0], |
||
270 | 'alpha': np.ones(2)*1.7793370720777268, |
||
271 | 'asymmetry1': np.ones(2)*0.9440237239896903, |
||
272 | 'asymmetry2': np.ones(2)*0.12, |
||
273 | 'asymmetry3': np.ones(2)*0.3691430189107616, |
||
274 | 'boundedness': np.ones(2)*0.25, |
||
275 | 'efficiency': np.ones(2)*2.0, |
||
276 | 'elongation': np.ones(2)*0.75, |
||
277 | 'fractal_dim': np.ones(2)*1.333333333333333, |
||
278 | 'frames': [5.0, 5.0], |
||
279 | 'kurtosis': np.ones(2)*1.166666666666667, |
||
280 | 'straightness': np.ones(2)*0.7071067811865476, |
||
281 | 'trappedness': np.ones(2)*-0.15258529289428524} |
||
282 | dfi = pd.DataFrame(data=d) |
||
283 | |||
284 | pdt.assert_frame_equal(dfi, feat) |
||
285 | |||
286 | def test_unmask_track(): |
||
287 | size = 10 |
||
288 | ID = np.ones(size) |
||
289 | frame = np.linspace(5, size-1+5, size) |
||
290 | x = frame + 1 |
||
291 | y = frame + 3 |
||
292 | |||
293 | d = {'Frame': frame, |
||
294 | 'Track_ID': ID, |
||
295 | 'X': x, |
||
296 | 'Y': y} |
||
297 | di = pd.DataFrame(data=d) |
||
298 | track = msd.all_msds2(di, frames=20) |
||
299 | output = ft.unmask_track(track) |
||
300 | |||
301 | d2 = {'Frame': frame-5, |
||
302 | 'Track_ID': ID, |
||
303 | 'X': x, |
||
304 | 'Y': y, |
||
305 | 'MSDs': np.array((0, 2, 8, 18, 32, 50, 72, 98, 128, 162)).astype('float64'), |
||
306 | 'Gauss': np.array((0, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25))} |
||
307 | check = pd.DataFrame(data=d2) |
||
308 | |||
309 | pdt.assert_frame_equal(output, check) |