suite2p icon indicating copy to clipboard operation
suite2p copied to clipboard

BUG: mutiple_functional_channels.ipynb is generating multiple errors

Open ghattasb opened this issue 8 months ago • 0 comments

Describe the issue:

Hi Suite2p team,

I'm working with two functional channels and a single imaging plane, and I'm using the multiple_functional_channels.ipynb example script from your repository to preprocess the data.

However, the script seems to run into several issues when applied to my data configuration. In particular, after running run_s2p() on the first channel, the following line throws a KeyError and when I tried to change that to "save_path0 = opsEnd['save_path0']", it generate another TypeError on a different line "ops['save_path0'] = os.path.join(save_path0,'chan2')"

Reproduce the code example:

import numpy as np
import sys
import os
# option to import from github folder
sys.path.insert(0, 'C:/Users/carse/github/suite2p')
import suite2p
from suite2p.run_s2p import run_s2p

ops = {
        # file paths
        'look_one_level_down': False, # whether to look in all subfolders when searching for tiffs
        'fast_disk': [], # used to store temporary binary file, defaults to save_path0
        'delete_bin': False, # whether to delete binary file after processing
        'h5py_key': 'data', # key in h5 where data array is stored (data should be time x pixels x pixels)
        # main settings
        'nplanes' : 1, # each tiff has these many planes in sequence
        'nchannels' : 2, # each tiff has these many channels per plane
        'functional_chan' : 1, # this channel is used to extract functional ROIs (1-based)
        'diameter':12, # this is the main parameter for cell detection, 2-dimensional if Y and X are different (e.g. [6 12])
        'tau':  1., # this is the main parameter for deconvolution
        'fs': 30,  # sampling rate (total across planes)
        # output settings
        'save_mat': True, # whether to save output as matlab files
        'combined': True, # combine multiple planes into a single result /single canvas for GUI
        # parallel settings
        'num_workers': 0, # 0 to select num_cores, -1 to disable parallelism, N to enforce value
        'num_workers_roi': -1, # 0 to select number of planes, -1 to disable parallelism, N to enforce value
        # registration settings
        'do_registration': True, # whether to register data
        'nimg_init': 200, # subsampled frames for finding reference image
        'batch_size': 200, # number of frames per batch
        'maxregshift': 0.1, # max allowed registration shift, as a fraction of frame max(width and height)
        'align_by_chan' : 1, # when multi-channel, you can align by non-functional channel (1-based)
        'reg_tif': False, # whether to save registered tiffs
        'subpixel' : 10, # precision of subpixel registration (1/subpixel steps)
        # cell detection settings
        'connected': True, # whether or not to keep ROIs fully connected (set to 0 for dendrites)
        'navg_frames_svd': 5000, # max number of binned frames for the SVD
        'nsvd_for_roi': 1000, # max number of SVD components to keep for ROI detection
        'max_iterations': 20, # maximum number of iterations to do cell detection
        'ratio_neuropil': 6., # ratio between neuropil basis size and cell radius
        'ratio_neuropil_to_cell': 3, # minimum ratio between neuropil radius and cell radius
        'tile_factor': 1., # use finer (>1) or coarser (<1) tiles for neuropil estimation during cell detection
        'threshold_scaling': 1., # adjust the automatically determined threshold by this scalar multiplier
        'max_overlap': 0.75, # cells with more overlap than this get removed during triage, before refinement
        'inner_neuropil_radius': 2, # number of pixels to keep between ROI and neuropil donut
        'outer_neuropil_radius': np.inf, # maximum neuropil radius
        'min_neuropil_pixels': 350, # minimum number of pixels in the neuropil
        # deconvolution settings
        'baseline': 'maximin', # baselining mode
        'win_baseline': 60., # window for maximin
        'sig_baseline': 10., # smoothing constant for gaussian filter
        'prctile_baseline': 8.,# optional (whether to use a percentile baseline)
        'neucoeff': .7,  # neuropil coefficient
        'allow_overlap': False,
        'xrange': np.array([0, 0]),
        'yrange': np.array([0, 0]),
      }

# provide an h5 path in 'h5py' or a tiff path in 'data_path'
# db overwrites any ops (allows for experiment specific settings)
db = {
      'h5py': [], # a single h5 file path
      'h5py_key': 'data',
      'look_one_level_down': False, # whether to look in ALL subfolders when searching for tiffs
      'data_path': ['C:/Users/ghattasb/Desktop/imaging/TL27/060825'], # a list of folders with tiffs 
                                             # (or folder of folders with tiffs if look_one_level_down is True, or subfolders is not empty)
      'subfolders': [] # choose subfolders of 'data_path' to look in (optional)
    }
### RUN PIPELINE ON FIRST CHANNEL
opsEnd=run_s2p(ops=ops,db=db)
### SETUP FOR RUNNING ONLY CELL DETECTION ON SECOND CHANNEL
import shutil

# grab fast_disk variable if it is user-specified
if 'fast_disk' in ops and len(ops['fast_disk'])>0:
    fast_disk = ops['fast_disk']
else:
    fast_disk = []
# grab save_path0
save_path0 = opsEnd[0]['save_path0']
# make a new folder for channel 2 save files and binary files
ops1 = []
j=0
for ops in opsEnd:
    # make a chan2 folder inside the save path
    ops['save_path0'] = os.path.join(save_path0,'chan2')
    ops['save_path'] = os.path.join(ops['save_path0'], 'suite2p', 'plane%d'%j)
    os.makedirs(ops['save_path'], exist_ok=True)
    ops['ops_path'] = os.path.join(ops['save_path'],'ops.npy')
    # put binary file there or in user-specified + chan2
    if len(fast_disk)==0:
        fast_disk0 = os.path.join(ops['save_path0'])
    else:
        fast_disk0 = os.path.join(fast_disk0,'chan2')
    ops['fast_disk'] = os.path.join(fast_disk0, 'suite2p', 'plane%d'%j)
    os.makedirs(ops['fast_disk'], exist_ok=True)
    ops['reg_file'] = os.path.join(ops['fast_disk'], 'data.bin')
    # switch meanImg <-> meanImg_chan2
    mimg = ops['meanImg']
    ops['meanImg'] = ops['meanImg_chan2']
    ops['meanImg_chan2'] = mimg
    # copy chan2 reg file to new location
    shutil.copyfile(ops['reg_file_chan2'], ops['reg_file'])
    print('reg_file_chan2 copied to %s'%(ops['reg_file']))
    # save new ops file with paths
    np.save(ops['ops_path'], ops)
    ops1.append(ops.copy())
    j+=1
# save ops across planes in new location
np.save(os.path.join(ops1[0]['save_path0'],'suite2p','ops1.npy'), ops1)

Example input dataset used to reproduce the issue:

No response

Error message:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[3], line 10
      8     fast_disk = []
      9 # grab save_path0
---> 10 save_path0 = opsEnd[0]['save_path0']
     11 # make a new folder for channel 2 save files and binary files
     12 ops1 = []

KeyError: 0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[7], line 16
     13 j=0
     14 for ops in opsEnd:
     15     # make a chan2 folder inside the save path
---> 16     ops['save_path0'] = os.path.join(save_path0,'chan2')
     17     ops['save_path'] = os.path.join(ops['save_path0'], 'suite2p', 'plane%d'%j)
     18     os.makedirs(ops['save_path'], exist_ok=True)

TypeError: 'str' object does not support item assignment

Version information:

suite2p (Python 3.9.21)

Context for the issue:

No response

ghattasb avatar May 11 '25 09:05 ghattasb