optimouse 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,263 @@
1
+ """CNMF extraction pipeline step and CLI runner."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import datetime
7
+ import json
8
+ import logging
9
+ import os
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ # Add project root to path
14
+ PROJECT_ROOT = Path(__file__).parent.parent
15
+ if str(PROJECT_ROOT) not in sys.path:
16
+ sys.path.insert(0, str(PROJECT_ROOT))
17
+
18
+ import mesmerize_core as mc
19
+ from modules import extraction
20
+ from pipeline.utils.pipeline_utils import (
21
+ log_and_print,
22
+ memory_manager,
23
+ cleanup_files,
24
+ find_latest_batch,
25
+ )
26
+ from pipeline.utils.config_loader import load_config
27
+
28
+
29
+ def run_cnmf(
30
+ data_path,
31
+ parameters,
32
+ export_path=None,
33
+ mcorr_movie=None,
34
+ ):
35
+ """Run CNMF extraction only.
36
+
37
+ Parameters
38
+ ----------
39
+ data_path : list | Path
40
+ Original data location for metadata logging.
41
+ parameters : dict
42
+ Dictionary containing at least ``params_extraction`` and ``export_path``.
43
+ export_path : str or Path, optional
44
+ Where to store the CNMF outputs.
45
+ mcorr_movie : str or Path, optional
46
+ Path to a motion-corrected movie to use when motion correction was
47
+ performed externally and no batch files are present.
48
+ """
49
+
50
+ log_and_print("Starting CNMF extraction.")
51
+ if export_path is None:
52
+ export_path = Path(parameters["export_path"])
53
+ else:
54
+ export_path = Path(export_path)
55
+ export_path.mkdir(parents=True, exist_ok=True)
56
+
57
+ batch_path = None
58
+ if mcorr_movie is None:
59
+ try:
60
+ batch_path = find_latest_batch(export_path)
61
+ except FileNotFoundError:
62
+ batch_path = None
63
+ if batch_path is None:
64
+ mcorr_movie = _detect_mcorr_movie(
65
+ export_path, parameters.get("params_mcorr", {})
66
+ )
67
+ if mcorr_movie is None:
68
+ raise FileNotFoundError(
69
+ f"No batch file or motion-corrected movie found in {export_path}."
70
+ )
71
+
72
+ if batch_path is None:
73
+ batch_path = export_path / f"batch_{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}.pickle"
74
+ mc.create_batch(batch_path)
75
+ log_and_print(f"Created new batch for CNMF at {batch_path}")
76
+
77
+ with memory_manager("cnmf"):
78
+ params_cnmf = parameters["params_extraction"]
79
+ if mcorr_movie is not None:
80
+ extraction.run_cnmf(
81
+ batch_path,
82
+ None,
83
+ export_path,
84
+ params_cnmf,
85
+ data_path,
86
+ input_movie_path=mcorr_movie,
87
+ )
88
+ else:
89
+ extraction.run_cnmf(batch_path, 0, export_path, params_cnmf, data_path)
90
+
91
+ extraction.create_components_movie(
92
+ batch_path=batch_path, export_path=export_path, excerpt=240
93
+ )
94
+
95
+ postproc_cleanup = parameters.get("params_extra", {}).get("cleanup", True)
96
+ if postproc_cleanup and batch_path is not None:
97
+ cleanup_files(batch_path, export_path, preserve_batch=False)
98
+ elif batch_path is not None:
99
+ log_and_print(
100
+ f"Keeping batch files associated to {batch_path}.", level="warning"
101
+ )
102
+
103
+ return export_path, batch_path
104
+
105
+
106
+ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
107
+ parser = argparse.ArgumentParser()
108
+ parser.add_argument("config_file", nargs="+", help="Input configuration JSON file")
109
+ parser.add_argument(
110
+ "--mcorr-movie",
111
+ dest="mcorr_output",
112
+ default=None,
113
+ help="Path to a motion corrected movie to use if motion correction was skipped",
114
+ )
115
+ parser.add_argument(
116
+ "--mcorr-output",
117
+ dest="mcorr_output",
118
+ default=None,
119
+ help="Path to a motion corrected movie to use if motion correction was skipped",
120
+ )
121
+ return parser.parse_args(argv)
122
+
123
+
124
+ def _deepcopy_dict(data: dict) -> dict:
125
+ return json.loads(json.dumps(data))
126
+
127
+
128
+ def _detect_mcorr_movie(export_path: Path, params_mcorr: dict | None) -> Path | None:
129
+ export_path = Path(export_path)
130
+ params_mcorr = params_mcorr or {}
131
+ preferred = []
132
+ save_format = params_mcorr.get("save_mcorr_movie")
133
+ if save_format:
134
+ save_format = save_format.lower()
135
+ if save_format in {"tif", "tiff"}:
136
+ preferred.append("mcorr_movie.tiff")
137
+ elif save_format == "h5":
138
+ preferred.append("mcorr_movie.h5")
139
+ elif save_format == "bin":
140
+ preferred.append("mcorr_movie.bin")
141
+ elif save_format in {"memmap", "mmap"}:
142
+ preferred.append("*.mmap")
143
+
144
+ fallback = ["mcorr_movie.tiff", "mcorr_movie.h5", "mcorr_movie.bin", "*.mmap"]
145
+ for name in preferred + [n for n in fallback if n not in preferred]:
146
+ if "*" in name:
147
+ candidates = sorted(export_path.glob(name), key=lambda p: p.stat().st_mtime, reverse=True)
148
+ if candidates:
149
+ log_and_print(f"Using motion corrected movie: {candidates[0]}")
150
+ return candidates[0]
151
+ continue
152
+ candidate = export_path / name
153
+ if candidate.exists():
154
+ log_and_print(f"Using motion corrected movie: {candidate}")
155
+ return candidate
156
+ return None
157
+
158
+
159
+ def _process_config(cfg_path: str, args: argparse.Namespace) -> None:
160
+ config = load_config(cfg_path)
161
+
162
+ paths_cfg = config.get("paths", {})
163
+ data_paths = paths_cfg.get("data_paths", [])
164
+ export_paths = paths_cfg.get("export_paths", [])
165
+ concatenation_groups = paths_cfg.get("concatenation_groups", None)
166
+
167
+ logging_cfg = config.get("logging", {})
168
+ if logging_cfg:
169
+ log_path = logging_cfg.get("log_path", os.path.dirname(export_paths[0]))
170
+ log_level = logging_cfg.get("log_level", "INFO")
171
+ else:
172
+ log_path = os.path.dirname(export_paths[0]) if export_paths else Path.cwd()
173
+ log_level = "INFO"
174
+
175
+ os.makedirs(log_path, exist_ok=True)
176
+ log_file = os.path.join(
177
+ log_path, datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".log"
178
+ )
179
+ print("\n")
180
+ print("Log file: " + log_file)
181
+ print("\n")
182
+ logging.basicConfig(
183
+ filename=log_file,
184
+ level=log_level,
185
+ format="%(asctime)s %(levelname)s: %(message)s",
186
+ datefmt="%Y-%m-%d %H:%M:%S",
187
+ )
188
+ logging.info("Starting batch CNMF extraction for data in %s", cfg_path)
189
+
190
+ if concatenation_groups:
191
+ grouped_paths = {}
192
+ for index, path in zip(concatenation_groups, data_paths):
193
+ grouped_paths.setdefault(index, []).append(path)
194
+ grouped_paths_list = list(grouped_paths.values())
195
+ else:
196
+ grouped_paths_list = [[p] for p in data_paths]
197
+
198
+ print("\n🔹 Runs will be processed as follows:")
199
+ for group_num, paths in enumerate(grouped_paths_list, start=1):
200
+ print(f" * Group {group_num}:")
201
+ for p in paths:
202
+ print(f" - {p}")
203
+ print("\n")
204
+
205
+ imaging_cfg = config.get("imaging", {})
206
+ params_extraction_cfg = _deepcopy_dict(config.get("params_extraction", {}))
207
+ extraction_main = params_extraction_cfg.setdefault("main", {})
208
+ if "fr" not in extraction_main and "fr" in imaging_cfg:
209
+ extraction_main["fr"] = imaging_cfg["fr"]
210
+
211
+ base_params = {
212
+ "params_extraction": params_extraction_cfg,
213
+ "params_extra": config.get("params_extra", {}),
214
+ "params_mcorr": config.get("params_mcorr", {}),
215
+ }
216
+
217
+ for i, data_group in enumerate(grouped_paths_list):
218
+ data_group_paths = [Path(p) for p in data_group]
219
+ print(f"\n🔹 Processing Group {i+1}:")
220
+ print(" Data path(s):", data_group_paths)
221
+
222
+ if i >= len(export_paths):
223
+ print(f"⚠️ Warning: Missing export path for Group {i+1}. Skipping.")
224
+ continue
225
+
226
+ export_path = Path(export_paths[i])
227
+ print(" Export path:", export_path)
228
+
229
+ params = _deepcopy_dict(base_params)
230
+ params["export_path"] = str(export_path)
231
+
232
+ logging.info("Data path: %s", data_group_paths)
233
+ logging.info("Export path: %s", export_path)
234
+ logging.info("Parameters: %s", params)
235
+
236
+ params_path = export_path / "run_cnmf_arguments.json"
237
+ export_path.mkdir(parents=True, exist_ok=True)
238
+ save_params = {
239
+ "data_path": [str(p) for p in data_group_paths],
240
+ "parameters": params,
241
+ }
242
+ with open(params_path, "w") as fh:
243
+ json.dump(save_params, fh, indent=4)
244
+
245
+ _, batch_path = run_cnmf(
246
+ data_group_paths,
247
+ params,
248
+ mcorr_movie=args.mcorr_output,
249
+ )
250
+
251
+ logging.info("Batch path: %s", batch_path)
252
+
253
+ logging.shutdown()
254
+
255
+
256
+ def main(argv: list[str] | None = None) -> None:
257
+ args = _parse_args(argv)
258
+ for cfg_path in args.config_file:
259
+ _process_config(cfg_path, args)
260
+
261
+
262
+ if __name__ == "__main__":
263
+ main()
@@ -0,0 +1,299 @@
1
+ """Motion correction pipeline step.
2
+
3
+ This module wraps the motion correction workflow.
4
+ It can be executed independently of ROI extraction.
5
+
6
+ Usage:
7
+ python -m pipeline.pipeline_mcorr path/to/config.json
8
+ (equivalent to `python pipeline/pipeline_mcorr.py path/to/config.json`)
9
+
10
+ Input:
11
+ A configuration JSON file specifying data paths, export paths, and parameters.
12
+ See `pipeline/configs/` for examples.
13
+
14
+ Output:
15
+ Motion-corrected movies, and associated batch files if using the caiman pipeline (memmap format).
16
+ Files are saved in the specified export paths
17
+
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import argparse
23
+ import datetime
24
+ import json
25
+ import logging
26
+ import os
27
+ import sys
28
+ from pathlib import Path
29
+
30
+ os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # Suppress TensorFlow warnings
31
+ os.environ['CUDA_VISIBLE_DEVICES'] = '0' # Use first GPU if available
32
+ os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true' # Prevent TF from taking all GPU memory
33
+ os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0' # Disable the Intel OneAPI Deep Neural Network Library optimizations
34
+ os.environ['TF_CPP_VMODULE'] = 'cuda_dnn=0,cuda_fft=0,cuda_blas=0' # Prevent TensorFlow from logging CUDA-related warnings
35
+
36
+ # Add project root to path
37
+ PROJECT_ROOT = Path(__file__).parent.parent
38
+ if str(PROJECT_ROOT) not in sys.path:
39
+ sys.path.insert(0, str(PROJECT_ROOT))
40
+
41
+ from modules import motion_correction as mcorr
42
+ from pipeline.utils.pipeline_utils import (
43
+ log_and_print,
44
+ memory_manager,
45
+ cleanup_files,
46
+ )
47
+ import pipeline.utils.pipeline_utils as _pipeline_utils
48
+ from pipeline.utils.config_loader import load_config
49
+
50
+
51
+ def _suppress_tensorflow_logging() -> None:
52
+ logging.getLogger('tensorflow').setLevel(logging.ERROR)
53
+
54
+
55
+ _suppress_tensorflow_logging()
56
+
57
+ def run_mcorr(
58
+ data_path,
59
+ parameters,
60
+ regex_pattern="*_Ch2_*.ome.tif",
61
+ recompute=True,
62
+ output_format="memmap",
63
+ ):
64
+ """Run motion correction only.
65
+
66
+ Parameters
67
+ ----------
68
+ data_path : list[Path] | Path
69
+ Input data paths.
70
+ parameters : dict
71
+ Dictionary containing at least ``params_mcorr`` and ``export_path``.
72
+ regex_pattern : str
73
+ Pattern to match input files.
74
+ recompute : bool
75
+ Recompute motion correction even if outputs exist.
76
+ output_format : {"memmap", "h5", "bin", False}
77
+ Format of the saved movie.
78
+ If not False, use the specified format for saving the motion-corrected movie.
79
+ Options are 'h5', 'memmap' (default), 'tiff' or 'bin'.
80
+ """
81
+ log_and_print("Starting motion correction pipeline.")
82
+ log_and_print(f"pipeline_utils loaded from: {_pipeline_utils.__file__}")
83
+ export_path = Path(parameters["export_path"])
84
+ export_path.mkdir(parents=True, exist_ok=True)
85
+
86
+ with memory_manager("motion_correction"):
87
+ mcorr_results = mcorr.run_motion_correction_workflow(
88
+ data_path=data_path,
89
+ export_path=export_path,
90
+ parameters=parameters,
91
+ regex_pattern=regex_pattern,
92
+ recompute=recompute,
93
+ create_movies=True,
94
+ output_format=output_format,
95
+ )
96
+
97
+ batch_path = mcorr_results["batch_path"]
98
+
99
+ postproc_cleanup = parameters.get("params_extra", {}).get("cleanup", False)
100
+
101
+ preserve_batch = False
102
+ if output_format == "memmap":
103
+ log_and_print(
104
+ "Output format is 'memmap'. Configuring cleanup to preserve the memory-mapped file.",
105
+ level="warning"
106
+ )
107
+ preserve_batch = True
108
+
109
+ if postproc_cleanup:
110
+ import inspect
111
+
112
+ cleanup_params = inspect.signature(cleanup_files).parameters
113
+ if "preserve_batch" in cleanup_params:
114
+ cleanup_files(batch_path, export_path, preserve_batch=preserve_batch)
115
+ else:
116
+ if preserve_batch:
117
+ log_and_print(
118
+ "cleanup_files does not support preserve_batch; proceeding without it.",
119
+ level="warning",
120
+ )
121
+ cleanup_files(batch_path, export_path)
122
+ else:
123
+ log_and_print(
124
+ f"Keeping batch files associated to {batch_path}.", level="warning"
125
+ )
126
+
127
+ return export_path, batch_path
128
+
129
+
130
+ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
131
+ parser = argparse.ArgumentParser()
132
+ parser.add_argument("config_file", nargs="+", help="Input configuration JSON file")
133
+ parser.add_argument(
134
+ "-rp",
135
+ "--regex_pattern",
136
+ default="*_Ch2_*.ome.tif",
137
+ help="Regular expression pattern to match the data files",
138
+ )
139
+ parser.add_argument(
140
+ "-rc",
141
+ "--recompute",
142
+ action="store_false",
143
+ default=True,
144
+ help="Recompute the motion correction even if the batch folder exists",
145
+ )
146
+ parser.add_argument(
147
+ "--save-binary",
148
+ default=False,
149
+ help=(
150
+ "Save final movie as binary file, either 'bin', 'tiff', or 'h5'. "
151
+ "Default is False (a binary memmap is used temporarily and removed after cleanup)"
152
+ ),
153
+ )
154
+ return parser.parse_args(argv)
155
+
156
+
157
+ def _deepcopy_dict(data: dict) -> dict:
158
+ return json.loads(json.dumps(data))
159
+
160
+
161
+ def _process_config(cfg_path: str, args: argparse.Namespace) -> None:
162
+ config = load_config(cfg_path)
163
+
164
+ paths_cfg = config.get("paths", {})
165
+ data_paths = paths_cfg.get("data_paths", [])
166
+ export_paths = paths_cfg.get("export_paths", [])
167
+ concatenation_groups = paths_cfg.get("concatenation_groups", None)
168
+ zstack_paths = paths_cfg.get("zstack_paths", None)
169
+
170
+ logging_cfg = config.get("logging", {})
171
+ if logging_cfg:
172
+ log_path = logging_cfg.get("log_path", os.path.dirname(export_paths[0]))
173
+ log_level = logging_cfg.get("log_level", "INFO")
174
+ else:
175
+ log_path = os.path.dirname(export_paths[0]) if export_paths else Path.cwd()
176
+ log_level = "INFO"
177
+
178
+ os.makedirs(log_path, exist_ok=True)
179
+ log_file = os.path.join(
180
+ log_path, datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".log"
181
+ )
182
+ print("\n")
183
+ print("Log file: " + log_file)
184
+ print("\n")
185
+ logging.basicConfig(
186
+ filename=log_file,
187
+ level=log_level,
188
+ format="%(asctime)s %(levelname)s: %(message)s",
189
+ datefmt="%Y-%m-%d %H:%M:%S",
190
+ )
191
+ logging.info("Starting batch motion correction for data in %s", cfg_path)
192
+
193
+ if concatenation_groups:
194
+ grouped_paths = {}
195
+ for index, path in zip(concatenation_groups, data_paths):
196
+ grouped_paths.setdefault(index, []).append(path)
197
+ grouped_paths_list = list(grouped_paths.values())
198
+ else:
199
+ grouped_paths_list = [[p] for p in data_paths]
200
+
201
+ print("\n🔹 Runs will be processed as follows:")
202
+ for group_num, paths in enumerate(grouped_paths_list, start=1):
203
+ print(f" * Group {group_num}:")
204
+ for p in paths:
205
+ print(f" - {p}")
206
+ print("\n")
207
+
208
+ base_params_mcorr = config.get("params_mcorr", {}).copy()
209
+ z_motion_correction = base_params_mcorr.pop("z_motion_correction", None)
210
+ base_params_mcorr.pop("method", None)
211
+ base_params_mcorr.pop("save_mcorr_movie", None)
212
+ base_params = {
213
+ "experimenter": config.get("experimenter", {}),
214
+ "subject": config.get("subject", {}),
215
+ "imaging": config.get("imaging", {}),
216
+ "params_mcorr": base_params_mcorr,
217
+ "params_extraction": config.get("params_extraction", {}),
218
+ "params_extra": config.get("params_extra", {}),
219
+ }
220
+
221
+ for i, data_group in enumerate(grouped_paths_list):
222
+ data_group_paths = [Path(p) for p in data_group]
223
+ print(f"\n🔹 Processing Group {i+1}:")
224
+ print(" Data path(s):", data_group_paths)
225
+
226
+ if i >= len(export_paths):
227
+ print(f"⚠️ Warning: Missing export path for Group {i+1}. Skipping.")
228
+ continue
229
+
230
+ export_path = Path(export_paths[i])
231
+ print(" Export path:", export_path)
232
+
233
+ missing_paths = [p for p in data_group_paths if not p.exists()]
234
+ if missing_paths:
235
+ print(f"❌ Data paths not found: {missing_paths}. Skipping.")
236
+ continue
237
+
238
+ params = _deepcopy_dict(base_params)
239
+
240
+ zstack_path = None
241
+ if zstack_paths is not None:
242
+ zstack_path = zstack_paths[i] if len(zstack_paths) > 1 else zstack_paths[0]
243
+ if not os.path.exists(zstack_path):
244
+ print(f"❌ Z-stack path not found: {zstack_path}. Check the path.")
245
+ continue
246
+ if z_motion_correction:
247
+ params["params_mcorr"]["z_motion_correction"] = z_motion_correction
248
+ params["zstack_path"] = str(zstack_path)
249
+
250
+ logging.info("Data path: %s", data_group_paths)
251
+ logging.info("Export path: %s", export_path)
252
+ logging.info("Parameters: %s", params)
253
+
254
+ params["export_path"] = str(export_path)
255
+
256
+ params_path = export_path / "run_mcorr_arguments.json"
257
+ export_path.mkdir(parents=True, exist_ok=True)
258
+ save_params = {
259
+ "data_path": [str(p) for p in data_group_paths],
260
+ "parameters": params,
261
+ "regex_pattern": args.regex_pattern,
262
+ "recompute": args.recompute,
263
+ }
264
+ with open(params_path, "w") as fh:
265
+ json.dump(save_params, fh, indent=4)
266
+
267
+ save_mcorr_movie = config.get("params_mcorr", {}).get("save_mcorr_movie", "memmap")
268
+ print(f" Save motion-corrected movie format from config: {save_mcorr_movie}")
269
+ if args.save_binary:
270
+ print(f"Overriding save_mcorr_movie with command line argument: {args.save_binary}")
271
+ save_mcorr_movie = args.save_binary
272
+
273
+ if save_mcorr_movie not in ['h5', 'memmap', 'bin', 'tiff']:
274
+ print(f"Invalid save_mcorr_movie format: {save_mcorr_movie}. Using 'memmap'")
275
+ save_mcorr_movie = 'memmap'
276
+
277
+ logging.info("Save motion-corrected movie as: %s", save_mcorr_movie)
278
+
279
+ _, batch_path = run_mcorr(
280
+ data_group_paths,
281
+ params,
282
+ regex_pattern=args.regex_pattern,
283
+ recompute=args.recompute,
284
+ output_format=save_mcorr_movie,
285
+ )
286
+
287
+ logging.info("Batch path: %s", batch_path)
288
+
289
+ logging.shutdown()
290
+
291
+
292
+ def main(argv: list[str] | None = None) -> None:
293
+ args = _parse_args(argv)
294
+ for cfg_path in args.config_file:
295
+ _process_config(cfg_path, args)
296
+
297
+
298
+ if __name__ == "__main__":
299
+ main()
pipeline/roi_zcorr.py ADDED
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Batch execution of ROI z-motion correction."""
3
+
4
+ import argparse
5
+ import logging
6
+ import datetime
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ # Add project root to path
12
+ PROJECT_ROOT = Path(__file__).parent.parent
13
+ if str(PROJECT_ROOT) not in sys.path:
14
+ sys.path.insert(0, str(PROJECT_ROOT))
15
+
16
+ from modules.motion_correction import run_roi_zcorr
17
+ from pipeline.utils.config_loader import load_config
18
+
19
+
20
+ def main():
21
+ parser = argparse.ArgumentParser()
22
+ parser.add_argument("config_file", nargs="+", help="Input configuration JSON file")
23
+ args = parser.parse_args()
24
+
25
+ for cfg_path in args.config_file:
26
+ config = load_config(cfg_path)
27
+
28
+ paths_cfg = config.get("paths", {})
29
+ export_paths = paths_cfg.get("export_paths", [])
30
+
31
+ logging_cfg = config.get("logging", {})
32
+ if logging_cfg:
33
+ log_path = logging_cfg.get("log_path", os.path.dirname(export_paths[0]))
34
+ log_level = logging_cfg.get("log_level", "INFO")
35
+ else:
36
+ log_path = os.path.dirname(export_paths[0])
37
+ log_level = "INFO"
38
+
39
+ os.makedirs(log_path, exist_ok=True)
40
+ log_file = os.path.join(
41
+ log_path, datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".log"
42
+ )
43
+ print("\n")
44
+ print("Log file: " + log_file)
45
+ print("\n")
46
+ logging.basicConfig(
47
+ filename=log_file,
48
+ level=log_level,
49
+ format="%(asctime)s %(levelname)s: %(message)s",
50
+ datefmt="%Y-%m-%d %H:%M:%S",
51
+ )
52
+ logging.info("Starting ROI z-motion correction for data in " + cfg_path)
53
+
54
+ params = {"params_mcorr": config.get("params_mcorr", {})}
55
+
56
+ for export_path in export_paths:
57
+ export_path = Path(export_path)
58
+ logging.info("Export path: " + str(export_path))
59
+ run_roi_zcorr(export_path, params)
60
+
61
+ logging.shutdown()
62
+
63
+
64
+ if __name__ == "__main__":
65
+ main()
File without changes