| 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) |