Skip to content

Commit

Permalink
Merge pull request #89 from GazzolaLab/update-0.2.0
Browse files Browse the repository at this point in the history
Update 0.2.0
  • Loading branch information
skim0119 authored Aug 9, 2022
2 parents 6674fbb + 0e5cfba commit 6f90f76
Show file tree
Hide file tree
Showing 45 changed files with 1,557 additions and 345 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exclude_lines =
# Enable pragma
pragma: no cover
TODO

# Don't complain if non-runnable code isn't run:
if 0:
Expand Down
15 changes: 8 additions & 7 deletions .github/workflows/ci-sphinx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
- name: Setup Poetry
uses: Gr1N/setup-poetry@v7
with:
poetry-preview: false
uses: snok/install-poetry@v1
- name: Poetry install docs dependencies
run: |
poetry --version
poetry config virtualenvs.in-project false
poetry config virtualenvs.create false
poetry config virtualenvs.in-project true
#poetry config virtualenvs.create false
poetry install -E docs
- name: Sphinx Build Check
run: |
source .venv/bin/activate
cd docs
python --version
which python
sphinx-build --version
make clean
if ! (make html SPHINXOPTS="-W --keep-going") ; then
echo Please resolve the warnings/errors
Expand All @@ -44,9 +45,9 @@ jobs:
echo Doc build success
exit 0
fi
- name: Sphinx Link Check
run: |
source .venv/bin/activate
cd docs
make clean
make linkcheck
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ __pycache__/

# C extensions
*.so
*.o

# Distribution / packaging
.Python
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#* Variables
PYTHON := python
PYTHON := python3
PYTHONPATH := `pwd`

#* Poetry
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
miv.visualization.connectivity.plot\_connectivity
=================================================

.. currentmodule:: miv.visualization.connectivity

.. autofunction:: plot_connectivity
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
miv.visualization.connectivity.plot\_connectivity\_interactive
==============================================================

.. currentmodule:: miv.visualization.connectivity

.. autofunction:: plot_connectivity_interactive
13 changes: 13 additions & 0 deletions docs/api/coding.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*************
Neural Coding
*************

Temporal Encoding/Decoding
==========================

.. automodule:: miv.coding.temporal

Spatial Encoding/Decoding
=========================

.. automodule:: miv.coding.spatial
14 changes: 14 additions & 0 deletions docs/api/visualization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ Burst Analysis

plot_burst

Connectivity Plots
------------------

.. currentmodule:: miv.visualization

.. automodule:: miv.visualization.connectivity

.. autosummary::
:nosignatures:
:toctree: _toctree/VisualizationAPI

plot_connectivity
plot_connectivity_interactive


Useful External Packages
========================
Expand Down
104 changes: 104 additions & 0 deletions docs/guide/connectivity_network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.13.8
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
---

# Channel-wise Signal Correlation

Here is the example script of cross-correlation analysis using `Elephant` package.

```{code-cell} ipython3
:tags: [hide-cell]
import os
import sys
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as ss
import miv
from miv.datasets import optogenetic
from miv.io import DataManager
from miv.signal.filter import ButterBandpass, FilterCollection, MedianFilter
from miv.signal.spike import ThresholdCutoff
from miv.visualization.connectivity import plot_connectivity
```

## Pre-processing

```{code-cell} ipython3
# Experiment name
experiment_query = "experiment0"
# Data call
signal_filter = (
FilterCollection()
.append(ButterBandpass(600, 2400, order=4))
.append(MedianFilter(threshold=60, k=30))
)
spike_detection = ThresholdCutoff(cutoff=5)
# Spike Detection
data_collection = optogenetic.load_data()
data = data_collection.query_path_name(experiment_query)[0]
#false_channels = [12,15,36,41,42,43,45,47,53,57,55,58,61,62]
#data.set_channel_mask(false_channels)
with data.load() as (signal, timestamps, sampling_rate):
# Preprocess
signal = signal_filter(signal, sampling_rate)
spiketrains = spike_detection(signal, timestamps, sampling_rate)
```

## Provide MEA mao

