Compare commits
5 Commits
a628359fe9
...
d79fa309bf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d79fa309bf | ||
|
|
f5479f513c | ||
|
|
365e309ce7 | ||
|
|
de42eba704 | ||
|
|
c09a4768f4 |
@@ -34,10 +34,16 @@ website:
|
|||||||
contents:
|
contents:
|
||||||
- text: "Introduction"
|
- text: "Introduction"
|
||||||
href: "index.qmd"
|
href: "index.qmd"
|
||||||
- section: "Tutorials"
|
- text: "Usage"
|
||||||
|
href: "usage.qmd"
|
||||||
|
- text: "Sample Rates"
|
||||||
|
href: "samplerates.qmd"
|
||||||
|
- section: "Delays"
|
||||||
contents:
|
contents:
|
||||||
- "usage.qmd"
|
- "baseline.qmd"
|
||||||
- "calibration.qmd"
|
- "calibration.qmd"
|
||||||
|
- "fi_curve.qmd"
|
||||||
|
- "filestimulus.qmd"
|
||||||
- section: "API"
|
- section: "API"
|
||||||
href: "api/index.qmd"
|
href: "api/index.qmd"
|
||||||
contents:
|
contents:
|
||||||
|
|||||||
107
doc/baseline.qmd
Normal file
107
doc/baseline.qmd
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
---
|
||||||
|
title: Baseline
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
toc: true
|
||||||
|
toc-title: Contents
|
||||||
|
code-block-bg: true
|
||||||
|
code-block-border-left: "#31BAE9"
|
||||||
|
code-line-numbers: true
|
||||||
|
highlight-style: atom-one
|
||||||
|
link-external-icon: true
|
||||||
|
link-external-newwindow: true
|
||||||
|
eqn-number: true
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1. Loading
|
||||||
|
Lets look at the calibration and the first trial of the recording.
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
import rlxnix as rlx
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import numpy as np
|
||||||
|
import scipy.signal as signal
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
|
||||||
|
from util import trial_plot, plot_line_comparision
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dataset_path = pathlib.Path("../oephys2nix/test/AllStimuli/2025-10-20-aa-invivo-2-recording.nix")
|
||||||
|
relacs_path = pathlib.Path("../oephys2nix/test/AllStimuli/2025-10-20-aa-invivo-2_relacs/2025-10-20-aa-invivo-2_relacs.nix")
|
||||||
|
|
||||||
|
dataset = rlx.Dataset(str(dataset_path))
|
||||||
|
relacs = rlx.Dataset(str(relacs_path))
|
||||||
|
|
||||||
|
#INFO: Select the first stimulus of the calibration repro
|
||||||
|
repro_d = dataset.repro_runs("BaselineActivity")[0]
|
||||||
|
repro_r = relacs.repro_runs("BaselineActivity")[0]
|
||||||
|
|
||||||
|
sinus, t = repro_d.trace_data("sinus")
|
||||||
|
sinus_r, t_r = repro_r.trace_data("V-1")
|
||||||
|
|
||||||
|
stimulus_oe, t = repro_d.trace_data("stimulus")
|
||||||
|
stimulus_re, t_r = repro_r.trace_data("GlobalEFieldStimulus")
|
||||||
|
|
||||||
|
local_eod_oe, t = repro_d.trace_data("local-eod")
|
||||||
|
local_eod_re, t_r = repro_r.trace_data("LocalEOD-1")
|
||||||
|
|
||||||
|
global_eod_oe, t = repro_d.trace_data("global-eod")
|
||||||
|
global_eod_re, t_r = repro_r.trace_data("EOD")
|
||||||
|
|
||||||
|
ttl, t = repro_d.trace_data("ttl-line")
|
||||||
|
```
|
||||||
|
### Plotting the First trial
|
||||||
|
If you zoom in you can see a little delay between the different recording systems. It seems that open-ephys is before the relacs recording.
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
# 2. Add traces to the FIRST subplot (row=1, col=1)
|
||||||
|
# Note: Plotly rows and columns are 1-indexed
|
||||||
|
fig = trial_plot(repro_d, repro_r, 1.0)
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
|
### Correlation between the Signals
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
print(f"Duration of the dataset {repro_d.duration}")
|
||||||
|
print(f"Duration of the relacs {repro_r.duration}")
|
||||||
|
# Resample the open-ephys data
|
||||||
|
sinus_resampled = signal.resample(sinus, len(sinus_r))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
fig= plot_line_comparision(t_r, t_r, sinus_r, sinus_resampled, ["sinus-relacs", "sinus-resampled-open-ephys"])
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
|
We need to scale the two signals
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
oephys_lanes = [sinus, local_eod_oe, global_eod_oe, stimulus_oe]
|
||||||
|
relacs_lanes = [sinus_r, local_eod_re, global_eod_re, stimulus_re]
|
||||||
|
names_lanes = ["sinus", "local-eod", "global-eod", "stimulus"]
|
||||||
|
samples_20kHz = t[-1] * 20_000
|
||||||
|
print(samples_20kHz)
|
||||||
|
print(f"Total duration {t[-1]}")
|
||||||
|
print(repro_d.duration)
|
||||||
|
lags_lanes = []
|
||||||
|
for oephys_lane, relacs_lane, names_lane in zip(oephys_lanes, relacs_lanes, names_lanes, strict=True):
|
||||||
|
print(oephys_lane.shape)
|
||||||
|
print(relacs_lane.shape)
|
||||||
|
oephys_lane_resampled = signal.resample(oephys_lane, int(samples_20kHz))
|
||||||
|
correlation = signal.correlate(oephys_lane_resampled, relacs_lane, mode="full")
|
||||||
|
lags = signal.correlation_lags(oephys_lane_resampled.size, relacs_lane.size, mode="full")
|
||||||
|
lag = lags[np.argmax(correlation)]
|
||||||
|
lags_lanes.append(lag)
|
||||||
|
print(f"{names_lane} has a lag of {lag}")
|
||||||
|
```
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
fig = plot_line_comparision(t_r, t_r, np.roll(sinus_r, lags_lanes[0]), sinus_resampled, ["rolled sinus-relacs", "sinus-resampled-open-ephys"])
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
@@ -26,6 +26,8 @@ import numpy as np
|
|||||||
import scipy.signal as signal
|
import scipy.signal as signal
|
||||||
from plotly.subplots import make_subplots
|
from plotly.subplots import make_subplots
|
||||||
|
|
||||||
|
from util import trial_plot, plot_line_comparision
|
||||||
|
|
||||||
|
|
||||||
dataset_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2-recording.nix")
|
dataset_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2-recording.nix")
|
||||||
relacs_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2_relacs/2025-10-08-aa-invivo-2.nix")
|
relacs_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2_relacs/2025-10-08-aa-invivo-2.nix")
|
||||||
@@ -56,91 +58,7 @@ If you zoom in you can see a little delay between the different recording system
|
|||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| echo: False
|
#| echo: False
|
||||||
# 2. Add traces to the FIRST subplot (row=1, col=1)
|
fig = trial_plot(repro_d, repro_r)
|
||||||
# Note: Plotly rows and columns are 1-indexed
|
|
||||||
fig = make_subplots( rows=5, cols=1, shared_xaxes=True, subplot_titles=("TTL-Line",
|
|
||||||
"Stimulus Comparison", "Local EOD Comparison", "Global EOD Comparison",
|
|
||||||
"Sinus Comparison"))
|
|
||||||
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(x=t, y=ttl, name="ttl-line", line_color="magenta"),
|
|
||||||
row=1,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(x=t_r, y=stimulus_re, name="stimulus (relacs)", line_color="blue"),
|
|
||||||
row=2,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(
|
|
||||||
x=t,
|
|
||||||
y=stimulus_oe - np.mean(stimulus_oe), # The same data transformation
|
|
||||||
name="stimulus (open-ephys)",
|
|
||||||
line_color="red",
|
|
||||||
),
|
|
||||||
row=2,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# 3. Add traces to the SECOND subplot (row=2, col=1)
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(x=t_r, y=local_eod_re, name="local EOD (relacs)", line_color="blue"),
|
|
||||||
row=3,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(x=t, y=local_eod_oe, name="local EOD (open-ephys)", line_color="red"),
|
|
||||||
row=3,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# 4. Add traces to the THIRD subplot (row=3, col=1)
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(x=t_r, y=global_eod_re, name="global EOD (relacs)", line_color="blue"),
|
|
||||||
row=4,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(
|
|
||||||
x=t, y=global_eod_oe, name="global EOD (open-ephys)", line_color="red"
|
|
||||||
),
|
|
||||||
row=4,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
# 5. Add traces to the FOURTH subplot (row=4, col=1)
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(x=t_r, y=sinus_r, name="sinus (relacs)", line_color="blue"),
|
|
||||||
row=5,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
fig.add_trace(
|
|
||||||
go.Scatter(x=t, y=sinus, name="sinus (open-ephys)", line_color="red"),
|
|
||||||
row=5,
|
|
||||||
col=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
# 6. Update the layout for a cleaner look
|
|
||||||
fig.update_layout(
|
|
||||||
template="plotly_dark",
|
|
||||||
height=800, # Set the figure height in pixels
|
|
||||||
# Control the legend
|
|
||||||
#legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
|
|
||||||
legend=dict(
|
|
||||||
bgcolor="rgba(0,0,0,0)", # transparent dark (or use "#1f2630" to match bg)
|
|
||||||
bordercolor="#444",
|
|
||||||
borderwidth=0,
|
|
||||||
font=dict(color="#e5ecf6") # matches plotly_dark foreground
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# Add a label to the shared x-axis (targeting the last subplot)
|
|
||||||
fig.update_xaxes(title_text="Time (s)", row=4, col=1)
|
|
||||||
|
|
||||||
# 7. Show the figure
|
|
||||||
fig.show()
|
fig.show()
|
||||||
```
|
```
|
||||||
### Correlation between the Signals
|
### Correlation between the Signals
|
||||||
@@ -155,22 +73,8 @@ sinus_resampled = signal.resample(sinus, len(sinus_r))
|
|||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| echo: False
|
#| echo: False
|
||||||
fig = go.Figure()
|
fig = plot_line_comparision(t_r, t, sinus_r, sinus, ["sinus-relacs", "sinus-oephys"])
|
||||||
fig.add_trace( go.Scatter(x=t_r, y=sinus_r, name="sinus (relacs)", line_color="blue", mode="lines+markers"))
|
fig.show()
|
||||||
fig.add_trace( go.Scatter(x=t_r, y=sinus_resampled, name="sinus-resampled (open-ephys)", line_color="red", mode="lines+markers"))
|
|
||||||
fig.update_layout(
|
|
||||||
template="plotly_dark",
|
|
||||||
height=500, # Set the figure height in pixels
|
|
||||||
# Control the legend
|
|
||||||
#legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
|
|
||||||
legend=dict(
|
|
||||||
bgcolor="rgba(0,0,0,0)", # transparent dark (or use "#1f2630" to match bg)
|
|
||||||
bordercolor="#444",
|
|
||||||
borderwidth=0,
|
|
||||||
font=dict(color="#e5ecf6") # matches plotly_dark foreground
|
|
||||||
)
|
|
||||||
)
|
|
||||||
fig.update_xaxes(range=[0, 0.01])
|
|
||||||
```
|
```
|
||||||
We need to scale the two signals
|
We need to scale the two signals
|
||||||
|
|
||||||
@@ -192,21 +96,6 @@ for oephys_lane, relacs_lane, names_lane in zip(oephys_lanes, relacs_lanes, name
|
|||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| echo: False
|
#| echo: False
|
||||||
fig = go.Figure()
|
fig = plot_line_comparision(t_r, t_r, np.roll(sinus_r, lags_lanes[0]),sinus_resampled, ["sinus-relacs", "sinus-resampled-openepyhs"])
|
||||||
fig.add_trace( go.Scatter(x=t_r, y=sinus_r, name="sinus (relacs)", line_color="blue", mode="lines+markers"))
|
fig.show()
|
||||||
fig.add_trace( go.Scatter(x=t_r, y=np.roll(sinus_resampled, -lags_lanes[0]), name="sinus-resampled (open-ephys)", line_color="red", mode="lines+markers"))
|
|
||||||
fig.update_layout(
|
|
||||||
title="Sinus",
|
|
||||||
template="plotly_dark",
|
|
||||||
height=500, # Set the figure height in pixels
|
|
||||||
# Control the legend
|
|
||||||
#legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
|
|
||||||
legend=dict(
|
|
||||||
bgcolor="rgba(0,0,0,0)", # transparent dark (or use "#1f2630" to match bg)
|
|
||||||
bordercolor="#444",
|
|
||||||
borderwidth=0,
|
|
||||||
font=dict(color="#e5ecf6") # matches plotly_dark foreground
|
|
||||||
)
|
|
||||||
)
|
|
||||||
fig.update_xaxes(range=[0, 0.01])
|
|
||||||
```
|
```
|
||||||
|
|||||||
103
doc/fi_curve.qmd
Normal file
103
doc/fi_curve.qmd
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
title: FI Curve
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
toc: true
|
||||||
|
toc-title: Contents
|
||||||
|
code-block-bg: true
|
||||||
|
code-block-border-left: "#31BAE9"
|
||||||
|
code-line-numbers: true
|
||||||
|
highlight-style: atom-one
|
||||||
|
link-external-icon: true
|
||||||
|
link-external-newwindow: true
|
||||||
|
eqn-number: true
|
||||||
|
---
|
||||||
|
|
||||||
|
### FI Curve
|
||||||
|
Lets look at the calibration and the first trial of the recording.
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
import rlxnix as rlx
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import numpy as np
|
||||||
|
import scipy.signal as signal
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
|
||||||
|
from util import trial_plot, plot_line_comparision
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dataset_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2-recording.nix")
|
||||||
|
relacs_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2_relacs/2025-10-08-aa-invivo-2.nix")
|
||||||
|
|
||||||
|
dataset = rlx.Dataset(str(dataset_path))
|
||||||
|
relacs = rlx.Dataset(str(relacs_path))
|
||||||
|
|
||||||
|
#INFO: Select the first stimulus of the calibration repro
|
||||||
|
repro_d = dataset.repro_runs("FICurve_1")[0].stimuli[2]
|
||||||
|
repro_r = relacs.repro_runs("FICurve_1")[0].stimuli[2]
|
||||||
|
|
||||||
|
sinus, t = repro_d.trace_data("sinus")
|
||||||
|
sinus_r, t_r = repro_r.trace_data("V-1")
|
||||||
|
|
||||||
|
stimulus_oe, t = repro_d.trace_data("stimulus")
|
||||||
|
stimulus_re, t_r = repro_r.trace_data("GlobalEFieldStimulus")
|
||||||
|
|
||||||
|
local_eod_oe, t = repro_d.trace_data("local-eod")
|
||||||
|
local_eod_re, t_r = repro_r.trace_data("LocalEOD-1")
|
||||||
|
|
||||||
|
global_eod_oe, t = repro_d.trace_data("global-eod")
|
||||||
|
global_eod_re, t_r = repro_r.trace_data("EOD")
|
||||||
|
|
||||||
|
ttl, t = repro_d.trace_data("ttl-line")
|
||||||
|
```
|
||||||
|
### Plotting the First trial
|
||||||
|
If you zoom in you can see a little delay between the different recording systems. It seems that open-ephys is before the relacs recording.
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
# 2. Add traces to the FIRST subplot (row=1, col=1)
|
||||||
|
# Note: Plotly rows and columns are 1-indexed
|
||||||
|
fig = trial_plot(repro_d, repro_r)
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
|
### Correlation between the Signals
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
print(f"Duration of the dataset {repro_d.duration}")
|
||||||
|
print(f"Duration of the relacs {repro_r.duration}")
|
||||||
|
# Resample the open-ephys data
|
||||||
|
sinus_resampled = signal.resample(sinus, len(sinus_r))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
fig= plot_line_comparision(t_r, t_r, sinus_r, sinus_resampled, ["sinus-relacs", "sinus-resampled-open-ephys"])
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
|
We need to scale the two signals
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
oephys_lanes = [sinus, local_eod_oe, global_eod_oe, stimulus_oe]
|
||||||
|
relacs_lanes = [sinus_r, local_eod_re, global_eod_re, stimulus_re]
|
||||||
|
names_lanes = ["sinus", "local-eod", "global-eod", "stimulus"]
|
||||||
|
lags_lanes = []
|
||||||
|
for oephys_lane, relacs_lane, names_lane in zip(oephys_lanes, relacs_lanes, names_lanes, strict=True):
|
||||||
|
print(oephys_lane.shape)
|
||||||
|
print(relacs_lane.shape)
|
||||||
|
oephys_lane_resampled = signal.resample(oephys_lane, len(relacs_lane))
|
||||||
|
correlation = signal.correlate(oephys_lane_resampled, relacs_lane, mode="full")
|
||||||
|
lags = signal.correlation_lags(oephys_lane_resampled.size, relacs_lane.size, mode="full")
|
||||||
|
lag = lags[np.argmax(correlation)]
|
||||||
|
lags_lanes.append(lag)
|
||||||
|
print(f"{names_lane} has a lag of {lag}")
|
||||||
|
```
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
fig = plot_line_comparision(t_r, t_r, np.roll(sinus_r, lags_lanes[0]), sinus_resampled, ["rolled sinus-relacs", "sinus-resampled-open-ephys"])
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
104
doc/filestimulus.qmd
Normal file
104
doc/filestimulus.qmd
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
title: File Stimulus
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
toc: true
|
||||||
|
toc-title: Contents
|
||||||
|
code-block-bg: true
|
||||||
|
code-block-border-left: "#31BAE9"
|
||||||
|
code-line-numbers: true
|
||||||
|
highlight-style: atom-one
|
||||||
|
link-external-icon: true
|
||||||
|
link-external-newwindow: true
|
||||||
|
eqn-number: true
|
||||||
|
---
|
||||||
|
|
||||||
|
### File Stimulus
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
import rlxnix as rlx
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import numpy as np
|
||||||
|
import scipy.signal as signal
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
|
||||||
|
from util import trial_plot, plot_line_comparision
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dataset_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2-recording.nix")
|
||||||
|
relacs_path = pathlib.Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2_relacs/2025-10-08-aa-invivo-2.nix")
|
||||||
|
|
||||||
|
dataset = rlx.Dataset(str(dataset_path))
|
||||||
|
relacs = rlx.Dataset(str(relacs_path))
|
||||||
|
|
||||||
|
#INFO: Select the first stimulus of the calibration repro
|
||||||
|
repro_d = dataset.repro_runs("FileStimulus_1")[0].stimuli[2]
|
||||||
|
repro_r = relacs.repro_runs("FileStimulus_1")[0].stimuli[2]
|
||||||
|
|
||||||
|
sinus, t = repro_d.trace_data("sinus")
|
||||||
|
sinus_r, t_r = repro_r.trace_data("V-1")
|
||||||
|
|
||||||
|
stimulus_oe, t = repro_d.trace_data("stimulus")
|
||||||
|
stimulus_re, t_r = repro_r.trace_data("GlobalEFieldStimulus")
|
||||||
|
|
||||||
|
local_eod_oe, t = repro_d.trace_data("local-eod")
|
||||||
|
local_eod_re, t_r = repro_r.trace_data("LocalEOD-1")
|
||||||
|
|
||||||
|
global_eod_oe, t = repro_d.trace_data("global-eod")
|
||||||
|
global_eod_re, t_r = repro_r.trace_data("EOD")
|
||||||
|
|
||||||
|
ttl, t = repro_d.trace_data("ttl-line")
|
||||||
|
```
|
||||||
|
### Plotting the First trial
|
||||||
|
If you zoom in you can see a little delay between the different recording systems. It seems that open-ephys is before the relacs recording.
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
# 2. Add traces to the FIRST subplot (row=1, col=1)
|
||||||
|
# Note: Plotly rows and columns are 1-indexed
|
||||||
|
fig = trial_plot(repro_d, repro_r)
|
||||||
|
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
|
### Correlation between the Signals
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
print(f"Duration of the dataset {repro_d.duration}")
|
||||||
|
print(f"Duration of the relacs {repro_r.duration}")
|
||||||
|
# Resample the open-ephys data
|
||||||
|
|
||||||
|
sinus_resampled = signal.resample(sinus, len(sinus_r))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
fig= plot_line_comparision(t_r, t_r, sinus_r, sinus_resampled, ["sinus-relacs", "sinus-resampled-open-ephys"])
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
|
We need to scale the two signals
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
oephys_lanes = [sinus, local_eod_oe, global_eod_oe, stimulus_oe]
|
||||||
|
relacs_lanes = [sinus_r, local_eod_re, global_eod_re, stimulus_re]
|
||||||
|
names_lanes = ["sinus", "local-eod", "global-eod", "stimulus"]
|
||||||
|
lags_lanes = []
|
||||||
|
for oephys_lane, relacs_lane, names_lane in zip(oephys_lanes, relacs_lanes, names_lanes, strict=True):
|
||||||
|
print(oephys_lane.shape)
|
||||||
|
print(relacs_lane.shape)
|
||||||
|
oephys_lane_resampled = signal.resample(oephys_lane, len(relacs_lane))
|
||||||
|
correlation = signal.correlate(oephys_lane_resampled, relacs_lane, mode="full")
|
||||||
|
lags = signal.correlation_lags(oephys_lane_resampled.size, relacs_lane.size, mode="full")
|
||||||
|
lag = lags[np.argmax(correlation)]
|
||||||
|
lags_lanes.append(lag)
|
||||||
|
print(f"{names_lane} has a lag of {lag}")
|
||||||
|
```
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
fig = plot_line_comparision(t_r, t_r, np.roll(sinus_r, lags_lanes[0]), sinus_resampled, ["rolled sinus-relacs", "sinus-resampled-open-ephys"])
|
||||||
|
fig.show()
|
||||||
|
```
|
||||||
182
doc/samplerates.qmd
Normal file
182
doc/samplerates.qmd
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
---
|
||||||
|
title: Differences between sample rates
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
toc: true
|
||||||
|
toc-title: Contents
|
||||||
|
code-block-bg: true
|
||||||
|
code-block-border-left: "#31BAE9"
|
||||||
|
code-line-numbers: true
|
||||||
|
highlight-style: atom-one
|
||||||
|
link-external-icon: true
|
||||||
|
link-external-newwindow: true
|
||||||
|
eqn-number: true
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1. General Idea
|
||||||
|
The two aquisition systems have a different default sampling rate and currently
|
||||||
|
there is a delay and maybe this is due to the different sampling rates.
|
||||||
|
|
||||||
|
`open-ephys` has a sample-rate of 30 kHz and `relacs` one of 20 kHz. In this
|
||||||
|
test we have two different recordings with one where the open-epyhs has 30 kHz
|
||||||
|
and the other with 20 kHz.
|
||||||
|
|
||||||
|
### 2. Loading the data
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import rlxnix as rlx
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
import scipy.signal as signal
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# Path to test recording with different samplerate open-epyhs 30kHz and relacs 20kHz
|
||||||
|
dataset_path_diff_fs = Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2-recording.nix")
|
||||||
|
relacs_path_diff_fs = Path("../oephys2nix/test/Test1/2025-10-08-aa-invivo-2_relacs/2025-10-08-aa-invivo-2.nix")
|
||||||
|
|
||||||
|
# Path to test recording with same samplerate open-epyhs 20kHz and relacs 20kHz
|
||||||
|
dataset_path_same_fs = Path("../oephys2nix/test/Test2/2025-10-08-ab-invivo-2-recording.nix")
|
||||||
|
relacs_path_same_fs = Path("../oephys2nix/test/Test2/2025-10-08-ab-invivo-2_relacs/2025-10-08-ab-invivo-2.nix")
|
||||||
|
|
||||||
|
|
||||||
|
dataset_diff_fs = rlx.Dataset(str(dataset_path_diff_fs))
|
||||||
|
relacs_diff_fs = rlx.Dataset(str(relacs_path_diff_fs))
|
||||||
|
|
||||||
|
dataset_same_fs = rlx.Dataset(str(dataset_path_same_fs))
|
||||||
|
relacs_same_fs = rlx.Dataset(str(relacs_path_same_fs))
|
||||||
|
|
||||||
|
|
||||||
|
repro_diff_fs_d = dataset_diff_fs.repro_runs("FileStimulus_1")[0].stimuli[2]
|
||||||
|
repro_diff_fs_r = relacs_diff_fs.repro_runs("FileStimulus_1")[0].stimuli[2]
|
||||||
|
|
||||||
|
repro_same_fs_d = dataset_same_fs.repro_runs("FileStimulus_1")[0].stimuli[2]
|
||||||
|
repro_same_fs_r = relacs_same_fs.repro_runs("FileStimulus_1")[0].stimuli[2]
|
||||||
|
|
||||||
|
#sinus, t = repro_diff_fs_d.trace_data("sinus")
|
||||||
|
#sinus_r, t_r = repro_diff_fs_r.trace_data("V-1")
|
||||||
|
|
||||||
|
stimulus_diff_oe, t_diff = repro_diff_fs_d.trace_data("stimulus")
|
||||||
|
stimulus_diff_re, t_diff_r = repro_diff_fs_r.trace_data("GlobalEFieldStimulus")
|
||||||
|
|
||||||
|
stimulus_same_oe, t_same = repro_same_fs_d.trace_data("stimulus")
|
||||||
|
stimulus_same_re, t_same_r = repro_same_fs_r.trace_data("GlobalEFieldStimulus")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Samples in the different recordings for one stimulus
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
|
||||||
|
print(f"Samples open-epyhs [30 kHz] for one trial: {stimulus_diff_oe.shape}")
|
||||||
|
print(f"Samples relacs for one trial: {stimulus_diff_re.shape}")
|
||||||
|
|
||||||
|
print(f"Samples open-epyhs [20 kHz] for one trial: {stimulus_same_oe.shape}")
|
||||||
|
print(f"Samples relacs for one trial: {stimulus_same_re.shape}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Plotting first trial
|
||||||
|
Here we plot the different output stimulus, different sample rates
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
x_lim = 0.05
|
||||||
|
fig = make_subplots( rows=2, cols=1, shared_xaxes=True, subplot_titles=("Different fs [30 khz and 20 kHz]", "Same fs [20kHz]"))
|
||||||
|
|
||||||
|
|
||||||
|
fig.add_trace( go.Scattergl(x=t_diff_r[t_diff_r<x_lim],
|
||||||
|
y=stimulus_diff_re[t_diff_r<x_lim],
|
||||||
|
showlegend=False, line_color="blue",
|
||||||
|
mode="markers+lines"), row=1, col=1)
|
||||||
|
fig.add_trace( go.Scattergl(x=t_diff[t_diff<x_lim],
|
||||||
|
y=stimulus_diff_oe[t_diff<x_lim],
|
||||||
|
showlegend=False,
|
||||||
|
line_color="red", mode="markers+lines"), row=1, col=1)
|
||||||
|
|
||||||
|
fig.add_trace( go.Scattergl(x=t_same_r[t_same_r<x_lim],
|
||||||
|
y=stimulus_same_re[t_same_r<x_lim],
|
||||||
|
name="GlobalStimulus (relacs)", line_color="blue",
|
||||||
|
mode="markers+lines") , row=2, col=1)
|
||||||
|
fig.add_trace( go.Scattergl(x=t_same[t_same<x_lim],
|
||||||
|
y=stimulus_same_oe[t_same<x_lim],
|
||||||
|
name="GlobalStimulus (open-ephys)",
|
||||||
|
line_color="red", mode="markers+lines"),row=2, col=1)
|
||||||
|
fig.update_layout(
|
||||||
|
template="plotly_dark",
|
||||||
|
height=400,
|
||||||
|
legend=dict(
|
||||||
|
bgcolor="rgba(0,0,0,0)",
|
||||||
|
bordercolor="#444",
|
||||||
|
borderwidth=0,
|
||||||
|
font=dict(color="#e5ecf6"),
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.06,
|
||||||
|
xanchor="right",
|
||||||
|
x=0.72,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_xaxes(range=[0, 0.01])
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Lags in recodings
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
# resample to 20 kHz
|
||||||
|
stimulus_diff_oe_resampled = signal.resample(stimulus_diff_oe, len(stimulus_same_re))
|
||||||
|
correlation_diff = signal.correlate(stimulus_diff_oe_resampled, stimulus_diff_re, mode="full")
|
||||||
|
lags_diff = signal.correlation_lags(stimulus_diff_oe_resampled.size, stimulus_diff_re.size, mode="full")
|
||||||
|
lag_diff = lags_diff[np.argmax(correlation_diff)]
|
||||||
|
|
||||||
|
correlation_same = signal.correlate(stimulus_same_oe, stimulus_same_re, mode="full")
|
||||||
|
lags_same = signal.correlation_lags(stimulus_same_oe.size, stimulus_same_re.size, mode="full")
|
||||||
|
lag_same = lags_same[np.argmax(correlation_same)]
|
||||||
|
|
||||||
|
print(f"The lag in with different sampling rates is {lag_diff}, and with the same sample rate is {lag_same}")
|
||||||
|
```
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| echo: False
|
||||||
|
fig = make_subplots( rows=2, cols=1, shared_xaxes=True, subplot_titles=("Different fs [30 khz and 20 kHz]", "Same fs [20kHz]"))
|
||||||
|
|
||||||
|
fig.add_trace( go.Scattergl(x=t_diff_r[t_diff_r<x_lim],
|
||||||
|
y=np.roll(stimulus_diff_re[t_diff_r<x_lim], lag_diff),
|
||||||
|
line_color="blue",
|
||||||
|
showlegend=False,
|
||||||
|
mode="markers+lines"), row=1, col=1)
|
||||||
|
fig.add_trace( go.Scattergl(x=t_diff[t_diff<x_lim],
|
||||||
|
y=stimulus_diff_oe[t_diff<x_lim], showlegend=False,
|
||||||
|
line_color="red", mode="markers+lines"), row=1,
|
||||||
|
col=1)
|
||||||
|
|
||||||
|
fig.add_trace( go.Scattergl(x=t_same_r[t_same_r<x_lim],
|
||||||
|
y=np.roll(stimulus_same_re[t_same_r<x_lim], lag_same),
|
||||||
|
name="GlobalStimulus (relacs)", line_color="blue",
|
||||||
|
mode="markers+lines") , row=2, col=1)
|
||||||
|
fig.add_trace( go.Scattergl(x=t_same[t_same<x_lim],
|
||||||
|
y=stimulus_same_oe[t_same<x_lim],
|
||||||
|
name="GlobalStimulus (open-ephys)",
|
||||||
|
line_color="red", mode="markers+lines"),row=2, col=1)
|
||||||
|
fig.update_layout(
|
||||||
|
template="plotly_dark",
|
||||||
|
height=400,
|
||||||
|
legend=dict(
|
||||||
|
bgcolor="rgba(0,0,0,0)",
|
||||||
|
bordercolor="#444",
|
||||||
|
borderwidth=0,
|
||||||
|
font=dict(color="#e5ecf6"),
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.06,
|
||||||
|
xanchor="right",
|
||||||
|
x=0.72,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_xaxes(range=[0, 0.01])
|
||||||
|
```
|
||||||
|
### 6. Conculsion
|
||||||
|
|
||||||
|
Lags of simuliar magnitude exists in both recordings therefor the sample rate is not the problem!
|
||||||
182
doc/util.py
Normal file
182
doc/util.py
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
import numpy as np
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
|
||||||
|
|
||||||
|
def trial_plot(repro_d, repro_r, x_lim: int = 1.0):
|
||||||
|
sinus, t = repro_d.trace_data("sinus")
|
||||||
|
sinus_r, t_r = repro_r.trace_data("V-1")
|
||||||
|
|
||||||
|
stimulus_oe, t = repro_d.trace_data("stimulus")
|
||||||
|
stimulus_re, t_r = repro_r.trace_data("GlobalEFieldStimulus")
|
||||||
|
|
||||||
|
local_eod_oe, t = repro_d.trace_data("local-eod")
|
||||||
|
local_eod_re, t_r = repro_r.trace_data("LocalEOD-1")
|
||||||
|
|
||||||
|
global_eod_oe, t = repro_d.trace_data("global-eod")
|
||||||
|
global_eod_re, t_r = repro_r.trace_data("EOD")
|
||||||
|
|
||||||
|
ttl, t = repro_d.trace_data("ttl-line")
|
||||||
|
|
||||||
|
mask = t < x_lim
|
||||||
|
mask_r = t_r < x_lim
|
||||||
|
|
||||||
|
t = t[mask]
|
||||||
|
t_r = t_r[mask_r]
|
||||||
|
sinus = sinus[mask]
|
||||||
|
sinus_r = sinus_r[mask_r]
|
||||||
|
stimulus_oe = stimulus_oe[mask]
|
||||||
|
stimulus_re = stimulus_re[mask_r]
|
||||||
|
local_eod_oe = local_eod_oe[mask]
|
||||||
|
local_eod_re = local_eod_re[mask_r]
|
||||||
|
global_eod_oe = global_eod_oe[mask]
|
||||||
|
global_eod_re = global_eod_re[mask_r]
|
||||||
|
ttl = ttl[mask]
|
||||||
|
|
||||||
|
fig = make_subplots(
|
||||||
|
rows=5,
|
||||||
|
cols=1,
|
||||||
|
shared_xaxes=True,
|
||||||
|
subplot_titles=(
|
||||||
|
"TTL-Line",
|
||||||
|
"Stimulus",
|
||||||
|
"Local EOD",
|
||||||
|
"Global EOD",
|
||||||
|
"Sinus",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t, y=ttl, name="ttl-line", line_color="magenta"),
|
||||||
|
row=1,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t_r, y=stimulus_re, line_color="blue"),
|
||||||
|
row=2,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(
|
||||||
|
x=t,
|
||||||
|
y=stimulus_oe - np.mean(stimulus_oe), # The same data transformation
|
||||||
|
name="stimulus (open-ephys)",
|
||||||
|
line_color="red",
|
||||||
|
),
|
||||||
|
row=2,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. Add traces to the SECOND subplot (row=2, col=1)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t_r, y=local_eod_re, line_color="blue", showlegend=False),
|
||||||
|
row=3,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t, y=local_eod_oe, showlegend=False, line_color="red"),
|
||||||
|
row=3,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4. Add traces to the THIRD subplot (row=3, col=1)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t_r, y=global_eod_re, showlegend=False, line_color="blue"),
|
||||||
|
row=4,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t, y=global_eod_oe, showlegend=False, line_color="red"),
|
||||||
|
row=4,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t_r, y=sinus_r, showlegend=False, line_color="blue"),
|
||||||
|
row=5,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(x=t, y=sinus, showlegend=False, line_color="red"),
|
||||||
|
row=5,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 6. Update the layout for a cleaner look
|
||||||
|
fig.update_layout(
|
||||||
|
template="plotly_dark",
|
||||||
|
height=800, # Set the figure height in pixels
|
||||||
|
# Control the legend
|
||||||
|
legend=dict(
|
||||||
|
bgcolor="rgba(0,0,0,0)", # transparent dark (or use "#1f2630" to match bg)
|
||||||
|
bordercolor="#444",
|
||||||
|
borderwidth=0,
|
||||||
|
font=dict(color="#e5ecf6"), # matches plotly_dark foreground
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.05,
|
||||||
|
xanchor="right",
|
||||||
|
x=0.72,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
# Add a label to the shared x-axis (targeting the last subplot)
|
||||||
|
fig.update_xaxes(title_text="Time (s)", row=4, col=1)
|
||||||
|
fig.update_xaxes(range=[0, 0.5])
|
||||||
|
|
||||||
|
return fig
|
||||||
|
|
||||||
|
|
||||||
|
def plot_line_comparision(
|
||||||
|
time_relacs,
|
||||||
|
time_oephys,
|
||||||
|
data_relacs,
|
||||||
|
data_oephys,
|
||||||
|
labels,
|
||||||
|
):
|
||||||
|
x_lim = 1.0
|
||||||
|
mask = time_oephys < x_lim
|
||||||
|
mask_r = time_relacs < x_lim
|
||||||
|
|
||||||
|
time_oephys = time_oephys[mask]
|
||||||
|
time_relacs = time_relacs[mask_r]
|
||||||
|
|
||||||
|
data_oephys = data_oephys[mask]
|
||||||
|
data_relacs = data_relacs[mask_r]
|
||||||
|
|
||||||
|
fig = go.Figure()
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(
|
||||||
|
x=time_relacs,
|
||||||
|
y=data_relacs,
|
||||||
|
name=labels[0],
|
||||||
|
line_color="blue",
|
||||||
|
mode="lines+markers",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(
|
||||||
|
x=time_oephys,
|
||||||
|
y=data_oephys,
|
||||||
|
name=labels[1],
|
||||||
|
line_color="red",
|
||||||
|
mode="lines+markers",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fig.update_layout(
|
||||||
|
template="plotly_dark",
|
||||||
|
height=500, # Set the figure height in pixels
|
||||||
|
legend=dict(
|
||||||
|
bgcolor="rgba(0,0,0,0)",
|
||||||
|
bordercolor="#444",
|
||||||
|
borderwidth=0,
|
||||||
|
font_color="#e5ecf6",
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.05,
|
||||||
|
xanchor="right",
|
||||||
|
x=0.72,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
fig.update_xaxes(range=[0, 0.01])
|
||||||
|
return fig
|
||||||
@@ -225,7 +225,7 @@ class StimulusToNix:
|
|||||||
for i, repro in enumerate(self.dataset.repro_runs()):
|
for i, repro in enumerate(self.dataset.repro_runs()):
|
||||||
log.debug(repro.name)
|
log.debug(repro.name)
|
||||||
log.debug(f"Current Position {current_position.item()}")
|
log.debug(f"Current Position {current_position.item()}")
|
||||||
if repro.duration < 1.0:
|
if repro.duration < 0.05:
|
||||||
log.warning(f"Skipping repro {repro.name} because it is two short")
|
log.warning(f"Skipping repro {repro.name} because it is two short")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user