|
| 1 | +import unittest |
| 2 | +import numpy as np |
| 3 | +import pandas as pd |
| 4 | +import brainbox.modeling.design_matrix as bdm |
| 5 | +import brainbox.modeling.utils as mut |
| 6 | +from pathlib import Path |
| 7 | + |
| 8 | + |
| 9 | +class TestModeling(unittest.TestCase): |
| 10 | + |
| 11 | + def setUp(self): |
| 12 | + # Params for test |
| 13 | + self.binwidth = 0.02 |
| 14 | + self.rng = np.random.default_rng(seed=112358) |
| 15 | + |
| 16 | + # Generate fake trial start, stimon, feedback, and end times |
| 17 | + starts = np.array([0, 1.48, 2.93, 4.67, 6.01, 7.31, 8.68, 9.99, 11.43, 12.86]) |
| 18 | + ends = np.array([1.35, 2.09, 3.53, 5.23, 6.58, 7.95, 9.37, 11.31, 12.14, 13.26]) |
| 19 | + stons = starts + 0.1 |
| 20 | + fdbks = stons + self.rng.normal(loc=0.1, scale=0.05, size=10) |
| 21 | + |
| 22 | + # Figure out how many bins each trial is and generate non-monotonic trace of fake wheel |
| 23 | + trlens = self.binf(ends - starts) |
| 24 | + fakewheels = [np.cumsum(self.rng.normal(loc=0.01, scale=0.01, size=(x))) for x in trlens] |
| 25 | + |
| 26 | + # Store trialsdf for later use |
| 27 | + self.trialsdf = pd.DataFrame({'trial_start': starts, |
| 28 | + 'trial_end': ends, |
| 29 | + 'stim_onset': stons, |
| 30 | + 'feedback': fdbks, |
| 31 | + 'wheel_traces': fakewheels}) |
| 32 | + |
| 33 | + def binf(self, x): |
| 34 | + return np.ceil(x / self.binwidth).astype(int) |
| 35 | + |
| 36 | + def test_dm_construct(self): |
| 37 | + """ |
| 38 | + Check whether or not design matrix construction works as intended |
| 39 | + """ |
| 40 | + |
| 41 | + # Design matrix instance |
| 42 | + self.design = bdm.DesignMatrix(self.trialsdf, |
| 43 | + vartypes={'trial_start': 'timing', |
| 44 | + 'trial_end': 'timing', |
| 45 | + 'stim_onset': 'timing', |
| 46 | + 'feedback': 'timing', |
| 47 | + 'wheel_traces': 'continuous'}) |
| 48 | + |
| 49 | + # Separate bases for wheel and timing |
| 50 | + tbases = mut.raised_cosine(0.2, 3, self.binf) |
| 51 | + wbases = mut.raised_cosine(0.1, 2, self.binf) |
| 52 | + # Add covariates one by one. Add different offsets on timings to test |
| 53 | + self.design.add_covariate_timing('start', 'trial_start', tbases, offset=0.02) |
| 54 | + self.design.add_covariate_timing('stim_on', 'stim_onset', tbases) |
| 55 | + self.design.add_covariate_timing('feedback', 'feedback', tbases, offset=-0.02) |
| 56 | + self.design.add_covariate('wheelpos', self.trialsdf.wheel_traces, wbases, offset=-0.1) |
| 57 | + self.design.compile_design_matrix() # Finally compile |
| 58 | + # Load target DM |
| 59 | + npy_file = Path(__file__).parent.joinpath('fixtures', 'design_matrix_test.npy') |
| 60 | + if npy_file.exists(): |
| 61 | + ref_dm = np.load(npy_file) |
| 62 | + self.assertEqual(self.design.dm, ref_dm) |
0 commit comments