Skip to content

Commit 17fad9a

Browse files
Merge pull request #1219 from MouseLand/fix_manual_labeling_gui
Fix manual labeling gui
2 parents 73e9d4d + 8b6cd2c commit 17fad9a

3 files changed

Lines changed: 48 additions & 27 deletions

File tree

suite2p/gui/drawroi.py

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
from ..detection.stats import roi_stats
1919
from ..extraction import preprocess
2020
from ..extraction.dcnv import oasis
21+
from ..extraction.extract import extract_traces
22+
from ..io.binary import BinaryFile
23+
from ..parameters import default_settings
24+
from ..run_s2p import _assign_torch_device
2125

2226

2327
def masks_and_traces(settings, stat_manual, stat_orig):
@@ -27,6 +31,8 @@ def masks_and_traces(settings, stat_manual, stat_orig):
2731
returns: F (ROIs x time), Fneu (ROIs x time), F_chan2, Fneu_chan2, settings, stat
2832
F_chan2 and Fneu_chan2 will be empty if no second channel
2933
"""
34+
# Merge with defaults to ensure all required keys are present
35+
settings = {**default_settings(), **settings}
3036

3137
t0 = time.time()
3238

@@ -35,11 +41,12 @@ def masks_and_traces(settings, stat_manual, stat_orig):
3541
for n in range(len(stat_orig)):
3642
stat_all.append(stat_orig[n])
3743

38-
stat_all = roi_stats(stat_all, settings["Ly"], settings["Lx"], aspect=settings.get("aspect", None),
44+
stat_all = np.array(stat_all)
45+
stat_all = roi_stats(stat_all, settings["Ly"], settings["Lx"],
3946
diameter=settings["diameter"])
4047
cell_masks = [
4148
masks.create_cell_mask(stat, Ly=settings["Ly"], Lx=settings["Lx"],
42-
allow_overlap=settings["allow_overlap"]) for stat in stat_all
49+
allow_overlap=settings["extraction"]["allow_overlap"]) for stat in stat_all
4350
]
4451
cell_pix = masks.create_cell_pix(stat_all, Ly=settings["Ly"], Lx=settings["Lx"])
4552
manual_roi_stats = stat_all[:len(stat_manual)]
@@ -48,13 +55,26 @@ def masks_and_traces(settings, stat_manual, stat_orig):
4855
ypixs=[stat["ypix"] for stat in manual_roi_stats],
4956
xpixs=[stat["xpix"] for stat in manual_roi_stats],
5057
cell_pix=cell_pix,
51-
inner_neuropil_radius=settings["inner_neuropil_radius"],
52-
min_neuropil_pixels=settings["min_neuropil_pixels"],
58+
inner_neuropil_radius=settings["extraction"]["inner_neuropil_radius"],
59+
min_neuropil_pixels=settings["extraction"]["min_neuropil_pixels"],
5360
)
5461
print("Masks made in %0.2f sec." % (time.time() - t0))
5562

56-
F, Fneu, F_chan2, Fneu_chan2 = extract_traces_from_masks(settings, manual_cell_masks,
57-
manual_neuropil_masks)
63+
# Extract traces from binary file
64+
Ly, Lx = settings["Ly"], settings["Lx"]
65+
batch_size = settings["extraction"]["batch_size"]
66+
device = _assign_torch_device(settings["torch_device"])
67+
f_reg = BinaryFile(Ly, Lx, settings["reg_file"])
68+
F, Fneu = extract_traces(f_reg, manual_cell_masks, manual_neuropil_masks, batch_size=batch_size, device=device)
69+
f_reg.close()
70+
71+
# Handle chan2 if present
72+
if "reg_file_chan2" in settings and settings["reg_file_chan2"]:
73+
f_reg_chan2 = BinaryFile(Ly, Lx, settings["reg_file_chan2"])
74+
F_chan2, Fneu_chan2 = extract_traces(f_reg_chan2, manual_cell_masks, manual_neuropil_masks, batch_size=batch_size, device=device)
75+
f_reg_chan2.close()
76+
else:
77+
F_chan2, Fneu_chan2 = None, None
5878

5979
# compute activity statistics for classifier
6080
npix = np.array([stat_orig[n]["npix"] for n in range(len(stat_orig))
@@ -69,7 +89,7 @@ def masks_and_traces(settings, stat_manual, stat_orig):
6989
manual_roi_stats[n]["iplane"] = stat_orig[0]["iplane"]
7090

7191
# subtract neuropil and compute skew, std from F
72-
dF = F - settings["neucoeff"] * Fneu
92+
dF = F - settings["extraction"]["neuropil_coefficient"] * Fneu
7393
sk = stats.skew(dF, axis=1)
7494
sd = np.std(dF, axis=1)
7595

@@ -81,10 +101,10 @@ def masks_and_traces(settings, stat_manual, stat_orig):
81101
np.mean(manual_roi_stats[n]["xpix"])
82102
]
83103

84-
dF = preprocess(F=dF, baseline=settings["baseline"], win_baseline=settings["win_baseline"],
85-
sig_baseline=settings["sig_baseline"], fs=settings["fs"],
86-
prctile_baseline=settings["prctile_baseline"])
87-
spks = oasis(F=dF, batch_size=settings["batch_size"], tau=settings["tau"], fs=settings["fs"])
104+
dF = preprocess(F=dF, baseline=settings["dcnv_preprocess"]["baseline"], win_baseline=settings["dcnv_preprocess"]["win_baseline"],
105+
sig_baseline=settings["dcnv_preprocess"]["sig_baseline"], fs=settings["fs"],
106+
prctile_baseline=settings["dcnv_preprocess"]["prctile_baseline"], device=device)
107+
spks = oasis(F=dF, batch_size=settings["extraction"]["batch_size"], tau=settings["tau"], fs=settings["fs"])
88108

89109
return F, Fneu, F_chan2, Fneu_chan2, spks, settings, manual_roi_stats
90110

@@ -187,7 +207,7 @@ def __init__(self, parent):
187207
self.saveGUI = False
188208
self.closeGUI = QPushButton("Save and Quit")
189209
self.closeGUI.setFont(QtGui.QFont("Arial", 8, QtGui.QFont.Bold))
190-
self.closeGUI.clicked.connect(self.close_GUI)
210+
self.closeGUI.clicked.connect(lambda: self.close_GUI())
191211
self.closeGUI.setEnabled(False)
192212
self.closeGUI.setFixedWidth(100)
193213
self.closeGUI.setStyleSheet(self.styleUnpressed)
@@ -247,9 +267,7 @@ def close_GUI(self):
247267

248268
# Append new stat file with old and save
249269
print("Saving new stat")
250-
stat_all = self.new_stat.copy()
251-
for n in range(len(self.parent.stat)):
252-
stat_all.append(self.parent.stat[n])
270+
stat_all = np.concatenate((self.new_stat, self.parent.stat))
253271
np.save(os.path.join(self.parent.basename, "stat.npy"), stat_all)
254272
iscell_prob = np.concatenate(
255273
(self.parent.iscell[:, np.newaxis], self.parent.probcell[:, np.newaxis]),
@@ -297,30 +315,26 @@ def normalize_img_add_masks(self):
297315
if i == 0:
298316
mimg = np.zeros((self.Ly, self.Lx), np.float32)
299317
mimg[self.parent.ops["yrange"][0]:self.parent.ops["yrange"][1],
300-
self.parent.ops["xrange"][0]:self.parent.
301-
settings["xrange"][1]] = self.parent.ops["meanImg"][
318+
self.parent.ops["xrange"][0]:self.parent.ops["xrange"][1]] = self.parent.ops["meanImg"][
302319
self.parent.ops["yrange"][0]:self.parent.ops["yrange"][1],
303320
self.parent.ops["xrange"][0]:self.parent.ops["xrange"][1]]
304321

305322
elif i == 1:
306323
mimg = np.zeros((self.Ly, self.Lx), np.float32)
307324
mimg[self.parent.ops["yrange"][0]:self.parent.ops["yrange"][1],
308-
self.parent.ops["xrange"][0]:self.parent.
309-
settings["xrange"][1]] = self.parent.ops["meanImgE"][
325+
self.parent.ops["xrange"][0]:self.parent.ops["xrange"][1]] = self.parent.ops["meanImgE"][
310326
self.parent.ops["yrange"][0]:self.parent.ops["yrange"][1],
311327
self.parent.ops["xrange"][0]:self.parent.ops["xrange"][1]]
312328
elif i == 2:
313329
mimg = np.zeros((self.Ly, self.Lx), np.float32)
314330
mimg[self.parent.ops["yrange"][0]:self.parent.ops["yrange"][1],
315-
self.parent.ops["xrange"][0]:self.parent.
316-
settings["xrange"][1]] = self.parent.ops["Vcorr"]
331+
self.parent.ops["xrange"][0]:self.parent.ops["xrange"][1]] = self.parent.ops["Vcorr"]
317332

318333
else:
319334
mimg = np.zeros((self.Ly, self.Lx), np.float32)
320335
if "max_proj" in self.parent.ops:
321336
mimg[self.parent.ops["yrange"][0]:self.parent.ops["yrange"][1],
322-
self.parent.ops["xrange"][0]:self.parent.
323-
settings["xrange"][1]] = self.parent.ops["max_proj"]
337+
self.parent.ops["xrange"][0]:self.parent.ops["xrange"][1]] = self.parent.ops["max_proj"]
324338

325339
mimg1 = np.percentile(mimg, 1)
326340
mimg99 = np.percentile(mimg, 99)

suite2p/gui/io.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ def save_merge(parent):
501501
(parent.iscell[:, np.newaxis], parent.probcell[:, np.newaxis]), axis=1)
502502
np.save(os.path.join(parent.basename, "iscell.npy"), iscell)
503503

504+
parent.lcell0.setText("%d" % (parent.iscell.sum()))
505+
parent.lcell1.setText("%d" % (parent.iscell.size - parent.iscell.sum()))
504506
parent.notmerged = np.ones(parent.iscell.size, "bool")
505507

506508

suite2p/gui/merge.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def do_merge(parent):
3838
merge_activity_masks(parent)
3939
parent.merged.append(parent.imerge)
4040
parent.update_plot()
41+
io.save_merge(parent)
4142
print(parent.merged)
4243
print("merged ROIs")
4344

@@ -125,10 +126,11 @@ def merge_activity_masks(parent):
125126
if parent.hasred:
126127
F_chan2 = F_chan2.mean(axis=0)
127128
Fneu_chan2 = Fneu_chan2.mean(axis=0)
128-
dF = F - parent.ops["neucoeff"] * Fneu
129+
dF = F - parent.ops["extraction"]["neuropil_coefficient"] * Fneu
129130
# activity stats
130131
stat0["skew"] = stats.skew(dF)
131132
stat0["std"] = dF.std()
133+
stat0["snr"] = 1 - 0.5 * np.diff(dF).var() / dF.var()
132134

133135
spks = oasis(F=dF[np.newaxis, :], batch_size=parent.ops["batch_size"],
134136
tau=parent.ops["tau"], fs=parent.ops["fs"])
@@ -151,9 +153,9 @@ def merge_activity_masks(parent):
151153
# add cell to structs
152154
parent.stat = np.concatenate((parent.stat, np.array([stat0])), axis=0)
153155
parent.stat = roi_stats(parent.stat, parent.Ly, parent.Lx,
154-
aspect=parent.ops.get("aspect", None),
155-
diameter=parent.ops.get("diameter", None),
156-
do_crop=parent.ops.get("soma_crop", 1))
156+
diameter=parent.ops["diameter"],
157+
do_soma_crop=parent.ops["detection"]["soma_crop"],
158+
max_overlap=None)
157159
parent.stat[-1]["lam"] = parent.stat[-1]["lam"] * merged_cells.size
158160
parent.Fcell = np.concatenate((parent.Fcell, F[np.newaxis, :]), axis=0)
159161
parent.Fneu = np.concatenate((parent.Fneu, Fneu[np.newaxis, :]), axis=0)
@@ -182,8 +184,10 @@ def merge_activity_masks(parent):
182184
# recompute binned F
183185
parent.mode_change(parent.activityMode)
184186

187+
# Remove the maskes for the previous cells that were merged.
185188
for n in merged_cells:
186189
parent.stat[n]["inmerge"] = len(parent.stat) - 1
190+
parent.iscell[n] = False
187191
masks.remove_roi(parent, n, i0)
188192
masks.add_roi(parent, len(parent.stat) - 1, i0)
189193
masks.redraw_masks(parent, ypix, xpix)
@@ -262,6 +266,7 @@ def do_merge(self, parent):
262266
merge_activity_masks(parent)
263267
parent.merged.append(parent.imerge)
264268
parent.update_plot()
269+
io.save_merge(parent)
265270

266271
self.cc_row = np.matmul(parent.Fbin[parent.iscell],
267272
parent.Fbin[-1].T) / parent.Fbin.shape[-1]

0 commit comments

Comments
 (0)