Skip to content

Commit 76ac9ee

Browse files
Merge branch 'main' into fix-skip-neuropil
2 parents 2231fc2 + eca2c68 commit 76ac9ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+931
-499
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# This workflows will upload a Python Package using Twine when a release is created
2+
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
3+
4+
name: tests
5+
6+
on:
7+
push:
8+
branches:
9+
- main
10+
tags:
11+
- "v*" # Push events to matching v*, i.e. v1.0, v20.15.10
12+
pull_request:
13+
branches:
14+
- main
15+
workflow_dispatch:
16+
17+
jobs:
18+
test:
19+
name: ${{ matrix.platform }} py${{ matrix.python-version }}
20+
runs-on: ${{ matrix.platform }}
21+
strategy:
22+
matrix:
23+
platform: [ubuntu-latest, windows-latest, macos-latest]
24+
python-version: [3.8]
25+
26+
steps:
27+
- uses: actions/checkout@v2
28+
29+
- name: Set up Python ${{ matrix.python-version }}
30+
uses: actions/setup-python@v2
31+
with:
32+
python-version: ${{ matrix.python-version }}
33+
34+
# these libraries, along with pytest-xvfb (added in the `deps` in tox.ini),
35+
# enable testing on Qt on linux
36+
- name: Install Linux libraries
37+
if: runner.os == 'Linux'
38+
run: |
39+
sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \
40+
libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \
41+
libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 pkg-config libhdf5-103 libhdf5-dev
42+
# strategy borrowed from vispy for installing opengl libs on windows
43+
- name: Install Windows OpenGL
44+
if: runner.os == 'Windows'
45+
run: |
46+
git clone --depth 1 git://github.com/pyvista/gl-ci-helpers.git
47+
powershell gl-ci-helpers/appveyor/install_opengl.ps1
48+
# note: if you need dependencies from conda, considering using
49+
# setup-miniconda: https://github.com/conda-incubator/setup-miniconda
50+
# and
51+
# tox-conda: https://github.com/tox-dev/tox-conda
52+
- name: Install dependencies
53+
run: |
54+
python -m pip install --upgrade pip
55+
pip install wheel setuptools tox tox-gh-actions
56+
pip install dvc==1.11.0 pydrive2
57+
- name: Get test data
58+
run: |
59+
dvc pull -r gdrive-travis
60+
# this runs the platform-specific tests declared in tox.ini
61+
- name: Test with tox
62+
run: tox
63+
env:
64+
PLATFORM: ${{ matrix.platform }}
65+
66+
- name: Coverage
67+
uses: codecov/codecov-action@v1

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
Note: Marius and Carsen are currently at The Neuromatch Academy, and we won't do anything Suite2p-related until after the deep learning course!
2+
13
# suite2p <img src="suite2p/logo/logo_unshaded.png" width="250" title="sweet two pea" alt="sweet two pea" align="right" vspace = "50">
24

