def test_random_data(): '''Doesn't test that meaningful results are produced, only that something is''' n = 40 tmap = np.random.rand(n, n) * 5 rmap = np.random.rand(n, n) a = func(tmap, rmap) print(f"{inspect.stack()[0][3]} passed") return True
def test_circular_arena(): times = np.arange(5) positions = np.array([[0, 0], [1, 0], [0, 1], [-1, 0], [0, -1]]).T - 1 kwargs = { "arena_shape": "circ", "arena_size": 3, "bin_width": 1, "limits": (-2, 2.01, -2, 2.01), } map, coverage, bin_edges = func(times, positions, **kwargs)
def test_valid_inputs(): n = 1000 t = np.arange(n, dtype=np.float64) nan_x = t.copy() nan_x[27] = np.nan inf_x = t.copy() inf_x[35] = np.inf mass_nan_x = t.copy() mass_nan_x[np.random.rand(n) > 0.6] = np.nan valid_kwargs = [ {"t": t, "x": t}, {"t": t, "x": t, "y": t}, {"t": t, "x": t, "moving_average": 5}, {"t": t, "x": nan_x}, {"t": t, "x": inf_x}, {"t": t, "x": mass_nan_x}, ] for kwargs in valid_kwargs: func(**kwargs) return
def test_central_field_square(): """A large firing field touching no wall""" field = np.zeros((40, 40)) field[5:-5, 5:-5] = 1 fields = {kw_field_map: field} assert func(fields, "s", search_width=8, walls="TRBL") == 0 # The field is within the search width, BUT the search_wdth is about handling # locations that the animal never visited - the field MUST extend into the # location closest to the wall (that the animal visited) in order to qualify print("test_central_field() passed") return True
def test_invalid_input(): fmap = np.ones((40, 40)) with pytest.raises(ValueError): # invalid input threshold init_thresh = 1.2 func(fmap, init_thresh=init_thresh) with pytest.raises(ValueError): # invalid input threshold init_thresh = 0 func(fmap, init_thresh=init_thresh) with pytest.raises(ValueError): # invalid search method - wrong type sm = 3 func(fmap, search_method=sm) with pytest.raises(ValueError): # invalid search method - unknown sm = "3" func(fmap, search_method=sm) with pytest.raises(NotImplementedError ): # invalid search method - known but not implemented sm = "not implemented" func(fmap, search_method=sm) print("test_invalid_input() passed") return True
def test_offset_perfect_field_square(): """Offset field: 100% coverage of wall, NaNs filling space between wall and field, distance 4, all else zero""" field = np.zeros((40, 40), dtype=float) field[:, 3] = 1 field[:, :3] = np.nan field = np.ma.masked_invalid(field) fields = {kw_field_map: field} shape = "s" assert func(fields, shape, search_width=8, walls="L") == 1 print("test_offset_field() passed") return True
def test_perfect_artificial_grid(): firing_map = th.generate_2d_map( "rect", 1, x=80, y=80, coverage=0.95, fields=th.generate_hexagonal_grid_fields_dict(), ) acorr = func(firing_map) return acorr
def test_invalid_inputs(): n = 1000 # Wrong dimensions for inputs # Tracking times, speeds not the same size with pytest.raises(ValueError): spike_times = np.sort(np.random.rand(n)) * n tracking_times = np.arange(n) tracking_speeds = np.random.rand(n+10) * 30 func(spike_times, tracking_times, tracking_speeds) # tracking_speeds wrong dimensions with pytest.raises(ValueError): spike_times = np.sort(np.random.rand(n)) * n tracking_times = np.arange(n) tracking_speeds = np.random.rand(n, 2) * 30 func(spike_times, tracking_times, tracking_speeds) # NaN speed values with pytest.raises(ValueError): spike_times = np.sort(np.random.rand(n)) * n tracking_times = np.arange(n) tracking_speeds = np.random.rand(n) * 30 tracking_speeds [10:30] = np.nan func(spike_times, tracking_times, tracking_speeds) # Invalid bandpass type with pytest.raises(NotImplementedError): spike_times = np.sort(np.random.rand(n)) * n tracking_times = np.arange(n) tracking_speeds = np.random.rand(n) * 30 bandpass= "******" func(spike_times, tracking_times, tracking_speeds, bandpass=bandpass) # Impossibly high speed_bandwidth with pytest.raises(ValueError): spike_times = np.sort(np.random.rand(n)) * n tracking_times = np.arange(n) tracking_speeds = np.random.rand(n) * 30 kwargs = {"bandpass":"******", "lower_bound_speed":2, "upper_bound_time": 10, "speed_bandwidth": 0.01} func(spike_times, tracking_times, tracking_speeds, **kwargs)
def test_perfect_fields(): '''Note: a perfect score (1) can only be achieved with a field that is full width and infinitesimal depth. Here we are testing with a 40x40 field, and a perfect score is 0.7288348... ''' bs, cov = func(*rmap1(), arena_shape="s", walls="B") assert (bs >= 0.728 and bs <= 0.729) #if __name__ == '__main__': # test_zero_fields() # test_perfect_fields() # show(rmap1()[0])
def test_perfect_grid_cell(): firing_map = th.generate_2d_map( "rect", 1, x=80, y=80, coverage=0.95, fields=th.generate_hexagonal_grid_fields_dict(), ) acorr = opexebo.analysis.autocorrelation(firing_map) gs, stats = func(acorr, debug=True, search_method="default") assert stats["grid_ellipse_aspect_ratio"] > 0.985 assert stats["grid_ellipse_aspect_ratio"] < 1.15
def test_zero_data(): '''Doesn't test that meaningful results are produced, only that something is''' n = 40 tmap = np.ma.zeros((n, n)) rmap = np.ma.zeros((n, n)) a = func(tmap, rmap) print(f"{inspect.stack()[0][3]} passed") return True #if __name__ == '__main__': # test_random_data() # test_zero_data()
def test_perfect_fields_square(): """Perfect field: 100% coverage of wall, zero distance, everywhere else zero""" shape = "s" perfect_left_field = np.zeros((40, 40)) perfect_left_field[:, 0] = 1 left = {kw_field_map: perfect_left_field} sw = 1 assert func(left, shape, search_width=sw, walls="L") == 1 right = {kw_field_map: np.fliplr(perfect_left_field)} assert func(right, shape, search_width=sw, walls="R") == 1 top = {kw_field_map: np.rot90(perfect_left_field)} assert func(top, shape, search_width=sw, walls="T") == 1 bottom = {kw_field_map: np.flipud(np.rot90(perfect_left_field))} assert func(bottom, shape, search_width=sw, walls="B") == 1 # The above verify that the function agrees with a field that is there # The below verify that the function correctly identifies that a field is *not* there. assert func(left, shape, search_width=sw, walls="TRB") == 1 / 40 print("test_perfect_fields() passed") return True
def test_linear_arena(): n = 1000 times = np.arange(n) positions = np.random.rand(n) speeds = np.ones(n) kwargs = { "arena_shape": "line", "arena_size": 1, "bin_width": 0.1, "speed_cutoff": 0.1, "limits": (0, 1) } map, cov, edges = func(times, positions, speeds, **kwargs) assert cov == 1 assert edges.size == 11 assert edges[1] == 0.1 # Check that it works with a 2d array of 1d position data positions = np.expand_dims(positions, 0) map, cov, edges = func(times, positions, speeds, **kwargs) assert cov == 1 assert edges.size == 11 assert edges[1] == 0.1
def test_linear_arena(): n = 1000 times = np.arange(n) positions = np.random.rand(n) kwargs = { "arena_shape": "line", "arena_size": 1, "bin_width": 0.1, "limits": (0, 1) } map, cov, edges = func(times, positions, **kwargs) assert cov == 1 assert edges.size == 11 assert edges[1] == 0.1
def test_grid_score_similarity(): data = spio.loadmat(th.test_data_square) print("Data loaded") ds = np.arange(th.get_data_size(data)) vals = np.zeros_like(ds).astype(float) for key in ds: acorr = get_acorr_bnt(data, key) bnt = get_grid_score_bnt(data, key) ope, _ = func(acorr, min_orientation=15, search_method="sep") if np.isnan(ope): ratio = np.abs(bnt / ope - 1) vals[key] = ratio tol = 1e-2 assert ((vals < tol).all()) print(f"{inspect.stack()[0][3]} passed") return True
def show_map(data, key): rmap = th.get_ratemap_bnt(data, key)[0] fmap_bnt = get_fields_bnt(data, key)[0] fmap_ope = func(rmap)[1] plt.figure(figsize=(18, 6)) plt.subplot(131) plt.title("Rate map") plt.imshow(rmap) plt.colorbar() plt.subplot(132) plt.title("BNT Field Map") plt.imshow(fmap_bnt) plt.subplot(133) plt.imshow(fmap_ope) plt.title("Opexebo Field Map") plt.show()
def test_1d_ratemap(): arena_size = 80 bin_width = 2.5 _num_bins = opexebo.general.bin_width_to_bin_number(arena_size, bin_width) tmap = np.ones(_num_bins) # equal occupancy in all locations n = 5000 times = np.sort(np.random.rand(n)) * 1200 # 20 minute session pos = np.random.rand(n) * arena_size spikes_tracking = np.array([times, pos]) rmap = func( tmap, spikes_tracking, bin_width=bin_width, arena_size=arena_size, ) assert rmap.ndim == 1 assert rmap.shape == tmap.shape
def test_1d_ratemap(): arena_size = 80 bin_width = 2.5 _num_bins = opexebo.general.bin_width_to_bin_number(arena_size, bin_width) tmap = np.ones(_num_bins) # equal occupancy in all locations n = 5000 times = np.sort(np.random.rand(n)) * 1200 # 20 minute session speeds = np.random.rand(n) * 10 # linearly distributed speeds up to 10cm/s pos = np.random.rand(n) * arena_size spikes_tracking = np.array([times, speeds, pos]) speed_cutoff = 2 rmap = func(tmap, spikes_tracking, bin_width=bin_width, speed_cutoff=speed_cutoff, arena_size=arena_size) assert rmap.ndim == 1 assert rmap.shape == tmap.shape
def test_random_inputs(): '''Try randomised inputs and check we get the right _kind_ of outputs''' n = 10000 spike_times = np.sort(np.random.rand(n)) * n tracking_times = np.arange(n) tracking_speeds = np.random.rand(n) * 30 for kwargs in({"bandpass":"******"}, {"bandpass":"******", "lower_bound_speed": 2, "upper_bound_speed": 10}, {"bandpass":"******", "lower_bound_speed":2, "upper_bound_time": 10, "speed_bandwidth": 2}): ss, thresholds = func(spike_times, tracking_times, tracking_speeds, **kwargs) for val in ss.values(): assert np.isfinite(val) assert -1 <= val <= 1 #if __name__ == '__main__': # test_invalid_inputs() # test_random_inputs()
def test_2d_ratemap(): arena_size = (80, 120) bin_number = (16, 24) tmap = np.ones( bin_number ).T # Want to be [x] 16 by [y] 24, whereas Numpy writes this the opposite, so transpose n = 5000 times = np.sort(np.random.rand(n)) * 1200 # 20 minute session pos_x = np.random.rand(n) * arena_size[0] pos_y = np.random.rand(n) * arena_size[1] spikes_tracking = np.array([times, pos_x, pos_y]) rmap = func( tmap, spikes_tracking, bin_number=bin_number, arena_size=arena_size, ) assert rmap.ndim == 2 assert rmap.shape == tmap.shape
def test_perfect_grid_cell(): firing_map = th.generate_2d_map( "rect", 1, x=80, y=80, coverage=0.95, fields=th.generate_hexagonal_grid_fields_dict()) # plt.figure() # plt.imshow(firing_map) acorr = opexebo.analysis.autocorrelation(firing_map) # plt.figure() # plt.imshow(acorr) # plt.show() gs, stats = func(acorr, debug=True, search_method="default") assert stats["grid_ellipse_aspect_ratio"] > 0.985 assert stats["grid_ellipse_aspect_ratio"] < 1.15 #if __name__ == '__main__': # test_perfect_grid_cell()
def test_unchanging_ratemap(): '''Check that the input arguments are not modified in place by the placefield detection function''' # All finite fmap = np.ones((40, 40)) fmap_original = fmap.copy() func(fmap) assert (np.array_equal(fmap, fmap_original)) # Some non-finite fmap = np.ones((40, 40)) fmap[21, 3] = np.inf fmap_original = fmap.copy() func(fmap) assert (np.array_equal(fmap, fmap_original)) #Masked array fmap = np.ones((40, 40)) fmap[21, 3] = np.inf fmap = np.ma.masked_invalid(fmap) fmap_original = fmap.copy() func(fmap) assert (np.array_equal(fmap, fmap_original)) print("test_unchanging_ratemap() passed") return True
def test_random_input(): firing_map = np.random.rand(80, 80) acorr = func(firing_map) return acorr
def test_invalid_inputs(): # wrong dimensions to positions n = 10 with pytest.raises(errors.ArgumentError): times = np.arange(n) positions = np.ones((3, n)) #! speeds = np.ones(n) func(times, positions, speeds, arena_size=1) with pytest.raises(errors.ArgumentError): times = np.arange(n) positions = np.ones((2, n)) speeds = np.ones((2, n)) #! func(times, positions, speeds, arena_size=1) # Mismatched pos/speed with pytest.raises(errors.ArgumentError): times = np.arange(n) positions = np.ones((2, n)) speeds = np.ones(n + 1) #! func(times, positions, speeds, arena_size=1) # No arena size with pytest.raises(TypeError): times = np.arange(n) positions = np.ones((2, n)) speeds = np.ones(n) func(times, positions, speeds) #! # All nan # This isn't explicit in the function, but comes as a result of excluding # all non-finite values, and then being left with an empty array with pytest.raises(ValueError): times = np.arange(n) positions = np.full((2, n), np.nan) speeds = np.full(n, np.nan) func(times, positions, speeds, arena_size=1) with pytest.raises(NotImplementedError): times = np.arange(5) positions = np.ones(5) speeds = np.ones(5) func(times, positions, speeds, arena_size=1, arena_shape="asdf") print("test_invalid_inputs passed")
def test_rmap_invalid_inputs(): # Mismatched dimensions # 2d time map but 1d spike pos with pytest.raises(err.DimensionMismatchError): tmap = np.ones((10, 10)) time = np.arange(100) spikes_x = np.random.rand(100) spikes_tracking = np.array((time, spikes_x)) func(tmap, spikes_tracking, arena_size=1) # 1d time map but 2d spike_pos with pytest.raises(err.DimensionMismatchError): tmap = np.ones(10) time = np.arange(100) spikes_x = np.random.rand(100) spikes_y = np.random.rand(100) spikes_tracking = np.array((time, spikes_x, spikes_y)) func(tmap, spikes_tracking, arena_size=(10, 10)) # invalid input types with pytest.raises(err.ArgumentError): tmap = (1, 2, 3, 4) #! tmap should be an ndarray spikes = np.ones((2, 100)) func(tmap, spikes, arena_size=1) with pytest.raises(err.ArgumentError): tmap = np.ones(10) spikes = ([0.23, 1], [0.5, 1.2], [0.75, -3]) #! spikes should be an ndarray func(tmap, spikes, arena_size=1) with pytest.raises(TypeError): tmap = np.ones((10, 10)) spikes = np.ones((3, 100)) # t, x, y func(tmap, spikes) #! missing arena_size with pytest.raises(ValueError): tmap = np.ones((10, 10)) spikes = np.ones((3, 100)) func(tmap, spikes, arena_size=1, limits="abc") # limits should be a tuple # mismatched sizes with pytest.raises(err.DimensionMismatchError): tmap = np.ones((40, 40)) spikes = np.ones((3, 100)) func(tmap, spikes, arena_size=80, bin_width=4) #! 80/4 != 40 print("test_rmap_invalid_inputs passed") return True
def test_zero_fields_square(): fields = [] assert func(fields, "s") == 0 print("test_zero_fields() passed") return True