Skip to content

Commit bfff9c2

Browse files
authored
Merge pull request #143 from samuelgarcia/some_fix
More explicite root_folder in launcher
2 parents 1ad9eef + dbedcf4 commit bfff9c2

File tree

3 files changed

+61
-46
lines changed

3 files changed

+61
-46
lines changed

spikeinterface_gui/launcher.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,32 @@ class Launcher:
1515
analyzers_folder : str, list or None
1616
Path to the folder containing analyzer folders or a list/dict of analyzer paths.
1717
If None, the user will be prompted to select an analyzer folder.
18+
root_folder: str|Path| None
19+
A folder that is explore to construct the list of analyzers.
20+
When not None analyzer_folders must be None.
1821
backend : str
1922
The backend to use for the GUI. Options are "qt" or "panel".
2023
verbose : bool
2124
If True, enables verbose logging in the GUI.
2225
"""
2326

24-
def __init__(self, analyzer_folders=None, backend="qt", verbose=False):
27+
def __init__(self, analyzer_folders=None, root_folder=None, backend="qt", verbose=False):
2528
from spikeinterface_gui.main import check_folder_is_analyzer
2629

27-
if analyzer_folders is not None:
28-
if isinstance(analyzer_folders, (str, Path)):
29-
# self.analyzer_folders = [
30-
# p for p in Path(analyzer_folders).iterdir() if p.is_dir() and check_folder_is_analyzer(p)
31-
# ]
32-
# @alessio I prefer this which explore also sub folders
33-
self.analyzer_folders = [
34-
f.parent for f in Path(analyzer_folders).glob('**/spikeinterface_info.json') if f.parent.is_dir() and check_folder_is_analyzer(f.parent)
35-
]
36-
elif isinstance(analyzer_folders, (list, tuple)):
37-
self.analyzer_folders = [
38-
p for p in analyzer_folders if isinstance(p, (str, Path)) and check_folder_is_analyzer(p)
39-
]
30+
self.analyzer_folders = None
31+
if root_folder is not None:
32+
assert analyzer_folders is None, "When using root_folder, analyzer_folders must be None"
33+
root_folder = Path(root_folder)
34+
self.analyzer_folders = [
35+
f.parent for f in root_folder.glob('**/spikeinterface_info.json') if check_folder_is_analyzer(f.parent)
36+
] + [
37+
f.parent for f in root_folder.glob('**/.zmetadata') if check_folder_is_analyzer(f.parent)
38+
]
39+
elif analyzer_folders is not None:
40+
if isinstance(analyzer_folders, (list, tuple)):
41+
self.analyzer_folders = [ p for p in analyzer_folders if check_folder_is_analyzer(p) ]
4042
elif isinstance(analyzer_folders, dict):
41-
self.analyzer_folders = {
42-
k: p for k, p in analyzer_folders.items() if isinstance(p, (str, Path)) and check_folder_is_analyzer(p)
43-
}
44-
else:
45-
self.analyzer_folders = None
46-
else:
47-
self.analyzer_folders = None
43+
self.analyzer_folders = { k: p for k, p in analyzer_folders.items() if check_folder_is_analyzer(p)}
4844

4945

5046
self.verbose = verbose
@@ -231,8 +227,12 @@ def _qt_on_launch_clicked(self):
231227
analyzer_path = self.analyzer_path_input.text()
232228
else:
233229
ind = self.analyzer_path_input.currentIndex()
234-
k = list(self.analyzer_folders.keys())[ind]
235-
analyzer_path = str(self.analyzer_folders[k])
230+
if isinstance(self.analyzer_folders, dict):
231+
k = list(self.analyzer_folders.keys())[ind]
232+
analyzer_path = str(self.analyzer_folders[k])
233+
else:
234+
analyzer_path = self.analyzer_folders[ind]
235+
236236

237237
if self.select_recording_checkbox.isChecked():
238238
recording_path = self.recording_path_input.text()

spikeinterface_gui/main.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,20 @@ def run_mainwindow(
138138
return win
139139

140140

141-
def run_launcher(mode="desktop", analyzer_folders=None, address="localhost", port=0, verbose=False):
141+
142+
def run_launcher(mode="desktop", analyzer_folders=None, root_folder=None, address="localhost", port=0, verbose=False):
142143
"""
143144
Run the launcher for the SpikeInterface GUI.
144145
145146
Parameters
146147
----------
147148
mode: 'desktop' | 'app', default: 'desktop'
148149
The backend to use for the GUI.
149-
analyzer_folders: list of str | None, default: None
150-
List of analyzer folders to load. If str, it is a single folder and subfolders are searched.
150+
analyzer_folders: list of str | dict | None, default: None
151+
List of analyzer folders to load.
152+
root_folder: str|Path| None
153+
A folder that is explore to construct the list of analyzers.
154+
When not None analyzer_folders must be None.
151155
address: str, default: "localhost"
152156
The address to use for the web mode. Default is "localhost".
153157
Use "auto-ip" to use the real IP address of the machine.
@@ -161,7 +165,7 @@ def run_launcher(mode="desktop", analyzer_folders=None, address="localhost", por
161165
if mode == "desktop":
162166
from .myqt import QT, mkQApp
163167
app = mkQApp()
164-
launcher = Launcher(analyzer_folders=analyzer_folders, backend="qt", verbose=verbose)
168+
launcher = Launcher(analyzer_folders=analyzer_folders, root_folder=root_folder, backend="qt", verbose=verbose)
165169
app.exec()
166170

167171
elif mode == "web":
@@ -171,7 +175,7 @@ def run_launcher(mode="desktop", analyzer_folders=None, address="localhost", por
171175
from spikeinterface_gui.launcher import panel_gui_view
172176
from spikeinterface_gui.backend_panel import start_server
173177

174-
launcher = Launcher(analyzer_folders=analyzer_folders, backend="panel", verbose=verbose)
178+
launcher = Launcher(analyzer_folders=analyzer_folders, root_folder=root_folder, backend="panel", verbose=verbose)
175179

176180
server, address, port, _ = start_server(
177181
{"/launcher": launcher.layout, "/gui": panel_gui_view},
@@ -202,7 +206,13 @@ def check_folder_is_analyzer(folder):
202206
bool
203207
True if the folder is a valid SortingAnalyzer folder, False otherwise.
204208
"""
209+
if not isinstance(folder, (str, Path)):
210+
return False
211+
205212
folder = Path(folder)
213+
if not folder.is_dir():
214+
return False
215+
206216
if not str(folder).endswith(".zarr"):
207217
spikeinterface_info_file = folder / 'spikeinterface_info.json'
208218
if not spikeinterface_info_file.exists():
@@ -217,10 +227,8 @@ def check_folder_is_analyzer(folder):
217227
else: #zarr folder
218228
import zarr
219229
# Check if the folder contains the necessary files for a SortingAnalyzer
220-
if not folder.exists():
221-
return False
222230
zarr_root = zarr.open(folder, mode='r')
223-
spikeinterface_info = zarr_root.get('spikeinterface_info')
231+
spikeinterface_info = zarr_root.attrs.get('spikeinterface_info')
224232
if spikeinterface_info is None:
225233
return False
226234
if spikeinterface_info.get("object") != "SortingAnalyzer":
@@ -234,7 +242,7 @@ def run_mainwindow_cli():
234242

235243
parser = argparse.ArgumentParser(description='spikeinterface-gui')
236244
parser.add_argument('analyzer_folder', help='SortingAnalyzer folder path', default=None, nargs='?')
237-
parser.add_argument('--analyzer-folders', help='Base folder for launcher mode with multiple analyzer folders', default=None)
245+
parser.add_argument('--root-folder', help='Base folder for launcher mode with multiple analyzer folders', default=None)
238246
parser.add_argument('--mode', help='Mode desktop or web', default='desktop')
239247
parser.add_argument('--no-traces', help='Do not show traces', action='store_true', default=False)
240248
parser.add_argument('--curation', help='Enable curation panel', action='store_true', default=False)
@@ -248,9 +256,9 @@ def run_mainwindow_cli():
248256

249257
analyzer_folder = args.analyzer_folder
250258
if analyzer_folder is None:
251-
print('Running launcher...')
252-
analyzer_folders = args.analyzer_folders
253-
run_launcher(analyzer_folders=analyzer_folders, mode=args.mode, address=args.address, port=args.port, verbose=args.verbose)
259+
if args.verbose:
260+
print('Running launcher...')
261+
run_launcher(root_folder=args.root_folder, mode=args.mode, address=args.address, port=args.port, verbose=args.verbose)
254262
else:
255263
if args.verbose:
256264
print('Loading analyzer...')

spikeinterface_gui/tests/test_mainwindow_qt.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,28 @@ def test_mainwindow(start_app=False, verbose=True, curation=False, only_some_ext
8383
def test_launcher(verbose=True):
8484

8585
# case 1
86-
# analyzer_folders = None
86+
analyzer_folders = None
87+
root_folder = None
88+
8789
# case 2 : explore parent
88-
analyzer_folders = Path(__file__).parent
90+
analyzer_folders = None
91+
root_folder = Path(__file__).parent
92+
8993
# case 3 : list
90-
analyzer_folders = [
91-
Path(__file__).parent / 'my_dataset_small/sorting_analyzer',
92-
Path(__file__).parent / 'my_dataset_big/sorting_analyzer',
93-
]
94+
# analyzer_folders = [
95+
# Path(__file__).parent / 'my_dataset_small/sorting_analyzer',
96+
# Path(__file__).parent / 'my_dataset_big/sorting_analyzer',
97+
# ]
98+
# root_folder = None
99+
94100
# case 4 : dict
95-
analyzer_folders = {
96-
'small' : Path(__file__).parent / 'my_dataset_small/sorting_analyzer',
97-
'big' : Path(__file__).parent / 'my_dataset_big/sorting_analyzer',
98-
}
101+
# analyzer_folders = {
102+
# 'small' : Path(__file__).parent / 'my_dataset_small/sorting_analyzer',
103+
# 'big' : Path(__file__).parent / 'my_dataset_big/sorting_analyzer',
104+
# }
105+
# root_folder = None
99106

100-
win = run_launcher(mode="desktop", analyzer_folders=analyzer_folders, verbose=verbose)
107+
win = run_launcher(mode="desktop", analyzer_folders=analyzer_folders, root_folder=root_folder, verbose=verbose)
101108

102109

103110
if __name__ == '__main__':

0 commit comments

Comments
 (0)