35
[![Documentation Status](https://readthedocs.org/projects/suite2p/badge/?version=dev)](https://suite2p.readthedocs.io/en/dev/?badge=dev)

benchmarks/registration_metrics.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ def registration_metrics(data_path, tiff_list, ops, nPC=10):
2525
ops['tiff_list'] = tiff_list
2626

2727
result_ops = suite2p.run_s2p(ops)
28+
if not isinstance(result_ops, list) or not isinstance(result_ops, np.ndarray):
29+
result_ops = [result_ops]
2830
metric_results = []
2931
for nplane, result_op in enumerate(result_ops):
3032
offsets = result_op['regDX']

environment.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
name: suite2p
22
channels:
33
- conda-forge
4+
- pytorch
45
dependencies:
5-
- python>=3.7.6,<3.8
6+
- python>=3.8,<3.9
67
- pip
7-
- mkl_fft=1.0.10
8-
- mkl=2019.3
8+
- mkl
99
- tbb
10-
- numpy<1.19.0
11-
- numba<0.50.0
10+
- numpy
11+
- numba
1212
- matplotlib
1313
- scipy
1414
- scikit-learn
15-
- pyqt
15+
- pytorch>=1.7.1
16+
- h5py=2.10.0
1617
- pip:
17-
- h5py==2.10.0
18+
- pyqt5
19+
- pyqt5.sip
1820
- natsort
1921
- rastermap>0.1.0
2022
- tifffile

setup.py

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
11
import setuptools
22

3+
install_deps = ['importlib-metadata',
4+
'natsort',
5+
'rastermap>0.1.0',
6+
'tifffile',
7+
'scanimage-tiff-reader>=1.4.1',
8+
'torch>=1.7.1',
9+
'paramiko',
10+
'numpy>=1.16',
11+
'numba>=0.43.1',
12+
'matplotlib',
13+
'scipy',
14+
'h5py',
15+
'sbxreader',
16+
'scikit-learn',]
17+
18+
gui_deps = [
19+
"pyqt5",
20+
"pyqt5-tools",
21+
"pyqt5.sip",
22+
'pyqtgraph',
23+
'rastermap>0.1.0',
24+
]
25+
data_deps = [
26+
"dvc==1.11.0",
27+
"pydrive2",
28+
]
29+
nwb_deps = [
30+
"pynwb",
31+
]
32+
test_deps = [
33+
'pytest',
34+
'pytest-qt==3.3.0',
35+
]
36+
37+
all_deps = gui_deps + data_deps + nwb_deps
38+
39+
try:
40+
import torch
41+
a = torch.ones(2, 3)
42+
version = int(torch.__version__[2])
43+
if version >= 6:
44+
install_deps.remove('torch')
45+
except:
46+
pass
47+
348
with open("README.md", "r") as fh:
449
long_description = fh.read()
550

@@ -17,24 +62,8 @@
1762
'setuptools_scm',
1863
],
1964
use_scm_version=True,
20-
install_requires=['importlib-metadata',
21-
'natsort',
22-
'rastermap>0.1.0',
23-
'tifffile',
24-
'scanimage-tiff-reader>=1.4.1',
25-
'pyqtgraph',
26-
'paramiko',
27-
'numpy>=1.16',
28-
'numba>=0.43.1',
29-
'matplotlib',
30-
'scipy',
31-
'h5py',
32-
'sbxreader',
33-
'scikit-learn',], # see environment.yml for this info.
34-
tests_require=[
35-
'pytest',
36-
'pytest-qt',
37-
],
65+
install_requires=install_deps,
66+
tests_require=test_deps,
3867
extras_require={
3968
"docs": [
4069
'sphinx>=3.0',
@@ -43,24 +72,10 @@
4372
'sphinx-prompt',
4473
'sphinx-autodoc-typehints',
4574
],
46-
# Note: Available in pypi, but cleaner to install as pyqt from conda.
47-
"gui": [
48-
"pyqt5",
49-
"pyqt5-tools",
50-
"pyqt5.sip",
51-
],
52-
# Note: Not currently available in pip: use conda to install.
53-
"mkl": [
54-
"mkl_fft>=1.0.10",
55-
"mkl>=2019.3",
56-
],
57-
"data": [
58-
"dvc==1.11.0",
59-
"pydrive2",
60-
],
61-
"nwb": [
62-
"pynwb",
63-
]
75+
"gui": gui_deps,
76+
"data": data_deps,
77+
"nwb": nwb_deps,
78+
"all": all_deps
6479
},
6580
include_package_data=True,
6681
classifiers=[

suite2p/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from .run_s2p import run_s2p, default_ops
2-
from .gui import run as run_gui
32
from .detection import ROI
3+
from .version import version
44

55

66
name = "suite2p"

suite2p/__main__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def add_args(parser: argparse.ArgumentParser):
99
parser.add_argument('--single_plane', action='store_true', help='run single plane ops')
1010
parser.add_argument('--ops', default=[], type=str, help='options')
1111
parser.add_argument('--db', default=[], type=str, help='options')
12-
#parser.add_argument('--version', action='store_true', help='print version number.')
12+
parser.add_argument('--version', action='store_true', help='print version number.')
1313
ops0 = default_ops()
1414
for k in ops0.keys():
1515
v = dict(default=ops0[k], help='{0} : {1}'.format(k, ops0[k]))
@@ -59,7 +59,7 @@ def parse_args(parser: argparse.ArgumentParser):
5959

6060
def main():
6161
args, ops = parse_args(add_args(argparse.ArgumentParser(description='Suite2p parameters')))
62-
if 0:#args.version:
62+
if args.version:
6363
print("suite2p v{}".format(version))
6464
elif args.single_plane and args.ops:
6565
from suite2p.run_s2p import run_plane

suite2p/detection/sparsedetect.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,8 @@ def extendROI(ypix, xpix, Ly, Lx,niter=1):
157157
ypix,xpix = yu[:, ix]
158158
return ypix,xpix
159159

160-
def two_comps(mpix0, lam, Th2):
160+
161+
def two_comps(mpix0, lam, Th2):
161162
""" check if splitting ROI increases variance explained
162163
163164
Parameters

suite2p/extraction/dcnv.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def oasis(F: np.ndarray, batch_size: int, tau: float, fs: float) -> np.ndarray:
8282

8383

8484
def preprocess(F: np.ndarray, baseline: str, win_baseline: float,
85-
sig_baseline: float, fs: float, prctile_baseline: float = 0.9) -> np.ndarray:
85+
sig_baseline: float, fs: float, prctile_baseline: float = 8) -> np.ndarray:
8686
""" preprocesses fluorescence traces for spike deconvolution
8787
8888
baseline-subtraction with window 'win_baseline'

suite2p/extraction/extract.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from numba.typed import List
77
from scipy import stats, signal
88
from .masks import create_masks
9+
from ..io import BinaryFile
910

1011
def extract_traces(ops, cell_masks, neuropil_masks, reg_file):
1112
""" extracts activity from reg_file using masks in stat and neuropil_masks
@@ -33,8 +34,9 @@ def extract_traces(ops, cell_masks, neuropil_masks, reg_file):
3334
each element is neuropil pixels in (Ly*Lx) coordinates
3435
GOING TO BE DEPRECATED: size [ncells x npixels] where weights of each mask are elements
3536
36-
reg_file : string
37-
path to registered binary file
37+
reg_file : io.BinaryFile object
38+
io.BinaryFile object that has iter_frames(batch_size=ops['batch_size']) method
39+
3840
3941
Returns
4042
----------------
@@ -58,36 +60,30 @@ def extract_traces(ops, cell_masks, neuropil_masks, reg_file):
5860
F = np.zeros((ncells, nframes),np.float32)
5961
Fneu = np.zeros((ncells, nframes),np.float32)
6062

61-
reg_file = open(reg_file, 'rb')
6263
nimgbatch = int(nimgbatch)
63-
block_size = Ly*Lx*nimgbatch*2
64-
ix = 0
65-
data = 1
66-
neuropil_ipix = None
64+
65+
cell_ipix = [cell_mask[0].astype(np.int64) for cell_mask in cell_masks]
66+
cell_lam = [cell_mask[1].astype(np.float32) for cell_mask in cell_masks]
6767

68-
cell_ipix = List()
69-
[cell_ipix.append(cell_mask[0].astype(np.int64)) for cell_mask in cell_masks]
70-
cell_lam = List()
71-
[cell_lam.append(cell_mask[1].astype(np.float32)) for cell_mask in cell_masks]
7268
if neuropil_masks is not None:
7369
if isinstance(neuropil_masks, np.ndarray) and neuropil_masks.shape[1] == Ly*Lx:
7470
neuropil_masks = [np.nonzero(neuropil_mask)[0] for neuropil_mask in neuropil_masks]
7571
else:
7672
neuropil_masks = [neuropil_mask.astype(np.int64) for neuropil_mask in neuropil_masks]
77-
neuropil_ipix = List()
78-
[neuropil_ipix.append(neuropil_mask) for neuropil_mask in neuropil_masks]
73+
neuropil_ipix = neuropil_masks
7974
neuropil_npix = np.array([len(neuropil_ipixi) for neuropil_ipixi in neuropil_ipix]).astype(np.float32)
75+
else:
76+
neuropil_ipix = None
8077

81-
while data is not None:
82-
buff = reg_file.read(block_size)
83-
data = np.frombuffer(buff, dtype=np.int16, offset=0)
84-
nimg = int(np.floor(data.size / (Ly*Lx)))
78+
ix = 0
79+
for k, (_, data) in enumerate(reg_file.iter_frames(batch_size=ops['batch_size'])):
80+
nimg = data.shape[0]
8581
if nimg == 0:
8682
break
87-
data = np.reshape(data, (-1, Ly, Lx))
8883
inds = ix+np.arange(0,nimg,1,int)
8984
data = np.reshape(data, (nimg,-1)).astype(np.float32)
9085
Fi = np.zeros((ncells, data.shape[0]), np.float32)
86+
9187
# extract traces and neuropil
9288

9389
# (WITHOUT NUMBA)
@@ -127,9 +123,13 @@ def extract_traces_from_masks(ops, cell_masks, neuropil_masks):
127123
128124
"""
129125
F_chan2, Fneu_chan2 = [], []
130-
F, Fneu, ops = extract_traces(ops, cell_masks, neuropil_masks, ops['reg_file'])
126+
with BinaryFile(Ly=ops['Ly'], Lx=ops['Lx'],
127+
read_filename=ops['reg_file']) as f:
128+
F, Fneu, ops = extract_traces(ops, cell_masks, neuropil_masks, f)
131129
if 'reg_file_chan2' in ops:
132-
F_chan2, Fneu_chan2, _ = extract_traces(ops.copy(), cell_masks, neuropil_masks, ops['reg_file_chan2'])
130+
with BinaryFile(Ly=ops['Ly'], Lx=ops['Lx'],
131+
read_filename=ops['reg_file_chan2']) as f:
132+
F_chan2, Fneu_chan2, _ = extract_traces(ops.copy(), cell_masks, neuropil_masks, f)
133133
return F, Fneu, F_chan2, Fneu_chan2, ops
134134

135135
def create_masks_and_extract(ops, stat, cell_masks=None, neuropil_masks=None):

0 commit comments

Comments
 (0)