Skip to main content
Ctrl+K
LBM-Suite2p-Python - Home
  • MBO User Hub
  • MBO Github
  • Connect with MBO
  • Installation Guide
  • Usage
    • 1. LBM-Suite2p Quickstart
    • 2. Grid-Search
    • 3. Cell Detection Parameters
  • Discussions
    • 1. Registration
  • Function Demos
  • API
  • Manual Curation (WIP)
  • Notebooks (deprecated)
  • Glossary
  • Image Gallery
  • Show source
  • Suggest edit
  • Open issue
  • .md

Grid-Search

Contents

  • 2.1. Setup
  • 2.2. ROI Detection
    • 2.2.1. Run the Grid Search
    • 2.2.2. Visualizing the Outputs
  • 2.3. Registration Grid Search
    • 2.3.1. Loading a registered tif
    • 2.3.2. Loading a data.bin or raw_data.bin file

2. Grid-Search#

Example Dataset

Example dataset collected by Kevin Barber with Dr. Alipasha Vaziri @ Rockefeller University.

Field

Value

Animal

mk301

Date

2025-03-01

Virus

jGCaMP8s

Framerate

17 Hz

FOV

900 µm × 900 µm

Resolution

2 µm × 2 µm × 16 µm

These are examples of how to use lbm_suite2p_python.run_grid_search().

We run a grid search on a single z-plane.

2.1. Setup#

The workflow is similar to that used in LBM-Suite2p Quickstart.

from pathlib import Path
import suite2p
import mbo_utilities as mbo
import lbm_suite2p_python as lsp

input_tiff = r"D:/W2_DATA/kbarber/2025_03_01/mk301/assembled/plane_07_mk301.tiff"
metadata = mbo.get_metadata(input_tiff)
base_ops = mbo.params_from_metadata(metadata, suite2p.default_ops())

2.2. ROI Detection#

When tuning segmentation parameters, the easiest knobs to turn are threshold_scaling and max_overlap.

Lower threshold_scaling → more candidate ROIs. Higher max_overlap → more overlapping ROIs are kept.

But their effects aren’t linear or always intuitive, so it’s often best to grid search them.

Override a few ops to use Cellpose (anatomical) detection:

base_ops["anatomical_only"] = 3
base_ops["diameter"] = 6
base_ops["flow_threshold"] = 0
base_ops["cellprob_threshold"] = -6
base_ops["max_overlap"] = 1.0

2.2.1. Run the Grid Search#

search_dict = {
    "max_overlap": [0.6, 0.75, 1.0],
    "threshold_scaling": [0.75, 1.0, 1.25]
}

save_path = Path("./grid_search")
save_path.mkdir(exist_ok=True)

lsp.run_grid_search(
    base_ops,
    search_dict,
    input_file=input_tiff,
    save_root=save_path.joinpath("spatial")
)

Each parameter combination will be saved to a subdirectory like:

./grid_search/spatial/
├── max0.60_thr0.75/
├── max0.75_thr1.00/
├── max1.00_thr1.25/
...

2.2.2. Visualizing the Outputs#

You can loop through the results using the saved ops.npy files, then use:

ops = lsp.load_ops("./grid_search/spatial/max0.75_thr1.00/plane0/ops.npy")
print("Accepted ROIs:", ops['iscell'].sum())

Use fpl.ImageWidget, Suite2p’s BinaryFile, or just tifffile to preview motion-corrected frames and masks.

Tip

Some values (like spatial_hp_cp, tau, or high_pass) can interact in non-obvious ways.

Grid searching more than 2 parameters is really the only way to evaluate these interactions, though this can take up a lot of memory and disk space. We encourage making sure ops['keep_data_raw']=False and ops['reg_tif'] = False (they are by default).

This grid search setup is extensible. Just edit search_dict to sweep any combination of Suite2p ops parameters.

2.3. Registration Grid Search#

To evaluate what registration parameters you should use, you can try both enabling two-step registration and lowering the block-size for rigid registration.

Here, we recommend ops["delete_bin"] = True (not default), but ops['reg_tif'] = True to allow comparisons after registration using a tiff rather than a binary file which takes an extra step to load and is not as easily memory mapped.

base_ops["roidetect"] = False

search_dict = {
    "two_step_registration": [False, True],
    "block_size": [[128, 128], [64, 64]]
}

save_path = Path("./grid_search")
save_path.mkdir(exist_ok=True)

lsp.run_grid_search(
    base_ops,
    search_dict,
    input_file=input_tiff,
    save_root=save_path.joinpath("registration")
)

Now, we can use fastplotlib to display the raw and registered movies:

input_tiff is already set to the filepath to our data pre-registration.

We can simply memory map it with tifffile so only frames that are being shown will be loaded.

data = tifffile.memmap(input_tiff)

Loading the registered data takes a bit more effort.

2.3.1. Loading a registered tif#

If you set ops['reg_tiff']=True, you will have an additional reg_tif folder next to your ops.npy suite2p outputs.

You can get a list of a all of the tif files, it loop through them to collect registerd data.

# a list, where each item is the name of the group
groups = list(save_root.iterdir())  

group_dict = {}
for path in groups:
    tifs = mbo.get_files(path, 'tif', 3)
    files = mbo.get_files(path, 'ops.npy', 4)
    group_dict[path.name] = np.concatenate([tifffile.memmap(tif) for tif in tifs])

Preview the results:

iw = fpl.ImageWidget(
    data=[group_dict[key] for key, _ in group_dict.items()],
    names=[key for key, _ in group_dict.items()]
)
iw.show()

2.3.2. Loading a data.bin or raw_data.bin file#

nframes = metadata["num_frames"]
bin_size = int(max(1, nframes // ops["nbinned"], np.round(ops["tau"] * ops["fs"])))

ops = lsp.load_ops(r"./grid_search/registration/two0/plane0/ops.npy")
bin_path = r"./grid_search/registration/two0/plane0/data.bin"

with suite2p.io.BinaryFile(filename=bin_path, Ly=ops["Ly"], Lx=ops["Lx"]) as f:
    registered_data = f.bin_movie(
        bin_size=bin_size,
        bad_frames=ops.get("badframes"),
        y_range=ops["yrange"],
        x_range=ops["xrange"],
    )

You can now use registered_data in the widget.

previous

1. LBM-Suite2p Quickstart

next

3. Cell Detection Parameters

Contents
  • 2.1. Setup
  • 2.2. ROI Detection
    • 2.2.1. Run the Grid Search
    • 2.2.2. Visualizing the Outputs
  • 2.3. Registration Grid Search
    • 2.3.1. Loading a registered tif
    • 2.3.2. Loading a data.bin or raw_data.bin file

By Author name not set

© Copyright 2024, Elizabeth R. Miller Brain Observatory | The Rockefeller University. All Rights Reserved.