Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
gviejo committed May 23, 2024
1 parent e0f2b97 commit 65b6aca
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 22 deletions.
77 changes: 65 additions & 12 deletions docs/api_guide/tutorial_pynapple_nwb.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,18 @@
The dataset in this example can be found [here](https://www.dropbox.com/s/pr1ze1nuiwk8kw9/MyProject.zip?dl=1).
"""
# %%
# !!! warning
# This tutorial uses seaborn and matplotlib for displaying the figure.
#
# You can install both with `pip install matplotlib seaborn`

import numpy as np
import pynapple as nap

# %%
# # NWB
#
# NWB
# --------------
# When loading a NWB file, pynapple will walk through it and test the compatibility of each data structure with a pynapple objects. If the data structure is incompatible, pynapple will ignore it. The class that deals with reading NWB file is [`nap.NWBFile`](../../../reference/io/interface_nwb/). You can pass the path to a NWB file or directly an opened NWB file. Alternatively you can use the function [`nap.load_file`](../../../reference/io/misc/#pynapple.io.misc.load_file).
#
#
# !!! warning
# !!! note
# Creating the NWB file is outside the scope of pynapple. The NWB file used here has already been created before.
# Multiple tools exists to create NWB file automatically. You can check [neuroconv](https://neuroconv.readthedocs.io/en/main/), [NWBGuide](https://nwb-guide.readthedocs.io/en/latest/) or even [NWBmatic](https://github.com/pynapple-org/nwbmatic).

Expand All @@ -45,11 +42,11 @@


# %%
#Loading an entry will get pynapple to read the data.
# Loading an entry will get pynapple to read the data.

z = data['z']

print(z)
print(data['z'])

# %%
# Internally, the `NWBClass` has replaced the pointer to the data with the actual data.
Expand All @@ -75,6 +72,13 @@

print(type(z_chunk.values))

# %%
# You can still apply any high level function of pynapple. For example here, we compute some tuning curves without preloading the dataset.

tc = nap.compute_1d_tuning_curves(data['units'], data['y'], 10)

print(tc)


# %%
# To change this behavior, you can pass `lazy_loading=False` when instantiating the `NWBClass`.
Expand All @@ -87,8 +91,10 @@


# %%
# # Numpy memory map
# In fact, pynapple can work with any type of memory map. Here we read a binary file with `np.memmap`.
# Numpy memory map
# ----------------
#
# In fact, pynapple can work with any type of memory map. Here we read a binary file with [`np.memmap`](https://numpy.org/doc/stable/reference/generated/numpy.memmap.html).

eeg_path = "../../your/path/to/MyProject/sub-A2929/A2929-200711/A2929-200711.eeg"
frequency = 1250 # Hz
Expand All @@ -108,7 +114,7 @@
print(type(fp))

# %%
# Instantiating a pynapple `TsdFrame` with `load_array=False` will not load the data into memory
# Instantiating a pynapple `TsdFrame` will keep the data as a memory map.

eeg = nap.TsdFrame(t=timestep, d=fp)

Expand All @@ -121,4 +127,51 @@


# %%
# # Zarr / h5py
# Zarr
# --------------
#
# It is also possible to use Higher level library like [zarr](https://zarr.readthedocs.io/en/stable/index.html) also not directly.

import zarr
data = zarr.zeros((10000, 5), chunks=(1000, 5), dtype='i4')
timestep = np.arange(len(data))

tsdframe = nap.TsdFrame(t=timestep, d=data)

# %%
# As the warning suggest, `data` is converted to numpy array.

print(type(tsdframe.d))

# %%
# To maintain a zarr array, you can change the argument `load_array` to False.

tsdframe = nap.TsdFrame(t=timestep, d=data, load_array=False)

print(type(tsdframe.d))

# %%
# Within pynapple, numpy memory map are recognized as numpy array while zarr array are not.

print(type(fp), "Is np.ndarray? ", isinstance(fp, np.ndarray))
print(type(data), "Is np.ndarray? ", isinstance(data, np.ndarray))


# %%
# Similar to numpy memory map, you can use pynapple functions directly.

ep = nap.IntervalSet(0, 10)
tsdframe.restrict(ep)

# %%
group = nap.TsGroup({0:nap.Ts(t=[10, 20, 30])})

sta = nap.compute_event_trigger_average(group, tsdframe, 1, (-2, 3))

print(type(tsdframe.values))
print("\n")
print(sta)

# %%
# !!! warning
# Carefulness should still apply when calling any pynapple function on a memory map. Pynapple does not implement any batching function internally. Calling a high level function of pynapple on a dataset that do not fit in memory will likely cause a memory error.
10 changes: 5 additions & 5 deletions pynapple/core/_jitted_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
def jitrestrict(time_array, starts, ends):
n = len(time_array)
m = len(starts)
ix = np.zeros(n, dtype=np.bool_)
ix = np.zeros(n, dtype="int")

k = 0
t = 0
x = 0

while ends[k] < time_array[t]:
k += 1
Expand All @@ -21,8 +22,6 @@ def jitrestrict(time_array, starts, ends):
# Outside
while t < n:
if time_array[t] >= starts[k]:
# ix[t] = True
# t += 1
break
t += 1

Expand All @@ -32,15 +31,16 @@ def jitrestrict(time_array, starts, ends):
k += 1
break
else:
ix[t] = True
ix[x] = t
x += 1
t += 1

if k == m:
break
if t == n:
break

return ix
return ix[0:x]


@jit(nopython=True)
Expand Down
11 changes: 6 additions & 5 deletions pynapple/core/time_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@ class BaseTsd(Base, NDArrayOperatorsMixin, abc.ABC):
def __init__(self, t, d, time_units="s", time_support=None, load_array=True):
super().__init__(t, time_units, time_support)

if not is_array_like(d):
raise TypeError(
"Data should be array-like, i.e. be indexable, iterable and, have attributes "
"`shape`, `ndim` and, `dtype`)."
)

if load_array:
self.values = convert_to_array(d, "d")
else:
if not is_array_like(d):
raise TypeError(
"Data should be array-like, i.e. be indexable, iterable and, have attributes "
"`shape`, `ndim` and, `dtype`)."
)
self.values = d

assert len(self.index) == len(
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ docs = [
"mkdocs-material",
"matplotlib",
"seaborn",
"zarr"
]
dandi = [
"dandi", # Dandi package
Expand Down

0 comments on commit 65b6aca

Please sign in to comment.