From b1c09ae5e32fec9bca49eb7008cbb2dd0f291aeb Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Fri, 15 Dec 2023 02:01:52 +0100 Subject: [PATCH 01/10] Version runnng --- pynapple/core/time_series.py | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pynapple/core/time_series.py b/pynapple/core/time_series.py index 51e11fc3..16a6cdc9 100644 --- a/pynapple/core/time_series.py +++ b/pynapple/core/time_series.py @@ -1403,6 +1403,62 @@ def save(self, filename): ) return + + def interpolate(self, ts, ep=None, left=None, right=None): + """Wrapper of the numpy linear interpolation method. See https://numpy.org/doc/stable/reference/generated/numpy.interp.html for an explanation of the parameters. + The argument ts should be Ts, Tsd, TsdFrame, TsdTensor to ensure interpolating from sorted timestamps in the right unit, + + Parameters + ---------- + ts : Ts, Tsd or TsdFrame + The object holding the timestamps + ep : IntervalSet, optional + The epochs to use to interpolate. If None, the time support of Tsd is used. + left : None, optional + Value to return for ts < tsd[0], default is tsd[0]. + right : None, optional + Value to return for ts > tsd[-1], default is tsd[-1]. + """ + if not isinstance(ts, (Ts, Tsd, TsdFrame)): + raise RuntimeError( + "First argument should be an instance of Ts, Tsd or TsdFrame" + ) + + if not isinstance(ep, IntervalSet): + ep = self.time_support + + new_t = ts.restrict(ep).index + new_d = np.empty((len(new_t), self.shape[1])) + new_d.fill(np.nan) + + start = 0 + for i in range(len(ep)): + t = ts.restrict(ep.loc[[i]]) + tmp = self.restrict(ep.loc[[i]]) + if len(t) and len(tmp): + # = np.interp( + # t.index.values, tmp.index.values, tmp.values, left=left, right=right + #) + # print(tmp.index.values.shape, tmp.values.shape, t.index.values.shape) + interpolated_values = np.apply_along_axis( + lambda row: np.interp(t.index.values, tmp.index.values, row), + 0, + tmp.values) + new_d[start : start + len(t), :] = interpolated_values + + # Function to apply along each row + + # def _interp_row(row): + # print(row.shape, t.index.values.shape, tmp.index.values.shape) + # return np.interp(t.index.values, tmp.index.values, row, left=left, right=right) + + # # Apply the function along the axis 1 (row-wise) + # interpolated_values = np.apply_along_axis(_interp_row, 0, tmp.values) + # new_d[start : start + len(t), :] = interpolated_values + + start += len(t) + + return TsdFrame(t=new_t, d=new_d, columns=self.columns, time_support=ep) class Tsd(NDArrayOperatorsMixin, _AbstractTsd): From 38e489719067991b1816d2602ec314771deaa707 Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Fri, 15 Dec 2023 10:00:19 +0100 Subject: [PATCH 02/10] removed comments --- pynapple/core/time_series.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pynapple/core/time_series.py b/pynapple/core/time_series.py index 16a6cdc9..3b2f4356 100644 --- a/pynapple/core/time_series.py +++ b/pynapple/core/time_series.py @@ -1436,26 +1436,12 @@ def interpolate(self, ts, ep=None, left=None, right=None): t = ts.restrict(ep.loc[[i]]) tmp = self.restrict(ep.loc[[i]]) if len(t) and len(tmp): - # = np.interp( - # t.index.values, tmp.index.values, tmp.values, left=left, right=right - #) - # print(tmp.index.values.shape, tmp.values.shape, t.index.values.shape) interpolated_values = np.apply_along_axis( lambda row: np.interp(t.index.values, tmp.index.values, row), 0, tmp.values) new_d[start : start + len(t), :] = interpolated_values - # Function to apply along each row - - # def _interp_row(row): - # print(row.shape, t.index.values.shape, tmp.index.values.shape) - # return np.interp(t.index.values, tmp.index.values, row, left=left, right=right) - - # # Apply the function along the axis 1 (row-wise) - # interpolated_values = np.apply_along_axis(_interp_row, 0, tmp.values) - # new_d[start : start + len(t), :] = interpolated_values - start += len(t) return TsdFrame(t=new_t, d=new_d, columns=self.columns, time_support=ep) From 2d2e90c5436f2e85fc7a106c84a5f59ec483ddf8 Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Fri, 15 Dec 2023 10:00:57 +0100 Subject: [PATCH 03/10] blacked --- pynapple/core/time_series.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pynapple/core/time_series.py b/pynapple/core/time_series.py index 3b2f4356..4fcf422c 100644 --- a/pynapple/core/time_series.py +++ b/pynapple/core/time_series.py @@ -1403,7 +1403,7 @@ def save(self, filename): ) return - + def interpolate(self, ts, ep=None, left=None, right=None): """Wrapper of the numpy linear interpolation method. See https://numpy.org/doc/stable/reference/generated/numpy.interp.html for an explanation of the parameters. The argument ts should be Ts, Tsd, TsdFrame, TsdTensor to ensure interpolating from sorted timestamps in the right unit, @@ -1437,9 +1437,10 @@ def interpolate(self, ts, ep=None, left=None, right=None): tmp = self.restrict(ep.loc[[i]]) if len(t) and len(tmp): interpolated_values = np.apply_along_axis( - lambda row: np.interp(t.index.values, tmp.index.values, row), - 0, - tmp.values) + lambda row: np.interp(t.index.values, tmp.index.values, row), + 0, + tmp.values, + ) new_d[start : start + len(t), :] = interpolated_values start += len(t) From e9a2d87d72ecbad6e311375fe1196bc178255d69 Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Sat, 16 Dec 2023 00:09:14 +0100 Subject: [PATCH 04/10] interpolation as TsdAbstract method --- pynapple/core/time_series.py | 160 +++++++++++++++++++---------------- tests/npzfilestest/tsd2.json | 4 + tests/test_time_series.py | 113 +++++++++++++++++++++++++ 3 files changed, 202 insertions(+), 75 deletions(-) create mode 100644 tests/npzfilestest/tsd2.json diff --git a/pynapple/core/time_series.py b/pynapple/core/time_series.py index 4fcf422c..fca39207 100644 --- a/pynapple/core/time_series.py +++ b/pynapple/core/time_series.py @@ -926,7 +926,56 @@ def smooth(self, std, size): window = signal.windows.gaussian(size, std=std) window = window / window.sum() return self.convolve(window) + + def interpolate(self, ts, ep=None, left=None, right=None): + """Wrapper of the numpy linear interpolation method. See https://numpy.org/doc/stable/reference/generated/numpy.interp.html for an explanation of the parameters. + The argument ts should be Ts, Tsd, TsdFrame, TsdTensor to ensure interpolating from sorted timestamps in the right unit, + + Parameters + ---------- + ts : Ts, Tsd or TsdFrame + The object holding the timestamps + ep : IntervalSet, optional + The epochs to use to interpolate. If None, the time support of Tsd is used. + left : None, optional + Value to return for ts < tsd[0], default is tsd[0]. + right : None, optional + Value to return for ts > tsd[-1], default is tsd[-1]. + """ + if not isinstance(ts, (Ts, Tsd, TsdFrame)): + raise RuntimeError( + "First argument should be an instance of Ts, Tsd or TsdFrame" + ) + + if not isinstance(ep, IntervalSet): + ep = self.time_support + + new_t = ts.restrict(ep).index + + new_shape = len(new_t) if self.values.ndim == 1 else (len(new_t),) + self.shape[1:] + new_d = np.full(new_shape, np.nan) + + start = 0 + for i in range(len(ep)): + t = ts.restrict(ep.loc[[i]]) + tmp = self.restrict(ep.loc[[i]]) + if len(t) and len(tmp): + if self.values.ndim == 1: + new_d[start : start + len(t)] = np.interp( + t.index.values, tmp.index.values, tmp.values, left=left, right=right + ) + else: + interpolated_values = np.apply_along_axis( + lambda row: np.interp(t.index.values, tmp.index.values, row), + 0, + tmp.values, + ) + new_d[start : start + len(t), ...] = interpolated_values + + start += len(t) + return self.__class__(t=new_t, d=new_d, time_support=ep) + class TsdTensor(NDArrayOperatorsMixin, _AbstractTsd): """ @@ -1404,48 +1453,48 @@ def save(self, filename): return - def interpolate(self, ts, ep=None, left=None, right=None): - """Wrapper of the numpy linear interpolation method. See https://numpy.org/doc/stable/reference/generated/numpy.interp.html for an explanation of the parameters. - The argument ts should be Ts, Tsd, TsdFrame, TsdTensor to ensure interpolating from sorted timestamps in the right unit, + # def interpolate(self, ts, ep=None, left=None, right=None): + # """Wrapper of the numpy linear interpolation method. See https://numpy.org/doc/stable/reference/generated/numpy.interp.html for an explanation of the parameters. + # The argument ts should be Ts, Tsd, TsdFrame, TsdTensor to ensure interpolating from sorted timestamps in the right unit, - Parameters - ---------- - ts : Ts, Tsd or TsdFrame - The object holding the timestamps - ep : IntervalSet, optional - The epochs to use to interpolate. If None, the time support of Tsd is used. - left : None, optional - Value to return for ts < tsd[0], default is tsd[0]. - right : None, optional - Value to return for ts > tsd[-1], default is tsd[-1]. - """ - if not isinstance(ts, (Ts, Tsd, TsdFrame)): - raise RuntimeError( - "First argument should be an instance of Ts, Tsd or TsdFrame" - ) + # Parameters + # ---------- + # ts : Ts, Tsd or TsdFrame + # The object holding the timestamps + # ep : IntervalSet, optional + # The epochs to use to interpolate. If None, the time support of Tsd is used. + # left : None, optional + # Value to return for ts < tsd[0], default is tsd[0]. + # right : None, optional + # Value to return for ts > tsd[-1], default is tsd[-1]. + # """ + # if not isinstance(ts, (Ts, Tsd, TsdFrame)): + # raise RuntimeError( + # "First argument should be an instance of Ts, Tsd or TsdFrame" + # ) - if not isinstance(ep, IntervalSet): - ep = self.time_support + # if not isinstance(ep, IntervalSet): + # ep = self.time_support - new_t = ts.restrict(ep).index - new_d = np.empty((len(new_t), self.shape[1])) - new_d.fill(np.nan) + # new_t = ts.restrict(ep).index + # new_d = np.empty((len(new_t), self.shape[1])) + # new_d.fill(np.nan) - start = 0 - for i in range(len(ep)): - t = ts.restrict(ep.loc[[i]]) - tmp = self.restrict(ep.loc[[i]]) - if len(t) and len(tmp): - interpolated_values = np.apply_along_axis( - lambda row: np.interp(t.index.values, tmp.index.values, row), - 0, - tmp.values, - ) - new_d[start : start + len(t), :] = interpolated_values + # start = 0 + # for i in range(len(ep)): + # t = ts.restrict(ep.loc[[i]]) + # tmp = self.restrict(ep.loc[[i]]) + # if len(t) and len(tmp): + # interpolated_values = np.apply_along_axis( + # lambda row: np.interp(t.index.values, tmp.index.values, row), + # 0, + # tmp.values, + # ) + # new_d[start : start + len(t), :] = interpolated_values - start += len(t) + # start += len(t) - return TsdFrame(t=new_t, d=new_d, columns=self.columns, time_support=ep) + # return TsdFrame(t=new_t, d=new_d, columns=self.columns, time_support=ep) class Tsd(NDArrayOperatorsMixin, _AbstractTsd): @@ -1779,45 +1828,6 @@ def save(self, filename): return - def interpolate(self, ts, ep=None, left=None, right=None): - """Wrapper of the numpy linear interpolation method. See https://numpy.org/doc/stable/reference/generated/numpy.interp.html for an explanation of the parameters. - The argument ts should be Ts, Tsd, TsdFrame, TsdTensor to ensure interpolating from sorted timestamps in the right unit, - - Parameters - ---------- - ts : Ts, Tsd or TsdFrame - The object holding the timestamps - ep : IntervalSet, optional - The epochs to use to interpolate. If None, the time support of Tsd is used. - left : None, optional - Value to return for ts < tsd[0], default is tsd[0]. - right : None, optional - Value to return for ts > tsd[-1], default is tsd[-1]. - """ - if not isinstance(ts, (Ts, Tsd, TsdFrame)): - raise RuntimeError( - "First argument should be an instance of Ts, Tsd or TsdFrame" - ) - - if not isinstance(ep, IntervalSet): - ep = self.time_support - - new_t = ts.restrict(ep).index - new_d = np.empty(len(new_t)) - new_d.fill(np.nan) - - start = 0 - for i in range(len(ep)): - t = ts.restrict(ep.loc[[i]]) - tmp = self.restrict(ep.loc[[i]]) - if len(t) and len(tmp): - new_d[start : start + len(t)] = np.interp( - t.index.values, tmp.index.values, tmp.values, left=left, right=right - ) - start += len(t) - - return Tsd(t=new_t, d=new_d, time_support=ep) - class Ts(_AbstractTsd): """ diff --git a/tests/npzfilestest/tsd2.json b/tests/npzfilestest/tsd2.json new file mode 100644 index 00000000..db82ff15 --- /dev/null +++ b/tests/npzfilestest/tsd2.json @@ -0,0 +1,4 @@ +{ + "time": "2023-12-15 18:20:19.335119", + "info": "Test description" +} \ No newline at end of file diff --git a/tests/test_time_series.py b/tests/test_time_series.py index 5d267c06..aaa0c1b1 100755 --- a/tests/test_time_series.py +++ b/tests/test_time_series.py @@ -7,11 +7,14 @@ """Tests of time series for `pynapple` package.""" +from turtle import st import pynapple as nap import numpy as np import pandas as pd import pytest +from pynapple.core.time_series import TsdTensor + def test_create_tsd(): tsd = nap.Tsd(t=np.arange(100), d=np.arange(100)) @@ -929,6 +932,60 @@ def test_save_npz(self, tsdframe): os.remove("tsdframe.npz") os.remove("tsdframe2.npz") + def test_interpolate(self, tsdframe): + + y = np.arange(0, 1001) + data_stack = np.stack([np.arange(0, 1001),]*4).T + + tsdframe = nap.TsdFrame(t=np.arange(0, 101), d=data_stack[0::10, :]) + + # Ts + ts = nap.Ts(t=y/10) + tsdframe2 = tsdframe.interpolate(ts) + np.testing.assert_array_almost_equal(tsdframe2.values, data_stack) + + # Tsd + ts = nap.Tsd(t=y/10, d=np.zeros_like(y)) + tsdframe2 = tsdframe.interpolate(ts) + np.testing.assert_array_almost_equal(tsdframe2.values, data_stack) + + # TsdFrame + ts = nap.TsdFrame(t=y/10, d=np.zeros((len(y), 2))) + tsdframe2 = tsdframe.interpolate(ts) + np.testing.assert_array_almost_equal(tsdframe2.values, data_stack) + + with pytest.raises(RuntimeError) as e: + tsdframe.interpolate([0, 1, 2]) + assert str(e.value) == "First argument should be an instance of Ts, Tsd or TsdFrame" + + # Right left + ep = nap.IntervalSet(start=0, end=5) + tsdframe = nap.Tsd(t=np.arange(1,4), d=np.arange(3), time_support=ep) + ts = nap.Ts(t=np.arange(0, 5)) + tsdframe2 = tsdframe.interpolate(ts, left=1234) + assert float(tsdframe2.values[0]) == 1234.0 + tsdframe2 = tsdframe.interpolate(ts, right=4321) + assert float(tsdframe2.values[-1]) == 4321.0 + + def test_interpolate_with_ep(self, tsdframe): + y = np.arange(0, 1001) + data_stack = np.stack([np.arange(0, 1001),]*4).T + + tsdframe = nap.TsdFrame(t=np.arange(0, 101), d=data_stack[0::10, :]) + ts = nap.Ts(t=y/10) + ep = nap.IntervalSet(start=np.arange(0, 100, 20), end=np.arange(10, 110, 20)) + tsdframe2 = tsdframe.interpolate(ts, ep) + tmp = ts.restrict(ep).index * 10 + print(tmp, tsdframe2.values) + print(tmp.shape, tsdframe2.values.shape) + print(tmp.mean(0), tsdframe2.values.mean(0)) + np.testing.assert_array_almost_equal(tmp, tsdframe2.values[:, 0]) + + # Empty ep + ep = nap.IntervalSet(start=200, end=300) + tsdframe2 = tsdframe.interpolate(ts, ep) + assert len(tsdframe2) == 0 + #################################################### # Test for ts #################################################### @@ -1174,3 +1231,59 @@ def test_save_npz(self, tsdtensor): os.remove("tsdtensor.npz") os.remove("tsdtensor2.npz") + + def test_interpolate(self, tsdtensor): + + y = np.arange(0, 1001) + data_stack = np.stack([np.stack([np.arange(0, 1001),] * 4)] * 3).T + + tsdtensor = nap.TsdTensor(t=np.arange(0, 101), d= data_stack[0::10, ...]) + + # Ts + ts = nap.Ts(t = y / 10) + tsdtensor2 = tsdtensor.interpolate(ts) + np.testing.assert_array_almost_equal(tsdtensor2.values, data_stack) + + # Tsd + ts = nap.Tsd(t=y/10, d=np.zeros_like(y)) + tsdtensor2 = tsdtensor.interpolate(ts) + np.testing.assert_array_almost_equal(tsdtensor2.values, data_stack) + + # TsdFrame + ts = nap.TsdFrame(t=y/10, d=np.zeros((len(y), 2))) + tsdtensor2 = tsdtensor.interpolate(ts) + np.testing.assert_array_almost_equal(tsdtensor2.values, data_stack) + + with pytest.raises(RuntimeError) as e: + tsdtensor.interpolate([0, 1, 2]) + assert str(e.value) == "First argument should be an instance of Ts, Tsd or TsdFrame" + + # Right left + ep = nap.IntervalSet(start=0, end=5) + tsdtensor = nap.Tsd(t=np.arange(1,4), d=np.arange(3), time_support=ep) + ts = nap.Ts(t=np.arange(0, 5)) + tsdtensor2 = tsdtensor.interpolate(ts, left=1234) + assert float(tsdtensor2.values[0]) == 1234.0 + tsdtensor2 = tsdtensor.interpolate(ts, right=4321) + assert float(tsdtensor2.values[-1]) == 4321.0 + + def test_interpolate_with_ep(self, tsdtensor): + y = np.arange(0, 1001) + data_stack = np.stack([np.stack([np.arange(0, 1001),] * 4),] * 3).T + + tsdtensor = nap.TsdTensor(t=np.arange(0, 101), d=data_stack[::10, ...]) + + ts = nap.Ts(t=y / 10) + + + ep = nap.IntervalSet(start=np.arange(0, 100, 20), end=np.arange(10, 110, 20)) + tsdframe2 = tsdtensor.interpolate(ts, ep) + tmp = ts.restrict(ep).index * 10 + + np.testing.assert_array_almost_equal(tmp, tsdframe2.values[:, 0, 0]) + + # Empty ep + ep = nap.IntervalSet(start=200, end=300) + tsdframe2 = tsdtensor.interpolate(ts, ep) + assert len(tsdframe2) == 0 + From 5167a8e7c1bcc838ea10545a1f9b1c8308e4275d Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Sat, 16 Dec 2023 00:15:40 +0100 Subject: [PATCH 05/10] blacked --- pynapple/core/time_series.py | 18 ++++++++++++------ pynapple/io/__init__.py | 8 +++++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pynapple/core/time_series.py b/pynapple/core/time_series.py index fca39207..d5c1cdc4 100644 --- a/pynapple/core/time_series.py +++ b/pynapple/core/time_series.py @@ -926,7 +926,7 @@ def smooth(self, std, size): window = signal.windows.gaussian(size, std=std) window = window / window.sum() return self.convolve(window) - + def interpolate(self, ts, ep=None, left=None, right=None): """Wrapper of the numpy linear interpolation method. See https://numpy.org/doc/stable/reference/generated/numpy.interp.html for an explanation of the parameters. The argument ts should be Ts, Tsd, TsdFrame, TsdTensor to ensure interpolating from sorted timestamps in the right unit, @@ -951,8 +951,10 @@ def interpolate(self, ts, ep=None, left=None, right=None): ep = self.time_support new_t = ts.restrict(ep).index - - new_shape = len(new_t) if self.values.ndim == 1 else (len(new_t),) + self.shape[1:] + + new_shape = ( + len(new_t) if self.values.ndim == 1 else (len(new_t),) + self.shape[1:] + ) new_d = np.full(new_shape, np.nan) start = 0 @@ -962,20 +964,24 @@ def interpolate(self, ts, ep=None, left=None, right=None): if len(t) and len(tmp): if self.values.ndim == 1: new_d[start : start + len(t)] = np.interp( - t.index.values, tmp.index.values, tmp.values, left=left, right=right + t.index.values, + tmp.index.values, + tmp.values, + left=left, + right=right, ) else: interpolated_values = np.apply_along_axis( lambda row: np.interp(t.index.values, tmp.index.values, row), 0, tmp.values, - ) + ) new_d[start : start + len(t), ...] = interpolated_values start += len(t) return self.__class__(t=new_t, d=new_d, time_support=ep) - + class TsdTensor(NDArrayOperatorsMixin, _AbstractTsd): """ diff --git a/pynapple/io/__init__.py b/pynapple/io/__init__.py index 20b194c7..f4eb2a70 100644 --- a/pynapple/io/__init__.py +++ b/pynapple/io/__init__.py @@ -1,4 +1,10 @@ from .folder import Folder from .interface_npz import NPZFile from .interface_nwb import NWBFile -from .misc import append_NWB_LFP, load_eeg, load_file, load_folder, load_session +from .misc import ( + append_NWB_LFP, + load_eeg, + load_file, + load_folder, + load_session, +) From 696e99591f8d6a60651ce2c73e17cff005a77003 Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Sat, 16 Dec 2023 00:16:17 +0100 Subject: [PATCH 06/10] isorting --- pynapple/core/ts_group.py | 1 - pynapple/io/interface_nwb.py | 1 - 2 files changed, 2 deletions(-) diff --git a/pynapple/core/ts_group.py b/pynapple/core/ts_group.py index 7f1dfaad..a98400f4 100644 --- a/pynapple/core/ts_group.py +++ b/pynapple/core/ts_group.py @@ -20,7 +20,6 @@ jitunion, jitunion_isets, ) - # from .time_units import format_timestamps from .time_index import TsIndex from .time_series import Ts, Tsd, TsdFrame diff --git a/pynapple/io/interface_nwb.py b/pynapple/io/interface_nwb.py index 70bcb4ff..c993ef32 100644 --- a/pynapple/io/interface_nwb.py +++ b/pynapple/io/interface_nwb.py @@ -19,7 +19,6 @@ import numpy as np import pynwb from pynwb import NWBHDF5IO - # from rich.console import Console # from rich.table import Table from tabulate import tabulate From 39ba50d4db45718d63d5966b03a6a850a951ae5e Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Sat, 16 Dec 2023 00:18:25 +0100 Subject: [PATCH 07/10] isorted fixed --- pynapple/core/ts_group.py | 1 + pynapple/io/__init__.py | 8 +------- pynapple/io/interface_nwb.py | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/pynapple/core/ts_group.py b/pynapple/core/ts_group.py index a98400f4..7f1dfaad 100644 --- a/pynapple/core/ts_group.py +++ b/pynapple/core/ts_group.py @@ -20,6 +20,7 @@ jitunion, jitunion_isets, ) + # from .time_units import format_timestamps from .time_index import TsIndex from .time_series import Ts, Tsd, TsdFrame diff --git a/pynapple/io/__init__.py b/pynapple/io/__init__.py index f4eb2a70..20b194c7 100644 --- a/pynapple/io/__init__.py +++ b/pynapple/io/__init__.py @@ -1,10 +1,4 @@ from .folder import Folder from .interface_npz import NPZFile from .interface_nwb import NWBFile -from .misc import ( - append_NWB_LFP, - load_eeg, - load_file, - load_folder, - load_session, -) +from .misc import append_NWB_LFP, load_eeg, load_file, load_folder, load_session diff --git a/pynapple/io/interface_nwb.py b/pynapple/io/interface_nwb.py index c993ef32..70bcb4ff 100644 --- a/pynapple/io/interface_nwb.py +++ b/pynapple/io/interface_nwb.py @@ -19,6 +19,7 @@ import numpy as np import pynwb from pynwb import NWBHDF5IO + # from rich.console import Console # from rich.table import Table from tabulate import tabulate From 36801544a336c23a74c70885fa0d6db6397e1b9c Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Tue, 9 Jan 2024 08:51:25 +0100 Subject: [PATCH 08/10] Columns name propagation and left/right interp args --- pynapple/core/time_series.py | 14 ++++++++++---- tests/npzfilestest/tsd2.json | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pynapple/core/time_series.py b/pynapple/core/time_series.py index d5c1cdc4..1a238a1e 100644 --- a/pynapple/core/time_series.py +++ b/pynapple/core/time_series.py @@ -942,7 +942,7 @@ def interpolate(self, ts, ep=None, left=None, right=None): right : None, optional Value to return for ts > tsd[-1], default is tsd[-1]. """ - if not isinstance(ts, (Ts, Tsd, TsdFrame)): + if not isinstance(ts, (Ts, Tsd, TsdFrame, TsdTensor)): raise RuntimeError( "First argument should be an instance of Ts, Tsd or TsdFrame" ) @@ -972,15 +972,21 @@ def interpolate(self, ts, ep=None, left=None, right=None): ) else: interpolated_values = np.apply_along_axis( - lambda row: np.interp(t.index.values, tmp.index.values, row), + lambda row: np.interp(t.index.values, + tmp.index.values, + row, + left=left, + right=right), 0, tmp.values, ) new_d[start : start + len(t), ...] = interpolated_values start += len(t) - - return self.__class__(t=new_t, d=new_d, time_support=ep) + kwargs_dict = dict(time_support=ep) + if hasattr(self, "columns"): + kwargs_dict["columns"] = self.columns + return self.__class__(t=new_t, d=new_d, **kwargs_dict) class TsdTensor(NDArrayOperatorsMixin, _AbstractTsd): diff --git a/tests/npzfilestest/tsd2.json b/tests/npzfilestest/tsd2.json index db82ff15..001b401d 100644 --- a/tests/npzfilestest/tsd2.json +++ b/tests/npzfilestest/tsd2.json @@ -1,4 +1,4 @@ { - "time": "2023-12-15 18:20:19.335119", + "time": "2024-01-09 08:48:11.597662", "info": "Test description" } \ No newline at end of file From bdea4a104d0d28ff3199b38d1e320ebf893aced6 Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Tue, 9 Jan 2024 08:55:33 +0100 Subject: [PATCH 09/10] Get instead of restrict --- pynapple/core/time_series.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pynapple/core/time_series.py b/pynapple/core/time_series.py index 1a238a1e..f048834c 100644 --- a/pynapple/core/time_series.py +++ b/pynapple/core/time_series.py @@ -959,8 +959,9 @@ def interpolate(self, ts, ep=None, left=None, right=None): start = 0 for i in range(len(ep)): - t = ts.restrict(ep.loc[[i]]) - tmp = self.restrict(ep.loc[[i]]) + t = ts.get(ep.loc[i, "start"], ep.loc[i, "end"]) + tmp = self.get(ep.loc[i, "start"], ep.loc[i, "end"]) + if len(t) and len(tmp): if self.values.ndim == 1: new_d[start : start + len(t)] = np.interp( @@ -972,11 +973,13 @@ def interpolate(self, ts, ep=None, left=None, right=None): ) else: interpolated_values = np.apply_along_axis( - lambda row: np.interp(t.index.values, - tmp.index.values, - row, - left=left, - right=right), + lambda row: np.interp( + t.index.values, + tmp.index.values, + row, + left=left, + right=right, + ), 0, tmp.values, ) From 4c1518b0a065e012d82c0e1a16cd6320c264c702 Mon Sep 17 00:00:00 2001 From: Luigi Petrucco Date: Thu, 11 Jan 2024 22:46:15 +0100 Subject: [PATCH 10/10] removed random import --- tests/test_time_series.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_time_series.py b/tests/test_time_series.py index aaa0c1b1..e81023c8 100755 --- a/tests/test_time_series.py +++ b/tests/test_time_series.py @@ -7,7 +7,6 @@ """Tests of time series for `pynapple` package.""" -from turtle import st import pynapple as nap import numpy as np import pandas as pd