From de42eba704d0df2974a5fba0870453fdca3a0461 Mon Sep 17 00:00:00 2001 From: wendtalexander Date: Mon, 20 Oct 2025 16:51:13 +0200 Subject: [PATCH] [doc] adding different repos for delays --- doc/baseline.qmd | 107 +++++++++++++++++++++++++ doc/fi_curve.qmd | 103 ++++++++++++++++++++++++ doc/filestimulus.qmd | 104 +++++++++++++++++++++++++ doc/samplerates.qmd | 182 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 496 insertions(+) create mode 100644 doc/baseline.qmd create mode 100644 doc/fi_curve.qmd create mode 100644 doc/filestimulus.qmd create mode 100644 doc/samplerates.qmd diff --git a/doc/baseline.qmd b/doc/baseline.qmd new file mode 100644 index 0000000..74a95d0 --- /dev/null +++ b/doc/baseline.qmd @@ -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() +``` diff --git a/doc/fi_curve.qmd b/doc/fi_curve.qmd new file mode 100644 index 0000000..af695f6 --- /dev/null +++ b/doc/fi_curve.qmd @@ -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() +``` diff --git a/doc/filestimulus.qmd b/doc/filestimulus.qmd new file mode 100644 index 0000000..f34f569 --- /dev/null +++ b/doc/filestimulus.qmd @@ -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() +``` diff --git a/doc/samplerates.qmd b/doc/samplerates.qmd new file mode 100644 index 0000000..3555445 --- /dev/null +++ b/doc/samplerates.qmd @@ -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