```{code-cell} ipython3
#Matrix containing electrode numbers according to their spatial location
mea_map = np.array([[25 , 10 , 12 , 14 , 31 , 28 , 26 , 40],
[18 , 17 , 11 , 13 , 32 , 27 , 38 , 37],
[20 , 19 , 9 , 15 , 30 , 39 , 36 , 35],
[23 , 22 , 21 , 16 , 29 , 34 , 33 , 56],
[24 , 1 , 2 , 61 , 44 , 53 , 54 , 55],
[3 , 4 , 7 , 62 , 43 , 48 , 51 , 52],
[5 , 6 , 59 , 64 , 41 , 46 , 49 , 50],
[57 , 58 , 60 , 63 , 42 , 45 , 47 , 8]])
```

## Forming Connectivity Matrix

```{code-cell} ipython3
#Correlation using Elephant
import elephant.statistics
import quantities as pq
from elephant.spike_train_correlation import correlation_coefficient
rates = elephant.statistics.BinnedSpikeTrain(spiketrains, bin_size=2*pq.ms)
corrcoef_matrix = correlation_coefficient(rates)
```

## Plot Connectivity

Plots connectivity using the provided MEA map and connectivity matrix. Documentation is available [here](miv.visualization.connectivity.plot_connectivity)

```{code-cell} ipython3
#Non-interactive connectivity plot using correlation
plot_connectivity(mea_map, corrcoef_matrix, False)
```

```{code-cell} ipython3
#Interactive connectivity plot using correlation
plot_connectivity_interactive(mea_map, corrcoef_matrix, False)
```
176 changes: 176 additions & 0 deletions docs/guide/lyon_ear_model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.13.8
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
---

# Temporal Encoding: Lyon Ear Model

- Schroeder, M. R. (1973). An integrable model for the basilar membrane. The Journal of the Acoustical Society of America, 53(2), 429–434. doi:10.1121/1.1913339
- Zweig, G., Lipes, R., & Pierce, J. R. (1976). The cochlear compromise. Journal of the Acoustical Society of America, 59(4), 975–982. doi:10.1121/1.380956
- Lyon, R. F. (1982). A Computational Model of Filtering, Detection, and Compreion in the Cochlea. IEEE Artificial IntelligenceArtificial Intelligence, 3–6.
- Lyon, R. F., & Lauritzen, N. (1985). Processing Speech With the Multi-Serial Signal Processor. ICASSP, IEEE International Conference on Acoustics, Speech and Signal Processing - Proceedings, 981–984. doi:10.1109/icassp.1985.1168158
- Slaney, M. (1988). Lyon’s Cochlear Model. 1–79.
- Van, L. M. (1992). Pitch and voiced/unvoiced determination with an auditory model. Journal of the Acoustical Society of America, 91(6), 3511–3526. doi:10.1121/1.402840
- Gabbiani, Fabrizio. (1996). Coding of time-varying signals in spike trains of linear and half-wave rectifying neurons. Network: Computation in Neural Systems, 7(1), 61–85. doi:10.1080/0954898x.1996.11978655
- Reich, D. S., Victor, J. D., & Knight, B. W. (1998). The power ratio and the interval map: Spiking models and extracellular recordings. Journal of Neuroscience, 18(23), 10090–10104. doi:10.1523/jneurosci.18-23-10090.1998
- Gabbiani, F., & Metzner, W. (1999). Encoding and processing of sensory information in neuronal spike trains. Journal of Experimental Biology, 202(10), 1267–1279. doi:10.1242/jeb.202.10.1267
- Schrauwen, B., & Van Campenhout, J. (2003). BSA, a Fast and Accurate Spike Train Encoding Scheme. Proceedings of the International Joint Conference on Neural Networks, 4, 2825–2830. doi:10.1109/ijcnn.2003.1224019
- Cosi, P., & Zovato, E. (2012). Lyon ’ s Auditory Model Inversion : a Tool for Sound Separation and Speech Enhancement. 3–6.
- Swanson, B. A. (2015). Pitch Perception with Cochlear Implants. (August 2008).
- Zai, A. T., Bhargava, S., Mesgarani, N., & Liu, S. C. (2015). Reconstruction of audio waveforms from spike trains of artificial cochlea models. Frontiers in Neuroscience, 9(OCT), 1–13. doi:10.3389/fnins.2015.00347
- Jin, Y., & Li, P. (2017). Performance and robustness of bio-inspired digital liquid state machines: A case study of speech recognition. Neurocomputing, 226(September 2015), 145–160. doi:10.1016/j.neucom.2016.11.045
- Huang, N., Slaney, M., & Elhilali, M. (2018). Connecting deep neural networks to physical, perceptual, and electrophysiological auditory signals. Frontiers in Neuroscience, 12(AUG), 1–14. doi:10.3389/fnins.2018.00532
- Petro, B., Kasabov, N., & Kiss, R. M. (2020). Selection and Optimization of Temporal Spike Encoding Methods for Spiking Neural Networks. IEEE Transactions on Neural Networks and Learning Systems, 31(2), 358–370. doi:10.1109/TNNLS.2019.2906158

