{"id":33049566,"url":"https://github.com/m-beau/NeuroPyxels","last_synced_at":"2025-11-18T20:02:00.008Z","repository":{"id":37054928,"uuid":"313917900","full_name":"m-beau/NeuroPyxels","owner":"m-beau","description":"NeuroPyxels (npyx) is a python library built for electrophysiologists using Neuropixels electrodes. This package stems from the need of a pythonist who really did not want to transition to MATLAB to work with Neuropixels: it features a suite of core utility functions for loading, processing and plotting Neuropixels data.","archived":false,"fork":false,"pushed_at":"2025-07-01T02:21:23.000Z","size":46885,"stargazers_count":132,"open_issues_count":6,"forks_count":31,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-28T19:27:04.743Z","etag":null,"topics":["electrophysiology","python"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m-beau.png","metadata":{"files":{"readme":"README.html","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-11-18T11:46:22.000Z","updated_at":"2025-09-20T05:07:25.000Z","dependencies_parsed_at":"2023-10-27T12:24:29.548Z","dependency_job_id":"4c28c901-714c-4353-8516-8ae2d87fa1c5","html_url":"https://github.com/m-beau/NeuroPyxels","commit_stats":null,"previous_names":["npix-routines/neuropyxels"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/m-beau/NeuroPyxels","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-beau%2FNeuroPyxels","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-beau%2FNeuroPyxels/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-beau%2FNeuroPyxels/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-beau%2FNeuroPyxels/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m-beau","download_url":"https://codeload.github.com/m-beau/NeuroPyxels/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-beau%2FNeuroPyxels/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285129556,"owners_count":27119601,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-18T02:00:05.759Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electrophysiology","python"],"created_at":"2025-11-14T02:00:33.949Z","updated_at":"2025-11-18T20:02:00.002Z","avatar_url":"https://github.com/m-beau.png","language":"Jupyter Notebook","funding_links":[],"categories":["Loading and plotting data"],"sub_categories":[],"readme":"\u003c!DOCTYPE html\u003e\n        \u003chtml\u003e\n        \u003chead\u003e\n            \u003cmeta charset=\"UTF-8\"\u003e\n            \u003ctitle\u003eNeuroPyxels\u0026colon; loading\u0026comma; processing and plotting Neuropixels data in Python\u0026lt;\u0026sol;h1\u0026gt; \u0026lt;img src\u0026equals;\u0026quot;https\u0026colon;\u0026sol;\u0026sol;raw\u0026period;githubusercontent\u0026period;com\u0026sol;m-beau\u0026sol;NeuroPyxels\u0026sol;master\u0026sol;images\u0026sol;NeuroPyxels\u0026lowbar;logo\u0026lowbar;final\u0026period;png\u0026quot; width\u0026equals;\u0026quot;150\u0026quot; title\u0026equals;\u0026quot;Neuropyxels\u0026quot; alt\u0026equals;\u0026quot;Neuropixels\u0026quot; align\u0026equals;\u0026quot;right\u0026quot; vspace \u0026equals; \u0026quot;50\u0026quot;\u0026gt;\u003c/title\u003e\n            \u003cstyle\u003e\n/* From extension vscode.github */\n/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n.vscode-dark img[src$=\\#gh-light-mode-only],\n.vscode-light img[src$=\\#gh-dark-mode-only] {\n\tdisplay: none;\n}\n\n\u003c/style\u003e\n            \n        \u003clink rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/markdown.css\"\u003e\n\u003clink rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/highlight.css\"\u003e\n\u003cstyle\u003e\n            body {\n                font-family: -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif;\n                font-size: 14px;\n                line-height: 1.6;\n            }\n        \u003c/style\u003e\n        \u003cstyle\u003e\n.task-list-item {\r\n    list-style-type: none;\r\n}\r\n\r\n.task-list-item-checkbox {\r\n    margin-left: -20px;\r\n    vertical-align: middle;\r\n    pointer-events: none;\r\n}\n\u003c/style\u003e\n\u003cstyle\u003e\n:root {\n  --color-note: #0969da;\n  --color-tip: #1a7f37;\n  --color-warning: #9a6700;\n  --color-severe: #bc4c00;\n  --color-caution: #d1242f;\n  --color-important: #8250df;\n}\n\n\u003c/style\u003e\n\u003cstyle\u003e\n@media (prefers-color-scheme: dark) {\n  :root {\n    --color-note: #2f81f7;\n    --color-tip: #3fb950;\n    --color-warning: #d29922;\n    --color-severe: #db6d28;\n    --color-caution: #f85149;\n    --color-important: #a371f7;\n  }\n}\n\n\u003c/style\u003e\n\u003cstyle\u003e\n.markdown-alert {\n  padding: 0.5rem 1rem;\n  margin-bottom: 16px;\n  color: inherit;\n  border-left: .25em solid #888;\n}\n\n.markdown-alert\u003e:first-child {\n  margin-top: 0\n}\n\n.markdown-alert\u003e:last-child {\n  margin-bottom: 0\n}\n\n.markdown-alert .markdown-alert-title {\n  display: flex;\n  font-weight: 500;\n  align-items: center;\n  line-height: 1\n}\n\n.markdown-alert .markdown-alert-title .octicon {\n  margin-right: 0.5rem;\n  display: inline-block;\n  overflow: visible !important;\n  vertical-align: text-bottom;\n  fill: currentColor;\n}\n\n.markdown-alert.markdown-alert-note {\n  border-left-color: var(--color-note);\n}\n\n.markdown-alert.markdown-alert-note .markdown-alert-title {\n  color: var(--color-note);\n}\n\n.markdown-alert.markdown-alert-important {\n  border-left-color: var(--color-important);\n}\n\n.markdown-alert.markdown-alert-important .markdown-alert-title {\n  color: var(--color-important);\n}\n\n.markdown-alert.markdown-alert-warning {\n  border-left-color: var(--color-warning);\n}\n\n.markdown-alert.markdown-alert-warning .markdown-alert-title {\n  color: var(--color-warning);\n}\n\n.markdown-alert.markdown-alert-tip {\n  border-left-color: var(--color-tip);\n}\n\n.markdown-alert.markdown-alert-tip .markdown-alert-title {\n  color: var(--color-tip);\n}\n\n.markdown-alert.markdown-alert-caution {\n  border-left-color: var(--color-caution);\n}\n\n.markdown-alert.markdown-alert-caution .markdown-alert-title {\n  color: var(--color-caution);\n}\n\n\u003c/style\u003e\n        \n        \u003c/head\u003e\n        \u003cbody class=\"vscode-body vscode-light\"\u003e\n            \u003cp\u003e\u003ca href=\"https://pypi.org/project/npyx/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/npyx.svg\" alt=\"PyPI Version\"\u003e\u003c/a\u003e\n\u003ca href=\"https://doi.org/10.5281/zenodo.5509733\"\u003e\u003cimg src=\"https://zenodo.org/badge/DOI/10.5281/zenodo.5509733.svg\" alt=\"DOI\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/m-beau/NeuroPyxels/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/pypi/l/npyx.svg\" alt=\"License\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pepy.tech/project/npyx\"\u003e\u003cimg src=\"https://static.pepy.tech/badge/npyx\" alt=\"Downloads\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003ch1 id=\"neuropyxels-loading-processing-and-plotting-neuropixels-data-in-python-\"\u003eNeuroPyxels: loading, processing and plotting Neuropixels data in Python\u003c/h1\u003e \u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/NeuroPyxels_logo_final.png\" width=\"150\" title=\"Neuropyxels\" alt=\"Neuropixels\" align=\"right\" vspace = \"50\"\u003e\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003eMaxime Beau, Federico D'Agostino, Ago Lajko, Gabriela Martínez, Michael Häusser \u0026amp; Dimitar Kostadinov.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels\"\u003eNeuroPyxels\u003c/a\u003e (npyx) is a python library built for electrophysiologists using Neuropixels electrodes. This package results from the needs of a pythonist who really did not want to transition to MATLAB to work with Neuropixels: it features a suite of core utility functions for loading, processing and plotting Neuropixels data.\u003c/p\u003e\n\u003cp\u003e❓\u003cstrong\u003eAny questions or issues?\u003c/strong\u003e: \u003ca href=\"https://github.com/Maxime-Beau/Neuropyxels/issues\"\u003eCreate a github issue\u003c/a\u003e to get support, or create a \u003ca href=\"https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request\"\u003epull request\u003c/a\u003e. Alternatively, you can email \u003ca href=\"mailto:maximebeaujeanroch047@gmail.com\"\u003eus: maximebeaujeanroch047[at]gmail[dot]com\u003c/a\u003e. You can also use the \u003ca href=\"neuropixelsgroup.slack.com\"\u003eNeuropixels slack workgroup\u003c/a\u003e.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#%EF%B8%8F-installation\"\u003e⬇️ Installation\u003c/a\u003e\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#-support-and-citing\"\u003e🤗 Support and citing \u003c/a\u003e\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#%EF%B8%8F-documentation\"\u003e🔍️ Documentation\u003c/a\u003e\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#-design-philosophy\"\u003e💡 Design philosophy\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#-directory-structure\"\u003e📁 Directory structure\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#-common-use-cases\"\u003e👉 Common use cases\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#load-recording-metadata\"\u003eLoad recording metadata\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#load-synchronization-channel\"\u003eLoad synchronization channel\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#get-good-units-from-dataset\"\u003eGet good units from dataset\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#load-spike-times-from-unit-u\"\u003eLoad spike times from unit u\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#load-waveforms-from-unit-u\"\u003eLoad waveforms from unit u\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#compute-autocrosscorrelogram-between-2-units\"\u003eCompute auto/crosscorrelogram between 2 units\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#plot-correlograms-and-waveforms-from-unit-u\"\u003ePlot waveform and crosscorrelograms of unit u\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#preprocess-your-waveforms-drift-shift-matching-and-spike-trains-detect-periods-with-few-false-positivenegative\"\u003ePreprocess your waveforms and spike trains\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#plot-chunk-of-raw-data-with-overlaid-units\"\u003ePlot chunk of raw data with overlaid units\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#plot-peri-stimulus-time-histograms-across-neurons-and-conditions\"\u003ePlot peri-stimulus time histograms across neurons and conditions\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#merge-datasets-acquired-on-two-probes-simultaneously\"\u003eMerge datasets acquired on two probes simultaneously\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/m-beau/NeuroPyxels#-bonus-matplotlib-plot-prettifier\"\u003e⭐ Bonus: matplotlib plot prettifier (mplp)\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"️-installation\"\u003e⬇️ Installation:\u003c/h2\u003e\n\u003cp\u003eWe recommend using a conda environment. Pre-existing packages on a python installation might be incompatible with npyx and break your installation. You can find instructions on setting up a conda environment \u003ca href=\"https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003e  conda create -n my_env python=3.10\n  conda activate my_env\n  pip install npyx\n  \u003cspan class=\"hljs-comment\"\u003e# optionally (see \u0026#x27;Dealing with cupy\u0026#x27; section below):\u003c/span\u003e\n  conda install -c conda-forge cupy cudatoolkit=11.0\n  \u003cspan class=\"hljs-comment\"\u003e# test installation:\u003c/span\u003e\n  python -c \u003cspan class=\"hljs-string\"\u003e\u0026#x27;import npyx\u0026#x27;\u003c/span\u003e \u003cspan class=\"hljs-comment\"\u003e# should not return any error\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eAdvanced installation\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eif you want the very latest version:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003econda create -n my_env python=3.10\nconda activate my_env\npip install git+https://github.com/m-beau/NeuroPyxels@master\n\u003cspan class=\"hljs-comment\"\u003e# optionally (see \u0026#x27;Dealing with cupy\u0026#x27; section below):\u003c/span\u003e\nconda install -c conda-forge cupy cudatoolkit=11.0\n\u003cspan class=\"hljs-comment\"\u003e# test installation:\u003c/span\u003e\npython -c \u003cspan class=\"hljs-string\"\u003e\u0026#x27;import npyx\u0026#x27;\u003c/span\u003e \u003cspan class=\"hljs-comment\"\u003e# should not return any error\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eIf you want to edit npyx locally and eventually contribute:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Tip: in an ipython/jupyter session, use \u003ccode\u003e%load_ext autoreload\u003c/code\u003e then \u003ccode\u003e%autoreload 2\u003c/code\u003e to make your local edits active in your session without having to restart your kernel. Amazing for development.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003econda create -n my_env python=3.10\nconda activate my_env\n\u003cspan class=\"hljs-built_in\"\u003ecd\u003c/span\u003e path/to/save_dir \u003cspan class=\"hljs-comment\"\u003e# any directory where your code will be accessible by your editor and safe. NOT downloads folder.\u003c/span\u003e\ngit \u003cspan class=\"hljs-built_in\"\u003eclone\u003c/span\u003e https://github.com/m-beau/NeuroPyxels\n\u003cspan class=\"hljs-built_in\"\u003ecd\u003c/span\u003e NeuroPyxels\npip install . \u003cspan class=\"hljs-comment\"\u003e# this will create an egg link to save_dir, which means that you do not need to reinstall the package each time you edit it (e.g. after pulling from github).\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# optionally (see \u0026#x27;Dealing with cupy\u0026#x27; section below):\u003c/span\u003e\nconda install -c conda-forge cupy cudatoolkit=11.0\n\u003cspan class=\"hljs-comment\"\u003e# test installation:\u003c/span\u003e\npython -c \u003cspan class=\"hljs-string\"\u003e\u0026#x27;import npyx\u0026#x27;\u003c/span\u003e \u003cspan class=\"hljs-comment\"\u003e# should not return any error\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eand pull every now and then:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"hljs-built_in\"\u003ecd\u003c/span\u003e path/to/save_dir/NeuroPyxels\ngit pull\n\u003cspan class=\"hljs-comment\"\u003e# And that\u0026#x27;s it, thanks to the egg link no need to reinstall the package!\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003c/br\u003e\nNpyx supports Python \u003e=3.7.\n\u003ch3 id=\"dealing-with-cupy-gpu-shenanigans\"\u003eDealing with cupy (GPU shenanigans)\u003c/h3\u003e\n\u003cp\u003eTo run some preprocessing functions, you will need NVIDIA drivers and cuda-toolkit installed on your computer. It is a notorious source of bugs. To test your CUDA installation do the following:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003envidia-smi \u003cspan class=\"hljs-comment\"\u003e# Should show how much your GPU is being used right now\u003c/span\u003e\nnvcc \u003cspan class=\"hljs-comment\"\u003e# This is the CUDA compiler\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIf it doesn't work, try up/downgrading the version of cudatoolkit installed:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"hljs-comment\"\u003e# check the current version\u003c/span\u003e\nconda activate my_env\nconda list cudatoolkit\n\u003cspan class=\"hljs-comment\"\u003e# E.g. install version 10.0\u003c/span\u003e\nconda activate my_env\nconda remove cupy, cudatoolkit\nconda install -c conda-forge cupy cudatoolkit=10.0\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch3 id=\"test-installation\"\u003eTest installation\u003c/h3\u003e\n\u003cp\u003eYou can use the built-in unit testing function 'test_npyx' to make sure that npyx core functions run smoothly, all at once.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.testing \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e test_npyx\n\n\u003cspan class=\"hljs-comment\"\u003e# any spike sorted recording compatible with phy\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# (e.g. kilosort output)\u003c/span\u003e\ndp = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;datapath/to/myrecording\u0026#x27;\u003c/span\u003e\ntest_npyx(dp)\n\n\u003cspan class=\"hljs-comment\"\u003e# if any test fails, re-run them with the following to print the error log, and try to fix it or post an issue on github:\u003c/span\u003e\ntest_npyx(dp, raise_error=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cspan style=\"color:#1F45FC\"\u003e\n\u003cp\u003e--- npyx version 2.3.4 unit testing initiated, on directory /media/maxime/AnalysisSSD/test_dataset_artefact... \u003cbr\u003e\u003c/p\u003e\n\u003cp\u003e--- Successfully ran 'read_metadata' from npyx.inout. \u003cbr\u003e\n--- Successfully ran 'get_npix_sync' from npyx.inout. \u003cbr\u003e\n--- Successfully ran 'get_units' from \u003ca href=\"http://npyx.gl\"\u003enpyx.gl\u003c/a\u003e. \u003cbr\u003e\n--- Successfully ran 'ids' from npyx.spk_t. \u003cbr\u003e\n--- Successfully ran 'trn' from npyx.spk_t. \u003cbr\u003e\n--- Successfully ran 'trn_filtered' from npyx.spk_t. \u003cbr\u003e\n--- Successfully ran 'wvf' from npyx.spk_wvf. \u003cbr\u003e\n--- Successfully ran 'wvf_dsmatch' from npyx.spk_wvf. \u003cbr\u003e\n--- Successfully ran 'get_peak_chan' from npyx.spk_wvf. \u003cbr\u003e\n--- Successfully ran 'templates' from npyx.spk_wvf. \u003cbr\u003e\n--- Successfully ran 'ccg' from npyx.corr. \u003cbr\u003e\n--- Successfully ran 'plot_wvf' from npyx.plot. \u003cbr\u003e\n--- Successfully ran 'plot_ccg' from npyx.plot. \u003cbr\u003e\n--- Successfully ran 'plot_raw' from npyx.plot. \u003cbr\u003e\u003c/p\u003e\n\u003c/span\u003e\n\u003cpre\u003e\u003ccode\u003e(bunch of plots...)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cdetails\u003e\n  \u003csummary\u003e:warning: Known installation issues\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003ecannot import numba.core hence cannot import npyx\u003c/strong\u003e \u003cbr/\u003e\nOlder versions of numba did not feature the .core submodule. If you get this error, you are probably running a too old version of numba. Make sure that you have installed npyx in a fresh conda environment if that happens to you. If you still get an error, check that numba is not installed in your root directory.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-#\"\u003epip uninstall numba\nconda activate my_env\npip uninstall numba\npip install numba\n\u003c/code\u003e\u003c/pre\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cbr/\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003ecore dumped when importing\u003c/strong\u003e \u003cbr/\u003e\nThis seems to be an issue related to PyQt5 required by opencv (opencv-python).\nSolution:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre\u003e\u003ccode\u003e# activate npyx environment first\npip uninstall opencv-python\npip install opencv-python\n# pip install other missing dependencies\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eFull log:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eIn [1]: from npyx import *\nIn [2]: QObject::moveToThread: Current thread (0x5622e1ea6800) is not the object's thread (0x5622e30e86f0).\nCannot move to target thread (0x5622e1ea6800)\n\nqt.qpa.plugin: Could not load the Qt platform plugin \u0026quot;xcb\u0026quot; in \u0026quot;/home/maxime/miniconda3/envs/npyx/lib/python3.7/site-packages/cv2/qt/plugins\u0026quot; even though it was found.\nThis application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.\n\nAvailable platform plugins are: xcb, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl.\n\nAborted (core dumped)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cbr/\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eI think I installed everything properly, but npyx is not found if I run 'python -c \u0026quot;import npyx\u0026quot; '!\u003c/strong\u003e \u003cbr/\u003e\nTypically:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003eTraceback (most recent call last):\n  File \u003cspan class=\"hljs-string\"\u003e\u0026quot;\u0026lt;stdin\u0026gt;\u0026quot;\u003c/span\u003e, line 1, \u003cspan class=\"hljs-keyword\"\u003ein\u003c/span\u003e \u0026lt;module\u0026gt;\nModuleNotFoundError: No module named \u003cspan class=\"hljs-string\"\u003e\u0026#x27;npyx\u0026#x27;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eMake sure that the python installation that you are using is indeed the version of your new environment. \u003cbr/\u003e\nTo do so, in your terminal, run \u0026quot;which python\u0026quot; on linux/mac or \u0026quot;where python\u0026quot; on windows: the output should be the path to the right environment e.g. \u0026quot;/home/.../anaconda/envs/npyx/bin/python\u0026quot;. If it isn't, try to deactivate/reactivate your conda environment, or make sure you do not have conflicting python installations on your machine.\u003c/p\u003e\n\u003c/details\u003e\n\u003ch2 id=\"-support-and-citing\"\u003e🤗 Support and citing\u003c/h2\u003e\n\u003cp\u003eIf you find Neuropyxels useful in your work, we kindly request that you cite:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eMaxime Beau, Federico D'Agostino, Ago Lajko, Gabriela Martínez, Michael Häusser \u0026amp; Dimitar Kostadinov. (2021). NeuroPyxels: loading, processing and plotting Neuropixels data in python. Zenodo. \u003ca href=\"https://doi.org/10.5281/zenodo.5509733\"\u003ehttps://doi.org/10.5281/zenodo.5509733\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eYou can additionally star this repo using the top-right star button to help it gain more visibility.\u003c/p\u003e\n\u003cp\u003eCheers!\u003c/p\u003e\n\u003ch2 id=\"️-documentation\"\u003e🔍️ Documentation:\u003c/h2\u003e\n\u003cp\u003eNpyx works with the data formatting employed by \u003ca href=\"https://billkarsh.github.io/SpikeGLX/\"\u003eSpikeGLX\u003c/a\u003e and \u003ca href=\"https://open-ephys.org/neuropixels\"\u003eOpenEphys\u003c/a\u003e (binary data and meta data) used in combination with \u003ca href=\"https://phy.readthedocs.io/en/latest/\"\u003ePhy\u003c/a\u003e-compatible spike-sorters (\u003ca href=\"https://github.com/MouseLand/Kilosort\"\u003eKilosort\u003c/a\u003e, \u003ca href=\"https://spyking-circus.readthedocs.io/en/latest/\"\u003eSpyKING CIRCUS\u003c/a\u003e...). \u003cspan style=\"color:pink\"\u003e\u003cstrong\u003eAny dataset compatible with phy can also be analyzed with npyx, in essence.\u003c/strong\u003e\u003c/span\u003e\u003c/p\u003e\n\u003ch3 id=\"-design-philosophy\"\u003e💡 Design philosophy\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://en.wikipedia.org/wiki/Memoization\"\u003eMemoization\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003cins\u003eNpyx is fast because it rarely computes the same thing twice by relying heavily on caching (memoization as purists like to call it)\u003c/ins\u003e - in the background, it saves most relevant outputs (spike trains, waveforms, correlograms...) at \u003cstrong\u003enpix_dataset/npyxMemory\u003c/strong\u003e, from where they are simply reloaded if called again.\u003c/p\u003e\n\u003cp\u003eAn important argument controlling this behaviour is \u003cstrong\u003e\u003ccode\u003eagain\u003c/code\u003e\u003c/strong\u003e (boolean), by default set to False: if True, most npyx functions will recompute their output rather than loading it from npyxMemory. This is important to be aware of this behaviour, as it can lead to mind boggling bugs. For instance, if you load a spike train then re-curate your dataset, e.g. by splitting unit 56 into 504 and 505, the train of the old 'unit 56' will still exist at kilosort_dataset/npyxMemory and you will remain able to load it even though the unit is gone!\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eUbiquitous arguments\u003c/p\u003e\n\u003cp\u003eMost npyx functions take at least one input: \u003cstrong\u003e\u003ccode\u003edp\u003c/code\u003e\u003c/strong\u003e, which is the path to your Neuropixels-phy dataset. You can find a \u003ca href=\"https://phy.readthedocs.io/en/latest/sorting_user_guide/#installation\"\u003efull description of the structure of such datasets\u003c/a\u003e on the phy documentation.\u003c/p\u003e\n\u003cp\u003eOther typical parameters are: \u003cstrong\u003e\u003ccode\u003everbose\u003c/code\u003e\u003c/strong\u003e (whether to print a bunch of informative messages, useful when debugging), \u003cstrong\u003e\u003ccode\u003esaveFig\u003c/code\u003e\u003c/strong\u003e (boolean) and \u003cstrong\u003e\u003ccode\u003esaveDir\u003c/code\u003e\u003c/strong\u003e (whether to save the figure in saveDir for plotting functions).\u003c/p\u003e\n\u003cp\u003eImportantly, \u003cstrong\u003e\u003ccode\u003edp\u003c/code\u003e\u003c/strong\u003e can also be the path to a \u003cstrong\u003emerged dataset\u003c/strong\u003e, generated with \u003ccode\u003enpyx.merge_datasets()\u003c/code\u003e - \u003cins\u003eevery function will run as smoothly on merged datasets as on any regular dataset\u003c/ins\u003e. See below for more details.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eMinimal and modular reliance of spike-sorter output\u003c/p\u003e\n\u003cp\u003eEvery function requires the files \u003ccode\u003emyrecording.ap.meta\u003c/code\u003e/\u003ccode\u003emyrecording.oebin\u003c/code\u003e (metadata from SpikeGLX/OpenEphys), \u003ccode\u003eparams.py\u003c/code\u003e, \u003ccode\u003espike_times.npy\u003c/code\u003e and \u003ccode\u003espike_clusters.npy\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eIf you have started spike sorting, \u003ccode\u003ecluster_groups.tsv\u003c/code\u003e will also be required obviously (will be created filled with 'unsorted' groups if none is found).\u003c/p\u003e\n\u003cp\u003eThen, specific functions will require specific files: loading waveforms with \u003ccode\u003enpyx.spk_wvf.wvf\u003c/code\u003e or extracting your sync channel with \u003ccode\u003enpyx.io.get_npix_sync\u003c/code\u003e require the raw data \u003ccode\u003emyrecording.ap.bin\u003c/code\u003e, \u003ccode\u003enpyx.spk_wvf.templates\u003c/code\u003e the files \u003ccode\u003etemplates.npy\u003c/code\u003e and \u003ccode\u003espike_templates.npy\u003c/code\u003e, and so on. This allows you to only transfer the strictly necassary files for your use case from a machine to the next: for instance, if you only want to make behavioural analysis of spike trains but do not care about the waveforms, you can run \u003ccode\u003eget_npix_sync\u003c/code\u003e on a first machine (which will generate a \u003ccode\u003esync_chan\u003c/code\u003e folder containing extracted onsets/offsets from the sync channel(s)), then exclusively transfer the \u003ccode\u003edataset/sync_chan/\u003c/code\u003e folder along with \u003ccode\u003espike_times.npy\u003c/code\u003e and \u003ccode\u003espike_clusters.npy\u003c/code\u003e (all very light files) on another computer and analyze your data there seemlessly.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"-directory-structure\"\u003e📁 Directory structure\u003c/h3\u003e\n\u003cp\u003eThe \u003cstrong\u003e\u003ccode\u003edp\u003c/code\u003e\u003c/strong\u003e parameter of all npyx functions must be the \u003cstrong\u003eabsolute path to \u003ccode\u003emyrecording\u003c/code\u003e\u003c/strong\u003e below.\u003c/p\u003e\n\u003cp\u003eFor SpikeGLX recordings:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003emyrecording/\n  myrecording.ap.meta\n  params.py\n  spike_times.npy\n  spike_clusters.npy\n  cluster_groups.tsv # optional, if manually curated with phy\n  myrecording.ap.bin # optional, if wanna plot waveforms\n\n  # other kilosort/spyking circus outputs here\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eFor Open-Ephys recordings:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003emyrecording/\n  myrecording.oebin\n  params.py\n  spike_times.npy\n  spike_clusters.npy\n  cluster_groups.tsv # if manually curated with phy\n\n  # other spikesorter outputs here\n\n  continuous/\n    Neuropix-PXI-100.somethingsomething (1, AP...)/\n      continuous.dat # optional, if wanna plot waveforms\n    Neuropix-PXI-100.somethingsomething (2, LFP...)/\n      continuous.dat # optional, if want to plot LFP with plot_raw\n\n  events/\n    Neuropix-PXI-100.somethingsomething (1, AP...)/\n      TTL somethingelse/\n        timestamps.npy # optional, if need to get synchronyzation channel to load with get_npix_sync e.g. to merge datasets\n    Neuropix-PXI-100.somethingsomething (2, LFP...)/\n      TTL somethingelse/\n        timestamps.npy # same timestamps for LFP channel\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch3 id=\"-common-use-cases\"\u003e👉 Common use cases\u003c/h3\u003e\n\u003ch4 id=\"load-recording-metadata\"\u003eLoad recording metadata\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e *\n\ndp = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;datapath/to/myrecording\u0026#x27;\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\"\u003e# load contents of .lf.meta and .ap.meta or .oebin files as python dictionnary.\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# The metadata of the high and lowpass filtered files are in meta[\u0026#x27;highpass\u0026#x27;] and meta[\u0026#x27;lowpass\u0026#x27;]\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# Quite handy to get probe version, sampling frequency, recording length etc\u003c/span\u003e\nmeta = read_metadata(dp) \u003cspan class=\"hljs-comment\"\u003e# works for spikeGLX (contents of .meta files) and open-ephys (contents of .oebin file)\u003c/span\u003e\n\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch4 id=\"load-synchronization-channel\"\u003eLoad synchronization channel\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.inout \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e get_npix_sync \u003cspan class=\"hljs-comment\"\u003e# star import is sufficient, but I like explicit imports!\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\"\u003e# If SpikeGLX: slow the first time, then super fast\u003c/span\u003e\nonsets, offsets = get_npix_sync(dp, filt_key=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;highpass\u0026#x27;\u003c/span\u003e) \u003cspan class=\"hljs-comment\"\u003e# works for spikeGLX (extracted from .ap.bin file) and open-ephys (/events/..AP/TTL/timestamps.npy)\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# onsets/offsets are dictionnaries\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# keys: ids of sync channel where a TTL was detected (0,1,2... for spikeGLX, name of TTL folders in events/..AP for openephys),\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# values: times of up (onsets) or down (offsets) threshold crosses, in seconds.\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch4 id=\"preprocess-binary-data\"\u003ePreprocess binary data\u003c/h4\u003e\n\u003cp\u003eMakes a preprocessed copy of the binary file in dp, moves original binary file at dp/original_data\nThis will be as fast as literally copying your file, with a decent GPU!\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.inout \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e preprocess_binary_file \u003cspan class=\"hljs-comment\"\u003e# star import is sufficient, but I like explicit imports!\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\"\u003e# can perform bandpass filtering (butterworth 3 nodes) and median subtraction (aka common average referenceing, CAR)\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# in the future: ADC realignment (like CatGT), whitening, spatial filtering (experimental).\u003c/span\u003e\nfiltered_fname = preprocess_binary_file(dp, filt_key=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;ap\u0026#x27;\u003c/span\u003e, median_subtract=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e, f_low=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e, f_high=\u003cspan class=\"hljs-number\"\u003e300\u003c/span\u003e, order=\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e, verbose=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch4 id=\"get-good-units-from-dataset\"\u003eGet good units from dataset\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.gl \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e get_units\nunits = get_units(dp, quality=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;good\u0026#x27;\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch4 id=\"load-spike-times-from-unit-u\"\u003eLoad spike times from unit u\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.spk_t \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e trn\nu=\u003cspan class=\"hljs-number\"\u003e234\u003c/span\u003e\nt = trn(dp, u) \u003cspan class=\"hljs-comment\"\u003e# gets all spikes from unit 234, in samples\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch4 id=\"load-waveforms-from-unit-u\"\u003eLoad waveforms from unit u\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.inout \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e read_spikeglx_meta\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.spk_t \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e ids, trn\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.spk_wvf \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e get_peak_chan, wvf, templates\n\n\u003cspan class=\"hljs-comment\"\u003e# returns a random sample of 100 waveforms from unit 234, in uV, across 384 channels\u003c/span\u003e\nwaveforms = wvf(dp, u) \u003cspan class=\"hljs-comment\"\u003e# return array of shape (n_waves, n_samples, n_channels)=(100, 82, 384) by default\u003c/span\u003e\nwaveforms = wvf(dp, u, n_waveforms=\u003cspan class=\"hljs-number\"\u003e1000\u003c/span\u003e, t_waveforms=\u003cspan class=\"hljs-number\"\u003e90\u003c/span\u003e) \u003cspan class=\"hljs-comment\"\u003e# now 1000 random waveforms, 90 samples=3ms long\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\"\u003e# Get the unit peak channel (channel with the biggest amplitude)\u003c/span\u003e\npeak_chan = get_peak_chan(dp,u)\n\u003cspan class=\"hljs-comment\"\u003e# extract the waveforms located on peak channel\u003c/span\u003e\nw=waves[:,:,peak_chan]\n\n\u003cspan class=\"hljs-comment\"\u003e# Extract waveforms of spikes occurring between\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# 0-100s and 300-400s in the recording,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# because that\u0026#x27;s when your mouse sneezed\u003c/span\u003e\nwaveforms = wvf(dp, u, periods=[(\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e100\u003c/span\u003e),(\u003cspan class=\"hljs-number\"\u003e300\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e400\u003c/span\u003e)])\n\n\u003cspan class=\"hljs-comment\"\u003e# alternatively, longer but more flexible:\u003c/span\u003e\nfs=meta[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;highpass\u0026#x27;\u003c/span\u003e][\u003cspan class=\"hljs-string\"\u003e\u0026#x27;sampling_rate\u0026#x27;\u003c/span\u003e]\nt=trn(dp,u)/fs \u003cspan class=\"hljs-comment\"\u003e# convert in s\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# get ids of unit u: all spikes have a unique index in the dataset,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# which is their rank sorted by time (as in spike_times.npy)\u003c/span\u003e\nu_ids = ids(dp,u)\nids=ids(dp,u)[(t\u0026gt;\u003cspan class=\"hljs-number\"\u003e900\u003c/span\u003e)\u0026amp;(t\u0026lt;\u003cspan class=\"hljs-number\"\u003e1000\u003c/span\u003e)]\nmask = (t\u0026lt;\u003cspan class=\"hljs-number\"\u003e100\u003c/span\u003e)|((t\u0026gt;\u003cspan class=\"hljs-number\"\u003e300\u003c/span\u003e)\u0026amp;(t\u0026lt;\u003cspan class=\"hljs-number\"\u003e400\u003c/span\u003e))\nwaves = wvf(dp, u, spike_ids=u_ids[mask])\n\n\u003cspan class=\"hljs-comment\"\u003e# If you want to load the templates instead (faster and does not require binary file):\u003c/span\u003e\ntemp = templates(dp,u) \u003cspan class=\"hljs-comment\"\u003e# return array of shape (n_templates, 82, n_channels)\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch4 id=\"compute-autocrosscorrelogram-between-2-units\"\u003eCompute auto/crosscorrelogram between 2 units\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.corr \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e ccg, ccg_stack\n\n\u003cspan class=\"hljs-comment\"\u003e# returns ccg between 234 and 92 with a binsize of 0.2 and a window of 80\u003c/span\u003e\nc = ccg(dp, [\u003cspan class=\"hljs-number\"\u003e234\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e92\u003c/span\u003e], cbin=\u003cspan class=\"hljs-number\"\u003e0.2\u003c/span\u003e, cwin=\u003cspan class=\"hljs-number\"\u003e80\u003c/span\u003e)\n\n\u003cspan class=\"hljs-comment\"\u003e# Only using spikes from the first and third minutes of recording\u003c/span\u003e\nc = ccg(dp, [\u003cspan class=\"hljs-number\"\u003e234\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e92\u003c/span\u003e], cbin=\u003cspan class=\"hljs-number\"\u003e0.2\u003c/span\u003e, cwin=\u003cspan class=\"hljs-number\"\u003e80\u003c/span\u003e, periods=[(\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e60\u003c/span\u003e), (\u003cspan class=\"hljs-number\"\u003e120\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e180\u003c/span\u003e)])\n\n\u003cspan class=\"hljs-comment\"\u003e# better, compute a big stack of crosscorrelograms with a given name\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# The first time, CCGs will be computed in parallel using all the available CPU cores\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# and it will be saved in the background and, reloadable instantaneously in the future\u003c/span\u003e\nsource_units = [\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e4\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e]\ntarget_units = [\u003cspan class=\"hljs-number\"\u003e6\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e8\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e9\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e10\u003c/span\u003e]\nc_stack = ccg_stack(dp, source_units, target_units, \u003cspan class=\"hljs-number\"\u003e0.2\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e80\u003c/span\u003e, name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;my_relevant_ccg_stack\u0026#x27;\u003c/span\u003e)\nc_stack = ccg_stack(dp, name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;my_relevant_ccg_stack\u0026#x27;\u003c/span\u003e) \u003cspan class=\"hljs-comment\"\u003e# will work to reaload in the future\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch4 id=\"plot-waveform-and-crosscorrelogram-of-unit-u\"\u003ePlot waveform and crosscorrelogram of unit u\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# all plotting functions return matplotlib figures\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.plot \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e plot_wvf, get_peak_chan\n\nu=\u003cspan class=\"hljs-number\"\u003e234\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# plot waveform, 2.8ms around templates center, on 16 channels around peak channel\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# (the peak channel is found automatically, no need to worry about finding it)\u003c/span\u003e\nfig = plot_wvf(dp, u, Nchannels=\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e, t_waveforms=\u003cspan class=\"hljs-number\"\u003e2.8\u003c/span\u003e)\n\n\u003cspan class=\"hljs-comment\"\u003e# But if you wished to get it, simply run\u003c/span\u003e\npeakchannel = get_peak_chan(dp, u)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/wvf.png\" width=\"300\"/\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# plot ccg between 234 and 92\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# as_grid also plot the autocorrelograms\u003c/span\u003e\nfig = plot_ccg(dp, [u,\u003cspan class=\"hljs-number\"\u003e92\u003c/span\u003e], cbin=\u003cspan class=\"hljs-number\"\u003e0.2\u003c/span\u003e, cwin=\u003cspan class=\"hljs-number\"\u003e80\u003c/span\u003e, as_grid=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/ccg.png\" width=\"400\"/\u003e\n\u003ch4 id=\"preprocess-your-waveforms-drift-shift-matching-and-spike-trains-detect-periods-with-few-false-positivenegative\"\u003ePreprocess your waveforms (drift-shift-matching) and spike trains (detect periods with few false positive/negative)\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# all plotting functions return matplotlib figures\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.spk_wvf \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e wvf_dsmatch\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.spk_t \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e trn_filtered\n\n\u003cspan class=\"hljs-comment\"\u003e# wvf_dsmatch subselect \u0026#x27;best looking\u0026#x27; waveforms\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# by first matching them by drift state (Z, peak channel and XY, amplitude on peak channel)\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# then shifting them around to realign them (using the crosscorr of its whole spatial footprint)\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# on the plot, black is the original waveform as it would be plotted in phy,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# green is drift-matched, red is drift-shift matched\u003c/span\u003e\nw_preprocessed = wvf_dsmatch(dp, u, plot_debug=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/dsmatch_example1_driftmatch.png\" width=\"500\"/\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/dsmatch_example1.png\" width=\"350\"/\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# trn_filtered clips the recording in 10s (default) chunks\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# and estimates the false positive/false negative spike sporting rates on such chunks\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# before masking out spikes occurring inside \u0026#x27;bad chunks\u0026#x27;,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# defined as chunks with too high FP OR FN rates (5% and 5% by default)\u003c/span\u003e\nt_preprocessed = trn_filtered(dp, u, plot_debug=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/trnfiltered_example1.png\" width=\"600\"/\u003e\n\u003ch4 id=\"plot-chunk-of-raw-data-with-overlaid-units\"\u003ePlot chunk of raw data with overlaid units\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003eunits = [\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e4\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e6\u003c/span\u003e]\nchannels = np.arange(\u003cspan class=\"hljs-number\"\u003e70\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e250\u003c/span\u003e)\n\u003cspan class=\"hljs-comment\"\u003e# raw data are whitened, high-pass filtered and median-subtracted by default - parameters are explicit below\u003c/span\u003e\nplot_raw_units(dp, times=[\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e0.130\u003c/span\u003e], units = units, channels = channels,\n               colors=[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;orange\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;red\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;limegreen\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;darkgreen\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;cyan\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;navy\u0026#x27;\u003c/span\u003e],\n               lw=\u003cspan class=\"hljs-number\"\u003e1.5\u003c/span\u003e, offset=\u003cspan class=\"hljs-number\"\u003e450\u003c/span\u003e, figsize=(\u003cspan class=\"hljs-number\"\u003e6\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e), Nchan_plot=\u003cspan class=\"hljs-number\"\u003e10\u003c/span\u003e,\n               med_sub=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, whiten=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, hpfilt=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/raw.png\" width=\"400\"/\u003e\n\u003ch4 id=\"plot-peri-stimulus-time-histograms-across-neurons-and-conditions\"\u003ePlot peri-stimulus time histograms across neurons and conditions\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# Explore responses of 3 neurons to 4 categories of events:\u003c/span\u003e\nfs=\u003cspan class=\"hljs-number\"\u003e30000\u003c/span\u003e \u003cspan class=\"hljs-comment\"\u003e# Hz\u003c/span\u003e\nunits=[\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e]\ntrains=[trn(dp,u)/fs \u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e u \u003cspan class=\"hljs-keyword\"\u003ein\u003c/span\u003e units] \u003cspan class=\"hljs-comment\"\u003e# make list of trains of 3 units\u003c/span\u003e\ntrains_str=units \u003cspan class=\"hljs-comment\"\u003e# can give specific names to units here, show on the left of each row\u003c/span\u003e\nevents=[licks, sneezes, visual_stimuli, auditory_stimuli] \u003cspan class=\"hljs-comment\"\u003e# get events corresponding to 4 conditions\u003c/span\u003e\nevents_str=[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;licking\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;sneezing\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;visual_stim\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-string\"\u003e\u0026#x27;auditory_stim\u0026#x27;\u003c/span\u003e] \u003cspan class=\"hljs-comment\"\u003e# can give specific names to events here, show above each column\u003c/span\u003e\nevents_col=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;batlow\u0026#x27;\u003c/span\u003e \u003cspan class=\"hljs-comment\"\u003e# colormap from which the event colors will be drawn\u003c/span\u003e\nfig=summary_psth(trains, trains_str, events, events_str, psthb=\u003cspan class=\"hljs-number\"\u003e10\u003c/span\u003e, psthw=[-\u003cspan class=\"hljs-number\"\u003e750\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e750\u003c/span\u003e],\n                 zscore=\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e, bsl_subtract=\u003cspan class=\"hljs-literal\"\u003eFalse\u003c/span\u003e, bsl_window=[-\u003cspan class=\"hljs-number\"\u003e3000\u003c/span\u003e,-\u003cspan class=\"hljs-number\"\u003e750\u003c/span\u003e], convolve=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e, gsd=\u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e,\n                 events_toplot=[\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e], events_col=events_col, trains_col_groups=trains_col_groups,\n                 title=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e, saveFig=\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e, saveDir=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;~/Downloads\u0026#x27;\u003c/span\u003e, _\u003cspan class=\"hljs-built_in\"\u003eformat\u003c/span\u003e=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;pdf\u0026#x27;\u003c/span\u003e,\n                 figh=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e, figratio=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e, transpose=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e,\n                 as_heatmap=\u003cspan class=\"hljs-literal\"\u003eFalse\u003c/span\u003e,  vmin=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e, center=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e, vmax=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e, cmap_str=\u003cspan class=\"hljs-literal\"\u003eNone\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/psth.png\" width=\"600\"/\u003e\n\u003ch4 id=\"merge-datasets-acquired-on-two-probes-simultaneously\"\u003eMerge datasets acquired on two probes simultaneously\u003c/h4\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# The three recordings need to include the same sync channel.\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.merger \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e merge_datasets\ndps = [\u003cspan class=\"hljs-string\"\u003e\u0026#x27;same_folder/lateralprobe_dataset\u0026#x27;\u003c/span\u003e,\n       \u003cspan class=\"hljs-string\"\u003e\u0026#x27;same_folder/medialprobe_dataset\u0026#x27;\u003c/span\u003e,\n       \u003cspan class=\"hljs-string\"\u003e\u0026#x27;same_folder/anteriorprobe_dataset\u0026#x27;\u003c/span\u003e]\nprobenames = [\u003cspan class=\"hljs-string\"\u003e\u0026#x27;lateral\u0026#x27;\u003c/span\u003e,\u003cspan class=\"hljs-string\"\u003e\u0026#x27;medial\u0026#x27;\u003c/span\u003e,\u003cspan class=\"hljs-string\"\u003e\u0026#x27;anterior\u0026#x27;\u003c/span\u003e]\ndp_dict = {p:dp \u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e p, dp \u003cspan class=\"hljs-keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\"\u003ezip\u003c/span\u003e(dps, probenames)}\n\n\u003cspan class=\"hljs-comment\"\u003e# This will merge the 3 datasets (only relevant information, not the raw data) in a new folder at\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# dp_merged: same_folder/merged_lateralprobe_dataset_medialprobe_dataset_anteriorprobe_dataset\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# where all npyx functions can smoothly run.\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# The only difference is that units now need to be called as floats,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# of format u.x (u=unit id, x=dataset id [0-2]).\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# lateralprobe, medial probe and anteriorprobe x will be respectively 0,1 and 2.\u003c/span\u003e\ndp_merged, datasets_table = merge_datasets(dp_dic)\n\n\n--- Merged data (\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e dataset(s)) will be saved here: /same_folder/merged_lateralprobe_dataset_medialprobe_dataset_anteriorprobe_dataset.\n\n--- Loading spike trains of \u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e datasets...\n\nsync channel extraction directory found: /same_folder/lateralprobe_dataset/sync_chan\nData found on sync channels:\nchan \u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e201\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e4\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e175\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e6\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e28447\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e93609\u003c/span\u003e events).\nWhich channel shall be used to synchronize probes? \u0026gt;\u0026gt;\u0026gt; \u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e\n\nsync channel extraction directory found: /same_folder/medialprobe_dataset/sync_chan\nData found on sync channels:\nchan \u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e201\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e4\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e175\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e6\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e28447\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e93609\u003c/span\u003e events).\nWhich channel shall be used to synchronize probes? \u0026gt;\u0026gt;\u0026gt; \u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e\n\nsync channel extraction directory found: /same_folder/anteriorprobe_dataset/sync_chan\nData found on sync channels:\nchan \u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e201\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e4\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e175\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e6\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e28194\u003c/span\u003e events).\nchan \u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e (\u003cspan class=\"hljs-number\"\u003e93609\u003c/span\u003e events).\nWhich channel shall be used to synchronize probes? \u0026gt;\u0026gt;\u0026gt; \u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e\n\n--- Aligning spike trains of \u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e datasets...\nMore than \u003cspan class=\"hljs-number\"\u003e50\u003c/span\u003e sync signals found - \u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e performance reasons, sub-sampling to \u003cspan class=\"hljs-number\"\u003e50\u003c/span\u003e homogenoeously spaced sync signals to align data.\n\u003cspan class=\"hljs-number\"\u003e50\u003c/span\u003e sync events used \u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e alignement - start-end drift of -\u003cspan class=\"hljs-number\"\u003e3080.633\u003c/span\u003ems\n\n--- Merged spike_times \u003cspan class=\"hljs-keyword\"\u003eand\u003c/span\u003e spike_clusters saved at /same_folder/merged_lateralprobe_dataset_medialprobe_dataset_anteriorprobe_dataset.\n\n--\u0026gt; Merge successful! Use a \u003cspan class=\"hljs-built_in\"\u003efloat\u003c/span\u003e u.x \u003cspan class=\"hljs-keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\"\u003eany\u003c/span\u003e npyx function to call unit u \u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e dataset x:\n- u\u003cspan class=\"hljs-number\"\u003e.0\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e dataset lateralprobe_dataset,\n- u\u003cspan class=\"hljs-number\"\u003e.1\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e dataset medialprobe_dataset,\n- u\u003cspan class=\"hljs-number\"\u003e.2\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e dataset anteriorprobe_dataset.\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cins\u003eNow any npyx function runs on the merged dataset!\u003c/ins\u003e\nUnder the hood, it will create a \u003ccode\u003emerged_dataset_dataset1_dataset2/npyxMemory\u003c/code\u003e folder to save any data computed across dataframes, but will use the original \u003ccode\u003edataset1/npyxMemory\u003c/code\u003e folder to save data related to this dataset exclusively (e.g. waveforms). Hence, there is no redundancy: space and time are saved.\u003c/p\u003e\n\u003cp\u003eThis is also why \u003cins\u003eit is primordial that you do not move your datatasets from their original paths after merging them\u003c/ins\u003e - else, functions ran on merged_dataset1_dataset2 will not know where to go fetch the data! They refer to the paths in \u003ccode\u003emerged_dataset_dataset1_dataset2/datasets_table.csv\u003c/code\u003e. If you really need to, you can move your datasets but do not forget to edit this file accordingly.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# These will work!\u003c/span\u003e\nt = trn(dp_merged, \u003cspan class=\"hljs-number\"\u003e92.1\u003c/span\u003e) \u003cspan class=\"hljs-comment\"\u003e# get spikes of unit 92 in dataset 1 i.e. medialprobe\u003c/span\u003e\nfig=plot_ccg(dp_merged,[\u003cspan class=\"hljs-number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e92.1\u003c/span\u003e, cbin=\u003cspan class=\"hljs-number\"\u003e0.2\u003c/span\u003e, cwin=\u003cspan class=\"hljs-number\"\u003e80\u003c/span\u003e]) \u003cspan class=\"hljs-comment\"\u003e# compute CCG between 2 units across datasets\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003ePS - The spike times are aligned across datasets by modelling the drift between the clocks of the neuropixels headstages linearly: TTL probe 1 = a * TTL probe 1 + b (if a!=1, there is drift between the clocks), so spiketimes_probe2_aligned_to_probe1  = a * spiketimes_probe2 + b\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/ttl1-ttl2_1.png\" width=\"600\"/\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/ttl1-ttl2_2.png\" width=\"600\"/\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/error_dist.png\" width=\"600\"/\u003e\n\u003cbr/\u003e\u003c/p\u003e\n\u003ch3 id=\"-bonus-matplotlib-plot-prettifier\"\u003e⭐ Bonus: matplotlib plot prettifier\u003c/h3\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.plot \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e get_ncolors_cmap\n\n\u003cspan class=\"hljs-comment\"\u003e# allows you to easily extract the (r,g,b) tuples from a matplotlib or crameri colormap\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# to use them in other plots!\u003c/span\u003e\ncolors = get_ncolors_cmap(\u003cspan class=\"hljs-string\"\u003e\u0026#x27;coolwarm\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e10\u003c/span\u003e, plot=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e)\ncolors = get_ncolors_cmap(\u003cspan class=\"hljs-string\"\u003e\u0026#x27;viridis\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e10\u003c/span\u003e, plot=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e)\n\u003cspan class=\"hljs-comment\"\u003e# in a jupyter notebook, will also plot he HTML colormap:\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/colormaps.png\" width=\"600\"/\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e npyx.plot \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e mplp\n\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e matplotlib.pyplot \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e plt\n\n\u003cspan class=\"hljs-comment\"\u003e# mplp() will turn any matplotlib plot into something you can work with.\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# fed up googling around and landing on stack overflow to tweak your figures?\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# just read mplp parameters, they are self-explanatory!\u003c/span\u003e\n\ndf1 = pd.load(\u003cspan class=\"hljs-string\"\u003e\u0026quot;my_dataframe.csv\u0026quot;\u003c/span\u003e)\n\n\u003cspan class=\"hljs-comment\"\u003e# Seaborn figure (seaborn is simply a wrapper for matplotlib):\u003c/span\u003e\nfig = plt.figure()\nsns.scatterplot(data=df1,\n                x=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;popsync\u0026#x27;\u003c/span\u003e, y=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;depth\u0026#x27;\u003c/span\u003e, hue=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;mean_popsync\u0026#x27;\u003c/span\u003e,\n                palette=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;plasma\u0026#x27;\u003c/span\u003e, alpha=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, linewidth=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, edgecolor=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;black\u0026#x27;\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/no_mplp.png\" width=\"600\"/\u003e\n\u003cpre\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"hljs-comment\"\u003e# Same figure, tweaked with mplp():\u003c/span\u003e\nfig = plt.figure()\nsns.scatterplot(data=df1,\n                x=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;popsync\u0026#x27;\u003c/span\u003e, y=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;depth\u0026#x27;\u003c/span\u003e, hue=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;mean_popsync\u0026#x27;\u003c/span\u003e,\n                palette=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;plasma\u0026#x27;\u003c/span\u003e, alpha=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, linewidth=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, edgecolor=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;black\u0026#x27;\u003c/span\u003e)\nmplp(figsize=(\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e), title=\u003cspan class=\"hljs-string\"\u003e\u0026quot;My title\u0026quot;\u003c/span\u003e, ylim=[-\u003cspan class=\"hljs-number\"\u003e10\u003c/span\u003e,-\u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e], xlim=[-\u003cspan class=\"hljs-number\"\u003e40\u003c/span\u003e,\u003cspan class=\"hljs-number\"\u003e60\u003c/span\u003e],\n      xlabel = \u003cspan class=\"hljs-string\"\u003e\u0026quot;My x label (rotated ticks)\u0026quot;\u003c/span\u003e, ylabel=\u003cspan class=\"hljs-string\"\u003e\u0026quot;My y label\u0026quot;\u003c/span\u003e,\n      xtickrot=\u003cspan class=\"hljs-number\"\u003e45\u003c/span\u003e,\n      hide_legend=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e, colorbar=\u003cspan class=\"hljs-literal\"\u003eTrue\u003c/span\u003e,\n      vmin=df[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;mean_popsync\u0026#x27;\u003c/span\u003e].\u003cspan class=\"hljs-built_in\"\u003emin\u003c/span\u003e(), vmax=df[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;mean_popsync\u0026#x27;\u003c/span\u003e].\u003cspan class=\"hljs-built_in\"\u003emax\u003c/span\u003e(),\n      cbar_w=\u003cspan class=\"hljs-number\"\u003e0.03\u003c/span\u003e, cbar_h=\u003cspan class=\"hljs-number\"\u003e0.4\u003c/span\u003e, clabel=\u003cspan class=\"hljs-string\"\u003e\u0026quot;My colorbar label\\n(no more ugly legend!)\u0026quot;\u003c/span\u003e, cmap=\u003cspan class=\"hljs-string\"\u003e\u0026quot;plasma\u0026quot;\u003c/span\u003e,\n      clabel_s=\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e, cticks_s=\u003cspan class=\"hljs-number\"\u003e14\u003c/span\u003e, ticklab_s=\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e,\n      saveFig=saveFig, saveDir=saveDir, figname = \u003cspan class=\"hljs-string\"\u003ef\u0026quot;popsync_\u003cspan class=\"hljs-subst\"\u003e{pair}\u003c/span\u003e\u0026quot;\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/m-beau/NeuroPyxels/master/images/mplp.png\" width=\"600\"/\u003e\n\u003cbr/\u003e\n            \n            \n        \u003c/body\u003e\n        \u003c/html\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-beau%2FNeuroPyxels","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm-beau%2FNeuroPyxels","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-beau%2FNeuroPyxels/lists"}