From 3ba0d4eb6f80984dd1c7db33382ba5947b259069 Mon Sep 17 00:00:00 2001 From: BalzaniEdoardo Date: Fri, 15 Nov 2024 16:54:43 -0500 Subject: [PATCH] fixed dark mode --- docs/assets/NeMoS_Logo_CMYK_White.svg | 1 + docs/background/README.md | 30 ++++++++++++++- docs/conf.py | 5 ++- docs/how_to_guide/README.md | 37 ++++++++++++++++++- docs/installation.md | 2 +- docs/tutorials/README.md | 45 ++++++++++++++++++++++- docs/tutorials/plot_04_v1_cells.md | 4 +- docs/tutorials/plot_05_place_cells.md | 31 +++++++++------- docs/tutorials/plot_06_calcium_imaging.md | 34 ++++++++++------- 9 files changed, 152 insertions(+), 37 deletions(-) create mode 100755 docs/assets/NeMoS_Logo_CMYK_White.svg diff --git a/docs/assets/NeMoS_Logo_CMYK_White.svg b/docs/assets/NeMoS_Logo_CMYK_White.svg new file mode 100755 index 00000000..cb453c01 --- /dev/null +++ b/docs/assets/NeMoS_Logo_CMYK_White.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/background/README.md b/docs/background/README.md index 2fdf2c7d..c4fa1093 100644 --- a/docs/background/README.md +++ b/docs/background/README.md @@ -14,12 +14,38 @@ pip install nemos[examples] ::: +::::{grid} 1 2 3 3 + +:::{grid-item-card} ```{toctree} :maxdepth: 2 -:caption: Contents plot_00_conceptual_intro.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_01_1D_basis_function.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_02_ND_basis_function.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_03_1D_convolution.md -``` \ No newline at end of file +``` +::: + +:::: diff --git a/docs/conf.py b/docs/conf.py index 42c285c0..6b04518e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -111,7 +111,6 @@ html_theme = 'pydata_sphinx_theme' -html_logo = "assets/NeMoS_Logo_CMYK_Full.svg" html_favicon = "assets/NeMoS_favicon.ico" # Additional theme options @@ -133,6 +132,10 @@ "show_prev_next": True, "header_links_before_dropdown": 6, "navigation_depth": 3, + "logo": { + "image_light": "_static/NeMoS_Logo_CMYK_Full.svg", + "image_dark": "_static/NeMoS_Logo_CMYK_White.svg", + } } html_context = { diff --git a/docs/how_to_guide/README.md b/docs/how_to_guide/README.md index a7a5a231..188fe5b2 100644 --- a/docs/how_to_guide/README.md +++ b/docs/how_to_guide/README.md @@ -14,13 +14,46 @@ pip install nemos[examples] ::: +::::{grid} 1 2 3 3 + +:::{grid-item-card} ```{toctree} :maxdepth: 2 -:caption: Contents plot_02_glm_demo.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_03_population_glm.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_04_batch_glm.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_05_sklearn_pipeline_cv_demo.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_06_glm_pytree.md -``` \ No newline at end of file +``` +::: + +:::: diff --git a/docs/installation.md b/docs/installation.md index 49410ed6..b8cfd47e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,4 +1,4 @@ - +# Install ## Prerequisites diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md index 909f4364..54f9845b 100644 --- a/docs/tutorials/README.md +++ b/docs/tutorials/README.md @@ -12,14 +12,55 @@ pip install nemos[examples] ``` ::: +::::{grid} 1 2 3 3 + +:::{grid-item-card} ```{toctree} :maxdepth: 2 -:caption: Contents plot_01_current_injection.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_02_head_direction.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_03_grid_cells.md +``` +::: + + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_04_v1_cells.md +``` +::: + + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 + plot_05_place_cells.md +``` +::: + +:::{grid-item-card} +```{toctree} +:maxdepth: 2 plot_06_calcium_imaging.md -``` \ No newline at end of file +``` +::: + +:::: \ No newline at end of file diff --git a/docs/tutorials/plot_04_v1_cells.md b/docs/tutorials/plot_04_v1_cells.md index 8a55c83d..cfe594b9 100644 --- a/docs/tutorials/plot_04_v1_cells.md +++ b/docs/tutorials/plot_04_v1_cells.md @@ -166,7 +166,7 @@ sta = nap.compute_event_trigger_average(spikes, stimulus, binsize=0.025, windowsize=(-0.15, 0.0)) ``` -sta is a `TsdTensor`, which gives us the 2d receptive field at each of the +sta is a [`TsdTensor`](https://pynapple.org/generated/pynapple.core.time_series.TsdTensor.html), which gives us the 2d receptive field at each of the time points. @@ -291,7 +291,7 @@ filtered_stimulus We can see that the time points are now aligned, and we've filled forward the values the way we'd like. -Now, similar to the [head direction tutorial](../plot_02_head_direction), we'll +Now, similar to the [head direction tutorial](plot_02_head_direction), we'll use the log-stretched raised cosine basis to create the predictor for our GLM: diff --git a/docs/tutorials/plot_05_place_cells.md b/docs/tutorials/plot_05_place_cells.md index ed81e904..59e81eae 100644 --- a/docs/tutorials/plot_05_place_cells.md +++ b/docs/tutorials/plot_05_place_cells.md @@ -34,6 +34,9 @@ from nemos import _documentation_utils as doc_plots # configure plots some plt.style.use(nmo.styles.plot_style) + +# shut down jax to numpy conversion warning +nap.nap_config.suppress_conversion_warnings = True ``` ## Data Streaming @@ -118,7 +121,7 @@ for i, n in enumerate(order): ## Phase precession -In addition to place modulation, place cells are also modulated by the theta oscillation. The phase at which neurons fire is dependant of the position. This phenomen is called "phase precession" (see [J. O’Keefe, M. L. Recce, "Phase relationship between hippocampal place units and the EEG theta rhythm." Hippocampus 3, 317–330 (1993).](https://doi.org/10.1002/hipo.450030307) +In addition to place modulation, place cells are also modulated by the theta oscillation. The phase at which neurons fire is dependant of the position. This phenomen is called "phase precession" (see [J. O’Keefe, M. L. Recce, "Phase relationship between hippocampal place units and the EEG theta rhythm." Hippocampus 3, 317–330 (1993).](https://doi.org/10.1002/hipo.450030307)). Let's compute the response of the neuron as a function of both theta and position. The phase of theta has already been computed but we have to bring it to the same dimension as the position feature. While the position has been sampled at 40Hz, the theta phase has been computed at 1250Hz. Later on during the analysis, we will use a bin size of 5 ms for counting the spikes. Since this corresponds to an intermediate frequency between 40 and 1250 Hz, we will bring all the features to 200Hz already. @@ -142,7 +145,7 @@ data = nap.TsdFrame( print(data) ``` -`data` is a `TsdFrame` that contains the position and phase. Before calling `compute_2d_tuning_curves` from pynapple to observe the theta phase precession, we will restrict the analysis to the place field of one neuron. +`data` is a [`TsdFrame`](https://pynapple.org/generated/pynapple.core.time_series.TsdTensor.html) that contains the position and phase. Before calling [`compute_2d_tuning_curves`](https://pynapple.org/generated/pynapple.process.tuning_curves.html#pynapple.process.tuning_curves.compute_2d_tuning_curves) from pynapple to observe the theta phase precession, we will restrict the analysis to the place field of one neuron. There are a lot of neurons but for this analysis, we will focus on one neuron only. @@ -163,7 +166,7 @@ This neurons place field is between 0 and 60 cm within the linear track. Here we within_ep = position.threshold(60.0, method="below").time_support ``` -`within_ep` is an `IntervalSet`. We can now give it to `compute_2d_tuning_curves` along with the spiking activity and the position-phase features. +`within_ep` is an [`IntervalSet`](https://pynapple.org/generated/pynapple.core.interval_set.IntervalSet.html). We can now give it to [`compute_2d_tuning_curves`](https://pynapple.org/generated/pynapple.process.tuning_curves.html#pynapple.process.tuning_curves.compute_2d_tuning_curves) along with the spiking activity and the position-phase features. ```{code-cell} ipython3 @@ -219,14 +222,14 @@ for s, e in data.time_support.values: # Time support contains the epochs speed = nap.Tsd(t=data.t, d=np.hstack(speed), time_support=data.time_support) ``` -Now that we have the speed of the animal, we can compute the tuning curves for speed modulation. Here we call pynapple `compute_1d_tuning_curves`: +Now that we have the speed of the animal, we can compute the tuning curves for speed modulation. Here we call pynapple [`compute_1d_tuning_curves`](https://pynapple.org/generated/pynapple.process.tuning_curves.html#pynapple.process.tuning_curves.compute_1d_tuning_curves): ```{code-cell} ipython3 tc_speed = nap.compute_1d_tuning_curves(spikes, speed, 20) ``` -To assess the variabilty in speed when the animal is travering the linear track, we can compute the average speed and estimate the standard deviation. Here we use numpy only and put the results in a pandas `DataFrame`: +To assess the variabilty in speed when the animal is travering the linear track, we can compute the average speed and estimate the standard deviation. Here we use numpy only and put the results in a pandas [`DataFrame`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html): ```{code-cell} ipython3 @@ -285,9 +288,9 @@ print(count.shape) For each feature, we will use a different set of basis : - - position : `nmo.basis.MSplineBasis` - - theta phase : `nmo.basis.CyclicBSplineBasis` - - speed : `nmo.basis.MSplineBasis` + - position : [`MSplineBasis`](nemos.basis.MSplineBasis) + - theta phase : [`CyclicBSplineBasis`](nemos.basis.CyclicBSplineBasis) + - speed : [`MSplineBasis`](nemos.basis.MSplineBasis) ```{code-cell} ipython3 @@ -335,7 +338,7 @@ glm.fit(X, count) ## Prediction -Let's check first if our model can accurately predict the different tuning curves we displayed above. We can use the `predict` function of NeMoS and then compute new tuning curves +Let's check first if our model can accurately predict the different tuning curves we displayed above. We can use the [`predict`](nemos.glm.GLM.predict) function of NeMoS and then compute new tuning curves ```{code-cell} ipython3 @@ -367,9 +370,10 @@ fig = doc_plots.plot_position_phase_speed_tuning( While this model captures nicely the features-rate relationship, it is not necessarily the simplest model. Let's construct several models and evaluate their score to determine the best model. -!!! note - To shorten this notebook, only a few combinations are tested. Feel free to expand this list. +:::{note} +To shorten this notebook, only a few combinations are tested. Feel free to expand this list. +::: ```{code-cell} ipython3 @@ -440,8 +444,9 @@ plt.tight_layout() Some models are doing better than others. -!!! warning - A proper model comparison should be done by scoring models repetitively on various train and test set. Here we are only doing partial models comparison for the sake of conciseness. +:::{warning} +A proper model comparison should be done by scoring models repetitively on various train and test set. Here we are only doing partial models comparison for the sake of conciseness. +::: Alternatively, we can plot some tuning curves to compare each models visually. diff --git a/docs/tutorials/plot_06_calcium_imaging.md b/docs/tutorials/plot_06_calcium_imaging.md index 06e78296..632abfeb 100644 --- a/docs/tutorials/plot_06_calcium_imaging.md +++ b/docs/tutorials/plot_06_calcium_imaging.md @@ -69,7 +69,7 @@ transients = data['RoiResponseSeries'] print(transients) ``` -`transients` is a `TsdFrame`. Each column contains the activity of one neuron. +`transients` is a [`TsdFrame`](https://pynapple.org/generated/pynapple.core.time_series.TsdTensor.html). Each column contains the activity of one neuron. The mouse was recorded for a 20 minute recording epoch as we can see from the `time_support` property of the `transients` object. @@ -99,8 +99,8 @@ You can see that the calcium signals are both nonnegative, and noisy. One (neuro +++ -We can also plot tuning curves, plotting mean calcium activity as a function of head direction, using the function `compute_1d_tuning_curves_continuous`. -Here `data['ry']` is a `Tsd` that contains the angular head-direction of the animal between 0 and 2$\pi$. +We can also plot tuning curves, plotting mean calcium activity as a function of head direction, using the function [`compute_1d_tuning_curves_continuous`](https://pynapple.org/generated/pynapple.process.tuning_curves.html#pynapple.process.tuning_curves.compute_1d_tuning_curves_continuous). +Here `data['ry']` is a [`Tsd`](https://pynapple.org/generated/pynapple.core.time_series.Tsd.html) that contains the angular head-direction of the animal between 0 and 2$\pi$. ```{code-cell} ipython3 @@ -159,7 +159,7 @@ heading_basis = nmo.basis.CyclicBSplineBasis(n_basis_funcs=12) coupling_basis = nmo.basis.RaisedCosineBasisLog(3, mode="conv", window_size=10) ``` -We need to make sure the design matrix will be full-rank by applying identifiability constraints to the Cyclic Bspline, and then combine the bases (the resturned object will be an `AdditiveBasis` object). +We need to make sure the design matrix will be full-rank by applying identifiability constraints to the Cyclic Bspline, and then combine the bases (the resturned object will be an [`AdditiveBasis`](nemos.basis.AdditiveBasis) object). ```{code-cell} ipython3 @@ -170,8 +170,11 @@ basis = heading_basis + coupling_basis ## Gamma GLM Until now, we have been modeling spike trains, and have used a Poisson distribution for the observation model. With calcium traces, things are quite different: we no longer have counts but continuous signals, so the Poisson assumption is no longer appropriate. A Gaussian model is also not ideal since the calcium traces are non-negative. To satisfy these constraints, we will use a Gamma distribution from NeMoS with a soft-plus non linearity. -!!! note "Non-linearity" - Different option are possible. With a soft-plus we are assuming an "additive" effect of the predictors, while an exponential non-linearity assumes multiplicative effects. Deciding which firing rate model works best is an empirical question. You can fit different configurations to see which one capture best the neural activity. +:::{admonirion} Non-linearity +:class: note + +Different option are possible. With a soft-plus we are assuming an "additive" effect of the predictors, while an exponential non-linearity assumes multiplicative effects. Deciding which firing rate model works best is an empirical question. You can fit different configurations to see which one capture best the neural activity. +::: ```{code-cell} ipython3 @@ -196,7 +199,7 @@ print(selected_neurons) ``` We need to bring the head-direction of the animal to the same size as the transients matrix. -We can use the function `bin_average` of pynapple. Notice how we pass the parameter `ep` +We can use the function [`bin_average`](https://pynapple.org/generated/pynapple.core.time_series.Tsd.bin_average.html#pynapple.core.time_series.Tsd.bin_average) of pynapple. Notice how we pass the parameter `ep` that is the `time_support` of the transients. @@ -224,7 +227,7 @@ X = basis.compute_features(head_direction, Y[:, selected_neurons]) ## Train & test set -Let's create a train epoch and a test epoch to fit and test the models. Since `X` is a pynapple time series, we can create `IntervalSet` objects to restrict them into a train set and test set. +Let's create a train epoch and a test epoch to fit and test the models. Since `X` is a pynapple time series, we can create [`IntervalSet`](https://pynapple.org/generated/pynapple.core.interval_set.IntervalSet.html) objects to restrict them into a train set and test set. ```{code-cell} ipython3 @@ -305,7 +308,7 @@ plt.show() While there is some variability in the fit for both models, one advantage of the gamma distribution is clear: the nonnegativity constraint is followed with the data. This is required for using GLMs to predict the firing rate, which must be positive, in response to simulated inputs. See Peyrache et al. 2018[$^{[1]}$](#ref-1) for an example of simulating activity with a GLM. -Another way to compare models is to compute tuning curves. Here we use the function `compute_1d_tuning_curves_continuous` from pynapple. +Another way to compare models is to compute tuning curves. Here we use the function [`compute_1d_tuning_curves_continuous`](https://pynapple.org/generated/pynapple.process.tuning_curves.html#pynapple.process.tuning_curves.compute_1d_tuning_curves_continuous) from pynapple. ```{code-cell} ipython3 @@ -328,11 +331,14 @@ plt.xlabel("Head-direction (rad)") plt.show() ``` -!!! note "Gamma-GLM for Calcium Imaging Analysis" - Using Gamma-GLMs for fitting calcium imaging data is still in early stages, and hasn't been through - the levels of review and validation that they have for fitting spike data. Users should consider - this a relatively unexplored territory, and we hope that we hope that NeMoS will help researchers - explore this new space of models. +:::{admonition} Gamma-GLM for Calcium Imaging Analysis +:class: note + +Using Gamma-GLMs for fitting calcium imaging data is still in early stages, and hasn't been through +the levels of review and validation that they have for fitting spike data. Users should consider +this a relatively unexplored territory, and we hope that we hope that NeMoS will help researchers +explore this new space of models. +::: ## References