diff --git a/bids/variables/tests/test_variables.py b/bids/variables/tests/test_variables.py index 339ad8553..74876489c 100644 --- a/bids/variables/tests/test_variables.py +++ b/bids/variables/tests/test_variables.py @@ -1,5 +1,6 @@ from bids.layout import BIDSLayout import pytest +import os from os.path import join from bids.tests import get_test_data_path from bids.variables import (merge_variables, DenseRunVariable, SimpleVariable, @@ -7,7 +8,9 @@ from bids.variables.entities import RunInfo import numpy as np import pandas as pd +import nibabel as nb import uuid +import json def generate_DEV(name='test', sr=20, duration=480): @@ -174,3 +177,28 @@ def test_filter_simple_variable(layout2): assert merged.filter({'nonexistent': 2}, strict=True) is None merged.filter({'acquisition': 'fullbrain'}, inplace=True) assert merged.to_df().shape == (40, 9) + + +@pytest.mark.parametrize( + "TR, nvols", + [(2.00000, 251), + (2.000001, 251)]) +def test_resampling_edge_case(tmpdir, TR, nvols): + tmpdir.chdir() + os.makedirs('sub-01/func') + with open('sub-01/func/sub-01_task-task_events.tsv', 'w') as fobj: + fobj.write('onset\tduration\tval\n1\t0.1\t1\n') + with open('sub-01/func/sub-01_task-task_bold.json', 'w') as fobj: + json.dump({'RepetitionTime': TR}, fobj) + + dataobj = np.zeros((5, 5, 5, nvols), dtype=np.int16) + affine = np.diag((2.5, 2.5, 2.5, 1)) + img = nb.Nifti1Image(dataobj, affine) + img.header.set_zooms((2.5, 2.5, 2.5, TR)) + img.to_filename('sub-01/func/sub-01_task-task_bold.nii.gz') + + layout = BIDSLayout('.', validate=False) + coll = load_variables(layout).get_collections('run')[0] + dense_var = coll.variables['val'].to_dense(coll.sampling_rate) + regressor = dense_var.resample(1.0 / TR).values + assert regressor.shape == (nvols, 1) diff --git a/bids/variables/variables.py b/bids/variables/variables.py index 0f98548bb..6cd06d9a1 100644 --- a/bids/variables/variables.py +++ b/bids/variables/variables.py @@ -448,12 +448,13 @@ def resample(self, sampling_rate, inplace=False, kind='linear'): self.index = self._build_entity_index(self.run_info, sampling_rate) x = np.arange(n) - num = int(np.ceil(n * sampling_rate / old_sr)) + num = len(self.index) from scipy.interpolate import interp1d f = interp1d(x, self.values.values.ravel(), kind=kind) x_new = np.linspace(0, n - 1, num=num) self.values = pd.DataFrame(f(x_new)) + assert len(self.values) == len(self.index) self.sampling_rate = sampling_rate