Skip to content

Commit 0a7b3cb

Browse files
committed
Add cloud readIngested integration test
Test downloads the Carbon fiber dataset from cloud, opens its session, reads carbonfiber probe timeseries and stimulator probe data, and verifies values match expected results. https://claude.ai/code/session_01A7rAxYf5pSvs19iVJe3ncL
1 parent 43ed8d2 commit 0a7b3cb

1 file changed

Lines changed: 119 additions & 0 deletions

File tree

tests/test_cloud_read_ingested.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
"""
2+
ndi.unittest.cloud.readIngested - Read an ingested dataset from the cloud.
3+
4+
Downloads the Carbon fiber microelectrode dataset, opens its session,
5+
reads timeseries data from a carbon-fiber probe and a stimulator probe,
6+
and verifies the returned values match expected results.
7+
8+
Requires:
9+
NDI_CLOUD_USERNAME and NDI_CLOUD_PASSWORD environment variables.
10+
11+
Skipped automatically if credentials are not set.
12+
"""
13+
14+
from __future__ import annotations
15+
16+
import os
17+
import tempfile
18+
19+
import numpy as np
20+
import pytest
21+
22+
# ---------------------------------------------------------------------------
23+
# Skip entire module if no credentials
24+
# ---------------------------------------------------------------------------
25+
26+
_has_creds = bool(os.environ.get("NDI_CLOUD_USERNAME") and os.environ.get("NDI_CLOUD_PASSWORD"))
27+
pytestmark = pytest.mark.skipif(not _has_creds, reason="NDI cloud credentials not set")
28+
29+
CARBON_FIBER_ID = "668b0539f13096e04f1feccd"
30+
31+
32+
@pytest.fixture(scope="module")
33+
def dataset():
34+
"""Download the Carbon fiber dataset to a temp directory."""
35+
from ndi.cloud.orchestration import downloadDataset
36+
37+
with tempfile.TemporaryDirectory() as target_dir:
38+
D = downloadDataset(CARBON_FIBER_ID, target_dir)
39+
yield D
40+
41+
42+
@pytest.fixture(scope="module")
43+
def session(dataset):
44+
"""Open the single session in the dataset."""
45+
refs, session_ids, *_ = dataset.session_list()
46+
assert len(session_ids) == 1, f"Expected 1 session, got {len(session_ids)}"
47+
S = dataset.open_session(session_ids[0])
48+
return S
49+
50+
51+
class TestReadIngested:
52+
"""ndi.unittest.cloud.readIngested — verify cloud dataset reads."""
53+
54+
def test_session_list_has_one_entry(self, dataset):
55+
"""session_list should return exactly one session."""
56+
refs, session_ids, *_ = dataset.session_list()
57+
assert len(session_ids) == 1
58+
59+
def test_carbonfiber_probe_timeseries(self, session):
60+
"""Read carbonfiber probe timeseries and check values."""
61+
p_cf = session.getprobes(name="carbonfiber", reference=1)
62+
assert len(p_cf) == 1, f"Expected 1 carbonfiber probe, got {len(p_cf)}"
63+
64+
d1, t1, _ = p_cf[0].readtimeseries(epoch=1, t0=10, t1=20)
65+
66+
# Check first time sample
67+
assert abs(t1[0] - 10.0) < 0.001, f"Expected t1[0] ≈ 10.0, got {t1[0]}"
68+
69+
# Expected values for d1[0, :]
70+
expected_d1_row0 = np.array([
71+
55.7700,
72+
253.3050,
73+
-43.2900,
74+
-9.5550,
75+
30.6150,
76+
23.4000,
77+
16.1850,
78+
-51.6750,
79+
-1.7550,
80+
-14.6250,
81+
-32.7600,
82+
45.6300,
83+
-7.2150,
84+
0.9750,
85+
-1.7550,
86+
45.0450,
87+
])
88+
89+
actual_d1_row0 = d1[0, :]
90+
assert actual_d1_row0.shape == expected_d1_row0.shape, (
91+
f"Expected {expected_d1_row0.shape} channels, got {actual_d1_row0.shape}"
92+
)
93+
np.testing.assert_allclose(
94+
actual_d1_row0,
95+
expected_d1_row0,
96+
atol=0.001,
97+
err_msg="d1[0,:] values do not match expected",
98+
)
99+
100+
def test_stimulator_probe_timeseries(self, session):
101+
"""Read stimulator probe timeseries and check stimid and timing."""
102+
p_st = session.getprobes(type="stimulator")
103+
assert len(p_st) >= 1, "Expected at least 1 stimulator probe"
104+
105+
ds, ts, _ = p_st[0].readtimeseries(epoch=1, t0=10, t1=20)
106+
107+
# ds should be a dict with 'stimid'
108+
assert ds["stimid"] == 31, f"Expected stimid == 31, got {ds['stimid']}"
109+
110+
# ts.stimon should be 15.2590 (within 0.001)
111+
stimon = ts["stimon"]
112+
if hasattr(stimon, "__len__"):
113+
# Could be an array; take scalar value
114+
stimon_val = float(stimon) if np.ndim(stimon) == 0 else float(stimon[0])
115+
else:
116+
stimon_val = float(stimon)
117+
assert abs(stimon_val - 15.2590) < 0.001, (
118+
f"Expected ts.stimon ≈ 15.2590, got {stimon_val}"
119+
)

0 commit comments

Comments
 (0)