diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index 44de9f284..e3efee390 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -41,7 +41,8 @@ jobs: sudo apt-get update sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \ libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \ - libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev + libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev \ + libegl1 # strategy borrowed from vispy for installing opengl libs on windows - name: Install Windows OpenGL if: runner.os == 'Windows' diff --git a/README.md b/README.md index 33a42c0e1..66e3cd083 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ [![GitHub forks](https://img.shields.io/github/forks/MouseLand/suite2p?style=social)](https://github.com/MouseLand/suite2p/) -Pipeline for processing two-photon calcium imaging data. -Copyright (C) 2018 Howard Hughes Medical Institute Janelia Research Campus +Pipeline for processing two-photon calcium imaging data. +Copyright (C) 2018 Howard Hughes Medical Institute Janelia Research Campus suite2p includes the following modules: @@ -25,12 +25,11 @@ suite2p includes the following modules: * Spike detection * Visualization GUI -This code was written by Carsen Stringer and Marius Pachitariu. +This code was written by Carsen Stringer and Marius Pachitariu. For support, please open an [issue](https://github.com/MouseLand/suite2p/issues). -The reference paper is [here](https://www.biorxiv.org/content/early/2017/07/20/061507). -The deconvolution algorithm is based on [this paper](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005423), with settings based on [this paper](http://www.jneurosci.org/content/early/2018/08/06/JNEUROSCI.3339-17.2018). +The reference paper is [here](https://www.biorxiv.org/content/early/2017/07/20/061507). The deconvolution algorithm is based on [this paper](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005423), with settings based on [this paper](http://www.jneurosci.org/content/early/2018/08/06/JNEUROSCI.3339-17.2018). -You can now run suite2p in google colab, no need to locally install: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/MouseLand/suite2p/blob/main/jupyter/run_suite2p_colab_2021.ipynb). Note you do not have access to the GUI via google colab, but you can download the processed files and view them locally in the GUI. +You can now run suite2p in google colab, no need to locally install (although we recommend doing so eventually): [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/MouseLand/suite2p/blob/main/jupyter/run_suite2p_colab_2021.ipynb). Note you do not have access to the GUI via google colab, but you can download the processed files and view them locally in the GUI. See this **twitter [thread](https://twitter.com/marius10p/status/1032804776633880583)** for GUI demonstrations. @@ -47,22 +46,19 @@ Pachitariu, M., Stringer, C., Schröder, S., Dipoppa, M., Rossi, L. F., Carandin ## Read the Documentation at https://suite2p.readthedocs.io/ -## Installation +## Local installation -### Installation for Linux, Windows, and MacOS (intel processors) machines 1. Install an [Anaconda](https://www.anaconda.com/download/) distribution of Python -- Choose **Python 3.8** and your operating system. Note you might need to use an anaconda prompt if you did not add anaconda to the path. 2. Open an anaconda prompt / command prompt with `conda` for **python 3** in the path 3. Create a new environment with `conda create --name suite2p python=3.9`. 4. To activate this new environment, run `conda activate suite2p` -5. (Option 1) You can install the minimal version of suite2p, run `python -m pip install suite2p`. +5. (Option 1) You can install the minimal version of suite2p, run `python -m pip install suite2p`. 6. (Option 2) You can install the GUI version with `python -m pip install suite2p[gui]`. If you're on a zsh server, you may need to use `' '` around the suite2p[gui] call: `python -m pip install 'suite2p[gui]'`. This also installs the NWB dependencies. 7. Now run `python -m suite2p` and you're all set. 8. Running the command `suite2p --version` in the terminal will print the install version of suite2p. For additional dependencies, like h5py, NWB, Scanbox, and server job support, use the command `python -m pip install suite2p[io]`. -If you are running suite2p on Windows or Linux we recommend installing ScanImage Tiff Reader with `pip install scanimage-tiff-reader` (this package is no longer supported on Mac, but may be supported again in the near future, we will change the instructions accordingly if so). - If you have an older `suite2p` environment you can remove it with `conda env remove -n suite2p` before creating a new one. Note you will always have to run **conda activate suite2p** before you run suite2p. Conda ensures mkl_fft and numba run correctly and quickly on your machine. If you want to run jupyter notebooks in this environment, then also `conda install jupyter`. @@ -72,13 +68,11 @@ To **upgrade** the suite2p (package [here](https://pypi.org/project/suite2p/)), pip install --upgrade suite2p ~~~~ -### Installation for Macs with Apple Silicon chips (e.g., M1) -1. Download an iTerm2 terminal from this [link](https://iterm2.com/). Install it into your /Applications folder. If you already have downloaded iTerm, duplicate it and give it whatever name you'd like (e.g., "iterm2Rosetta"). -2. Navigate to the iTerm app you will use, right click it, and then select "Get Info". Check "Open using Rosetta". -3. Open up this iTerm app and follow steps 1 & 2 in the installation section [above](#installation_section) to install anaconda. -4. Use the following command `CONDA_SUBDIR=osx-64 conda create --name suite2p python=3.9` -5. Follow steps 4-7 in the installation section [above](#installation_section) to install the `suite2p` package. +### Dependencies + +This package relies on the awesomeness of [pyqtgraph](http://pyqtgraph.org/), [PyQt6](http://pyqt.sourceforge.net/Docs/PyQt6/), [torch](http://pytorch.org), [numpy](http://www.numpy.org/), [numba](http://numba.pydata.org/numba-doc/latest/user/5minguide.html), [scanimage-tiff-reader](https://vidriotech.gitlab.io/scanimagetiffreader-python/), [scipy](https://www.scipy.org/), [scikit-learn](http://scikit-learn.org/stable/), [tifffile](https://pypi.org/project/tifffile/), [natsort](https://natsort.readthedocs.io/en/master/), and our neural visualization tool [rastermap](https://github.com/MouseLand/rastermap). You can pip install or conda install all of these packages. If having issues with PyQt6, then try to install within it conda install pyqt. On Ubuntu you may need to `sudo apt-get install libegl1` to support PyQt6. Alternatively, you can use PyQt5 by running `pip uninstall PyQt6` and `pip install PyQt5`. If you already have a PyQt version installed, suite2p will not install a new one. +The software has been heavily tested on Windows 10 and Ubuntu 18.04, and less well tested on Mac OS. Please post an [issue](https://github.com/MouseLand/suite2p/issues) if you have installation problems. ### Installing the latest github version of the code @@ -88,16 +82,11 @@ pip install git+https://github.com/MouseLand/suite2p.git ~~~ If you want to download and edit the code, and use that version, -1. Clone the repository with git and `cd suite2p` +1. Clone the repository with git and `cd suite2p` 2. Run `pip install -e .` in that folder -**Common issues** - -If you are on Yosemite Mac OS, PyQt doesn't work, and you won't be able to install suite2p. More recent versions of Mac OS are fine. - -The software has been heavily tested on Windows 10 and Ubuntu 18.04, and less well tested on Mac OS. Please post an issue if you have installation problems. The registration step runs faster on Ubuntu than Windows, so if you have a choice we recommend using the Ubuntu OS. -## Installation for developers +### Installation for developers 1. Clone the repository and `cd suite2p` in an anaconda prompt / command prompt with `conda` for **python 3** in the path 2. Run `conda env create --name suite2p` @@ -131,9 +120,10 @@ Then: ### Using the GUI -![multiselect](gui_images/multiselect.gif) +selecting multiple ROIs in suite2p with Ctrl -suite2p output goes to a folder called "suite2p" inside your save_path, which by default is the same as the data_path. If you ran suite2p in the GUI, it loads the results automatically. Otherwise, load the results with File -> Load results. + +The suite2p output goes to a folder called "suite2p" inside your save_path, which by default is the same as the data_path. If you ran suite2p in the GUI, it loads the results automatically. Otherwise, you can load the results with File -> Load results or by dragging and dropping the stat.npy file into the GUI. The GUI serves two main functions: @@ -148,7 +138,7 @@ The GUI serves two main functions: Main GUI controls (works in all views): -1. Pan = Left-Click + drag +1. Pan = Left-Click + drag 2. Zoom = (Scroll wheel) OR (Right-Click + drag) 3. Full view = Double left-click OR escape key 4. Swap cell = Right-click on the cell @@ -169,32 +159,24 @@ from suite2p.run_s2p import run_s2p ops1 = run_s2p(ops, db) ~~~~ -See our example jupyter notebook [here](jupyter/run_pipeline_tiffs_or_batch.ipynb). It also explains how to batch-run suite2p. +See our example jupyter notebook [here](https://github.com/MouseLand/suite2p/blob/main/jupyter/run_suite2p_colab_2023.ipynb). ## Outputs ~~~~ -F.npy: array of fluorescence traces (ROIs by timepoints) -Fneu.npy: array of neuropil fluorescence traces (ROIs by timepoints) -spks.npy: array of deconvolved traces (ROIs by timepoints) -stat.npy: array of statistics computed for each cell (ROIs by 1) +F.npy: array of fluorescence traces (ROIs by timepoints) +Fneu.npy: array of neuropil fluorescence traces (ROIs by timepoints) +spks.npy: array of deconvolved traces (ROIs by timepoints) +stat.npy: array of statistics computed for each cell (ROIs by 1) ops.npy: options and intermediate outputs iscell.npy: specifies whether an ROI is a cell, first column is 0/1, and second column is probability that the ROI is a cell based on the default classifier ~~~~ -## Dependencies -suite2p relies on the following excellent packages (which are automatically installed with conda/pip if missing): -- [rastermap](https://github.com/MouseLand/rastermap) -- [pyqtgraph](http://pyqtgraph.org/) -- [PyQt5](http://pyqt.sourceforge.net/Docs/PyQt5/) -- [torch](http://pytorch.org) -- [numpy](http://www.numpy.org/) (>=1.16.0) -- [numba](http://numba.pydata.org/numba-doc/latest/user/5minguide.html) -- [scanimage-tiff-reader](https://vidriotech.gitlab.io/scanimagetiffreader-python/) -- [scipy](https://www.scipy.org/) -- [scikit-learn](http://scikit-learn.org/stable/) -- [tifffile](https://pypi.org/project/tifffile/) -- [natsort](https://natsort.readthedocs.io/en/master/) +# License + +Copyright (C) 2023 Howard Hughes Medical Institute Janelia Research Campus, the labs of Carsen Stringer and Marius Pachitariu. + +**This code is licensed under GPL v3 (no redistribution without credit, and no redistribution in private repos, see the [license](LICENSE) for more details).** ### Logo Logo was designed by Shelby Stringer and [Chris Czaja](http://chrisczaja.com/). diff --git a/gui_images/multiselect.gif b/gui_images/multiselect.gif deleted file mode 100644 index 46ff32f42..000000000 Binary files a/gui_images/multiselect.gif and /dev/null differ diff --git a/setup.py b/setup.py index 79ea31356..52713dd44 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ install_deps = ["importlib-metadata", "natsort", - "rastermap>0.1.0", + "rastermap>=0.9.0", "tifffile", "torch>=1.13.1", "numpy>=1.24.3", @@ -11,17 +11,17 @@ "scipy>=1.9.0", "scikit-learn", "cellpose", + "scanimage-tiff-reader>=1.4.1" ] gui_deps = [ - "pyqt5", - "pyqt5-tools", - "pyqt5.sip", + "qtpy", + "pyqt6", + "pyqt6.sip", "pyqtgraph", ] io_deps = [ - "scanimage-tiff-reader>=1.4.1", "paramiko", "nd2", "sbxreader", @@ -40,6 +40,28 @@ "pytest-qt>3.3.0", ] +# check if pyqt/pyside already installed +try: + import PyQt5 + gui_deps.remove("pyqt6") + gui_deps.remove("pyqt6.sip") +except: + pass + +try: + import PySide2 + gui_deps.remove("pyqt6") + gui_deps.remove("pyqt6.sip") +except: + pass + +try: + import PySide6 + gui_deps.remove("pyqt6") + gui_deps.remove("pyqt6.sip") +except: + pass + all_deps = gui_deps + nwb_deps + test_deps + io_deps try: diff --git a/suite2p/__init__.py b/suite2p/__init__.py index 2fa352e50..e4b8c622d 100644 --- a/suite2p/__init__.py +++ b/suite2p/__init__.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .version import version from .default_ops import default_ops diff --git a/suite2p/__main__.py b/suite2p/__main__.py index 59f7c5c92..045feda8c 100644 --- a/suite2p/__main__.py +++ b/suite2p/__main__.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import argparse import numpy as np diff --git a/suite2p/classification/__init__.py b/suite2p/classification/__init__.py index 84b68e9a4..8cdc1eb11 100644 --- a/suite2p/classification/__init__.py +++ b/suite2p/classification/__init__.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .classifier import Classifier from .classify import classify, builtin_classfile, user_classfile \ No newline at end of file diff --git a/suite2p/classification/classifier.py b/suite2p/classification/classifier.py index c9c247031..f8a45ca54 100644 --- a/suite2p/classification/classifier.py +++ b/suite2p/classification/classifier.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from scipy.ndimage import gaussian_filter diff --git a/suite2p/classification/classify.py b/suite2p/classification/classify.py index 73b6bc175..cdf62d68a 100644 --- a/suite2p/classification/classify.py +++ b/suite2p/classification/classify.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from pathlib import Path diff --git a/suite2p/default_ops.py b/suite2p/default_ops.py index 80c907eeb..380408ef9 100644 --- a/suite2p/default_ops.py +++ b/suite2p/default_ops.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .version import version diff --git a/suite2p/detection/__init__.py b/suite2p/detection/__init__.py index 982ca0f59..bb97b8fa6 100644 --- a/suite2p/detection/__init__.py +++ b/suite2p/detection/__init__.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .detect import detect, detection_wrapper, bin_movie from .stats import roi_stats, ROI \ No newline at end of file diff --git a/suite2p/detection/anatomical.py b/suite2p/detection/anatomical.py index 2872c1cc3..93178317f 100644 --- a/suite2p/detection/anatomical.py +++ b/suite2p/detection/anatomical.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from typing import Any, Dict diff --git a/suite2p/detection/chan2detect.py b/suite2p/detection/chan2detect.py index d9a47679f..de34cf3b2 100644 --- a/suite2p/detection/chan2detect.py +++ b/suite2p/detection/chan2detect.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from scipy.ndimage import gaussian_filter diff --git a/suite2p/detection/denoise.py b/suite2p/detection/denoise.py index 58787c7d2..6eaef7a55 100644 --- a/suite2p/detection/denoise.py +++ b/suite2p/detection/denoise.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from typing import List diff --git a/suite2p/detection/detect.py b/suite2p/detection/detect.py index 3e7089d7c..70d11304e 100644 --- a/suite2p/detection/detect.py +++ b/suite2p/detection/detect.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import time import numpy as np diff --git a/suite2p/detection/metrics.py b/suite2p/detection/metrics.py index cc9319d79..3201cb2e7 100644 --- a/suite2p/detection/metrics.py +++ b/suite2p/detection/metrics.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import time import numpy as np diff --git a/suite2p/detection/sourcery.py b/suite2p/detection/sourcery.py index 308658e02..75886cb64 100644 --- a/suite2p/detection/sourcery.py +++ b/suite2p/detection/sourcery.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import math import time diff --git a/suite2p/detection/sparsedetect.py b/suite2p/detection/sparsedetect.py index 2fd20be2d..9b718f515 100644 --- a/suite2p/detection/sparsedetect.py +++ b/suite2p/detection/sparsedetect.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from typing import Tuple, Dict, List, Any from copy import deepcopy diff --git a/suite2p/detection/stats.py b/suite2p/detection/stats.py index d6a9832dc..a21b82aec 100644 --- a/suite2p/detection/stats.py +++ b/suite2p/detection/stats.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from __future__ import annotations diff --git a/suite2p/detection/utils.py b/suite2p/detection/utils.py index cccb80942..b5d5cecb7 100644 --- a/suite2p/detection/utils.py +++ b/suite2p/detection/utils.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from numba import jit diff --git a/suite2p/extraction/__init__.py b/suite2p/extraction/__init__.py index e0e880562..a3f53115c 100644 --- a/suite2p/extraction/__init__.py +++ b/suite2p/extraction/__init__.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .dcnv import preprocess, oasis from .extract import create_masks_and_extract, enhanced_mean_image, extract_traces_from_masks, extraction_wrapper diff --git a/suite2p/extraction/dcnv.py b/suite2p/extraction/dcnv.py index 524a825e5..45d8f55c0 100644 --- a/suite2p/extraction/dcnv.py +++ b/suite2p/extraction/dcnv.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from numba import njit, prange diff --git a/suite2p/extraction/extract.py b/suite2p/extraction/extract.py index 49914397e..8a5093453 100644 --- a/suite2p/extraction/extract.py +++ b/suite2p/extraction/extract.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os import time diff --git a/suite2p/extraction/masks.py b/suite2p/extraction/masks.py index f3941093d..ba1cc22e5 100644 --- a/suite2p/extraction/masks.py +++ b/suite2p/extraction/masks.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from typing import List, Tuple, Dict, Any from itertools import count diff --git a/suite2p/gui/__init__.py b/suite2p/gui/__init__.py index 1b3469a5d..0af7de0f3 100644 --- a/suite2p/gui/__init__.py +++ b/suite2p/gui/__init__.py @@ -1,4 +1,4 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .gui2p import run \ No newline at end of file diff --git a/suite2p/gui/buttons.py b/suite2p/gui/buttons.py index 6e25ec336..c5d48e78f 100644 --- a/suite2p/gui/buttons.py +++ b/suite2p/gui/buttons.py @@ -1,9 +1,9 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QPushButton, QButtonGroup, QLabel, QLineEdit +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QPushButton, QButtonGroup, QLabel, QLineEdit def make_selection(parent): diff --git a/suite2p/gui/classgui.py b/suite2p/gui/classgui.py index e507ca87d..3838fa506 100644 --- a/suite2p/gui/classgui.py +++ b/suite2p/gui/classgui.py @@ -1,12 +1,12 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os import shutil import numpy as np -from PyQt5 import QtGui -from PyQt5.QtWidgets import QDialog, QLabel, QPushButton, QMessageBox, QFileDialog, QListWidget, QGridLayout, QWidget, QAbstractItemView +from qtpy import QtGui +from qtpy.QtWidgets import QDialog, QLabel, QPushButton, QMessageBox, QFileDialog, QListWidget, QGridLayout, QWidget, QAbstractItemView from . import masks from .. import classification diff --git a/suite2p/gui/drawroi.py b/suite2p/gui/drawroi.py index bee73fb40..90e707834 100644 --- a/suite2p/gui/drawroi.py +++ b/suite2p/gui/drawroi.py @@ -1,13 +1,13 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os import time import numpy as np import pyqtgraph as pg -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QPushButton, QLabel, QLineEdit, QMainWindow, QGridLayout, QButtonGroup, QMessageBox, QWidget +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QPushButton, QLabel, QLineEdit, QMainWindow, QGridLayout, QButtonGroup, QMessageBox, QWidget from matplotlib.colors import hsv_to_rgb from scipy import stats diff --git a/suite2p/gui/graphics.py b/suite2p/gui/graphics.py index 9d22c4051..5fe0ef676 100644 --- a/suite2p/gui/graphics.py +++ b/suite2p/gui/graphics.py @@ -1,9 +1,9 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np import pyqtgraph as pg -from PyQt5 import QtCore +from qtpy import QtCore from pyqtgraph import Point from pyqtgraph import functions as fn from pyqtgraph.graphicsItems.ViewBox.ViewBoxMenu import ViewBoxMenu diff --git a/suite2p/gui/gui2p.py b/suite2p/gui/gui2p.py index 531801b6f..a1d4e0c64 100644 --- a/suite2p/gui/gui2p.py +++ b/suite2p/gui/gui2p.py @@ -1,12 +1,12 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os, pathlib, shutil, sys, warnings import numpy as np import pyqtgraph as pg -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QGridLayout, QCheckBox, QLineEdit, QLabel +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QMainWindow, QApplication, QWidget, QGridLayout, QCheckBox, QLineEdit, QLabel from . import menus, io, merge, views, buttons, classgui, traces, graphics, masks from .. import run_s2p, default_ops diff --git a/suite2p/gui/io.py b/suite2p/gui/io.py index 23cab4cfc..49f5db52f 100644 --- a/suite2p/gui/io.py +++ b/suite2p/gui/io.py @@ -1,11 +1,11 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os, time import numpy as np import scipy.io -from PyQt5 import QtGui -from PyQt5.QtWidgets import QFileDialog, QMessageBox +from qtpy import QtGui +from qtpy.QtWidgets import QFileDialog, QMessageBox from . import utils, masks, views, graphics, traces, classgui from .. import io @@ -167,32 +167,34 @@ def enable_views_and_classifier(parent): def load_dialog(parent): - options = QFileDialog.Options() - options |= QFileDialog.DontUseNativeDialog - name = QFileDialog.getOpenFileName(parent, "Open stat.npy", filter="stat.npy", - options=options) + dlg_kwargs = { + "parent": parent, + "caption": "Open stat.npy", + "filter": "stat.npy", + } + name = QFileDialog.getOpenFileName(**dlg_kwargs) parent.fname = name[0] load_proc(parent) - def load_dialog_NWB(parent): - options = QFileDialog.Options() - options |= QFileDialog.DontUseNativeDialog - name = QFileDialog.getOpenFileName(parent, "Open ophys.nwb", filter="*.nwb", - options=options) + dlg_kwargs = { + "parent": parent, + "caption": "Open ophys.nwb", + "filter": "*.nwb", + } + name = QFileDialog.getOpenFileName(**dlg_kwargs) parent.fname = name[0] load_NWB(parent) - def load_dialog_folder(parent): - options = QFileDialog.Options() - options |= QFileDialog.DontUseNativeDialog - name = QFileDialog.getExistingDirectory(parent, "Open folder with planeX folders", - options=options) + dlg_kwargs = { + "parent": parent, + "caption": "Open folder with planeX folders", + } + name = QFileDialog.getExistingDirectory(**dlg_kwargs) parent.fname = name load_folder(parent) - def load_NWB(parent): name = parent.fname print(name) diff --git a/suite2p/gui/masks.py b/suite2p/gui/masks.py index b9637f51f..41bdb47ff 100644 --- a/suite2p/gui/masks.py +++ b/suite2p/gui/masks.py @@ -1,12 +1,12 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from pathlib import Path import matplotlib.cm import numpy as np import pyqtgraph as pg -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QPushButton, QButtonGroup, QLabel, QComboBox, QLineEdit +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QPushButton, QButtonGroup, QLabel, QComboBox, QLineEdit from matplotlib.colors import hsv_to_rgb import suite2p.gui.merge diff --git a/suite2p/gui/menus.py b/suite2p/gui/menus.py index 318ed3b0c..29c8fe60b 100644 --- a/suite2p/gui/menus.py +++ b/suite2p/gui/menus.py @@ -1,8 +1,8 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ -from PyQt5 import QtGui -from PyQt5.QtWidgets import QAction, QMenu +from qtpy import QtGui +from qtpy.QtWidgets import QAction, QMenu from pkg_resources import iter_entry_points from . import reggui, drawroi, merge, io, rungui, visualize, classgui diff --git a/suite2p/gui/merge.py b/suite2p/gui/merge.py index a5291ac49..cdb713db1 100644 --- a/suite2p/gui/merge.py +++ b/suite2p/gui/merge.py @@ -1,11 +1,11 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os import numpy as np import pyqtgraph as pg -from PyQt5 import QtGui -from PyQt5.QtWidgets import QDialog, QLineEdit, QGridLayout, QMessageBox, QLabel, QPushButton, QWidget +from qtpy import QtGui +from qtpy.QtWidgets import QDialog, QLineEdit, QGridLayout, QMessageBox, QLabel, QPushButton, QWidget from scipy import stats from . import masks, io diff --git a/suite2p/gui/reggui.py b/suite2p/gui/reggui.py index 30e213cbd..12e687ec7 100644 --- a/suite2p/gui/reggui.py +++ b/suite2p/gui/reggui.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ # heavily modified script from a pyqt4 release import os @@ -7,9 +7,9 @@ import numpy as np import pyqtgraph as pg -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QStyle -from PyQt5.QtWidgets import QMainWindow, QGridLayout, QCheckBox, QLabel, QLineEdit, QSlider, QFileDialog, QPushButton, QToolButton, QButtonGroup, QWidget +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QStyle +from qtpy.QtWidgets import QMainWindow, QGridLayout, QCheckBox, QLabel, QLineEdit, QSlider, QFileDialog, QPushButton, QToolButton, QButtonGroup, QWidget from scipy.ndimage import gaussian_filter1d from natsort import natsorted from tifffile import imread diff --git a/suite2p/gui/rungui.py b/suite2p/gui/rungui.py index 601aba913..995a01cfe 100644 --- a/suite2p/gui/rungui.py +++ b/suite2p/gui/rungui.py @@ -1,13 +1,13 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ -import glob, json, os, shutil, pathlib +import glob, json, os, shutil, pathlib, sys from datetime import datetime import numpy as np -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QDialog, QLineEdit, QLabel, QPushButton, QWidget, QGridLayout, QButtonGroup, QComboBox, QTextEdit, QFileDialog +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QDialog, QLineEdit, QLabel, QPushButton, QWidget, QGridLayout, QButtonGroup, QComboBox, QTextEdit, QFileDialog from cellpose.models import get_user_models, model_path, MODEL_NAMES @@ -119,8 +119,9 @@ def create_buttons(self): nrkeys = [["nonrigid", "block_size", "snr_thresh", "maxregshiftNR"], ["1Preg", "spatial_hp_reg", "pre_smooth", "spatial_taper"]] cellkeys = [ - "roidetect", "sparse_mode", "denoise", "spatial_scale", "threshold_scaling", - "max_overlap", "max_iterations", "high_pass", "spatial_hp_detect" + "roidetect", "sparse_mode", "denoise", "spatial_scale", "connected", + "threshold_scaling", "max_overlap", "max_iterations", "high_pass", + "spatial_hp_detect" ] anatkeys = [ "anatomical_only", "diameter", "cellprob_threshold", "flow_threshold", @@ -177,6 +178,7 @@ def create_buttons(self): "if 1, run sparse_mode cell detection", "if 1, run PCA denoising on binned movie to improve cell detection", "choose size of ROIs: 0 = multi-scale; 1 = 6 pixels, 2 = 12, 3 = 24, 4 = 48", + "whether or not to require ROIs to be fully connected (set to 0 for dendrites/boutons)", "adjust the automatically determined threshold for finding ROIs by this scalar multiplier", "ROIs with greater than this overlap as a fraction of total pixels will be discarded", "maximum number of iterations for ROI detection", @@ -444,11 +446,14 @@ def run_S2P(self): shutil.copy(os.path.join(self.ops_path, "ops%d.npy" % self.f), ops_file) shutil.copy(os.path.join(self.ops_path, "db%d.npy" % self.f), db_file) self.db = np.load(db_file, allow_pickle=True).item() - print("Running suite2p!") - print("starting process") print(self.db) - self.process.start('python -u -W ignore -m suite2p --ops "%s" --db "%s"' % - (ops_file, db_file)) + print("Running suite2p with command:") + cmd = f"-u -W ignore -m suite2p --ops {ops_file} --db {db_file}" + print("python " + cmd) + self.process.start(sys.executable, cmd.split(" ")) + + #self.process.start('python -u -W ignore -m suite2p --ops "%s" --db "%s"' % + # (ops_file, db_file)) def stop(self): self.finish = False diff --git a/suite2p/gui/traces.py b/suite2p/gui/traces.py index 980bd3eef..fd6a587b3 100644 --- a/suite2p/gui/traces.py +++ b/suite2p/gui/traces.py @@ -1,9 +1,9 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QLabel, QComboBox, QPushButton, QLineEdit, QCheckBox +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QLabel, QComboBox, QPushButton, QLineEdit, QCheckBox def plot_trace(parent): diff --git a/suite2p/gui/utils.py b/suite2p/gui/utils.py index 44ebccbca..80293ea58 100644 --- a/suite2p/gui/utils.py +++ b/suite2p/gui/utils.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from scipy.ndimage.morphology import binary_dilation, binary_fill_holes diff --git a/suite2p/gui/views.py b/suite2p/gui/views.py index 22edc2325..391c281ef 100644 --- a/suite2p/gui/views.py +++ b/suite2p/gui/views.py @@ -1,10 +1,10 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QPushButton, QSlider, QButtonGroup, QLabel, QStyle, QStyleOptionSlider, QApplication -from PyQt5.QtGui import QPainter +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QPushButton, QSlider, QButtonGroup, QLabel, QStyle, QStyleOptionSlider, QApplication +from qtpy.QtGui import QPainter from .. import extraction diff --git a/suite2p/gui/visualize.py b/suite2p/gui/visualize.py index d8dc969a1..d11ed7d36 100644 --- a/suite2p/gui/visualize.py +++ b/suite2p/gui/visualize.py @@ -1,14 +1,14 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import sys import time import numpy as np import pyqtgraph as pg -from PyQt5 import QtGui, QtCore -from PyQt5.QtWidgets import QStyle -from PyQt5.QtWidgets import QWidget, QSlider, QMainWindow, QGridLayout, QStyleOptionSlider, QApplication, QLabel, QLineEdit, QPushButton, QComboBox, QCheckBox +from qtpy import QtGui, QtCore +from qtpy.QtWidgets import QStyle +from qtpy.QtWidgets import QWidget, QSlider, QMainWindow, QGridLayout, QStyleOptionSlider, QApplication, QLabel, QLineEdit, QPushButton, QComboBox, QCheckBox from matplotlib import cm from rastermap.rastermap import Rastermap from scipy.ndimage import gaussian_filter1d @@ -634,8 +634,8 @@ def activate(self): #model = np.load(os.path.join(parent.ops["save_path0"], "embedding.npy")) #model = np.load("embedding.npy", allow_pickle=True).item() self.isort1 = np.argsort(self.model.embedding[:, 0]) - self.u = self.model.u - self.v = self.model.v + self.Usv = self.model.Usv + self.Vsv = self.model.Vsv self.comboBox.addItem("rastermap") #self.isort1, self.isort2 = mapping.main(self.sp,None,self.u,self.sv,self.v) @@ -678,19 +678,16 @@ def compute_map(self): self.mapOn.setEnabled(False) self.tic = time.time() try: - self.model = Rastermap(n_components=ops["n_components"], n_X=ops["n_X"], - nPC=ops["nPC"], init=ops["init"], alpha=ops["alpha"], - K=ops["K"], constraints=ops["constraints"], - annealing=ops["annealing"]) + self.model = Rastermap() self.model.fit(self.sp) #proc = {"embedding": model.embedding, "uv": [model.u, model.v], # "ops": ops, "filename": args.S, "train_time": train_time} #basename, fname = os.path.split(args.S) #np.save(os.path.join(basename, "embedding.npy"), proc) - print("raster map computed in %3.2f s" % (time.time() - self.tic)) self.activate() - except: + except Exception as e: print("Rastermap issue: Interrupted by error (not finished)\n") + print(e) #self.process.start("python -u -W ignore -m rastermap --S %s --ops %s"% # (spath, opspath)) @@ -740,13 +737,9 @@ def sort_time(self): "end_time": -1 } if not hasattr(self, "isort2"): - self.model = Rastermap(n_components=ops["n_components"], - n_X=ops["n_X"], nPC=ops["nPC"], - init=ops["init"], alpha=ops["alpha"], - K=ops["K"], constraints=ops["constraints"], - annealing=ops["annealing"]) - unorm = (self.u**2).sum(axis=0)**0.5 - self.model.fit(self.sp.T, u=self.v * unorm, v=self.u / unorm) + self.model = Rastermap() + #unorm = (self.u**2).sum(axis=0)**0.5 + self.model.fit(self.sp.T, Usv=self.Vsv, Vsv=self.Usv) self.isort2 = np.argsort(self.model.embedding[:, 0]) self.tsort = self.isort2.astype(np.int32) else: @@ -755,7 +748,7 @@ def sort_time(self): def neural_sorting(self, i): if i == 0: - self.isort = np.argsort(self.u[:, int(self.PCedit.text()) - 1]) + self.isort = np.argsort(self.Usv[:, int(self.PCedit.text()) - 1]) elif i == 1: self.isort = self.isort1 if i < 2: diff --git a/suite2p/io/__init__.py b/suite2p/io/__init__.py index affdfacda..1b8dbe3ab 100644 --- a/suite2p/io/__init__.py +++ b/suite2p/io/__init__.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .h5 import h5py_to_binary from .nwb import save_nwb, read_nwb, nwb_to_binary diff --git a/suite2p/io/binary.py b/suite2p/io/binary.py index fde44da18..0ba8c1e80 100644 --- a/suite2p/io/binary.py +++ b/suite2p/io/binary.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from typing import Optional, Tuple, Sequence from contextlib import contextmanager diff --git a/suite2p/io/h5.py b/suite2p/io/h5.py index 95d1ab3bf..fbfe53e8f 100644 --- a/suite2p/io/h5.py +++ b/suite2p/io/h5.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import math diff --git a/suite2p/io/nd2.py b/suite2p/io/nd2.py index e8a8bbac0..7a2c722bc 100644 --- a/suite2p/io/nd2.py +++ b/suite2p/io/nd2.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os import gc diff --git a/suite2p/io/nwb.py b/suite2p/io/nwb.py index 97b044fd6..1f009764b 100644 --- a/suite2p/io/nwb.py +++ b/suite2p/io/nwb.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import datetime import gc diff --git a/suite2p/io/save.py b/suite2p/io/save.py index 08eb7fcf1..74e20b4ef 100644 --- a/suite2p/io/save.py +++ b/suite2p/io/save.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os from natsort import natsorted diff --git a/suite2p/io/sbx.py b/suite2p/io/sbx.py index 693e60aa0..bd1e1ce57 100644 --- a/suite2p/io/sbx.py +++ b/suite2p/io/sbx.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os diff --git a/suite2p/io/server.py b/suite2p/io/server.py index 951eb3f70..da4c9c954 100644 --- a/suite2p/io/server.py +++ b/suite2p/io/server.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import sys, os, time, glob from pathlib import Path diff --git a/suite2p/io/tiff.py b/suite2p/io/tiff.py index 178c75910..bd3a7ee38 100644 --- a/suite2p/io/tiff.py +++ b/suite2p/io/tiff.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import gc import glob diff --git a/suite2p/io/utils.py b/suite2p/io/utils.py index e812f6232..325902654 100644 --- a/suite2p/io/utils.py +++ b/suite2p/io/utils.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import glob import os diff --git a/suite2p/ops/clean.py b/suite2p/ops/clean.py index 19f8312bc..e91c7275a 100644 --- a/suite2p/ops/clean.py +++ b/suite2p/ops/clean.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import argparse diff --git a/suite2p/registration/__init__.py b/suite2p/registration/__init__.py index 76844f97c..b3ae9a00d 100644 --- a/suite2p/registration/__init__.py +++ b/suite2p/registration/__init__.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from .register import (registration_wrapper, save_registration_outputs_to_ops, compute_enhanced_mean_image) diff --git a/suite2p/registration/bidiphase.py b/suite2p/registration/bidiphase.py index be5cdba0a..5a15326ef 100644 --- a/suite2p/registration/bidiphase.py +++ b/suite2p/registration/bidiphase.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import numpy as np from numpy import fft diff --git a/suite2p/registration/metrics.py b/suite2p/registration/metrics.py index 73697e842..cb56dfacf 100644 --- a/suite2p/registration/metrics.py +++ b/suite2p/registration/metrics.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from multiprocessing import Pool diff --git a/suite2p/registration/nonrigid.py b/suite2p/registration/nonrigid.py index 593031cfe..ae0809968 100644 --- a/suite2p/registration/nonrigid.py +++ b/suite2p/registration/nonrigid.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import warnings from typing import Tuple diff --git a/suite2p/registration/register.py b/suite2p/registration/register.py index a2af254fb..7b4cf3478 100644 --- a/suite2p/registration/register.py +++ b/suite2p/registration/register.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import time from os import path diff --git a/suite2p/registration/rigid.py b/suite2p/registration/rigid.py index 94b4f4526..12d63db34 100644 --- a/suite2p/registration/rigid.py +++ b/suite2p/registration/rigid.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from typing import Tuple diff --git a/suite2p/registration/utils.py b/suite2p/registration/utils.py index 77804133f..cc49569e2 100644 --- a/suite2p/registration/utils.py +++ b/suite2p/registration/utils.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import warnings from functools import lru_cache diff --git a/suite2p/registration/zalign.py b/suite2p/registration/zalign.py index aa2db5662..b9df99b64 100644 --- a/suite2p/registration/zalign.py +++ b/suite2p/registration/zalign.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os import time diff --git a/suite2p/run_s2p.py b/suite2p/run_s2p.py index 022068025..45e516893 100644 --- a/suite2p/run_s2p.py +++ b/suite2p/run_s2p.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ import os import shutil diff --git a/suite2p/version.py b/suite2p/version.py index dcf14e201..087f15270 100644 --- a/suite2p/version.py +++ b/suite2p/version.py @@ -1,5 +1,5 @@ """ -Copright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. +Copyright © 2023 Howard Hughes Medical Institute, Authored by Carsen Stringer and Marius Pachitariu. """ from importlib_metadata import metadata as _metadata diff --git a/tutorial/tutorial.md b/tutorial/tutorial.md new file mode 100644 index 000000000..1c06e2b97 --- /dev/null +++ b/tutorial/tutorial.md @@ -0,0 +1,80 @@ +This tutorial will take you through running suite2p and exploring the results in the GUI. + +### 0. Download our example data, or use your own. + +A short recording is available [here](https://drive.google.com/file/d/1Q8OT7mxn9_5jUg1vl48ZQZpw7OYMirrt/view?usp=sharing). It's a subset of frames from one plane in a 3-plane recording. + +### 1. Install suite2p + +There are more details on the readme, but in brief: + +1. Install an [Anaconda](https://www.anaconda.com/download/) distribution of Python -- Choose **Python 3.9** and your operating system. Note you might need to use an anaconda prompt if you did not add anaconda to the path. +2. Open an anaconda prompt / command prompt with `conda` for **python 3** in the path +3. Create a new environment with `conda create --name suite2p python=3.9`. +4. To activate this new environment, run `conda activate suite2p` +5. Install the GUI version with `python -m pip install suite2p[gui]`. If you're on a zsh server, you may need to use `' '` around the suite2p[gui] call: `python -m pip install 'suite2p[gui]'`. +7. Now run `python -m suite2p` and you're all set. +8. Running the command `suite2p --version` in the terminal will print the install version of suite2p. + +For additional dependencies, like h5py, NWB, Scanbox, and server job support, use the command `python -m pip install suite2p[io]`. If using the zsh shell, make sure to use `' '` around the suite2p[io]. + +### 2. Run suite2p on the dataset + +Click `File > Run suite2p`. This will open up a menu with options for running suite2p. Provide suite2p with the folder with the tiffs using `Add directory to data_path`. You can also change the input format with the drop-down menu. If you have an SSD on your computer you can change the `fast_disk` to a folder on the SSD -- this will speed up processing. See details about all parameters [here](https://suite2p.readthedocs.io/en/latest/settings.html). + +There are a few parameters that are important to set: +~~~~ + nplanes, nchannels, tau, fs +~~~~ + +For the tiff provided, this is `nplanes`=1, `nchannels`=1, `tau`=1.25, and `fs`=13. To be able to view the registered and unregistered data after running, turn on `keep_movie_raw` by setting it to 1 (this is recommended the first few times you're running new data through suite2p to help examine the registration quality). + +Otherwise, we recommend using the default settings in most cases. For more zoomed in recordings, you may want to increase `spatial_hp_detect` to 40 or more. For datasets with a lot of nonrigid motion, you may want to decrease the `block_size` to 64, 64. + +You can enable PCA denoising of the data for detection with `denoise` = 1. + +The `threshold_scaling` parameter can be reduced to find more cells, or increased to find fewer cells. Also, the number of iterations can be increased to find more cells -- the maximum number of cells found is 250 * `max_iterations`. + +Click `RUN SUITE2P` to start the processing. + +### 3. Explore the output + +Once suite2p finishes running, you will see the output in the GUI, and you can close the run window. You can see more info [here](https://suite2p.readthedocs.io/en/latest/gui.html) about how to explore your data in the GUI. The main key commands are: + +1. Pan = Left-Click + drag +2. Zoom = (Scroll wheel) OR (Right-Click + drag) +3. Full view = Double left-click OR escape key +4. Swap ROI label = Right-click on the ROI to changes its label (ie, cell to non-cell). +5. Select multiple cells = (Ctrl + left-click) OR (SHIFT + left-click) AND/OR ("Draw selection" button) + +You will see ROIs classified as CELLS on the left, and ROIs classified as NOT CELLS on the right, classified using suite2p's default classifier. You can click on different cells with left-click to see their activity over time + +### 4. Registration quality + +Let's first look at the registration. Click on the menu option `Registration >> View registered binary`. A window will pop up with the binary file loaded (first row) along with the registration shifts (second row), and the fluorescence of a selected ROI (third row). The fourth row can be used for z-registration (not demo'ed here). Since we set `keep_movie_raw`=1, we can click the checkbox `view raw binary` and see the raw movie on the right side. You can select an ROI by typing in the ROI number in the upper right. + +When not playing the movie, you can click on the shift plot and the fluorescence plot to go to a specific point in time in the movie. You can also seek through the movie by clicking the slide bar. The space bar will pause and play the movie. When paused the left and right arrow keys will move the slide bar incrementally. This can allow you to see if the registration looks good or bad. + +Now let's quantify the quality of the registration. Click on the menu option `Registration >> View registration metrics`. A window will pop up with ops[‘regDX’] and ops[‘regPC’] plotted. The ops[‘regPC’]’s are computed by taking the principal components of the registered movie. ops['regPC'][0,0] is the average of the top 500 frames of the 1st PC, ops['regPC'][1,0] is the average of the bottom 500 frames of the 1st PC -- these are what are plotted in the 3 image plots. The first image is the “difference” between the top and the bottom of the PC. The second image is the “merged” image of the top and bottom of the PC. The third image allows you to flip between the top and bottom PCs using the “play” button. The left and right arrow keys will change the PC number (or you can type in a number). The space bar will pause and play the movie. + +If you "play" this movie, ideally you will see different cells lighting up -- this means the PC is activity-based, that's good! (that's what it looks like in the demo tiff). If it looks instead like there are movements of cells in and out of the field of view or translating in the field of view, then this PC corresponds to motion -- this is bad. If the movement is in-plane (cells translating), then the registration could work better with better parameters potentially (maybe decreasing the `block_size` or increasing `maxregshiftNR`). But if the movement is out-of-plane, then no algorithm can fix your data. What you should hope then is that most cells' activity traces are not correlated with this PC over time, and also that any behavioral/other variables you are tracking are not related to this PC. You can see the PC over time in the upper right corner of the plot. You can see some examples of movements [here](https://twitter.com/marius10p/status/1051494533786193920). + +More info about registration is available [here](https://suite2p.readthedocs.io/en/latest/registration.html#). + +### 5. Cell detection + +You can see all the ROIs detected if you go under the Colors bar and set `J: classifier, cell prob`= 0.0 and click enter -- this sets the cell probability threshold to 0.0. Now all ROIs will flip to the left side. Not all of these ROIs will be somatic. For example, you can see that some of them look more like dendrites (elongated), you can color the ROIs by that statistic by clicking `G: aspect_ratio` or typing the letter `g`, these you likely want classified as "NOT CELLS". You will also see very small ROIs, these are likely dendrites passing through the plane, or tips of cells. These we also probably don't want to use. You will also see some big frilly looking cells, these might be part of the neuropil (sums of dendrites) that we don't want to use as a cell either. These will often be classified as "NOT CELLS" because their traces will not be skewed -- you can color all the ROIs by skewness with `S: skew` or letter `s`. + +We can build our own classifier but for now we'll be using the built-in classifier or default classifier that was used when we ran suite2p. This was trained using our own manual curation of GCaMP6s imaging of cells in cortex. Let's set the cell probability threshold to 0.25 and click enter. Now most of the elongated, smaller and/or frilly ROIs are on the right side. You can further classify ROIs yourself by right-clicking to flip the ROI to the other side. The assignment of the ROIs is updated each time you click / change the cell probability, and is available in the output file `iscell.npy`. + +The ROI statistics are available in `stat.npy`. You can see more info about this [here](https://suite2p.readthedocs.io/en/latest/outputs.html#stat-npy-fields). To revisit a past run of suite2p, click `File > Load processed data`. + +### 6. Signal extraction + +From each ROI, we extract the mean activity in the ROI from each timepoint (weighted by the pixel mask in `stat['lam']`), this is the `F` fluorescence matrix saved in `F.npy`. We also compute the mean activity of the pixels surrounding the ROI -- the `Fneu` neuropil matrix saved in `Fneu.npy`. This neuropil activity contributes to the ROI itself so we correct the fluorescence trace of the ROI using the equation `F - 0.7*Fnew`. This corrected trace is then baselined over time and deconvolved to get an estimated spike rate at each timepoint for the ROI. Note that the scaling of this spike rate is arbitrary. Some discussion about it [here](https://suite2p.readthedocs.io/en/latest/FAQ.html#deconvolution-means-what). + +When one cell is selected, the fluorescence, neuropil and deconvolved traces are shown for the chosen cell in the bottom row of the GUI. When multiple cells are selected, you can choose what type of traces to view with the "Activity mode" drop-down menu in the lower left: F: fluorescence; Fneu: neuropil fluorescence; F - 0.7*Fneu: corrected fluorescence; deconvolved: deconvolution of corrected and baselined fluorescence + +You can resize the trace view with the triangle buttons (bigger = ▲, smaller = ▼). If multiple cells are selected, you can vary how much the traces overlap with the +/- buttons. You can select as many cells as you want, but by default only 40 of those will be plotted. You can increase or decrease this number by changing the number in the box below max # plotted. + +The "Activity mode" is also used for the [Rastermap](https://github.com/mouseland/rastermap) visualization to explore patterns in the data -- choosing "deconvolved" is recommended. Click on the menu option `Visualizations >> Visualize selected cells`. This will either show selected cells (if you have selected more than one cell), or all cells on the side of the GUI on which you are clicked (e.g. select an ROI on the CELLS side to show all CELLS). This will open up a window to view all the traces. Click `compute rastermap + PCs` and then you'll see in the terminal that Rastermap is running. Once it runs, you'll see groups of neurons that are active together. You can then move the red box and click `show selected cells in GUI` to see which cells are active together. For more options when running Rastermap, run in a terminal with your `suite2p` environment `python -m rastermap` and then drag and drop your `spks.npy` file. See the Rastermap [github](https://github.com/mouseland/rastermap) for more details.