- Xu, Y., Thakur, C. S., Singh, R. K., Hamilton, T. J., Wang, R. M., & van Schaik, A. (2018). A FPGA implementation of the CAR-FAC cochlear model. Frontiers in Neuroscience, 12(APR), 1–14. doi:10.3389/fnins.2018.00198

+++

## Quick Demo

```{code-cell} ipython3
:tags: [hide-cell]
import IPython
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
```

```{code-cell} ipython3
from miv.converter.temporal import LyonEarModel, BensSpikerAlgorithm
```

```{code-cell} ipython3
filepath = "Cochlear-Implant-Processor/Samples/Birds.wav"
IPython.display.Audio(filepath)
```

```{code-cell} ipython3
sampling_rate, waveform = wavfile.read(filepath)
waveform = waveform.astype(np.float_)
print(f"{sampling_rate=}, {waveform.shape=}")
left_wave = np.ascontiguousarray(waveform[:,0])
right_wave = np.ascontiguousarray(waveform[:,1])
```

### Lyon Ear Model

```{code-cell} ipython3
decimation_factor = 64
ear_model = LyonEarModel(sampling_rate=sampling_rate, decimation_factor=decimation_factor)
```

```{code-cell} ipython3
decimation_factor = 64
cochlear_left = ear_model(left_wave)
cochlear_right = ear_model(right_wave)
print(cochlear_right.shape)
```

```{code-cell} ipython3
fig = plt.figure(figsize=(16,8))
ax1 = fig.add_subplot(211)
img1 = ax1.imshow(cochlear_right.T)
ax1.set_aspect('auto')
plt.colorbar(img1)
ax2 = fig.add_subplot(212)
img2 = ax2.imshow(cochlear_right.T)
ax2.set_aspect('auto')
plt.colorbar(img2)
```

## BSA

```{code-cell} ipython3
out = np.stack([cochlear_left, cochlear_right])
```

```{code-cell} ipython3
bsa = BensSpikerAlgorithm(out)
spiketrain = bsa.get_spikes()[0]
```

```{code-cell} ipython3
# Binning
spiketime = [[] for _ in range(spiketrain.shape[1])]
spikestamp = np.where(spiketrain)
for i, j in zip(spikestamp[0], spikestamp[1]):
spiketime[j].append(i)
```

### Replay

```{code-cell} ipython3
from matplotlib import animation
plt.rcParams["animation.html"] = "jshtml"
plt.rcParams["figure.dpi"] = 150
plt.ioff()
```

```{code-cell} ipython3
fig, ax = plt.subplots()
window = 0.15
tfinal = 10.0
dps = int(spiketrain.shape[0] / tfinal)
fps = 60.0
def animate(frame):
t = frame / fps
plt.cla()
low = t * dps
high = (t + window) * dps
plt.eventplot([np.array(list(filter(lambda x: x >= low and x <= high, sp)))/dps for sp in spiketime])
plt.xlim(t,t+window)
plt.xlabel('time (sec)')
plt.ylabel('channel')
plt.title(f'{t=:.02f} {frame=}')
ax.set_aspect('auto')
animation.FuncAnimation(fig, animate, frames=int(tfinal * fps))
```

## Testing (Sinusoidal)

```{code-cell} ipython3
raise Exception # Do not proceed beyond
```

```{code-cell} ipython3
out = calc.lyon_passive_ear(data[:,0], samplerate)
print('Out:')
print(out.shape)
```

```{code-cell} ipython3
data2 = np.sin(np.arange(2041)/20000*2*np.pi*1000)
out = calc.lyon_passive_ear(data2, 20000, 20)
```

```{code-cell} ipython3
plt.imshow(out, aspect='auto')
plt.colorbar()
```

```{code-cell} ipython3
data3 = np.zeros(256); data3[0] = 1
out = calc.lyon_passive_ear(data3, 16000, 1)
out = np.fmin(out, 0.0004)
```

```{code-cell} ipython3
plt.imshow(out, aspect='auto')
plt.colorbar()
```

```{code-cell} ipython3
```
Loading

0 comments on commit 6f90f76

Please sign in to comment.