├── .github └── workflows │ └── python-package.yml ├── .gitignore ├── .readthedocs.yaml ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── binder ├── environment.yml └── postBuild ├── docs └── source │ ├── AUTHORS.rst │ ├── CITE.rst │ ├── DOCUMENTATION.rst │ ├── INSTALL.rst │ ├── LICENSE.rst │ ├── NOTES.rst │ ├── TUTORIALS.rst │ ├── conf.py │ ├── index.rst │ └── requirements.txt ├── figures ├── kCSD_properties │ ├── L_curve_simulation.py │ ├── README.txt │ ├── colorblind_friendly.py │ ├── different_error_maps.py │ ├── error_propagation.py │ ├── figure_LC.py │ ├── figure_LCandCV.py │ ├── figure_LCandCVperformance.py │ ├── figure_Tbasis.py │ ├── figure_Tbasis_noise.py │ ├── figure_Teigensources.py │ ├── figure_eigensources_M_1D.py │ ├── figure_eigensources_M_2D.py │ ├── figure_eigensources_R_1D.py │ ├── figure_error_3x3.py │ ├── figure_properties.py │ ├── kCSD_with_reliability_map_2D.py │ ├── pdf_merger.py │ ├── pots_propagation.py │ ├── projection_eigensources_1D.py │ ├── reconstruction_stability.py │ ├── reliability_map_2D.py │ ├── reliability_map_3x3.py │ ├── skcsd_and_l_curve_complex_morphology.py │ ├── sources_electrodes.odg │ ├── targeted_basis.py │ ├── targeted_basis_with_projection.py │ ├── tutorial3.py │ ├── tutorial_basic.py │ ├── tutorial_basic_3d.py │ ├── tutorial_broken_electrodes.py │ ├── tutorial_broken_electrodes_diff_err.py │ └── tutorial_noisy_electrodes.py ├── npx │ ├── DemoReadSGLXData │ │ ├── __init__.py │ │ └── readSGLX.py │ ├── NP_do_map.xlsx │ ├── Neuropixels_for_NEURON.ipynb │ ├── Neuropixels_with_fitted_dipoles_model.py │ ├── dan_kCSD_from_npx.py │ ├── figure_properties.py │ ├── figure_traub_eigensources.py │ ├── figure_traub_timespace.py │ ├── kCSD2D_reconstruction_from_npx.py │ ├── map_npx_ele.py │ ├── map_npx_ele_Daniel.py │ ├── npx_data.npy │ └── traub_data_kcsd_column_figure.py ├── sKCSD_paper │ ├── README │ ├── __init__.py │ ├── make_fig_10.py │ ├── make_fig_2.py │ ├── make_fig_3.py │ ├── make_fig_5.py │ ├── make_fig_6.py │ ├── make_fig_7.py │ ├── make_fig_8.py │ ├── make_fig_9.py │ ├── make_fig_lcurve.py │ ├── run_LFP.py │ └── sKCSD_utils.py └── what_you_can_see_with_lfp │ ├── README.txt │ ├── kCSD_properties │ └── Fig1-figure_Tbasis.py │ └── npx │ ├── Fig2_traub_data_kcsd_column_figure.py │ ├── Fig3-figure_traub_timespace.py │ ├── Fig4-Neuropixels_with_fitted_dipoles_model.py │ ├── figure_properties.py │ └── kCSD2D_reconstruction_from_npx.py ├── kcsd ├── KCSD.py ├── __init__.py ├── basis_functions.py ├── data │ ├── ElcoordsDomi14.txt │ ├── Simple_with_branches │ │ ├── LFP │ │ │ └── myLFP │ │ ├── electrode_positions │ │ │ └── elcoord_x_y_z │ │ └── morphology │ │ │ └── Badea2011Fig2Du.CNG.swc │ ├── Y_shaped_neuron │ │ ├── LFP │ │ │ └── MyLFP │ │ ├── electrode_positions │ │ │ └── elcoord_x_y_x │ │ └── morphology │ │ │ └── Y_shaped.swc │ ├── ball_and_stick_128 │ │ ├── LFP │ │ │ └── myLFP │ │ ├── electrode_positions │ │ │ └── elcoord_x_y_z │ │ └── morphology │ │ │ └── ball_and_stick.swc │ ├── ball_and_stick_16 │ │ ├── LFP │ │ │ └── myLFP │ │ ├── electrode_positions │ │ │ └── elcoord_x_y_z │ │ └── morphology │ │ │ └── ball_and_stick.swc │ ├── ball_and_stick_8 │ │ ├── LFP │ │ │ └── MyLFP │ │ ├── electrode_positions │ │ │ └── elcoord_x_y_x │ │ └── morphology │ │ │ └── Figure_2_rows_8.swc │ ├── gang_7x7_200 │ │ ├── LFP │ │ │ └── MyLFP │ │ ├── electrode_positions │ │ │ └── elcoord_x_y_z │ │ ├── membcurr │ │ ├── morphology │ │ │ └── gang_7x7_200_rows_4_cols_5_xmin_-20_xmax_20_ymin_-20_ymax_20_orientation_3.swc │ │ ├── seglength │ │ ├── somav.txt │ │ └── tvec.txt │ ├── morphology │ │ ├── Badea2011Fig2Du.CNG.swc │ │ ├── DomiCell.swc │ │ ├── ElcoordsDomi14.txt │ │ ├── L5_Mainen96_LFPy.hoc │ │ ├── Mainen_swcLike.swc │ │ ├── Test.swc │ │ ├── active.hoc │ │ ├── ballstick.hoc │ │ ├── ballstick.swc │ │ ├── morpho1.swc │ │ ├── retina_ganglion.swc │ │ ├── villa.hoc │ │ └── villa.swc │ └── sinsyn.mod ├── sKCSD.py ├── sKCSD_utils.py ├── tests │ ├── __init__.py │ ├── api_tests.py │ ├── kcsd_tests.py │ ├── test_loadData.py │ ├── test_sKCSD.py │ ├── test_sKCSDcell.py │ └── test_sKCSDutils.py ├── utility_functions.py └── validation │ ├── ValidateKCSD.py │ ├── VisibilityMap.py │ ├── __init__.py │ ├── csd_profile.py │ └── plotting_functions.py ├── requirements.txt ├── setup.py └── tutorials ├── __init__.py ├── config.py ├── plotting_helpers.py ├── skcsd_tutorial.ipynb ├── tutorial_advanced.ipynb ├── tutorial_basic.ipynb └── widget_helpers.py /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python 3 | 4 | name: Python package 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | python-version: ["3.8", "3.9", "3.10", "3.11"] 20 | 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Set up Python ${{ matrix.python-version }} 25 | uses: actions/setup-python@v3 26 | with: 27 | python-version: ${{ matrix.python-version }} 28 | - name: Install dependencies 29 | run: | 30 | python -m pip install --upgrade pip 31 | python -m pip install flake8 pytest 32 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 33 | 34 | - name: Lint with flake8 35 | run: | 36 | # stop the build if there are Python syntax errors or undefined names 37 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 38 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 39 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 40 | - name: Test with pytest 41 | run: | 42 | pytest 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *~ 6 | \#*\# 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *,cover 48 | .hypothesis/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | 57 | # coveralls 58 | /coverage/ 59 | 60 | # Sphinx documentation 61 | docs/_build/ 62 | 63 | # PyBuilder 64 | target/ 65 | 66 | #Ipython Notebook 67 | .ipynb_checkpoints 68 | #testing files 69 | testing/ 70 | 71 | #data 72 | examples/ 73 | .idea/ 74 | preprocessed_data/ 75 | raw_data/ 76 | *~ 77 | /#* 78 | *png 79 | Data/gang_min/ 80 | simulation 81 | deactivate/ 82 | #directory with generated figures 83 | Figures 84 | #directories generated by neuron 85 | synapse_locations 86 | x86_64 87 | LCurve -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Set the version of Python and other tools you might need 9 | build: 10 | os: ubuntu-22.04 11 | tools: 12 | python: "3.11" 13 | 14 | # Build documentation in the docs/ directory with Sphinx 15 | sphinx: 16 | configuration: docs/source/conf.py 17 | 18 | # We recommend specifying your dependencies to enable reproducible builds: 19 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 20 | python: 21 | install: 22 | - requirements: docs/source/requirements.txt -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Corresponding SPDX licence 2 | BSD 3-Clause "New" or "Revised" License 3 | Licence ID 4 | BSD-3-Clause 5 | 6 | 7 | Licence text 8 | Copyright (c) 2019-2023, Chintaluri et al. 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 12 | 13 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 16 | 17 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE.txt 2 | include README.rst 3 | include kcsd/data/gang_7x7_200/electrode_positions/elcoord_x_y_z 4 | include kcsd/data/gang_7x7_200/LFP/myLFP 5 | include kcsd/data/gang_7x7_200/morphology/* 6 | include kcsd/data/ball_and_stick_8/electrode_positions/elcoord_x_y_z 7 | include kcsd/data/ball_and_stick_8/LFP/myLFP 8 | include kcsd/data/ball_and_stick_8/morphology/* 9 | include kcsd/data/ball_and_stick_16/electrode_positions/elcoord_x_y_z 10 | include kcsd/data/ball_and_stick_16/LFP/myLFP 11 | include kcsd/data/ball_and_stick_16/morphology/* 12 | include kcsd/data/ball_and_stick_128/electrode_positions/elcoord_x_y_z 13 | include kcsd/data/ball_and_stick_128/LFP/myLFP 14 | include kcsd/data/ball_and_stick_128/morphology/* 15 | include kcsd/data/Y_shaped_neuron/electrode_positions/elcoord_x_y_z 16 | include kcsd/data/Y_shaped_neuron/LFP/myLFP 17 | include kcsd/data/Y_shaped_neuron/morphology/* 18 | include kcsd/data/Simple_with_branches/electrode_positions/elcoord_x_y_z 19 | include kcsd/data/Simple_with_branches/LFP/myLFP 20 | include kcsd/data/Simple_with_branches/morphology/* 21 | include kcsd/data/morphology/* 22 | include kcsd/data/sinsyn.mod 23 | graft figures 24 | graft docs 25 | graft tutorials 26 | global-exclude *.py[cod] __pycache__ *.so *.pdf *.npz *.png *.npy 27 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Kernel Current Source Density 2 | ============================= 3 | 4 | This is version 2.0 of kCSD-python implementing kCSD method and related functionality. 5 | 6 | Only supported for python 3. 7 | 8 | 9 | 10 | Relevant Papers 11 | --------------- 12 | 13 | Paper 1: "Kernel Current Source Density 14 | Method", J. Potworowski, W. Jakuczun, S. Łȩski, D. K. Wójcik; Neural 15 | Comput 2012; 24 (2): 541–575, doi: 16 | https://doi.org/10.1162/NECO_a_00236 17 | 18 | 19 | Paper 2 : "What we can and what we cannot see with extracellular 20 | multielectrodes", C. Chintaluri, M. Bejtka, W. 21 | Średniawa, M. Czerwiński, J. M. Dzik, J. 22 | Jędrzejewska-Szmek, K. Kondrakiewicz, E. Kublik, D. K. Wójcik; PLoS 23 | Computational Biology (2021), 17(5): e1008615, doi: 24 | https://doi.org/10.1371/journal.pcbi.1008615 25 | 26 | Paper 3 : "kCSD-python, reliable current source density estimation with quality control", 27 | C. Chintaluri, M. Bejtka, W. Średniawa, M. Czerwiński, J. M. Dzik, J. Jędrzejewska-Szmek, D. K. Wójcik; 28 | bioRxiv, doi: https://doi.org/10.1101/708511 29 | 30 | Paper 1 is the original paper with software code in Matlab. 31 | Paper 2 is an improvement and development of the paper 1. 32 | Paper 3 is a feature showcase and walk-through of the method and its applications. 33 | 34 | Tutorials 35 | --------- 36 | 37 | This library comes with three tutorials and **does not require any installation**. 38 | 39 | 1. `Basic tutorial `_ 40 | 2. `Advanced tutorial `_ 41 | 3. `sKCSD tutorial `_ 42 | 43 | More information on the tutorials is provided here `Tutorials!`_ 44 | 45 | .. _Tutorials!: /docs/source/TUTORIALS.rst 46 | 47 | You can also save these tutorials on your desktop, for this you will 48 | need to install jupyter-notebook. Do this by 49 | 50 | .. code-block:: bash 51 | 52 | pip install jupyter notebook 53 | 54 | 55 | Figures 56 | ------- 57 | 58 | This library includes all the necessary scripts to generate the figures for papers 2 and 3. 59 | 60 | `Figures for Paper 2`_ 61 | 62 | .. _Figures for Paper 2: /figures/what_you_can_see_with_lfp/README.txt 63 | 64 | `Figures for Paper 3`_ 65 | 66 | .. _Figures for Paper 3: /figures/kCSD_properties/README.txt 67 | 68 | Installation 69 | ------------ 70 | 71 | .. code-block:: bash 72 | 73 | user:~/$ pip install kcsd 74 | 75 | `More Installations`_ 76 | 77 | .. _More Installations : https://kcsd-python.readthedocs.io/en/latest/INSTALL.html 78 | 79 | 80 | Documentation 81 | ------------- 82 | 83 | Autogenerated documentation available from readthedocs: 84 | 85 | `kCSD-python_Reference`_ 86 | 87 | .. _kCSD-python_Reference : https://kcsd-python.readthedocs.io/en/latest/ 88 | 89 | Also included here are authors and their contributions, citation policy, contacts etc., 90 | 91 | 92 | Earlier Stable versions 93 | ----------------------- 94 | Please see git tags for earlier versions. These are not available as packages unfortunately. 95 | 96 | - v1.2 corresponds to the first time kCSD-python released as a python package 97 | - v1.0 corresponds to the version with the test cases written inside tests folder 98 | - v1.1 corresponds to the elephant python library version - no tests here 99 | 100 | 101 | Health Report 102 | ------------- 103 | 104 | Continuous Integration (Travis): 105 | 106 | .. image:: https://travis-ci.org/Neuroinflab/kCSD-python.png?branch=master 107 | :target: https://travis-ci.org/Neuroinflab/kCSD-python 108 | 109 | Test Coverage : 110 | 111 | .. image:: https://coveralls.io/repos/github/Neuroinflab/kCSD-python/badge.png?branch=master 112 | :target: https://coveralls.io/github/Neuroinflab/kCSD-python?branch=master 113 | 114 | Documentation Status: 115 | 116 | .. image:: https://readthedocs.org/projects/kcsd-python/badge/?version=latest 117 | :target: https://kcsd-python.readthedocs.io/en/latest/?badge=latest 118 | 119 | 120 | License 121 | ------- 122 | `Modified BSD License`_ 123 | 124 | .. _Modified BSD License: https://opensource.org/licenses/BSD-3-Clause 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /binder/environment.yml: -------------------------------------------------------------------------------- 1 | channels: 2 | - defaults 3 | dependencies: 4 | - _libgcc_mutex 5 | - _openmp_mutex 6 | - ca-certificates=2022.07.19=h06a4308_0 7 | - certifi=2022.6.15=py39h06a4308_0 8 | - ld_impl_linux-64=2.38=h1181459_1 9 | - libffi 10 | - libgcc-ng 11 | - libgomp 12 | - libstdcxx-ng 13 | - ncurses=6.3=h5eee18b_3 14 | - openssl=1.1.1q=h7f8727e_0 15 | - pip 16 | - python=3.9 17 | - readline=8.1.2=h7f8727e_1 18 | - setuptools=63.4.1=py39h06a4308_0 19 | - sqlite 20 | - tzdata=2022a=hda174b7_0 21 | - wheel=0.37.1=pyhd3eb1b0_0 22 | - xz=5.2.5=h7f8727e_1 23 | - pip: 24 | - cycler==0.11.0 25 | - fonttools==4.37.1 26 | - future==0.18.2 27 | - kiwisolver==1.4.4 28 | - matplotlib==3.5.3 29 | - numpy==1.23.2 30 | - packaging==21.3 31 | - pillow==9.2.0 32 | - pyparsing==3.0.9 33 | - python-dateutil==2.8.2 34 | - scipy==1.9.1 35 | - six==1.16.0 36 | - "git+https://github.com/Neuroinflab/kCSD-python.git" 37 | -------------------------------------------------------------------------------- /binder/postBuild: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | jupyter nbextension enable --py widgetsnbextension --sys-prefix -------------------------------------------------------------------------------- /docs/source/AUTHORS.rst: -------------------------------------------------------------------------------- 1 | Authors 2 | ------- 3 | 4 | - Chaitanya Chintaluri[1, 2] 5 | - Marta Kowalska[1] 6 | - Michał Czerwinski[1] 7 | - Joanna Jędrzejewska–Szmek[1] 8 | - Jakub Dzik[1] 9 | - Władysław Średniawa[1] 10 | - Jan Mąka [1, 4] 11 | - Grzegorz Parka[3] 12 | 13 | - Daniel K. Wójcik[1] 14 | 15 | 1. Nencki Institute of Experimental Biology, Warsaw, Poland 16 | 2. University of Oxford, United Kingdom 17 | 3. Google Summer of Code 2014, INCF/pykCSD 18 | 4. University of Warsaw, Poland 19 | 20 | Contributions 21 | ------------- 22 | 23 | - C.C : Design, implentation kcsd core classes, validation, tests, binder, tutorials 24 | - M.K : Reliability maps, Spectral decomposition, validation class, tutorials 25 | - M.C : KCSD1D class 26 | - J.J-S : skCSD class, tests 27 | - J.D : Error propagation maps 28 | - J.M : initial work on sKCSD class 29 | - W.S : L-curve implementation 30 | - G.P : first pass python library for kCSD as part of GSoC. 31 | 32 | - D.W : supervision, code quality 33 | 34 | 35 | Contact 36 | ------- 37 | Prof. Daniel K. Wójcik : d.wojcik[at]nencki[dot]gov[dot]pl 38 | 39 | 40 | Contribute 41 | ---------- 42 | If you wish to contribute to this code, please get it touch with Prof. Wójcik 43 | -------------------------------------------------------------------------------- /docs/source/CITE.rst: -------------------------------------------------------------------------------- 1 | Citation policy 2 | --------------- 3 | If you use this software in published research please cite the following work 4 | 5 | - KCSD1D - [1, 2] 6 | - KCSD2D - [1, 3] 7 | - KCSD3D - [1, 4] 8 | - MoIkCSD - [1, 3, 5] 9 | - sKCSD - [6] 10 | 11 | 1) Potworowski, J., Jakuczun, W., Łęski, S. & Wójcik, D. (2012) 'Kernel current source density method.' Neural Comput 24(2), 541-575. 12 | 13 | 2) Pettersen, K. H., Devor, A., Ulbert, I., Dale, A. M. & Einevoll, G. T. (2006) 'Current-source density estimation based on inversion of electrostatic forward solution: effects of finite extent of neuronal activity and conductivity discontinuities.' J Neurosci Methods 154(1-2), 116-133. 14 | 15 | 3) Łęski, S., Pettersen, K. H., Tunstall, B., Einevoll, G. T., Gigg, J. & Wójcik, D. K. (2011) 'Inverse Current Source Density method in two dimensions: Inferring neural activation from multielectrode recordings.' Neuroinformatics 9(4), 401-425. 16 | 17 | 4) Łęski, S., Wójcik, D. K., Tereszczuk, J., Świejkowski, D. A., Kublik, E. & Wróbel, A. (2007) 'Inverse current-source density method in 3D: reconstruction fidelity, boundary effects, and influence of distant sources.' Neuroinformatics 5(4), 207-222. 18 | 19 | 5) Ness, T. V., Chintaluri, C., Potworowski, J., Łeski, S., Głabska, H., Wójcik, D. K. & Einevoll, G. T. (2015) 'Modelling and Analysis of Electrical Potentials Recorded in Microelectrode Arrays (MEAs).' Neuroinformatics 13(4), 403-426. 20 | 21 | 6) Cserpan, D., Meszena, D., Wittner, L., Toth, K., Ulbert, I., Somogyvari, Z., Wójcik, D. K. (2017) 'Revealing The Distribution Of Transmembrane Currents Along The Dendritic Tree Of A Neuron From Extracellular Recordings.' eLife (2017) 6:e29384 22 | -------------------------------------------------------------------------------- /docs/source/DOCUMENTATION.rst: -------------------------------------------------------------------------------- 1 | Documentation 2 | ------------ 3 | .. toctree:: 4 | :maxdepth: 1 5 | :caption: Contents: 6 | 7 | KCSD Methods 8 | ~~~~~~~~~~~~ 9 | 10 | .. automodule:: kcsd.KCSD 11 | :members: 12 | :inherited-members: 13 | 14 | .. autoclass:: kcsd.sKCSD 15 | :members: 16 | :inherited-members: 17 | 18 | Spectral Structure 19 | ~~~~~~~~~~~~~~~~~~ 20 | 21 | .. autoclass:: kcsd.validation.ValidateKCSD.SpectralStructure 22 | :members: 23 | :inherited-members: 24 | 25 | Validation 26 | ~~~~~~~~~~ 27 | 28 | .. autoclass:: kcsd.validation.ValidateKCSD.ValidateKCSD 29 | :members: 30 | :inherited-members: 31 | 32 | .. autoclass:: kcsd.validation.ValidateKCSD.ValidateKCSD1D 33 | :members: 34 | :inherited-members: 35 | 36 | .. autoclass:: kcsd.validation.ValidateKCSD.ValidateKCSD2D 37 | :members: 38 | :inherited-members: 39 | 40 | .. autoclass:: kcsd.validation.ValidateKCSD.ValidateKCSD3D 41 | :members: 42 | :inherited-members: 43 | 44 | Reliability Maps 45 | ~~~~~~~~~~~~~~~~ 46 | 47 | .. automodule:: kcsd.validation.VisibilityMap 48 | :members: 49 | :inherited-members: 50 | 51 | Basis functions 52 | ~~~~~~~~~~~~~~~ 53 | 54 | 1-Dimensional 55 | +++++++++++++ 56 | 57 | .. autofunction:: kcsd.basis_functions.gauss_1D 58 | 59 | .. autofunction:: kcsd.basis_functions.gauss_lim_1D 60 | 61 | .. autofunction:: kcsd.basis_functions.step_1D 62 | 63 | 2-Dimensional 64 | +++++++++++++ 65 | 66 | .. autofunction:: kcsd.basis_functions.gauss_2D 67 | 68 | .. autofunction:: kcsd.basis_functions.gauss_lim_2D 69 | 70 | .. autofunction:: kcsd.basis_functions.step_2D 71 | 72 | 3-Dimensional 73 | +++++++++++++ 74 | 75 | .. autofunction:: kcsd.basis_functions.gauss_3D 76 | 77 | .. autofunction:: kcsd.basis_functions.gauss_lim_3D 78 | 79 | .. autofunction:: kcsd.basis_functions.step_3D 80 | 81 | 82 | CSD Test Sources 83 | ~~~~~~~~~~~~~~~~ 84 | 85 | Variable (Seedable) 86 | +++++++++++++++++++ 87 | 88 | .. autofunction:: kcsd.validation.csd_profile.gauss_1d_dipole 89 | 90 | .. autofunction:: kcsd.validation.csd_profile.gauss_1d_mono 91 | 92 | .. autofunction:: kcsd.validation.csd_profile.gauss_2d_small 93 | 94 | .. autofunction:: kcsd.validation.csd_profile.gauss_2d_large 95 | 96 | .. autofunction:: kcsd.validation.csd_profile.gauss_3d_small 97 | 98 | .. autofunction:: kcsd.validation.csd_profile.gauss_3d_large 99 | 100 | Fixed (Non seedable) 101 | ++++++++++++++++++++ 102 | 103 | .. autofunction:: kcsd.validation.csd_profile.gauss_1d_dipole_f 104 | 105 | .. autofunction:: kcsd.validation.csd_profile.gauss_2d_large_f 106 | 107 | .. autofunction:: kcsd.validation.csd_profile.gauss_2d_small_f 108 | 109 | .. autofunction:: kcsd.validation.csd_profile.gauss_3d_mono1_f 110 | 111 | .. autofunction:: kcsd.validation.csd_profile.gauss_3d_mono2_f 112 | 113 | .. autofunction:: kcsd.validation.csd_profile.gauss_3d_mono3_f 114 | -------------------------------------------------------------------------------- /docs/source/INSTALL.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ------------ 3 | 4 | From PyPi 5 | ~~~~~~~~~ 6 | 7 | .. code-block:: bash 8 | 9 | user:~$ pip install kcsd 10 | 11 | 12 | From repository 13 | ~~~~~~~~~~~~~~~~ 14 | 15 | .. code-block:: bash 16 | 17 | user:~$ git clone https://github.com/Neuroinflab/kCSD-python.git 18 | user:~$ cd kCSD-python 19 | user:~/kCSD-python$ python setup.py install 20 | 21 | 22 | On Anaconda 23 | ~~~~~~~~~~~ 24 | 25 | .. code-block:: bash 26 | 27 | (base)user:~/kCSD-python$ conda activate testkcsd 28 | (testkcsd)user:~/kCSD-python$ pip install kcsd 29 | 30 | 31 | Development and testing 32 | ~~~~~~~~~~~~~~~~~~~~~~~ 33 | 34 | .. code-block:: bash 35 | 36 | user:~/kCSD-python$ pip install -e . 37 | 38 | or 39 | 40 | .. code-block:: bash 41 | 42 | user:~/kCSD-python$ python setup.py develop 43 | -------------------------------------------------------------------------------- /docs/source/LICENSE.rst: -------------------------------------------------------------------------------- 1 | License 2 | ------- 3 | 4 | BSD 3-Clause License 5 | ~~~~~~~~~~~~~~~~~~~~ 6 | 7 | Copyright (c) 2019, Laboratory of Neuroinformatics, Nencki Institute 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this 14 | list of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | * Neither the name of the copyright holder nor the names of its 21 | contributors may be used to endorse or promote products derived from 22 | this software without specific prior written permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | -------------------------------------------------------------------------------- /docs/source/NOTES.rst: -------------------------------------------------------------------------------- 1 | 2018_05_21 2 | 1) Major updates (tagged v1.2) 3 | 4 | - ipython notebooks for basic and advanced tutorials 5 | - L-curve for determining lambda 6 | - validation and visibility maps (prev. called error maps) 7 | - sKCSD implementation for Dori's paper 8 | 9 | 2) infrastructure changes 10 | 11 | - tests 12 | - travis / coveralls / github integration 13 | - binder 14 | - pip install - now a package! woohooo! (or is it?) 15 | - folder reorganization 16 | - figures for the skcsd paper and tests 17 | 18 | 3) Further 19 | 20 | - to identify bugs, and suggest fixes untill the point of publication 21 | - to add figures for the paper 22 | - documentation 23 | - tutorial for elephant package? 24 | 25 | 26 | 2017_12_20 27 | 1) Tagged the previous stable version as v1.0 28 | 2) Tagged the version on elephant as v1.1 29 | 3) Merged elephant version which is Py2/3 compatible into master 30 | 4) Changed the folder structure a bit to accomodate for the new dev 31 | 32 | -corelib has the KCSD.py file which includes all the necessary classes 33 | -tests is where the unit tests will eventually go 34 | -validation is where the tests from the previous edition go (poor naming choice by me, in retrospect) these are being re-written in a saner 'class'y way now. 35 | -tutorials is where ther ipython notebooks will eventually supposed to go. 36 | 37 | 38 | NOTES FROM v1.0 which is no longer applicable. Eventually should all move to tutorials. 39 | ===================================================================== 40 | Try 41 | --- 42 | In file test_kCSD1D.py, test_kCSD2D.py and test_kCSD3D.py play with 43 | 1) csd_seed to change True CSD profile 44 | 2) total_ele to change the number of electrodes in the plane of electrodes, n evenly spaced in 1D, n^2 in 2D and n^3 in 3D volume 45 | 3) in main_loop change ele_lims to change the position of the electrodes 46 | 4) in do_kcsd function play with params for regularization 47 | 48 | Legend 49 | ------ 50 | CSD.py - base class of CSD 51 | KCSD.py - base class for kernel CSD methods. 52 | KCSD1D.py - relevant KCD1D reconstruction file (Inherits from KCSD.py) 53 | KCSD2D.py - relevant KCD2D reconstruction file (Inherits from KCSD.py) 54 | KCSD3D.py - relevant KCD3D reconstruction file (inherits from KCSD.py) 55 | MoIKCSD.py - relevant KCSD2D which includes the method of images - models saline conductivity 56 | 57 | basis_functions.py - necessary functions that are used as basis sources 58 | utility_functions.py - necessary generic functions 59 | 60 | tests/test_kCSD1D.py - file generates TrueCSD, potentials in a plane, and its kCSD reconstruction 61 | - use with relevant seed - for small sources and large sources. 62 | - illustrates the basic API of KCSD2D.py 63 | 64 | tests/test_kCSD2D.py - file generates TrueCSD, potentials in a plane, and its kCSD reconstruction 65 | - use with relevant seed - for small sources and large sources. 66 | - illustrates the basic API of KCSD2D.py 67 | 68 | tests/test_kCSD3D.py - file generates TrueCSD, potentials in a volume, and its kCSD reconstruction 69 | - use with relevant seed - for small sources, large sources, monopoles, dipole sources 70 | - illustrates the basic API of KCSD3D.py 71 | 72 | tests/csd_profile.py - used by test_kCSD1D.py, test_kCSD2D.py, test_kCSD3D.py for CSD profiles. 73 | 74 | ======================================================================== 75 | 76 | 77 | 2016_04_18 78 | Preparing for release 79 | Moved functions from KCSD1D_Helpers etc into something more sane. 80 | Using **kwargs instead of params to pass agruments 81 | Saner method names. 82 | 83 | Comments for future 84 | 1) Possibility to use errfunc instead of gaussian 85 | 86 | 2016_03_07 87 | Pushing KCSD1D + tests to beta phase 88 | 89 | Comments for future 90 | 0) Write unit tests and facilitate regression tests for future. 91 | 1) Write test_kCSDx.py as a class 92 | 2) The gaussian source normalization, see guass_rescale_xD function. 93 | 3) Better uniform way to generate csd_profiles, across 3 dims. For legacy reasons, left as it is for now. 94 | 4) Better names for functions and variables? (k.update_b_interp_pot, and k_interp_cross etc) 95 | 96 | 2016_02_09 97 | Pushing KCSD3D + tests to beta phase 98 | 99 | 2015_10_12 100 | REASON for such absurd merging from tags is as follows 101 | 1) intended to not inclue the test_kcsd2d cases 102 | 2.1) someone asked as to how they can trust the method 103 | 2.2) someone asked if the default values in kcsd2d method have any meaning - which they dont 104 | 3) in two separate instances, gave the code to the respective people hence multiple versions 105 | 4) unable to keep up with multiple versions, now including this in trunk. 106 | -------------------------------------------------------------------------------- /docs/source/TUTORIALS.rst: -------------------------------------------------------------------------------- 1 | Tutorials 2 | --------- 3 | 4 | kcsd-python library comes with three extensive tutorials. These 5 | tutorials can be explored online or installed on your desktop computer 6 | depending on your usage. To simple test it out try the online version 7 | first, and if required install the python package. 8 | 9 | **Online version** 10 | 11 | To play around with the library without any installation, you can run 12 | the tutorials on Google collaboratory in a web-browser. **Note:** the 13 | results from a browser are not saved and cannot be retreived. If you 14 | wish to have the results stored somewhere, please use the desktop 15 | version. 16 | 17 | **Desktop version** 18 | 19 | This requires you to install the kCSD-package and additionally to 20 | install jupyter notebook on your desktop. 21 | 22 | .. code-block:: bash 23 | 24 | pip install kcsd 25 | pip install jupyter notebook 26 | 27 | 28 | 29 | 30 | Basic Features 31 | ~~~~~~~~~~~~~~ 32 | 33 | This tutorial showcases, the use of the kCSD-python package in the 34 | case of the simplest 2D square grid of electrodes. It defines a region 35 | where can place true current sources, probe it with a grid or 36 | electrodes, based on these measurements and using the proposed method, 37 | estimate the CSD. Since we also know the true sources, we can now 38 | estimate the error in the estimation method as well. To this 39 | preliminary setup, we add noise to the measurements at the electrodes, 40 | and repeat the procedure. We also explore the situation when certain 41 | number of the electrode are broken, and how that would effect the 42 | reconstructions. 43 | 44 | The tutorial is provided with Google collaboratory, click the button below to 45 | interact with it in a browser, no installation necessary. 46 | 47 | `Basic tutorial `_ 48 | 49 | .. 50 | .. image:: https://mybinder.org/badge.svg 51 | :target: https://mybinder.org/v2/gh/Neuroinflab/kCSD-python/master?filepath=tutorials%2Ftutorial_basic.ipynb 52 | 53 | 54 | For a non-interactive static version of this tutorial, see 55 | `Tutorial1 `_. 56 | 57 | 58 | 59 | Advanced Features 60 | ~~~~~~~~~~~~~~~~~ 61 | 62 | This tutorial showcases many more features of the kcsd-python package, 63 | especially the cases when the electrodes are distributed in 1D 64 | (laminar probe like), 2D (Neuropixel like), 3D (Utah array like) or on 65 | a microelectrode arrays (MEA, slice with saline). It is provided with 66 | buttons and easy clickable interface to enable the user to navigate 67 | the otherwise dense details. In some ways, it extends on the Basic 68 | Features tutorial and expands it to the other dimensions. NOTE, the 69 | user might have to 'Reset this tutorial' before using to enable the 70 | buttons (Kernel>Restart & Run All). 71 | 72 | The tutorial is provided with Google collaboratory, click the button below to 73 | interact with it in a browser, no installation necessary. 74 | 75 | `Advanced tutorial `_ 76 | 77 | .. 78 | .. image:: https://mybinder.org/badge.svg 79 | :target: https://mybinder.org/v2/gh/Neuroinflab/kCSD-python/master?filepath=tutorials%2Ftutorial_advanced.ipynb 80 | 81 | 82 | For a non-interactive static version of this tutorial, see 83 | `Tutorial2 `_. 84 | 85 | sKCSD Tutorial 86 | ~~~~~~~~~~~~~~ 87 | 88 | This tutorial showcases the possibility to reconstruct the current sources 89 | of a single neuron provided the morphology of the said neuron is known. 90 | This methods has been described extensively here: https://doi.org/10.7554/eLife.29384 91 | 92 | 93 | `sKCSD tutorial `_ 94 | 95 | 96 | For a non-interactive static version of this tutorial, see 97 | `sKCSD Tutorial `_ 98 | 99 | 100 | More Tutorials 101 | ~~~~~~~~~~~~~~ 102 | 103 | There are many more ways to test this method some of these can be made 104 | into tutorials for easier understanding. While we are working on this, 105 | they will appear here once they reach production level. Please 106 | watch-out this space in the near future. We also take requests for 107 | tutorials. 108 | 109 | Do you wish there was a tutorial for your setup? Can you provide us 110 | with the electrode positions and some sample recordings under open 111 | license? If so, we might be able to tailor-make a tutorial for you! 112 | Please get in touch. See Contacts. 113 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # kCSD-python documentation build configuration file, created by 5 | # sphinx-quickstart on Sat Jun 15 16:08:11 2019. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | # 20 | import os 21 | import sys 22 | sys.path.insert(0, os.path.abspath('.')) 23 | sys.path.insert(0, os.path.abspath('../../')) 24 | 25 | 26 | # -- General configuration ------------------------------------------------ 27 | 28 | # If your documentation needs a minimal Sphinx version, state it here. 29 | # 30 | # needs_sphinx = '1.0' 31 | 32 | # Add any Sphinx extension module names here, as strings. They can be 33 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 34 | # ones. 35 | extensions = ['sphinx.ext.autodoc', 36 | 'sphinx.ext.coverage', 37 | 'sphinx.ext.viewcode', 38 | 'sphinx.ext.autosummary', 39 | 'numpydoc',] 40 | 41 | # numpydoc_show_class_members = False 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ['_templates'] 44 | 45 | # The suffix(es) of source filenames. 46 | # You can specify multiple suffix as a list of string: 47 | # 48 | # source_suffix = ['.rst', '.md'] 49 | source_suffix = '.rst' 50 | 51 | # The master toctree document. 52 | master_doc = 'index' 53 | 54 | # General information about the project. 55 | project = 'kCSD-python' 56 | copyright = '2019-2023, Chintaluri et al' 57 | author = 'Chintaluri et al' 58 | 59 | # The version info for the project you're documenting, acts as replacement for 60 | # |version| and |release|, also used in various other places throughout the 61 | # built documents. 62 | # 63 | # The short X.Y version. 64 | version = '2.0' 65 | # The full version, including alpha/beta/rc tags. 66 | release = 'rc' 67 | 68 | # The language for content autogenerated by Sphinx. Refer to documentation 69 | # for a list of supported languages. 70 | # 71 | # This is also used if you do content translation via gettext catalogs. 72 | # Usually you set "language" from the command line for these cases. 73 | language = 'en' 74 | 75 | # List of patterns, relative to source directory, that match files and 76 | # directories to ignore when looking for source files. 77 | # This patterns also effect to html_static_path and html_extra_path 78 | exclude_patterns = [] 79 | 80 | # The name of the Pygments (syntax highlighting) style to use. 81 | pygments_style = 'sphinx' 82 | 83 | # If true, `todo` and `todoList` produce output, else they produce nothing. 84 | todo_include_todos = False 85 | 86 | 87 | # -- Options for HTML output ---------------------------------------------- 88 | 89 | # The theme to use for HTML and HTML Help pages. See the documentation for 90 | # a list of builtin themes. 91 | # 92 | html_theme = 'alabaster' 93 | 94 | # Theme options are theme-specific and customize the look and feel of a theme 95 | # further. For a list of options available for each theme, see the 96 | # documentation. 97 | # 98 | # html_theme_options = {} 99 | 100 | # Add any paths that contain custom static files (such as style sheets) here, 101 | # relative to this directory. They are copied after the builtin static files, 102 | # so a file named "default.css" will overwrite the builtin "default.css". 103 | # html_static_path = ['_static'] 104 | html_static_path = [] 105 | 106 | # Custom sidebar templates, must be a dictionary that maps document names 107 | # to template names. 108 | # 109 | # This is required for the alabaster theme 110 | # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars 111 | html_sidebars = { 112 | '**': [ 113 | 'about.html', 114 | 'navigation.html', 115 | 'relations.html', # needs 'show_related': True theme option to display 116 | 'searchbox.html', 117 | 'donate.html', 118 | ] 119 | } 120 | 121 | 122 | # -- Options for HTMLHelp output ------------------------------------------ 123 | 124 | # Output file base name for HTML help builder. 125 | htmlhelp_basename = 'kCSD-pythondoc' 126 | 127 | 128 | # -- Options for LaTeX output --------------------------------------------- 129 | 130 | latex_elements = { 131 | # The paper size ('letterpaper' or 'a4paper'). 132 | # 133 | # 'papersize': 'letterpaper', 134 | 135 | # The font size ('10pt', '11pt' or '12pt'). 136 | # 137 | # 'pointsize': '10pt', 138 | 139 | # Additional stuff for the LaTeX preamble. 140 | # 141 | # 'preamble': '', 142 | 143 | # Latex figure (float) alignment 144 | # 145 | # 'figure_align': 'htbp', 146 | } 147 | 148 | # Grouping the document tree into LaTeX files. List of tuples 149 | # (source start file, target name, title, 150 | # author, documentclass [howto, manual, or own class]). 151 | latex_documents = [ 152 | (master_doc, 153 | 'kCSD-python.tex', 154 | 'kCSD-python Documentation', 155 | 'Chintaluri et al.', 156 | 'manual'), 157 | ] 158 | 159 | 160 | # -- Options for manual page output --------------------------------------- 161 | 162 | # One entry per manual page. List of tuples 163 | # (source start file, name, description, authors, manual section). 164 | man_pages = [ 165 | (master_doc, 'kcsd-python', 'kCSD-python Documentation', 166 | [author], 1) 167 | ] 168 | 169 | 170 | # -- Options for Texinfo output ------------------------------------------- 171 | 172 | # Grouping the document tree into Texinfo files. List of tuples 173 | # (source start file, target name, title, author, 174 | # dir menu entry, description, category) 175 | texinfo_documents = [ 176 | (master_doc, 'kCSD-python', 'kCSD-python Documentation', 177 | author, 'kCSD-python', 'One line description of project.', 178 | 'Miscellaneous'), 179 | ] 180 | 181 | 182 | 183 | def skip(app, what, name, obj, would_skip, options): 184 | if name == "__init__": 185 | return False 186 | return would_skip 187 | 188 | def setup(app): 189 | app.connect("autodoc-skip-member", skip) 190 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. kCSD-python documentation master file, created by 2 | sphinx-quickstart on Sat Jun 15 16:08:11 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to kCSD-python's documentation! 7 | ======================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | INSTALL 14 | DOCUMENTATION 15 | TUTORIALS 16 | LICENSE 17 | AUTHORS 18 | CITE 19 | 20 | Indices and tables 21 | ================== 22 | 23 | * :ref:`genindex` 24 | * :ref:`search` 25 | -------------------------------------------------------------------------------- /docs/source/requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements for building documentation 2 | scipy 3 | numpy 4 | matplotlib 5 | numpydoc 6 | sphinx 7 | 8 | -------------------------------------------------------------------------------- /figures/kCSD_properties/README.txt: -------------------------------------------------------------------------------- 1 | Instructions for the figures from kCSD-python, reliable current source density estimation with quality control. 2 | 3 | ~~~~~~~~~~~~~~~~~~~~~~~ 4 | Figure 1 - Schematic 5 | 6 | name: figure1.png 7 | 8 | ~~~~~~~~~~~~~~~~~~~~~~~ 9 | Figure 2 - L-curve method for regularization 10 | 11 | You will need to run L_curve_simulation.py first. 12 | 13 | figure_LC.py 14 | 15 | ~~~~~~~~~~~~~~~~~~~~~~~ 16 | Figure 3 - Error propagation map 17 | 18 | error_propagation.py 19 | colorblind_friendly.py 20 | 21 | ~~~~~~~~~~~~~~~~~~~~~~~ 22 | Figure 4 - Reliability map 2D 23 | 24 | reliability_map_2d.py 25 | 26 | Download kCSD_properties.zip file from here: http://bit.ly/kCSD-supplementary 27 | and unzip the data 28 | kCSD_properties/error_maps_2D/point_error_large_100_all_ele.npy 29 | kCSD_properties/error_maps_2D/point_error_small_100_all_ele.npy 30 | 31 | ~~~~~~~~~~~~~~~~~~~~~~~ 32 | Figure 5 - Reliability map; Use case in a 2D dipolar large source 33 | 34 | kCSD_with_reliability_map_2D.py 35 | 36 | Download kCSD_properties.zip file from here http://bit.ly/kCSD-supplementary 37 | and unzip the data 38 | kCSD_properties/error_maps_2D/point_error_large_100_all_ele.npy 39 | kCSD_properties/error_maps_2D/point_error_small_100_all_ele.npy 40 | 41 | ~~~~~~~~~~~~~~~~~~~~~~~ 42 | Figure 6 - Average Error (Diff) when broken electrode and loss in reconstruction quality 43 | 44 | You will need to run tutorial3.py first or download kCSD_properties.zip file from here 45 | http://bit.ly/kCSD-supplementary 46 | 47 | tutorial_broken_electrodes_diff_err.py 48 | 49 | ~~~~~~~~~~~~~~~~~~~~~~~ 50 | 51 | Figure 7 - L-Curve and CV landscape 52 | 53 | You will need to run L_curve_simulation.py first. 54 | 55 | figure_LCandCV.py 56 | 57 | ~~~~~~~~~~~~~~~~~~~~~~~ 58 | 59 | Figure 8 - Basic features tutorial 60 | 61 | You will need to run tutorial3.py first or download kCSD_properties.zip file from here 62 | http://bit.ly/kCSD-supplementary 63 | 64 | tutorial_basic.py 65 | 66 | ~~~~~~~~~~~~~~~~~~~~~~~ 67 | 68 | Figure 9 - Noisy electrodes tutorial 69 | 70 | tutorial_noisy_electrodes.py 71 | 72 | ~~~~~~~~~~~~~~~~~~~~~~~ 73 | Figure 10 - Broken electrodes tutorial 74 | 75 | Download kCSD_properties.zip file first from 76 | http://bit.ly/kCSD-supplementary 77 | (generated from tweaking tutorial3.py) 78 | 79 | tutorial_broken_electrodes.py 80 | 81 | ~~~~~~~~~~~~~~~~~~~~~~~ 82 | Figure 11 - Error propagation maps for 1D 83 | 84 | pots_propagation.py 85 | 86 | ~~~~~~~~~~~~~~~~~~~~~~~ 87 | Figure 12 - 3D source reconstruction 88 | 89 | tutorial_basic_3d.py 90 | 91 | ~~~~~~~~~~~~~~~~~~~~~~~ 92 | Figure 13 - sKCSD example 93 | 94 | You will need to install LFPy package first: 95 | pip install lfpy 96 | 97 | skcsd_and_l_curve_complex_morphology.py 98 | -------------------------------------------------------------------------------- /figures/kCSD_properties/colorblind_friendly.py: -------------------------------------------------------------------------------- 1 | # Based on 2 | # Color Universal Design (CUD) 3 | # - How to make figures and presentations that are friendly to Colorblind people 4 | # 5 | # 6 | # Masataka Okabe 7 | # Jikei Medial School (Japan) 8 | # 9 | # Kei Ito 10 | # University of Tokyo, Institute for Molecular and Cellular Biosciences (Japan) 11 | # (both are strong protanopes) 12 | # 11.20.2002 (modified on 2.15.2008, 9.24.2008) 13 | # http://jfly.iam.u-tokyo.ac.jp/color/#pallet 14 | 15 | import collections 16 | from matplotlib import colors 17 | 18 | 19 | _Color = collections.namedtuple('_Color', ['red', 'green', 'blue']) 20 | 21 | def _html(r, g, b): 22 | return "#{:02X}{:02X}{:02X}".format(r, g, b) 23 | 24 | 25 | _BLACK = _Color( 0, 0, 0) 26 | _ORANGE = _Color(230, 159, 0) 27 | _SKY_BLUE = _Color( 86, 180, 233) 28 | _GREEN = _Color( 0, 158, 115) 29 | _YELLOW = _Color(240, 228, 66) 30 | _BLUE = _Color( 0, 114, 178) 31 | _VERMILION = _Color(213, 94, 0) 32 | _PURPLE = _Color(204, 121, 167) 33 | 34 | BLACK = _html(*_BLACK) 35 | ORANGE = _html(*_ORANGE) 36 | SKY_BLUE = _html(*_SKY_BLUE) 37 | GREEN = _html(*_GREEN) 38 | YELLOW = _html(*_YELLOW) 39 | BLUE = _html(*_BLUE) 40 | VERMILION = _html(*_VERMILION) 41 | PURPLE = _html(*_PURPLE) 42 | 43 | def _BipolarColormap(name, negative, positive): 44 | return colors.LinearSegmentedColormap( 45 | name, 46 | {k: [(0.0,) + (getattr(negative, k) / 255.,) * 2, 47 | (0.5, 1.0, 1.0), 48 | (1.0,) + (getattr(positive, k) / 255.,) * 2,] 49 | for k in ['red', 'green', 'blue']}) 50 | 51 | bwr = _BipolarColormap('cbf.bwr', _BLUE, _VERMILION) 52 | PRGn = _BipolarColormap('cbf.PRGn', _PURPLE, _GREEN) -------------------------------------------------------------------------------- /figures/kCSD_properties/figure_LC.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jul 18 16:39:53 2019 4 | 5 | @author: Wladek 6 | """ 7 | import scipy.stats as st 8 | import os 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.gridspec as gridspec 12 | from figure_properties import * 13 | 14 | def set_axis(ax, x, y, letter=None): 15 | ax.text(x, 16 | y, 17 | letter, 18 | fontsize=15, 19 | weight='bold', 20 | transform=ax.transAxes) 21 | return ax 22 | 23 | def make_plots(title, m_norm, m_resi, true_csd, curveseq, ele_y, 24 | pots_n, pots, k_csd_x, est_pot, est_csd, noreg_csd, save_as): 25 | """ 26 | Shows 4 plots 27 | 1_ LFP measured (with added noise) and estimated LFP with kCSD method 28 | 2_ true CSD and reconstructed CSD with kCSD 29 | 3_ L-curve of the model 30 | 4_ Surface of parameters R and Lambda with scores for optimal paramater selection with L-curve or cross-validation 31 | """ 32 | #True CSD 33 | lambdas = np.logspace(-7, -3, 50) 34 | fig = plt.figure(figsize=(12, 12), dpi=300) 35 | widths = [1, 1] 36 | heights = [1, 1] 37 | xpad= 5 38 | ypad = 10 39 | gs = gridspec.GridSpec(2, 2, height_ratios=heights, width_ratios=widths, 40 | hspace=0.6, wspace=0.6) 41 | xrange = np.linspace(0, 1, len(true_csd)) 42 | ax1 = plt.subplot(gs[0]) 43 | ax1.plot(ele_y, pots_n*1e3, 'r', marker='o', linewidth=0, label='Measured potential with noise') 44 | ax1.plot(ele_y, pots*1e3, 'b', marker='o', linewidth=0, label='Measured potential') 45 | ax1.scatter(ele_y, np.zeros(len(ele_y))-11, 8, color='black', 46 | clip_on=False, label = "Electrode position") 47 | ax1.plot(xrange, est_pot*1e3, label='Reconstructed potential', color='blue') 48 | plt.ylim(-11,11) 49 | ax1.set_ylabel('Potential ($mV$)', labelpad = ypad+2) 50 | ax1.set_xlabel('Distance ($mm$)', labelpad = xpad) 51 | ax1.tick_params(axis='both', which='major') 52 | ax1.spines['right'].set_visible(False) 53 | ax1.spines['top'].set_visible(False) 54 | set_axis(ax1, -0.05, 1.05, letter='A') 55 | ax1.legend(bbox_to_anchor=(1.7, -0.2), ncol=2, frameon=False) 56 | 57 | ax_L = plt.subplot(gs[1]) 58 | m_resi = np.log(m_resi) 59 | m_norm = np.log(m_norm) 60 | imax = np.argmax(curveseq[np.argmax(np.max(curveseq, axis=-1))]) 61 | imax2 = np.argmax(np.max(curveseq, axis=-1)) 62 | plt.ylabel("Log norm of the model", labelpad = ypad) 63 | plt.xlabel("Log norm of the prediction error", labelpad = xpad) 64 | ax_L.plot(m_resi, m_norm, marker=".", c="green", label = 'L-Curve') 65 | ax_L.plot([m_resi[imax]], [m_norm[imax]], marker="o", c="red") 66 | x = [m_resi[0], m_resi[imax], m_resi[-1]] 67 | y = [m_norm[0], m_norm[imax], m_norm[-1]] 68 | ax_L.fill(x, y, alpha=0.2) 69 | plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0)) 70 | ax_L.spines['right'].set_visible(False) 71 | ax_L.spines['top'].set_visible(False) 72 | set_axis(ax_L, -0.05, 1.05, letter='B') 73 | ax_L.legend(bbox_to_anchor=(0.7, -0.2), ncol=1, frameon=False) 74 | 75 | ax2 = plt.subplot(gs[2]) 76 | plt.plot(xrange, true_csd, label='True CSD', color='red', linestyle = '--') 77 | plt.plot(xrange, est_csd, label='kCSD + regularization', color='blue') 78 | plt.plot(xrange, noreg_csd, label='kCSD', color='darkgreen', alpha = 0.6) 79 | plt.scatter(ele_y, np.zeros(len(ele_y))-1, 8, color='black', 80 | label = "Electrode position", clip_on=False) 81 | ax2.set_ylabel('CSD ($mA/mm$)', labelpad = ypad) 82 | ax2.set_xlabel('Distance ($mm$)', labelpad = xpad) 83 | plt.ylim(-1, 1) 84 | ax2.spines['right'].set_visible(False) 85 | ax2.spines['top'].set_visible(False) 86 | ax2.legend(bbox_to_anchor=(-.25, -0.27), ncol=2, frameon=False, loc = 'center left') 87 | set_axis(ax2, -0.05, 1.05, letter='C') 88 | 89 | ax4 = plt.subplot(gs[3]) 90 | ax4.plot(lambdas, curveseq[imax2], marker=".", label = 'Curvature evaluation') 91 | ax4.plot([lambdas[imax]], [curveseq[imax2][imax]], marker="o", c="red") 92 | ax4.set_ylabel('Curvature', labelpad = ypad) 93 | ax4.set_xlabel('$\lambda$', labelpad = xpad) 94 | ax4.set_xscale('log') 95 | ax4.tick_params(axis='both', which='major') 96 | ax4.spines['right'].set_visible(False) 97 | ax4.spines['top'].set_visible(False) 98 | ax4.legend(bbox_to_anchor=(1, -0.2), ncol=2, frameon=False) 99 | set_axis(ax4, -0.05, 1.05, letter='D') 100 | fig.savefig(save_as+'.png') 101 | 102 | if __name__=='__main__': 103 | os.chdir("./LCurve/LC2") 104 | noises = 3 105 | noise_lvl = np.linspace(0, 0.5, noises) 106 | df = np.load('data_fig4_and_fig13_LC_noise25.0.npz') 107 | Rs = np.linspace(0.025, 8*0.025, 8) 108 | title = ['file_name'] 109 | save_as = 'noise' 110 | make_plots(title, df['m_norm'], df['m_resi'], df['true_csd'], 111 | df['curve_surf'], df['ele_y'], df['pots_n'], 112 | df['pots'], df['estm_x'], df['est_pot'], df['est_csd'], 113 | df['noreg_csd'], save_as) 114 | -------------------------------------------------------------------------------- /figures/kCSD_properties/figure_LCandCV.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jul 18 16:39:53 2019 4 | 5 | @author: Wladek 6 | """ 7 | import scipy.stats as st 8 | import os 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.gridspec as gridspec 12 | from figure_properties import * 13 | 14 | def set_axis(ax, x, y, letter=None): 15 | ax.text(x, 16 | y, 17 | letter, 18 | fontsize=15, 19 | weight='bold', 20 | transform=ax.transAxes) 21 | return ax 22 | 23 | def plot_surface(curve_surf, errsy, save_as): 24 | fsize = 18 25 | lambdas = np.logspace(-7, -3, 50) 26 | fig = plt.figure(figsize = (15, 6), dpi = 300) 27 | gs = gridspec.GridSpec(16, 12, hspace=1, wspace=1) 28 | ax = plt.subplot(gs[0:16, 0:6]) 29 | set_axis(ax, -0.05, 1.05, letter='A') 30 | 31 | plt.pcolormesh(lambdas, np.arange(8), curve_surf, 32 | cmap = 'BrBG', vmin = -3, vmax=3) 33 | plt.colorbar() 34 | for i,m in enumerate(curve_surf.argmax(axis=1)): 35 | plt.scatter([lambdas[m]], [i], s=50, color='red', alpha = 0.7) 36 | if i==7: 37 | plt.scatter([lambdas[m]], [i], s=50, color='red', 38 | label = 'Maximum \nCurvature', alpha = 0.7) 39 | plt.xlim(lambdas[1],lambdas[-1]) 40 | plt.title('L-curve regularization', fontsize = fsize) 41 | # plt.legend(loc='center', bbox_to_anchor=(0.5, -0.12), ncol=1, 42 | # frameon = False, fontsize = fsize) 43 | plt.legend(loc='upper left', ncol=1, 44 | frameon = False, fontsize = fsize) 45 | plt.yticks(np.arange(8), [str(x)+'x' for x in range(1,9)]) 46 | plt.xscale('log') 47 | plt.ylabel('Parameter $R$ in electrode distance', fontsize=fsize, labelpad = 15) 48 | plt.xlabel('$\lambda$',fontsize=fsize) 49 | ax = plt.subplot(gs[0:16, 6:12]) 50 | set_axis(ax, -0.05, 1.05, letter='B') 51 | plt.pcolormesh(lambdas, np.arange(8), errsy, cmap='Greys', vmin=0.01, vmax=0.02) 52 | plt.colorbar() 53 | for i,m in enumerate(errsy.argmin(axis=1)): 54 | plt.scatter([lambdas[m]], [i], s=50, color='red', alpha = 0.7) 55 | if i==7: 56 | plt.scatter([lambdas[m]], [i], s=50, color='red', 57 | label = 'Minimum \nError', alpha = 0.7) 58 | plt.xlim(lambdas[1],lambdas[-1]) 59 | # plt.legend(loc='center', bbox_to_anchor=(0.5, -0.12), ncol=1, 60 | # frameon = False, fontsize = fsize) 61 | plt.legend(loc='upper left', ncol=1, 62 | frameon = False, fontsize = fsize) 63 | plt.title('Cross-validation regularization', fontsize = fsize) 64 | plt.yticks(np.arange(8), [str(x)+'x' for x in range(1,9)]) 65 | plt.xscale('log') 66 | plt.xlabel('$\lambda$', fontsize=fsize) 67 | fig.savefig(save_as+'.png') 68 | 69 | if __name__=='__main__': 70 | os.chdir("./LCurve/") 71 | noises = 3 72 | noise_lvl = np.linspace(0, 0.5, noises) 73 | print(os.getcwd()) 74 | df = np.load(os.path.join('LC2', 'data_fig4_and_fig13_LC_noise25.0.npz')) 75 | 76 | Rs = np.linspace(0.025, 8*0.025, 8) 77 | title = ['file_name'] 78 | save_as = 'noise' 79 | plot_surface(df['curve_surf'], df['errsy'], save_as+'surf') 80 | plt.close('all') 81 | -------------------------------------------------------------------------------- /figures/kCSD_properties/figure_LCandCVperformance.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jul 18 16:39:53 2019 4 | 5 | @author: Wladek 6 | """ 7 | import scipy.stats as st 8 | import os 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | import matplotlib.gridspec as gridspec 12 | from figure_properties import * 13 | 14 | def set_axis(ax, x, y, letter=None): 15 | ax.text(x, 16 | y, 17 | letter, 18 | fontsize=15, 19 | weight='bold', 20 | transform=ax.transAxes) 21 | return ax 22 | 23 | def make_plot_perf(sim_results, noise_lvl): 24 | rms_lc = sim_results[0, 2] 25 | lam_lc = sim_results[0, 0] 26 | rms_cv = sim_results[1, 2] 27 | lam_cv = sim_results[1, 0] 28 | fig = plt.figure(figsize = (12,7), dpi = 300) 29 | widths = [1, 1] 30 | heights = [1] 31 | gs = gridspec.GridSpec(1, 2, height_ratios=heights, width_ratios=widths, 32 | hspace=0.45, wspace=0.3) 33 | ax1 = plt.subplot(gs[0]) 34 | if np.min(rms_cv) < np.min(rms_lc): 35 | trans = np.min(np.mean(rms_cv, axis=0)) 36 | else: 37 | trans = np.min(np.mean(rms_lc, axis=0)) 38 | mn_rms = np.mean(rms_lc, axis=0) - trans 39 | st_rms = st.sem(rms_lc, axis=0) 40 | plt.plot(noise_lvl, mn_rms, marker = 'o', color = 'blue', label = 'kCSD L-Curve') 41 | plt.fill_between(noise_lvl, mn_rms - st_rms, 42 | mn_rms + st_rms, alpha = 0.3, color = 'blue') 43 | mn_rms = np.mean(rms_cv, axis=0) - trans 44 | st_rms = st.sem(rms_cv, axis=0) 45 | plt.plot(noise_lvl, mn_rms, marker = 'o', color = 'green', label = 'kCSD Cross-Validation') 46 | plt.fill_between(noise_lvl, mn_rms - st_rms, 47 | mn_rms + st_rms, alpha = 0.3, color = 'green') 48 | plt.ylabel('Estimation Error', labelpad = 15) 49 | plt.xlabel('Relative Noise Level', labelpad = 15) 50 | ax1.spines['right'].set_visible(False) 51 | ax1.spines['top'].set_visible(False) 52 | set_axis(ax1, -0.05, 1.05, letter='A') 53 | ax1.legend(loc='upper left', frameon=False) 54 | # plt.title('Performance of regularization methods') 55 | 56 | '''second plot''' 57 | ax2 = plt.subplot(gs[1]) 58 | mn_lam = np.mean(lam_lc, axis=0) 59 | st_lam = st.sem(lam_lc, axis=0) 60 | plt.plot(noise_lvl, mn_lam, marker = 'o', color = 'blue', label = 'kCSD L-Curve') 61 | plt.fill_between(noise_lvl, mn_lam - st_lam, 62 | mn_lam + st_lam, alpha = 0.3, color = 'blue') 63 | mn_lam = np.mean(lam_cv, axis=0) 64 | st_lam = st.sem(lam_cv, axis=0) 65 | plt.plot(noise_lvl, mn_lam, marker = 'o', color = 'green', label = 'kCSD Cross-Validation') 66 | plt.fill_between(noise_lvl, mn_lam - st_lam, 67 | mn_lam + st_lam, alpha = 0.3, color = 'green') 68 | ax2.ticklabel_format(style='sci', axis='y', scilimits=((0.0, 0.0))) 69 | plt.ylabel('$\lambda$', labelpad = 30, rotation = 0) 70 | plt.xlabel('Relative Noise Level', labelpad = 15) 71 | set_axis(ax2, -0.05, 1.05, letter='B') 72 | ht, lh = ax2.get_legend_handles_labels() 73 | #fig.legend(ht, lh, loc='upper center', ncol=2, frameon=False) 74 | ax2.spines['right'].set_visible(False) 75 | ax2.spines['top'].set_visible(False) 76 | ax2.legend(loc='upper left', frameon=False) 77 | fig.savefig('stats.png') 78 | 79 | if __name__=='__main__': 80 | os.chdir("./LCurve/") 81 | noises = 9 82 | noise_lvl = np.linspace(0, 0.5, noises) 83 | sim_results = np.load('sim_results.npy') 84 | make_plot_perf(sim_results, noise_lvl) 85 | -------------------------------------------------------------------------------- /figures/kCSD_properties/figure_error_3x3.py: -------------------------------------------------------------------------------- 1 | """ 2 | @author: mkowalska 3 | """ 4 | 5 | import os 6 | import numpy as np 7 | from figure_properties import * 8 | from kCSD_with_reliability_map_2D import matrix_symmetrization 9 | from reliability_map_2D import generate_reliability_map 10 | 11 | 12 | if __name__ == '__main__': 13 | path = os.path.join(os.path.expanduser('~'), 'Dropbox', 'kCSDrev-pics') 14 | large = np.load(path + '/error_maps_2D/data_large_100_3x3.npz') 15 | small = np.load(path + '/error_maps_2D/data_small_100_3x3.npz') 16 | data_l = {key: large[key].item() for key in large} 17 | data_s = {key: small[key].item() for key in small} 18 | csd_at = data_l['data']['csd_at'] 19 | error_l = data_l['data']['error'] 20 | error_s = data_s['data']['error'] 21 | ele_pos = data_l['data']['ele_pos'] 22 | 23 | error_all = np.concatenate((error_l, error_s)) 24 | symm_array_large = matrix_symmetrization(error_l) 25 | symm_array_small = matrix_symmetrization(error_s) 26 | symm_array_all = matrix_symmetrization(error_all) 27 | generate_reliability_map(np.mean(symm_array_all, axis=0), ele_pos, 28 | 'Reliability_map_random_newRDM_symm_3x3') 29 | generate_reliability_map(np.mean(symm_array_large, axis=0), ele_pos, 30 | 'Reliability_map_large_newRDM_symm_3x3') 31 | generate_reliability_map(np.mean(symm_array_small, axis=0), ele_pos, 32 | 'Reliability_map_small_newRDM_symm_3x3') 33 | -------------------------------------------------------------------------------- /figures/kCSD_properties/figure_properties.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | plt.rcParams.update({ 4 | 5 | 'xtick.labelsize': 15, 6 | 'xtick.major.size': 10, 7 | 'ytick.labelsize': 15, 8 | 'ytick.major.size': 10, 9 | 'font.size': 12, 10 | 'axes.labelsize': 15, 11 | 'axes.titlesize': 20, 12 | 'axes.titlepad' : 30, 13 | 'legend.fontsize': 15, 14 | # 'figure.subplot.wspace': 0.4, 15 | # 'figure.subplot.hspace': 0.4, 16 | # 'figure.subplot.left': 0.1, 17 | }) 18 | 19 | 20 | def cm_to_inches(vals): 21 | return [0.393701*ii for ii in vals] 22 | -------------------------------------------------------------------------------- /figures/kCSD_properties/pdf_merger.py: -------------------------------------------------------------------------------- 1 | from PyPDF2 import PdfFileMerger 2 | 3 | path = '/home/mkowalska/Marta/kCSD-python/figures/kCSD_properties/' 4 | name = 'small_srcs_all_ele' 5 | 6 | merger = PdfFileMerger() 7 | 8 | for i in range(100): 9 | pdf = path + name + '/' + str(i) + '.pdf' 10 | merger.append(open(pdf, 'rb')) 11 | 12 | with open(path + name + '/' + name + '_err.pdf', 'wb') as fout: 13 | merger.write(fout) 14 | -------------------------------------------------------------------------------- /figures/kCSD_properties/pots_propagation.py: -------------------------------------------------------------------------------- 1 | """ 2 | @author: mkowalska 3 | """ 4 | import os 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | from figure_properties import * 8 | import matplotlib.gridspec as gridspec 9 | 10 | from kcsd import KCSD1D 11 | 12 | __abs_file__ = os.path.abspath(__file__) 13 | 14 | 15 | def pots_scan(n_src, ele_lims, true_csd_xlims, 16 | total_ele, ele_pos, R_init=0.23): 17 | """ 18 | Investigates kCSD reconstructions for unitary potential on different 19 | electrodes 20 | 21 | Parameters 22 | ---------- 23 | n_src: int 24 | Number of basis sources. 25 | ele_lims: list 26 | Boundaries for electrodes placement. 27 | true_csd_xlims: list 28 | Boundaries for ground truth space. 29 | total_ele: int 30 | Number of electrodes. 31 | ele_pos: numpy array 32 | Electrodes positions. 33 | 34 | Returns 35 | ------- 36 | obj_all: class object 37 | eigenvalues: numpy array 38 | Eigenvalues of k_pot matrix. 39 | eigenvectors: numpy array 40 | Eigen vectors of k_pot matrix. 41 | """ 42 | obj_all = [] 43 | est_csd = [] 44 | for i, value in enumerate(ele_pos): 45 | pots = np.zeros(len(ele_pos)) 46 | pots[i] = 1 47 | pots = pots.reshape((len(ele_pos), 1)) 48 | obj = KCSD1D(ele_pos, pots, src_type='gauss', sigma=0.3, h=0.25, 49 | gdx=0.01, n_src_init=n_src, ext_x=0, xmin=0, xmax=1, 50 | R_init=R_init) 51 | est_csd.append(obj.values('CSD')) 52 | 53 | obj_all.append(obj) 54 | return obj_all, est_csd 55 | 56 | 57 | def set_axis(ax, x, y, letter=None): 58 | """ 59 | Formats the plot's caption. 60 | 61 | Parameters 62 | ---------- 63 | ax: Axes object. 64 | x: float 65 | X-position of caption. 66 | y: float 67 | Y-position of caption. 68 | letter: string 69 | Caption of the plot. 70 | Default: None. 71 | 72 | Returns 73 | ------- 74 | ax: modyfied Axes object. 75 | """ 76 | ax.text( 77 | x, 78 | y, 79 | letter, 80 | fontsize=15, 81 | weight='bold', 82 | transform=ax.transAxes) 83 | return ax 84 | 85 | 86 | def generate_figure(true_csd_xlims, total_ele, ele_lims, R_init=0.23): 87 | """ 88 | Generates figure for potential propagation. Shows kCSD recostruction 89 | for unitary potential on one electrode. 90 | 91 | Parameters 92 | ---------- 93 | true_csd_xlims: list 94 | Boundaries for ground truth space. 95 | total_ele: int 96 | Number of electrodes. 97 | ele_lims: list 98 | Electrodes limits. 99 | R_init: float 100 | Initial value of R parameter. 101 | 102 | Returns 103 | ------- 104 | None 105 | """ 106 | ele_pos = np.linspace(ele_lims[0], ele_lims[1], total_ele) 107 | ele_pos = ele_pos.reshape((len(ele_pos), 1)) 108 | n_src = 256 109 | OBJ_M, est_csd = pots_scan(n_src, ele_lims, true_csd_xlims, 110 | total_ele, ele_pos, R_init=R_init) 111 | 112 | plt_cord = [(0, 0), (0, 2), (0, 4), 113 | (1, 0), (1, 2), (1, 4), 114 | (2, 0), (2, 2), (2, 4), 115 | (3, 0), (3, 2), (3, 4)] 116 | 117 | letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'] 118 | 119 | fig = plt.figure(figsize=(17, 12)) 120 | heights = [1, 1, 1, 1] 121 | gs = gridspec.GridSpec(4, 6, height_ratios=heights, hspace=0.3, wspace=0.8) 122 | 123 | for i in range(len(ele_pos)): 124 | ax = fig.add_subplot(gs[plt_cord[i][0], 125 | plt_cord[i][1]:plt_cord[i][1]+2]) 126 | ax.plot(np.linspace(0, 1, 101), est_csd[i], lw=2, c='red', 127 | label='kCSD') 128 | ax.scatter(ele_pos, np.zeros(len(ele_pos)), c='k', label='Electrodes') 129 | ax2 = ax.twinx() 130 | ax2.plot(np.linspace(0, 1, 101), OBJ_M[i].values('POT'), c='green', 131 | label='Potentials') 132 | ax2.set_ylim([-1.5, 1.5]) 133 | ax.set_ylim([-150, 150]) 134 | set_axis(ax, -0.10, 1.1, letter=letters[i]) 135 | 136 | if i < 9: 137 | ax.get_xaxis().set_visible(False) 138 | ax.spines['bottom'].set_visible(False) 139 | else: 140 | ax.set_xlabel('Depth ($mm$)') 141 | if i % 3 == 0: 142 | ax.set_ylabel('CSD ($mA/mm$)') 143 | ax.set_yticks((-100, 0, 100)) 144 | ax.set_yticklabels(('-100', '0', '100')) 145 | ax.yaxis.set_label_coords(-0.18, 0.5) 146 | else: 147 | ax.set_yticks(()) 148 | if (i+1) % 3 == 0: 149 | ax2.set_ylabel('Potentials ($mV$)') 150 | ax2.set_yticks((-1, 0, 1)) 151 | ax2.set_yticklabels(('-1', '0', '1')) 152 | else: 153 | ax2.set_yticks(()) 154 | 155 | # ax.ticklabel_format(style='sci', axis='y', scilimits=((0.0, 0.0))) 156 | ax.spines['right'].set_visible(False) 157 | ax.spines['top'].set_visible(False) 158 | # align_yaxis(ax, 0, ax2, 0) 159 | ht1, lh1 = ax.get_legend_handles_labels() 160 | ht2, lh2 = ax2.get_legend_handles_labels() 161 | 162 | fig.legend(ht1+ht2, lh1+lh2, loc='lower center', ncol=3, frameon=False) 163 | fig.savefig(os.path.join('potential_propagation_R0_2' + '.png'), dpi=300) 164 | plt.show() 165 | 166 | 167 | if __name__ == '__main__': 168 | ELE_LIMS = [0, 1.] 169 | TRUE_CSD_XLIMS = [0., 1.] 170 | TOTAL_ELE = 12 171 | R_init = 0.2 172 | lambdas = np.zeros([1]) 173 | generate_figure(TRUE_CSD_XLIMS, TOTAL_ELE, ELE_LIMS, 174 | R_init=R_init) 175 | -------------------------------------------------------------------------------- /figures/kCSD_properties/reliability_map_2D.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | import matplotlib.cm as cm 5 | from matplotlib import gridspec 6 | from kcsd import csd_profile as CSD 7 | from kcsd import ValidateKCSD2D 8 | from figure_properties import * 9 | from kCSD_with_reliability_map_2D import make_reconstruction, matrix_symmetrization 10 | 11 | 12 | def set_axis(ax, letter=None): 13 | """ 14 | Formats the plot's caption. 15 | 16 | Parameters 17 | ---------- 18 | ax: Axes object. 19 | x: float 20 | X-position of caption. 21 | y: float 22 | Y-position of caption. 23 | letter: string 24 | Caption of the plot. 25 | Default: None. 26 | 27 | Returns 28 | ------- 29 | ax: modyfied Axes object. 30 | """ 31 | ax.text( 32 | -0.05, 33 | 1.05, 34 | letter, 35 | fontsize=20, 36 | weight='bold', 37 | transform=ax.transAxes) 38 | return ax 39 | 40 | 41 | def make_single_subplot(ax, val_type, xs, ys, values, cax, title=None, 42 | ele_pos=None, xlabel=False, ylabel=False, letter='', 43 | t_max=1., mask=False, level=False): 44 | cmap = cm.Greys 45 | ax.set_aspect('equal') 46 | if t_max is None: 47 | t_max = np.max(np.abs(values)) 48 | if level is not False: 49 | levels = level 50 | else: 51 | levels = np.linspace(0, 0.2, 32) 52 | im = ax.contourf(xs, ys, values, 53 | levels=levels, cmap=cmap, alpha=1) 54 | CS = ax.contour(xs, ys, values, cmap='Greys') 55 | ax.clabel(CS, # label every second level 56 | inline=1, 57 | fmt='%1.2f', 58 | colors='blue') 59 | if val_type == 'err': 60 | ax.scatter(ele_pos[:, 0], ele_pos[:, 1], s=20, marker='.', c='black', 61 | zorder=3) 62 | ax.set_xlim([0, 1]) 63 | ax.set_ylim([0, 1]) 64 | if xlabel: 65 | ax.set_xlabel('X (mm)') 66 | if ylabel: 67 | ax.set_ylabel('Y (mm)') 68 | if title is not None: 69 | ax.set_title(title) 70 | ax.set_xticks([0, 0.5, 1]) 71 | ax.set_yticks([0, 0.5, 1]) 72 | ticks = np.linspace(0, 0.2, 3, endpoint=True) 73 | plt.colorbar(im, cax=cax, orientation='horizontal', format='%.2f', 74 | ticks=ticks) 75 | set_axis(ax, letter=letter) 76 | #plt.tight_layout() 77 | return ax, cax 78 | 79 | 80 | def generate_reliability_map(point_error, ele_pos, title): 81 | csd_at = np.mgrid[0.:1.:100j, 82 | 0.:1.:100j] 83 | csd_x, csd_y = csd_at 84 | plt.figure(figsize=(17, 6)) 85 | gs = gridspec.GridSpec(2, 1, height_ratios=[1., 0.04], left=0.415, 86 | right=0.585, top=0.880, bottom=0.110) 87 | ax = plt.subplot(gs[0, 0]) 88 | cax = plt.subplot(gs[1, 0]) 89 | make_single_subplot(ax, 'err', csd_x, csd_y, point_error, cax=cax, 90 | ele_pos=ele_pos, title=None, xlabel=True, ylabel=True, 91 | letter=' ', t_max=0.2, level=np.linspace(0, 0.2, 16)) 92 | plt.savefig(title + '.png', dpi=300) 93 | plt.show() 94 | 95 | 96 | if __name__ == '__main__': 97 | CSD_PROFILE = CSD.gauss_2d_large 98 | CSD_SEED = 16 99 | ELE_LIMS = [0.05, 0.95] # range of electrodes space 100 | method = 'cross-validation' 101 | Rs = np.arange(0.2, 0.5, 0.1) 102 | lambdas = np.zeros(1) 103 | noise = 0 104 | 105 | KK = ValidateKCSD2D(CSD_SEED, h=50., sigma=1., n_src_init=400, 106 | est_xres=0.01, est_yres=0.01, ele_lims=ELE_LIMS) 107 | k, csd_at, true_csd, ele_pos, pots = make_reconstruction(KK, CSD_PROFILE, 108 | CSD_SEED, 109 | total_ele=100, 110 | noise=noise, 111 | Rs=Rs, 112 | lambdas=lambdas, 113 | method=method) 114 | 115 | error_l = np.load('error_maps_2D/point_error_large_100_all_ele.npy') 116 | error_s = np.load('error_maps_2D/point_error_small_100_all_ele.npy') 117 | error_all = np.concatenate((error_l, error_s)) 118 | symm_array_large = matrix_symmetrization(error_l) 119 | symm_array_small = matrix_symmetrization(error_s) 120 | symm_array_all = matrix_symmetrization(error_all) 121 | 122 | generate_reliability_map(np.mean(symm_array_all, axis=0), ele_pos, 123 | 'Reliability_map_random_newRDM_symm') 124 | generate_reliability_map(np.mean(symm_array_large, axis=0), ele_pos, 125 | 'Reliability_map_large_newRDM_symm') 126 | generate_reliability_map(np.mean(symm_array_small, axis=0), ele_pos, 127 | 'Reliability_map_small_newRDM_symm') 128 | -------------------------------------------------------------------------------- /figures/kCSD_properties/reliability_map_3x3.py: -------------------------------------------------------------------------------- 1 | """ 2 | @author: mkowalska 3 | """ 4 | from builtins import range 5 | 6 | import numpy as np 7 | from kcsd import csd_profile as CSD 8 | from kcsd import ValidateKCSD2D 9 | from figure_properties import * 10 | 11 | try: 12 | from joblib import Parallel, delayed 13 | import multiprocessing 14 | NUM_CORES = multiprocessing.cpu_count() - 1 15 | PARALLEL_AVAILABLE = True 16 | except ImportError: 17 | PARALLEL_AVAILABLE = False 18 | 19 | 20 | def set_axis(ax, letter=None): 21 | """ 22 | Formats the plot's caption. 23 | 24 | Parameters 25 | ---------- 26 | ax: Axes object. 27 | x: float 28 | X-position of caption. 29 | y: float 30 | Y-position of caption. 31 | letter: string 32 | Caption of the plot. 33 | Default: None. 34 | 35 | Returns 36 | ------- 37 | ax: modyfied Axes object. 38 | """ 39 | ax.text( 40 | -0.05, 41 | 1.05, 42 | letter, 43 | fontsize=20, 44 | weight='bold', 45 | transform=ax.transAxes) 46 | return ax 47 | 48 | 49 | def make_reconstruction(KK, csd_profile, csd_seed, total_ele, 50 | ele_lims=None, noise=0, nr_broken_ele=None, 51 | Rs=None, lambdas=None, method='cross-validation'): 52 | """ 53 | Main method, makes the whole kCSD reconstruction. 54 | 55 | Parameters 56 | ---------- 57 | KK: instance of the class 58 | Instance of ValidateKCSD2D class. 59 | csd_profile: function 60 | Function to produce csd profile. 61 | csd_seed: int 62 | Seed for random generator to choose random CSD profile. 63 | total_ele: int 64 | Number of electrodes. 65 | ele_lims: list 66 | Electrodes limits. 67 | Default: None. 68 | noise: float 69 | Determines the level of noise in the data. 70 | Default: 0. 71 | nr_broken_ele: int 72 | How many electrodes are broken (excluded from analysis) 73 | Default: None. 74 | Rs: numpy 1D array 75 | Basis source parameter for crossvalidation. 76 | Default: None. 77 | lambdas: numpy 1D array 78 | Regularization parameter for crossvalidation. 79 | Default: None. 80 | method: string 81 | Determines the method of regularization. 82 | Default: cross-validation. 83 | 84 | Returns 85 | ------- 86 | 87 | """ 88 | csd_at, true_csd = KK.generate_csd(csd_profile, csd_seed) 89 | ele_pos, pots = KK.electrode_config(csd_profile, csd_seed, total_ele, 90 | ele_lims, KK.h, KK.sigma, 91 | noise, nr_broken_ele) 92 | k, est_csd = KK.do_kcsd(pots, ele_pos, method=method, Rs=Rs, 93 | lambdas=lambdas) 94 | err = point_errors(true_csd, est_csd) 95 | return (k.k_pot, k.k_interp_cross, k.lambd, csd_at, true_csd, ele_pos, 96 | pots, est_csd, err) 97 | 98 | 99 | def point_errors(true_csd, est_csd): 100 | true_csd_r = true_csd.reshape(true_csd.size, 1) 101 | est_csd_r = est_csd.reshape(est_csd.size, 1) 102 | epsilon = np.linalg.norm(true_csd_r)/np.max(abs(true_csd_r)) 103 | err_r = abs(est_csd_r/(np.linalg.norm(est_csd_r)) - 104 | true_csd_r/(np.linalg.norm(true_csd_r))) 105 | err_r *= epsilon 106 | err = err_r.reshape(true_csd.shape) 107 | return err 108 | 109 | 110 | if __name__ == '__main__': 111 | CSD_PROFILE = CSD.gauss_2d_small 112 | CSD_SEED = 16 113 | ELE_LIMS = [0.118, 0.882] # range of electrodes space 114 | method = 'cross-validation' 115 | Rs = np.linspace(0.01, 0.15, 15) 116 | lambdas = None 117 | noise = 0 118 | n = 100 119 | 120 | KK = ValidateKCSD2D(CSD_SEED, h=50., sigma=1., n_src_init=1000, 121 | est_xres=0.01, est_yres=0.01, ele_lims=ELE_LIMS) 122 | 123 | if PARALLEL_AVAILABLE: 124 | err = Parallel(n_jobs=NUM_CORES)(delayed 125 | (make_reconstruction) 126 | (KK, CSD_PROFILE, i, total_ele=9, 127 | noise=noise, Rs=Rs, 128 | lambdas=lambdas, method=method) 129 | for i in range(n)) 130 | k_pot_n = np.array([item[0] for item in err]) 131 | k_interp_cross_n = np.array([item[1] for item in err]) 132 | lambd_n = np.array([item[2] for item in err]) 133 | csd_at = np.array([item[3] for item in err])[0] 134 | true_csd_n = np.array([item[4] for item in err]) 135 | ele_pos = np.array([item[5] for item in err])[0] 136 | pots_n = np.array([item[6] for item in err]) 137 | est_csd_n = np.array([item[7] for item in err]) 138 | error_n = np.array([item[8] for item in err]) 139 | else: 140 | k_n = [] 141 | true_csd_n = [] 142 | pots_n = [] 143 | est_csd_n = [] 144 | error_n = [] 145 | for i in range(n): 146 | print(i) 147 | (k_pot, k_interp_cross, lambd, csd_at, true_csd, ele_pos, pots, 148 | est_csd, err) = make_reconstruction(KK, CSD_PROFILE, i, 149 | total_ele=9, 150 | noise=noise, 151 | Rs=Rs, 152 | lambdas=lambdas, 153 | method=method) 154 | k_pot_n.append(k_pot) 155 | k_interp_cross_n.append(k_interp_cross) 156 | lambd_n.append(lambd) 157 | true_csd_n.append(true_csd) 158 | pots_n.append(pots) 159 | est_csd_n.append(est_csd) 160 | error_n.append(err) 161 | data = {} 162 | data['k_pot_n'] = k_pot_n 163 | data['k_interp_cross_n'] = k_interp_cross_n 164 | data['lambd_n'] = lambd_n 165 | data['csd_at'] = csd_at 166 | data['true_csd_n'] = true_csd_n 167 | data['ele_pos'] = ele_pos 168 | data['pots'] = pots_n 169 | data['est_csd'] = est_csd_n 170 | data['error'] = error_n 171 | np.savez('data_small_100.npz', data=data) 172 | -------------------------------------------------------------------------------- /figures/kCSD_properties/sources_electrodes.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neuroinflab/kCSD-python/21418c5e0c81829673ab60b7c42c064c8bd52433/figures/kCSD_properties/sources_electrodes.odg -------------------------------------------------------------------------------- /figures/kCSD_properties/tutorial3.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import os 3 | from kcsd import csd_profile as CSD 4 | from kcsd import KCSD2D 5 | from scipy.integrate import simps 6 | from scipy.interpolate import griddata 7 | from figure_properties import * 8 | import matplotlib.pyplot as plt 9 | import matplotlib.cm as cm 10 | 11 | 12 | def integrate_2d(csd_at, true_csd, ele_pos, h, csd_lims): 13 | csd_x, csd_y = csd_at 14 | xlin = csd_lims[0] 15 | ylin = csd_lims[1] 16 | Ny = ylin.shape[0] 17 | m = np.sqrt((ele_pos[0] - csd_x)**2 + (ele_pos[1] - csd_y)**2) 18 | m[m < 0.0000001] = 0.0000001 19 | y = np.arcsinh(2 * h / m) * true_csd 20 | integral_1D = np.zeros(Ny) 21 | for i in range(Ny): 22 | integral_1D[i] = simps(y[:, i], ylin) 23 | integral = simps(integral_1D, xlin) 24 | return integral 25 | 26 | def grid(x, y, z): 27 | x = x.flatten() 28 | y = y.flatten() 29 | z = z.flatten() 30 | xi, yi = np.mgrid[min(x):max(x):complex(0, 100), 31 | min(y):max(y):complex(0, 100)] 32 | zi = griddata((x, y), z, (xi, yi), method='linear') 33 | return xi, yi, zi 34 | 35 | 36 | def do_kcsd(CSD_PROFILE, csd_seed, prefix, missing_ele): 37 | # True CSD_PROFILE 38 | csd_at = np.mgrid[0.:1.:100j, 39 | 0.:1.:100j] 40 | csd_x, csd_y = csd_at 41 | true_csd = CSD_PROFILE(csd_at, seed=csd_seed) 42 | 43 | # Electrode positions 44 | ele_x, ele_y = np.mgrid[0.05: 0.95: 10j, 45 | 0.05: 0.95: 10j] 46 | ele_pos = np.vstack((ele_x.flatten(), ele_y.flatten())).T 47 | 48 | #Remove some electrodes 49 | remove_num = missing_ele 50 | rstate = np.random.RandomState(42) # just a random seed 51 | rmv = rstate.choice(ele_pos.shape[0], remove_num, replace=False) 52 | ele_pos = np.delete(ele_pos, rmv, 0) 53 | 54 | # Potentials generated 55 | pots = np.zeros(ele_pos.shape[0]) 56 | xlin = csd_at[0, :, 0] 57 | ylin = csd_at[1, 0, :] 58 | h = 50. 59 | sigma = 0.3 60 | for ii in range(ele_pos.shape[0]): 61 | pots[ii] = integrate_2d(csd_at, true_csd, 62 | [ele_pos[ii][0], ele_pos[ii][1]], h, 63 | [xlin, ylin]) 64 | pots /= 2 * np.pi * sigma 65 | pot_X, pot_Y, pot_Z = grid(ele_pos[:, 0], ele_pos[:, 1], pots) 66 | pots = pots.reshape((len(ele_pos), 1)) 67 | 68 | # KCSD2D 69 | k = KCSD2D(ele_pos, pots, h=h, sigma=sigma, 70 | xmin=0.0, xmax=1.0, 71 | ymin=0.0, ymax=1.0, 72 | gdx=0.01, gdy=0.01, 73 | R_init=0.1, n_src_init=1000, 74 | src_type='gauss') # rest of the parameters are set at default 75 | est_csd_pre_cv = k.values('CSD') 76 | R_range = np.linspace(0.1, 1.0, 10) 77 | #R_range = np.linspace(0.03, 0.12, 10) 78 | #R_range = np.linspace(0.1, 1.0, 10) 79 | k.cross_validate(Rs=R_range) 80 | #k.cross_validate() 81 | #k.cross_validate(lambdas=None, Rs=np.array(0.08).reshape(1)) 82 | est_csd_post_cv = k.values('CSD') 83 | 84 | fig = plt.figure(figsize=(20, 5)) 85 | ax = plt.subplot(141) 86 | ax.set_aspect('equal') 87 | t_max = np.max(np.abs(true_csd)) 88 | levels = np.linspace(-1 * t_max, t_max, 16) 89 | im = ax.contourf(csd_x, csd_y, true_csd, 90 | levels=levels, cmap=cm.bwr) 91 | ax.set_xlabel('X [mm]') 92 | ax.set_ylabel('Y [mm]') 93 | ax.set_title('True CSD') 94 | ax.set_xticks([0, 0.5, 1]) 95 | ax.set_yticks([0, 0.5, 1]) 96 | ticks = np.linspace(-1 * t_max, t_max, 5, endpoint=True) 97 | plt.colorbar(im, orientation='horizontal', format='%.2f', ticks=ticks, pad=0.25) 98 | 99 | ax = plt.subplot(142) 100 | ax.set_aspect('equal') 101 | v_max = np.max(np.abs(pots)) 102 | levels_pot = np.linspace(-1 * v_max, v_max, 16) 103 | im = ax.contourf(pot_X, pot_Y, pot_Z, 104 | levels=levels_pot, cmap=cm.PRGn) 105 | ax.scatter(ele_pos[:, 0], ele_pos[:, 1], 10, c='k') 106 | ax.set_xlim([0, 1]) 107 | ax.set_ylim([0, 1]) 108 | ax.set_xticks([0, 0.5, 1]) 109 | ax.set_yticks([0, 0.5, 1]) 110 | ax.set_xlabel('X [mm]') 111 | ax.set_title('Interpolated potentials') 112 | ticks = np.linspace(-1 * v_max, v_max, 5, endpoint=True) 113 | plt.colorbar(im, orientation='horizontal', format='%.2f', ticks=ticks, pad=0.25) 114 | 115 | ax = plt.subplot(143) 116 | ax.set_aspect('equal') 117 | t_max = np.max(np.abs(est_csd_pre_cv[:, :, 0])) 118 | levels_kcsd = np.linspace(-1 * t_max, t_max, 16, endpoint=True) 119 | im = ax.contourf(k.estm_x, k.estm_y, est_csd_pre_cv[:, :, 0], 120 | levels=levels_kcsd, cmap=cm.bwr) 121 | ax.set_xlim([0, 1]) 122 | ax.set_ylim([0, 1]) 123 | ax.set_xticks([0, 0.5, 1]) 124 | ax.set_yticks([0, 0.5, 1]) 125 | ax.set_xlabel('X [mm]') 126 | ax.set_title('Estimated CSD without CV') 127 | ticks = np.linspace(-1 * t_max, t_max, 5, endpoint=True) 128 | plt.colorbar(im, orientation='horizontal', format='%.2f', ticks=ticks, pad=0.25) 129 | 130 | ax = plt.subplot(144) 131 | ax.set_aspect('equal') 132 | t_max = np.max(np.abs(est_csd_post_cv[:, :, 0])) 133 | levels_kcsd = np.linspace(-1 * t_max, t_max, 16, endpoint=True) 134 | im = ax.contourf(k.estm_x, k.estm_y, est_csd_post_cv[:, :, 0], 135 | levels=levels_kcsd, cmap=cm.bwr) 136 | ax.set_xlim([0, 1]) 137 | ax.set_ylim([0, 1]) 138 | ax.set_xticks([0, 0.5, 1]) 139 | ax.set_yticks([0, 0.5, 1]) 140 | ax.set_xlabel('X [mm]') 141 | ax.set_title('Estimated CSD with CV') 142 | ticks = np.linspace(-1 * t_max, t_max, 5, endpoint=True) 143 | plt.colorbar(im, orientation='horizontal', format='%.2f', ticks=ticks, pad=0.25) 144 | plt.savefig(os.path.join(prefix, str(csd_seed)+'.pdf')) 145 | plt.close() 146 | #plt.show() 147 | np.savez(os.path.join(prefix, str(csd_seed)+'.npz'), 148 | true_csd=true_csd, pots=pots, post_cv=est_csd_post_cv, R=k.R) 149 | 150 | if __name__ == '__main__': 151 | CSD_PROFILE = CSD.gauss_2d_large 152 | prefix = '/home/chaitanya/kCSD-python/figures/kCSD_properties/large_srcs_all_ele' 153 | for csd_seed in range(100): 154 | do_kcsd(CSD_PROFILE, csd_seed, prefix, missing_ele=0) 155 | print("Done ", csd_seed) 156 | CSD_PROFILE = CSD.gauss_2d_small 157 | prefix = '/home/chaitanya/kCSD-python/figures/kCSD_properties/small_srcs_all_ele' 158 | for csd_seed in range(100): 159 | do_kcsd(CSD_PROFILE, csd_seed, prefix, missing_ele=0) 160 | print("Done ", csd_seed) 161 | -------------------------------------------------------------------------------- /figures/npx/DemoReadSGLXData/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neuroinflab/kCSD-python/21418c5e0c81829673ab60b7c42c064c8bd52433/figures/npx/DemoReadSGLXData/__init__.py -------------------------------------------------------------------------------- /figures/npx/NP_do_map.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neuroinflab/kCSD-python/21418c5e0c81829673ab60b7c42c064c8bd52433/figures/npx/NP_do_map.xlsx -------------------------------------------------------------------------------- /figures/npx/figure_properties.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | def set_axis(ax, x, y, letter=None): 4 | ax.text( 5 | x, 6 | y, 7 | letter, 8 | fontsize=25, 9 | weight='bold', 10 | transform=ax.transAxes) 11 | return ax 12 | 13 | plt.rcParams.update({ 14 | 'xtick.labelsize': 15, 15 | 'xtick.major.size': 10, 16 | 'ytick.labelsize': 15, 17 | 'ytick.major.size': 10, 18 | 'font.size': 12, 19 | 'axes.labelsize': 15, 20 | 'axes.titlesize': 20, 21 | 'axes.titlepad' : 30, 22 | 'legend.fontsize': 15, 23 | # 'figure.subplot.wspace': 0.4, 24 | # 'figure.subplot.hspace': 0.4, 25 | # 'figure.subplot.left': 0.1, 26 | }) 27 | 28 | 29 | -------------------------------------------------------------------------------- /figures/npx/figure_traub_eigensources.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | @author: mbejtka 5 | """ 6 | 7 | import numpy as np 8 | import h5py as h5 9 | import matplotlib.pyplot as plt 10 | import os 11 | from kcsd import KCSD2D 12 | from numpy.linalg import LinAlgError 13 | from traub_data_kcsd_column_figure import (prepare_electrodes, prepare_pots, 14 | set_axis) 15 | 16 | 17 | def do_kcsd_evd(pot, ele_pos, xmin, xmax, ymin, ymax, n_src_init=1000, 18 | R_init=30): 19 | k = KCSD2D(ele_pos, pot, 20 | xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, h=1, sigma=1, 21 | n_src_init=n_src_init, gdx=4, gdy=4, R_init=R_init) 22 | try: 23 | eigenvalue, eigenvector = np.linalg.eigh(k.k_pot + 24 | k.lambd * 25 | np.identity(k.k_pot.shape[0])) 26 | except LinAlgError: 27 | raise LinAlgError('EVD is failing - try moving the electrodes' 28 | 'slightly') 29 | idx = eigenvalue.argsort()[::-1] 30 | eigenvalues = eigenvalue[idx] 31 | eigenvectors = eigenvector[:, idx] 32 | return k, eigenvalues, eigenvectors 33 | 34 | 35 | def plot_eigensources(k, v): 36 | letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] 37 | index_list = [0, 1, 2, 3, 4, 5, 33, 35] 38 | fig = plt.figure(figsize=(15, 16)) 39 | for idx, i in enumerate(index_list): 40 | ax = plt.subplot(241 + idx, aspect='equal') 41 | a = v[:, i].reshape(k.estm_x.shape) 42 | max_a = np.max(np.abs(a)) 43 | levels = np.linspace(-max_a, max_a, 200) 44 | ax.contourf(k.estm_x, k.estm_y, a[:, :], levels=levels, cmap=plt.cm.bwr) 45 | ax.set_xlabel('X ($\mu$m)') 46 | ax.set_ylabel('Y ($\mu$m)') 47 | ax.set_title(r"$\tilde{K} \cdot{v_{{%(i)d}}}$" % {'i': i+1}, fontsize=20) 48 | set_axis(ax, letter=letters[idx]) 49 | fig.savefig(os.path.join('Eigensources.png'), dpi=300) 50 | 51 | 52 | if __name__ == '__main__': 53 | time_pt_interest = 3000 54 | time_pts = 6000 # number of all time frames 55 | num_cmpts = [74, 74, 59, 59, 59, 59, 61, 61, 50, 59, 59, 59] 56 | cell_range = [0, 1000, 1050, 1140, 1230, 1320, 57 | 1560, 2360, 2560, 3060, 3160, 3260, 3360] 58 | num_cells = np.diff(cell_range) / 10 # 10% MODEL 59 | total_cmpts = list(num_cmpts * num_cells) 60 | pop_names = ['pyrRS23', 'pyrFRB23', 'bask23', 'axax23', 'LTS23', 61 | 'spinstel4', 'tuftIB5', 'tuftRS5', 'nontuftRS6', 62 | 'bask56', 'axax56', 'LTS56'] 63 | 64 | h = h5.File('pulsestimulus10model.h5', 'r') 65 | elec_pos_list, names_list = prepare_electrodes() 66 | pot_np = prepare_pots(elec_pos_list[1], names_list[1], h, pop_names, time_pts) 67 | k, eigenvalues, eigenvectors = do_kcsd_evd(pot_np, elec_pos_list[1][:, :2], 68 | -400, 400, -2000, 500, 69 | R_init=30, n_src_init=5000) 70 | v = np.dot(k.k_interp_cross, eigenvectors) 71 | plot_eigensources(k, v) 72 | -------------------------------------------------------------------------------- /figures/npx/figure_traub_timespace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | @author: mbejtka 5 | """ 6 | import numpy as np 7 | import h5py as h5 8 | import matplotlib.pyplot as plt 9 | import os 10 | from traub_data_kcsd_column_figure import (prepare_electrodes, prepare_pots, 11 | do_kcsd, set_axis) 12 | import kCSD2D_reconstruction_from_npx as npx 13 | from scipy.signal import filtfilt, butter 14 | 15 | 16 | def make_plot_spacetime(ax, val, cut=9, title='True CSD', 17 | cmap=plt.cm.bwr, letter='A', ylabel=True): 18 | yy = np.linspace(-3500, 500, val.shape[1]) 19 | xx = np.linspace(-50, 250, val[cut, :, :].shape[1]) 20 | max_val = np.max(np.abs(val[cut, :, :])) 21 | levels = np.linspace(-max_val, max_val, 200) 22 | im = ax.contourf(xx, yy, val[cut, :, :], levels=levels, cmap=cmap) 23 | if 'CSD' in title: 24 | name = ['', 'II/III', 'IV', 'V', 'VI'] 25 | layer_level = [0, -400, -700, -1200, -1700] 26 | for i, value in enumerate(layer_level): 27 | plt.axhline(y=value, xmin=xx.min(), xmax=xx.max(), linewidth=1, 28 | color='k', ls='--') 29 | plt.text(110, value+165, name[i], fontsize=10, va='top', ha='center') 30 | ax.set_xlabel('Time (ms)') 31 | if ylabel: 32 | ax.set_ylabel('Y ($\mu$m)') 33 | ax.set_title(title, fontsize=20, pad=30) 34 | ax.set_xlim(-50, 100) 35 | ticks = np.linspace(-max_val, max_val, 3, endpoint=True) 36 | plt.colorbar(im, orientation='horizontal', format='%.3f', ticks=ticks) 37 | set_axis(ax, letter=letter) 38 | #plt.tight_layout() 39 | 40 | 41 | def make_plot_1D_pics(ax, k, est_val, tp, Fs, cut=9, title='Experimental data', 42 | cmap=plt.cm.bwr, letter='A', ylabel=True): 43 | 44 | set_axis(ax, letter=letter) 45 | npx.make_plot_spacetime(ax, k.estm_x, k.estm_y, est_val[cut,:,:], Fs, 46 | title=title, cmap=cmap, ylabel=ylabel) 47 | if letter == 'D': 48 | for lvl, name in zip([-500,-850,-2000], ['II/III', 'IV', 'V/VI']): 49 | plt.axhline(lvl, ls='--', color='grey') 50 | plt.text(340, lvl+20, name) 51 | elif letter == 'C': 52 | plt.axvline(tp/Fs*1000, ls='--', color ='grey', lw=2) 53 | 54 | plt.xlim(250, 400) 55 | plt.xticks([250, 300, 350, 400], [-50, 0, 50, 100]) 56 | 57 | #plt.tight_layout() 58 | plt.savefig('figure_1D_pics', dpi=300) 59 | 60 | 61 | def make_figure_spacetime(val_pots_m, val_csd_m, kcsd_obj, val_pots_e, val_csd_e, tp, Fs, cut1=13, cut2=15, 62 | titl1='POT', titl2='CSD', fig_title='Pot and CSD in time'): 63 | fig = plt.figure(figsize=(16, 8)) 64 | ax2 = plt.subplot(141) 65 | make_plot_spacetime(ax2, val_pots_m, cut=cut1, 66 | title=titl1, cmap=plt.cm.PRGn, letter='A') 67 | ax1 = plt.subplot(142) 68 | make_plot_spacetime(ax1, val_csd_m, cut=cut1, 69 | title=titl2, cmap=plt.cm.bwr, letter='B', ylabel=False) 70 | ax3 = plt.subplot(143) 71 | make_plot_1D_pics(ax3, kcsd_obj, val_pots_e, tp, Fs, cut=cut2, title=titl1, cmap=plt.cm.PRGn, letter='C', ylabel=False) 72 | ax4 = plt.subplot(144) 73 | make_plot_1D_pics(ax4, kcsd_obj, val_csd_e, tp, Fs, cut=cut2, title=titl2, cmap=plt.cm.bwr, letter='D', ylabel=False) 74 | plt.tight_layout() 75 | fig.savefig(os.path.join(fig_title + '.png'), dpi=300) 76 | 77 | 78 | if __name__ == '__main__': 79 | time_pt_interest = 3000 80 | time_pts = 6000 # number of all time frames 81 | num_cmpts = [74, 74, 59, 59, 59, 59, 61, 61, 50, 59, 59, 59] 82 | cell_range = [0, 1000, 1050, 1140, 1230, 1320, 83 | 1560, 2360, 2560, 3060, 3160, 3260, 3360] 84 | num_cells = np.diff(cell_range) / 10 # 10% MODEL 85 | total_cmpts = list(num_cmpts * num_cells) 86 | pop_names = ['pyrRS23', 'pyrFRB23', 'bask23', 'axax23', 'LTS23', 87 | 'spinstel4', 'tuftIB5', 'tuftRS5', 'nontuftRS6', 88 | 'bask56', 'axax56', 'LTS56'] 89 | 90 | h = h5.File('pulsestimulus10model.h5', 'r') 91 | elec_pos_list, names_list = prepare_electrodes() 92 | 93 | pot_np = prepare_pots(elec_pos_list[1], names_list[1], h, pop_names, time_pts) 94 | kcsd_m, est_pot_m, x_m, y_m, k_m = do_kcsd(pot_np, elec_pos_list[1][:, :2], -40, 40, -3500, 500) 95 | 96 | lowpass = 0.5 97 | highpass = 300 98 | Fs = 30000 99 | resamp = 12 100 | tp= 760 101 | 102 | forfilt=np.load('npx_data.npy') 103 | 104 | [b,a] = butter(3, [lowpass/(Fs/2.0), highpass/(Fs/2.0)] ,btype = 'bandpass') 105 | filtData = filtfilt(b,a, forfilt) 106 | pots_resamp = filtData[:,::resamp] 107 | pots = pots_resamp[:, :] 108 | Fs=int(Fs/resamp) 109 | 110 | pots_for_csd = np.delete(pots, 191, axis=0) 111 | ele_pos_def = npx.eles_to_coords(np.arange(384,0,-1)) 112 | ele_pos_for_csd = np.delete(ele_pos_def, 191, axis=0) 113 | 114 | k_e, est_csd_e, est_pots_e, ele_pos_e = npx.do_kcsd(ele_pos_for_csd, pots_for_csd, ele_limit = (0,320)) 115 | 116 | time_pts_ds = int(time_pts/4) 117 | cut1 = 9 118 | start_pt = 625 # 50 ms before the stimulus 119 | end_pt = 1375 # 250 ms after the stimulus 120 | # for cut in range(kcsd.shape[0]): 121 | make_figure_spacetime(est_pot_m[:, :, start_pt:end_pt], 122 | kcsd_m[:, :, start_pt:end_pt], k_e, est_pots_e, est_csd_e, tp, Fs, cut1=cut1, cut2=15, 123 | titl1='Estimated LFP', titl2='Estimated CSD', 124 | fig_title=('Estimated POT and CSD in time 1stim ')) 125 | #plot_1D_pics(k, est_csd, est_pots, tp, 15) 126 | -------------------------------------------------------------------------------- /figures/npx/kCSD2D_reconstruction_from_npx.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from kcsd import KCSD2D 3 | import matplotlib.pyplot as plt 4 | import matplotlib.cm as cm 5 | from scipy.signal import filtfilt, butter 6 | from figure_properties import * 7 | plt.close('all') 8 | #%% 9 | def make_plot_spacetime(ax, xx, yy, zz, Fs, title='True CSD', cmap=cm.bwr_r, ymin=0, ymax=10000, ylabel=True): 10 | im = ax.imshow(zz,extent=[0, zz.shape[1]/Fs*1000,-3500, 500], aspect='auto', 11 | vmax = 1*zz.max(),vmin = -1*zz.max(), cmap=cmap) 12 | ax.set_xlabel('Time (ms)') 13 | if ylabel: 14 | ax.set_ylabel('Y ($\mu$m)') 15 | if 'Pot' in title: ax.set_ylabel('Y ($\mu$m)') 16 | ax.set_title(title) 17 | ticks = np.linspace(-zz.max(), zz.max(), 3, endpoint=True) 18 | if 'CSD' in title: 19 | plt.colorbar(im, orientation='horizontal', format='%.2f', ticks = ticks) 20 | else: 21 | plt.colorbar(im, orientation='horizontal', format='%.1f', ticks = ticks) 22 | # plt.gca().invert_yaxis() 23 | 24 | def make_plot(ax, xx, yy, zz, title='True CSD', cmap=cm.bwr): 25 | ax.set_aspect('auto') 26 | levels = np.linspace(zz.min(), -zz.min(), 61) 27 | im = ax.contourf(xx, -(yy-500), zz, levels=levels, cmap=cmap) 28 | ax.set_xlabel('X ($\mu$m)') 29 | ax.set_ylabel('Y ($\mu$m)') 30 | ax.set_title(title) 31 | if 'CSD' in title: 32 | plt.colorbar(im, orientation='vertical', format='%.2f', ticks=[-0.02,0,0.02]) 33 | else: plt.colorbar(im, orientation='vertical', format='%.1f', ticks=[-0.6,0,0.6]) 34 | plt.scatter(ele_pos[:, 0], 35 | -(ele_pos[:, 1]-500), 36 | s=0.8, color='black') 37 | # plt.gca().invert_yaxis() 38 | return ax 39 | 40 | def eles_to_ycoord(eles): 41 | y_coords = [] 42 | for ii in range(192): 43 | y_coords.append(ii*20) 44 | y_coords.append(ii*20) 45 | return y_coords[::-1] 46 | 47 | def eles_to_xcoord(eles): 48 | x_coords = [] 49 | for ele in eles: 50 | off = ele%4 51 | if off == 1: x_coords.append(-24) 52 | elif off == 2: x_coords.append(8) 53 | elif off == 3: x_coords.append(-8) 54 | elif off==0: x_coords.append(24) 55 | return x_coords 56 | 57 | def eles_to_coords(eles): 58 | xs = eles_to_xcoord(eles) 59 | ys = eles_to_ycoord(eles) 60 | return np.array((xs, ys)).T 61 | 62 | def plot_1D_pics(k, est_csd, est_pots, tp, Fs, cut=9): 63 | plt.figure(figsize=(12, 8)) 64 | # plt.suptitle('plane: '+str(k.estm_x[cut,0])+' $\mu$m '+' $\lambda$ : '+str(k.lambd)+ 65 | # ' R: '+ str(k.R)) 66 | ax1 = plt.subplot(122) 67 | set_axis(ax1, -0.05, 1.05, letter= 'D') 68 | make_plot_spacetime(ax1, k.estm_x, k.estm_y, est_csd[cut,:,:], Fs, 69 | title='Estimated CSD', cmap='bwr') 70 | for lvl, name in zip([-500,-850,-2000], ['II/III', 'IV', 'V/VI']): 71 | plt.axhline(lvl, ls='--', color='grey') 72 | plt.text(340, lvl+20, name) 73 | plt.xlim(250, 400) 74 | plt.xticks([250, 300, 350, 400], [-50, 0, 50, 100]) 75 | ax2 = plt.subplot(121) 76 | set_axis(ax2, -0.05, 1.05, letter= 'C') 77 | make_plot_spacetime(ax2, k.estm_x, k.estm_y, est_pots[cut,:,:], 78 | title='Estimated LFP', cmap='PRGn') 79 | plt.axvline(tp/Fs*1000, ls='--', color ='grey', lw=2) 80 | plt.xlim(250, 400) 81 | plt.xticks([250, 300, 350, 400], [-50, 0, 50, 100]) 82 | plt.tight_layout() 83 | plt.savefig('figure_1D_pics', dpi=300) 84 | 85 | def plot_2D_pics(k, est_csd, est_pots, tp, Fs, cut, save=0): 86 | plt.figure(figsize=(12, 8)) 87 | ax1 = plt.subplot(122) 88 | set_axis(ax1, -0.05, 1.05, letter= 'B') 89 | make_plot(ax1, k.estm_x, k.estm_y, est_csd[:,:,tp], 90 | title='Estimated CSD', cmap='bwr') 91 | # for i in range(383): plt.text(ele_pos_for_csd[i,0], ele_pos_for_csd[i,1]+8, str(i+1)) 92 | plt.axvline(k.estm_x[cut][0], ls='--', color ='grey', lw=2) 93 | ax2 = plt.subplot(121) 94 | set_axis(ax2, -0.05, 1.05, letter= 'A') 95 | make_plot(ax2, k.estm_x, k.estm_y, est_pots[:,:,tp], 96 | title='Estimated LFP', cmap='PRGn') 97 | # plt.suptitle(' $\lambda$ : '+str(k.lambd)+ ' R: '+ str(k.R)) 98 | plt.tight_layout() 99 | plt.savefig('figure_2D_pics', dpi=300) 100 | 101 | def do_kcsd(ele_pos_for_csd, pots_for_csd, ele_limit): 102 | ele_position = ele_pos_for_csd[:ele_limit[1]][0::1] 103 | csd_pots = pots_for_csd[:ele_limit[1]][0::1] 104 | k = KCSD2D(ele_position, csd_pots, 105 | h=1, sigma=1, R_init=32, lambd=1e-9, 106 | xmin= -42, xmax=42, gdx=4, 107 | ymin=0, ymax=4000, gdy=4) 108 | # k.L_curve(Rs=np.linspace(16, 48, 3), lambdas=np.logspace(-9, -3, 20)) 109 | return k, k.values('CSD'), k.values('POT'), ele_position 110 | #%% 111 | if __name__ == '__main__': 112 | lowpass = 0.5 113 | highpass = 300 114 | Fs = 30000 115 | resamp = 12 116 | tp= 760 117 | 118 | forfilt=np.load('npx_data.npy') 119 | 120 | [b,a] = butter(3, [lowpass/(Fs/2.0), highpass/(Fs/2.0)] ,btype = 'bandpass') 121 | filtData = filtfilt(b,a, forfilt) 122 | pots_resamp = filtData[:,::resamp] 123 | pots = pots_resamp[:, :] 124 | Fs=int(Fs/resamp) 125 | 126 | pots_for_csd = np.delete(pots, 191, axis=0) 127 | ele_pos_def = eles_to_coords(np.arange(384,0,-1)) 128 | ele_pos_for_csd = np.delete(ele_pos_def, 191, axis=0) 129 | 130 | k, est_csd, est_pots, ele_pos = do_kcsd(ele_pos_for_csd, pots_for_csd, ele_limit = (0,320)) 131 | 132 | plot_1D_pics(k, est_csd, est_pots, tp, Fs, 15) 133 | plot_2D_pics(k, est_csd, est_pots, tp, Fs, cut=15) 134 | -------------------------------------------------------------------------------- /figures/npx/map_npx_ele.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from kcsd import KCSD2D 3 | from pathlib import Path 4 | from openpyxl import load_workbook 5 | from DemoReadSGLXData.readSGLX import readMeta, SampRate, makeMemMapRaw, GainCorrectIM, GainCorrectNI, ExtractDigital 6 | import matplotlib.pyplot as plt 7 | from matplotlib import gridspec 8 | 9 | 10 | def eles_to_rows(eles): 11 | rows = [] 12 | for ele in eles: 13 | rows.append(int(np.ceil(ele/2))) 14 | return rows 15 | 16 | def eles_to_ycoord(eles): 17 | rows = eles_to_rows(eles) 18 | y_coords = [] 19 | for ii in rows: 20 | y_coords.append(int((480 - ii)*20)) 21 | return y_coords 22 | 23 | def eles_to_xcoord(eles): 24 | x_coords = [] 25 | for ele in eles: 26 | off = ele%4 27 | if off == 1: 28 | x_coords.append(-24) 29 | elif off == 2: 30 | x_coords.append(8) 31 | elif off == 3: 32 | x_coords.append(-8) 33 | else: 34 | x_coords.append(24) 35 | return x_coords 36 | 37 | def eles_to_coords(eles): 38 | xs = eles_to_xcoord(eles) 39 | ys = eles_to_ycoord(eles) 40 | return np.array((xs, ys)).T 41 | 42 | 43 | # Specific to Ewas experimental setup 44 | def load_chann_map(): 45 | book = load_workbook('NP_do_map.xlsx') 46 | sheet = book.get_sheet_by_name('sov12 sorted') 47 | eleid = sheet['C3':'C386'] 48 | chanid = sheet['J3':'J386'] 49 | chan_ele_dict = {} 50 | ele_chan_dict = {} 51 | for e,c in zip(eleid, chanid): 52 | chan_ele_dict[int(c[0].value)] = int(e[0].value) 53 | ele_chan_dict[int(e[0].value)] = int(c[0].value) 54 | return ele_chan_dict, chan_ele_dict 55 | 56 | 57 | ele_chan_dict, chan_ele_dict = load_chann_map() 58 | 59 | def fetch_channels(eles): 60 | chans = [] 61 | exist_ele = [] 62 | for ii in eles: 63 | try: 64 | chans.append(ele_chan_dict[ii]) 65 | exist_ele.append(ii) 66 | except KeyError: 67 | print('Not recording from ele', ii) 68 | return chans, exist_ele 69 | 70 | # print(ele_dict) 71 | 72 | 73 | # File with the data 74 | # old 75 | # binFullPath = Path('./data/08_refGND_APx500_LFPx125_ApfiltON_corr_banks_stim50V_g0_t0.imec0.lf.bin') 76 | # Daniel 77 | binFullPath = Path('/mnt/zasoby/data/neuropixel/Neuropixel data from Ewa Kublik/SOV_12/data/08_refGND_APx500_LFPx125_ApfiltON_corr_banks_stim50V_g0_t0.imec0.lf.bin') 78 | # Chaitanya 79 | # binFullPath = Path('/home/chaitanya/LFP/SOV_12/data/08_refGND_APx500_LFPx125_ApfiltON_corr_banks_stim50V_g0_t0.imec0.lf.bin') 80 | 81 | tStart = 0 # in seconds 82 | tEnd = 1 83 | # chanList = [0, 6, 9, 383] 84 | # eleList = np.arange(769, 860) 85 | eleList = np.arange(0, 959) 86 | 87 | chanList, eleList = fetch_channels(eleList) 88 | 89 | 90 | 91 | # Which digital word to read. 92 | # For imec, there is only 1 digital word, dw = 0. 93 | # For NI, digital lines 0-15 are in word 0, lines 16-31 are in word 1, etc. 94 | dw = 0 95 | # Which lines within the digital word, zero-based 96 | # Note that the SYNC line for PXI 3B is stored in line 6. 97 | dLineList = [6] 98 | 99 | meta = readMeta(binFullPath) 100 | sRate = SampRate(meta) 101 | firstSamp = int(sRate*tStart) 102 | lastSamp = int(sRate*tEnd) 103 | rawData = makeMemMapRaw(binFullPath, meta) 104 | selectData = rawData[chanList, firstSamp:lastSamp+1] 105 | digArray = ExtractDigital(rawData, firstSamp, lastSamp, dw, dLineList, meta) 106 | 107 | if meta['typeThis'] == 'imec': 108 | # apply gain correction and convert to uV 109 | convData = 1e6*GainCorrectIM(selectData, chanList, meta) 110 | else: 111 | # apply gain correction and convert to mV 112 | convData = 1e3*GainCorrectNI(selectData, chanList, meta) 113 | 114 | tDat = np.arange(firstSamp, lastSamp+1) 115 | tDat = 1000*tDat/sRate # plot time axis in msec 116 | 117 | 118 | 119 | ele_pos = eles_to_coords(eleList) 120 | print(ele_pos) 121 | csd_at_time = 0.04 122 | pots = [] 123 | for ii, chann in enumerate(chanList): 124 | pots.append(convData[ii, int(sRate*csd_at_time)]) 125 | 126 | pots = np.array(pots) 127 | # print(pots.shape) 128 | pots = pots.reshape((len(chanList), 1)) 129 | R_init = 0.3 130 | h = 50. 131 | sigma = 0.3 132 | k = KCSD2D(ele_pos, pots, h=h, sigma=sigma, 133 | xmin=-35, xmax=35, 134 | ymin=1100, ymax=2000, 135 | gdx=10, gdy=10, 136 | R_init=R_init, n_src_init=1000, 137 | src_type='gauss') # rest of the parameters are set at default 138 | k.cross_validate(Rs=np.linspace(0.1, 1.001, 20), lambdas=None) 139 | 140 | # # ax = plt.subplot(121) 141 | # # for ii, chan in enumerate(chanList): 142 | # # ax.plot(tDat, convData[ii, :], label=str(chan)+' Ele'+str(chan_dict[chan])) 143 | # # plt.legend() 144 | # # ax = plt.subplot(122) 145 | # # for i in range(0, len(dLineList)): 146 | # # ax.plot(tDat, digArray[i, :]) 147 | 148 | # rowList = eles_to_rows(eleList) 149 | # num_rows = max(rowList) - min(rowList) + 1 150 | # print(num_rows) 151 | # fig = plt.figure(figsize=(4, num_rows)) 152 | # gs = gridspec.GridSpec(nrows=num_rows, ncols=4, wspace=0, hspace=0) 153 | # all_maxy = -100 154 | # axs = [] 155 | # for ii, chann in enumerate(chanList): 156 | # ee = chan_ele_dict[chann] 157 | # rr = eles_to_rows([ee])[0] - min(rowList) # last row first 158 | # rr = num_rows - rr - 1 159 | # print(rr, ee, num_rows-rr) 160 | # off = ee%4 161 | # if off == 0: 162 | # ax = fig.add_subplot(gs[rr, 3]) 163 | # elif off == 1: 164 | # ax = fig.add_subplot(gs[rr, 0]) 165 | # elif off == 2: 166 | # ax = fig.add_subplot(gs[rr, 2]) 167 | # else: 168 | # ax = fig.add_subplot(gs[rr, 1]) 169 | # ax.plot(tDat, convData[ii, :]) 170 | # all_maxy = max(all_maxy, max(convData[ii, :])) 171 | # ax.spines['right'].set_visible(False) 172 | # ax.spines['top'].set_visible(False) 173 | # # ax.spines['left'].set_visible(False) 174 | # # ax.set_yticklabels([]) 175 | # # ax.set_yticks([]) 176 | # ax.set_title('E('+str(ee)+')') 177 | # axs.append(ax) 178 | # print(all_maxy) 179 | # plt.show() 180 | 181 | -------------------------------------------------------------------------------- /figures/npx/map_npx_ele_Daniel.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from pathlib import Path 3 | from openpyxl import load_workbook 4 | from DemoReadSGLXData.readSGLX import readMeta, SampRate, makeMemMapRaw, GainCorrectIM, GainCorrectNI, ExtractDigital 5 | import matplotlib.pyplot as plt 6 | from matplotlib import gridspec 7 | 8 | def eles_to_rows(eles): 9 | rows = [] 10 | for ele in eles: 11 | rows.append(int(np.ceil(ele/2))) 12 | return rows 13 | 14 | def eles_to_ycoord(eles): 15 | rows = eles_to_rows(eles) 16 | y_coords = [] 17 | for ii in rows: 18 | y_coords.append(int((480 - ii)*20)) 19 | return y_coords 20 | 21 | def eles_to_xcoord(eles): 22 | x_coords = [] 23 | for ele in eles: 24 | off = ele%4 25 | if off == 1: 26 | x_coords.append(-24) 27 | elif off == 2: 28 | x_coords.append(8) 29 | elif off == 3: 30 | x_coords.append(-8) 31 | else: 32 | x_coords.append(24) 33 | return x_coords 34 | 35 | def eles_to_coords(eles): 36 | xs = eles_to_xcoord(eles) 37 | ys = eles_to_ycoord(eles) 38 | return np.array((xs, ys)).T 39 | 40 | 41 | # Specific to Ewas experimental setup 42 | def load_chann_map(): 43 | book = load_workbook('NP_do_map.xlsx') 44 | sheet = book.get_sheet_by_name('sov12 sorted') 45 | eleid = sheet['C3':'C386'] 46 | chanid = sheet['J3':'J386'] 47 | chan_ele_dict = {} 48 | ele_chan_dict = {} 49 | for e,c in zip(eleid, chanid): 50 | chan_ele_dict[int(c[0].value)] = int(e[0].value) 51 | ele_chan_dict[int(e[0].value)] = int(c[0].value) 52 | return ele_chan_dict, chan_ele_dict 53 | 54 | 55 | ele_chan_dict, chan_ele_dict = load_chann_map() 56 | 57 | def fetch_channels(eles): 58 | chans = [] 59 | exist_ele = [] 60 | for ii in eles: 61 | try: 62 | chans.append(ele_chan_dict[ii]) 63 | exist_ele.append(ii) 64 | except KeyError: 65 | print('Not recording from ele', ii) 66 | return chans, exist_ele 67 | 68 | # print(ele_dict) 69 | 70 | 71 | # File with the data 72 | # binFullPath = Path('./data/08_refGND_APx500_LFPx125_ApfiltON_corr_banks_stim50V_g0_t0.imec0.lf.bin') 73 | binFullPath = Path('/mnt/zasoby/data/neuropixel/Neuropixel data from Ewa Kublik/SOV_12/data/08_refGND_APx500_LFPx125_ApfiltON_corr_banks_stim50V_g0_t0.imec0.lf.bin') 74 | 75 | tStart = 0 # in seconds 76 | tEnd = 1 77 | # chanList = [0, 6, 9, 383] 78 | # eleList = np.arange(769, 860) 79 | eleList = np.arange(0, 959) 80 | 81 | chanList, eleList = fetch_channels(eleList) 82 | 83 | 84 | # Which digital word to read. 85 | # For imec, there is only 1 digital word, dw = 0. 86 | # For NI, digital lines 0-15 are in word 0, lines 16-31 are in word 1, etc. 87 | dw = 0 88 | # Which lines within the digital word, zero-based 89 | # Note that the SYNC line for PXI 3B is stored in line 6. 90 | dLineList = [6] 91 | 92 | meta = readMeta(binFullPath) 93 | sRate = SampRate(meta) 94 | firstSamp = int(sRate*tStart) 95 | lastSamp = int(sRate*tEnd) 96 | rawData = makeMemMapRaw(binFullPath, meta) 97 | selectData = rawData[chanList, firstSamp:lastSamp+1] 98 | digArray = ExtractDigital(rawData, firstSamp, lastSamp, dw, dLineList, meta) 99 | 100 | if meta['typeThis'] == 'imec': 101 | # apply gain correction and convert to uV 102 | convData = 1e6*GainCorrectIM(selectData, chanList, meta) 103 | else: 104 | # apply gain correction and convert to mV 105 | convData = 1e3*GainCorrectNI(selectData, chanList, meta) 106 | 107 | tDat = np.arange(firstSamp, lastSamp+1) 108 | tDat = 1000*tDat/sRate # plot time axis in msec 109 | 110 | # ax = plt.subplot(121) 111 | # for ii, chan in enumerate(chanList): 112 | # ax.plot(tDat, convData[ii, :], label=str(chan)+' Ele'+str(chan_dict[chan])) 113 | # plt.legend() 114 | # ax = plt.subplot(122) 115 | # for i in range(0, len(dLineList)): 116 | # ax.plot(tDat, digArray[i, :]) 117 | 118 | rowList = eles_to_rows(eleList) 119 | num_rows = max(rowList) - min(rowList) + 1 120 | print(num_rows) 121 | fig = plt.figure(figsize=(4, num_rows)) 122 | gs = gridspec.GridSpec(nrows=num_rows, ncols=4, wspace=0, hspace=0) 123 | all_maxy = -100 124 | axs = [] 125 | for ii, chann in enumerate(chanList): 126 | ee = chan_ele_dict[chann] 127 | rr = eles_to_rows([ee])[0] - min(rowList) # last row first 128 | rr = num_rows - rr - 1 129 | print(rr, ee, num_rows-rr) 130 | off = ee%4 131 | if off == 0: 132 | ax = fig.add_subplot(gs[rr, 3]) 133 | elif off == 1: 134 | ax = fig.add_subplot(gs[rr, 0]) 135 | elif off == 2: 136 | ax = fig.add_subplot(gs[rr, 2]) 137 | else: 138 | ax = fig.add_subplot(gs[rr, 1]) 139 | ax.plot(tDat, convData[ii, :]) 140 | all_maxy = max(all_maxy, max(convData[ii, :])) 141 | ax.spines['right'].set_visible(False) 142 | ax.spines['top'].set_visible(False) 143 | # ax.spines['left'].set_visible(False) 144 | # ax.set_yticklabels([]) 145 | # ax.set_yticks([]) 146 | ax.set_title('E('+str(ee)+')') 147 | axs.append(ax) 148 | print(all_maxy) 149 | plt.show() 150 | 151 | -------------------------------------------------------------------------------- /figures/npx/npx_data.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neuroinflab/kCSD-python/21418c5e0c81829673ab60b7c42c064c8bd52433/figures/npx/npx_data.npy -------------------------------------------------------------------------------- /figures/sKCSD_paper/README: -------------------------------------------------------------------------------- 1 | All figures are generated using LFPy package. Since there is no LFPy 2 | for Python3, if you want to run scripts generating figures first you 3 | have to run them with Python2, so all the generated data is saved on 4 | your disk and then rerun the scripts using Python3. -------------------------------------------------------------------------------- /figures/sKCSD_paper/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neuroinflab/kCSD-python/21418c5e0c81829673ab60b7c42c064c8bd52433/figures/sKCSD_paper/__init__.py -------------------------------------------------------------------------------- /figures/sKCSD_paper/make_fig_2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | from distutils.spawn import find_executable, spawn 4 | import shutil 5 | import subprocess 6 | from kcsd import sample_data_path 7 | if find_executable('nrnivmodl') is not None: 8 | for path in ['x86_64', 'i686', 'powerpc']: 9 | if os.path.isdir(path): 10 | shutil.rmtree(path) 11 | spawn([find_executable('nrnivmodl')]) 12 | sinsyn_loc = os.path.join(sample_data_path, "sinsyn.mod") 13 | subprocess.call(["cp", sinsyn_loc, os.getcwd()]) 14 | subprocess.call(["nrnivmodl", "sinsyn.mod"]) 15 | else: 16 | print("""nrnivmodl script not found in PATH, thus NEURON .mod files could 17 | not be compiled, and LFPy.test() functions will fail""") 18 | import numpy as np 19 | import matplotlib.pyplot as plt 20 | from kcsd import sKCSD 21 | from kcsd import sKCSD_utils as utils 22 | import sKCSD_utils 23 | from kcsd.validation import plotting_functions as pl 24 | 25 | n_src = 512 26 | lambd = .1 27 | R = 8e-6/2**.5 28 | if __name__ == '__main__': 29 | fname_base = "Figure_2" 30 | fig_name = sKCSD_utils.make_fig_names(fname_base) 31 | tstop = 850 32 | scaling_factor = 1000**2 33 | scaling_factor_LFP = 1000 34 | electrode_number = [8, 16, 128] 35 | data_dir = [] 36 | xmin, xmax = -100, 600 37 | ymin, ymax = 0, 200 38 | orientation = 1 39 | 40 | for rownb in electrode_number: 41 | fname = '%s_rows_%d' % (fname_base, rownb) 42 | if sys.version_info < (3, 0): 43 | c = sKCSD_utils.simulate(fname, 44 | morphology=1, 45 | simulate_what="sine", 46 | colnb=1, 47 | rownb=rownb, 48 | xmin=xmin, 49 | xmax=xmax, 50 | ymin=ymin, 51 | ymax=ymax, 52 | tstop=tstop, 53 | seed=1988, 54 | weight=0.1, 55 | n_syn=100) 56 | data_dir.append(c.return_paths_skCSD_python()) 57 | else: 58 | new_dir = os.path.join('simulation', fname) 59 | data_dir.append(new_dir) 60 | 61 | seglen = np.loadtxt(os.path.join(data_dir[0], 'seglength')) 62 | ground_truth = np.loadtxt(os.path.join(data_dir[0], 'membcurr')) 63 | ground_truth = ground_truth/seglen[:, None]*1e-3 64 | gvmax, gvmin = pl.get_min_max(ground_truth) 65 | fname = fname_base + '.png' 66 | fig_name = sKCSD_utils.make_fig_names(fname) 67 | data_paths = [] 68 | fig, ax = plt.subplots(4, 1) 69 | xticklabels = list(np.linspace(0, 800, 5)) 70 | yticklabels = list(np.linspace(0, 52, 5)) 71 | pl.make_map_plot(ax[0], ground_truth, alpha=1., vmin=gvmin, vmax=gvmax) 72 | for i, datd in enumerate(data_dir): 73 | l = 0 74 | data = utils.LoadData(datd) 75 | ele_pos = data.ele_pos/scaling_factor 76 | data.LFP = data.LFP/scaling_factor_LFP 77 | morphology = data.morphology 78 | morphology[:, 2:6] = morphology[:, 2:6]/scaling_factor 79 | k = sKCSD(ele_pos, 80 | data.LFP, 81 | morphology, 82 | n_src_init=n_src, 83 | src_type='gauss', 84 | lambd=lambd, 85 | R_init=R, 86 | exact=True, 87 | sigma=0.3) 88 | est_csd = k.values(transformation='segments') 89 | if i == 2: 90 | pl.make_map_plot(ax[i+1], 91 | est_csd, 92 | xticklabels=xticklabels, 93 | yticklabels=yticklabels, 94 | xlabel='Time [ms]', 95 | ylabel='#segment', 96 | vmin=gvmin, 97 | vmax=gvmax, 98 | alpha=1.) 99 | else: 100 | pl.make_map_plot(ax[i+1], 101 | est_csd, 102 | vmin=gvmin, 103 | vmax=gvmax, 104 | alpha=1.) 105 | 106 | if sys.version_info < (3, 0): 107 | path = os.path.join(datd, "preprocessed_data/Python_2") 108 | else: 109 | path = os.path.join(datd, "preprocessed_data/Python_3") 110 | 111 | if not os.path.exists(path): 112 | print("Creating", path) 113 | os.makedirs(path) 114 | utils.save_sim(path, k) 115 | fig.savefig(fig_name, bbox_inches='tight', transparent=True, pad_inches=0.1) 116 | -------------------------------------------------------------------------------- /figures/sKCSD_paper/make_fig_3.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | import sys 4 | import os 5 | from kcsd import sKCSD 6 | from kcsd import sKCSD_utils as utils 7 | import kcsd.validation.plotting_functions as pl 8 | import sKCSD_utils 9 | n_src = 512 10 | lambd = 1 11 | R = 8e-6/2**.5 12 | if __name__ == '__main__': 13 | fname_base = "Figure_3" 14 | tstop = 75 15 | scaling_factor = 1000**2 16 | scaling_factor_LFP = 1000 17 | R_inits = [2**i for i in range(3, 8)] 18 | lambdas = [10**(-i) for i in range(6)] 19 | electrode_number = [8, 32, 128] 20 | data_dir = [] 21 | xmin, xmax = -100, 600 22 | ymin, ymax = 0, 200 23 | orientation = 1 24 | for rownb in electrode_number: 25 | fname = '%s_rows_%d' % (fname_base, rownb) 26 | if sys.version_info < (3, 0): 27 | c = sKCSD_utils.simulate(fname, 28 | morphology=1, 29 | simulate_what="random", 30 | colnb=1, 31 | rownb=rownb, 32 | xmin=xmin, 33 | xmax=xmax, 34 | ymin=ymin, 35 | ymax=ymax, 36 | tstop=tstop, 37 | seed=1988, 38 | weight=0.1, 39 | n_syn=100) 40 | new_dir = c.return_paths_skCSD_python() 41 | else: 42 | new_dir = os.path.join('simulation', fname) 43 | data_dir.append(new_dir) 44 | seglen = np.loadtxt(os.path.join(data_dir[0], 'seglength')) 45 | ground_truth = np.loadtxt(os.path.join(data_dir[0], 'membcurr')) 46 | ground_truth = ground_truth/seglen[:, None]*1e-3 47 | gvmax, gvmin = pl.get_min_max(ground_truth) 48 | data_paths = [] 49 | fig, ax = plt.subplots(2, 3) 50 | cax = ax[0, 0].imshow(ground_truth, 51 | extent=[0, tstop, 1, 52], 52 | origin='lower', 53 | aspect='auto', 54 | cmap='seismic_r', 55 | vmax=gvmax, 56 | vmin=gvmin) 57 | new_fname = fname_base + '.png' 58 | fig_name = sKCSD_utils.make_fig_names(new_fname) 59 | for i, datd in enumerate(data_dir): 60 | data = utils.LoadData(datd) 61 | ele_pos = data.ele_pos/scaling_factor 62 | data.LFP = data.LFP/scaling_factor_LFP 63 | morphology = data.morphology 64 | morphology[:, 2:6] = morphology[:, 2:6]/scaling_factor 65 | k = sKCSD(ele_pos, 66 | data.LFP, 67 | morphology, 68 | n_src_init=n_src, 69 | src_type='gauss', 70 | lambd=lambd, 71 | R_init=R, 72 | exact=True, 73 | sigma=0.3) 74 | csd = k.values(transformation='segments') 75 | 76 | cax = ax[1, i].imshow(csd, 77 | extent=[0, tstop, 1, 52], 78 | origin='lower', 79 | aspect='auto', 80 | cmap='seismic_r', 81 | vmax=gvmax, 82 | vmin=gvmin) 83 | ax[1, i].set_title(electrode_number[i]) 84 | fig.savefig(fig_name, 85 | bbox_inches='tight', 86 | transparent=True, 87 | pad_inches=0.1) 88 | -------------------------------------------------------------------------------- /figures/sKCSD_paper/make_fig_6.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | import sys 4 | import os 5 | from kcsd import sKCSD 6 | from kcsd import sKCSD_utils as utils 7 | import kcsd.validation.plotting_functions as pl 8 | import sKCSD_utils 9 | n_src = 512 10 | R = 16e-6/2**.5 11 | lambd = .1/((2*(2*np.pi)**3*R**2*n_src)) 12 | if __name__ == '__main__': 13 | fname_base = "Figure_6" 14 | tstop = 70 15 | scaling_factor = 1000**2 16 | scaling_factor_LFP = 1000 17 | data_dir = [] 18 | colnb = 4 19 | dt = 2**(-4) 20 | rows = [2, 4, 8, 16] 21 | xmin, xmax = -100, 600 22 | ymin, ymax = -100, 100 23 | sim_type = {'1': "grid", '2': "random"} 24 | for i, rownb in enumerate(rows): 25 | for orientation in [1, 2]: 26 | fname = "Figure_6_" + sim_type[str(orientation)] 27 | c = sKCSD_utils.simulate(fname, 28 | morphology=2, 29 | simulate_what="symmetric", 30 | colnb=rownb, 31 | rownb=colnb, 32 | xmin=-100, 33 | xmax=500, 34 | ymin=-100, 35 | ymax=100, 36 | tstop=tstop, 37 | seed=1988, 38 | weight=0.04, 39 | n_syn=100, 40 | electrode_distribution=orientation, 41 | electrode_orientation=2, 42 | dt=2**(-4)) 43 | data_dir.append(c.return_paths_skCSD_python()) 44 | seglen = np.loadtxt(os.path.join(data_dir[0], 45 | 'seglength')) 46 | ground_truth = np.loadtxt(os.path.join(data_dir[0], 47 | 'membcurr')) 48 | ground_truth = ground_truth/seglen[:, None]*1e-3 49 | t1 = int(42/dt) 50 | t2 = int(5/dt) 51 | atstart = t2 52 | atstop = int(t2 + 10/dt) 53 | simulation_paths = [] 54 | data_paths = [] 55 | skcsd_grid = [] 56 | skcsd_random = [] 57 | fig, ax = plt.subplots(1, 3) 58 | fname = fname_base + '.png' 59 | fig_name = sKCSD_utils.make_fig_names(fname) 60 | vmax, vmin = pl.get_min_max(ground_truth[:, atstart:atstop]) 61 | pl.make_map_plot(ax[0], 62 | ground_truth[:, atstart:atstop], 63 | yticklabels=[x for x in range(0, 86, 15)], 64 | fig=fig, 65 | title="Ground truth", 66 | ylabel='#segment', 67 | sinksource=True) 68 | for i, datd in enumerate(data_dir): 69 | data = utils.LoadData(datd) 70 | ele_pos = data.ele_pos/scaling_factor 71 | data.LFP = data.LFP/scaling_factor_LFP 72 | morphology = data.morphology 73 | morphology[:, 2:6] = morphology[:, 2:6]/scaling_factor 74 | k = sKCSD(ele_pos, 75 | data.LFP, 76 | morphology, 77 | n_src_init=n_src, 78 | src_type='gauss', 79 | lambd=lambd, 80 | R_init=R, 81 | dist_table_density=20, 82 | exact=True, 83 | sigma=0.3) 84 | est_skcsd = k.values(estimate='CSD', 85 | transformation='segments') 86 | if i % 2: 87 | skcsd_random.append(est_skcsd) 88 | else: 89 | skcsd_grid.append(est_skcsd) 90 | if sys.version_info < (3, 0): 91 | path = os.path.join(datd, "preprocessed_data/Python_2") 92 | else: 93 | path = os.path.join(datd, "preprocessed_data/Python_3") 94 | if not os.path.exists(path): 95 | print("Creating", path) 96 | os.makedirs(path) 97 | utils.save_sim(path, k) 98 | skcsd_maps_grid = sKCSD_utils.merge_maps(skcsd_grid, 99 | tstart=atstart, 100 | tstop=atstop, 101 | merge=1) 102 | pl.make_map_plot(ax[1], 103 | skcsd_maps_grid, 104 | xticklabels=['8', '16', '32', '64'], 105 | title="Grid", 106 | xlabel='electrodes', 107 | alpha=1) 108 | skcsd_maps_random = sKCSD_utils.merge_maps(skcsd_random, 109 | tstart=atstart, 110 | tstop=atstop, 111 | merge=1) 112 | pl.make_map_plot(ax[2], 113 | skcsd_maps_random, 114 | xticklabels=['8', '16', '32', '64'], 115 | title="Random", 116 | xlabel='electrodes', 117 | alpha=1) 118 | fig.savefig(fig_name, 119 | bbox_inches='tight', 120 | transparent=True, 121 | pad_inches=0.1) 122 | -------------------------------------------------------------------------------- /figures/sKCSD_paper/make_fig_7.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | import sys 4 | import os 5 | from kcsd import sKCSD 6 | from kcsd import sKCSD_utils as utils 7 | import kcsd.validation.plotting_functions as pl 8 | import sKCSD_utils 9 | dt = 0.5 10 | if __name__ == '__main__': 11 | fname_base = "Figure_7" 12 | fig_name = sKCSD_utils.make_fig_names(fname_base + '.png') 13 | tstop = 70 14 | scale_factor = 1000**2 15 | scale_factor_LFP = 1000 16 | R_inits = np.array([(2**(i - .5))/scale_factor for i in range(3, 7)]) 17 | lambdas = np.array([(10**(-i))for i in range(5, -5, -1)]) 18 | n_srcs = np.array([32, 64, 128, 512, 1024]) 19 | x_ticklabels = [2**i for i in range(3, 7)] 20 | y_ticklabels = [str(lambd) for lambd in lambdas] 21 | colnb = 4 22 | rownb = 4 23 | c = sKCSD_utils.simulate(fname_base, 24 | morphology=2, 25 | colnb=colnb, 26 | rownb=rownb, 27 | xmin=0, 28 | xmax=500, 29 | ymin=-100, 30 | ymax=100, 31 | tstop=tstop, 32 | seed=1988, 33 | weight=0.04, 34 | n_syn=100, 35 | electrode_orientation=2, 36 | simulate_what='symmetric', 37 | dt=dt) 38 | new_path = c.return_paths_skCSD_python() 39 | data = utils.LoadData(new_path) 40 | ele_pos = data.ele_pos/scale_factor 41 | pots = data.LFP/scale_factor_LFP 42 | morphology = data.morphology 43 | morphology[:, 2:6] = morphology[:, 2:6]/scale_factor 44 | new_path = c.return_paths_skCSD_python() 45 | ground_truth = np.loadtxt(os.path.join(new_path, 46 | 'membcurr')) 47 | seglen = np.loadtxt(os.path.join(new_path, 48 | 'seglength')) 49 | ground_truth = ground_truth/seglen[:, None]*1e-3 50 | outs = np.zeros((len(n_srcs), len(lambdas), len(R_inits))) 51 | for i, n_src in enumerate(n_srcs): 52 | for j, l in enumerate(lambdas): 53 | for k, R in enumerate(R_inits): 54 | lambd = l 55 | ker = sKCSD(ele_pos, 56 | pots, 57 | morphology, 58 | n_src_init=n_src, 59 | src_type='gauss', 60 | lambd=lambd, 61 | R_init=R, 62 | exact=True, 63 | sigma=0.3) 64 | est_skcsd = ker.values(estimate='CSD', 65 | transformation='segments') 66 | 67 | outs[i, j, k] = sKCSD_utils.L1_error(ground_truth, 68 | est_skcsd) 69 | print(outs[i, j, k], est_skcsd.min(), est_skcsd.max(), ground_truth.min(), ground_truth.max(), n_src, l, R) 70 | fig, ax = plt.subplots(1, len(n_srcs), sharey=True) 71 | vmax = outs.max() 72 | vmin = outs.min() 73 | for i, ax_i in enumerate(ax): 74 | title = "M = %d" % n_srcs[i] 75 | if not i: 76 | pl.make_map_plot(ax_i, 77 | outs[i], 78 | yticklabels=y_ticklabels, 79 | xticklabels=x_ticklabels, 80 | vmin=vmin, 81 | vmax=vmax, 82 | title=title, 83 | cmap='gray') 84 | elif i < len(n_srcs) - 1: 85 | pl.make_map_plot(ax_i, 86 | outs[i], 87 | xticklabels=x_ticklabels, 88 | vmin=vmin, 89 | vmax=vmax, 90 | title=title, 91 | cmap='gray') 92 | else: 93 | pl.make_map_plot(ax_i, 94 | outs[i], 95 | xticklabels=x_ticklabels, 96 | fig=fig, 97 | vmin=vmin, 98 | vmax=vmax, 99 | sinksource=False, 100 | title=title, 101 | cmap='gray') 102 | fig.savefig(fig_name, 103 | bbox_inches='tight', 104 | transparent=True, 105 | pad_inches=0.1) 106 | -------------------------------------------------------------------------------- /figures/sKCSD_paper/make_fig_9.py: -------------------------------------------------------------------------------- 1 | import run_LFP 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | import sys 5 | import os 6 | from kcsd import sKCSD, sKCSDcell 7 | from kcsd import sKCSD_utils as utils 8 | import kcsd.validation.plotting_functions as pl 9 | import sKCSD_utils 10 | import numpy.random 11 | 12 | n_src = 512 13 | l = 1e-1 14 | R = 16e-6/2**.5 15 | dt = 2**(-1) 16 | noise_levels = [0, 16, 4 , 1] 17 | lambd = l/(2*(2*np.pi)**3*R**2*n_src) 18 | if __name__ == '__main__': 19 | fname_base = "simulation/Figure_9_noise_%f" 20 | tstop = 7 21 | scaling_factor = 1000**2 22 | scaling_factor_LFP = 1000 23 | data_dir = [] 24 | colnb = 4 25 | rownb = 8 26 | xmin, xmax = 0, 500 27 | ymin, ymax = -80, 80 28 | t1 = int(5.5/dt) 29 | fname = "Figure_9" 30 | c = sKCSD_utils.simulate(fname, 31 | morphology=2, 32 | simulate_what="symmetric", 33 | colnb=colnb, 34 | rownb=rownb, 35 | xmin=xmin, 36 | xmax=xmax, 37 | ymin=ymin, 38 | ymax=ymax, 39 | tstop=tstop, 40 | seed=1988, 41 | weight=0.04, 42 | n_syn=100, 43 | electrode_distribution=1, 44 | dt=dt) 45 | 46 | data_dir = c.return_paths_skCSD_python() 47 | 48 | seglen = np.loadtxt(os.path.join(data_dir, 49 | 'seglength')) 50 | 51 | ground_truth = np.loadtxt(os.path.join(data_dir, 52 | 'membcurr')) 53 | 54 | ground_truth = ground_truth/seglen[:, None]*1e-3 55 | 56 | fig, ax = plt.subplots(2, 3, figsize=(8,20)) 57 | fname = "Figure_9.png" 58 | fig_name = sKCSD_utils.make_fig_names(fname) 59 | 60 | data = utils.LoadData(data_dir) 61 | ele_pos = data.ele_pos/scaling_factor 62 | data.LFP = data.LFP/scaling_factor_LFP 63 | morphology = data.morphology 64 | morphology[:, 2:6] = morphology[:, 2:6]/scaling_factor 65 | std = data.LFP.var()**.5 66 | shape = data.LFP.shape 67 | cell = sKCSDcell(morphology, ele_pos, n_src, 68 | tolerance=2e-6, 69 | xmin=-120e-6, xmax=120e-6, 70 | zmin=-50e-6, zmax=550e-6) 71 | ground_truth_grid = cell.transform_to_3D(ground_truth, what="morpho") 72 | vmax, vmin = pl.get_min_max(ground_truth_grid[:, :, :, t1].sum(axis=1)) 73 | gdt1 = ground_truth_grid[:,:,:,t1].sum(axis=1) 74 | morpho, extent = cell.draw_cell2D(axis=1) 75 | extent = [extent[-2], extent[-1], extent[0], extent[1]] 76 | new_ele_pos = np.array([ele_pos[:, 2], ele_pos[:, 0]]).T 77 | pl.make_map_plot(ax[0, 0], 78 | gdt1, 79 | vmin=vmin, 80 | vmax=vmax, 81 | extent=extent, 82 | alpha=.9, 83 | morphology=morpho, 84 | ele_pos=new_ele_pos) 85 | snrs = [] 86 | L1 = [] 87 | 88 | for i, nl in enumerate(noise_levels): 89 | new_LFP = data.LFP 90 | if nl: 91 | noise = numpy.random.normal(scale=std/nl, size=shape) 92 | snr = np.round((new_LFP.var()**.5/noise.var()**.5)) 93 | 94 | else: 95 | noise = 0 96 | snr = 0 97 | new_LFP += noise 98 | snrs.append(snr) 99 | 100 | 101 | 102 | 103 | 104 | k = sKCSD(ele_pos, 105 | new_LFP, 106 | morphology, 107 | n_src_init=n_src, 108 | src_type='gauss', 109 | lambd=lambd, 110 | R_init=R, 111 | exact=True, 112 | sigma=0.3) 113 | 114 | if sys.version_info < (3, 0): 115 | path = os.path.join(fname_base % nl, "preprocessed_data/Python_2") 116 | else: 117 | path = os.path.join(fname_base % nl, "preprocessed_data/Python_3") 118 | 119 | if not os.path.exists(path): 120 | print("Creating", path) 121 | os.makedirs(path) 122 | try: 123 | utils.save_sim(path, k) 124 | except NameError: 125 | pass 126 | 127 | 128 | est_skcsd, est_pot, morphology, ele_pos, n_src = utils.load_sim(path) 129 | cell_object = sKCSDcell(morphology, ele_pos, n_src) 130 | est_skcsd = cell.transform_to_3D(est_skcsd) 131 | L1.append(sKCSD_utils.L1_error(ground_truth_grid, est_skcsd)) 132 | if nl == 0: 133 | pl.make_map_plot(ax[0, 1], 134 | est_skcsd[:,:,:,t1].sum(axis=1), 135 | vmin=vmin, 136 | vmax=vmax, 137 | extent=extent, 138 | title="No noise", 139 | alpha=.9, 140 | morphology=morpho, 141 | ele_pos=new_ele_pos) 142 | else: 143 | pl.make_map_plot(ax[1, i-1], 144 | est_skcsd[:,:,:,t1].sum(axis=1), 145 | vmin=vmin, 146 | vmax=vmax, 147 | extent=extent, 148 | title='SNR %f' % snr, 149 | alpha=.9, 150 | morphology=morpho, 151 | ele_pos=new_ele_pos) 152 | 153 | ax[0, 2].plot([i for i in range(len(snrs))], L1, 'dk') 154 | ax[0, 2].set_xticks([i for i in range(len(snrs))]) 155 | ax[0, 2].set_xticklabels([ 'No noise','16', '4', '1', ], rotation = 90) 156 | ax[0, 0].set_title('Ground truth') 157 | ax[0, 2].set_ylabel('L1 error', fontsize=12) 158 | ax[0, 2].set_xlabel('SNR', fontsize=12) 159 | fig.subplots_adjust(hspace=.5, wspace=.35) 160 | fig.savefig(fig_name, 161 | bbox_inches='tight', 162 | transparent=True, 163 | pad_inches=0.1) 164 | 165 | -------------------------------------------------------------------------------- /figures/sKCSD_paper/sKCSD_utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import os 3 | import sys 4 | import run_LFP 5 | 6 | 7 | def make_fig_names(fname_base): 8 | if not os.path.exists('Figures'): 9 | os.makedirs('Figures') 10 | return os.path.join('Figures', fname_base) 11 | 12 | 13 | def simulate(fname_base, **kwargs): 14 | morphology = kwargs.pop("morphology", 1) 15 | simulate_what = kwargs.pop("simulate_what", 1) 16 | electrode_orientation = kwargs.pop("electrode_orientation", 2) 17 | electrode_distribution = kwargs.pop("electrode_distribution", 1) 18 | colnb = kwargs.pop("colnb", 4) 19 | rownb = kwargs.pop("rownb", 4) 20 | xmin = kwargs.pop("xmin", -200) 21 | xmax = kwargs.pop("xmax", 200) 22 | ymin = kwargs.pop("ymin", -200) 23 | ymax = kwargs.pop("ymax", 200) 24 | tstop = kwargs.pop("tstop", 100) 25 | seed = kwargs.pop("seed", 1988) 26 | weight = kwargs.pop("weight", .01) 27 | n_syn = kwargs.pop("n_syn", 1000) 28 | fname = fname_base+'_rows_%s_cols_%s_xmin_%s_xmax_%s_ymin_%s_ymax_%s_orientation_%s' % (rownb, colnb, xmin, xmax, ymin, ymax, electrode_orientation) 29 | triside = kwargs.pop("triside", 60) 30 | electrode_distance = kwargs.pop("electrode_distance", 50) 31 | dt = kwargs.pop("dt", 0.5) 32 | if kwargs: 33 | raise TypeError('Invalid keyword arguments:', kwargs.keys()) 34 | c = run_LFP.CellModel(morphology=morphology, 35 | cell_name=fname, 36 | colnb=colnb, 37 | rownb=rownb, 38 | xmin=xmin, 39 | xmax=xmax, 40 | ymin=ymin, 41 | ymax=ymax, 42 | tstop=tstop, 43 | seed=seed, 44 | weight=weight, 45 | n_syn=n_syn, 46 | electrode_distribution=electrode_distribution, 47 | electrode_orientation=electrode_orientation, 48 | electrode_distance=electrode_distance, 49 | triside=triside, 50 | dt=dt) 51 | c.simulate(stimulus=simulate_what) 52 | c.save_skCSD_python() 53 | c.save_memb_curr() 54 | c.save_seg_length() 55 | c.save_somav() 56 | c.save_tvec() 57 | return c 58 | 59 | 60 | def L1_error(csd, est_csd): 61 | return (abs(csd-est_csd)).sum()/abs(csd).sum() 62 | 63 | 64 | def make_output(what, tstart, tstop, merge): 65 | plotage = what[:, tstart:tstop] 66 | out = np.zeros((what.shape[0], (tstop-tstart)//merge)) 67 | for k in range((tstop-tstart)//merge): 68 | out[:, k] = plotage[:, k*merge:(k+1)*merge].sum(axis=1)/merge 69 | return out 70 | 71 | 72 | def merge_maps(maps, tstart, tstop, merge=1): 73 | single_width = (tstop-tstart)//merge 74 | outs = np.zeros((maps[0].shape[0], single_width*len(maps))) 75 | for i, mappe in enumerate(maps): 76 | outs[:, i*single_width:(i+1)*single_width] = make_output(mappe, 77 | tstart=tstart, 78 | tstop=tstop, 79 | merge=merge) 80 | return outs 81 | 82 | 83 | if __name__ == '__main__': 84 | fname_base = "gang_7x7_200_distal_osc" 85 | args = { 86 | 'morphology': 9, 87 | 'xmin': -40, 88 | 'xmax': 40, 89 | 'ymin': -20, 90 | 'ymax': 20, 91 | 'electrode_distribution': 1, 92 | 'electrode_orientation': 3, 93 | 'colnb': 5, 94 | 'rownb': 4, 95 | 'tstop': 100, 96 | 'simulate_what': 'distal_oscillatory', 97 | } 98 | simulate(fname_base, **args) 99 | fname_base = "gang_7x7_200" 100 | args = { 101 | 'morphology': 9, 102 | 'xmin': -200, 103 | 'xmax': 200, 104 | 'ymin': -200, 105 | 'ymax': 200, 106 | 'electrode_distribution': 1, 107 | 'electrode_orientation': 3, 108 | 'simulate_what':'oscillatory', 109 | 'colnb': 10, 110 | 'rownb': 10, 111 | 'tstop': 100, 112 | } 113 | simulate(fname_base, **args) 114 | 115 | -------------------------------------------------------------------------------- /figures/what_you_can_see_with_lfp/README.txt: -------------------------------------------------------------------------------- 1 | Instructions for the figures from kCSD-revisited paper. 2 | 3 | ~~~~~~~~~~~~~~~~~~~~~~~ 4 | Figure 1 - Spectral properties of kCSD method for well-placed and misplaced electrodes 5 | 6 | name: kcsd_properties/Fig1-figure_Tbasis.py 7 | 8 | ~~~~~~~~~~~~~~~~~~~~~~~ 9 | Figure 2 - Simulated cortical column and kCSD analysis 10 | 11 | name: npx/Fig2-traub_data_kcsd_column_figure.py 12 | 13 | ~~~~~~~~~~~~~~~~~~~~~~~ 14 | Figure 3 - LFP and CSD within the model column and experimental data as a function of time 15 | 16 | name: npx/Fig3-figure_traub_timespace.py 17 | 18 | ~~~~~~~~~~~~~~~~~~~~~~~ 19 | Figure 4 - An example reconstruction of the LFP and CSD in the plane of the 20 | electrodes from a snapshot in time from an experimental recording in the rat barrel cortex 21 | 22 | name: npx/Fig4-Neuropixels_with_fitted_dipoles_model.py 23 | 24 | ~~~~~~~~~~~~~~~~~~~~~~~ 25 | Figure 5 - Schematic 26 | 27 | ~~~~~~~~~~~~~~~~~~~~~~~ 28 | Figure 6 - Eigensources for a single bank of a Neuropixels probe 29 | 30 | name: npx/Fig6-figure_traub_eigensources.py 31 | -------------------------------------------------------------------------------- /figures/what_you_can_see_with_lfp/npx/Fig3-figure_traub_timespace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | @author: mbejtka 5 | """ 6 | import numpy as np 7 | import h5py as h5 8 | import matplotlib.pyplot as plt 9 | from Fig2_traub_data_kcsd_column_figure import (prepare_electrodes, prepare_pots, do_kcsd) 10 | import kCSD2D_reconstruction_from_npx as npx 11 | from scipy.signal import filtfilt, butter 12 | 13 | 14 | def set_axis(ax, letter=None): 15 | ax.text(-0.05, 16 | 1.05, 17 | letter, 18 | fontsize=20, 19 | weight='bold', 20 | transform=ax.transAxes) 21 | return ax 22 | 23 | 24 | def make_plot_spacetime(ax, val, cut=9, title='True CSD', 25 | cmap=plt.cm.bwr, letter='A', ylabel=True, label=''): 26 | yy = np.linspace(-3500, 500, val.shape[1]) 27 | xx = np.linspace(-50, 250, val[cut, :, :].shape[1]) 28 | max_val = np.max(np.abs(val[cut, :, :])) 29 | levels = np.linspace(-max_val, max_val, 200) 30 | im = ax.contourf(xx, yy, val[cut, :, :], levels=levels, cmap=cmap) 31 | if 'CSD' in title: 32 | name = ['', 'II/III', 'IV', 'V', 'VI'] 33 | layer_level = [0, -400, -700, -1200, -1700] 34 | for i, value in enumerate(layer_level): 35 | plt.axhline(y=value, xmin=xx.min(), xmax=xx.max(), linewidth=1, color='k', ls='--') 36 | plt.text(60, value+145, name[i], fontsize=15, va='top', ha='center') 37 | ax.set_xlabel('Time (ms)', fontsize=20) 38 | if ylabel: 39 | ax.set_ylabel('Y ($\mu$m)', fontsize=20) 40 | if letter=='B': ax.set_yticks([]) 41 | ax.set_title(title, fontsize=20, pad=30) 42 | ax.set_xlim(-50, 100) 43 | ax.xaxis.set_tick_params(labelsize=18) 44 | ax.yaxis.set_tick_params(labelsize=18) 45 | ticks = np.linspace(-max_val, max_val, 3, endpoint=True) 46 | cb = plt.colorbar(im, orientation='horizontal', format='%.3f', ticks=ticks) 47 | cb.set_label(label) 48 | set_axis(ax, letter=letter) 49 | plt.tight_layout() 50 | 51 | 52 | def make_plot_1D_pics(ax, k, est_val, tp, Fs, cut=9, title='Experimental data', 53 | cmap=plt.cm.bwr, letter='A', ylabel=True, label=''): 54 | 55 | set_axis(ax, letter=letter) 56 | npx.make_plot_spacetime(ax, k.estm_x, k.estm_y, est_val[cut,:,:], Fs, 57 | title=title, cmap=cmap, ylabel=ylabel, label=label) 58 | if letter == 'D': 59 | for lvl, name in zip([-500,-850,-2000], ['II/III', 'IV', 'V/VI']): 60 | plt.axhline(lvl, ls='--', color='grey') 61 | plt.text(340, lvl+20, name, fontsize=15) 62 | elif letter == 'C': 63 | plt.axvline(tp/Fs*1000, ls='--', color ='grey', lw=2) 64 | ax.set_yticks([]) 65 | plt.xlim(250, 400) 66 | plt.xticks([250, 300, 350, 400], [-50, 0, 50, 100]) 67 | plt.tick_params(labelsize=18) 68 | plt.tight_layout() 69 | #plt.savefig('figure_1D_pics', dpi=300) 70 | 71 | 72 | def make_figure_spacetime(val_pots_m, val_csd_m, kcsd_obj, val_pots_e, val_csd_e, tp, Fs, cut1=13, cut2=15, 73 | titl1='POT', titl2='CSD', fig_title='Pot and CSD in time'): 74 | #fig, axes = plt.subplots(1, 4, figsize=(16, 9)) 75 | fig = plt.figure(figsize=(16, 9)) 76 | #plt.text(x=0.3, y=1, s="MODEL", fontsize=24, ha="center", transform=fig.transFigure) 77 | #plt.text(x=0.7, y=1, s= "EXPERIMENT", fontsize=24, ha="center", transform=fig.transFigure) 78 | fig.suptitle('MODEL EXPERIMENT', y=0.95, fontsize=24, x=0.54) 79 | #fig.suptitle('EXPERIMENT', y=0.95, fontsize=25, x=0.7) 80 | ax2 = plt.subplot(141) 81 | make_plot_spacetime(ax2, val_pots_m, cut=cut1, 82 | title='Estimated LFP', cmap=plt.cm.PRGn, letter='A', label='mV') 83 | ax1 = plt.subplot(142) 84 | make_plot_spacetime(ax1, val_csd_m, cut=cut1, 85 | title='Estimated CSD', cmap=plt.cm.bwr, letter='B', ylabel=False, 86 | label='$\mu$A/mm$^3$') 87 | ax3 = plt.subplot(143) 88 | make_plot_1D_pics(ax3, kcsd_obj, val_pots_e, tp, Fs, cut=cut2, title='Estimated LFP', 89 | cmap=plt.cm.PRGn, letter='C', ylabel=False, label='mV') 90 | ax4 = plt.subplot(144) 91 | make_plot_1D_pics(ax4, kcsd_obj, val_csd_e, tp, Fs, cut=cut2, title='Estimated CSD', 92 | cmap=plt.cm.bwr, letter='D', ylabel=False,label='$\mu$A/mm$^3$') 93 | plt.subplots_adjust(top=0.8) 94 | #plt.tight_layout() 95 | fig.savefig(fig_title + '.png', dpi=300) 96 | 97 | 98 | if __name__ == '__main__': 99 | time_pt_interest = 3000 100 | time_pts = 6000 # number of all time frames 101 | num_cmpts = [74, 74, 59, 59, 59, 59, 61, 61, 50, 59, 59, 59] 102 | cell_range = [0, 1000, 1050, 1140, 1230, 1320, 103 | 1560, 2360, 2560, 3060, 3160, 3260, 3360] 104 | num_cells = np.diff(cell_range) / 10 # 10% MODEL 105 | total_cmpts = list(num_cmpts * num_cells) 106 | pop_names = ['pyrRS23', 'pyrFRB23', 'bask23', 'axax23', 'LTS23', 107 | 'spinstel4', 'tuftIB5', 'tuftRS5', 'nontuftRS6', 108 | 'bask56', 'axax56', 'LTS56'] 109 | 110 | h = h5.File('pulsestimulus10model.h5', 'r') 111 | elec_pos_list, names_list = prepare_electrodes() 112 | 113 | pot_np = prepare_pots(elec_pos_list[1], names_list[1], h, pop_names, time_pts) 114 | kcsd_m, est_pot_m, x_m, y_m, k_m = do_kcsd(pot_np, elec_pos_list[1][:, :2], -40, 40, -3500, 500, n_src_init=5000) 115 | 116 | lowpass = 0.5 117 | highpass = 300 118 | Fs = 30000 119 | resamp = 12 120 | tp= 760 121 | 122 | forfilt=np.load('npx_data.npy') 123 | 124 | [b,a] = butter(3, [lowpass/(Fs/2.0), highpass/(Fs/2.0)] ,btype = 'bandpass') 125 | filtData = filtfilt(b,a, forfilt) 126 | pots_resamp = filtData[:,::resamp] 127 | pots = pots_resamp[:, :] 128 | Fs=int(Fs/resamp) 129 | 130 | pots_for_csd = np.delete(pots, 191, axis=0) 131 | ele_pos_def = npx.eles_to_coords(np.arange(384,0,-1)) 132 | ele_pos_for_csd = np.delete(ele_pos_def, 191, axis=0) 133 | 134 | k_e, est_csd_e, est_pots_e, ele_pos_e = npx.do_kcsd(ele_pos_for_csd, pots_for_csd, ele_limit=(0,330)) 135 | 136 | time_pts_ds = int(time_pts/4) 137 | cut1 = 9 138 | start_pt = 625 # 50 ms before the stimulus 139 | end_pt = 1375 # 250 ms after the stimulus 140 | # for cut in range(kcsd.shape[0]): 141 | make_figure_spacetime(est_pot_m[:, :, start_pt:end_pt], 142 | kcsd_m[:, :, start_pt:end_pt], k_e, est_pots_e, est_csd_e, tp, Fs, cut1=cut1, cut2=15, 143 | titl1='Estimated LFP', titl2='Estimated CSD', 144 | fig_title=('Fig3_h=1_final')) 145 | #plot_1D_pics(k, est_csd, est_pots, tp, 15) 146 | -------------------------------------------------------------------------------- /figures/what_you_can_see_with_lfp/npx/figure_properties.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | def set_axis(ax, x, y, letter=None): 4 | ax.text( 5 | x, 6 | y, 7 | letter, 8 | fontsize=25, 9 | weight='bold', 10 | transform=ax.transAxes) 11 | return ax 12 | 13 | plt.rcParams.update({ 14 | 'xtick.labelsize': 15, 15 | 'xtick.major.size': 10, 16 | 'ytick.labelsize': 15, 17 | 'ytick.major.size': 10, 18 | 'font.size': 12, 19 | 'axes.labelsize': 15, 20 | 'axes.titlesize': 20, 21 | 'axes.titlepad' : 30, 22 | 'legend.fontsize': 15, 23 | # 'figure.subplot.wspace': 0.4, 24 | # 'figure.subplot.hspace': 0.4, 25 | # 'figure.subplot.left': 0.1, 26 | }) 27 | 28 | 29 | -------------------------------------------------------------------------------- /figures/what_you_can_see_with_lfp/npx/kCSD2D_reconstruction_from_npx.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from kcsd import KCSD2D 3 | import matplotlib.pyplot as plt 4 | import matplotlib.cm as cm 5 | from scipy.signal import filtfilt, butter 6 | from figure_properties import * 7 | plt.close('all') 8 | #%% 9 | def make_plot_spacetime(ax, xx, yy, zz, Fs, title='True CSD', cmap=cm.bwr_r, ymin=0, ymax=10000, ylabel=True, label=''): 10 | im = ax.imshow(zz,extent=[0, zz.shape[1]/Fs*1000,-3500, 500], aspect='auto', 11 | vmax = 1*zz.max(),vmin = -1*zz.max(), cmap=cmap) 12 | ax.set_xlabel('Time (ms)', fontsize=20) 13 | if ylabel: 14 | ax.set_ylabel('Y ($\mu$m)', fontsize=20) 15 | if 'Pot' in title: ax.set_ylabel('Y ($\mu$m)', fontsize=20) 16 | ax.set_title(title, fontsize=20, pad=30) 17 | ticks = np.linspace(-zz.max(), zz.max(), 3, endpoint=True) 18 | if 'CSD' in title: 19 | cb = plt.colorbar(im, orientation='horizontal', format='%.2f', ticks = ticks) 20 | else: 21 | cb = plt.colorbar(im, orientation='horizontal', format='%.1f', ticks = ticks) 22 | cb.set_label(label) 23 | # plt.gca().invert_yaxis() 24 | 25 | def make_plot(ax, xx, yy, zz, title='True CSD', cmap=cm.bwr): 26 | ax.set_aspect('auto') 27 | levels = np.linspace(zz.min(), -zz.min(), 61) 28 | im = ax.contourf(xx, -(yy-500), zz, levels=levels, cmap=cmap) 29 | ax.set_xlabel('X ($\mu$m)', fontsize=20) 30 | ax.set_ylabel('Y ($\mu$m)', fontsize=20) 31 | ax.set_title(title) 32 | if 'CSD' in title: 33 | plt.colorbar(im, orientation='vertical', format='%.2f', ticks=[-0.02,0,0.02]) 34 | else: plt.colorbar(im, orientation='vertical', format='%.1f', ticks=[-0.6,0,0.6]) 35 | plt.scatter(ele_pos[:, 0], 36 | -(ele_pos[:, 1]-500), 37 | s=0.8, color='black') 38 | # plt.gca().invert_yaxis() 39 | return ax 40 | 41 | def eles_to_ycoord(eles): 42 | y_coords = [] 43 | for ii in range(192): 44 | y_coords.append(ii*20) 45 | y_coords.append(ii*20) 46 | return y_coords[::-1] 47 | 48 | def eles_to_xcoord(eles): 49 | x_coords = [] 50 | for ele in eles: 51 | off = ele%4 52 | if off == 1: x_coords.append(-24) 53 | elif off == 2: x_coords.append(8) 54 | elif off == 3: x_coords.append(-8) 55 | elif off==0: x_coords.append(24) 56 | return x_coords 57 | 58 | def eles_to_coords(eles): 59 | xs = eles_to_xcoord(eles) 60 | ys = eles_to_ycoord(eles) 61 | return np.array((xs, ys)).T 62 | 63 | def plot_1D_pics(k, est_csd, est_pots, tp, Fs, cut=9): 64 | plt.figure(figsize=(12, 8)) 65 | # plt.suptitle('plane: '+str(k.estm_x[cut,0])+' $\mu$m '+' $\lambda$ : '+str(k.lambd)+ 66 | # ' R: '+ str(k.R)) 67 | ax1 = plt.subplot(122) 68 | set_axis(ax1, -0.05, 1.05, letter= 'D') 69 | make_plot_spacetime(ax1, k.estm_x, k.estm_y, est_csd[cut,:,:], Fs, 70 | title='Estimated CSD', cmap='bwr') 71 | for lvl, name in zip([-500,-850,-2000], ['II/III', 'IV', 'V/VI']): 72 | plt.axhline(lvl, ls='--', color='grey') 73 | plt.text(340, lvl+20, name, fontsize=15) 74 | plt.xlim(250, 400) 75 | plt.xticks([250, 300, 350, 400], [-50, 0, 50, 100]) 76 | ax2 = plt.subplot(121) 77 | set_axis(ax2, -0.05, 1.05, letter= 'C') 78 | make_plot_spacetime(ax2, k.estm_x, k.estm_y, est_pots[cut,:,:], Fs, 79 | title='Estimated LFP', cmap='PRGn') 80 | plt.axvline(tp/Fs*1000, ls='--', color ='grey', lw=2) 81 | plt.xlim(250, 400) 82 | plt.xticks([250, 300, 350, 400], [-50, 0, 50, 100]) 83 | plt.tight_layout() 84 | plt.savefig('figure_1D_pics', dpi=300) 85 | 86 | def plot_2D_pics(k, est_csd, est_pots, tp, Fs, cut, save=0): 87 | plt.figure(figsize=(12, 8)) 88 | ax1 = plt.subplot(122) 89 | set_axis(ax1, -0.05, 1.05, letter= 'B') 90 | make_plot(ax1, k.estm_x, k.estm_y, est_csd[:,:,tp], 91 | title='Estimated CSD', cmap='bwr') 92 | # for i in range(383): plt.text(ele_pos_for_csd[i,0], ele_pos_for_csd[i,1]+8, str(i+1)) 93 | plt.axvline(k.estm_x[cut][0], ls='--', color ='grey', lw=2) 94 | ax2 = plt.subplot(121) 95 | set_axis(ax2, -0.05, 1.05, letter= 'A') 96 | make_plot(ax2, k.estm_x, k.estm_y, est_pots[:,:,tp], 97 | title='Estimated LFP', cmap='PRGn') 98 | # plt.suptitle(' $\lambda$ : '+str(k.lambd)+ ' R: '+ str(k.R)) 99 | plt.tight_layout() 100 | plt.savefig('figure_2D_pics', dpi=300) 101 | 102 | def do_kcsd(ele_pos_for_csd, pots_for_csd, ele_limit): 103 | ele_position = ele_pos_for_csd[:ele_limit[1]][0::1] 104 | csd_pots = pots_for_csd[:ele_limit[1]][0::1] 105 | k = KCSD2D(ele_position, csd_pots, n_src_init=5000, 106 | h=1, sigma=1, R_init=32, lambd=1e-9, 107 | xmin= -42, xmax=42, gdx=4, 108 | ymin=0, ymax=4000, gdy=4) 109 | # k.L_curve(Rs=np.linspace(16, 48, 3), lambdas=np.logspace(-9, -3, 20)) 110 | return k, k.values('CSD'), k.values('POT'), ele_position 111 | #%% 112 | if __name__ == '__main__': 113 | lowpass = 0.5 114 | highpass = 300 115 | Fs = 30000 116 | resamp = 12 117 | tp= 760 118 | 119 | forfilt=np.load('npx_data.npy') 120 | 121 | [b,a] = butter(3, [lowpass/(Fs/2.0), highpass/(Fs/2.0)] ,btype = 'bandpass') 122 | filtData = filtfilt(b,a, forfilt) 123 | pots_resamp = filtData[:,::resamp] 124 | pots = pots_resamp[:, :] 125 | Fs=int(Fs/resamp) 126 | 127 | pots_for_csd = np.delete(pots, 191, axis=0) 128 | ele_pos_def = eles_to_coords(np.arange(384,0,-1)) 129 | ele_pos_for_csd = np.delete(ele_pos_def, 191, axis=0) 130 | 131 | k, est_csd, est_pots, ele_pos = do_kcsd(ele_pos_for_csd, pots_for_csd, ele_limit = (0,330)) 132 | 133 | plot_1D_pics(k, est_csd, est_pots, tp, Fs, 15) 134 | plot_2D_pics(k, est_csd, est_pots, tp, Fs, cut=15) 135 | -------------------------------------------------------------------------------- /kcsd/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | kcsd_loc = os.path.dirname(os.path.abspath(__file__)) 3 | sample_data_path = os.path.join(kcsd_loc, 'data') 4 | 5 | from .KCSD import KCSD1D, KCSD2D, KCSD3D, MoIKCSD, oKCSD1D, oKCSD2D, oKCSD3D 6 | from .sKCSD import sKCSD, sKCSDcell 7 | from .validation import csd_profile 8 | from .validation.ValidateKCSD import ValidateKCSD, ValidateKCSD1D, ValidateKCSD2D, ValidateKCSD3D, SpectralStructure, ValidateMoIKCSD 9 | from .validation.VisibilityMap import VisibilityMap1D, VisibilityMap2D, VisibilityMap3D 10 | -------------------------------------------------------------------------------- /kcsd/basis_functions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | This script is used to generate basis sources for the 4 | kCSD method Jan et.al (2012) for 1D,2D and 3D cases. 5 | Two 'types' are described here, gaussian and step source, 6 | These can be easily extended. 7 | """ 8 | import numpy as np 9 | 10 | 11 | def gauss(d, stdev, dim): 12 | """Gaussian function 13 | 14 | Parameters 15 | ---------- 16 | d : floats or np.arrays 17 | Distance array to the point of evaluation 18 | stdev : float 19 | cutoff range 20 | dim : int 21 | dimension of the gaussian function 22 | 23 | Returns 24 | ------- 25 | Z : floats or np.arrays 26 | function evaluated 27 | 28 | """ 29 | Z = np.exp(-(d**2) / (2*stdev**2)) / (np.sqrt(2*np.pi)*stdev)**dim 30 | return Z 31 | 32 | 33 | def step_1D(d, R): 34 | """Returns normalized 1D step function. 35 | 36 | Parameters 37 | ---------- 38 | d : floats or np.arrays 39 | Distance array to the point of evaluation 40 | R : float 41 | cutoff range 42 | 43 | Returns 44 | ------- 45 | s : Value of the function (d <= R) / R 46 | 47 | """ 48 | s = (d <= R) 49 | s = s / R #normalize with width 50 | return s 51 | 52 | def gauss_1D(d, three_stdev): 53 | """Returns normalized gaussian 2D scale function 54 | 55 | Parameters 56 | ---------- 57 | d : floats or np.arrays 58 | Distance array to the point of evaluation 59 | three_stdev : float 60 | 3 * standard deviation of the distribution 61 | 62 | Returns 63 | ------- 64 | Z : (three_std/3)*(1/2*pi)*(exp(-0.5)*stddev**(-2) *(d**2)) 65 | 66 | """ 67 | stdev = three_stdev/3 68 | Z = gauss(d, stdev, 1) 69 | return Z 70 | 71 | 72 | def gauss_lim_1D(d, three_stdev): 73 | """Returns gausian 2D function cut off after 3 standard deviations. 74 | 75 | Parameters 76 | ---------- 77 | d : floats or np.arrays 78 | Distance array to the point of evaluation 79 | three_stdev : float 80 | 3 * standard deviation of the distribution 81 | 82 | Returns 83 | ------- 84 | Z : (three_std/3)*(1/2*pi)*(exp(-0.5)*stddev**(-2) *((x-mu)**2)), 85 | cut off = three_stdev 86 | 87 | """ 88 | Z = gauss_1D(d, three_stdev) 89 | Z *= (d < three_stdev) 90 | return Z 91 | 92 | 93 | def step_2D(d, R): 94 | """Returns normalized 2D step function. 95 | 96 | Parameters 97 | ---------- 98 | d : float or np.arrays 99 | Distance array to the point of evaluation 100 | R : float 101 | cutoff range 102 | 103 | Returns 104 | ------- 105 | s : step function 106 | 107 | """ 108 | s = (d <= R) / (np.pi*(R**2)) 109 | return s 110 | 111 | def gauss_2D(d, three_stdev): 112 | """Returns normalized gaussian 2D scale function 113 | 114 | Parameters 115 | ---------- 116 | d : floats or np.arrays 117 | distance at which we need the function evaluated 118 | three_stdev : float 119 | 3 * standard deviation of the distribution 120 | 121 | Returns 122 | ------- 123 | Z : function 124 | Normalized gaussian 2D function 125 | 126 | """ 127 | stdev = three_stdev/3 128 | Z = gauss(d, stdev, 2) 129 | return Z 130 | 131 | 132 | def gauss_lim_2D(d, three_stdev): 133 | """Returns gausian 2D function cut off after 3 standard deviations. 134 | 135 | Parameters 136 | ---------- 137 | d : floats or np.arrays 138 | distance at which we need the function evaluated 139 | three_stdev : float 140 | 3 * standard deviation of the distribution 141 | 142 | Returns 143 | ------- 144 | Z : function 145 | Normalized gaussian 2D function cut off after three_stdev 146 | 147 | """ 148 | Z = (d <= three_stdev)*gauss_2D(d, three_stdev) 149 | return Z 150 | 151 | 152 | def gauss_3D(d, three_stdev): 153 | """Returns normalized gaussian 3D scale function 154 | 155 | Parameters 156 | ---------- 157 | d : floats or np.arrays 158 | distance at which we need the function evaluated 159 | three_stdev : float 160 | 3 * standard deviation of the distribution 161 | 162 | Returns 163 | ------- 164 | Z : funtion 165 | Normalized gaussian 3D function 166 | 167 | """ 168 | stdev = three_stdev/3 169 | Z = gauss(d, stdev, 3) 170 | return Z 171 | 172 | 173 | def gauss_lim_3D(d, three_stdev): 174 | """Returns normalized gaussian 3D scale function cut off after 3stdev 175 | 176 | Parameters 177 | ---------- 178 | d : floats or np.arrays 179 | distance at which we need the function evaluated 180 | three_stdev : float 181 | 3 * standard deviation of the distribution 182 | 183 | Returns 184 | ------- 185 | Z : funtion 186 | Normalized gaussian 3D function cutoff three_Stdev 187 | 188 | """ 189 | Z = gauss_3D(d, three_stdev) 190 | Z = Z * (d < (three_stdev)) 191 | return Z 192 | 193 | 194 | def step_3D(d, R): 195 | """Returns normalized 3D step function. 196 | 197 | Parameters 198 | ---------- 199 | d : floats or np.arrays 200 | distance at which we need the function evaluated 201 | R : float 202 | cutoff range 203 | 204 | Returns 205 | ------- 206 | s : step function in 3D 207 | 208 | """ 209 | s = 3/(4*np.pi*R**3)*(d <= R) 210 | return s 211 | 212 | basis_1D = { 213 | "step": step_1D, 214 | "gauss": gauss_1D, 215 | "gauss_lim": gauss_lim_1D, 216 | } 217 | 218 | 219 | basis_2D = { 220 | "step": step_2D, 221 | "gauss": gauss_2D, 222 | "gauss_lim": gauss_lim_2D, 223 | } 224 | 225 | basis_3D = { 226 | "step": step_3D, 227 | "gauss": gauss_3D, 228 | "gauss_lim": gauss_lim_3D, 229 | } 230 | -------------------------------------------------------------------------------- /kcsd/data/ElcoordsDomi14.txt: -------------------------------------------------------------------------------- 1 | -918.319793756703 392.071582444667 5.0687610640665 2 | -880.978407236736 384.319062677909 5.12935689990195 3 | -839.828990783331 375.775950218092 5.19613222659749 4 | -795.777147374483 366.630259106525 5.26761747447451 5 | -745.47963929279 356.187893089572 5.34923789156912 6 | -702.889667700557 347.345704102885 5.41835088300717 7 | -655.739574044626 337.556779075244 5.49486382484111 8 | -608.118734686921 327.670121593128 5.5721406705341 9 | -560.802201953914 317.846641816581 5.64892370182992 10 | -510.401354123951 307.382821228285 5.73071181378015 11 | -467.083241685521 298.38946146758 5.8010063977431 12 | -374.237026823772 279.113473533937 5.95167284369034 13 | -326.640344834721 269.23183141133 6.0289104879481 14 | -227.105088957892 248.567118325172 6.19043159326985 15 | -------------------------------------------------------------------------------- /kcsd/data/Simple_with_branches/electrode_positions/elcoord_x_y_z: -------------------------------------------------------------------------------- 1 | -600 2 | -400 3 | -200 4 | 0 5 | 200 6 | 400 7 | 600 8 | -600 9 | -400 10 | -200 11 | 0 12 | 200 13 | 400 14 | 600 15 | -600 16 | -400 17 | -200 18 | 0 19 | 200 20 | 400 21 | 600 22 | -600 23 | -400 24 | -200 25 | 0 26 | 200 27 | 400 28 | 600 29 | -600 30 | -400 31 | -200 32 | 0 33 | 200 34 | 400 35 | 600 36 | -600 37 | -400 38 | -200 39 | 0 40 | 200 41 | 400 42 | 600 43 | -600 44 | -400 45 | -200 46 | 0 47 | 200 48 | 400 49 | 600 50 | -600 51 | -600 52 | -600 53 | -600 54 | -600 55 | -600 56 | -600 57 | -400 58 | -400 59 | -400 60 | -400 61 | -400 62 | -400 63 | -400 64 | -200 65 | -200 66 | -200 67 | -200 68 | -200 69 | -200 70 | -200 71 | 0 72 | 0 73 | 0 74 | 0 75 | 0 76 | 0 77 | 0 78 | 200 79 | 200 80 | 200 81 | 200 82 | 200 83 | 200 84 | 200 85 | 400 86 | 400 87 | 400 88 | 400 89 | 400 90 | 400 91 | 400 92 | 600 93 | 600 94 | 600 95 | 600 96 | 600 97 | 600 98 | 600 99 | -20 100 | -20 101 | -20 102 | -20 103 | -20 104 | -20 105 | -20 106 | -20 107 | -20 108 | -20 109 | -20 110 | -20 111 | -20 112 | -20 113 | -20 114 | -20 115 | -20 116 | -20 117 | -20 118 | -20 119 | -20 120 | -20 121 | -20 122 | -20 123 | -20 124 | -20 125 | -20 126 | -20 127 | -20 128 | -20 129 | -20 130 | -20 131 | -20 132 | -20 133 | -20 134 | -20 135 | -20 136 | -20 137 | -20 138 | -20 139 | -20 140 | -20 141 | -20 142 | -20 143 | -20 144 | -20 145 | -20 146 | -20 147 | -20 148 | -------------------------------------------------------------------------------- /kcsd/data/Simple_with_branches/morphology/Badea2011Fig2Du.CNG.swc: -------------------------------------------------------------------------------- 1 | 1 1 0.0 0.0 0.0 11.543 -1 2 | 2 1 1.55 -1.41 3.12 17.815 1 3 | 3 1 3.21 -6.72 6.25 21.708 2 4 | 4 1 1.6 -7.45 9.37 17.62 3 5 | 5 1 1.73 -8.42 12.5 17.948 4 6 | 6 1 2.14 -9.52 15.62 19.036 5 7 | 7 1 2.47 -10.41 18.75 19.667 6 8 | 8 1 20.29 -11.05 12.5 16.01 3 9 | 9 1 34.53 -15.34 12.5 7.5932 8 10 | 10 3 6.04 0.09 20.48 1.5207 1 11 | 11 3 8.82 6.29 25.0 1.8409 10 12 | 12 3 11.01 12.43 28.12 1.6667 11 13 | 13 3 11.99 16.46 28.12 1.2304 12 14 | 14 3 11.69 19.87 31.25 1.2304 13 15 | 15 3 11.11 21.86 34.37 1.1335 14 16 | 16 3 10.98 25.03 34.37 1.118 15 17 | 17 3 9.59 28.66 34.37 1.9185 16 18 | 18 3 7.46 32.71 34.37 1.8276 17 19 | 19 3 5.08 36.78 34.37 0.94282 18 20 | 20 3 3.67 39.14 37.5 0.79057 19 21 | 21 3 1.52 40.65 37.5 1.0833 20 22 | 22 3 -0.86 42.26 37.5 1.0961 21 23 | 23 3 -2.92 44.18 37.5 1.3437 22 -------------------------------------------------------------------------------- /kcsd/data/Y_shaped_neuron/electrode_positions/elcoord_x_y_x: -------------------------------------------------------------------------------- 1 | -2.000000000000000000e+02 2 | -2.000000000000000000e+02 3 | -2.000000000000000000e+02 4 | -2.000000000000000000e+02 5 | -1.733333333333333428e+02 6 | -1.733333333333333428e+02 7 | -1.733333333333333428e+02 8 | -1.733333333333333428e+02 9 | -1.466666666666666572e+02 10 | -1.466666666666666572e+02 11 | -1.466666666666666572e+02 12 | -1.466666666666666572e+02 13 | -1.200000000000000000e+02 14 | -1.200000000000000000e+02 15 | -1.200000000000000000e+02 16 | -1.200000000000000000e+02 17 | -9.333333333333332860e+01 18 | -9.333333333333332860e+01 19 | -9.333333333333332860e+01 20 | -9.333333333333332860e+01 21 | -6.666666666666665719e+01 22 | -6.666666666666665719e+01 23 | -6.666666666666665719e+01 24 | -6.666666666666665719e+01 25 | -4.000000000000000000e+01 26 | -4.000000000000000000e+01 27 | -4.000000000000000000e+01 28 | -4.000000000000000000e+01 29 | -1.333333333333331439e+01 30 | -1.333333333333331439e+01 31 | -1.333333333333331439e+01 32 | -1.333333333333331439e+01 33 | 1.333333333333334281e+01 34 | 1.333333333333334281e+01 35 | 1.333333333333334281e+01 36 | 1.333333333333334281e+01 37 | 4.000000000000000000e+01 38 | 4.000000000000000000e+01 39 | 4.000000000000000000e+01 40 | 4.000000000000000000e+01 41 | 6.666666666666668561e+01 42 | 6.666666666666668561e+01 43 | 6.666666666666668561e+01 44 | 6.666666666666668561e+01 45 | 9.333333333333337123e+01 46 | 9.333333333333337123e+01 47 | 9.333333333333337123e+01 48 | 9.333333333333337123e+01 49 | 1.200000000000000000e+02 50 | 1.200000000000000000e+02 51 | 1.200000000000000000e+02 52 | 1.200000000000000000e+02 53 | 1.466666666666666856e+02 54 | 1.466666666666666856e+02 55 | 1.466666666666666856e+02 56 | 1.466666666666666856e+02 57 | 1.733333333333333712e+02 58 | 1.733333333333333712e+02 59 | 1.733333333333333712e+02 60 | 1.733333333333333712e+02 61 | 2.000000000000000000e+02 62 | 2.000000000000000000e+02 63 | 2.000000000000000000e+02 64 | 2.000000000000000000e+02 65 | 5.000000000000000000e+01 66 | 5.000000000000000000e+01 67 | 5.000000000000000000e+01 68 | 5.000000000000000000e+01 69 | 5.000000000000000000e+01 70 | 5.000000000000000000e+01 71 | 5.000000000000000000e+01 72 | 5.000000000000000000e+01 73 | 5.000000000000000000e+01 74 | 5.000000000000000000e+01 75 | 5.000000000000000000e+01 76 | 5.000000000000000000e+01 77 | 5.000000000000000000e+01 78 | 5.000000000000000000e+01 79 | 5.000000000000000000e+01 80 | 5.000000000000000000e+01 81 | 5.000000000000000000e+01 82 | 5.000000000000000000e+01 83 | 5.000000000000000000e+01 84 | 5.000000000000000000e+01 85 | 5.000000000000000000e+01 86 | 5.000000000000000000e+01 87 | 5.000000000000000000e+01 88 | 5.000000000000000000e+01 89 | 5.000000000000000000e+01 90 | 5.000000000000000000e+01 91 | 5.000000000000000000e+01 92 | 5.000000000000000000e+01 93 | 5.000000000000000000e+01 94 | 5.000000000000000000e+01 95 | 5.000000000000000000e+01 96 | 5.000000000000000000e+01 97 | 5.000000000000000000e+01 98 | 5.000000000000000000e+01 99 | 5.000000000000000000e+01 100 | 5.000000000000000000e+01 101 | 5.000000000000000000e+01 102 | 5.000000000000000000e+01 103 | 5.000000000000000000e+01 104 | 5.000000000000000000e+01 105 | 5.000000000000000000e+01 106 | 5.000000000000000000e+01 107 | 5.000000000000000000e+01 108 | 5.000000000000000000e+01 109 | 5.000000000000000000e+01 110 | 5.000000000000000000e+01 111 | 5.000000000000000000e+01 112 | 5.000000000000000000e+01 113 | 5.000000000000000000e+01 114 | 5.000000000000000000e+01 115 | 5.000000000000000000e+01 116 | 5.000000000000000000e+01 117 | 5.000000000000000000e+01 118 | 5.000000000000000000e+01 119 | 5.000000000000000000e+01 120 | 5.000000000000000000e+01 121 | 5.000000000000000000e+01 122 | 5.000000000000000000e+01 123 | 5.000000000000000000e+01 124 | 5.000000000000000000e+01 125 | 5.000000000000000000e+01 126 | 5.000000000000000000e+01 127 | 5.000000000000000000e+01 128 | 5.000000000000000000e+01 129 | -2.000000000000000000e+02 130 | 6.666666666666668561e+01 131 | 3.333333333333333712e+02 132 | 6.000000000000000000e+02 133 | -2.000000000000000000e+02 134 | 6.666666666666668561e+01 135 | 3.333333333333333712e+02 136 | 6.000000000000000000e+02 137 | -2.000000000000000000e+02 138 | 6.666666666666668561e+01 139 | 3.333333333333333712e+02 140 | 6.000000000000000000e+02 141 | -2.000000000000000000e+02 142 | 6.666666666666668561e+01 143 | 3.333333333333333712e+02 144 | 6.000000000000000000e+02 145 | -2.000000000000000000e+02 146 | 6.666666666666668561e+01 147 | 3.333333333333333712e+02 148 | 6.000000000000000000e+02 149 | -2.000000000000000000e+02 150 | 6.666666666666668561e+01 151 | 3.333333333333333712e+02 152 | 6.000000000000000000e+02 153 | -2.000000000000000000e+02 154 | 6.666666666666668561e+01 155 | 3.333333333333333712e+02 156 | 6.000000000000000000e+02 157 | -2.000000000000000000e+02 158 | 6.666666666666668561e+01 159 | 3.333333333333333712e+02 160 | 6.000000000000000000e+02 161 | -2.000000000000000000e+02 162 | 6.666666666666668561e+01 163 | 3.333333333333333712e+02 164 | 6.000000000000000000e+02 165 | -2.000000000000000000e+02 166 | 6.666666666666668561e+01 167 | 3.333333333333333712e+02 168 | 6.000000000000000000e+02 169 | -2.000000000000000000e+02 170 | 6.666666666666668561e+01 171 | 3.333333333333333712e+02 172 | 6.000000000000000000e+02 173 | -2.000000000000000000e+02 174 | 6.666666666666668561e+01 175 | 3.333333333333333712e+02 176 | 6.000000000000000000e+02 177 | -2.000000000000000000e+02 178 | 6.666666666666668561e+01 179 | 3.333333333333333712e+02 180 | 6.000000000000000000e+02 181 | -2.000000000000000000e+02 182 | 6.666666666666668561e+01 183 | 3.333333333333333712e+02 184 | 6.000000000000000000e+02 185 | -2.000000000000000000e+02 186 | 6.666666666666668561e+01 187 | 3.333333333333333712e+02 188 | 6.000000000000000000e+02 189 | -2.000000000000000000e+02 190 | 6.666666666666668561e+01 191 | 3.333333333333333712e+02 192 | 6.000000000000000000e+02 193 | -------------------------------------------------------------------------------- /kcsd/data/Y_shaped_neuron/morphology/Y_shaped.swc: -------------------------------------------------------------------------------- 1 | 1 1 0.00 0.00 -9.85 9.86 -1 2 | 2 1 0.00 0.00 0.00 9.86 1 3 | 3 1 0.00 0.00 9.85 9.86 2 4 | 4 3 0.00 0.00 19.66 2.00 3 5 | 5 3 0.00 0.00 29.47 2.00 4 6 | 6 3 0.00 0.00 39.28 2.00 5 7 | 7 3 0.00 0.00 49.09 2.00 6 8 | 8 3 0.00 0.00 58.89 2.00 7 9 | 9 3 0.00 0.00 68.70 2.00 8 10 | 10 3 0.00 0.00 78.51 2.00 9 11 | 11 3 0.00 0.00 88.32 2.00 10 12 | 12 3 0.00 0.00 98.13 2.00 11 13 | 13 3 0.00 0.00 107.93 2.00 12 14 | 14 3 0.00 0.00 117.74 2.00 13 15 | 15 3 0.00 0.00 127.55 2.00 14 16 | 16 3 0.00 0.00 137.36 2.00 15 17 | 17 3 0.00 0.00 147.17 2.00 16 18 | 18 3 0.00 0.00 156.97 2.00 17 19 | 19 3 0.00 0.00 166.78 2.00 18 20 | 20 3 0.00 0.00 176.59 2.00 19 21 | 21 3 0.00 0.00 186.40 2.00 20 22 | 22 3 0.00 0.00 196.21 2.00 21 23 | 23 3 0.00 0.00 206.01 2.00 22 24 | 24 3 3.12 0.00 215.39 2.00 23 25 | 25 3 6.25 0.00 224.76 2.00 24 26 | 26 3 9.38 0.00 234.14 2.00 25 27 | 27 3 12.50 0.00 243.51 2.00 26 28 | 28 3 15.62 0.00 252.89 2.00 27 29 | 29 3 18.75 0.00 262.26 2.00 28 30 | 30 3 21.88 0.00 271.64 2.00 29 31 | 31 3 25.00 0.00 281.01 2.00 30 32 | 32 3 28.12 0.00 290.39 2.00 31 33 | 33 3 31.25 0.00 299.76 2.00 32 34 | 34 3 34.38 0.00 309.14 2.00 33 35 | 35 3 37.50 0.00 318.51 2.00 34 36 | 36 3 40.62 0.00 327.89 2.00 35 37 | 37 3 43.75 0.00 337.26 2.00 36 38 | 38 3 46.88 0.00 346.64 2.00 37 39 | 39 3 50.00 0.00 356.01 2.00 38 40 | 40 3 53.12 0.00 365.39 2.00 39 41 | 41 3 56.25 0.00 374.76 2.00 40 42 | 42 3 59.38 0.00 384.14 2.00 41 43 | 43 3 62.50 0.00 393.51 2.00 42 44 | 44 3 65.62 0.00 402.89 2.00 43 45 | 45 3 68.75 0.00 412.26 2.00 44 46 | 46 3 71.88 0.00 421.64 2.00 45 47 | 47 3 75.00 0.00 431.01 2.00 46 48 | 48 3 78.12 0.00 440.39 2.00 47 49 | 49 3 81.25 0.00 449.76 2.00 48 50 | 50 3 84.38 0.00 459.14 2.00 49 51 | 51 3 87.50 0.00 468.51 2.00 50 52 | 52 3 90.62 0.00 477.89 2.00 51 53 | 53 3 93.75 0.00 487.26 2.00 52 54 | 54 3 96.88 0.00 496.64 2.00 53 55 | 55 3 100.00 0.00 506.01 2.00 54 56 | 56 3 -3.12 0.00 215.39 2.00 23 57 | 57 3 -6.25 0.00 224.76 2.00 56 58 | 58 3 -9.38 0.00 234.14 2.00 57 59 | 59 3 -12.50 0.00 243.51 2.00 58 60 | 60 3 -15.62 0.00 252.89 2.00 59 61 | 61 3 -18.75 0.00 262.26 2.00 60 62 | 62 3 -21.88 0.00 271.64 2.00 61 63 | 63 3 -25.00 0.00 281.01 2.00 62 64 | 64 3 -28.12 0.00 290.39 2.00 63 65 | 65 3 -31.25 0.00 299.76 2.00 64 66 | 66 3 -34.38 0.00 309.14 2.00 65 67 | 67 3 -37.50 0.00 318.51 2.00 66 68 | 68 3 -40.62 0.00 327.89 2.00 67 69 | 69 3 -43.75 0.00 337.26 2.00 68 70 | 70 3 -46.88 0.00 346.64 2.00 69 71 | 71 3 -50.00 0.00 356.01 2.00 70 72 | 72 3 -53.12 0.00 365.39 2.00 71 73 | 73 3 -56.25 0.00 374.76 2.00 72 74 | 74 3 -59.38 0.00 384.14 2.00 73 75 | 75 3 -62.50 0.00 393.51 2.00 74 76 | 76 3 -65.62 0.00 402.89 2.00 75 77 | 77 3 -68.75 0.00 412.26 2.00 76 78 | 78 3 -71.88 0.00 421.64 2.00 77 79 | 79 3 -75.00 0.00 431.01 2.00 78 80 | 80 3 -78.12 0.00 440.39 2.00 79 81 | 81 3 -81.25 0.00 449.76 2.00 80 82 | 82 3 -84.38 0.00 459.14 2.00 81 83 | 83 3 -87.50 0.00 468.51 2.00 82 84 | 84 3 -90.62 0.00 477.89 2.00 83 85 | 85 3 -93.75 0.00 487.26 2.00 84 86 | 86 3 -96.88 0.00 496.64 2.00 85 87 | 87 3 -100.00 0.00 506.01 2.00 86 88 | -------------------------------------------------------------------------------- /kcsd/data/ball_and_stick_128/electrode_positions/elcoord_x_y_z: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 0 32 | 0 33 | 0 34 | 0 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 0 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | 0 66 | 0 67 | 0 68 | 0 69 | 0 70 | 0 71 | 0 72 | 0 73 | 0 74 | 0 75 | 0 76 | 0 77 | 0 78 | 0 79 | 0 80 | 0 81 | 0 82 | 0 83 | 0 84 | 0 85 | 0 86 | 0 87 | 0 88 | 0 89 | 0 90 | 0 91 | 0 92 | 0 93 | 0 94 | 0 95 | 0 96 | 0 97 | 0 98 | 0 99 | 0 100 | 0 101 | 0 102 | 0 103 | 0 104 | 0 105 | 0 106 | 0 107 | 0 108 | 0 109 | 0 110 | 0 111 | 0 112 | 0 113 | 0 114 | 0 115 | 0 116 | 0 117 | 0 118 | 0 119 | 0 120 | 0 121 | 0 122 | 0 123 | 0 124 | 0 125 | 0 126 | 0 127 | 0 128 | 0 129 | 50 130 | 50 131 | 50 132 | 50 133 | 50 134 | 50 135 | 50 136 | 50 137 | 50 138 | 50 139 | 50 140 | 50 141 | 50 142 | 50 143 | 50 144 | 50 145 | 50 146 | 50 147 | 50 148 | 50 149 | 50 150 | 50 151 | 50 152 | 50 153 | 50 154 | 50 155 | 50 156 | 50 157 | 50 158 | 50 159 | 50 160 | 50 161 | 50 162 | 50 163 | 50 164 | 50 165 | 50 166 | 50 167 | 50 168 | 50 169 | 50 170 | 50 171 | 50 172 | 50 173 | 50 174 | 50 175 | 50 176 | 50 177 | 50 178 | 50 179 | 50 180 | 50 181 | 50 182 | 50 183 | 50 184 | 50 185 | 50 186 | 50 187 | 50 188 | 50 189 | 50 190 | 50 191 | 50 192 | 50 193 | 50 194 | 50 195 | 50 196 | 50 197 | 50 198 | 50 199 | 50 200 | 50 201 | 50 202 | 50 203 | 50 204 | 50 205 | 50 206 | 50 207 | 50 208 | 50 209 | 50 210 | 50 211 | 50 212 | 50 213 | 50 214 | 50 215 | 50 216 | 50 217 | 50 218 | 50 219 | 50 220 | 50 221 | 50 222 | 50 223 | 50 224 | 50 225 | 50 226 | 50 227 | 50 228 | 50 229 | 50 230 | 50 231 | 50 232 | 50 233 | 50 234 | 50 235 | 50 236 | 50 237 | 50 238 | 50 239 | 50 240 | 50 241 | 50 242 | 50 243 | 50 244 | 50 245 | 50 246 | 50 247 | 50 248 | 50 249 | 50 250 | 50 251 | 50 252 | 50 253 | 50 254 | 50 255 | 50 256 | 50 257 | -100 258 | -94.488188976378 259 | -88.9763779527559 260 | -83.4645669291339 261 | -77.9527559055118 262 | -72.4409448818898 263 | -66.9291338582677 264 | -61.4173228346457 265 | -55.9055118110236 266 | -50.3937007874016 267 | -44.8818897637795 268 | -39.3700787401575 269 | -33.8582677165354 270 | -28.3464566929134 271 | -22.8346456692913 272 | -17.3228346456693 273 | -11.8110236220472 274 | -6.2992125984252 275 | -0.787401574803155 276 | 4.7244094488189 277 | 10.2362204724409 278 | 15.748031496063 279 | 21.259842519685 280 | 26.7716535433071 281 | 32.2834645669291 282 | 37.7952755905512 283 | 43.3070866141732 284 | 48.8188976377953 285 | 54.3307086614173 286 | 59.8425196850394 287 | 65.3543307086614 288 | 70.8661417322835 289 | 76.3779527559055 290 | 81.8897637795276 291 | 87.4015748031496 292 | 92.9133858267716 293 | 98.4251968503937 294 | 103.937007874016 295 | 109.448818897638 296 | 114.96062992126 297 | 120.472440944882 298 | 125.984251968504 299 | 131.496062992126 300 | 137.007874015748 301 | 142.51968503937 302 | 148.031496062992 303 | 153.543307086614 304 | 159.055118110236 305 | 164.566929133858 306 | 170.07874015748 307 | 175.590551181102 308 | 181.102362204724 309 | 186.614173228346 310 | 192.125984251968 311 | 197.637795275591 312 | 203.149606299213 313 | 208.661417322835 314 | 214.173228346457 315 | 219.685039370079 316 | 225.196850393701 317 | 230.708661417323 318 | 236.220472440945 319 | 241.732283464567 320 | 247.244094488189 321 | 252.755905511811 322 | 258.267716535433 323 | 263.779527559055 324 | 269.291338582677 325 | 274.803149606299 326 | 280.314960629921 327 | 285.826771653543 328 | 291.338582677165 329 | 296.850393700787 330 | 302.362204724409 331 | 307.874015748031 332 | 313.385826771654 333 | 318.897637795276 334 | 324.409448818898 335 | 329.92125984252 336 | 335.433070866142 337 | 340.944881889764 338 | 346.456692913386 339 | 351.968503937008 340 | 357.48031496063 341 | 362.992125984252 342 | 368.503937007874 343 | 374.015748031496 344 | 379.527559055118 345 | 385.03937007874 346 | 390.551181102362 347 | 396.062992125984 348 | 401.574803149606 349 | 407.086614173228 350 | 412.59842519685 351 | 418.110236220472 352 | 423.622047244094 353 | 429.133858267717 354 | 434.645669291339 355 | 440.157480314961 356 | 445.669291338583 357 | 451.181102362205 358 | 456.692913385827 359 | 462.204724409449 360 | 467.716535433071 361 | 473.228346456693 362 | 478.740157480315 363 | 484.251968503937 364 | 489.763779527559 365 | 495.275590551181 366 | 500.787401574803 367 | 506.299212598425 368 | 511.811023622047 369 | 517.322834645669 370 | 522.834645669291 371 | 528.346456692913 372 | 533.858267716535 373 | 539.370078740158 374 | 544.88188976378 375 | 550.393700787402 376 | 555.905511811024 377 | 561.417322834646 378 | 566.929133858268 379 | 572.44094488189 380 | 577.952755905512 381 | 583.464566929134 382 | 588.976377952756 383 | 594.488188976378 384 | 600 385 | -------------------------------------------------------------------------------- /kcsd/data/ball_and_stick_128/morphology/ball_and_stick.swc: -------------------------------------------------------------------------------- 1 | 1 1 0 0 -1.08250027894974 1.972200012207031250e+01 -1 2 | 2 1 0 0 -10.9375001788139 1.972200012207031250e+01 1 3 | 3 2 0 0 8.80409979343414 4.000000000000000000e+00 1 4 | 4 2 0 0 18.7272997951508 4.000000000000000000e+00 3 5 | 5 2 0 0 28.6504997968674 4.000000000000000000e+00 4 6 | 6 2 0 0 38.573699798584 4.000000000000000000e+00 5 7 | 7 2 0 0 48.4968998003006 4.000000000000000000e+00 6 8 | 8 2 0 0 58.4200998020172 4.000000000000000000e+00 7 9 | 9 2 0 0 68.3432998037338 4.000000000000000000e+00 8 10 | 10 2 0 0 78.2664998054505 4.000000000000000000e+00 9 11 | 11 2 0 0 88.189699807167 4.000000000000000000e+00 10 12 | 12 2 0 0 98.1128998088837 4.000000000000000000e+00 11 13 | 13 2 0 0 108.0360998106 4.000000000000000000e+00 12 14 | 14 2 0 0 117.959299812317 4.000000000000000000e+00 13 15 | 15 2 0 0 127.882499814034 4.000000000000000000e+00 14 16 | 16 2 0 0 137.80569981575 4.000000000000000000e+00 15 17 | 17 2 0 0 147.728899817467 4.000000000000000000e+00 16 18 | 18 2 0 0 157.652099819183 4.000000000000000000e+00 17 19 | 19 2 0 0 167.5752998209 4.000000000000000000e+00 18 20 | 20 2 0 0 177.498499822617 4.000000000000000000e+00 19 21 | 21 2 0 0 187.421699824333 4.000000000000000000e+00 20 22 | 22 2 0 0 197.34489982605 4.000000000000000000e+00 21 23 | 23 2 0 0 207.268099827766 4.000000000000000000e+00 22 24 | 24 2 0 0 217.191299829483 4.000000000000000000e+00 23 25 | 25 2 0 0 227.1144998312 4.000000000000000000e+00 24 26 | 26 2 0 0 237.037699832916 4.000000000000000000e+00 25 27 | 27 2 0 0 246.960899834633 4.000000000000000000e+00 26 28 | 28 2 0 0 256.884099836349 4.000000000000000000e+00 27 29 | 29 2 0 0 266.807299838066 4.000000000000000000e+00 28 30 | 30 2 0 0 276.730499839783 4.000000000000000000e+00 29 31 | 31 2 0 0 286.653699841499 4.000000000000000000e+00 30 32 | 32 2 0 0 296.576899843216 4.000000000000000000e+00 31 33 | 33 2 0 0 306.500099844933 4.000000000000000000e+00 32 34 | 34 2 0 0 316.423299846649 4.000000000000000000e+00 33 35 | 35 2 0 0 326.346499848366 4.000000000000000000e+00 34 36 | 36 2 0 0 336.269699850082 4.000000000000000000e+00 35 37 | 37 2 0 0 346.192899851799 4.000000000000000000e+00 36 38 | 38 2 0 0 356.116099853516 4.000000000000000000e+00 37 39 | 39 2 0 0 366.039299855232 4.000000000000000000e+00 38 40 | 40 2 0 0 375.962499856949 4.000000000000000000e+00 39 41 | 41 2 0 0 385.885699858665 4.000000000000000000e+00 40 42 | 42 2 0 0 395.808899860382 4.000000000000000000e+00 41 43 | 43 2 0 0 405.732099862099 4.000000000000000000e+00 42 44 | 44 2 0 0 415.655299863815 4.000000000000000000e+00 43 45 | 45 2 0 0 425.578499865532 4.000000000000000000e+00 44 46 | 46 2 0 0 435.501699867249 4.000000000000000000e+00 45 47 | 47 2 0 0 445.424899868965 4.000000000000000000e+00 46 48 | 48 2 0 0 455.348099870682 4.000000000000000000e+00 47 49 | 49 2 0 0 465.271299872398 4.000000000000000000e+00 48 50 | 50 2 0 0 475.194499874115 4.000000000000000000e+00 49 51 | 51 2 0 0 485.117699875832 4.000000000000000000e+00 50 52 | 52 2 0 0 495.040899877548 4.000000000000000000e+00 51 53 | -------------------------------------------------------------------------------- /kcsd/data/ball_and_stick_16/electrode_positions/elcoord_x_y_z: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 50 18 | 50 19 | 50 20 | 50 21 | 50 22 | 50 23 | 50 24 | 50 25 | 50 26 | 50 27 | 50 28 | 50 29 | 50 30 | 50 31 | 50 32 | 50 33 | -100 34 | -53.3333333333333 35 | -6.66666666666667 36 | 40 37 | 86.6666666666667 38 | 133.333333333333 39 | 180 40 | 226.666666666667 41 | 273.333333333333 42 | 320 43 | 366.666666666667 44 | 413.333333333333 45 | 460 46 | 506.666666666667 47 | 553.333333333333 48 | 600 49 | -------------------------------------------------------------------------------- /kcsd/data/ball_and_stick_16/morphology/ball_and_stick.swc: -------------------------------------------------------------------------------- 1 | 1 1 0 0 -1.08250027894974 1.972200012207031250e+01 -1 2 | 2 1 0 0 -10.9375001788139 1.972200012207031250e+01 1 3 | 3 2 0 0 8.80409979343414 4.000000000000000000e+00 1 4 | 4 2 0 0 18.7272997951508 4.000000000000000000e+00 3 5 | 5 2 0 0 28.6504997968674 4.000000000000000000e+00 4 6 | 6 2 0 0 38.573699798584 4.000000000000000000e+00 5 7 | 7 2 0 0 48.4968998003006 4.000000000000000000e+00 6 8 | 8 2 0 0 58.4200998020172 4.000000000000000000e+00 7 9 | 9 2 0 0 68.3432998037338 4.000000000000000000e+00 8 10 | 10 2 0 0 78.2664998054505 4.000000000000000000e+00 9 11 | 11 2 0 0 88.189699807167 4.000000000000000000e+00 10 12 | 12 2 0 0 98.1128998088837 4.000000000000000000e+00 11 13 | 13 2 0 0 108.0360998106 4.000000000000000000e+00 12 14 | 14 2 0 0 117.959299812317 4.000000000000000000e+00 13 15 | 15 2 0 0 127.882499814034 4.000000000000000000e+00 14 16 | 16 2 0 0 137.80569981575 4.000000000000000000e+00 15 17 | 17 2 0 0 147.728899817467 4.000000000000000000e+00 16 18 | 18 2 0 0 157.652099819183 4.000000000000000000e+00 17 19 | 19 2 0 0 167.5752998209 4.000000000000000000e+00 18 20 | 20 2 0 0 177.498499822617 4.000000000000000000e+00 19 21 | 21 2 0 0 187.421699824333 4.000000000000000000e+00 20 22 | 22 2 0 0 197.34489982605 4.000000000000000000e+00 21 23 | 23 2 0 0 207.268099827766 4.000000000000000000e+00 22 24 | 24 2 0 0 217.191299829483 4.000000000000000000e+00 23 25 | 25 2 0 0 227.1144998312 4.000000000000000000e+00 24 26 | 26 2 0 0 237.037699832916 4.000000000000000000e+00 25 27 | 27 2 0 0 246.960899834633 4.000000000000000000e+00 26 28 | 28 2 0 0 256.884099836349 4.000000000000000000e+00 27 29 | 29 2 0 0 266.807299838066 4.000000000000000000e+00 28 30 | 30 2 0 0 276.730499839783 4.000000000000000000e+00 29 31 | 31 2 0 0 286.653699841499 4.000000000000000000e+00 30 32 | 32 2 0 0 296.576899843216 4.000000000000000000e+00 31 33 | 33 2 0 0 306.500099844933 4.000000000000000000e+00 32 34 | 34 2 0 0 316.423299846649 4.000000000000000000e+00 33 35 | 35 2 0 0 326.346499848366 4.000000000000000000e+00 34 36 | 36 2 0 0 336.269699850082 4.000000000000000000e+00 35 37 | 37 2 0 0 346.192899851799 4.000000000000000000e+00 36 38 | 38 2 0 0 356.116099853516 4.000000000000000000e+00 37 39 | 39 2 0 0 366.039299855232 4.000000000000000000e+00 38 40 | 40 2 0 0 375.962499856949 4.000000000000000000e+00 39 41 | 41 2 0 0 385.885699858665 4.000000000000000000e+00 40 42 | 42 2 0 0 395.808899860382 4.000000000000000000e+00 41 43 | 43 2 0 0 405.732099862099 4.000000000000000000e+00 42 44 | 44 2 0 0 415.655299863815 4.000000000000000000e+00 43 45 | 45 2 0 0 425.578499865532 4.000000000000000000e+00 44 46 | 46 2 0 0 435.501699867249 4.000000000000000000e+00 45 47 | 47 2 0 0 445.424899868965 4.000000000000000000e+00 46 48 | 48 2 0 0 455.348099870682 4.000000000000000000e+00 47 49 | 49 2 0 0 465.271299872398 4.000000000000000000e+00 48 50 | 50 2 0 0 475.194499874115 4.000000000000000000e+00 49 51 | 51 2 0 0 485.117699875832 4.000000000000000000e+00 50 52 | 52 2 0 0 495.040899877548 4.000000000000000000e+00 51 53 | -------------------------------------------------------------------------------- /kcsd/data/ball_and_stick_8/electrode_positions/elcoord_x_y_x: -------------------------------------------------------------------------------- 1 | 0.000000000000000000e+00 2 | 0.000000000000000000e+00 3 | 0.000000000000000000e+00 4 | 0.000000000000000000e+00 5 | 0.000000000000000000e+00 6 | 0.000000000000000000e+00 7 | 0.000000000000000000e+00 8 | 0.000000000000000000e+00 9 | 5.000000000000000000e+01 10 | 5.000000000000000000e+01 11 | 5.000000000000000000e+01 12 | 5.000000000000000000e+01 13 | 5.000000000000000000e+01 14 | 5.000000000000000000e+01 15 | 5.000000000000000000e+01 16 | 5.000000000000000000e+01 17 | -1.000000000000000000e+02 18 | 0.000000000000000000e+00 19 | 1.000000000000000000e+02 20 | 2.000000000000000000e+02 21 | 3.000000000000000000e+02 22 | 4.000000000000000000e+02 23 | 5.000000000000000000e+02 24 | 6.000000000000000000e+02 25 | -------------------------------------------------------------------------------- /kcsd/data/ball_and_stick_8/morphology/Figure_2_rows_8.swc: -------------------------------------------------------------------------------- 1 | 1 1 0.00 0.00 -9.86 9.86 -1 2 | 2 1 0.00 0.00 0.00 9.86 1 3 | 3 1 0.00 0.00 9.86 9.86 2 4 | 4 3 0.00 0.00 19.67 2.00 3 5 | 5 3 0.00 0.00 29.47 2.00 4 6 | 6 3 0.00 0.00 39.28 2.00 5 7 | 7 3 0.00 0.00 49.08 2.00 6 8 | 8 3 0.00 0.00 58.89 2.00 7 9 | 9 3 0.00 0.00 68.69 2.00 8 10 | 10 3 0.00 0.00 78.50 2.00 9 11 | 11 3 0.00 0.00 88.31 2.00 10 12 | 12 3 0.00 0.00 98.11 2.00 11 13 | 13 3 0.00 0.00 107.92 2.00 12 14 | 14 3 0.00 0.00 117.72 2.00 13 15 | 15 3 0.00 0.00 127.53 2.00 14 16 | 16 3 0.00 0.00 137.33 2.00 15 17 | 17 3 0.00 0.00 147.14 2.00 16 18 | 18 3 0.00 0.00 156.94 2.00 17 19 | 19 3 0.00 0.00 166.75 2.00 18 20 | 20 3 0.00 0.00 176.56 2.00 19 21 | 21 3 0.00 0.00 186.36 2.00 20 22 | 22 3 0.00 0.00 196.17 2.00 21 23 | 23 3 0.00 0.00 205.97 2.00 22 24 | 24 3 0.00 0.00 215.78 2.00 23 25 | 25 3 0.00 0.00 225.58 2.00 24 26 | 26 3 0.00 0.00 235.39 2.00 25 27 | 27 3 0.00 0.00 245.19 2.00 26 28 | 28 3 0.00 0.00 255.00 2.00 27 29 | 29 3 0.00 0.00 264.81 2.00 28 30 | 30 3 0.00 0.00 274.61 2.00 29 31 | 31 3 0.00 0.00 284.42 2.00 30 32 | 32 3 0.00 0.00 294.22 2.00 31 33 | 33 3 0.00 0.00 304.03 2.00 32 34 | 34 3 0.00 0.00 313.83 2.00 33 35 | 35 3 0.00 0.00 323.64 2.00 34 36 | 36 3 0.00 0.00 333.44 2.00 35 37 | 37 3 0.00 0.00 343.25 2.00 36 38 | 38 3 0.00 0.00 353.06 2.00 37 39 | 39 3 0.00 0.00 362.86 2.00 38 40 | 40 3 0.00 0.00 372.67 2.00 39 41 | 41 3 0.00 0.00 382.47 2.00 40 42 | 42 3 0.00 0.00 392.28 2.00 41 43 | 43 3 0.00 0.00 402.08 2.00 42 44 | 44 3 0.00 0.00 411.89 2.00 43 45 | 45 3 0.00 0.00 421.69 2.00 44 46 | 46 3 0.00 0.00 431.50 2.00 45 47 | 47 3 0.00 0.00 441.31 2.00 46 48 | 48 3 0.00 0.00 451.11 2.00 47 49 | 49 3 0.00 0.00 460.92 2.00 48 50 | 50 3 0.00 0.00 470.72 2.00 49 51 | 51 3 0.00 0.00 480.53 2.00 50 52 | 52 3 0.00 0.00 490.33 2.00 51 53 | 53 3 0.00 0.00 500.14 2.00 52 54 | -------------------------------------------------------------------------------- /kcsd/data/gang_7x7_200/electrode_positions/elcoord_x_y_z: -------------------------------------------------------------------------------- 1 | -2.000000000000000000e+01 2 | -6.666666666666666075e+00 3 | 6.666666666666667851e+00 4 | 2.000000000000000000e+01 5 | -2.000000000000000000e+01 6 | -6.666666666666666075e+00 7 | 6.666666666666667851e+00 8 | 2.000000000000000000e+01 9 | -2.000000000000000000e+01 10 | -6.666666666666666075e+00 11 | 6.666666666666667851e+00 12 | 2.000000000000000000e+01 13 | -2.000000000000000000e+01 14 | -6.666666666666666075e+00 15 | 6.666666666666667851e+00 16 | 2.000000000000000000e+01 17 | -2.000000000000000000e+01 18 | -6.666666666666666075e+00 19 | 6.666666666666667851e+00 20 | 2.000000000000000000e+01 21 | -2.000000000000000000e+01 22 | -2.000000000000000000e+01 23 | -2.000000000000000000e+01 24 | -2.000000000000000000e+01 25 | -1.000000000000000000e+01 26 | -1.000000000000000000e+01 27 | -1.000000000000000000e+01 28 | -1.000000000000000000e+01 29 | 0.000000000000000000e+00 30 | 0.000000000000000000e+00 31 | 0.000000000000000000e+00 32 | 0.000000000000000000e+00 33 | 1.000000000000000000e+01 34 | 1.000000000000000000e+01 35 | 1.000000000000000000e+01 36 | 1.000000000000000000e+01 37 | 2.000000000000000000e+01 38 | 2.000000000000000000e+01 39 | 2.000000000000000000e+01 40 | 2.000000000000000000e+01 41 | 5.000000000000000000e+01 42 | 5.000000000000000000e+01 43 | 5.000000000000000000e+01 44 | 5.000000000000000000e+01 45 | 5.000000000000000000e+01 46 | 5.000000000000000000e+01 47 | 5.000000000000000000e+01 48 | 5.000000000000000000e+01 49 | 5.000000000000000000e+01 50 | 5.000000000000000000e+01 51 | 5.000000000000000000e+01 52 | 5.000000000000000000e+01 53 | 5.000000000000000000e+01 54 | 5.000000000000000000e+01 55 | 5.000000000000000000e+01 56 | 5.000000000000000000e+01 57 | 5.000000000000000000e+01 58 | 5.000000000000000000e+01 59 | 5.000000000000000000e+01 60 | 5.000000000000000000e+01 61 | -------------------------------------------------------------------------------- /kcsd/data/gang_7x7_200/morphology/gang_7x7_200_rows_4_cols_5_xmin_-20_xmax_20_ymin_-20_ymax_20_orientation_3.swc: -------------------------------------------------------------------------------- 1 | 1 1 -31.46 0.00 0.00 31.46 -1 2 | 2 1 -23.59 0.00 0.00 31.46 1 3 | 3 1 -15.73 0.00 0.00 31.46 2 4 | 4 1 -7.86 0.00 0.00 31.46 3 5 | 5 1 0.00 0.00 0.00 31.46 4 6 | 6 3 -17.73 -22.38 -0.16 0.30 4 7 | 7 3 -11.93 -29.20 -0.16 0.30 6 8 | 8 3 -7.05 -36.24 -0.16 0.30 7 9 | 9 3 -6.47 -42.70 -0.20 0.30 8 10 | 10 3 1.92 -42.16 -0.13 0.30 9 11 | 11 3 9.44 -37.48 -0.03 0.30 10 12 | 12 3 16.14 -34.46 0.04 0.30 11 13 | 13 3 24.47 -32.39 0.12 0.30 12 14 | 14 3 31.96 -27.83 0.22 0.30 13 15 | 15 3 34.38 -33.31 0.20 0.30 14 16 | 16 3 37.16 -38.61 0.19 0.30 15 17 | 17 3 36.17 -23.56 0.29 0.30 14 18 | 18 3 40.95 -19.69 0.35 0.30 17 19 | -------------------------------------------------------------------------------- /kcsd/data/gang_7x7_200/seglength: -------------------------------------------------------------------------------- 1 | 7.864999771118164062e+00 2 | 7.864999771118164062e+00 3 | 7.864999771118164062e+00 4 | 7.864999771118164062e+00 5 | 8.968441886270198893e+00 6 | 8.968441886270198893e+00 7 | 8.968441886270198893e+00 8 | 8.968441886270198893e+00 9 | 8.968441886270198893e+00 10 | 8.968441886270198893e+00 11 | 8.968441886270198893e+00 12 | 8.968441886270198893e+00 13 | 8.968441886270198893e+00 14 | 6.013939266097024117e+00 15 | 6.013939266097024117e+00 16 | 6.160190508817574795e+00 17 | 6.160190508817574795e+00 18 | -------------------------------------------------------------------------------- /kcsd/data/gang_7x7_200/somav.txt: -------------------------------------------------------------------------------- 1 | -6.500000000000000000e+01 2 | -5.816608947979112543e+01 3 | -4.822429466247495355e+01 4 | -2.661994166108848958e+01 5 | 2.322862817008510916e+01 6 | 2.742005798710957265e+01 7 | 2.888892801592493953e+00 8 | -2.028261420296600193e+01 9 | -3.726755608374355688e+01 10 | -5.195932208279968734e+01 11 | -5.942442368918327134e+01 12 | -5.828292717876684748e+01 13 | -5.878359274055905104e+01 14 | -5.730386598167422108e+01 15 | -5.581193919411248316e+01 16 | -5.211736098695718056e+01 17 | -5.027661072073362902e+01 18 | -4.824208909029723458e+01 19 | -4.641965459618457146e+01 20 | -4.558295005366988306e+01 21 | -4.570945407511406700e+01 22 | -4.316029647171292538e+01 23 | -4.242258993559249802e+01 24 | -4.094278018794497598e+01 25 | -3.859444415443550014e+01 26 | -3.807432226262280750e+01 27 | -3.964293272744001939e+01 28 | -3.947467400220559597e+01 29 | -4.000973745139282300e+01 30 | -4.153487567314629558e+01 31 | -4.369319309213182123e+01 32 | -4.685460411296799776e+01 33 | -5.037587147257731601e+01 34 | -4.646796766247163646e+01 35 | -4.643251014781183272e+01 36 | -4.690635719770403966e+01 37 | -4.639682652529483420e+01 38 | -4.515609089841850476e+01 39 | -4.247168967825661667e+01 40 | -4.163634266862008104e+01 41 | -4.067093955135658945e+01 42 | -4.107329954811480377e+01 43 | -4.285335558224957708e+01 44 | -4.539449062854791350e+01 45 | -4.693075021082343312e+01 46 | -4.878134018902233038e+01 47 | -5.049111638242745670e+01 48 | -5.128099379705445671e+01 49 | -5.156471149788344377e+01 50 | -4.885380302017017584e+01 51 | -4.739105571412635953e+01 52 | -4.060773820177475102e+01 53 | -3.509662019663055332e+01 54 | -2.874654704966746621e+01 55 | -2.671290417848799592e+01 56 | -3.031160478862472374e+01 57 | -3.574635105800038559e+01 58 | -4.143530016547862260e+01 59 | -4.710776471389403497e+01 60 | -4.850554761931297776e+01 61 | -4.730769150829301140e+01 62 | -4.754307683387347083e+01 63 | -4.653983225966730686e+01 64 | -4.499400986914821488e+01 65 | -4.478327089846274589e+01 66 | -4.345993395583975882e+01 67 | -4.335275460386976931e+01 68 | -4.231154254045743812e+01 69 | -4.251777106375338633e+01 70 | -4.194776737878905237e+01 71 | -4.263514548900114676e+01 72 | -4.252802639942335361e+01 73 | -4.092723347571183012e+01 74 | -3.885094610891583500e+01 75 | -3.802209690429725697e+01 76 | -3.707428755856064839e+01 77 | -3.581456498446546988e+01 78 | -3.770072031622397901e+01 79 | -4.093789523464386093e+01 80 | -4.455761673541834256e+01 81 | -4.782385442745425053e+01 82 | -5.016436613816990331e+01 83 | -4.656570678719419476e+01 84 | -4.308286222057039083e+01 85 | -4.086365712925682203e+01 86 | -3.915323655526906776e+01 87 | -3.915359409540614877e+01 88 | -4.049633254482583311e+01 89 | -4.159616394312234888e+01 90 | -4.267983167995481608e+01 91 | -4.343967466482531137e+01 92 | -4.263497498422302101e+01 93 | -4.354706654744327921e+01 94 | -4.512109241513961422e+01 95 | -4.536229818848286754e+01 96 | -4.650606294078343694e+01 97 | -4.607491613088734539e+01 98 | -4.509608555097027249e+01 99 | -4.367258561803672734e+01 100 | -4.369823012083458025e+01 101 | -4.427275168808265704e+01 102 | -4.257886457108528333e+01 103 | -4.130457127215697710e+01 104 | -4.175483663811483837e+01 105 | -4.311683129157522387e+01 106 | -4.136509531679693907e+01 107 | -3.745254005528727248e+01 108 | -3.467826311266345840e+01 109 | -3.469005265969178708e+01 110 | -3.678143644383873578e+01 111 | -3.886030657811312494e+01 112 | -4.288263716265886671e+01 113 | -4.698187035131866907e+01 114 | -4.789782151564645574e+01 115 | -4.813428784520301917e+01 116 | -4.524338207194142569e+01 117 | -4.280818419490472593e+01 118 | -3.972235156455826655e+01 119 | -3.865699487670965340e+01 120 | -3.895284633060913393e+01 121 | -3.813483964030879747e+01 122 | -4.055531667181681854e+01 123 | -4.300363878603187118e+01 124 | -4.559820378978097466e+01 125 | -4.488441818935058336e+01 126 | -4.684174053368405310e+01 127 | -4.912872030880120633e+01 128 | -5.006707368363752408e+01 129 | -4.982144998051588658e+01 130 | -4.937106424824268203e+01 131 | -5.013299928107620929e+01 132 | -5.174282450407769574e+01 133 | -5.108644285293344467e+01 134 | -5.212393622091332190e+01 135 | -5.095950171181094390e+01 136 | -4.754363817120083979e+01 137 | -4.664491615332471497e+01 138 | -4.714934661297473895e+01 139 | -4.468136282525065184e+01 140 | -4.305642394070063972e+01 141 | -4.134839671693251262e+01 142 | -4.035329023297465056e+01 143 | -3.644118627830408030e+01 144 | -3.449415186370353581e+01 145 | -3.428070976042491935e+01 146 | -3.830006968474044271e+01 147 | -4.468044243540921912e+01 148 | -5.113188365715397055e+01 149 | -5.538754568283854951e+01 150 | -5.904326544394042031e+01 151 | -5.651399641547487818e+01 152 | -5.535100974335296797e+01 153 | -5.627586012795450188e+01 154 | -5.584678958434770379e+01 155 | -5.216380392388043674e+01 156 | -5.302995526884633648e+01 157 | -5.245380754193593020e+01 158 | -5.211665506331414122e+01 159 | -4.908529516592631126e+01 160 | -4.980612117224048774e+01 161 | -4.760789609637824782e+01 162 | -4.665150898424791848e+01 163 | -4.769575617707904058e+01 164 | -5.144070862001883881e+01 165 | -5.250837572816688237e+01 166 | -4.987434007427646065e+01 167 | -4.906945429871465336e+01 168 | -4.743160536917258696e+01 169 | -4.682240307338320662e+01 170 | -4.735773993581577912e+01 171 | -4.673387117534843327e+01 172 | -4.787820251199926247e+01 173 | -4.982601504245347002e+01 174 | -5.290327098376185688e+01 175 | -5.808056744425620366e+01 176 | -6.397181424124083549e+01 177 | -6.829288371017699433e+01 178 | -7.245134628113785880e+01 179 | -7.122824387507353094e+01 180 | -6.499962520867168791e+01 181 | -6.161686199798953112e+01 182 | -6.023460259469732136e+01 183 | -5.898741624932088712e+01 184 | -6.264303951616174970e+01 185 | -6.798884566056820233e+01 186 | -6.456877390736384825e+01 187 | -6.689545527876892095e+01 188 | -6.719074248415027739e+01 189 | -6.596862002956483195e+01 190 | -5.676856270113663072e+01 191 | -5.301622292608617926e+01 192 | -4.747289953749355362e+01 193 | -4.131623746135083053e+01 194 | -2.491905001584004609e+01 195 | 4.917888317179805568e+00 196 | 6.922693937828794830e+00 197 | -1.523265363872276090e+01 198 | -3.577455169727046780e+01 199 | -5.299861753285699706e+01 200 | -6.994692115872302907e+01 201 | -7.683181012042716418e+01 202 | -------------------------------------------------------------------------------- /kcsd/data/gang_7x7_200/tvec.txt: -------------------------------------------------------------------------------- 1 | 0.000000000000000000e+00 2 | 5.000000000000000000e-01 3 | 1.000000000000000000e+00 4 | 1.500000000000000000e+00 5 | 2.000000000000000000e+00 6 | 2.500000000000000000e+00 7 | 3.000000000000000000e+00 8 | 3.500000000000000000e+00 9 | 4.000000000000000000e+00 10 | 4.500000000000000000e+00 11 | 5.000000000000000000e+00 12 | 5.500000000000000000e+00 13 | 6.000000000000000000e+00 14 | 6.500000000000000000e+00 15 | 7.000000000000000000e+00 16 | 7.500000000000000000e+00 17 | 8.000000000000000000e+00 18 | 8.500000000000000000e+00 19 | 9.000000000000000000e+00 20 | 9.500000000000000000e+00 21 | 1.000000000000000000e+01 22 | 1.050000000000000000e+01 23 | 1.100000000000000000e+01 24 | 1.150000000000000000e+01 25 | 1.200000000000000000e+01 26 | 1.250000000000000000e+01 27 | 1.300000000000000000e+01 28 | 1.350000000000000000e+01 29 | 1.400000000000000000e+01 30 | 1.450000000000000000e+01 31 | 1.500000000000000000e+01 32 | 1.550000000000000000e+01 33 | 1.600000000000000000e+01 34 | 1.650000000000000000e+01 35 | 1.700000000000000000e+01 36 | 1.750000000000000000e+01 37 | 1.800000000000000000e+01 38 | 1.850000000000000000e+01 39 | 1.900000000000000000e+01 40 | 1.950000000000000000e+01 41 | 2.000000000000000000e+01 42 | 2.050000000000000000e+01 43 | 2.100000000000000000e+01 44 | 2.150000000000000000e+01 45 | 2.200000000000000000e+01 46 | 2.250000000000000000e+01 47 | 2.300000000000000000e+01 48 | 2.350000000000000000e+01 49 | 2.400000000000000000e+01 50 | 2.450000000000000000e+01 51 | 2.500000000000000000e+01 52 | 2.550000000000000000e+01 53 | 2.600000000000000000e+01 54 | 2.650000000000000000e+01 55 | 2.700000000000000000e+01 56 | 2.750000000000000000e+01 57 | 2.800000000000000000e+01 58 | 2.850000000000000000e+01 59 | 2.900000000000000000e+01 60 | 2.950000000000000000e+01 61 | 3.000000000000000000e+01 62 | 3.050000000000000000e+01 63 | 3.100000000000000000e+01 64 | 3.150000000000000000e+01 65 | 3.200000000000000000e+01 66 | 3.250000000000000000e+01 67 | 3.300000000000000000e+01 68 | 3.350000000000000000e+01 69 | 3.400000000000000000e+01 70 | 3.450000000000000000e+01 71 | 3.500000000000000000e+01 72 | 3.550000000000000000e+01 73 | 3.600000000000000000e+01 74 | 3.650000000000000000e+01 75 | 3.700000000000000000e+01 76 | 3.750000000000000000e+01 77 | 3.800000000000000000e+01 78 | 3.850000000000000000e+01 79 | 3.900000000000000000e+01 80 | 3.950000000000000000e+01 81 | 4.000000000000000000e+01 82 | 4.050000000000000000e+01 83 | 4.100000000000000000e+01 84 | 4.150000000000000000e+01 85 | 4.200000000000000000e+01 86 | 4.250000000000000000e+01 87 | 4.300000000000000000e+01 88 | 4.350000000000000000e+01 89 | 4.400000000000000000e+01 90 | 4.450000000000000000e+01 91 | 4.500000000000000000e+01 92 | 4.550000000000000000e+01 93 | 4.600000000000000000e+01 94 | 4.650000000000000000e+01 95 | 4.700000000000000000e+01 96 | 4.750000000000000000e+01 97 | 4.800000000000000000e+01 98 | 4.850000000000000000e+01 99 | 4.900000000000000000e+01 100 | 4.950000000000000000e+01 101 | 5.000000000000000000e+01 102 | 5.050000000000000000e+01 103 | 5.100000000000000000e+01 104 | 5.150000000000000000e+01 105 | 5.200000000000000000e+01 106 | 5.250000000000000000e+01 107 | 5.300000000000000000e+01 108 | 5.350000000000000000e+01 109 | 5.400000000000000000e+01 110 | 5.450000000000000000e+01 111 | 5.500000000000000000e+01 112 | 5.550000000000000000e+01 113 | 5.600000000000000000e+01 114 | 5.650000000000000000e+01 115 | 5.700000000000000000e+01 116 | 5.750000000000000000e+01 117 | 5.800000000000000000e+01 118 | 5.850000000000000000e+01 119 | 5.900000000000000000e+01 120 | 5.950000000000000000e+01 121 | 6.000000000000000000e+01 122 | 6.050000000000000000e+01 123 | 6.100000000000000000e+01 124 | 6.150000000000000000e+01 125 | 6.200000000000000000e+01 126 | 6.250000000000000000e+01 127 | 6.300000000000000000e+01 128 | 6.350000000000000000e+01 129 | 6.400000000000000000e+01 130 | 6.450000000000000000e+01 131 | 6.500000000000000000e+01 132 | 6.550000000000000000e+01 133 | 6.600000000000000000e+01 134 | 6.650000000000000000e+01 135 | 6.700000000000000000e+01 136 | 6.750000000000000000e+01 137 | 6.800000000000000000e+01 138 | 6.850000000000000000e+01 139 | 6.900000000000000000e+01 140 | 6.950000000000000000e+01 141 | 7.000000000000000000e+01 142 | 7.050000000000000000e+01 143 | 7.100000000000000000e+01 144 | 7.150000000000000000e+01 145 | 7.200000000000000000e+01 146 | 7.250000000000000000e+01 147 | 7.300000000000000000e+01 148 | 7.350000000000000000e+01 149 | 7.400000000000000000e+01 150 | 7.450000000000000000e+01 151 | 7.500000000000000000e+01 152 | 7.550000000000000000e+01 153 | 7.600000000000000000e+01 154 | 7.650000000000000000e+01 155 | 7.700000000000000000e+01 156 | 7.750000000000000000e+01 157 | 7.800000000000000000e+01 158 | 7.850000000000000000e+01 159 | 7.900000000000000000e+01 160 | 7.950000000000000000e+01 161 | 8.000000000000000000e+01 162 | 8.050000000000000000e+01 163 | 8.100000000000000000e+01 164 | 8.150000000000000000e+01 165 | 8.200000000000000000e+01 166 | 8.250000000000000000e+01 167 | 8.300000000000000000e+01 168 | 8.350000000000000000e+01 169 | 8.400000000000000000e+01 170 | 8.450000000000000000e+01 171 | 8.500000000000000000e+01 172 | 8.550000000000000000e+01 173 | 8.600000000000000000e+01 174 | 8.650000000000000000e+01 175 | 8.700000000000000000e+01 176 | 8.750000000000000000e+01 177 | 8.800000000000000000e+01 178 | 8.850000000000000000e+01 179 | 8.900000000000000000e+01 180 | 8.950000000000000000e+01 181 | 9.000000000000000000e+01 182 | 9.050000000000000000e+01 183 | 9.100000000000000000e+01 184 | 9.150000000000000000e+01 185 | 9.200000000000000000e+01 186 | 9.250000000000000000e+01 187 | 9.300000000000000000e+01 188 | 9.350000000000000000e+01 189 | 9.400000000000000000e+01 190 | 9.450000000000000000e+01 191 | 9.500000000000000000e+01 192 | 9.550000000000000000e+01 193 | 9.600000000000000000e+01 194 | 9.650000000000000000e+01 195 | 9.700000000000000000e+01 196 | 9.750000000000000000e+01 197 | 9.800000000000000000e+01 198 | 9.850000000000000000e+01 199 | 9.900000000000000000e+01 200 | 9.950000000000000000e+01 201 | 1.000000000000000000e+02 202 | -------------------------------------------------------------------------------- /kcsd/data/morphology/ElcoordsDomi14.txt: -------------------------------------------------------------------------------- 1 | -918.319793756703 392.071582444667 5.0687610640665 2 | -880.978407236736 384.319062677909 5.12935689990195 3 | -839.828990783331 375.775950218092 5.19613222659749 4 | -795.777147374483 366.630259106525 5.26761747447451 5 | -745.47963929279 356.187893089572 5.34923789156912 6 | -702.889667700557 347.345704102885 5.41835088300717 7 | -655.739574044626 337.556779075244 5.49486382484111 8 | -608.118734686921 327.670121593128 5.5721406705341 9 | -560.802201953914 317.846641816581 5.64892370182992 10 | -510.401354123951 307.382821228285 5.73071181378015 11 | -467.083241685521 298.38946146758 5.8010063977431 12 | -374.237026823772 279.113473533937 5.95167284369034 13 | -326.640344834721 269.23183141133 6.0289104879481 14 | -227.105088957892 248.567118325172 6.19043159326985 15 | -------------------------------------------------------------------------------- /kcsd/data/morphology/Test.swc: -------------------------------------------------------------------------------- 1 | # SWC to SWC conversion from L-Measure. Sridevi Polavaram: spolavar@gmu.edu 2 | # Original fileName:/cng_repository/Soumya/LM_Automated_Testing_Enviornment/Test_Lm3.7.2_10062011_SG_Linux_NMOConv6/TestResults/LoadTest/test_7/021105.CNG.swc 3 | # 4 | # Original file 021105.swc edited using StdSwc version 1.31 on 3/21/11. 5 | # Irregularities and fixes documented in 021105.swc.std. See StdSwc1.31.doc for more information. 6 | # 7 | # Neurolucida to SWC conversion from L-Measure. R. Scorcioni: rscorcio@gmu.edu 8 | # Original fileName:C:\Users\praveen\Desktop\File_Processing_in_progress\Master File Processing\Original\021105.asc 9 | # 10 | 1 1 0 0 0 15.73 -1 11 | 2 1 0 15.73 0 15.73 1 12 | 3 1 0 -15.73 0 15.73 1 13 | 4 3 -1.41 -13.71 -0.1 0.15 1 14 | 5 3 -1.79 -15.86 -0.12 0.15 4 15 | 6 3 -1.73 -18 -0.13 0.15 5 16 | 7 3 -2.29 -21.22 -0.16 0.15 6 17 | 8 3 -2.48 -21.87 -0.16 0.15 7 18 | 9 3 0.81 -25.41 -0.16 0.15 8 19 | 10 3 2.57 -27.51 -0.16 0.15 9 20 | 11 3 3.68 -28.98 -0.16 0.15 10 21 | 12 3 4.58 -30.66 -0.16 0.15 11 22 | 13 3 5.9 -31.91 -0.16 0.15 12 23 | 14 3 7.85 -33.35 -0.15 0.15 13 24 | 15 3 8.78 -35.9 -0.16 0.15 14 25 | 16 3 8.19 -37.84 -0.18 0.15 15 26 | 17 3 6.49 -38.74 -0.2 0.15 16 27 | 18 3 6.99 -41.29 -0.21 0.15 17 28 | 19 3 8.31 -42.54 -0.21 0.15 18 29 | 20 3 9.39 -42.72 -0.2 0.15 19 30 | 21 3 14.55 -43.87 -0.16 0.15 20 31 | 22 3 16.02 -43.19 -0.15 0.15 21 32 | 23 3 21.28 -39.85 -0.08 0.15 22 33 | 24 3 22.53 -38.53 -0.06 0.15 23 34 | 25 3 26.55 -36.93 -0.01 0.15 24 35 | 26 3 27.78 -35.19 0 0.15 25 36 | 27 3 29.23 -33.23 0.02 0.15 26 37 | 28 3 32.7 -34.85 0.04 0.15 27 38 | 29 3 33.55 -34.83 0.05 0.15 28 39 | 30 3 35.89 -34.55 0.07 0.15 29 40 | 31 3 38 -33.21 0.1 0.15 30 41 | 32 3 39.91 -32.53 0.12 0.15 31 42 | 33 3 42.23 -31.39 0.15 0.15 32 43 | 34 3 43.47 -30.08 0.17 0.15 33 44 | 35 3 44.97 -29.83 0.18 0.15 34 45 | 36 3 46.02 -29.16 0.2 0.15 35 46 | 37 3 47.69 -27.83 0.22 0.15 36 47 | 38 3 49.53 -32.49 0.2 0.15 37 48 | 39 3 51.31 -35 0.2 0.15 38 49 | 40 3 52.89 -38.61 0.19 0.15 39 50 | 41 3 47.68 -27.4 0.22 0.15 37 51 | 42 3 49.97 -25 0.26 0.15 41 52 | 43 3 51.44 -23.88 0.28 0.15 42 53 | 44 3 53.96 -22.11 0.31 0.15 43 54 | 45 3 56.05 -20.35 0.34 0.15 44 55 | 46 3 56.68 -19.69 0.35 0.15 45 56 | -------------------------------------------------------------------------------- /kcsd/data/morphology/active.hoc: -------------------------------------------------------------------------------- 1 | soma insert hh 2 | -------------------------------------------------------------------------------- /kcsd/data/morphology/ballstick.hoc: -------------------------------------------------------------------------------- 1 | 2 | create soma[1] 3 | create dend[1] 4 | 5 | soma[0] { 6 | pt3dadd(0, 0, 0, 9.861) 7 | pt3dadd(0, 0, 19.722,9.861) 8 | } 9 | 10 | dend[0] { 11 | pt3dadd(0, 0, 19.722, 2.) 12 | pt3dadd(0, 0, 510, 2.) 13 | } 14 | 15 | soma[0] insert hh 16 | 17 | connect dend[0](0), soma[0](1) 18 | 19 | -------------------------------------------------------------------------------- /kcsd/data/morphology/ballstick.swc: -------------------------------------------------------------------------------- 1 | 1 1 0.00 0.00 -6.01 9.861 -1 2 | 2 1 0.00 0.00 3.84 9.861 1 3 | 3 1 0.00 0.00 -15.87 9.861 1 4 | 4 4 0.00 0.00 500 2.0 2 5 | -------------------------------------------------------------------------------- /kcsd/data/morphology/villa.hoc: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------- 2 | example_morphology.hoc 3 | 4 | This hoc file creates a neuron of the following shape: 5 | 6 | \ 7 | \ 8 | \ / 9 | \ / 10 | V 11 | | 12 | | 13 | | 14 | O 15 | 16 | Note the conventions: 17 | - soma needs to be a list (soma[0], not soma), 18 | - use soma for the soma compartment, 19 | - use a name starting with dend for the dendrites. 20 | -----------------------------------------------------*/ 21 | 22 | 23 | create soma[1] 24 | create dend[3] 25 | 26 | soma[0] { 27 | pt3dadd(0, 0,-15.87 , 9.861) 28 | pt3dadd(0, 0, 3.84, 9.861) 29 | } 30 | 31 | dend[0] { 32 | pt3dadd(0, 0, 3.84, 2) 33 | pt3dadd(0, 0, 200, 2) 34 | } 35 | 36 | dend[1] { 37 | pt3dadd(0, 0, 200, 2) 38 | pt3dadd(100, 0, 500, 2) 39 | } 40 | 41 | dend[2] { 42 | pt3dadd(0, 0, 200, 2) 43 | pt3dadd(-100, 0, 500, 2) 44 | } 45 | 46 | connect dend[0](0), soma[0](1) 47 | connect dend[1](0), dend[0](1) 48 | connect dend[2](0), dend[0](1) 49 | -------------------------------------------------------------------------------- /kcsd/data/morphology/villa.swc: -------------------------------------------------------------------------------- 1 | 1 1 0.00 0.00 -6.01 9.861 -1 2 | 2 1 0.00 0.00 3.84 9.861 1 3 | 3 1 0.00 0.00 -15.87 9.861 1 4 | 4 4 0.00 0.00 200 2 2 5 | 5 4 100 0.00 500 2 4 6 | 6 4 -100 0.00 500 2 4 7 | -------------------------------------------------------------------------------- /kcsd/data/sinsyn.mod: -------------------------------------------------------------------------------- 1 | COMMENT 2 | This code comes from LFPy tests. It has been written by Espen Hagen. 3 | 4 | Since this is an electrode current, positive values of i depolarize the cell 5 | and in the presence of the extracellular mechanism there will be a change 6 | in vext since i is not a transmembrane current but a current injected 7 | directly to the inside of the cell. 8 | ENDCOMMENT 9 | 10 | NEURON { 11 | POINT_PROCESS SinSyn 12 | RANGE del, dur, pkamp, freq, phase, bias 13 | NONSPECIFIC_CURRENT i 14 | } 15 | 16 | UNITS { 17 | (nA) = (nanoamp) 18 | } 19 | 20 | PARAMETER { 21 | del=5 (ms) 22 | dur=200 (ms) 23 | pkamp=1 (nA) 24 | freq=1 (Hz) 25 | phase=0 26 | bias=0 (nA) 27 | PI=3.14159265358979323846 28 | } 29 | 30 | ASSIGNED { 31 | i (nA) 32 | } 33 | 34 | BREAKPOINT { 35 | at_time(del) 36 | at_time(del + dur) 37 | 38 | if (t < del) { 39 | i=0 40 | }else{ 41 | if (t < del+dur) { 42 | i = -pkamp*sin(2*PI*freq*(t-del)*(0.001)+phase)-bias 43 | }else{ 44 | i = 0 45 | }}} 46 | 47 | NET_RECEIVE(weight (nA)) { 48 | } 49 | -------------------------------------------------------------------------------- /kcsd/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neuroinflab/kCSD-python/21418c5e0c81829673ab60b7c42c064c8bd52433/kcsd/tests/__init__.py -------------------------------------------------------------------------------- /kcsd/tests/test_loadData.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | from kcsd import sample_data_path 4 | from kcsd.sKCSD_utils import LoadData 5 | import os 6 | import unittest 7 | import numpy as np 8 | try: 9 | basestring 10 | except NameError: 11 | basestring = str 12 | 13 | class testData(unittest.TestCase): 14 | @classmethod 15 | def setUpClass(cls): 16 | cls.path = os.path.join(sample_data_path, "gang_7x7_200") 17 | cls.data = LoadData(cls.path) 18 | 19 | def test_path_expansion_morphology(self): 20 | path = self.data.path 21 | m_path = '' 22 | for p in self.data.sub_dir_path(path): 23 | if 'morphology' in p: 24 | m_path = p 25 | a = 'data/gang_7x7_200/morphology' in m_path 26 | self.assertTrue(a) 27 | 28 | def test_get_fname_string(self): 29 | path = self.data.get_fname('data/gang_7x7_200/LFP', ['MyLFP']) 30 | self.assertTrue(isinstance(path, basestring)) 31 | 32 | def test_get_fname_list(self): 33 | path = self.data.get_fname('data/gang_7x7_200/LFP', 34 | ['MyLFP', 'yourLFP']) 35 | self.assertTrue(isinstance(path, list)) 36 | 37 | def test_get_paths_LFP(self): 38 | print(self.data.path_LFP) 39 | self.assertTrue('data/gang_7x7_200/LFP/MyLFP' in self.data.path_LFP) 40 | 41 | def test_get_paths_morpho(self): 42 | path = os.path.join(self.path,'morphology/gang_7x7_200_rows_4_cols_5_xmin_-20_xmax_20_ymin_-20_ymax_20_orientation_3.swc') 43 | self.assertTrue(path in self.data.path_morphology) 44 | 45 | def test_get_paths_ele_pos(self): 46 | path = os.path.join(self.path, 'electrode_positions/elcoord_x_y_z') 47 | self.assertTrue(path in self.data.path_ele_pos) 48 | 49 | def test_load_morpho_correct(self): 50 | self.assertTrue(isinstance(self.data.morphology, np.ndarray)) 51 | 52 | def test_load_ele_pos_correct(self): 53 | self.assertTrue(isinstance(self.data.ele_pos, np.ndarray)) 54 | 55 | def test_load_LFP_correct(self): 56 | self.assertTrue(isinstance(self.data.LFP, np.ndarray)) 57 | 58 | def test_load_morpho_no_file(self): 59 | self.data.load(path='gugu', what="morphology") 60 | self.assertFalse(self.data.morphology) 61 | 62 | def test_load_morpho_no_array(self): 63 | self.data.load(path='test_loadData.py', what="morphology") 64 | self.assertFalse(self.data.morphology) 65 | 66 | def test_reload_morpho(self): 67 | path = os.path.join(self.path, 'morphology/gang_7x7_200_rows_4_cols_5_xmin_-20_xmax_20_ymin_-20_ymax_20_orientation_3.swc') 68 | self.data.load(path=path, what='morphology') 69 | self.assertTrue(isinstance(self.data.morphology, np.ndarray)) 70 | 71 | def test_load_ele_pos_no_file(self): 72 | self.data.load(path='gugu', what="electrode_positions") 73 | self.assertFalse(self.data.ele_pos) 74 | 75 | def test_load_ele_pos_no_array(self): 76 | self.data.load(path='test_loadData.py', 77 | what="electrode_positions") 78 | self.assertFalse(self.data.ele_pos) 79 | 80 | def test_reload_ele_pos(self): 81 | path = os.path.join(self.path, 'electrode_positions/elcoord_x_y_z') 82 | self.data.load(path=path, what="electrode_positions") 83 | self.assertTrue(isinstance(self.data.ele_pos, np.ndarray)) 84 | 85 | def test_load_LFP_no_file(self): 86 | self.data.load(path='gugu', what="LFP") 87 | self.assertFalse(self.data.LFP) 88 | 89 | def test_load_LFP_no_array(self): 90 | self.data.load(path='test_loadData.py', what="LFP") 91 | self.assertFalse(self.data.LFP) 92 | 93 | def test_reload_LFP(self): 94 | lfp_path = os.path.join(self.path,'LFP/MyLFP') 95 | self.data.load(path=lfp_path, what="LFP") 96 | self.assertTrue(isinstance(self.data.LFP, np.ndarray)) 97 | 98 | 99 | if __name__ == '__main__': 100 | unittest.main() 101 | -------------------------------------------------------------------------------- /kcsd/tests/test_sKCSD.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | import os 4 | import unittest 5 | 6 | from kcsd import sKCSD, sample_data_path 7 | from kcsd.sKCSD_utils import LoadData 8 | 9 | try: 10 | basestring 11 | except NameError: 12 | basestring = str 13 | 14 | 15 | n_src = 5 16 | 17 | class testsKCD(unittest.TestCase): 18 | @classmethod 19 | def setUpClass(cls, n_src=5): 20 | 21 | sc = 1e6 22 | cls.data = LoadData(os.path.join(sample_data_path, "ball_and_stick_8")) 23 | cls.data.morphology[:,2:6] = cls.data.morphology[:,2:6]/sc 24 | cls.reco = sKCSD(cls.data.ele_pos/sc,cls.data.LFP[:,:10]/1e3,cls.data.morphology, n_src_init=n_src, exact=True) 25 | cls.segments = cls.reco.values(transformation='segments') 26 | cls.loops = cls.reco.values(transformation=None) 27 | cls.cartesian = cls.reco.values(transformation='3D') 28 | cls.data2 = LoadData(os.path.join(sample_data_path, "Simple_with_branches")) 29 | cls.data2.morphology[:, 2:6] = cls.data2.morphology[:, 2:6]/sc 30 | cls.data2.ele_pos = cls.data2.ele_pos/sc 31 | cls.data2.LFP = cls.data2.LFP[:,:10]/1e3 32 | cls.reco2 = sKCSD(cls.data2.ele_pos, cls.data2.LFP, cls.data2.morphology, n_src_init=n_src, dist_table_density=5) 33 | 34 | def test_values_segments_shape(self): 35 | self.assertTrue(len(self.segments.shape) == 2) 36 | 37 | def test_values_segments_length(self): 38 | self.assertTrue(self.segments.shape[0] == len(self.data.morphology)-1) 39 | 40 | def test_values_loops_shape(self): 41 | self.assertTrue(len(self.loops.shape) == 2) 42 | 43 | def test_values_loops_length(self): 44 | self.assertTrue(self.loops.shape[0] == 2*(len(self.data.morphology)-1)) 45 | 46 | def test_values_cartesian_shape(self): 47 | self.assertTrue(len(self.cartesian.shape) == 4) 48 | 49 | if __name__ == '__main__': 50 | unittest.main() 51 | -------------------------------------------------------------------------------- /kcsd/tests/test_sKCSDutils.py: -------------------------------------------------------------------------------- 1 | from kcsd.sKCSD_utils import check_estimated_shape 2 | import os 3 | import unittest 4 | import numpy as np 5 | 6 | class testCheckEstimatedShape(unittest.TestCase): 7 | def test_unchanged(self): 8 | array = np.ones((1, 5)) 9 | out = check_estimated_shape(array) 10 | self.assertEqual(array.shape, out.shape) 11 | 12 | def test_changed(self): 13 | array = np.ones((5, )) 14 | out = check_estimated_shape(array) 15 | self.assertEqual(out.shape, (5, 1)) 16 | 17 | 18 | if __name__ == '__main__': 19 | unittest.main() 20 | -------------------------------------------------------------------------------- /kcsd/validation/__init__.py: -------------------------------------------------------------------------------- 1 | # from .csd_profile import gauss_1d_mono, gauss_1d_dipole 2 | # from .csd_profile import gauss_2d_large, gauss_2d_small 3 | # from .csd_profile import gauss_3d_small 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | scipy 3 | wheel 4 | matplotlib 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python implementation of kernel Current Source Density method 3 | """ 4 | from setuptools import setup, find_packages 5 | import sys 6 | 7 | 8 | def readme(): 9 | """ 10 | Used for README 11 | """ 12 | if sys.version_info.major < 3: 13 | print('No support for python versions < 3.8') 14 | with open('README.rst') as f: 15 | return f.read().decode('utf-8') 16 | else: 17 | with open('README.rst', encoding='utf-8') as f: 18 | return f.read() 19 | 20 | 21 | setup(name='kcsd', 22 | version='2.0.1', 23 | description='kernel current source density methods', 24 | long_description=readme(), 25 | classifiers=[ 26 | 'Development Status :: 5 - Production/Stable', 27 | 'License :: OSI Approved :: BSD License', 28 | 'Natural Language :: English', 29 | 'Programming Language :: Python :: 3', 30 | 'Programming Language :: Python :: 3.8', 31 | 'Programming Language :: Python :: 3.9', 32 | 'Programming Language :: Python :: 3.10', 33 | 'Programming Language :: Python :: 3.11', 34 | 'Operating System :: OS Independent', 35 | 'Topic :: Scientific/Engineering :: Medical Science Apps.', 36 | 'Intended Audience :: Science/Research', 37 | ], 38 | keywords='Electrophysiology CSD LFP MEA', 39 | url='https://github.com/Neuroinflab/kCSD-python', 40 | author='Chaitanya Chintaluri et al', 41 | license='Modified BSD License', 42 | packages=find_packages(where="."), 43 | include_package_data=True, 44 | package_data={'kcsd': 45 | ['data/*', 46 | 'data/ball_and_stick_128/*', 47 | 'data/ball_and_stick_16/*', 48 | 'data/ball_and_stick_8/*', 49 | 'data/gang_7x7_200/*', 50 | 'data/morphology/*', 51 | 'data/Simple_with_branches/*', 52 | 'data/Y_shaped_neuron/*', 53 | 'tutorials/*', 54 | 'figures/*' 55 | ] 56 | }, 57 | install_requires=['numpy>=1.19', 58 | 'scipy>=1.8.0', 59 | 'matplotlib>=3.6'], 60 | extras_require={'docs': ['numpydoc>=1.6.0', 61 | 'sphinx>=5']}, 62 | test_suite='kcsd.tests', 63 | zip_safe=False) 64 | -------------------------------------------------------------------------------- /tutorials/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neuroinflab/kCSD-python/21418c5e0c81829673ab60b7c42c064c8bd52433/tutorials/__init__.py -------------------------------------------------------------------------------- /tutorials/config.py: -------------------------------------------------------------------------------- 1 | from kcsd import csd_profile as csd 2 | #from kcsd import MoIKCSD 3 | from kcsd import ValidateKCSD, ValidateKCSD1D, ValidateKCSD2D, ValidateKCSD3D, SpectralStructure, ValidateMoIKCSD 4 | from kcsd import VisibilityMap1D, VisibilityMap2D, VisibilityMap3D 5 | 6 | 7 | # Function to initialize default parameters 8 | def initialize(value): 9 | if value == '1D': 10 | dim = 1 11 | csd_profile = csd.gauss_1d_mono 12 | kCSD = ValidateKCSD1D 13 | visibility_map = VisibilityMap1D 14 | elif value == '2D': 15 | dim = 2 16 | csd_profile = csd.gauss_2d_small 17 | kCSD = ValidateKCSD2D 18 | visibility_map = VisibilityMap2D 19 | else: 20 | dim = 3 21 | csd_profile = csd.gauss_3d_small 22 | kCSD = ValidateKCSD3D 23 | visibility_map = VisibilityMap3D 24 | return dim, csd_profile, kCSD, visibility_map 25 | 26 | 27 | dim, csd_profile, kCSD, visibility_map = initialize('1D') 28 | 29 | 30 | kcsd_options = {1: {'ValidateKCSD1D': ValidateKCSD1D}, 31 | 2: {'ValidateKCSD2D': ValidateKCSD2D, 32 | 'ValidateMoIKCSD': ValidateMoIKCSD}, 33 | 3: {'ValidateKCSD3D': ValidateKCSD3D}} 34 | 35 | csd_options = {1: {'monopole gauss': csd.gauss_1d_mono, 36 | 'dipole gauss': csd.gauss_1d_dipole}, 37 | 2: {'quadpole small': csd.gauss_2d_small, 38 | 'dipole large': csd.gauss_2d_large}, 39 | 3: {'gaussian small': csd.gauss_3d_small}} 40 | 41 | defaults = {'ValidateKCSD1D': {'R_init': 0.23, 42 | 'n_src_init': 300, 43 | 'true_csd_xlims': [0., 1.], 44 | 'ele_lims': [0.1, 0.9], 45 | 'kcsd_xlims': [0.1, 0.9], 46 | 'est_xres': 0.01, 47 | 'ext_x': 0.0, 48 | 'sigma': 1.0, 49 | 'h': 1.0}, 50 | 'ValidateKCSD2D': {'R_init': 0.08, 51 | 'n_src_init': 1000, 52 | 'est_xres': 0.01, 'est_yres': 0.01, 53 | 'ext_x': 0.0, 'ext_y': 0.0, 54 | 'sigma': 1.0, 55 | 'h': 1.0}, 56 | 'ValidateMoIKCSD': {'R_init': 0.08, 57 | 'n_src_init': 1000, 58 | 'gdx': 0.01, 'gdy': 0.01, 59 | 'xmin': 0.0, 'xmax': 1.0, 60 | 'ymin': 0.0, 'ymax': 1.0, 61 | 'ext_x': 0.0, 'ext_y': 0.0, 62 | 'sigma': 1.0, 63 | 'h': 1.0, 64 | 'lambd': 0.0, 65 | 'MoI_iters': 20, 66 | 'sigma_S': 5.0}, 67 | 'ValidateKCSD3D': {'R_init': 0.31, 68 | 'n_src_init': 300, 69 | 'est_xres': 0.05, 'est_yres': 0.05, 'est_zres': 0.05, 70 | 'ext_x': 0.0, 'ext_y': 0.0, 'ext_z': 0.0, 71 | 'sigma': 1.0, 72 | 'h': 1.0}} 73 | -------------------------------------------------------------------------------- /tutorials/widget_helpers.py: -------------------------------------------------------------------------------- 1 | import ipywidgets as widgets 2 | import config 3 | 4 | 5 | def change_dim(value): 6 | if dim_select.value == '1D': 7 | config.dim, config.csd_profile, config.kCSD, config.visibility_map = \ 8 | config.initialize(dim_select.value) 9 | elif dim_select.value == '2D': 10 | config.dim, config.csd_profile, config.kCSD, config.visibility_map = \ 11 | config.initialize(dim_select.value) 12 | else: 13 | config.dim, config.csd_profile, config.kCSD, config.visibility_map = \ 14 | config.initialize(dim_select.value) 15 | update_csd_types() 16 | update_kcsd_types() 17 | update_accordion() 18 | 19 | 20 | def change_csd(value): 21 | config.csd_profile = config.csd_options[config.dim][csd_select.value] 22 | 23 | 24 | def change_kcsd(value): 25 | config.kCSD = config.kcsd_options[config.dim][kcsd_select.value] 26 | 27 | 28 | def update_csd_types(): 29 | csd_select.options = list(config.csd_options[config.dim].keys()) 30 | 31 | 32 | def update_kcsd_types(): 33 | kcsd_select.options = list(config.kcsd_options[config.dim].keys()) 34 | 35 | 36 | dim_select = widgets.ToggleButtons(options=['1D', '2D', '3D'], 37 | description='Dimensions of the setup:', 38 | disabled=False, 39 | button_style='', 40 | tooltips=['Laminar probes', 41 | 'MEA like flat electrodes', 42 | 'Utah array or SEEG']) 43 | 44 | csd_select = widgets.ToggleButtons(options=list(config.csd_options[1].keys()), 45 | description='True source type', 46 | button_style='') 47 | 48 | kcsd_select = widgets.ToggleButtons(options=list(config.kcsd_options[1].keys()), 49 | description='KCSD method', 50 | button_style='') 51 | 52 | nr_ele_select = widgets.BoundedIntText(value=10, 53 | min=1, 54 | max=200, 55 | step=1, 56 | description='Select nr of electrodes:', 57 | disabled=False) 58 | 59 | nr_broken_ele = widgets.BoundedIntText(value=5, 60 | min=1, 61 | max=nr_ele_select.value - 1, 62 | step=1, 63 | description='Select number of broken electrodes:', 64 | disabled=False) 65 | 66 | noise_select = widgets.FloatSlider(value=0., 67 | min=0, 68 | max=100, 69 | step=0.1, 70 | description='Noise level [%]:', 71 | disabled=False, 72 | continuous_update=False, 73 | orientation='horizontal', 74 | readout=True, 75 | readout_format='.1f') 76 | 77 | regularization_select = widgets.Select(options=['cross-validation', 'L-curve'], 78 | value='cross-validation', 79 | description='Regularization method:', 80 | disabled=False) 81 | 82 | def create_text_wid(txt, val): 83 | wid = widgets.FloatText(value=val, 84 | description=txt + ':', 85 | disabled=False) 86 | return wid 87 | 88 | 89 | def wid_lists(var_list): 90 | def_dict = config.defaults[config.kCSD.__name__] 91 | wid_list = [] 92 | for var in var_list: 93 | try: 94 | wid_list.append(create_text_wid(var, def_dict[var])) 95 | big_wid = widgets.VBox(wid_list) 96 | except KeyError: 97 | pass 98 | return big_wid 99 | 100 | 101 | def refresh_accordion_wids(): 102 | src_ass = wid_lists(['R_init', 'n_src_init', 'lambd']) 103 | est_pos = wid_lists(['xmin', 'xmax', 104 | 'ymin', 'ymax', 105 | 'zmin', 'zmax', 106 | 'ext_x', 'ext_y', 'ext_z', 107 | 'gdx', 'gdy', 'gdz']) 108 | med_ass = wid_lists(['simga', 'h', 'sigma_S', 'MoI_iters']) 109 | return [src_ass, est_pos, med_ass] 110 | 111 | 112 | accordion = widgets.Accordion(children=refresh_accordion_wids()) 113 | accordion.set_title(0, 'Source assumptions') 114 | accordion.set_title(1, 'Estimate positions') 115 | accordion.set_title(2, 'Medium assumptions') 116 | 117 | 118 | def update_accordion(): 119 | accordion.children = refresh_accordion_wids() 120 | accordion.set_title(0, 'Source assumptions') 121 | accordion.set_title(1, 'Estimate positions') 122 | accordion.set_title(2, 'Medium assumptions') 123 | 124 | 125 | dim_select.observe(change_dim, 'value') 126 | csd_select.observe(change_csd, 'value') 127 | kcsd_select.observe(change_kcsd, 'value') 128 | --------------------------------------------------------------------------------