diff --git a/README.md b/README.md index 8dbe422..a8db1b6 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,8 @@ events = RTMSequence( # 4. Run! ctrl = Controller(mic, pipeline) -ctrl.run_experiment(list(events), stim_mode="current") +handle = ctrl.run_experiment(list(events), stim_mode="current") +handle.wait() # run_experiment is non-blocking; wait() blocks until done ``` ## Pipeline @@ -132,6 +133,14 @@ events = combine(setup_a, setup_b, axis="p") `combine()` is variadic (`combine(a, b, c, d, ..., axis=...)`), handles the N=0 and N=1 degenerate cases, and is the only composition primitive — there is deliberately no shorthand operator, so every multi-step experiment reads the composition axis explicitly. +**Timed waits between phases.** `wait(seconds)` inserts a fixed-duration pause — e.g. to let cells recover before stimulating. It acquires no frames and just delays everything after it: + +```python +from faro.core.data_structures import wait + +events = combine(baseline, wait(60), stim_phase, axis="t") +``` + ### Stimulation Stimulation channels are acquired on specific frames, controlled via DMD/SLM. Define them with `stim_channels` and `stim_frames`: @@ -235,11 +244,25 @@ events = apply_fov_batching(events, time_per_fov=2.0) from faro.core.controller import Controller ctrl = Controller(mic, pipeline) -ctrl.run_experiment(events, stim_mode="current") +handle = ctrl.run_experiment(events, stim_mode="current") +handle.wait() # block until the run finishes ``` `validate_events()` runs automatically before the experiment starts (disable with `validate=False`). It checks both pipeline compatibility and hardware limits. +`run_experiment()` and `continue_experiment()` are **non-blocking** — they return a `RunHandle` so the kernel stays free (e.g. to use the napari viewer). Call `handle.wait()` to block until the run finishes. + +```python +handle = ctrl.run_experiment(events, stim_mode="current") +handle.pause(); handle.resume() # stop/resume acquiring; schedule is preserved +handle.cancel() # graceful stop +handle.wait() # block until done + +# Live status badge, progress strip, and Pause/Stop buttons in napari: +from faro.widgets import ExperimentStatusWidget +viewer.window.add_dock_widget(ExperimentStatusWidget(ctrl), area="right") +``` + ### Experiment Continuation Call `run_experiment()` once, then `continue_experiment()` to append more phases. The Analyzer (and all per-FOV tracking state) is reused, so timesteps, filenames, and particle IDs continue seamlessly. @@ -249,7 +272,7 @@ ctrl = Controller(mic, pipeline) # Phase 1: baseline — find cells, measure growth rate phase1 = RTMSequence(time_plan={"interval": 10, "loops": 60}, ...) -ctrl.run_experiment(phase1, validate=False) +ctrl.run_experiment(phase1, validate=False).wait() # wait() before reading results # Analyse phase-1 results to decide what to do next df = pd.read_parquet("tracks/000_latest.parquet") @@ -257,7 +280,7 @@ fast_growers = df.groupby("particle")["area"].apply(lambda x: x.diff().mean()) # Phase 2: stimulate based on analysis phase2 = RTMSequence(time_plan={"interval": 10, "loops": 120}, ...) -ctrl.continue_experiment(phase2) +ctrl.continue_experiment(phase2).wait() # Always call finish_experiment() when done ctrl.finish_experiment() @@ -270,12 +293,12 @@ ctrl.run_experiment(baseline_events, validate=False) # runs in background threa ctrl.extend_experiment(extra_events) # non-blocking, appends to running acquisition ``` -| Method | When to use | -|--------|-------------| -| `run_experiment()` | First acquisition — creates a fresh Analyzer | -| `continue_experiment()` | Subsequent phases — reuses Analyzer, offsets timesteps | -| `extend_experiment()` | Mid-run additions — pushes events into the running loop | -| `finish_experiment()` | Cleanup — shuts down Analyzer, resets state | +| Method | When to use | Returns | +|--------|-------------|---------| +| `run_experiment()` | First acquisition — creates a fresh Analyzer | `RunHandle` (non-blocking) | +| `continue_experiment()` | Subsequent phases — reuses Analyzer, offsets timesteps | `RunHandle` (non-blocking) | +| `extend_experiment()` | Mid-run additions — pushes events into the running loop | — (non-blocking) | +| `finish_experiment()` | Cleanup — shuts down Analyzer, resets state | — (blocks until drained) | ## Simulated Controller @@ -287,7 +310,7 @@ It supports both **TIFF** (`raw/`, `ref/` folders) and **OME-Zarr** (`acquisitio from faro.core.controller import ControllerSimulated ctrl = ControllerSimulated(mic, pipeline, old_data_project_path="/path/to/old_experiment") -ctrl.run_experiment(events, stim_mode="current") +ctrl.run_experiment(events, stim_mode="current").wait() ``` Use cases: diff --git a/experiments/01_demo_microsocpe/demo_microscope.ipynb b/experiments/01_demo_microsocpe/demo_microscope.ipynb index b8ac232..103b7d6 100644 --- a/experiments/01_demo_microsocpe/demo_microscope.ipynb +++ b/experiments/01_demo_microsocpe/demo_microscope.ipynb @@ -250,236 +250,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
[04/02/26 16:26:05] INFO     MDA Started: GeneratorMDASequence()                                     _runner.py:378\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:05]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Started: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=494889;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=524151;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#378\u001b\\\u001b[2m378\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 0, 'fname': '000_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=396421;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=557215;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:06] INFO     index={'t': 1, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 1, 'fname': '000_00001', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:06]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=812928;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=648595;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:07] INFO     index={'t': 2, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=2.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 2, 'fname': '000_00002', 'time': 2.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:07]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=268993;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=147524;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m2.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:08] INFO     index={'t': 3, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=3.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 3, 'fname': '000_00003', 'time': 3.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:08]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=47802;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=69148;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m3\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m3.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:09] INFO     index={'t': 4, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=4.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 4, 'fname': '000_00004', 'time': 4.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:09]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=437065;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=950385;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m4\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00004'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m4.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:10] INFO     index={'t': 5, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=5.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 5, 'fname': '000_00005', 'time': 5.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:10]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=717530;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=619451;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m5\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00005'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m5.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:11] INFO     index={'t': 6, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=6.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 6, 'fname': '000_00006', 'time': 6.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:11]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=376837;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=919649;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m6\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00006'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m6.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:12] INFO     index={'t': 7, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=7.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 7, 'fname': '000_00007', 'time': 7.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:12]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=417937;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=493013;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m7\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00007'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m7.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:13] INFO     index={'t': 8, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=8.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 8, 'fname': '000_00008', 'time': 8.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:13]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=168168;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=385801;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m8\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00008'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m8.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 16:26:14] INFO     index={'t': 9, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=9.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 9, 'fname': '000_00009', 'time': 9.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI'], 'img_type': <ImgType.IMG_RAW: 1>}                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 16:26:14]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m9\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=158593;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=582889;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m9\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m9\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00009'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m9.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     MDA Finished: GeneratorMDASequence()                                    _runner.py:465\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Finished: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=569362;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=370691;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#465\u001b\\\u001b[2m465\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from faro.core.controller import Controller\n", - "from faro.core.writers import OmeZarrWriter\n", - "\n", - "writer = OmeZarrWriter(storage_path=path)\n", - "\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.run_experiment(events)\n", - "ctrl.finish_experiment()" - ] + "outputs": [], + "source": "from faro.core.controller import Controller\nfrom faro.core.writers import OmeZarrWriter\n\nwriter = OmeZarrWriter(storage_path=path)\n\nctrl = Controller(mic, pipeline, writer=writer)\nctrl.run_experiment(events).wait()\nctrl.finish_experiment()" }, { "cell_type": "markdown", @@ -887,4 +661,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/experiments/02_demo_sim_optogenetic/demo_sim_optogenetic.ipynb b/experiments/02_demo_sim_optogenetic/demo_sim_optogenetic.ipynb index 858cb84..260c15a 100644 --- a/experiments/02_demo_sim_optogenetic/demo_sim_optogenetic.ipynb +++ b/experiments/02_demo_sim_optogenetic/demo_sim_optogenetic.ipynb @@ -2646,123 +2646,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "9efecc101b4a46989bfa391f21577d85", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Experiment: 0%| | 0/40 [00:000.5s): 1/40\n", - " WARNING: 1 frames could not keep up with requested timing. Consider increasing time_interval or reducing FOV count.\n" - ] - } - ], - "source": [ - "import sys, io, logging, time as _time\n", - "from tqdm.auto import tqdm\n", - "from faro.core.data_structures import ImgType\n", - "from faro.core.controller import Controller\n", - "from faro.core.writers import TiffWriter\n", - "\n", - "writer = TiffWriter(storage_path=path)\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "\n", - "n_total = len(events)\n", - "pbar = tqdm(total=n_total, desc=\"Experiment\", unit=\"frames\")\n", - "_frame_count = [0]\n", - "_t0 = [None] # wall-clock start (set on first frame)\n", - "_max_delay = [0.0] # track worst-case delay\n", - "_late_frames = [0] # count of frames that arrived late\n", - "\n", - "# Frames arriving more than this many seconds late trigger a warning\n", - "_LATE_THRESHOLD = 0.5\n", - "\n", - "\n", - "def _on_frame(img, event):\n", - " md = event.metadata or {}\n", - " if md.get(\"img_type\") != ImgType.IMG_RAW:\n", - " return\n", - "\n", - " _frame_count[0] += 1\n", - " pbar.update(1)\n", - "\n", - " # --- Timing check ---\n", - " now = _time.time()\n", - " if _t0[0] is None:\n", - " _t0[0] = now # first imaging frame = reference\n", - " expected = md.get(\"time\", 0)\n", - " elapsed = now - _t0[0]\n", - " delay = elapsed - expected\n", - " _max_delay[0] = max(_max_delay[0], delay)\n", - " late = \"\"\n", - " if delay > _LATE_THRESHOLD:\n", - " _late_frames[0] += 1\n", - " late = f\" LATE +{delay:.1f}s\"\n", - "\n", - " fov = md.get(\"fov\", 0)\n", - " n_cells = ctrl._analyzer.get_fov_state(fov).n_cells_latest\n", - " ts = md.get(\"timestep\", 0)\n", - " pbar.set_postfix_str(\n", - " f\"frame {ts+1}/{n_total}, cells={n_cells}, delay={delay:+.2f}s{late}\"\n", - " )\n", - "\n", - "\n", - "core.mda.events.frameReady.connect(_on_frame)\n", - "\n", - "# Suppress verbose per-frame logs from pipeline and pymmcore-plus\n", - "_stdout = sys.stdout\n", - "sys.stdout = io.StringIO()\n", - "_mda_logger = logging.getLogger(\"pymmcore-plus\")\n", - "_prev_level = _mda_logger.level\n", - "_mda_logger.setLevel(logging.WARNING)\n", - "try:\n", - " ctrl.run_experiment(events, stim_mode=\"current\")\n", - " mic.post_experiment()\n", - " ctrl.finish_experiment()\n", - "finally:\n", - " sys.stdout = _stdout\n", - " _mda_logger.setLevel(_prev_level)\n", - " try:\n", - " core.mda.events.frameReady.disconnect(_on_frame)\n", - " except Exception:\n", - " pass\n", - " pbar.close()\n", - "\n", - "# Print timing summary\n", - "print(f\"\\nTiming summary:\")\n", - "print(f\" Max delay: {_max_delay[0]:.2f}s\")\n", - "print(f\" Late frames (>{_LATE_THRESHOLD}s): {_late_frames[0]}/{n_total}\")\n", - "if _late_frames[0] > 0:\n", - " print(\n", - " f\" WARNING: {_late_frames[0]} frames could not keep up with requested timing.\"\n", - " f\" Consider increasing time_interval or reducing FOV count.\"\n", - " )" - ] + "outputs": [], + "source": "import sys, io, logging, time as _time\nfrom tqdm.auto import tqdm\nfrom faro.core.data_structures import ImgType\nfrom faro.core.controller import Controller\nfrom faro.core.writers import TiffWriter\n\nwriter = TiffWriter(storage_path=path)\nctrl = Controller(mic, pipeline, writer=writer)\n\nn_total = len(events)\npbar = tqdm(total=n_total, desc=\"Experiment\", unit=\"frames\")\n_frame_count = [0]\n_t0 = [None] # wall-clock start (set on first frame)\n_max_delay = [0.0] # track worst-case delay\n_late_frames = [0] # count of frames that arrived late\n\n# Frames arriving more than this many seconds late trigger a warning\n_LATE_THRESHOLD = 0.5\n\n\ndef _on_frame(img, event):\n md = event.metadata or {}\n if md.get(\"img_type\") != ImgType.IMG_RAW:\n return\n\n _frame_count[0] += 1\n pbar.update(1)\n\n # --- Timing check ---\n now = _time.time()\n if _t0[0] is None:\n _t0[0] = now # first imaging frame = reference\n expected = md.get(\"time\", 0)\n elapsed = now - _t0[0]\n delay = elapsed - expected\n _max_delay[0] = max(_max_delay[0], delay)\n late = \"\"\n if delay > _LATE_THRESHOLD:\n _late_frames[0] += 1\n late = f\" LATE +{delay:.1f}s\"\n\n fov = md.get(\"fov\", 0)\n n_cells = ctrl._analyzer.get_fov_state(fov).n_cells_latest\n ts = md.get(\"timestep\", 0)\n pbar.set_postfix_str(\n f\"frame {ts+1}/{n_total}, cells={n_cells}, delay={delay:+.2f}s{late}\"\n )\n\n\ncore.mda.events.frameReady.connect(_on_frame)\n\n# Suppress verbose per-frame logs from pipeline and pymmcore-plus\n_stdout = sys.stdout\nsys.stdout = io.StringIO()\n_mda_logger = logging.getLogger(\"pymmcore-plus\")\n_prev_level = _mda_logger.level\n_mda_logger.setLevel(logging.WARNING)\ntry:\n ctrl.run_experiment(events, stim_mode=\"current\").wait()\n mic.post_experiment()\n ctrl.finish_experiment()\nfinally:\n sys.stdout = _stdout\n _mda_logger.setLevel(_prev_level)\n try:\n core.mda.events.frameReady.disconnect(_on_frame)\n except Exception:\n pass\n pbar.close()\n\n# Print timing summary\nprint(f\"\\nTiming summary:\")\nprint(f\" Max delay: {_max_delay[0]:.2f}s\")\nprint(f\" Late frames (>{_LATE_THRESHOLD}s): {_late_frames[0]}/{n_total}\")\nif _late_frames[0] > 0:\n print(\n f\" WARNING: {_late_frames[0]} frames could not keep up with requested timing.\"\n f\" Consider increasing time_interval or reducing FOV count.\"\n )" }, { "cell_type": "markdown", @@ -3302,93 +3189,11 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "id": "cell-25", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Directory /var/folders/zy/d2yp5vws25l6vkr2g5l4t39c0000gn/T/test_optogenetic_sim_multiphase5a297anq/tracks created \n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "fddc7e0c2ade4dbdacbe3621d988fee3", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Multi-phase: 0%| | 0/50 [00:00Config Groups\n", + "└── Channel\n", + " ├── DAPI\n", + " ├── membrane\n", + " └── phase-contrast\n", + "\n" + ], + "text/plain": [ + "\u001b[1mConfig Groups\u001b[0m\n", + "└── \u001b[1;36mChannel\u001b[0m\n", + " ├── DAPI\n", + " ├── membrane\n", + " └── phase-contrast\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from virtual_microscope.backends.optogenetic import setup_optogenetic\n", + "from faro.microscope.simulation import UniMMCoreSimulation\n", + "import faro.core.utils as utils\n", + "\n", + "core, sim = setup_optogenetic()\n", + "utils.print_configs(core)\n", + "\n", + "mic = UniMMCoreSimulation(mmc=core)\n", + "mic.init_scope() # detect SLM device for optogenetic stimulation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Open napari + napari-micromanager\n", + "\n", + "We attach the simulated `core` to a `napari-micromanager` `MainWindow` so frames stream into the viewer as they are acquired." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import napari\n", + "from napari_micromanager import MainWindow\n", + "\n", + "viewer = napari.Viewer()\n", + "mm_wdg = MainWindow(viewer)\n", + "mm_wdg._mmc = core\n", + "viewer.window.add_dock_widget(mm_wdg, name=\"napari-micromanager\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Build the pipeline (segmentation + tracking + features + stimulation)\n", + "\n", + "Same components as the original demo: Otsu/watershed segmentation, trackpy linker, simple region-props feature extractor, and the `StimUpDown` stimulator that pushes even-particle cells up and odd-particle cells down." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from skimage.filters import gaussian, threshold_otsu\n", + "from skimage.feature import peak_local_max\n", + "from skimage.segmentation import watershed\n", + "from skimage.measure import label, regionprops\n", + "from skimage.morphology import disk, dilation\n", + "from scipy import ndimage\n", + "import skimage.measure\n", + "import pandas as pd\n", + "\n", + "from faro.segmentation.base import Segmentator\n", + "from faro.feature_extraction.base import FeatureExtractor\n", + "from faro.stimulation.base import StimWithPipeline\n", + "from faro.tracking.trackpy import TrackerTrackpy\n", + "from faro.core.data_structures import SegmentationMethod\n", + "\n", + "\n", + "class WatershedSegmentator(Segmentator):\n", + " \"\"\"Gaussian blur -> Otsu -> distance transform -> watershed.\"\"\"\n", + "\n", + " def segment(self, image: np.ndarray) -> np.ndarray:\n", + " blurred = gaussian(image, sigma=3)\n", + " thresh = threshold_otsu(blurred)\n", + " binary = blurred > thresh\n", + " distance = ndimage.distance_transform_edt(binary)\n", + " coords = peak_local_max(distance, min_distance=20, labels=binary)\n", + " markers = np.zeros(distance.shape, dtype=bool)\n", + " markers[tuple(coords.T)] = True\n", + " markers = label(markers)\n", + " return watershed(-distance, markers, mask=binary)\n", + "\n", + "\n", + "class SimpleFE(FeatureExtractor):\n", + " def __init__(self, used_mask):\n", + " self.used_mask = used_mask\n", + " super().__init__()\n", + "\n", + " def extract_features(self, labels, image, df_tracked=None, metadata=None):\n", + " table = skimage.measure.regionprops_table(\n", + " labels[self.used_mask], properties=[\"label\", \"area\"]\n", + " )\n", + " return pd.DataFrame.from_dict(table), None\n", + "\n", + "\n", + "class StimUpDown(StimWithPipeline):\n", + " \"\"\"Even particles -> illuminate top edge; odd particles -> bottom edge.\"\"\"\n", + "\n", + " def __init__(self, fraction=0.2):\n", + " self.fraction = fraction\n", + "\n", + " def get_stim_mask(self, label_images, metadata=None, img=None, tracks=None):\n", + " labels = label_images[\"labels\"]\n", + " stim_mask = np.zeros(labels.shape, dtype=np.uint8)\n", + " selem = disk(3)\n", + "\n", + " if tracks is None or tracks.empty:\n", + " return stim_mask, None\n", + "\n", + " current = tracks[tracks[\"timestep\"] == tracks[\"timestep\"].max()]\n", + " label_to_particle = dict(zip(current[\"label\"], current[\"particle\"]))\n", + "\n", + " for prop in regionprops(labels):\n", + " minr, minc, maxr, maxc = prop.bbox\n", + " pid = label_to_particle.get(prop.label, 0)\n", + "\n", + " if pid % 2 == 0:\n", + " y_cutoff = minr + self.fraction * (maxr - minr)\n", + " select = lambda rows, c=y_cutoff: rows < c\n", + " else:\n", + " y_cutoff = maxr - self.fraction * (maxr - minr)\n", + " select = lambda rows, c=y_cutoff: rows > c\n", + "\n", + " cell_mask = labels == prop.label\n", + " rows, cols = np.where(cell_mask)\n", + " edge_pixels = select(rows)\n", + " if not edge_pixels.any():\n", + " continue\n", + "\n", + " local = np.zeros_like(labels, dtype=np.uint8)\n", + " local[rows[edge_pixels], cols[edge_pixels]] = 1\n", + " local = dilation(local, footprint=selem)\n", + " stim_mask = np.maximum(stim_mask, local)\n", + "\n", + " return stim_mask, None\n", + "\n", + "\n", + "segmentators = [\n", + " SegmentationMethod(\n", + " name=\"labels\",\n", + " segmentation_class=WatershedSegmentator(),\n", + " use_channel=0,\n", + " save_tracked=True,\n", + " )\n", + "]\n", + "\n", + "tracker = TrackerTrackpy(search_range=15)\n", + "feature_extractor = SimpleFE(\"labels\")\n", + "stimulator = StimUpDown(fraction=0.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Assemble the pipeline + controller" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Directory /var/folders/zy/d2yp5vws25l6vkr2g5l4t39c0000gn/T/napari_async_optogenetic_yg4xg969/tracks created \n", + "Storage path: /var/folders/zy/d2yp5vws25l6vkr2g5l4t39c0000gn/T/napari_async_optogenetic_yg4xg969\n" + ] + } + ], + "source": [ + "import os, shutil, tempfile\n", + "from faro.core.pipeline import ImageProcessingPipeline\n", + "from faro.core.controller import Controller\n", + "from faro.core.writers import TiffWriter\n", + "\n", + "path = tempfile.mkdtemp(prefix=\"napari_async_optogenetic_\")\n", + "if os.path.exists(path):\n", + " shutil.rmtree(path)\n", + "\n", + "pipeline = ImageProcessingPipeline(\n", + " storage_path=path,\n", + " segmentators=segmentators,\n", + " feature_extractor=feature_extractor,\n", + " tracker=tracker,\n", + " stimulator=stimulator,\n", + ")\n", + "\n", + "writer = TiffWriter(storage_path=path)\n", + "ctrl = Controller(mic, pipeline, writer=writer)\n", + "print(f\"Storage path: {path}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Dock the `ExperimentStatusWidget`\n", + "\n", + "The widget subscribes to `ctrl.runStarted`, so it automatically re-binds whenever a new run begins. The **Stop** button calls `handle.cancel()` on the currently bound run." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from faro.widgets import ExperimentStatusWidget\n", + "\n", + "status_widget = ExperimentStatusWidget(ctrl)\n", + "viewer.window.add_dock_widget(status_widget, name=\"experiment status\", area=\"right\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Build a multi-phase event sequence\n", + "\n", + "Baseline → stimulation → recovery, all on a single FOV. Phases are joined with `combine(..., axis=\"t\")`, which offsets each subsequent sequence's `t` indices and `min_start_time` past the previous one. Slow enough that you can comfortably interact with the napari viewer while it runs." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "32 events: 10s wait + 5 baseline + 5 stim + 10s wait + 5 recovery\n" + ] + }, + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "fov", + "rawType": "int64", + "type": "integer" + }, + { + "name": "timestep", + "rawType": "int64", + "type": "integer" + }, + { + "name": "time", + "rawType": "float64", + "type": "float" + }, + { + "name": "x_pos", + "rawType": "float64", + "type": "float" + }, + { + "name": "y_pos", + "rawType": "float64", + "type": "float" + }, + { + "name": "z_pos", + "rawType": "float64", + "type": "float" + }, + { + "name": "channels", + "rawType": "object", + "type": "unknown" + }, + { + "name": "stim_channels", + "rawType": "object", + "type": "unknown" + }, + { + "name": "ref_channels", + "rawType": "object", + "type": "unknown" + }, + { + "name": "stim", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "ref", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "phase", + "rawType": "object", + "type": "unknown" + }, + { + "name": "stim_power", + "rawType": "float64", + "type": "float" + }, + { + "name": "stim_exposure", + "rawType": "float64", + "type": "float" + } + ], + "ref": "98917d0a-3a0b-4f59-9a19-cf6299e997ee", + "rows": [ + [ + "0", + "0", + "0", + "0.0", + null, + null, + null, + "()", + "()", + "()", + "False", + "False", + null, + null, + null + ], + [ + "1", + "0", + "0", + "11.0", + "0.0", + "0.0", + "0.0", + "({'config': 'phase-contrast', 'exposure': 50.0, 'group': None},)", + "()", + "()", + "False", + "False", + "baseline", + null, + null + ], + [ + "2", + "0", + "0", + "21.0", + null, + null, + null, + "()", + "()", + "()", + "False", + "False", + null, + null, + null + ], + [ + "3", + "1", + "0", + "11.0", + "20.0", + "20.0", + "0.0", + "({'config': 'phase-contrast', 'exposure': 50.0, 'group': None},)", + "()", + "()", + "False", + "False", + "baseline", + null, + null + ], + [ + "4", + "0", + "1", + "12.0", + "0.0", + "0.0", + "0.0", + "({'config': 'phase-contrast', 'exposure': 50.0, 'group': None},)", + "()", + "()", + "False", + "False", + "baseline", + null, + null + ] + ], + "shape": { + "columns": 14, + "rows": 5 + } + }, + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fovtimesteptimex_posy_posz_poschannelsstim_channelsref_channelsstimrefphasestim_powerstim_exposure
0000.0NaNNaNNaN()()()FalseFalseNaNNaNNaN
10011.00.00.00.0({'config': 'phase-contrast', 'exposure': 50.0...()()FalseFalsebaselineNaNNaN
20021.0NaNNaNNaN()()()FalseFalseNaNNaNNaN
31011.020.020.00.0({'config': 'phase-contrast', 'exposure': 50.0...()()FalseFalsebaselineNaNNaN
40112.00.00.00.0({'config': 'phase-contrast', 'exposure': 50.0...()()FalseFalsebaselineNaNNaN
\n", + "
" + ], + "text/plain": [ + " fov timestep time x_pos y_pos z_pos \\\n", + "0 0 0 0.0 NaN NaN NaN \n", + "1 0 0 11.0 0.0 0.0 0.0 \n", + "2 0 0 21.0 NaN NaN NaN \n", + "3 1 0 11.0 20.0 20.0 0.0 \n", + "4 0 1 12.0 0.0 0.0 0.0 \n", + "\n", + " channels stim_channels \\\n", + "0 () () \n", + "1 ({'config': 'phase-contrast', 'exposure': 50.0... () \n", + "2 () () \n", + "3 ({'config': 'phase-contrast', 'exposure': 50.0... () \n", + "4 ({'config': 'phase-contrast', 'exposure': 50.0... () \n", + "\n", + " ref_channels stim ref phase stim_power stim_exposure \n", + "0 () False False NaN NaN NaN \n", + "1 () False False baseline NaN NaN \n", + "2 () False False NaN NaN NaN \n", + "3 () False False baseline NaN NaN \n", + "4 () False False baseline NaN NaN " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from faro.core.data_structures import RTMSequence, combine, wait\n", + "from faro.core.utils import events_to_dataframe\n", + "\n", + "n_baseline = 5\n", + "n_stim = 5\n", + "n_recovery = 5\n", + "interval_s = 1 # seconds between frames; raise if your machine struggles\n", + "wait_s = 10 # pre-baseline settle + post-stim recovery pauses\n", + "\n", + "baseline = RTMSequence(\n", + " time_plan={\"interval\": interval_s, \"loops\": n_baseline},\n", + " stage_positions=[(0.0, 0.0, 0.0),(20,20,0.0)],\n", + " channels=[{\"config\": \"phase-contrast\", \"exposure\": 50}],\n", + " rtm_metadata={\"phase\": \"baseline\"},\n", + ")\n", + "\n", + "stim_phase = RTMSequence(\n", + " time_plan={\"interval\": interval_s, \"loops\": n_stim},\n", + " stage_positions=[(0.0, 0.0, 0.0),(20,20,0.0)],\n", + " channels=[{\"config\": \"phase-contrast\", \"exposure\": 50}],\n", + " stim_channels=[{\"config\": \"phase-contrast\", \"exposure\": 50}],\n", + " stim_frames=range(n_stim),\n", + " rtm_metadata={\"phase\": \"stimulation\"},\n", + ")\n", + "\n", + "recovery = RTMSequence(\n", + " time_plan={\"interval\": interval_s, \"loops\": n_recovery},\n", + " stage_positions=[(0.0, 0.0, 0.0),(20,20,0.0)],\n", + " channels=[{\"config\": \"phase-contrast\", \"exposure\": 50}],\n", + " rtm_metadata={\"phase\": \"recovery\"},\n", + ")\n", + "\n", + "events = combine(wait(wait_s), baseline, stim_phase, wait(wait_s), recovery, axis=\"t\")\n", + "df_events = events_to_dataframe(events)\n", + "print(\n", + " f\"{len(events)} events: {wait_s}s wait + {n_baseline} baseline + {n_stim} stim \"\n", + " f\"+ {wait_s}s wait + {n_recovery} recovery\"\n", + ")\n", + "df_events.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Launch the run (non-blocking)\n", + "\n", + "`run_experiment` now returns a `RunHandle` immediately. The MDA feed loop is on a worker thread; the kernel is free.\n", + "\n", + "Watch the **napari viewer** for live frames and the **Experiment status** dock for state / FOV / event index / lag. Try clicking **Stop** mid-run — the worker exits at the next event boundary." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "run started, handle.is_running()=True\n", + "current status: running\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/Cellar/python@3.12/3.12.12/Frameworks/Python.framework/Versions/3.12/lib/python3.12/threading.py:1012: UserWarning: FOV 0 position changed: (0.0, 0.0, 0.0) -> (None, None, None). Tracking continuity may be broken.\n", + " self._target(*self._args, **self._kwargs)\n", + "/opt/homebrew/Cellar/python@3.12/3.12.12/Frameworks/Python.framework/Versions/3.12/lib/python3.12/threading.py:1012: UserWarning: FOV 0 position changed: (None, None, None) -> (0.0, 0.0, 0.0). Tracking continuity may be broken.\n", + " self._target(*self._args, **self._kwargs)\n" + ] + } + ], + "source": [ + "handle = ctrl.run_experiment(events, stim_mode=\"previous\")\n", + "print(f\"run started, handle.is_running()={handle.is_running()}\")\n", + "print(f\"current status: {handle.status().state}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Poll the status from the kernel\n", + "\n", + "Re-run the cell below as often as you like while the experiment is running." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "state : waiting\n", + "events consumed : 1 / 32\n", + "frames received : 0\n", + "current FOV : None\n", + "current event : {}\n", + "lag (ms) : None\n", + "bg errors : 0\n", + "fatal error : None\n" + ] + } + ], + "source": [ + "s = handle.status()\n", + "print(f\"state : {s.state}\")\n", + "print(f\"events consumed : {s.n_events_consumed} / {s.n_events_total}\")\n", + "print(f\"frames received : {s.n_frames_received}\")\n", + "print(f\"current FOV : {s.current_fov}\")\n", + "print(f\"current event : {s.current_event_index}\")\n", + "print(f\"lag (ms) : {s.lag_ms}\")\n", + "print(f\"bg errors : {len(s.background_errors)}\")\n", + "print(f\"fatal error : {s.fatal_error!r}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Subscribe to live updates from the kernel\n", + "\n", + "Anything you do here is in *addition* to the dock widget — the widget already listens. Useful if you want to pipe status into your own logging." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def _print_status(status):\n", + " print(f\"[notify] state={status.state} consumed={status.n_events_consumed}\"\n", + " f\"/{status.n_events_total} frames={status.n_frames_received}\"\n", + " f\" lag_ms={status.lag_ms}\")\n", + "\n", + "handle.statusChanged.connect(_print_status)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Cancel from the kernel (alternative to the Stop button)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# handle.cancel() # uncomment to abort" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Block until the run finishes\n", + "\n", + "Equivalent to the old synchronous behavior. Re-raises any worker-side `fatal_error`." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "final state : done\n", + "frames received : 80\n" + ] + } + ], + "source": [ + "final_status = handle.wait()\n", + "print(f\"final state : {final_status.state}\")\n", + "print(f\"frames received : {final_status.n_frames_received}\")\n", + "if final_status.fatal_error is not None:\n", + " print(f\"fatal : {final_status.fatal_error!r}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Continue the experiment (optional)\n", + "\n", + "`ctrl.continue_experiment(...)` reuses the existing Analyzer and tracking state. Same async semantics: returns a fresh `RunHandle`, the widget re-binds automatically via `runStarted`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "extra = RTMSequence(\n", + " time_plan={\"interval\": interval_s, \"loops\": 10},\n", + " stage_positions=[(0.0, 0.0, 0.0)],\n", + " channels=[{\"config\": \"phase-contrast\", \"exposure\": 50}],\n", + " rtm_metadata={\"phase\": \"extra-recovery\"},\n", + ")\n", + "\n", + "handle2 = ctrl.continue_experiment(list(extra), stim_mode=\"previous\")\n", + "print(f\"continuation started, handle2.is_running()={handle2.is_running()}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "handle2.wait()\n", + "print(handle2.status().state)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 9. Finish + tear down" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mic.post_experiment()\n", + "ctrl.finish_experiment()\n", + "print(f\"All data written to: {path}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv (3.12.12)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/experiments/03_demo_writer_implementation/ome_zarr_writer.ipynb b/experiments/03_demo_writer_implementation/ome_zarr_writer.ipynb index 182056b..951dee8 100644 --- a/experiments/03_demo_writer_implementation/ome_zarr_writer.ipynb +++ b/experiments/03_demo_writer_implementation/ome_zarr_writer.ipynb @@ -263,2095 +263,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
[04/02/26 09:02:45] INFO     MDA Started: GeneratorMDASequence()                                     _runner.py:378\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:45]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Started: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=728559;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=20873;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#378\u001b\\\u001b[2m378\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 0, 'fname': '000_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=52286;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=716636;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 0, 'fname': '000_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=409514;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=399863;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 0, 'fname': '001_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=908341;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=458268;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 0, 'fname': '001_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=967219;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=827831;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 0, 'fname': '002_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=18054;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=409817;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:46] INFO     index={'t': 0, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 0, 'fname': '002_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:46]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=911226;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=22889;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 3, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 3, 'timestep': 0, 'fname': '003_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=747507;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=908344;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 3, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 3,                       \n",
-       "                             'timestep': 0, 'fname': '003_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=468565;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=152443;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 4, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 4, 'timestep': 0, 'fname': '004_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=934566;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=587064;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 4, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 4,                       \n",
-       "                             'timestep': 0, 'fname': '004_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=163621;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=877245;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 5, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 5, 'timestep': 0, 'fname': '005_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=953337;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=389876;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 5, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 5,                       \n",
-       "                             'timestep': 0, 'fname': '005_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=598783;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=78765;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 6, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 6, 'timestep': 0, 'fname': '006_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=500017;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=496287;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 6, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 6,                       \n",
-       "                             'timestep': 0, 'fname': '006_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=935740;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=709262;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 7, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 7, 'timestep': 0, 'fname': '007_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=709559;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=43334;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:47] INFO     index={'t': 0, 'p': 7, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 7,                       \n",
-       "                             'timestep': 0, 'fname': '007_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:47]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=486576;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=171283;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 8, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 8, 'timestep': 0, 'fname': '008_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=431587;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=183792;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 8, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 8,                       \n",
-       "                             'timestep': 0, 'fname': '008_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=883053;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=154335;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 1, 'fname': '000_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=505724;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=540251;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 1, 'fname': '000_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=511030;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=882527;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 0} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 0, 'timestep': 1, 'fname':                        \n",
-       "                             '000_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=986107;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=252197;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 1, 'fname': '001_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=574227;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=239882;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 1, 'fname': '001_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=784364;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=419060;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 1} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 1, 'timestep': 1, 'fname':                        \n",
-       "                             '001_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=759394;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=181064;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'001_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 1, 'fname': '002_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=345013;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=944588;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:48] INFO     index={'t': 1, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 1, 'fname': '002_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:48]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=402213;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=126090;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 2} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 2, 'timestep': 1, 'fname':                        \n",
-       "                             '002_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=287780;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=592630;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'002_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 3, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 3, 'timestep': 1, 'fname': '003_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=886551;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=332224;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 3, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 3,                       \n",
-       "                             'timestep': 1, 'fname': '003_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=92242;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=655638;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 3} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 3, 'timestep': 1, 'fname':                        \n",
-       "                             '003_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=780346;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=284267;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'003_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 4, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 4, 'timestep': 1, 'fname': '004_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=656323;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=606776;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 4, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 4,                       \n",
-       "                             'timestep': 1, 'fname': '004_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=538648;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=754654;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 4} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 4, 'timestep': 1, 'fname':                        \n",
-       "                             '004_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=397637;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=962921;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'004_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 5, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 5, 'timestep': 1, 'fname': '005_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=412431;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=21726;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 5, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 5,                       \n",
-       "                             'timestep': 1, 'fname': '005_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=55606;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=859300;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:49] INFO     index={'t': 1, 'p': 5} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 5, 'timestep': 1, 'fname':                        \n",
-       "                             '005_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:49]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=963248;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=442724;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'005_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 6, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 6, 'timestep': 1, 'fname': '006_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=266828;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=327422;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 6, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 6,                       \n",
-       "                             'timestep': 1, 'fname': '006_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=721574;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=538662;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 6} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 6, 'timestep': 1, 'fname':                        \n",
-       "                             '006_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=414363;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=626019;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'006_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 7, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 7, 'timestep': 1, 'fname': '007_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=289679;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=226154;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 7, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 7,                       \n",
-       "                             'timestep': 1, 'fname': '007_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=627318;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=999096;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 7} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 7, 'timestep': 1, 'fname':                        \n",
-       "                             '007_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=127200;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=467582;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'007_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 8, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 8, 'timestep': 1, 'fname': '008_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=797145;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=495574;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 8, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 8,                       \n",
-       "                             'timestep': 1, 'fname': '008_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=608671;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=925475;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 8} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 8, 'timestep': 1, 'fname':                        \n",
-       "                             '008_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=503453;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=922009;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'008_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:50] INFO     index={'t': 2, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 2, 'fname': '000_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:50]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=250335;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=788235;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 2, 'fname': '000_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=661724;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=412828;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 2, 'fname': '001_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=430998;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=939574;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 2, 'fname': '001_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=10920;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=86364;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 2, 'fname': '002_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=660681;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=446334;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 2, 'fname': '002_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=961130;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=501559;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 3, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 3, 'timestep': 2, 'fname': '003_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=37282;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=378759;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 3, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 3,                       \n",
-       "                             'timestep': 2, 'fname': '003_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=16995;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=536411;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 4, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 4, 'timestep': 2, 'fname': '004_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=168383;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=82211;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 4, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 4,                       \n",
-       "                             'timestep': 2, 'fname': '004_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=435733;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=419453;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:51] INFO     index={'t': 2, 'p': 5, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 5, 'timestep': 2, 'fname': '005_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:51]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=112455;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=582007;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 5, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 5,                       \n",
-       "                             'timestep': 2, 'fname': '005_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=889098;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=651178;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 6, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 6, 'timestep': 2, 'fname': '006_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=704532;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=268824;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 6, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 6,                       \n",
-       "                             'timestep': 2, 'fname': '006_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=289748;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=73254;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 7, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 7, 'timestep': 2, 'fname': '007_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=295683;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=316675;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 7, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 7,                       \n",
-       "                             'timestep': 2, 'fname': '007_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=229056;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=900128;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 8, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 8, 'timestep': 2, 'fname': '008_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=681978;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=58650;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 8, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 8,                       \n",
-       "                             'timestep': 2, 'fname': '008_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=807195;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=220100;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 3, 'fname': '000_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=993214;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=926475;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 3, 'fname': '000_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=369910;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=72399;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:52] INFO     index={'t': 3, 'p': 0, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 0, 'timestep': 3,                   \n",
-       "                             'fname': '000_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:52]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=158705;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=96673;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 0} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 0, 'timestep': 3, 'fname':                        \n",
-       "                             '000_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=239390;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=433437;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 3, 'fname': '001_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=180755;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=244581;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 3, 'fname': '001_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=622425;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=637726;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 1, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 1, 'timestep': 3,                   \n",
-       "                             'fname': '001_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=646215;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=734527;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 1} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 1, 'timestep': 3, 'fname':                        \n",
-       "                             '001_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=667203;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=919844;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'001_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 3, 'fname': '002_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=451946;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=276285;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 3, 'fname': '002_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=477831;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=131596;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 2, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 2, 'timestep': 3,                   \n",
-       "                             'fname': '002_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=375096;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=72296;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 2} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 2, 'timestep': 3, 'fname':                        \n",
-       "                             '002_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=442909;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=609364;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'002_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 3, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 3, 'timestep': 3, 'fname': '003_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=911490;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=160218;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:53] INFO     index={'t': 3, 'p': 3, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 3,                       \n",
-       "                             'timestep': 3, 'fname': '003_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:53]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=106576;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=401044;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 3, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 3, 'timestep': 3,                   \n",
-       "                             'fname': '003_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=354676;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=20929;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'003_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 3} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 3, 'timestep': 3, 'fname':                        \n",
-       "                             '003_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=572396;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=777995;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'003_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 4, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 4, 'timestep': 3, 'fname': '004_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=401240;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=608943;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 4, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 4,                       \n",
-       "                             'timestep': 3, 'fname': '004_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=593104;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=684619;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 4, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 4, 'timestep': 3,                   \n",
-       "                             'fname': '004_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=348550;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=736315;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'004_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 4} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 4, 'timestep': 3, 'fname':                        \n",
-       "                             '004_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m4\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=558517;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=47004;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'004_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 5, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 5, 'timestep': 3, 'fname': '005_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=12509;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=516400;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 5, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 5,                       \n",
-       "                             'timestep': 3, 'fname': '005_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=110144;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=296595;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 5, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 5, 'timestep': 3,                   \n",
-       "                             'fname': '005_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=615707;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=197475;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'005_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 5} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 5, 'timestep': 3, 'fname':                        \n",
-       "                             '005_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m5\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=548126;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=432194;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'005_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:54] INFO     index={'t': 3, 'p': 6, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 6, 'timestep': 3, 'fname': '006_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:54]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=514630;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=211701;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 6, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 6,                       \n",
-       "                             'timestep': 3, 'fname': '006_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=736692;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=353908;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 6, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 6, 'timestep': 3,                   \n",
-       "                             'fname': '006_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=824878;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=415270;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'006_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 6} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 6, 'timestep': 3, 'fname':                        \n",
-       "                             '006_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m6\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=299195;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=436641;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'006_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 7, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 7, 'timestep': 3, 'fname': '007_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=314234;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=710227;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 7, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 7,                       \n",
-       "                             'timestep': 3, 'fname': '007_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=257699;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=967330;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 7, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 7, 'timestep': 3,                   \n",
-       "                             'fname': '007_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=736299;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=671081;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'007_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 7} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 7, 'timestep': 3, 'fname':                        \n",
-       "                             '007_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m7\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=877064;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=573612;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'007_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 8, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 8, 'timestep': 3, 'fname': '008_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=822433;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=192703;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 8, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 8,                       \n",
-       "                             'timestep': 3, 'fname': '008_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=549412;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=582442;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/02/26 09:02:55] INFO     index={'t': 3, 'p': 8, 'c': 2} channel=Channel(config='Rhodamine')      _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 metadata={'fov': 8, 'timestep': 3,                   \n",
-       "                             'fname': '008_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI',                 \n",
-       "                             'FITC'], 'stim_power': None, 'stim_exposure': 100.0, 'img_type':                      \n",
-       "                             <ImgType.IMG_REF: 3>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/02/26 09:02:55]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Rhodamine'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=307810;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=625240;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'fname'\u001b[0m: \u001b[32m'008_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_REF:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 8} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 8, 'timestep': 3, 'fname':                        \n",
-       "                             '008_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m8\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=234026;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=360137;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'008_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     MDA Finished: GeneratorMDASequence()                                    _runner.py:465\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Finished: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=24146;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=882084;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#465\u001b\\\u001b[2m465\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Experiment complete.\n" - ] - } - ], - "source": [ - "from faro.core.controller import Controller\n", - "\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.run_experiment(events)\n", - "ctrl.finish_experiment()\n", - "\n", - "print(\"Experiment complete.\")" - ] + "outputs": [], + "source": "from faro.core.controller import Controller\n\nctrl = Controller(mic, pipeline, writer=writer)\nctrl.run_experiment(events).wait()\nctrl.finish_experiment()\n\nprint(\"Experiment complete.\")" }, { "cell_type": "markdown", @@ -2566,4 +481,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/experiments/03_demo_writer_implementation/ome_zarr_writer_plate.ipynb b/experiments/03_demo_writer_implementation/ome_zarr_writer_plate.ipynb index 27f297d..e4a45b1 100644 --- a/experiments/03_demo_writer_implementation/ome_zarr_writer_plate.ipynb +++ b/experiments/03_demo_writer_implementation/ome_zarr_writer_plate.ipynb @@ -247,670 +247,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
[04/01/26 18:07:48] INFO     MDA Started: GeneratorMDASequence()                                     _runner.py:378\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 18:07:48]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Started: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=674946;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=772363;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#378\u001b\\\u001b[2m378\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 0, 'fname': '000_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=789389;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=398802;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 0, 'fname': '000_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=669338;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=541317;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 0, 'fname': '001_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=713599;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=585434;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 0, 'fname': '001_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=724329;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=676121;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 18:07:49] INFO     index={'t': 0, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 0, 'fname': '002_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 18:07:49]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=90513;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=496824;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 0, 'fname': '002_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=690288;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=833851;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 1, 'fname': '000_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=138309;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=475300;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 1, 'fname': '000_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=247224;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=792674;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 0} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 0, 'timestep': 1, 'fname':                        \n",
-       "                             '000_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=190152;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=972588;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 1, 'fname': '001_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=178487;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=956673;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 1, 'fname': '001_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=884593;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=652035;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 1} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 1, 'timestep': 1, 'fname':                        \n",
-       "                             '001_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=327167;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=890495;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'001_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 1, 'fname': '002_00001', 'time': 0.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=622314;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=882301;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.5 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 1, 'fname': '002_00001', 'time': 0.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=202618;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=635682;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 18:07:50] INFO     index={'t': 1, 'p': 2} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=0.5 metadata={'fov': 2, 'timestep': 1, 'fname':                        \n",
-       "                             '002_00001', 'time': 0.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 18:07:50]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=508262;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=717046;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'002_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 2, 'fname': '000_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=124292;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=439929;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 2, 'fname': '000_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=587043;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=377522;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 2, 'fname': '001_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=363037;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=293924;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 2, 'fname': '001_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=12535;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=582083;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 2, 'fname': '002_00002', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=243331;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=419720;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 2, 'fname': '002_00002', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=870990;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=113330;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 3, 'fname': '000_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=367154;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=526370;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 3, 'fname': '000_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=719463;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=422785;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 0} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 0, 'timestep': 3, 'fname':                        \n",
-       "                             '000_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=97359;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=533;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 18:07:51] INFO     index={'t': 3, 'p': 1, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=1.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 1, 'timestep': 3, 'fname': '001_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 18:07:51]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=405618;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=804735;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 1, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 1,                       \n",
-       "                             'timestep': 3, 'fname': '001_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=730488;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=246479;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'001_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 1} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 1, 'timestep': 3, 'fname':                        \n",
-       "                             '001_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=163326;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=338826;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'001_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 2, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.5 x_pos=2.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 2, 'timestep': 3, 'fname': '002_00003', 'time': 1.5,                 \n",
-       "                             'stim': True, 'channels': ['DAPI', 'FITC'], 'stim_power': None,                       \n",
-       "                             'stim_exposure': 100.0, 'img_type': <ImgType.IMG_RAW: 1>}                             \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=766689;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=843976;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 2, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.5 z_pos=0.0 metadata={'fov': 2,                       \n",
-       "                             'timestep': 3, 'fname': '002_00003', 'time': 1.5, 'stim': True,                       \n",
-       "                             'channels': ['DAPI', 'FITC'], 'stim_power': None, 'stim_exposure':                    \n",
-       "                             100.0, 'img_type': <ImgType.IMG_RAW: 1>}                                              \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=187147;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=484161;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'002_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 2} channel=Channel(config='Cy5') exposure=100.0     _runner.py:337\n",
-       "                             min_start_time=1.5 metadata={'fov': 2, 'timestep': 3, 'fname':                        \n",
-       "                             '002_00003', 'time': 1.5, 'stim': True, 'channels': ['DAPI', 'FITC'],                 \n",
-       "                             'stim_power': None, 'stim_exposure': 100.0, 'img_type':                               \n",
-       "                             <ImgType.IMG_STIM: 2>}                                                                \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m2\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'Cy5'\u001b[0m\u001b[1m)\u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b]8;id=482789;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=332543;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'002_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.5\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim_power'\u001b[0m: \u001b[3;35mNone\u001b[0m, \u001b[32m'stim_exposure'\u001b[0m: \u001b[1;36m100.0\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_STIM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     MDA Finished: GeneratorMDASequence()                                    _runner.py:465\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Finished: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=607404;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=57147;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#465\u001b\\\u001b[2m465\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Experiment complete.\n" - ] - } - ], - "source": [ - "from faro.core.controller import Controller\n", - "\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.run_experiment(events)\n", - "ctrl.finish_experiment()\n", - "\n", - "print(\"Experiment complete.\")" - ] + "outputs": [], + "source": "from faro.core.controller import Controller\n\nctrl = Controller(mic, pipeline, writer=writer)\nctrl.run_experiment(events).wait()\nctrl.finish_experiment()\n\nprint(\"Experiment complete.\")" }, { "cell_type": "markdown", @@ -1164,4 +504,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/experiments/03_demo_writer_implementation/tiff_writer.ipynb b/experiments/03_demo_writer_implementation/tiff_writer.ipynb index 795c57c..17726bd 100644 --- a/experiments/03_demo_writer_implementation/tiff_writer.ipynb +++ b/experiments/03_demo_writer_implementation/tiff_writer.ipynb @@ -230,452 +230,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
[04/01/26 12:48:39] INFO     MDA Started: GeneratorMDASequence()                                     _runner.py:378\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:39]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Started: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=809786;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=570283;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#378\u001b\\\u001b[2m378\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=0.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 0, 'fname': '000_00000', 'time': 0,                   \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=444791;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=997601;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 0, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=0.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 0, 'fname': '000_00000', 'time': 0, 'stim': False,                        \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=681959;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=575149;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00000'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:40] INFO     index={'t': 1, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=1.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 1, 'fname': '000_00001', 'time': 1.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:40]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=122352;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=427006;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 1, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=1.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 1, 'fname': '000_00001', 'time': 1.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=12943;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=156631;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00001'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:41] INFO     index={'t': 2, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=2.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 2, 'fname': '000_00002', 'time': 2.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:41]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=975111;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=94027;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m2.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 2, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=2.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 2, 'fname': '000_00002', 'time': 2.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=627817;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=863970;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m2\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00002'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m2.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:42] INFO     index={'t': 3, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=3.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 3, 'fname': '000_00003', 'time': 3.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:42]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=539976;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=277514;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m3\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m3.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 3, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=3.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 3, 'fname': '000_00003', 'time': 3.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=148283;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=398423;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m3\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00003'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m3.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:43] INFO     index={'t': 4, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=4.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 4, 'fname': '000_00004', 'time': 4.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:43]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=92492;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=615835;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m4\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00004'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m4.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 4, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=4.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 4, 'fname': '000_00004', 'time': 4.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=894555;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=912017;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m4\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00004'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m4.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:44] INFO     index={'t': 5, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=5.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 5, 'fname': '000_00005', 'time': 5.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:44]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=175752;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=776062;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m5\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00005'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m5.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 5, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=5.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 5, 'fname': '000_00005', 'time': 5.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=926112;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=729931;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m5\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m5\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00005'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m5.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:45] INFO     index={'t': 6, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=6.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 6, 'fname': '000_00006', 'time': 6.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:45]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=813712;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=584856;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m6\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00006'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m6.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 6, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=6.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 6, 'fname': '000_00006', 'time': 6.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=190896;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=695213;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m6\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00006'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m6.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:46] INFO     index={'t': 7, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=7.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 7, 'fname': '000_00007', 'time': 7.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:46]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=197260;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=495841;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m7\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00007'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m7.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 7, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=7.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 7, 'fname': '000_00007', 'time': 7.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=228591;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=439837;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m7\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00007'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m7.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:47] INFO     index={'t': 8, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=8.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 8, 'fname': '000_00008', 'time': 8.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:47]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=525250;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=716632;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m8\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00008'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m8.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 8, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=8.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 8, 'fname': '000_00008', 'time': 8.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=168114;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=64073;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m8\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m8\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00008'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m8.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
[04/01/26 12:48:48] INFO     index={'t': 9, 'p': 0, 'c': 0} channel=Channel(config='DAPI')           _runner.py:337\n",
-       "                             exposure=50.0 min_start_time=9.0 x_pos=0.0 y_pos=0.0 z_pos=0.0                        \n",
-       "                             metadata={'fov': 0, 'timestep': 9, 'fname': '000_00009', 'time': 9.0,                 \n",
-       "                             'stim': False, 'channels': ['DAPI', 'FITC'], 'img_type':                              \n",
-       "                             <ImgType.IMG_RAW: 1>}                                                                 \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m[04/01/26 12:48:48]\u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m9\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'DAPI'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=531232;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=270000;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m50\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m9\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mx_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33my_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'timestep'\u001b[0m: \u001b[1;36m9\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00009'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m9.0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     index={'t': 9, 'p': 0, 'c': 1} channel=Channel(config='FITC')           _runner.py:337\n",
-       "                             exposure=100.0 min_start_time=9.0 z_pos=0.0 metadata={'fov': 0,                       \n",
-       "                             'timestep': 9, 'fname': '000_00009', 'time': 9.0, 'stim': False,                      \n",
-       "                             'channels': ['DAPI', 'FITC'], 'img_type': <ImgType.IMG_RAW: 1>}                       \n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m \u001b[33mindex\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m't'\u001b[0m: \u001b[1;36m9\u001b[0m, \u001b[32m'p'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[32m'c'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m \u001b[33mchannel\u001b[0m=\u001b[1;35mChannel\u001b[0m\u001b[1m(\u001b[0m\u001b[33mconfig\u001b[0m=\u001b[32m'FITC'\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=906189;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=611317;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#337\u001b\\\u001b[2m337\u001b[0m\u001b]8;;\u001b\\\n", - "\u001b[2;36m \u001b[0m \u001b[33mexposure\u001b[0m=\u001b[1;36m100\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmin_start_time\u001b[0m=\u001b[1;36m9\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mz_pos\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'fov'\u001b[0m: \u001b[1;36m0\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'timestep'\u001b[0m: \u001b[1;36m9\u001b[0m, \u001b[32m'fname'\u001b[0m: \u001b[32m'000_00009'\u001b[0m, \u001b[32m'time'\u001b[0m: \u001b[1;36m9.0\u001b[0m, \u001b[32m'stim'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[2m \u001b[0m\n", - "\u001b[2;36m \u001b[0m \u001b[32m'channels'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'DAPI'\u001b[0m, \u001b[32m'FITC'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'img_type'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mImgType.IMG_RAW:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m \u001b[2m \u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
                    INFO     MDA Finished: GeneratorMDASequence()                                    _runner.py:465\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[34mINFO \u001b[0m MDA Finished: \u001b[1;35mGeneratorMDASequence\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m \u001b]8;id=378565;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py\u001b\\\u001b[2m_runner.py\u001b[0m\u001b]8;;\u001b\\\u001b[2m:\u001b[0m\u001b]8;id=966271;file://c:\\Users\\Alex\\Programmierung\\01_git\\PhD\\faro_main\\.venv\\Lib\\site-packages\\pymmcore_plus\\mda\\_runner.py#465\u001b\\\u001b[2m465\u001b[0m\u001b]8;;\u001b\\\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Experiment complete.\n" - ] - } - ], - "source": [ - "from faro.core.controller import Controller\n", - "\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.run_experiment(events)\n", - "ctrl.finish_experiment()\n", - "\n", - "print(\"Experiment complete.\")" - ] + "outputs": [], + "source": "from faro.core.controller import Controller\n\nctrl = Controller(mic, pipeline, writer=writer)\nctrl.run_experiment(events).wait()\nctrl.finish_experiment()\n\nprint(\"Experiment complete.\")" }, { "cell_type": "code", @@ -706,4 +264,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/experiments/11_erk_experiments_full_fov_stim/stim_dfacquire.ipynb b/experiments/11_erk_experiments_full_fov_stim/stim_dfacquire.ipynb index d53cf8f..d89933c 100644 --- a/experiments/11_erk_experiments_full_fov_stim/stim_dfacquire.ipynb +++ b/experiments/11_erk_experiments_full_fov_stim/stim_dfacquire.ipynb @@ -3,7 +3,7 @@ { "cell_type": "markdown", "metadata": {}, - "source": "# ERK-KTR Full FOV Stimulation Pipeline (df_acquire API)\n\nThis notebook uses the **legacy `df_acquire` API** to build acquisition events via pandas DataFrames.\nIt is functionally equivalent to `Full_FOV_stim_ERKKTR_RTMSequence.ipynb`, which uses the newer **`RTMSequence` API** \u2014 a more concise, declarative way to define multi-phase experiments.\n\n**When to use which API:**\n- **RTMSequence** (recommended): phases are defined as `RTMSequence` objects and concatenated with `+`. Stim frames, ref frames, and channels are declared per-phase. See `Full_FOV_stim_ERKKTR_RTMSequence.ipynb`.\n- **df_acquire** (this notebook): gives full control over the acquisition DataFrame. Useful for complex per-FOV condition assignments, wellplate layouts, or custom stim schedules that don't map cleanly to RTMSequence phases.\n\n**Workflow overview:**\n1. Initialize microscope and define channels / stimulation treatments\n2. Configure the image processing pipeline (segmentation, tracking, feature extraction)\n3. Select FOV positions in napari and build a `df_acquire` DataFrame per phase\n4. Convert DataFrames to events and run the experiment\n5. Post-process tracks into a single `exp_data.parquet`" + "source": "# ERK-KTR Full FOV Stimulation Pipeline (df_acquire API)\n\nThis notebook uses the **legacy `df_acquire` API** to build acquisition events via pandas DataFrames.\nIt is functionally equivalent to `Full_FOV_stim_ERKKTR_RTMSequence.ipynb`, which uses the newer **`RTMSequence` API** — a more concise, declarative way to define multi-phase experiments.\n\n**When to use which API:**\n- **RTMSequence** (recommended): phases are defined as `RTMSequence` objects and concatenated with `+`. Stim frames, ref frames, and channels are declared per-phase. See `Full_FOV_stim_ERKKTR_RTMSequence.ipynb`.\n- **df_acquire** (this notebook): gives full control over the acquisition DataFrame. Useful for complex per-FOV condition assignments, wellplate layouts, or custom stim schedules that don't map cleanly to RTMSequence phases.\n\n**Workflow overview:**\n1. Initialize microscope and define channels / stimulation treatments\n2. Configure the image processing pipeline (segmentation, tracking, feature extraction)\n3. Select FOV positions in napari and build a `df_acquire` DataFrame per phase\n4. Convert DataFrames to events and run the experiment\n5. Post-process tracks into a single `exp_data.parquet`" }, { "cell_type": "markdown", @@ -31,7 +31,7 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Experimental Settings\n\n**Microscope:** Jungfrau (no DMD). Change the import to use a different microscope.\n\n> **RTMSequence equivalent:** Channel definitions are the same, but stimulation is defined via `PowerChannel` + `stim_channels`/`stim_frames` on `RTMSequence` instead of `StimTreatment` objects. The RTMSequence API also handles per-phase timing automatically \u2014 no need for manual `N_FRAMES_PHASE_*` or `TIME_PER_FOV` bookkeeping." + "source": "### Experimental Settings\n\n**Microscope:** Jungfrau (no DMD). Change the import to use a different microscope.\n\n> **RTMSequence equivalent:** Channel definitions are the same, but stimulation is defined via `PowerChannel` + `stim_channels`/`stim_frames` on `RTMSequence` instead of `StimTreatment` objects. The RTMSequence API also handles per-phase timing automatically — no need for manual `N_FRAMES_PHASE_*` or `TIME_PER_FOV` bookkeeping." }, { "cell_type": "code", @@ -1915,7 +1915,7 @@ " \n", " \n", "\n", - "

300 rows \u00d7 22 columns

\n", + "

300 rows × 22 columns

\n", "" ], "text/plain": [ @@ -2065,7 +2065,7 @@ }, { "attachments": {}, - "cell_type": "markdown", + "cell_type": "code", "metadata": {}, "source": "# Phase 2: separate df_acquire with optocheck channel on specific timepoints\n# RTMSequence equivalent: RTMSequence(..., ref_channels=(optocheck_channel,), ref_frames=[-1])\ndf_acquire_2 = utils.generate_df_acquire(\n fovs,\n n_frames=N_FRAMES_PHASE_2,\n time_between_timesteps=TIME_BETWEEN_TIMESTEPS,\n time_per_fov=TIME_PER_FOV,\n channels=channels,\n channel_optocheck=channel_optocheck, # df_acquire passes optocheck as a parameter here\n optocheck_timepoints=optocheck_timepoints, # absolute timestep indices (not per-phase like RTMSequence)\n phase_name=\"PostDrug\",\n phase_id=1,\n condition=condition,\n)\ndf_acquire_2 = utils.apply_stim_treatments_to_df_acquire(\n df_acquire_2,\n stim_phase_2,\n condition,\n n_fovs_per_well=n_fovs_per_well,\n add_stim_exposure_group=ADD_STIM_EXPOSURE_GROUP,\n regular_spacing_between_stimulations=REGULAR_SPACING_BETWEEN_STIMULATIONS,\n)\ndf_acquire_2" }, @@ -2081,41 +2081,21 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "from faro.core.controller import Controller\n", - "from faro.core.writers import OmeZarrWriter\n", - "from faro.core.conversion import (\n", - " df_to_events,\n", - ") # df_acquire-specific: converts DataFrame -> list[RTMEvent]\n", - "\n", - "# Optional: wait before starting\n", - "for _ in range(0, int(SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600)):\n", - " time.sleep(1)\n", - "\n", - "# Disconnect napari live view so it does not interfere with the acquisition engine\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "except:\n", - " pass\n", - "\n", - "# Phase 1: convert df_acquire -> events and run\n", - "events = df_to_events(df_acquire)\n", - "writer = OmeZarrWriter(storage_path=path)\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.run_experiment(events, stim_mode=\"current\")" - ] + "source": "from faro.core.controller import Controller\nfrom faro.core.writers import OmeZarrWriter\nfrom faro.core.conversion import (\n df_to_events,\n) # df_acquire-specific: converts DataFrame -> list[RTMEvent]\nfrom faro.widgets import ExperimentStatusWidget\n\n# Optional: wait before starting\nfor _ in range(0, int(SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600)):\n time.sleep(1)\n\n# Phase 1: convert df_acquire -> events and run (non-blocking; returns a handle)\n# napari-micromanager keeps routing frames during the run -- no need to tear\n# down the live link first.\nevents = df_to_events(df_acquire)\nwriter = OmeZarrWriter(storage_path=path)\nctrl = Controller(mic, pipeline, writer=writer)\nviewer.window.add_dock_widget(\n ExperimentStatusWidget(ctrl), name=\"experiment status\", area=\"right\"\n)\nhandle = ctrl.run_experiment(events, stim_mode=\"current\")" }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": "# Phase 2: convert second df_acquire -> events and run with a new Controller\n# Note: df_acquire requires separate Controller instances per phase\n# RTMSequence equivalent: phases are concatenated and run with a single ctrl.run_experiment()\nevents_2 = df_to_events(df_acquire_2)\nctrl_2 = Controller(mic, pipeline, writer=writer)\nctrl_2.run_experiment(events_2, stim_mode=\"current\")" + "source": "# Phase 2: convert second df_acquire -> events and run with a new Controller\n# Note: df_acquire requires separate Controller instances per phase\n# RTMSequence equivalent: phases are concatenated and run with a single ctrl.run_experiment()\nhandle.wait() # phase 1 must finish before phase 2 starts on the same microscope\nevents_2 = df_to_events(df_acquire_2)\nctrl_2 = Controller(mic, pipeline, writer=writer)\nhandle2 = ctrl_2.run_experiment(events_2, stim_mode=\"current\")" }, { - "cell_type": "markdown", + "cell_type": "code", "metadata": {}, - "source": "# Post-processing (same for both APIs)\nmic.post_experiment() # currently a no-op on Jungfrau, but good practice to call\ntime.sleep(10)\n\nutils.generate_exp_data_from_tracks(path) # merge per-FOV tracks into exp_data.parquet\n\n# Reconnect napari live view\nfrom napari_micromanager._core_link import CoreViewerLink\n\nif \"viewer\" in locals():\n mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" + "source": "# Post-processing (same for both APIs)\nhandle2.wait() # block until phase 2 finishes\nmic.post_experiment() # currently a no-op on Jungfrau, but good practice to call\nctrl_2.finish_experiment() # drain the pipeline so all tracks are written\n\nutils.generate_exp_data_from_tracks(path) # merge per-FOV tracks into exp_data.parquet", + "execution_count": null, + "outputs": [] }, { "cell_type": "code", @@ -2169,4 +2149,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/experiments/11_erk_experiments_full_fov_stim/stim_ramp_dfacquire.ipynb b/experiments/11_erk_experiments_full_fov_stim/stim_ramp_dfacquire.ipynb index ca30bbb..7be6dca 100644 --- a/experiments/11_erk_experiments_full_fov_stim/stim_ramp_dfacquire.ipynb +++ b/experiments/11_erk_experiments_full_fov_stim/stim_ramp_dfacquire.ipynb @@ -690,43 +690,7 @@ "id": "414db88b", "metadata": {}, "outputs": [], - "source": [ - "from datetime import datetime\n", - "import time\n", - "\n", - "## Optional: schedule experiment start to align with drug pipetting\n", - "start_at = \"2026-04-02 08:45:00\" # target time for 1st drug addition\n", - "\n", - "# Wait so that df_acquire_1_1 finishes right at start_at (drug pipetting time)\n", - "wait_seconds = (\n", - " datetime.strptime(start_at, \"%Y-%m-%d %H:%M:%S\") - datetime.now()\n", - ").total_seconds() - df_acquire_1_1.time.max()\n", - "if wait_seconds > 0:\n", - " print(\n", - " f\"Waiting {wait_seconds/60:.1f} minutes, 1st pipetting scheduled at {start_at}\"\n", - " )\n", - " for _ in range(0, int(wait_seconds)):\n", - " time.sleep(1)\n", - "\n", - "print(\"Starting experiment\")\n", - "\n", - "# Disconnect napari live view so it does not interfere with the MDA engine\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "except:\n", - " pass\n", - "\n", - "## Phase 1: Group 1 pre-drug -- uses run_experiment (creates a new Analyzer)\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "events = df_to_events(df_acquire_1_1)\n", - "ctrl.run_experiment(events, stim_mode=\"current\")\n", - "\n", - "# Reconnect napari live view (pause point: pipette drug for group 1)\n", - "from napari_micromanager._core_link import CoreViewerLink\n", - "\n", - "if \"viewer\" in locals():\n", - " mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" - ] + "source": "from datetime import datetime\nimport time\nfrom faro.widgets import ExperimentStatusWidget\n\n## Optional: schedule experiment start to align with drug pipetting\nstart_at = \"2026-04-02 08:45:00\" # target time for 1st drug addition\n\n# Wait so that df_acquire_1_1 finishes right at start_at (drug pipetting time)\nwait_seconds = (\n datetime.strptime(start_at, \"%Y-%m-%d %H:%M:%S\") - datetime.now()\n).total_seconds() - df_acquire_1_1.time.max()\nif wait_seconds > 0:\n print(\n f\"Waiting {wait_seconds/60:.1f} minutes, 1st pipetting scheduled at {start_at}\"\n )\n for _ in range(0, int(wait_seconds)):\n time.sleep(1)\n\nprint(\"Starting experiment\")\n\n## Phase 1: Group 1 pre-drug -- uses run_experiment (creates a new Analyzer)\n## napari-micromanager keeps routing frames during the run -- the live link\n## stays connected throughout (no cleanup/reconnect needed).\nctrl = Controller(mic, pipeline, writer=writer)\nviewer.window.add_dock_widget(\n ExperimentStatusWidget(ctrl), name=\"experiment status\", area=\"right\"\n)\nevents = df_to_events(df_acquire_1_1)\n# Non-blocking; wait() blocks until the phase finishes so the next phase's\n# continue_experiment doesn't hit \"a run is already in progress\".\nctrl.run_experiment(events, stim_mode=\"current\").wait()\n\n# Pause point: pipette drug for group 1, then run the next cell." }, { "cell_type": "code", @@ -734,26 +698,7 @@ "id": "1e25eca3", "metadata": {}, "outputs": [], - "source": [ - "## Phase 2: Group 1 post-drug + Group 2 pre-drug\n", - "## Uses continue_experiment to preserve tracking state from phase 1\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "except:\n", - " pass\n", - "\n", - "events = df_to_events(df_acquire_1_2)\n", - "ctrl.continue_experiment(events, stim_mode=\"current\") # preserves pipeline state\n", - "\n", - "events = df_to_events(df_acquire_2_1)\n", - "ctrl.continue_experiment(events, stim_mode=\"current\")\n", - "\n", - "# Reconnect napari (pause point: pipette drug for group 2)\n", - "from napari_micromanager._core_link import CoreViewerLink\n", - "\n", - "if \"viewer\" in locals():\n", - " mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" - ] + "source": "## Phase 2: Group 1 post-drug + Group 2 pre-drug\n## Uses continue_experiment to preserve tracking state from phase 1\nevents = df_to_events(df_acquire_1_2)\nctrl.continue_experiment(events, stim_mode=\"current\").wait() # preserves pipeline state\n\nevents = df_to_events(df_acquire_2_1)\nctrl.continue_experiment(events, stim_mode=\"current\").wait()\n\n# Pause point: pipette drug for group 2, then run the next cell." }, { "cell_type": "code", @@ -761,25 +706,7 @@ "id": "eb3178f6", "metadata": {}, "outputs": [], - "source": [ - "## Phase 3: Group 2 post-drug + Group 3 pre-drug\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "except:\n", - " pass\n", - "\n", - "events = df_to_events(df_acquire_2_2)\n", - "ctrl.continue_experiment(events, stim_mode=\"current\")\n", - "\n", - "events = df_to_events(df_acquire_3_1)\n", - "ctrl.continue_experiment(events, stim_mode=\"current\")\n", - "\n", - "# Reconnect napari (pause point: pipette drug for group 3)\n", - "from napari_micromanager._core_link import CoreViewerLink\n", - "\n", - "if \"viewer\" in locals():\n", - " mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" - ] + "source": "## Phase 3: Group 2 post-drug + Group 3 pre-drug\nevents = df_to_events(df_acquire_2_2)\nctrl.continue_experiment(events, stim_mode=\"current\").wait()\n\nevents = df_to_events(df_acquire_3_1)\nctrl.continue_experiment(events, stim_mode=\"current\").wait()\n\n# Pause point: pipette drug for group 3, then run the next cell." }, { "cell_type": "code", @@ -799,25 +726,7 @@ "id": "0d0c67f2", "metadata": {}, "outputs": [], - "source": [ - "## Phase 4: Group 3 post-drug (final phase)\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "except:\n", - " pass\n", - "\n", - "events = df_to_events(df_acquire_3_2)\n", - "ctrl.continue_experiment(events, stim_mode=\"current\")\n", - "\n", - "## Finish: flush pipeline queue, close zarr store, merge tracks\n", - "ctrl.finish_experiment()\n", - "utils.generate_exp_data_from_tracks(path) # merge per-FOV tracks into exp_data.parquet\n", - "\n", - "from napari_micromanager._core_link import CoreViewerLink\n", - "\n", - "if \"viewer\" in locals():\n", - " mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" - ] + "source": "## Phase 4: Group 3 post-drug (final phase)\nevents = df_to_events(df_acquire_3_2)\nctrl.continue_experiment(events, stim_mode=\"current\").wait()\n\n## Finish: flush pipeline queue, close zarr store, merge tracks\nctrl.finish_experiment()\nutils.generate_exp_data_from_tracks(path) # merge per-FOV tracks into exp_data.parquet" }, { "cell_type": "code", @@ -911,4 +820,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence.ipynb b/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence.ipynb index 6289da3..067412f 100644 --- a/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence.ipynb +++ b/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence.ipynb @@ -241,24 +241,13 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.validate_events(events) # checks channels, positions, pipeline compatibility" - ], + "source": "ctrl = Controller(mic, pipeline, writer=writer)\nctrl.validate_events(events) # checks channels, positions, pipeline compatibility\n\n# Live status + pause/stop buttons; re-binds when run_experiment starts.\nfrom faro.widgets import ExperimentStatusWidget\n\nviewer.window.add_dock_widget(\n ExperimentStatusWidget(ctrl), name=\"experiment status\", area=\"right\"\n)", "id": "5718ece3" }, { "cell_type": "markdown", "metadata": {}, - "source": [ - "### Run experiment\n", - "\n", - "The optional sleep loop delays acquisition start (set `SLEEP_BEFORE_EXPERIMENT_START_in_H` above).\n", - "\n", - "`mm_wdg._core_link.cleanup()` disconnects the napari live view so it does not interfere with the MDA engine during acquisition.\n", - "\n", - "`ctrl.run_experiment(events, stim_mode=\"current\")` starts the acquisition. Images are stored and pipeline runs asynchronously." - ], + "source": "### Run experiment\n\nThe optional sleep loop delays acquisition start (set `SLEEP_BEFORE_EXPERIMENT_START_in_H` above).\n\n`ctrl.run_experiment(events, stim_mode=\"current\")` starts the acquisition (non-blocking). Images are stored and the pipeline runs asynchronously; napari-micromanager keeps showing frames in its preview layer during the run, so the live link does not need to be torn down first.", "id": "8fc9c376" }, { @@ -266,19 +255,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "# Optional: wait before starting (set SLEEP_BEFORE_EXPERIMENT_START_in_H above)\n", - "for _ in range(0, int(SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600)):\n", - " time.sleep(1)\n", - "\n", - "# Disconnect napari live view so it does not interfere with the acquisition engine\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "except:\n", - " pass\n", - "\n", - "ctrl.run_experiment(events, stim_mode=\"current\")" - ], + "source": "# Optional: wait before starting (set SLEEP_BEFORE_EXPERIMENT_START_in_H above)\nfor _ in range(0, int(SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600)):\n time.sleep(1)\n\n# napari-micromanager keeps routing frames into the preview layer during the\n# run; no need to tear down the live link first.\nctrl.run_experiment(events, stim_mode=\"current\")", "id": "e9146e29" }, { @@ -299,17 +276,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "ctrl.finish_experiment() # flush pipeline queue and close zarr store\n", - "\n", - "utils.generate_exp_data_from_tracks(path) # merge per-FOV tracks into exp_data.parquet\n", - "\n", - "# Reconnect napari live view after acquisition is done\n", - "from napari_micromanager._core_link import CoreViewerLink\n", - "\n", - "if \"viewer\" in locals():\n", - " mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" - ], + "source": "ctrl.finish_experiment() # flush pipeline queue and close zarr store\n\nutils.generate_exp_data_from_tracks(path) # merge per-FOV tracks into exp_data.parquet", "id": "6d784fe9" } ], diff --git a/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence_demo_mic.ipynb b/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence_demo_mic.ipynb index 44041ba..2ff8be6 100644 --- a/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence_demo_mic.ipynb +++ b/experiments/11_erk_experiments_full_fov_stim/stim_rtmsequence_demo_mic.ipynb @@ -588,48 +588,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[ControllerSimulated] frameReady: img_type=ImgType.IMG_RAW fname=000_00000\n", - "[ControllerSimulated] frameReady: img_type=ImgType.IMG_RAW fname=001_00000\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\Jungfrau\\Documents\\alandolt\\code\\restructure_repo\\faro\\.venv\\Lib\\site-packages\\cellpose\\dynamics.py:524: UserWarning: Sparse invariant checks are implicitly disabled. Memory errors (e.g. SEGFAULT) will occur when operating on a sparse tensor which violates the invariants, but checks incur performance overhead. To silence this warning, explicitly opt in or out. See `torch.sparse.check_sparse_tensor_invariants.__doc__` for guidance. (Triggered internally at C:\\actions-runner\\_work\\pytorch\\pytorch\\pytorch\\aten\\src\\ATen\\Context.cpp:767.)\n", - " coo = torch.sparse_coo_tensor(pt, torch.ones(pt.shape[1], device=pt.device, dtype=torch.int),\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[ControllerSimulated] frameReady: img_type=ImgType.IMG_RAW fname=000_00001\n", - "[ControllerSimulated] frameReady: img_type=ImgType.IMG_RAW fname=001_00001\n", - "[ControllerSimulated] frameReady: img_type=ImgType.IMG_RAW fname=000_00002\n", - "[ControllerSimulated] frameReady: img_type=ImgType.IMG_RAW fname=001_00002\n" - ] - } - ], - "source": [ - "from faro.core.controller import ControllerSimulated\n", - "from faro.core.writers import OmeZarrWriter\n", - "\n", - "writer = OmeZarrWriter(storage_path=path)\n", - "\n", - "ctrl = ControllerSimulated(\n", - " mic, pipeline, old_data_project_path=demo_data_path, writer=writer\n", - ")\n", - "ctrl.run_experiment(events)\n", - "ctrl.finish_experiment()" - ] + "outputs": [], + "source": "from faro.core.controller import ControllerSimulated\nfrom faro.core.writers import OmeZarrWriter\n\nwriter = OmeZarrWriter(storage_path=path)\n\nctrl = ControllerSimulated(\n mic, pipeline, old_data_project_path=demo_data_path, writer=writer\n)\nctrl.run_experiment(events).wait()\nctrl.finish_experiment()" }, { "cell_type": "markdown", @@ -1543,4 +1505,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/experiments/21_cell_migration/cell_migration.ipynb b/experiments/21_cell_migration/cell_migration.ipynb index a96d608..4f2954b 100644 --- a/experiments/21_cell_migration/cell_migration.ipynb +++ b/experiments/21_cell_migration/cell_migration.ipynb @@ -1818,7 +1818,7 @@ " \n", " \n", "\n", - "

480 rows \u00d7 20 columns

\n", + "

480 rows × 20 columns

\n", "" ], "text/plain": [ @@ -1970,34 +1970,14 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "from faro.core.controller import Controller\n", - "from faro.core.writers import OmeZarrWriter\n", - "from faro.core.conversion import df_to_events\n", - "\n", - "for _ in range(0, SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600):\n", - " time.sleep(1)\n", - "\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "\n", - "except:\n", - " pass\n", - "\n", - "events = df_to_events(df_acquire)\n", - "writer = OmeZarrWriter(storage_path=path)\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.run_experiment(events, stim_mode=\"current\")\n", - "mic.post_experiment()\n", - "time.sleep(10)\n", - "\n", - "utils.generate_exp_data_from_tracks(path)\n", - "\n", - "from napari_micromanager._core_link import CoreViewerLink\n", - "\n", - "if \"viewer\" in locals():\n", - " mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" - ] + "source": "from faro.core.controller import Controller\nfrom faro.core.writers import OmeZarrWriter\nfrom faro.core.conversion import df_to_events\nfrom faro.widgets import ExperimentStatusWidget\n\nfor _ in range(0, SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600):\n time.sleep(1)\n\nevents = df_to_events(df_acquire)\nwriter = OmeZarrWriter(storage_path=path)\nctrl = Controller(mic, pipeline, writer=writer)\n\n# Live status + pause/stop buttons for the (non-blocking) run.\n# napari-micromanager keeps routing frames during the run -- no need to tear\n# down the live link first.\nviewer.window.add_dock_widget(\n ExperimentStatusWidget(ctrl), name=\"experiment status\", area=\"right\"\n)\nhandle = ctrl.run_experiment(events, stim_mode=\"current\")" + }, + { + "cell_type": "code", + "source": "# Block until the run finishes, then tear down and collect results.\nhandle.wait()\nmic.post_experiment()\nctrl.finish_experiment() # drain the pipeline so all tracks are written\n\nutils.generate_exp_data_from_tracks(path)", + "metadata": {}, + "execution_count": null, + "outputs": [] }, { "cell_type": "markdown", diff --git a/experiments/21_cell_migration/cell_migration_test.ipynb b/experiments/21_cell_migration/cell_migration_test.ipynb index b25f0c3..fc35011 100644 --- a/experiments/21_cell_migration/cell_migration_test.ipynb +++ b/experiments/21_cell_migration/cell_migration_test.ipynb @@ -936,42 +936,14 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "from faro.core.controller import ControllerSimulated\n", - "from faro.core.writers import OmeZarrWriter\n", - "from faro.core.conversion import df_to_events\n", - "\n", - "for _ in range(0, SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600):\n", - " time.sleep(1)\n", - "\n", - "try:\n", - " mm_wdg._core_link.cleanup()\n", - "except:\n", - " pass\n", - "\n", - "print(\n", - " f\"Running in simulated mode with old data from {path_with_old_data_for_simulation}\"\n", - ")\n", - "events = df_to_events(df_acquire)\n", - "writer = OmeZarrWriter(storage_path=path)\n", - "ctrl = ControllerSimulated(\n", - " mic, pipeline, path_with_old_data_for_simulation, writer=writer\n", - ")\n", - "ctrl.run_experiment(events, stim_mode=\"current\")\n", - "print(\"Experiment finished\")\n", - "mic.post_experiment()\n", - "\n", - "time.sleep(90)\n", - "\n", - "fovs_i_list = os.listdir(os.path.join(path, \"tracks\"))\n", - "fovs_i_list.sort()\n", - "dfs = []\n", - "for fov_i in fovs_i_list:\n", - " track_file = os.path.join(path, \"tracks\", fov_i)\n", - " df = pd.read_parquet(track_file)\n", - " dfs.append(df)\n", - "pd.concat(dfs).to_parquet(os.path.join(path, \"exp_data.parquet\"))" - ] + "source": "from faro.core.controller import ControllerSimulated\nfrom faro.core.writers import OmeZarrWriter\nfrom faro.core.conversion import df_to_events\nfrom faro.widgets import ExperimentStatusWidget\n\nfor _ in range(0, SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600):\n time.sleep(1)\n\nprint(\n f\"Running in simulated mode with old data from {path_with_old_data_for_simulation}\"\n)\nevents = df_to_events(df_acquire)\nwriter = OmeZarrWriter(storage_path=path)\nctrl = ControllerSimulated(\n mic, pipeline, path_with_old_data_for_simulation, writer=writer\n)\n\n# Live status + pause/stop buttons for the (non-blocking) run.\n# napari-micromanager keeps routing frames during the run -- no need to tear\n# down the live link first.\nviewer.window.add_dock_widget(\n ExperimentStatusWidget(ctrl), name=\"experiment status\", area=\"right\"\n)\nhandle = ctrl.run_experiment(events, stim_mode=\"current\")" + }, + { + "cell_type": "code", + "source": "# Block until the run finishes, then tear down and collect results.\nhandle.wait()\nprint(\"Experiment finished\")\nmic.post_experiment()\nctrl.finish_experiment() # drain the pipeline so all tracks are written\n\nfovs_i_list = os.listdir(os.path.join(path, \"tracks\"))\nfovs_i_list.sort()\ndfs = []\nfor fov_i in fovs_i_list:\n track_file = os.path.join(path, \"tracks\", fov_i)\n df = pd.read_parquet(track_file)\n dfs.append(df)\npd.concat(dfs).to_parquet(os.path.join(path, \"exp_data.parquet\"))", + "metadata": {}, + "execution_count": null, + "outputs": [] } ], "metadata": { @@ -996,4 +968,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/experiments/22_line_stimulation/line_stimulation.ipynb b/experiments/22_line_stimulation/line_stimulation.ipynb index 6797ae0..b163332 100644 --- a/experiments/22_line_stimulation/line_stimulation.ipynb +++ b/experiments/22_line_stimulation/line_stimulation.ipynb @@ -2439,47 +2439,14 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "from faro.core.controller import Controller\n", - "from faro.core.writers import OmeZarrWriter\n", - "from faro.core.conversion import df_to_events\n", - "\n", - "for _ in range(0, SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600):\n", - " time.sleep(1)\n", - "\n", - "try:\n", - "\n", - " mm_wdg._core_link.cleanup()\n", - "\n", - "except:\n", - " pass\n", - "\n", - "events = df_to_events(df_acquire)\n", - "writer = OmeZarrWriter(storage_path=path)\n", - "ctrl = Controller(mic, pipeline, writer=writer)\n", - "ctrl.run_experiment(events, stim_mode=\"current\")\n", - "print(\"Experiment finished\")\n", - "mic.post_experiment()\n", - "\n", - "time.sleep(10)\n", - "\n", - "fovs_i_list = os.listdir(os.path.join(path, \"tracks\"))\n", - "fovs_i_list.sort()\n", - "dfs = []\n", - "\n", - "for fov_i in fovs_i_list:\n", - "\n", - " track_file = os.path.join(path, \"tracks\", fov_i)\n", - " df = pd.read_parquet(track_file)\n", - " dfs.append(df)\n", - "\n", - "pd.concat(dfs).to_parquet(os.path.join(path, \"exp_data.parquet\"))\n", - "\n", - "from napari_micromanager._core_link import CoreViewerLink\n", - "\n", - "if \"viewer\" in locals():\n", - " mm_wdg._core_link = CoreViewerLink(viewer, mic.mmc)" - ] + "source": "from faro.core.controller import Controller\nfrom faro.core.writers import OmeZarrWriter\nfrom faro.core.conversion import df_to_events\nfrom faro.widgets import ExperimentStatusWidget\n\nfor _ in range(0, SLEEP_BEFORE_EXPERIMENT_START_in_H * 3600):\n time.sleep(1)\n\nevents = df_to_events(df_acquire)\nwriter = OmeZarrWriter(storage_path=path)\nctrl = Controller(mic, pipeline, writer=writer)\n\n# Live status + pause/stop buttons for the (non-blocking) run.\n# napari-micromanager keeps routing frames during the run -- no need to tear\n# down the live link first.\nviewer.window.add_dock_widget(\n ExperimentStatusWidget(ctrl), name=\"experiment status\", area=\"right\"\n)\nhandle = ctrl.run_experiment(events, stim_mode=\"current\")" + }, + { + "cell_type": "code", + "source": "# Block until the run finishes, then tear down and collect results.\nhandle.wait()\nprint(\"Experiment finished\")\nmic.post_experiment()\nctrl.finish_experiment() # drain the pipeline so all tracks are written\n\nfovs_i_list = os.listdir(os.path.join(path, \"tracks\"))\nfovs_i_list.sort()\ndfs = []\n\nfor fov_i in fovs_i_list:\n\n track_file = os.path.join(path, \"tracks\", fov_i)\n df = pd.read_parquet(track_file)\n dfs.append(df)\n\npd.concat(dfs).to_parquet(os.path.join(path, \"exp_data.parquet\"))", + "metadata": {}, + "execution_count": null, + "outputs": [] }, { "cell_type": "markdown", diff --git a/faro/core/controller.py b/faro/core/controller.py index b3e92a0..dc23b5a 100644 --- a/faro/core/controller.py +++ b/faro/core/controller.py @@ -1,5 +1,6 @@ from faro.core.pipeline import store_img, ImageProcessingPipeline -from faro.core.data_structures import FovState, ImgType, StimMode +from faro.core.data_structures import FovState, FrameWaitCancelled, ImgType, StimMode, WaitEvent +from faro.core.run_status import RunHandle, RunStatus from faro.core.writers import ( Writer, TiffWriter, @@ -12,11 +13,13 @@ ) from faro.stimulation.base import Stim, StimWithImage, StimWithPipeline +import contextlib import threading import traceback from dataclasses import dataclass from typing import Literal from faro.core._useq_compat import SLMImage +from psygnal import Signal from useq import MDAEvent from queue import Queue, Empty as QueueEmpty import numpy as np @@ -39,6 +42,34 @@ class BackgroundError: traceback: str +@dataclass(frozen=True) +class QueueStats: + """Snapshot of the Analyzer's queue depths, for backpressure display. + + The three depths each flag a distinct way the analyzer can fall + behind real time: + + * ``storage_*`` -- images buffered in RAM awaiting a disk write. + Bounded; if it saturates, the camera buffer is at risk. + * ``pipeline_*`` -- tracking/segmentation tasks submitted to the + executor and not yet finished. At ``pipeline_max`` new frames + start being deferred instead of run inline. + * ``deferred_depth`` -- frames the pipeline could not keep up with, + queued (metadata only) to be reloaded from disk and processed + later. Unbounded; a steadily growing value means the pipeline is + permanently behind. + """ + + storage_depth: int # images buffered, awaiting disk write + storage_max: int # storage queue capacity + pipeline_inflight: int # pipeline tasks submitted, not yet finished + pipeline_max: int # depth at which new frames get deferred + deferred_depth: int # frames deferred for later reprocessing + stored_images: int # cumulative images written + skipped_pipeline: int # cumulative frames deferred + deferred_processed: int # cumulative deferred frames later processed + + class Analyzer: """Image analyzer with priority: Get -> Store >> Pipeline. @@ -137,6 +168,44 @@ def get_fov_state(self, fov_index: int) -> FovState: self.fov_states[fov_index] = FovState() return self.fov_states[fov_index] + def cancel_pending_waits(self) -> None: + """Wake any feed-loop thread parked in :meth:`get_stim_mask`. + + ``get_stim_mask`` blocks on ``stim_mask_queue.wait_for_frame`` + for up to ``stim_mask_timeout`` seconds. Cancelling the + dispensers makes that wait raise ``FrameWaitCancelled`` + immediately, so a cancelled run tears down without waiting out + the timeout. Called (via ``Controller._cancel_stim_waits``) + from ``RunHandle.cancel`` on the caller's thread. + + Only the stim-mask dispensers are cancelled: the tracks-queue + waiters run on pipeline workers that ``shutdown`` already + drains, and they have a file-based fallback for timeouts. + """ + # Snapshot: the feed-loop thread may insert a new FovState via + # get_fov_state() concurrently with this iteration. + for fov_state in list(self.fov_states.values()): + fov_state.stim_mask_queue.cancel() + + def queue_stats(self) -> "QueueStats": + """Return a thread-safe snapshot of the current queue depths. + + Cheap enough to poll from a UI timer. ``Queue.qsize`` is + approximate under concurrency but fine for a read-out. + """ + with self.task_lock: + inflight = self.active_pipeline_tasks + return QueueStats( + storage_depth=self._storage_queue.qsize(), + storage_max=self._storage_queue.maxsize, + pipeline_inflight=inflight, + pipeline_max=self.max_queue_size, + deferred_depth=self._deferred_queue.qsize(), + stored_images=self.stored_images, + skipped_pipeline=self.skipped_pipeline, + deferred_processed=self.deferred_processed, + ) + def _record_background_error( self, source: BackgroundErrorSource, exc: BaseException ) -> None: @@ -188,6 +257,12 @@ def get_stim_mask( mask = fov_state.stim_mask_queue.wait_for_frame( frame_idx, timeout=timeout ) + except FrameWaitCancelled: + # Run is being cancelled — the dispenser was woken by + # Analyzer.cancel_pending_waits(). Unwind quietly so the + # feed loop reaches its cancel check; not a failure, so + # no background error is recorded. + return None except QueueEmpty as e: # _build_stim_slm still log-and-continues with False, but # hardware tests check background_errors so the dropped stim @@ -570,6 +645,11 @@ class Controller: STOP_EVENT = object() + # Emitted on each new ``run_experiment`` / ``continue_experiment`` call, + # carrying the freshly-created RunHandle. Widgets subscribe to this so + # they can re-bind to whichever run is current. + runStarted = Signal(object) + def __init__(self, mic, pipeline, *, writer: Writer | None = None): """ Args: @@ -577,6 +657,15 @@ def __init__(self, mic, pipeline, *, writer: Writer | None = None): pipeline: ImageProcessingPipeline instance. writer: Storage backend. If None, Analyzer uses TiffWriter (default). Pass an OmeZarrWriter for OME-Zarr output. + + Note: + ``run_experiment`` and ``continue_experiment`` are *non-blocking* + in this version: they spawn a worker thread and return a + :class:`RunHandle` immediately. Call ``handle.wait()`` to block + until the run finishes, ``handle.cancel()`` to abort, or + subscribe to ``handle.statusChanged`` for live updates. The + ``runStarted`` signal on the controller fires for every new run + so widgets can re-bind. """ self._mic = mic self._pipeline = pipeline @@ -592,6 +681,7 @@ def __init__(self, mic, pipeline, *, writer: Writer | None = None): self._experiment_start: float | None = None self._event_queue: Queue | None = None # for extend_experiment self._pending_sentinels: int = 0 # number of None sentinels yet to consume + self._pending_sentinels_lock = threading.Lock() self._fov_positions: dict[int, tuple[float, float, float]] = {} self._pre_loop_hook: callable | None = None # testing hook self._all_events: list = [] # accumulated events for JSON persistence @@ -600,10 +690,23 @@ def __init__(self, mic, pipeline, *, writer: Writer | None = None): # Survives finish_experiment() so tests/notebooks can inspect it. self.background_errors: list[BackgroundError] = [] - # Fatal condition raised from the signal-callback thread, re-raised - # after the MDA drains (see _on_frame_ready + _run_mda_with_events). + # Fatal condition raised from the signal-callback thread, surfaced + # through the handle's RunStatus.fatal_error. self._fatal_error: BaseException | None = None + # Current run handle (None when no run is in progress / between runs). + # The worker thread owns it; status update sites use it via this attr. + self._current_handle: RunHandle | None = None + + # (p, t) index of the RTMEvent whose frames are currently arriving. + # _bump_status_for_frame uses it to detect RTMEvent boundaries so + # n_events_acquired / lag update once per RTMEvent, not per frame. + self._rtm_key: tuple | None = None + + # monotonic-clock origin for lag, anchored to the *first* frame of + # the run (see _bump_status_for_frame). None until that frame. + self._lag_origin: float | None = None + # ------------------------------------------------------------------ # Public API # ------------------------------------------------------------------ @@ -623,23 +726,35 @@ def validate_events(self, events) -> bool: ok = self._mic.validate_hardware(events) and ok return ok - def run_experiment(self, events, *, stim_mode="current", validate=True): - """Run an acquisition from a list of RTMEvents. + def run_experiment( + self, events, *, stim_mode="current", validate=True + ) -> RunHandle: + """Start an acquisition asynchronously. Returns immediately. + + The MDA feed loop runs in a worker thread; ``RunHandle`` exposes + ``wait()`` / ``cancel()`` / ``status()`` and a ``statusChanged`` + signal for live observation. There is **no** synchronous fallback — + callers that previously did ``ctrl.run_experiment(events)`` must + now do ``ctrl.run_experiment(events).wait()`` if they want the old + blocking semantics. ``handle.wait()`` re-raises any worker-side + ``fatal_error`` so the prior raise-on-failure behaviour is + preserved when callers explicitly opt in. Args: - events: Iterable of RTMEvent. Will be materialised to a list - when ``validate=True`` so it can be iterated twice. - stim_mode: How stim masks are resolved when the stimulator needs - labels or images. - - * ``"current"`` -- acquire the imaging frame, wait for the - pipeline to segment it and produce the mask, then stimulate - within the same timepoint. - * ``"previous"`` -- stimulate using the mask produced from the - *previous* timepoint (for the same FOV). - validate: Run :meth:`validate_events` before starting. Set to - ``False`` to skip (e.g. if you already validated manually). + events: Iterable of RTMEvent. Materialised to a list. + stim_mode: How stim masks are resolved (``"current"`` / + ``"previous"``). See previous docstring for the gritty + semantics. + validate: Run :meth:`validate_events` before starting. Validation + still happens *synchronously* before the worker spawns so + bad event lists surface as exceptions on the calling thread. + + Raises: + RuntimeError: If a previous run is still in progress. Call + ``handle.wait()`` or ``handle.cancel()`` first. + ValueError: If ``validate=True`` and events fail validation. """ + self._require_no_active_run() events = list(events) if validate: if not self.validate_events(events): @@ -648,58 +763,47 @@ def run_experiment(self, events, *, stim_mode="current", validate=True): "Fix the issues or pass validate=False to skip." ) - if self._experiment_start is None: - self._experiment_start = time.monotonic() - - # Pre-compute offset so extend_experiment can use it during the run - if events: - self._t_offset = max(e.index.get("t", 0) for e in events) + 1 - - # Persist events to storage as JSON - self._all_events = list(events) - if self._writer is not None: - self._writer.save_events(self._all_events) - - # Initialize writer stream with values derived from events + microscope - if ( - isinstance(self._writer, OmeZarrWriter) - and self._writer._stream is None - and self._writer._raw_array is None - ): - self._writer.init_stream( - position_names=_extract_positions_from_events(events), - channel_names=_extract_channel_names_from_events(events), - image_height=self._mic.mmc.getImageHeight(), - image_width=self._mic.mmc.getImageWidth(), - n_timepoints=_extract_n_timepoints_from_events(events), - n_stim_channels=_extract_n_stim_channels_from_events(events), - ) - - self._analyzer = Analyzer(self._pipeline, writer=self._writer) - self._analyzer.stim_mode = stim_mode - self._validate_fov_positions(events) - self._run_mda_with_events(events, stim_mode=stim_mode) - - # Update wall-clock offset for continuation - self._time_offset = time.monotonic() - self._experiment_start + # Sort once here so the order the worker processes them matches + # the order the widget displays. _run_mda_with_events also sorts + # (idempotent on an already-sorted list); doing it here lets us + # stash the canonical sequence on the handle for status widgets. + events = sorted( + events, key=lambda e: (e.min_start_time or 0, e.index.get("p", 0)) + ) - def continue_experiment(self, events, *, stim_mode="current", validate=True): - """Continue acquisition with new events, preserving all pipeline state. + handle = RunHandle( + n_events_total=len(events), + events=events, + on_cancel=self._cancel_stim_waits, + ) + self._current_handle = handle + + handle._thread = threading.Thread( + target=self._run_worker, + args=(events, stim_mode, handle), + kwargs={"is_continue": False}, + name="FaroRunWorker", + daemon=True, + ) + handle._thread.start() + self.runStarted.emit(handle) + return handle - Reuses the existing ``Analyzer`` (and its ``FovState`` objects) so - that tracking, timestep counters, and filenames continue seamlessly - from the previous ``run_experiment()`` or ``continue_experiment()`` - call. + def continue_experiment( + self, events, *, stim_mode="current", validate=True + ) -> RunHandle: + """Continue acquisition with new events, preserving Analyzer state. - Args: - events: Iterable of RTMEvent. Timesteps and metadata will be - offset automatically. - stim_mode: Same as :meth:`run_experiment`. - validate: Same as :meth:`run_experiment`. + Same async semantics as :meth:`run_experiment`. Reuses the existing + ``Analyzer`` and per-FOV state so tracking and timestep counters + continue seamlessly across runs. Raises: - RuntimeError: If no previous experiment exists to continue. + RuntimeError: If no previous experiment exists to continue, or + if a run is still in progress. + ValueError: If ``validate=True`` and events fail validation. """ + self._require_no_active_run() if self._analyzer is None: raise RuntimeError( "No experiment to continue. Call run_experiment() first." @@ -721,21 +825,147 @@ def continue_experiment(self, events, *, stim_mode="current", validate=True): ) offset_events = self._offset_events(events) + offset_events = sorted( + offset_events, + key=lambda e: (e.min_start_time or 0, e.index.get("p", 0)), + ) - # Pre-compute offset so extend_experiment can use it during the run - if offset_events: - self._t_offset = max(e.index.get("t", 0) for e in offset_events) + 1 + handle = RunHandle( + n_events_total=len(offset_events), + events=offset_events, + on_cancel=self._cancel_stim_waits, + ) + self._current_handle = handle + + handle._thread = threading.Thread( + target=self._run_worker, + args=(offset_events, stim_mode, handle), + kwargs={"is_continue": True}, + name="FaroRunWorker", + daemon=True, + ) + handle._thread.start() + self.runStarted.emit(handle) + return handle + + def _require_no_active_run(self) -> None: + """Raise if a run is still in progress.""" + if self._current_handle is not None and self._current_handle.is_running(): + raise RuntimeError( + "An experiment is already running. Call handle.wait() or " + "handle.cancel() first." + ) + + def _cancel_stim_waits(self) -> None: + """RunHandle ``on_cancel`` hook — wake a feed loop blocked on a stim mask. + + The feed loop checks ``handle.cancel_event`` at every iteration, + but while it is parked inside ``_build_stim_slm`` -> + ``Analyzer.get_stim_mask`` -> ``FrameDispenser.wait_for_frame`` + it cannot poll. Without this hook a cancel issued during that + window would not take effect until the stim-mask timeout (up to + 80 s) elapsed — and until the feed loop unwinds, its + ``finally`` block never disconnects ``_on_frame_ready``, so + stray frames (e.g. a later DMD calibration) keep reaching the + Analyzer. Cancelling the dispensers releases the wait at once. + """ + analyzer = self._analyzer + if analyzer is not None: + analyzer.cancel_pending_waits() + + def _get_image_size(self) -> tuple[int, int]: + """Return (height, width) of the microscope's camera frames. + + Prefers ``self._mic.image_height`` / ``image_width`` (the + ``AbstractMicroscope``-level convention; ``Moench.init_scope`` and + peers populate them on the microscope instance). Falls back to a + pymmcore-plus core call when the microscope exposes one. Raises if + neither is available. + """ + h = getattr(self._mic, "image_height", None) + w = getattr(self._mic, "image_width", None) + if h is not None and w is not None: + return h, w + mmc = getattr(self._mic, "mmc", None) + if mmc is not None: + return mmc.getImageHeight(), mmc.getImageWidth() + raise RuntimeError( + "Microscope does not expose image dimensions. Set " + "self.image_height / self.image_width on the microscope, or " + "provide a CMMCorePlus instance via self.mmc." + ) + + def _run_worker( + self, events, stim_mode: str, handle: RunHandle, /, *, is_continue: bool + ) -> None: + """Background-thread entry point for an experiment run. + + Owns: writer init (incl. potentially-slow zarr ``rmtree`` on overwrite), + ``Analyzer`` construction (or reuse for continue), the feed loop, and + the final wall-clock offset update. All status updates flow through + ``handle.update`` so listeners see the progression. + """ + # started_at is set on the first acquired frame (see _on_frame_ready) + # so a pre-acquisition WaitEvent doesn't tick elapsed/lag. + handle.update(state="running") + # Fresh RTMEvent-boundary + lag-origin trackers for this run. + self._rtm_key = None + self._lag_origin = None + try: + # ---- pre-loop setup ----------------------------------------- + if self._experiment_start is None: + self._experiment_start = time.monotonic() + + if events: + self._t_offset = max(e.index.get("t", 0) for e in events) + 1 - # Append to accumulated events and persist - self._all_events.extend(offset_events) - if self._writer is not None: - self._writer.save_events(self._all_events) + if is_continue: + self._all_events.extend(events) + else: + self._all_events = list(events) + + if self._writer is not None: + self._writer.save_events(self._all_events) + + if ( + not is_continue + and isinstance(self._writer, OmeZarrWriter) + and self._writer._stream is None + and self._writer._raw_array is None + ): + # NB: on a network drive an overwrite-existing init can do a + # multi-minute rmtree. With the feed loop on a worker thread + # this no longer freezes napari; status stays "running" until + # the actual MDA starts. + img_h, img_w = self._get_image_size() + self._writer.init_stream( + position_names=_extract_positions_from_events(events), + channel_names=_extract_channel_names_from_events(events), + image_height=img_h, + image_width=img_w, + n_timepoints=_extract_n_timepoints_from_events(events), + n_stim_channels=_extract_n_stim_channels_from_events(events), + ) + + if not is_continue: + self._analyzer = Analyzer(self._pipeline, writer=self._writer) + self._analyzer.stim_mode = stim_mode + + self._validate_fov_positions(events) - self._validate_fov_positions(offset_events) - self._run_mda_with_events(offset_events, stim_mode=stim_mode) + # ---- the feed loop ------------------------------------------ + self._run_mda_with_events(events, stim_mode=stim_mode, handle=handle) - # Update wall-clock offset for continuation - self._time_offset = time.monotonic() - self._experiment_start + except BaseException as exc: + traceback.print_exc() + handle.update( + state="error", fatal_error=exc, finished_at=time.monotonic() + ) + else: + # Update wall-clock offset for continuation + if self._experiment_start is not None: + self._time_offset = time.monotonic() - self._experiment_start + handle.update(state="done", finished_at=time.monotonic()) def extend_experiment(self, events): """Add more events to a running experiment (non-blocking). @@ -751,8 +981,11 @@ def extend_experiment(self, events): events = list(events) offset_events = self._offset_events(events) - # Add events + sentinel; bump counter so the loop keeps going - self._pending_sentinels += 1 + # Add events + sentinel; bump counter so the loop keeps going. Lock + # because the feed loop now reads _pending_sentinels from the worker + # thread while extend_experiment runs from the caller's thread. + with self._pending_sentinels_lock: + self._pending_sentinels += 1 for ev in offset_events: self._event_queue.put(ev) self._event_queue.put(None) # sentinel for this batch @@ -770,23 +1003,88 @@ def finish_experiment(self, *, drain_timeout: float = 300.0): pipeline queues to drain before raising ``TimeoutError``. On timeout no teardown happens, so the call is safe to retry with a larger value. + + If a run is still in progress this blocks until it finishes — + cancel it first via ``handle.cancel()`` if you want to abort. + + Teardown (waiting on the run + draining the Analyzer queues) runs + on a worker thread; this method pumps the Qt event loop while it + waits, so napari stays responsive instead of freezing for the + whole drain. """ - if self._analyzer is not None: - # shutdown is the gate — only snapshot background_errors and - # drop the Analyzer once it succeeds. On TimeoutError the - # Analyzer is still alive and the caller can retry. - self._analyzer.shutdown(wait=True, drain_timeout=drain_timeout) - self.background_errors.extend(self._analyzer.background_errors) - self._analyzer = None - self._t_offset = 0 - self._time_offset = 0.0 - self._experiment_start = None - self._event_queue = None - self._all_events.clear() - self._fov_positions.clear() - self._frame_buffers.clear() + done = threading.Event() + box: list[BaseException] = [] + + def _teardown() -> None: + try: + handle = self._current_handle + if handle is not None and handle.is_running(): + try: + handle.wait() + except BaseException as run_exc: + # Remember a run-side failure but still tear down. + box.append(run_exc) + self._current_handle = None + + if self._analyzer is not None: + # shutdown is the gate — only snapshot background_errors + # and drop the Analyzer once it succeeds. On TimeoutError + # the Analyzer is still alive and the caller can retry. + self._analyzer.shutdown( + wait=True, drain_timeout=drain_timeout + ) + self.background_errors.extend( + self._analyzer.background_errors + ) + self._analyzer = None + self._t_offset = 0 + self._time_offset = 0.0 + self._experiment_start = None + self._event_queue = None + self._all_events.clear() + self._fov_positions.clear() + self._frame_buffers.clear() + except BaseException as exc: + box.append(exc) + finally: + done.set() + + threading.Thread( + target=_teardown, name="FaroFinishWorker", daemon=True + ).start() + while not done.wait(timeout=0.05): + self._pump_qt_events() + if box: + raise box[0] + + @staticmethod + def _pump_qt_events() -> None: + """Process pending Qt events if a Qt app is running; no-op otherwise. + + Used by finish_experiment (which blocks the calling/main thread by + design) to keep napari responsive while teardown runs on a worker. + """ + try: + from qtpy.QtCore import QCoreApplication + except Exception: + return + app = QCoreApplication.instance() + if app is not None: + app.processEvents() + + def queue_stats(self) -> "QueueStats | None": + """Snapshot of the Analyzer's queue depths, or None when idle. + + Returns None between experiments (no Analyzer). Status widgets + poll this to show storage / pipeline / deferred backpressure. + """ + analyzer = self._analyzer + return analyzer.queue_stats() if analyzer is not None else None def stop_run(self): + """Hard-stop the run path (legacy). Prefer ``handle.cancel()``.""" + if self._current_handle is not None: + self._current_handle.cancel() self._queue.put(self.STOP_EVENT) self._mic.cancel_mda() if self._analyzer is not None: @@ -834,15 +1132,44 @@ def _validate_fov_positions(self, events): ) self._fov_positions[fov] = pos - def _run_mda_with_events(self, events, *, stim_mode): - """Run the MDA event loop — shared by run/continue_experiment.""" + def _run_mda_with_events(self, events, *, stim_mode, handle: RunHandle): + """Run the MDA event loop on the worker thread. + + Called from :meth:`_run_worker`. The whole body runs off the main + thread, so blocking primitives (``time.sleep``, ``thread.join``, + ``FrameDispenser.wait_for_frame``) no longer freeze napari. The + feed loop checks ``handle.cancel_event`` at each iteration so + ``handle.cancel()`` returns control without a Ctrl-C. + """ + # Live mode (continuous sequence acquisition) and MDA both drive the + # camera. If live is still running when the MDA's first snapImage + # fires, the snap buffer is consumed by the live-poll listener (in + # napari-micromanager: _core_link._image_snapped) before the engine + # calls getImage, and the engine raises "Camera image buffer read + # failed". Stop it unconditionally before MDA starts. + mmc = getattr(self._mic, "mmc", None) + if mmc is not None and mmc.isSequenceRunning(): + mmc.stopSequenceAcquisition() + self._mic.connect_frame(self._on_frame_ready) + # Recreate the engine queue for this run. The finally-block below + # puts a STOP_EVENT sentinel into self._queue to stop the engine; + # on a *cancelled* run the engine is aborted via cancel_mda() and + # may stop without draining the queue, leaving stale events + the + # STOP sentinel behind. Reusing that queue for the next run makes + # the new engine consume the stale sentinel and exit almost + # immediately -- the feed loop keeps pushing but nothing snaps + # (the run "sticks" after a few events). A fresh queue per run + # avoids that entirely. + self._queue = Queue() + # Set up event queue for extend_experiment support. # _pending_sentinels tracks how many extra batches (from # extend_experiment) still need to be drained. self._event_queue = Queue() - self._pending_sentinels = 0 + with self._pending_sentinels_lock: + self._pending_sentinels = 0 events = sorted( events, key=lambda e: (e.min_start_time or 0, e.index.get("p", 0)) ) @@ -858,16 +1185,116 @@ def _run_mda_with_events(self, events, *, stim_mode): try: while True: - rtm_event = self._event_queue.get() + if handle.cancel_event.is_set(): + break + + # Drain the backpressure window so queued events don't keep + # snapping while the user adjusts hardware. min_start_times + # are not shifted; late events catch up on resume. + if handle.pause_event.is_set(): + held: list[MDAEvent] = [] + try: + while True: + held.append(self._queue.get_nowait()) + except QueueEmpty: + pass + handle.update(state="paused") + while handle.pause_event.is_set(): + if handle.cancel_event.is_set(): + break + time.sleep(0.05) + for ev in held: + self._queue.put(ev) + if handle.cancel_event.is_set(): + break + handle.update(state="running") + continue + + # Short timeout so cancellation is responsive even when + # the queue is empty (waiting for extend_experiment). + try: + rtm_event = self._event_queue.get(timeout=0.1) + except QueueEmpty: + continue + if rtm_event is None: # Sentinel consumed — stop only if no extension pending - if self._pending_sentinels > 0: - self._pending_sentinels -= 1 - continue + with self._pending_sentinels_lock: + if self._pending_sentinels > 0: + self._pending_sentinels -= 1 + continue break + if isinstance(rtm_event, WaitEvent): + prev = handle.status() + handle.update( + current_event_index=dict(rtm_event.index), + n_events_consumed=prev.n_events_consumed + 1, + ) + # Feed loop runs ~3 events ahead of the engine; let + # those in-flight imaging events finish before the + # cursor jumps onto the wait cell. + while not handle.cancel_event.is_set(): + s = handle.status() + if s.n_events_acquired >= s.n_events_consumed - 1: + break + if handle.cancel_event.wait(0.05): + break + if handle.cancel_event.is_set(): + break + + base = self._experiment_start or time.monotonic() + # Anchor to whichever is later: scheduled start or now. + # A pause-drain can push wallclock past the scheduled + # window; without max() the wait would flash through. + scheduled_start = base + (rtm_event.min_start_time or 0) + deadline = max(scheduled_start, time.monotonic()) + rtm_event.duration_s + handle.update(state="waiting", wait_remaining_s=rtm_event.duration_s) + last_displayed = int(rtm_event.duration_s) + while True: + remaining = deadline - time.monotonic() + if remaining <= 0: + break + # Throttle emissions to once per displayed second: + # the widget renders int(remaining), so sub-second + # updates only churn the Qt event queue. + cur = int(remaining) + if cur != last_displayed: + handle.update(wait_remaining_s=remaining) + last_displayed = cur + if handle.cancel_event.wait(min(0.1, remaining)): + break + if handle.cancel_event.is_set(): + break + # Bump n_events_acquired so the cursor stays monotonic + # when state leaves "waiting". + new_state = "pausing" if handle.pause_event.is_set() else "running" + handle.update( + state=new_state, + wait_remaining_s=None, + n_events_acquired=handle.status().n_events_acquired + 1, + ) + continue + + # Status update: the feed loop committed to this RTMEvent. + prev = handle.status() + fov = rtm_event.index.get("p") + handle.update( + current_event_index=dict(rtm_event.index), + current_fov=fov, + n_events_consumed=prev.n_events_consumed + 1, + ) + + # Backpressure: don't get too far ahead of the MDA engine. + # Plain time.sleep is fine here -- this is a worker thread, + # not the main thread, so napari's event loop is untouched. while self._queue.qsize() >= 3: - time.sleep(0.1) + if handle.cancel_event.is_set(): + break + time.sleep(0.05) + if handle.cancel_event.is_set(): + break + self._n_channels = len(rtm_event.channels) # In "previous" mode at t=0 there is no predecessor @@ -909,9 +1336,17 @@ def _run_mda_with_events(self, events, *, stim_mode): self._event_queue = None self._queue.put(self.STOP_EVENT) if mda_thread is not None: + if handle.cancel_event.is_set(): + # Ask the engine to drop the in-flight event so the + # worker thread can exit promptly. + with contextlib.suppress(Exception): + self._mic.cancel_mda() mda_thread.join() self._mic.disconnect_frame(self._on_frame_ready) + # _fatal_error from a signal-callback thread surfaces through the + # handle's RunStatus.fatal_error -- _run_worker reads it after we + # return. Re-raise so the worker's try/except can record it. if self._fatal_error is not None: fatal = self._fatal_error self._fatal_error = None @@ -921,11 +1356,81 @@ def _run_mda_with_events(self, events, *, stim_mode): # Frame handling # ------------------------------------------------------------------ + def _bump_status_for_frame(self, event: MDAEvent) -> None: + """Update RunHandle counters for the current frame; no-op if no handle. + + An RTMEvent expands into several MDAEvents (one per imaging/ref + channel, plus stim). This handler fires per MDAEvent, so it does + two different things: + + * ``n_frames_received`` -- bumped on every imaging/ref frame. + * ``n_events_acquired`` + ``lag_ms`` -- updated only on the + *first* frame of each RTMEvent, detected by the (p, t) index + changing. So the widget's progress and the lag readout move + once per RTMEvent, not once per channel-frame. + + Stim emissions are skipped entirely: a stim frame is the + SLM-illuminated snap firing alongside its imaging frame, not a + data frame. + """ + handle = self._current_handle + if handle is None: + return + img_type = (event.metadata or {}).get("img_type", ImgType.IMG_RAW) + if img_type == ImgType.IMG_STIM: + return + prev = handle.status() + wallclock = time.time() + + # RTMEvent boundary: (p, t) identifies one logical timepoint+FOV. + key = (event.index.get("p"), event.index.get("t")) + is_new_rtm_event = key != self._rtm_key + + updates: dict = { + "n_frames_received": prev.n_frames_received + 1, + "last_frame_wallclock": wallclock, + } + if is_new_rtm_event: + self._rtm_key = key + updates["n_events_acquired"] = prev.n_events_acquired + 1 + if prev.started_at is None: + # Anchor elapsed clock to first acquisition (matches _lag_origin). + exposure_s_for_start = (getattr(event, "exposure", None) or 0.0) / 1000.0 + updates["started_at"] = time.monotonic() - exposure_s_for_start + # Lag = how far this RTMEvent's acquisition start drifted from + # its scheduled min_start_time. frameReady fires when the frame + # *finished*, so back out the exposure to estimate the start. + # + # The reference clock is anchored to the *first* frame of the + # run, NOT to started_at: min_start_time is relative to when + # the engine began acquiring, while started_at is stamped + # before writer init + Analyzer construction + engine/hardware + # startup (~1 s). Charging that constant startup to every lag + # reading made an on-schedule run look ~1 s behind. Anchoring + # to the first frame cancels it -- frame 0 reads ~0, later + # frames show genuine drift. Engine-agnostic: it needs only + # the frame callback firing plus useq's min_start_time / + # exposure, no engine-specific timing metadata. + min_start = getattr(event, "min_start_time", None) + if min_start is not None: + exposure_s = (getattr(event, "exposure", None) or 0.0) / 1000.0 + acq_start = time.monotonic() - exposure_s + if self._lag_origin is None: + # First frame defines t0: its acquisition start + # corresponds to this event's scheduled min_start_time. + self._lag_origin = acq_start - min_start + updates["lag_ms"] = ( + acq_start - self._lag_origin - min_start + ) * 1000.0 + handle.update(**updates) + def _on_frame_ready(self, img: np.ndarray, event: MDAEvent) -> None: # Drop subsequent frames after a fatal error — the MDA is winding down. if self._fatal_error is not None: return + self._bump_status_for_frame(event) + meta = event.metadata or {} img_type = meta.get("img_type", ImgType.IMG_RAW) @@ -1081,6 +1586,7 @@ def _read_zarr_raw(self, timestep: int, fov: int) -> np.ndarray: def _on_frame_ready(self, img: np.ndarray, event: MDAEvent) -> None: """Override to load images from disk for simulated controller.""" + self._bump_status_for_frame(event) meta = event.metadata or {} img_type = meta.get("img_type", ImgType.IMG_RAW) diff --git a/faro/core/data_structures.py b/faro/core/data_structures.py index 26830ac..f1b58ad 100644 --- a/faro/core/data_structures.py +++ b/faro/core/data_structures.py @@ -22,6 +22,15 @@ StimMask = Union[np.ndarray, bool] +class FrameWaitCancelled(Exception): + """Raised by :class:`FrameDispenser` wait methods after :meth:`FrameDispenser.cancel`. + + Distinct from :class:`queue.Empty` (a timeout): a cancel is a + deliberate abort, not a failure, so callers should unwind quietly + rather than recording a background error. + """ + + class FrameDispenser(Generic[_T]): """Frame-ordered handoff for per-frame values between pipeline workers. @@ -58,6 +67,7 @@ def __init__(self) -> None: self._entries: dict[int, _T] = {} self._skipped: set[int] = set() self._cond = threading.Condition() + self._cancelled = False def put_for_frame(self, idx: int, value: _T) -> None: """Record *value* as this frame's output. @@ -102,6 +112,11 @@ def get_predecessor( deadline = None if timeout is None else time.monotonic() + timeout with self._cond: while True: + if self._cancelled: + raise FrameWaitCancelled( + f"FrameDispenser cancelled while waiting for the " + f"predecessor of frame {idx}" + ) status, info = self._resolve_predecessor_locked(idx) if status == "found": value = self._entries[info] @@ -143,6 +158,10 @@ def wait_for_frame(self, idx: int, timeout: Optional[float] = None) -> Optional[ deadline = None if timeout is None else time.monotonic() + timeout with self._cond: while True: + if self._cancelled: + raise FrameWaitCancelled( + f"FrameDispenser cancelled while waiting for frame {idx}" + ) if idx in self._entries: return self._entries[idx] if idx in self._skipped: @@ -180,14 +199,35 @@ def prune_below(self, idx: int) -> None: if k < idx: self._skipped.remove(k) + def cancel(self) -> None: + """Abort every blocked waiter immediately. + + Sets a latch and wakes the condition variable, so any thread + parked in :meth:`wait_for_frame` / :meth:`get_predecessor` + raises :class:`FrameWaitCancelled` on its next loop pass + instead of sitting out the full ``timeout``. This is how an + experiment tears down promptly: a feed loop that would + otherwise wait up to ``stim_mask_timeout`` seconds for a + pipeline mask is released the instant the run is cancelled. + + The latch persists until :meth:`reset` clears it — a cancelled + dispenser fails all subsequent waits. + """ + with self._cond: + self._cancelled = True + self._cond.notify_all() + def reset(self) -> None: """Clear all state. Call only when no workers are in-flight — waiters with ``timeout=None`` would otherwise block on a chain whose predecessors you just erased. + + Also lifts a :meth:`cancel` latch so the dispenser is reusable. """ with self._cond: self._entries.clear() self._skipped.clear() + self._cancelled = False self._cond.notify_all() def _resolve_predecessor_locked( @@ -539,6 +579,23 @@ def _resolve_ch(ch): return events +class WaitEvent(RTMEvent): + """A timed pause of ``duration_s`` seconds; emits no MDAEvents.""" + + duration_s: float + + def plan_events(self, **_kwargs) -> list[MDAEvent]: + return [] + + +def wait(duration_s: float, *, min_start_time: float | None = None) -> WaitEvent: + """Construct a :class:`WaitEvent`; composes with :func:`combine`:: + + events = combine(baseline, wait(60), stim, axis="t") + """ + return WaitEvent(duration_s=duration_s, min_start_time=min_start_time) + + # --------------------------------------------------------------------------- # Frame-set helpers # --------------------------------------------------------------------------- @@ -776,18 +833,40 @@ def _combine_pair( if not events_b: return events_a - max_key = max(e.index.get(axis, 0) for e in events_a) + 1 + # WaitEvents are pure time markers: they don't claim an axis index + # (so subsequent t/p numbering is unaffected) but their duration_s + # extends the wall-clock end of the preceding sequence. + max_key = max( + (e.index.get(axis, 0) for e in events_a if not isinstance(e, WaitEvent)), + default=-1, + ) + 1 time_offset = 0.0 if offset_time: - max_time_a = max(e.min_start_time or 0 for e in events_a) - time_offset = max_time_a + _infer_interval(b, events_b) + max_time_a = max( + (e.min_start_time or 0) + (e.duration_s if isinstance(e, WaitEvent) else 0) + for e in events_a + ) + # A WaitEvent is an *explicit* gap (its duration_s), so the inferred + # inter-source interval must NOT be added across a wait boundary -- + # otherwise the wait is double-counted: the feed loop sleeps for + # duration_s AND the next source's min_start_time would include the + # wait *plus* an interval. E.g. combine(wait(10), phase) with a 10 s + # interval started the first acquisition at t=20 instead of t=10. + boundary_has_wait = isinstance(events_a[-1], WaitEvent) or isinstance( + events_b[0], WaitEvent + ) + gap = 0.0 if boundary_has_wait else _infer_interval(b, events_b) + time_offset = max_time_a + gap offset_b: list[RTMEvent] = [] for ev in events_b: - updates: dict = { - "index": {**dict(ev.index), axis: ev.index.get(axis, 0) + max_key}, - } + if isinstance(ev, WaitEvent): + updates = {} + else: + updates = { + "index": {**dict(ev.index), axis: ev.index.get(axis, 0) + max_key}, + } if offset_time: updates["min_start_time"] = (ev.min_start_time or 0) + time_offset offset_b.append(ev.model_copy(update=updates)) @@ -803,7 +882,7 @@ def _combine_pair( def combine( - *sources: RTMSequence | Iterable[RTMEvent], + *sources: RTMSequence | RTMEvent | Iterable[RTMEvent], axis: str = Axis.TIME, offset_time: bool | None = None, ) -> list[RTMEvent]: @@ -853,11 +932,14 @@ def combine( f"channels per position is a v2 feature." ) - result: list[RTMEvent] = list(sources[0]) + def _as_list(src): + return [src] if isinstance(src, RTMEvent) else list(src) + + result: list[RTMEvent] = _as_list(sources[0]) for src in sources[1:]: result = _combine_pair( result, - src, + _as_list(src), axis=axis, offset_time=offset_time, ) diff --git a/faro/core/dmd.py b/faro/core/dmd.py index 6a11010..568d08f 100644 --- a/faro/core/dmd.py +++ b/faro/core/dmd.py @@ -229,15 +229,20 @@ def calibrate( ) events.append(event_p) - self.mmc.mda.events.frameReady.disconnect() - + # Connect a calibration-only frame collector. Do NOT call the + # no-arg frameReady.disconnect() -- that removes EVERY listener, + # including napari-micromanager's preview updater and the faro + # controller's pipeline callback, and they never come back. + # Connect our own handler alongside the others and disconnect + # only it when the collection loop is done. @self.mmc.mda.events.frameReady.connect - def new_frame(img: np.ndarray, event: MDAEvent): + def _collect_calibration_frame(img: np.ndarray, event: MDAEvent): calibration_images.append(img) for event in events: self.mmc.mda.run([event]) time.sleep(0.1) + self.mmc.mda.events.frameReady.disconnect(_collect_calibration_frame) calibration_images = np.array(calibration_images) for img in calibration_images: @@ -281,7 +286,6 @@ def new_frame(img: np.ndarray, event: MDAEvent): ) if np.sum(inliers) < 4: - self.mmc.mda.events.frameReady.disconnect() self.mmc.mda.run( [ MDAEvent( @@ -350,15 +354,14 @@ def new_frame(img: np.ndarray, event: MDAEvent): ) events.append(event_p) - self.mmc.mda.events.frameReady.disconnect() - @self.mmc.mda.events.frameReady.connect - def new_frame(img: np.ndarray, event: MDAEvent): + def _collect_test_frame(img: np.ndarray, event: MDAEvent): test_image.append(img) for event in events: self.mmc.mda.run([event]) time.sleep(0.5) + self.mmc.mda.events.frameReady.disconnect(_collect_test_frame) calibration_images = np.array(calibration_images) for img in test_image: img = skimage.filters.gaussian(img, sigma=1) @@ -399,7 +402,6 @@ def new_frame(img: np.ndarray, event: MDAEvent): axs[3].set_ylim(camera_height, 0) plt.show() - self.mmc.mda.events.frameReady.disconnect() self.mmc.mda.run( [ MDAEvent( diff --git a/faro/core/pipeline.py b/faro/core/pipeline.py index 15a0f1e..8a14723 100644 --- a/faro/core/pipeline.py +++ b/faro/core/pipeline.py @@ -14,7 +14,7 @@ from faro.stimulation.base import StimWithImage, StimWithPipeline import faro.tracking.base as abstract_tracker import faro.feature_extraction.base as abstract_fe -from faro.core.data_structures import FovState, ImgType, SegmentationMethod +from faro.core.data_structures import FovState, ImgType, SegmentationMethod, WaitEvent from faro.core.utils import labels_to_particles, create_folders from datetime import datetime import queue @@ -311,6 +311,8 @@ def validate_pipeline(self, events) -> bool: stim_required = getattr(self.stimulator, "required_metadata", set()) for event in events: + if isinstance(event, WaitEvent): + continue # timed gap, carries no acquisition metadata meta_keys = set(event.metadata.keys()) # General requirements (all events) missing = general_required - meta_keys @@ -327,6 +329,16 @@ def validate_pipeline(self, events) -> bool: f"Stim event t={event.index.get('t')} p={event.index.get('p')} " f"missing stim metadata: {missing_stim}" ) + # Phased-storage requirement: run() names the per-phase tracks file + # {fov}_phase_{phase_id}_latest.parquet and reads metadata['phase_id'] + # directly, so phase_name without phase_id would crash storage mid-run. + if "phase_name" in meta_keys and "phase_id" not in meta_keys: + warnings_list.append( + f"Event t={event.index.get('t')} p={event.index.get('p')} " + f"has 'phase_name' but no 'phase_id'; add phase_id to the " + f"RTMSequence rtm_metadata (the pipeline needs it to name the " + f"per-phase tracks file)." + ) if warnings_list: import warnings as w @@ -379,7 +391,10 @@ def run( frame_idx = event.index.get("t", 0) filename_for_parquet = f"{metadata['fov']}_latest.parquet" - if "phase_id" in metadata or "phase_name" in metadata: + # A per-phase tracks file needs phase_id; key off it (not phase_name) + # so phase_name-without-phase_id can't KeyError here. validate_pipeline + # flags that combination up front. + if "phase_id" in metadata: metadata["fov_timestep"] = frame_idx filename_for_parquet = ( f"{metadata['fov']}_phase_{metadata['phase_id']}_latest.parquet" diff --git a/faro/core/pipeline_post.py b/faro/core/pipeline_post.py index 7fab940..ffd2bb6 100644 --- a/faro/core/pipeline_post.py +++ b/faro/core/pipeline_post.py @@ -517,7 +517,9 @@ def run_on_fov(self, fov_id) -> dict: df_tracked = convert_track_dtypes(df_tracked) filename_for_parquet = f"{metadata['fov']}_latest.parquet" - if "phase_id" in metadata or "phase_name" in metadata: + # Key off phase_id alone (not phase_name) so phase_name-without-phase_id + # can't KeyError here either; mirrors pipeline.run(). + if "phase_id" in metadata: metadata["fov_timestep"] = fov_obj.fov_timestep_counter filename_for_parquet = ( f"{metadata['fov']}_phase_{metadata['phase_id']}_latest.parquet" diff --git a/faro/core/run_status.py b/faro/core/run_status.py new file mode 100644 index 0000000..7dd7e28 --- /dev/null +++ b/faro/core/run_status.py @@ -0,0 +1,229 @@ +"""Status reporting + cancellation handle for asynchronous experiment runs. + +``Controller.run_experiment`` returns a ``RunHandle``. The handle owns: + +* the worker thread driving the MDA feed loop, +* a cooperative cancellation event, +* an immutable ``RunStatus`` snapshot that the controller's threads update + via :meth:`RunHandle.update`, +* a ``statusChanged`` :mod:`psygnal` signal that UI widgets (and any other + observer) can subscribe to for live updates. + +The handle is thread-safe: callers and the worker can both read ``status()`` +and the worker can call ``update(...)`` without coordination from the +caller. Status updates emit ``statusChanged`` synchronously; with ``qtpy`` +loaded :mod:`psygnal` routes the emission to listeners' threads through +Qt's queued connections, so a napari widget connected on the main thread +sees a queued slot call from the worker without extra plumbing. +""" +from __future__ import annotations + +import threading +import traceback +from dataclasses import dataclass, field, replace +from typing import TYPE_CHECKING, Any, Callable, Literal + +from psygnal import Signal + +if TYPE_CHECKING: + pass + + +RunState = Literal[ + "pending", "running", "pausing", "paused", "waiting", "cancelling", "done", "error" +] + + +@dataclass(frozen=True) +class RunStatus: + """Immutable snapshot of an experiment run.""" + + state: RunState = "pending" + # Latest RTMEvent index the feed loop committed to the MDA queue. + current_event_index: dict[str, int] | None = None + current_fov: int | None = None + # Counts. Note the distinct units: + # - *_events_* counts RTMEvents (one logical timepoint+FOV; expands + # into several MDAEvents -- one per imaging/ref channel + stim). + # - n_frames_received counts MDAEvents (individual channel snaps). + # Widgets must compare like-with-like: progress is n_events_acquired + # / n_events_total, NOT n_frames_received / n_events_total. + n_events_total: int = 0 # how many RTMEvents the run was started with + n_events_consumed: int = 0 # RTMEvents pulled by the feed loop so far + n_events_acquired: int = 0 # RTMEvents whose first frame has arrived (WaitEvents bump on completion) + n_frames_received: int = 0 # MDAEvent frames acknowledged via frameReady + # Timing. + started_at: float | None = None # time.monotonic() when the first frame began acquiring + finished_at: float | None = None # time.monotonic() when the worker exited + last_frame_wallclock: float | None = None + # Lag: how late the *current RTMEvent* started acquiring vs its + # scheduled min_start_time, in ms. Measured once per RTMEvent (on its + # first frame), not per channel-frame. Positive == behind schedule. + lag_ms: float | None = None + # Seconds left on an active WaitEvent countdown. Non-None only while + # state == "waiting"; cleared back to None when the wait ends. + wait_remaining_s: float | None = None + # Pipeline / storage backpressure visibility (best-effort). + pipeline_inflight: int = 0 + storage_queue_depth: int = 0 + # Errors. ``background_errors`` accumulates analyzer-side issues; ``fatal_error`` + # is set when the worker itself raises. + background_errors: tuple[Any, ...] = field(default_factory=tuple) + fatal_error: BaseException | None = None + + +class RunHandle: + """Handle returned by ``Controller.run_experiment`` / ``continue_experiment``. + + Use ``wait()`` to block until the run finishes, ``cancel()`` to request a + graceful stop, ``status()`` for a snapshot, or subscribe to + ``statusChanged`` for live updates. ``statusChanged`` is a per-instance + :mod:`psygnal` signal that emits the latest ``RunStatus`` after every + update. + """ + + # psygnal class-level Signal is a descriptor; access via ``handle.statusChanged`` + # gives an instance-bound signal. Different handles have independent signals. + statusChanged = Signal(RunStatus) + + def __init__( + self, + n_events_total: int = 0, + events: list | None = None, + *, + on_cancel: Callable[[], None] | None = None, + ) -> None: + self._lock = threading.RLock() + self._status = RunStatus(state="pending", n_events_total=n_events_total) + self._cancel_event = threading.Event() + self._pause_event = threading.Event() + self._thread: threading.Thread | None = None + # Hook run synchronously on the caller's thread the first time + # cancel() is called, before it returns. The controller uses it + # to wake a feed loop parked in a stim-mask wait so cancellation + # is prompt rather than bounded by the stim-mask timeout. + self._on_cancel = on_cancel + # Optional snapshot of the (sorted) RTMEvents this handle is driving. + # Widgets use this to render per-event visualisations (e.g. an event + # strip + FOV map) that need to know the full run plan up front. + # ``None`` keeps backward-compat with callers that construct + # RunHandle directly without an events list. + self.events: list | None = list(events) if events is not None else None + + # -- public API --------------------------------------------------------- + + def status(self) -> RunStatus: + """Return the current immutable status snapshot.""" + with self._lock: + return self._status + + def wait(self, timeout: float | None = None) -> RunStatus: + """Block until the worker thread finishes (or ``timeout`` elapses). + + Returns the final ``RunStatus``. Re-raises ``fatal_error`` if the + worker crashed -- mirroring the previous synchronous-run behaviour. + """ + if self._thread is not None: + self._thread.join(timeout) + status = self.status() + if status.fatal_error is not None: + raise status.fatal_error + return status + + def cancel(self) -> None: + """Request graceful cancellation. Idempotent. Does not block. + + Sets the cancel event the feed loop polls on each iteration; on the + next poll the loop stops feeding new events, asks the MDA engine to + abort the in-flight event, and exits. Use ``wait()`` afterwards to + block until the worker actually stops. + + The feed loop can also be parked deep inside a blocking stim-mask + wait, where it cannot poll the cancel event. The ``on_cancel`` + hook (set by the controller) is invoked synchronously here to + wake that wait, so cancellation takes effect immediately instead + of after the stim-mask timeout. + """ + first_cancel = not self._cancel_event.is_set() + self._cancel_event.set() + # A cancel during pause must also release the feed loop's pause-wait. + self._pause_event.clear() + if first_cancel and self._on_cancel is not None: + try: + self._on_cancel() + except Exception: + traceback.print_exc() + with self._lock: + if self._status.state in ("running", "pausing", "paused"): + self._status = replace(self._status, state="cancelling") + new_status = self._status + else: + return + self.statusChanged.emit(new_status) + + def pause(self) -> None: + """Request a graceful pause. Idempotent. Does not block. + + Sets the pause event the feed loop polls before pulling each new + RTMEvent. The loop finishes feeding the current event, then halts + at the next iteration -- the MDA engine drains whatever is already + queued, and no further events are fed until :meth:`resume`. State + goes ``running -> pausing`` here; the feed loop flips it to + ``paused`` once it actually stops. + """ + if self._pause_event.is_set(): + return + self._pause_event.set() + with self._lock: + if self._status.state == "running": + self._status = replace(self._status, state="pausing") + new_status = self._status + else: + return + self.statusChanged.emit(new_status) + + def resume(self) -> None: + """Resume a paused run. Idempotent. Does not block.""" + if not self._pause_event.is_set(): + return + self._pause_event.clear() + with self._lock: + if self._status.state in ("pausing", "paused"): + self._status = replace(self._status, state="running") + new_status = self._status + else: + return + self.statusChanged.emit(new_status) + + def is_running(self) -> bool: + """True if the worker thread is alive.""" + return self._thread is not None and self._thread.is_alive() + + def is_paused(self) -> bool: + """True if a pause has been requested (pausing or paused).""" + return self._pause_event.is_set() + + # -- worker-side helpers ------------------------------------------------ + + @property + def cancel_event(self) -> threading.Event: + """The cooperative-cancel event the feed loop polls. Worker-side.""" + return self._cancel_event + + @property + def pause_event(self) -> threading.Event: + """The cooperative-pause event the feed loop polls. Worker-side.""" + return self._pause_event + + def update(self, **updates: Any) -> RunStatus: + """Atomically apply ``updates`` to the status snapshot and emit. + + Called from worker / pipeline / storage threads. ``statusChanged`` + listeners on the main thread see queued-connection delivery via + psygnal's Qt integration. + """ + with self._lock: + self._status = replace(self._status, **updates) + new_status = self._status + self.statusChanged.emit(new_status) + return new_status diff --git a/faro/core/utils.py b/faro/core/utils.py index 8b2c46c..d91be48 100644 --- a/faro/core/utils.py +++ b/faro/core/utils.py @@ -10,6 +10,7 @@ FovState, RTMEvent, RTMSequence, + WaitEvent, ) import math import random @@ -741,6 +742,8 @@ def events_to_dataframe(events: list) -> pd.DataFrame: """ rows = [] for e in events: + if isinstance(e, WaitEvent): + continue # timed gap, not an acquired frame channels = getattr(e, "channels", ()) stim_channels = getattr(e, "stim_channels", ()) ref_channels = getattr(e, "ref_channels", ()) @@ -915,6 +918,7 @@ def apply_fov_batching( events: list[RTMEvent], time_per_fov: float, n_parallel: int | None = None, + offset_min_start_time: bool = True, ) -> list[RTMEvent]: """Adjust timing so that overflow FOVs run in subsequent batches. @@ -928,6 +932,15 @@ def apply_fov_batching( time_per_fov: Time (in seconds) to image one FOV. n_parallel: Max FOVs per batch. If *None*, computed from ``time_per_fov`` and the inferred timepoint interval. + offset_min_start_time: When True (default), stagger each FOV's + ``min_start_time`` by its position within its batch times + ``time_per_fov``. FOVs in a batch are imaged sequentially, + not simultaneously, so the k-th FOV of a batch only starts + ~``k * time_per_fov`` after the first. Encoding that in + ``min_start_time`` keeps the scheduled per-FOV frame interval + consistent and makes lag measurement meaningful. The first + FOV of every batch gets 0 offset (its batch wall-clock + offset still applies for batches > 0). Returns: New list of RTMEvent with adjusted ``min_start_time`` and ``t`` @@ -937,30 +950,40 @@ def apply_fov_batching( fov_ids = sorted({e.index.get("p", 0) for e in events}) n_fovs = len(fov_ids) - if n_fovs <= n_parallel: + # A single batch with no per-FOV stagger requested is a no-op. + if n_fovs <= n_parallel and not offset_min_start_time: return list(events) - # Map each FOV to its batch index - fov_to_batch = {fov: i // n_parallel for i, fov in enumerate(fov_ids)} + # Sorted position of each FOV: batch = pos // n_parallel, + # within-batch slot = pos % n_parallel. + fov_pos = {fov: i for i, fov in enumerate(fov_ids)} - # Per-batch wall-clock offset only — the ``t`` index stays per-FOV + # Per-batch wall-clock offset — the ``t`` index stays per-FOV # relative (every FOV uses 0..N-1) so the writer's time axis is # aligned across batches instead of concatenated. Without this each # batch was mapped to a disjoint slab of t and the zarr store had # n_batches * N empty rows per FOV. - batch0_events = [e for e in events if fov_to_batch[e.index.get("p", 0)] == 0] - max_time_batch0 = max(e.min_start_time or 0 for e in batch0_events) + batch0_events = [ + e for e in events if fov_pos[e.index.get("p", 0)] // n_parallel == 0 + ] + max_time_batch0 = max((e.min_start_time or 0 for e in batch0_events), default=0) batch_duration = max_time_batch0 + n_parallel * time_per_fov result: list[RTMEvent] = [] for ev in events: fov = ev.index.get("p", 0) - batch = fov_to_batch[fov] - if batch == 0: + pos = fov_pos[fov] + batch = pos // n_parallel + slot = pos % n_parallel + + offset = batch * batch_duration + if offset_min_start_time: + offset += slot * time_per_fov + + if offset == 0: result.append(ev) else: - time_offset = batch * batch_duration - new_time = (ev.min_start_time or 0) + time_offset + new_time = (ev.min_start_time or 0) + offset result.append(ev.model_copy(update={"min_start_time": new_time})) result.sort(key=lambda e: (e.min_start_time or 0, e.index.get("p", 0))) diff --git a/faro/microscope/base.py b/faro/microscope/base.py index 0c4309b..f4d29ce 100644 --- a/faro/microscope/base.py +++ b/faro/microscope/base.py @@ -12,6 +12,22 @@ category=FutureWarning, ) +# Force pymmcore-plus to use the psygnal signal backend regardless of whether +# a QApplication is loaded. With "auto" (the default), pymmcore-plus picks +# the qt backend whenever Qt is around, which routes core.mda.events.frameReady +# through Qt.AutoConnection -- queued delivery to the main thread for any +# non-QObject listener. The Controller's frame handler runs on the MDA engine +# thread (no Qt objects touched); since Controller.run_experiment now spawns +# a worker thread and Controller.RunHandle.wait() joins on that worker, +# the main thread is typically blocked while the engine emits frames. +# A queued Qt connection on top of that means frame callbacks pile up +# undelivered -- the engine completes happily, but no frames reach the +# pipeline. Forcing 'psygnal' keeps the data path direct and synchronous, +# decoupled from any GUI loop. Widgets that subscribe to RunHandle's own +# psygnal signals still get Qt-routed updates because *those* receivers +# are QObjects. +os.environ.setdefault("PYMM_SIGNALS_BACKEND", "psygnal") + import numpy as np from useq import MDAEvent diff --git a/faro/microscope/pertzlab/moench.py b/faro/microscope/pertzlab/moench.py index 88e261e..2c48cba 100644 --- a/faro/microscope/pertzlab/moench.py +++ b/faro/microscope/pertzlab/moench.py @@ -35,6 +35,21 @@ def _set_c_numeric_locale(): continue +def _pump_qt_events() -> None: + """Process pending Qt events if a Qt app is running; no-op otherwise. + + Used by ``calibrate_dmd(background=True)`` to keep napari responsive + while the calibration MDAs run on a worker thread. + """ + try: + from qtpy.QtCore import QCoreApplication + except Exception: + return + app = QCoreApplication.instance() + if app is not None: + app.processEvents() + + class KeepDMDAlive: def __init__(self, mmc): self.mmc = mmc @@ -97,14 +112,12 @@ class Moench(PyMMCoreMicroscope): "power": 10, } BINNING = "2x2" - # ROI: full width (no x crop), symmetric top-bottom crop to ROI_HEIGHT. - # ROI_X / ROI_Y / ROI_WIDTH are recomputed in set_roi() against the - # live camera dimensions so the values stay correct under any binning. - # Defaults below match Prime BSI (2048 unbinned -> 1024 with 2x2). + # ROI applied as-is after binning — no centering recomputation. + # Defaults below are for Prime BSI under 2x2 binning (1024 binned px wide). ROI_X = 0 - ROI_Y = 112 + ROI_Y = 30 ROI_WIDTH = 1024 - ROI_HEIGHT = 800 + ROI_HEIGHT = 792 SET_ROI_REQUIRED = True # Devices whose Busy() flag is unreliable — waitForDevice on these @@ -161,36 +174,72 @@ def calibrate_dmd( exposure=25, marker_style="x", calibration_points_DMD=None, + background=True, ): + """Calibrate the DMD against the camera (if not already calibrated). + + Args: + background: When True (default), the calibration MDAs run on a + worker thread while this call pumps the Qt event loop, so + napari stays responsive and previews the calibration spots + live. The call still blocks until calibration finishes -- + it just doesn't freeze the GUI. Set False to run + synchronously on the calling thread. + + Note: + With ``background=True`` and ``verbose=True`` the matplotlib + diagnostic plots are created from the worker thread. With the + Jupyter inline backend this routes to the running cell fine; + if plots misbehave, use ``background=False`` for verbose runs. + """ self.disable_log_output() - "Calibrate the DMD if it is not already calibrated." "" - if self.dmd is not None and self.dmd.affine is None: + if self.dmd is None or self.dmd.affine is not None: + return + + def _do_calibration() -> None: self.wakeup_dmd.stop() - self.dmd.calibrate( - verbose=verbose, - n_points=n_points, - radius=radius, - exposure=exposure, - marker_style=marker_style, - calibration_points_DMD=calibration_points_DMD, - ) - self.wakeup_dmd.run() + try: + self.dmd.calibrate( + verbose=verbose, + n_points=n_points, + radius=radius, + exposure=exposure, + marker_style=marker_style, + calibration_points_DMD=calibration_points_DMD, + ) + finally: + self.wakeup_dmd.run() - def set_roi(self): - """Apply full-width, symmetric top-bottom ROI of height ROI_HEIGHT. + if not background: + _do_calibration() + return - Recomputes ROI_X / ROI_Y / ROI_WIDTH from the camera's live - full-frame dimensions under the active binning, then writes - them back to the instance so downstream callers reading - ``mic.ROI_*`` see the actual values in effect. - """ + # Run on a worker thread; pump Qt here so napari keeps repainting + # and previewing the calibration frames. The call still blocks + # until calibration is done -- it just doesn't starve the GUI. + done = threading.Event() + box: list[BaseException] = [] + + def _worker() -> None: + try: + _do_calibration() + except BaseException as exc: # noqa: BLE001 + box.append(exc) + finally: + done.set() + + threading.Thread( + target=_worker, name="DMDCalibration", daemon=True + ).start() + while not done.wait(timeout=0.05): + _pump_qt_events() + if box: + raise box[0] + + def set_roi(self): + """Apply the class's ROI_* settings as-is (after binning is set).""" self.mmc.clearROI() - full_w = self.mmc.getImageWidth() - full_h = self.mmc.getImageHeight() - self.ROI_X = 0 - self.ROI_Y = max(0, (full_h - self.ROI_HEIGHT) // 2) - self.ROI_WIDTH = full_w self.mmc.setROI(self.ROI_X, self.ROI_Y, self.ROI_WIDTH, self.ROI_HEIGHT) def post_experiment(self): diff --git a/faro/microscope/pertzlab/niesen.py b/faro/microscope/pertzlab/niesen.py index 57313e6..1954411 100644 --- a/faro/microscope/pertzlab/niesen.py +++ b/faro/microscope/pertzlab/niesen.py @@ -107,3 +107,23 @@ def calibrate_dmd( def post_experiment(self): """Post-process the experiment.""" self.wl.stop() + + def shutdown(self): + """Tear down hardware state so the microscope can be discarded. + + Stops the wake-up-laser keepalive thread and unloads all + Micro-Manager devices so COM ports and the SLM handle are + released. Without this, pymmcore's native threads keep the + Python process alive after the main thread exits, leaving a + zombie that blocks the next session. + """ + wl = getattr(self, "wl", None) + if wl is not None: + try: + wl.stop() + except Exception: + pass + try: + self.mmc.unloadAllDevices() + except Exception: + pass diff --git a/faro/widgets/__init__.py b/faro/widgets/__init__.py new file mode 100644 index 0000000..f57b352 --- /dev/null +++ b/faro/widgets/__init__.py @@ -0,0 +1,8 @@ +"""Optional UI widgets for visualising / controlling faro runs. + +These imports are guarded so that headless deployments don't pay the Qt +import cost just from ``import faro``. +""" +from faro.widgets.experiment_status import ExperimentStatusWidget + +__all__ = ["ExperimentStatusWidget"] diff --git a/faro/widgets/experiment_status.py b/faro/widgets/experiment_status.py new file mode 100644 index 0000000..6c17223 --- /dev/null +++ b/faro/widgets/experiment_status.py @@ -0,0 +1,1005 @@ +"""Qt status widget for the controller's currently-bound run. + +Construct with a :class:`faro.core.controller.Controller` instance:: + + from faro.widgets import ExperimentStatusWidget + widget = ExperimentStatusWidget(ctrl) + viewer.window.add_dock_widget(widget, name="Experiment") + +Layout (top to bottom): + + - State label (RUNNING / DONE / CANCELLING / ERROR, color-coded) + - Legend chips (imaging / stim / ref) -- the chip matching the *current* + event type is fully opaque; the others are dimmed + - Event strip (one cell per RTMEvent, color-coded by type; past cells + are fully opaque, future cells are dimmed; the current cell has a + darker border) + - FOV map (one dot per unique FOV position, equal-aspect, with a + grey path drawn in visit order; the dot for the current FOV is + re-colored in the active event-type's color) + - Stats panels (three separate shaded frames: timing -- event N/M, + elapsed, scheduled, lag, remaining; queues -- storage / pipeline / + deferred depths, the bounded two drawn as fill bars; errors) + - Pause + Stop buttons + +The Stop button cancels the run *and* calls ``finish_experiment()`` +(flush buffered frames to disk, drop the Analyzer) so the next run +starts clean; the state banner shows ``STOPPING...`` for the duration. + +The widget subscribes to ``ctrl.runStarted``, so it automatically re-binds +to whichever run is current. Each ``RunHandle.statusChanged`` emission +updates the labels / strip / map; a small QTimer also refreshes the +``elapsed`` / ``remaining`` fields between status updates so the clock +doesn't appear frozen between frames. +""" +from __future__ import annotations + +import time +from typing import TYPE_CHECKING, Sequence + +from qtpy.QtCore import Qt, QTimer, QPointF, QRectF +from qtpy.QtGui import ( + QBrush, QColor, QFontDatabase, QPainter, QPalette, QPen, +) +from qtpy.QtWidgets import ( + QFormLayout, + QFrame, + QHBoxLayout, + QLabel, + QProgressBar, + QPushButton, + QVBoxLayout, + QWidget, +) + +from faro.core.data_structures import ImgType, WaitEvent +from faro.core.run_status import RunHandle, RunStatus + +if TYPE_CHECKING: + from faro.core.controller import Controller + + +# ───────────────────────────────────────────────────────────────────────── +# Design tokens +# ───────────────────────────────────────────────────────────────────────── + +EVENT_COLORS: dict[str, str] = { + "imaging": "#2e7d32", + "stim": "#1565c0", + "ref": "#ef6c00", + "wait": "#9e9e9e", +} +DEFAULT_EVENT_COLOR = "#888888" + +# Corner radius -- matches napari's own widgets (buttons, layer controls). +_RADIUS_PX = 3 + +# Translucent neutral overlay for the grouped panels (FOV map / stats). +# A 50%-grey at low alpha lightens a dark theme and darkens a light one, +# so the grouping reads on both without hardcoding a theme color. +_PANEL_BG = "rgba(128, 128, 128, 28)" + +# Event strip +_FUTURE_ALPHA = 90 +_PAST_ALPHA = 255 +_BORDER_PX = 2 +_GAP_PX = 1 +_MIN_GAP_AT_CELL_W = 3.0 +_WAIT_HATCH_MIN_W = 8.0 # min cell width (px) to overlay the wait hatch + +# FOV map +_DOT_RADIUS_PX = 5 +_PATH_WIDTH_PX = 2 +_MAP_PADDING_PX = 24 +_MIN_WORLD_EXTENT = 1e-6 + +# Lag warn threshold (red is recognizable on both light and dark themes) +_LAG_WARN_S = 5.0 +_LAG_BAD_COLOR = "#e53935" + +# Queue fill bars (storage / pipeline). The bar's chunk is a translucent +# fill drawn *behind* the "N / max" text; depth >= _QUEUE_WARN_FRAC of max +# flips fill + text to red, mirroring the lag warning. +_QUEUE_BAR_HEIGHT = 18 +_QUEUE_WARN_FRAC = 0.8 +# Neutral mid-grey: at low-ish alpha it lightens a dark theme and darkens +# a light one, so it reads on both without hardcoding a theme color (the +# same trick as _PANEL_BG). +_BAR_FILL = "rgba(128, 128, 128, 120)" +_BAR_FILL_WARN = "rgba(229, 57, 53, 130)" # _LAG_BAD_COLOR, translucent + + +# ───────────────────────────────────────────────────────────────────────── +# Helpers (event-list introspection + small formatters) +# ───────────────────────────────────────────────────────────────────────── + +def _event_type_token(ev) -> str: + """Map an RTMEvent to one of {"wait", "ref", "stim", "imaging"} for visualisation. + + Order of precedence matches what the user sees as the *dominant* effect + for that timepoint: wait > ref > stim > imaging. + + RTMEvent doesn't expose ``stim`` / ``ref`` booleans directly -- + ``events_to_dataframe`` derives them from the channel tuple lengths, + so we do the same here. + """ + if isinstance(ev, WaitEvent): + return "wait" + if getattr(ev, "ref_channels", ()): + return "ref" + if getattr(ev, "stim_channels", ()): + return "stim" + # Fallback for plain MDAEvents: peek at metadata['img_type'] + md = getattr(ev, "metadata", None) or {} + img_type = md.get("img_type") + if img_type == ImgType.IMG_REF: + return "ref" + if img_type == ImgType.IMG_STIM: + return "stim" + return "imaging" + + +def _extract_plan(events: Sequence) -> tuple[list[str], list[int], list[tuple[float, float]], list[float]]: + """Walk events once and return (types, fovs, positions_by_fov, scheduled). + + - ``types``: per-event type token + - ``fovs``: per-event FOV index + - ``positions_by_fov``: list indexed by FOV index, holding ``(x, y)`` + of that FOV's stage position (taken from the first event that visits + each FOV). + - ``scheduled``: per-event ``min_start_time`` in seconds (0.0 if missing) + """ + types: list[str] = [] + fovs: list[int] = [] + scheduled: list[float] = [] + seen_fov: dict[int, tuple[float, float]] = {} + + for ev in events: + types.append(_event_type_token(ev)) + p = ev.index.get("p", 0) + fovs.append(p) + if p not in seen_fov: + seen_fov[p] = (float(ev.x_pos or 0.0), float(ev.y_pos or 0.0)) + mst = getattr(ev, "min_start_time", None) + scheduled.append(float(mst) if mst is not None else 0.0) + + if seen_fov: + max_p = max(seen_fov) + positions = [seen_fov.get(i, (0.0, 0.0)) for i in range(max_p + 1)] + else: + positions = [] + return types, fovs, positions, scheduled + + +def format_duration(seconds: float, *, show_ms: bool = False) -> str: + """``hh:mm:ss h`` / ``mm:ss min`` / ``s s`` with optional .mmm. + + Leading components are dropped when zero, and the largest displayed + component is suffixed with its unit ("h" / "min" / "s") so the unit + stays explicit even after truncation. + """ + if seconds < 0: + return "-" + format_duration(-seconds, show_ms=show_ms) + h = int(seconds // 3600) + m = int((seconds % 3600) // 60) + s = seconds - h * 3600 - m * 60 + if show_ms: + if h: + return f"{h:d}:{m:02d}:{s:06.3f} h" + if m: + return f"{m:d}:{s:06.3f} min" + return f"{s:.3f} s" + s_int = int(s) + if h: + return f"{h:d}:{m:02d}:{s_int:02d} h" + if m: + return f"{m:d}:{s_int:02d} min" + return f"{s_int:d} s" + + +def _runs(seq: Sequence[str]): + """Yield (start, end_exclusive, value) for each contiguous run.""" + if not seq: + return + start, cur = 0, seq[0] + for i in range(1, len(seq)): + if seq[i] != cur: + yield start, i, cur + start, cur = i, seq[i] + yield start, len(seq), cur + + +def _hex_to_rgb(h: str) -> tuple[int, int, int]: + h = h.lstrip("#") + return int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16) + + +def _chip_style(color_hex: str, *, active: bool) -> str: + r, g, b = _hex_to_rgb(color_hex) + if active: + return ( + f"background-color: rgba({r},{g},{b},255); color: white; " + f"padding: 2px 8px; border-radius: {_RADIUS_PX}px; font-weight: bold;" + ) + return ( + f"background-color: rgba({r},{g},{b},60); color: rgba({r},{g},{b},105); " + f"padding: 2px 8px; border-radius: {_RADIUS_PX}px; font-weight: bold;" + ) + + +def _bar_style(warn: bool) -> str: + """Stylesheet for a queue fill bar; *warn* swaps fill + text to red.""" + fill = _BAR_FILL_WARN if warn else _BAR_FILL + text = f"color: {_LAG_BAD_COLOR}; font-weight: bold; " if warn else "" + return ( + f"QProgressBar {{ border: none; border-radius: {_RADIUS_PX}px; " + f"background-color: {_PANEL_BG}; {text}}}" + f"QProgressBar::chunk {{ background-color: {fill}; " + f"border-radius: {_RADIUS_PX}px; }}" + ) + + +def _make_queue_bar(font) -> QProgressBar: + """A compact QProgressBar used as a fill bar behind 'N / max' text. + + The chunk *is* the background fill; the format string carries the + numeric read-out. ``bar._warn`` caches the last applied warn state so + the stylesheet is only re-set when it actually changes. + """ + bar = QProgressBar() + bar.setTextVisible(True) + bar.setAlignment(Qt.AlignmentFlag.AlignCenter) + bar.setFixedHeight(_QUEUE_BAR_HEIGHT) + bar.setFont(font) + bar.setRange(0, 1) + bar.setValue(0) + bar.setFormat("-") + bar._warn = None # None -> first _set_queue_bar always applies a style + bar.setStyleSheet(_bar_style(False)) + return bar + + +def _wrap_panel(form: QFormLayout) -> QFrame: + """Wrap a stats form in a subtly-shaded, rounded panel frame. + + Echoes napari's boxed layer-controls sections. Each stats section + gets its own panel, so the layout's normal inter-widget spacing + reads as a clear gap between distinct areas (a hairline rule did + not separate them clearly enough). + """ + panel = QFrame() + panel.setObjectName("faroPanel") + lay = QVBoxLayout(panel) + lay.setContentsMargins(0, 0, 0, 0) + lay.addLayout(form) + panel.setStyleSheet( + f"QFrame#faroPanel {{ background-color: {_PANEL_BG}; " + f"border-radius: {_RADIUS_PX}px; }}" + ) + return panel + + +# ───────────────────────────────────────────────────────────────────────── +# EventStrip +# ───────────────────────────────────────────────────────────────────────── + +class EventStrip(QWidget): + """Horizontal strip with one cell per event, color-coded by type. + + Past + current cells are fully opaque (acts as a progress bar). Future + cells are dimmed. Same-type contiguous runs are merged into a single + fill so 1000s of events still render correctly with consistent alpha + rather than the over-stacking that per-cell alpha causes at sub-pixel + cell widths. + """ + + def __init__(self, event_types: Sequence[str], parent: QWidget | None = None): + super().__init__(parent) + self._types = list(event_types) + self._current = -1 + self.setMinimumHeight(20) + self.setMinimumWidth(120) + + def set_types(self, event_types: Sequence[str]) -> None: + self._types = list(event_types) + self._current = -1 + self.update() + + def set_current(self, index: int) -> None: + if index != self._current: + self._current = index + self.update() + + def paintEvent(self, _event) -> None: + painter = QPainter(self) + + # Empty state: grey rounded placeholder so the timeline region is + # visible before a run is loaded (replaced by the colored progress + # bar once events arrive). + if not self._types: + painter.setRenderHint(QPainter.RenderHint.Antialiasing, True) + painter.setPen(Qt.PenStyle.NoPen) + painter.setBrush(QBrush(QColor(128, 128, 128, 28))) + painter.drawRoundedRect(QRectF(self.rect()), _RADIUS_PX, _RADIUS_PX) + placeholder = self.palette().color(QPalette.ColorRole.WindowText) + placeholder.setAlpha(128) + painter.setPen(QPen(placeholder)) + painter.drawText( + self.rect(), + Qt.AlignmentFlag.AlignCenter, + "(no events loaded)", + ) + return + + painter.setRenderHint(QPainter.RenderHint.Antialiasing, False) + + n = len(self._types) + w = self.width() + h = self.height() + gap = _GAP_PX if (w / max(n, 1)) >= _MIN_GAP_AT_CELL_W else 0 + cell_w = (w - max(0, n - 1) * gap) / n + stride = cell_w + gap + + def x_for(i: int) -> float: + return i * stride + + def _fill_run(start: int, end: int, t: str, alpha: int) -> None: + color = QColor(EVENT_COLORS.get(t, DEFAULT_EVENT_COLOR)) + color.setAlpha(alpha) + # Span to the next run's start so phase boundaries don't leave + # the trailing inter-cell gap visible (within a run the merged + # fill already covers those gaps). + x0 = x_for(start) + x1 = min(x_for(end), float(w)) + rect = QRectF(x0, 0, x1 - x0, h) + # Solid base keeps thin cells visible; a bare hatch over a + # 1-2px wide wait cell renders as near-transparent and reads + # as a gap. Overlay the hatch only when wide enough to show. + painter.fillRect(rect, color) + if t == "wait" and rect.width() >= _WAIT_HATCH_MIN_W: + hatch = QColor(0, 0, 0, alpha // 3) + painter.fillRect(rect, QBrush(hatch, Qt.BrushStyle.BDiagPattern)) + + # Future / dim layer + for start, end, t in _runs(self._types): + _fill_run(start, end, t, _FUTURE_ALPHA) + + # Past + current overlay + if self._current >= 0: + past_end = min(self._current + 1, n) + for start, end, t in _runs(self._types[:past_end]): + _fill_run(start, end, t, _PAST_ALPHA) + + # Active border + if 0 <= self._current < n: + t = self._types[self._current] + pen = QPen(QColor(EVENT_COLORS.get(t, DEFAULT_EVENT_COLOR)).darker(160)) + pen.setWidth(_BORDER_PX) + painter.setPen(pen) + x0 = x_for(self._current) + cell = min(x_for(self._current + 1), float(w)) - x0 + visible_w = max(cell, 3.0) + x = min(max(0.0, x0 - (visible_w - cell) / 2), w - visible_w) + painter.drawRect(QRectF(x + 0.5, 0.5, visible_w - 1, h - 1)) + + +# ───────────────────────────────────────────────────────────────────────── +# FovMap +# ───────────────────────────────────────────────────────────────────────── + +class FovMap(QWidget): + """Equal-aspect map of FOV positions with a visit-order path. + + The active dot is recolored by ``set_current(idx, color=...)`` so it + can match the current event type's color. Background is transparent so + napari's theme shows through; the drawing area is constrained to the + largest centered square so the widget never appears taller than wide. + """ + + def __init__( + self, + positions: Sequence[tuple[float, float]], + parent: QWidget | None = None, + ): + super().__init__(parent) + self._positions = list(positions) + self._current = -1 + self._active_color = EVENT_COLORS["imaging"] + self.setMinimumWidth(160) + # The paint code (_world_to_screen) already confines the drawing + # to the largest centered square in min(width, height), so the + # *widget* itself need not be square. Make it freely resizable in + # both directions. The old approach -- setSizePolicy(.., Fixed) + # plus setFixedHeight(width) in resizeEvent -- pinned the panel's + # minimum height to its width, so once the dock was undocked and + # widened it could no longer be shrunk vertically. + from qtpy.QtWidgets import QSizePolicy + self.setSizePolicy( + QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding + ) + self.setMinimumHeight(80) + + def set_positions(self, positions: Sequence[tuple[float, float]]) -> None: + self._positions = list(positions) + self._current = -1 + self.update() + + def set_current(self, index: int, color: str | None = None) -> None: + changed = ( + index != self._current + or (color is not None and color != self._active_color) + ) + if color is not None: + self._active_color = color + self._current = index + if changed: + self.update() + + def _world_to_screen(self) -> tuple[float, float, float]: + if not self._positions: + return 1.0, 0.0, 0.0 + xs = [p[0] for p in self._positions] + ys = [p[1] for p in self._positions] + x_min, x_max = min(xs), max(xs) + y_min, y_max = min(ys), max(ys) + x_span = max(x_max - x_min, _MIN_WORLD_EXTENT) + y_span = max(y_max - y_min, _MIN_WORLD_EXTENT) + # Confine the drawing to the largest centered square -- so even if + # the widget ends up wider than tall (or vice-versa), the dots stay + # together in a square region rather than getting spread thin + # along the longer axis. + side = min(self.width(), self.height()) + usable = max(1.0, side - 2 * _MAP_PADDING_PX) + scale_x = usable / x_span if x_span > _MIN_WORLD_EXTENT * 10 else float("inf") + scale_y = usable / y_span if y_span > _MIN_WORLD_EXTENT * 10 else float("inf") + scale = min(scale_x, scale_y) + if scale == float("inf"): + scale = 1.0 + x_off = self.width() / 2 - scale * (x_min + x_max) / 2 + y_off = self.height() / 2 + scale * (y_min + y_max) / 2 # +y up + return scale, x_off, y_off + + def _to_screen(self, x: float, y: float) -> QPointF: + s, xo, yo = self._world_to_screen() + return QPointF(s * x + xo, yo - s * y) + + def paintEvent(self, _event) -> None: + painter = QPainter(self) + painter.setRenderHint(QPainter.RenderHint.Antialiasing, True) + + # Panel background -- the map paints its own rounded-rect fill (same + # translucent neutral as the stats panel) rather than sitting in a + # QFrame, so the FOV-counter text lands exactly at the panel's + # top-left corner regardless of how the layout sizes the widget. + painter.setPen(Qt.PenStyle.NoPen) + painter.setBrush(QBrush(QColor(128, 128, 128, 28))) + painter.drawRoundedRect(QRectF(self.rect()), _RADIUS_PX, _RADIUS_PX) + + # FOV counter, pinned to the panel's top-left corner. + n = len(self._positions) + if n == 0: + label = "FOV -/-" + else: + cur_txt = str(self._current + 1) if 0 <= self._current < n else "-" + label = f"FOV {cur_txt}/{n}" + text_color = self.palette().color(QPalette.ColorRole.WindowText) + painter.setPen(QPen(text_color)) + painter.drawText( + QPointF(8, 6 + painter.fontMetrics().ascent()), label + ) + + if not self._positions: + return + + # Inactive dots / path use napari's foreground text color at 50% + # alpha, so the map reads correctly on both light and dark themes. + inactive = self.palette().color(QPalette.ColorRole.WindowText) + inactive.setAlpha(128) + + pts = [self._to_screen(*p) for p in self._positions] + + if len(pts) >= 2: + pen = QPen(inactive) + pen.setWidth(_PATH_WIDTH_PX) + pen.setCapStyle(Qt.PenCapStyle.RoundCap) + pen.setJoinStyle(Qt.PenJoinStyle.RoundJoin) + painter.setPen(pen) + for a, b in zip(pts[:-1], pts[1:]): + painter.drawLine(a, b) + + painter.setPen(Qt.PenStyle.NoPen) + painter.setBrush(QBrush(inactive)) + for pt in pts: + painter.drawEllipse(pt, _DOT_RADIUS_PX, _DOT_RADIUS_PX) + + if 0 <= self._current < len(pts): + painter.setBrush(QBrush(QColor(self._active_color))) + painter.drawEllipse(pts[self._current], _DOT_RADIUS_PX, _DOT_RADIUS_PX) + + +# ───────────────────────────────────────────────────────────────────────── +# ExperimentStatusWidget +# ───────────────────────────────────────────────────────────────────────── + +class ExperimentStatusWidget(QWidget): + """Read-out + Stop button for the controller's currently-bound run.""" + + def __init__(self, controller: "Controller", parent: QWidget | None = None) -> None: + super().__init__(parent) + self._controller = controller + self._handle: RunHandle | None = None + # True while _on_stop_clicked is inside cancel()+finish_experiment(); + # _refresh keeps the state banner on "STOPPING..." for the duration. + self._finishing = False + + # Cached plan derived from handle.events at run start + self._event_types: list[str] = [] + self._event_fovs: list[int] = [] + self._scheduled: list[float] = [] + self._total_duration: float = 0.0 + + self._build_ui() + self._refresh(None) + + controller.runStarted.connect(self._on_run_started) + + # Drain psygnal's queued callbacks via a main-thread QTimer; without + # this, statusChanged emissions from the worker thread would sit in + # psygnal's _GLOBAL_QUEUE forever. Idempotent across widgets. + try: + from psygnal.qt import start_emitting_from_queue + start_emitting_from_queue() + except ImportError: + pass + + # Tick the elapsed/remaining clocks between statusChanged emissions + # so the time fields don't visibly freeze between frames. + self._tick_timer = QTimer(self) + self._tick_timer.timeout.connect(self._tick) + self._tick_timer.start(250) + + # -- UI construction ---------------------------------------------------- + + def _build_ui(self) -> None: + self.setWindowTitle("Experiment status") + + # ── State chip -- translucent neutral fill (matches the FOV map / + # stats panels), so it keeps the legend-chip shape without + # competing with the imaging/stim/ref colors. + self._state_label = QLabel("idle") + self._state_label.setAlignment(Qt.AlignmentFlag.AlignCenter) + self._state_label.setStyleSheet( + "font-weight: bold; padding: 2px 8px; " + f"border-radius: {_RADIUS_PX}px; " + f"background-color: {_PANEL_BG};" + ) + + # ── Legend chips + self._legend_chips: dict[str, QLabel] = {} + legend_row = QHBoxLayout() + legend_row.setContentsMargins(0, 0, 0, 0) + legend_row.setSpacing(6) + for label, key in [("imaging", "imaging"), ("stim", "stim"), ("ref", "ref"), ("wait", "wait")]: + chip = QLabel(label) + chip.setStyleSheet(_chip_style(EVENT_COLORS[key], active=False)) + self._legend_chips[key] = chip + legend_row.addWidget(chip) + legend_row.addStretch(1) + + # ── Strip + map + self._strip = EventStrip([]) + self._map = FovMap([]) + + # ── Stats form -- inherit napari's font/palette; only the time + # values get the platform's fixed-width font (column alignment). + mono = QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont) + self._event_value = QLabel("-/-") + self._elapsed_value = QLabel("-") + self._scheduled_value = QLabel("-") + self._lag_value = QLabel("-") + self._remaining_value = QLabel("-") + self._deferred_value = QLabel("-") + self._errors_value = QLabel("-") + right_align = ( + Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter + ) + for w in ( + self._event_value, self._elapsed_value, self._scheduled_value, + self._lag_value, self._remaining_value, self._deferred_value, + self._errors_value, + ): + w.setAlignment(right_align) + for w in (self._elapsed_value, self._scheduled_value, + self._lag_value, self._remaining_value, + self._deferred_value): + w.setFont(mono) + + # storage / pipeline depths render as a fill bar behind "N / max" + # text -- a QProgressBar whose chunk *is* the background fill. + # deferred has no bound, so it stays a plain count label. + self._storage_bar = _make_queue_bar(mono) + self._pipeline_bar = _make_queue_bar(mono) + + def _stat_form() -> QFormLayout: + f = QFormLayout() + f.setContentsMargins(6, 6, 6, 6) + f.setSpacing(2) + f.setLabelAlignment(Qt.AlignmentFlag.AlignLeft) + # Stretch the value column so right-aligned text / the queue + # bars land at the panel's right edge, not hugging the label. + f.setFieldGrowthPolicy( + QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow + ) + return f + + timing_form = _stat_form() + timing_form.addRow("event:", self._event_value) + timing_form.addRow("elapsed:", self._elapsed_value) + timing_form.addRow("scheduled:", self._scheduled_value) + timing_form.addRow("lag:", self._lag_value) + timing_form.addRow("remaining:", self._remaining_value) + + queues_form = _stat_form() + queues_form.addRow("storage:", self._storage_bar) + queues_form.addRow("pipeline:", self._pipeline_bar) + queues_form.addRow("deferred:", self._deferred_value) + + errors_form = _stat_form() + errors_form.addRow("errors:", self._errors_value) + + # ── Stats panels: three separate shaded frames (timing / queues + # / errors). Standalone panels with the layout's normal spacing + # between them -- like the FOV map above -- read as clearly + # distinct areas. (The FOV map paints its own matching background + # in paintEvent, so it isn't wrapped here.) + timing_panel = _wrap_panel(timing_form) + queues_panel = _wrap_panel(queues_form) + errors_panel = _wrap_panel(errors_form) + + # ── Pause + Stop buttons + self._pause_btn = QPushButton("Pause") + self._pause_btn.clicked.connect(self._on_pause_clicked) + self._pause_btn.setEnabled(False) + self._stop_btn = QPushButton("Stop") + self._stop_btn.clicked.connect(self._on_stop_clicked) + self._stop_btn.setEnabled(False) + button_row = QHBoxLayout() + button_row.addStretch(1) + button_row.addWidget(self._pause_btn) + button_row.addWidget(self._stop_btn) + + layout = QVBoxLayout(self) + layout.setContentsMargins(8, 8, 8, 8) + layout.setSpacing(6) + layout.addWidget(self._state_label) + layout.addLayout(legend_row) + layout.addWidget(self._strip) + # The map is the one elastic element: give it the layout stretch + # so all leftover vertical space goes to it (the map then draws + # the largest centered square that fits). No trailing addStretch + # -- that spacer used to swallow the slack and pin the map at its + # minimum height. + layout.addWidget(self._map, 1) + layout.addWidget(timing_panel) + layout.addWidget(queues_panel) + layout.addWidget(errors_panel) + layout.addLayout(button_row) + + # -- run binding -------------------------------------------------------- + + def _on_run_started(self, handle: RunHandle) -> None: + """Re-bind to a new run; rebuild the strip + map from its events.""" + if self._handle is not None: + try: + self._handle.statusChanged.disconnect(self._refresh) + except Exception: + pass + + self._handle = handle + # thread="main" routes worker-thread emits through psygnal's main- + # thread queue (drained by start_emitting_from_queue's QTimer in + # __init__). Without it the slot would run synchronously off the + # worker thread and touch QWidgets / OpenGL from the wrong thread. + handle.statusChanged.connect(self._refresh, thread="main") + + # Rebuild plan-derived widgets from the events list, if we have one + events = getattr(handle, "events", None) or [] + types, fovs, positions, scheduled = _extract_plan(events) + self._event_types = types + self._event_fovs = fovs + self._scheduled = scheduled + self._total_duration = scheduled[-1] if scheduled else 0.0 + self._strip.set_types(types) + self._map.set_positions(positions) + + self._refresh(handle.status()) + + def _on_stop_clicked(self) -> None: + """Cancel the run, then finish the experiment. + + ``cancel()`` aborts the acquisition loop; ``finish_experiment()`` + then flushes buffered frames to disk and disposes of the + Analyzer, so the next run starts clean instead of leaking the + old one. The finish drain runs with the Qt loop pumped, so + napari stays responsive; the state banner reads ``STOPPING...`` + until it returns. + """ + if self._handle is None or self._finishing: + return + self._finishing = True + # Disable both buttons up front: finish_experiment() blocks this + # slot (pumping Qt), so without this a second click would re-enter. + self._stop_btn.setEnabled(False) + self._pause_btn.setEnabled(False) + self._state_label.setText("STOPPING...") + failed = False + try: + self._handle.cancel() + self._controller.finish_experiment() + except BaseException as exc: # noqa: BLE001 - surface, don't crash the slot + import traceback + traceback.print_exc() + self._state_label.setText(f"STOP FAILED: {type(exc).__name__}") + failed = True + finally: + self._finishing = False + if failed: + # finish_experiment may leave the Analyzer alive (e.g. a drain + # timeout) -- re-enable Stop so the user can retry. + self._stop_btn.setEnabled(True) + else: + # Teardown done -- reflect the run's final state. + self._refresh(self._handle.status() if self._handle else None) + + def _on_pause_clicked(self) -> None: + """Toggle pause / resume on the bound handle.""" + if self._handle is None: + return + if self._handle.is_paused(): + self._handle.resume() + else: + self._handle.pause() + # statusChanged may not fire if state didn't transition (pause + # during "waiting" defers the state flip until the wait ends), + # so refresh the label locally to keep it in sync. + self._update_buttons(self._handle.status().state) + + # -- refresh ------------------------------------------------------------ + + def _refresh(self, status: RunStatus | None) -> None: + """Slot connected to ``handle.statusChanged``. + + Also called once with ``None`` at construction time (no handle yet). + """ + if status is None: + self._render_idle() + return + + # ── State banner -- plain bold text, no background fill (a colored + # banner clashed with the imaging/stim/ref legend colors). While + # _on_stop_clicked runs, keep it on STOPPING... -- statusChanged + # emissions from the winding-down worker would otherwise flip it + # to DONE before the finish drain completes. + if self._finishing: + self._state_label.setText("STOPPING...") + elif status.state == "waiting" and status.wait_remaining_s is not None: + self._state_label.setText(f"WAITING {format_duration(status.wait_remaining_s)}") + else: + self._state_label.setText(status.state.upper()) + + # ── Strip + map cursor + cur_idx = self._current_index(status) + n_total = status.n_events_total or len(self._event_types) + + if 0 <= cur_idx < len(self._event_types): + t = self._event_types[cur_idx] + color = EVENT_COLORS.get(t, DEFAULT_EVENT_COLOR) + self._strip.set_current(cur_idx) + if t == "wait": # no FOV + self._map.set_current(-1) + else: + fov_for_event = self._event_fovs[cur_idx] + self._map.set_current(fov_for_event, color=color) + self._update_legend(active_type=t) + else: + self._strip.set_current(-1) + self._map.set_current(-1) + self._update_legend(active_type=None) + + # ── Stats: event index + self._event_value.setText( + f"{cur_idx + 1} / {n_total}" if n_total else "-/-" + ) + + # ── Stats: elapsed, scheduled, lag, remaining + self._render_time_fields(status, cur_idx) + + # ── Errors + n_errors = len(status.background_errors) + if status.fatal_error is not None: + self._errors_value.setText( + f"{n_errors} bg + fatal: {type(status.fatal_error).__name__}" + ) + self._errors_value.setStyleSheet( + f"color: {_LAG_BAD_COLOR}; font-weight: bold;" + ) + else: + self._errors_value.setText(str(n_errors)) + self._errors_value.setStyleSheet("") + + # ── Queue depths + self._render_queue_fields() + + # ── Buttons -- left alone while finishing (deliberately disabled + # by _on_stop_clicked; a stale "running" emission must not re-enable). + if not self._finishing: + self._update_buttons(status.state) + + def _update_buttons(self, state: str) -> None: + """Enable/label Pause + Stop according to the run state.""" + live = state in ("running", "pausing", "paused", "waiting") + self._pause_btn.setEnabled(live) + # Drive the label off pause_event so a click during "waiting" + # flips to Resume immediately, even though state stays "waiting" + # until the wait completes. + paused = self._handle is not None and self._handle.is_paused() + self._pause_btn.setText("Resume" if paused else "Pause") + self._stop_btn.setEnabled(live) + + def _render_idle(self) -> None: + self._state_label.setText("idle (no run yet)") + self._strip.set_current(-1) + self._map.set_current(-1) + self._update_legend(active_type=None) + self._event_value.setText("-/-") + for w in (self._elapsed_value, self._scheduled_value, + self._lag_value, self._remaining_value): + w.setText("-") + self._lag_value.setStyleSheet("") + self._errors_value.setText("-") + self._errors_value.setStyleSheet("") + self._render_queue_fields() + self._pause_btn.setEnabled(False) + self._pause_btn.setText("Pause") + self._stop_btn.setEnabled(False) + + @staticmethod + def _current_index(status: RunStatus) -> int: + """Index of the RTMEvent currently being acquired (-1 if none yet). + + Uses ``n_events_acquired`` -- RTMEvents whose first frame has + arrived -- which is the *same unit* as ``n_events_total`` and as + the event strip / FOV map, so progress can never exceed the + total. Deliberately NOT ``n_frames_received`` (that counts + per-channel MDAEvents, ~2-3 per RTMEvent, so it overshoots the + total) and NOT ``n_events_consumed`` (the feed loop runs several + events ahead of the engine because of the backpressure window, + which would make the strip jump). Both ``_refresh`` and the + ``_tick`` QTimer call this so they always agree on "current". + While ``waiting``, ``n_events_acquired`` doesn't bump (no frame + arrives for a WaitEvent), so use ``n_events_consumed`` to keep + the cursor on the wait cell during the countdown. + """ + if status.state == "waiting" and status.n_events_consumed > 0: + return status.n_events_consumed - 1 + return status.n_events_acquired - 1 if status.n_events_acquired > 0 else -1 + + def _render_time_fields(self, status: RunStatus, cur_idx: int) -> None: + # Elapsed: prefer (now - started_at); fall back to last_frame_wallclock. + if status.started_at is not None: + if status.finished_at is not None: + elapsed = status.finished_at - status.started_at + else: + elapsed = time.monotonic() - status.started_at + else: + elapsed = None + + scheduled = ( + self._scheduled[cur_idx] + if 0 <= cur_idx < len(self._scheduled) + else None + ) + + # lag: prefer the controller's per-frame measurement; fall back to + # elapsed-vs-scheduled if the per-frame value isn't populated yet. + lag_s: float | None = None + if status.lag_ms is not None: + lag_s = status.lag_ms / 1000.0 + elif elapsed is not None and scheduled is not None: + lag_s = elapsed - scheduled + + remaining: float | None = None + if elapsed is not None and self._total_duration: + remaining = max(0.0, self._total_duration - elapsed) + + self._elapsed_value.setText( + format_duration(elapsed) if elapsed is not None else "-" + ) + self._scheduled_value.setText( + format_duration(scheduled) if scheduled is not None else "-" + ) + if lag_s is None: + self._lag_value.setText("-") + self._lag_value.setStyleSheet("") + else: + sign = "+" if lag_s >= 0 else "" + self._lag_value.setText(f"{sign}{format_duration(lag_s, show_ms=True)}") + if lag_s > _LAG_WARN_S: + self._lag_value.setStyleSheet( + f"color: {_LAG_BAD_COLOR}; font-weight: bold;" + ) + else: + self._lag_value.setStyleSheet("") + self._remaining_value.setText( + format_duration(remaining) if remaining is not None else "-" + ) + + def _render_queue_fields(self) -> None: + """Refresh the storage / pipeline / deferred read-outs. + + Polled from the QTimer so the depths track live between frames -- + in particular the storage bar is seen draining to 0 while + finish_experiment() runs. Shows empty "-" bars when no experiment + is active. + """ + stats = self._controller.queue_stats() + if stats is None: + self._set_queue_bar(self._storage_bar, 0, 0) + self._set_queue_bar(self._pipeline_bar, 0, 0) + self._deferred_value.setText("-") + return + self._set_queue_bar( + self._storage_bar, stats.storage_depth, stats.storage_max + ) + self._set_queue_bar( + self._pipeline_bar, stats.pipeline_inflight, stats.pipeline_max + ) + self._deferred_value.setText(str(stats.deferred_depth)) + + @staticmethod + def _set_queue_bar(bar: QProgressBar, depth: int, maximum: int) -> None: + """Drive one queue bar: fill fraction, 'N / max' text, warn color. + + Fill + text turn red once depth reaches _QUEUE_WARN_FRAC of max -- + a near-full storage queue means disk writes can't keep pace and + the camera buffer is at risk. ``maximum <= 0`` renders an empty + "-" bar (no active experiment). + """ + if maximum <= 0: + bar.setRange(0, 1) + bar.setValue(0) + bar.setFormat("-") + warn = False + else: + bar.setRange(0, maximum) + bar.setValue(min(depth, maximum)) + bar.setFormat(f"{depth} / {maximum}") + warn = depth >= _QUEUE_WARN_FRAC * maximum + # Re-style only on a warn-state change -- setStyleSheet every tick + # would force a needless restyle/repaint. + if warn != bar._warn: + bar._warn = warn + bar.setStyleSheet(_bar_style(warn)) + + def _update_legend(self, active_type: str | None) -> None: + for key, chip in self._legend_chips.items(): + chip.setStyleSheet( + _chip_style(EVENT_COLORS[key], active=(key == active_type)) + ) + + def _tick(self) -> None: + """QTimer slot: poll the handle and refresh the whole widget. + + ``statusChanged`` is the push path, but its cross-thread queued + delivery (psygnal worker thread -> Qt main thread) proved + unreliable in some embeddings -- notably Jupyter notebooks -- + leaving the strip / FOV cursor / counters frozen even though + ``handle.status()`` is current. Polling the latest snapshot here + every tick guarantees the whole widget stays live regardless of + signal delivery; the push connection remains as an optimisation. + ``_refresh``'s repaints are change-guarded, so a full refresh at + this cadence is cheap. + """ + if self._handle is None: + return + self._refresh(self._handle.status()) diff --git a/pyproject.toml b/pyproject.toml index 56dcf12..ac562b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,13 @@ dependencies = [ test = [ "pytest", "pytest-xdist", + # The suite exercises both tracking backends; motile is the non-default + # one (trackpy is a core dep). + "faro[motile]", +] + +motile = [ + "motile", ] stardist = [ diff --git a/tests/hardware/conftest.py b/tests/hardware/conftest.py deleted file mode 100644 index 9b4e3fd..0000000 --- a/tests/hardware/conftest.py +++ /dev/null @@ -1,303 +0,0 @@ -"""Fixtures for the hardware-in-the-loop test suite. - -Each fixture is session-scoped so the microscope is initialized only -once per pytest run, regardless of how many hardware tests fire. The -``--scope`` CLI option (defined in ``tests/conftest.py``) selects which -Pertzlab microscope class to instantiate. - -Safety: -- ``safe_positions`` reads the stage XY at session start and returns - positions as RELATIVE offsets so we never move into uncalibrated - territory or hit stage limits. -- The Z stage is read for record-keeping only — never written. -- The stage is restored to its original XY at session end. -""" - -from __future__ import annotations - -import os -from pathlib import Path - -import numpy as np -import pytest -import zarr - -from tests.conftest import resolve_scope - - -# --------------------------------------------------------------------------- -# Per-scope channel mapping -# --------------------------------------------------------------------------- -# Channel groups and channel names per scope are inferred from each -# microscope's Micro-Manager cfg in ``pertzlab_mic_configs/``. Update -# these tables when adding a new scope or when a cfg's groups change. -# -# Each scope provides: -# channel_group — Micro-Manager ConfigGroup that hosts the channels -# imaging_channel — primary imaging channel (passed to segmentation) -# optocheck_channel — second channel acquired on the last frame as a ref -# stim_channel — stimulation channel (driven by the DMD path) -# Exposures are intentionally short so the smoke test stays under a minute. -SCOPE_CHANNELS = { - "moench": { - "channel_group": "TTL_ERK", - "imaging_channel": "mScarlet3", - "imaging_exposure": 100.0, - "optocheck_channel": "mCitrine", - "optocheck_exposure": 100.0, - "stim_channel": "CyanStim", - "stim_exposure": 100.0, - "stim_power": 5, - }, - "niesen": { - "channel_group": "WF_DMD", - "imaging_channel": "Red", - "imaging_exposure": 100.0, - "optocheck_channel": "Green", - "optocheck_exposure": 100.0, - "stim_channel": "CyanStim", - "stim_exposure": 100.0, - "stim_power": 5, - }, - "jungfrau": { - "channel_group": "TTL_ERK", - "imaging_channel": "mScarlet3", - "imaging_exposure": 100.0, - "optocheck_channel": "mCitrine", - "optocheck_exposure": 100.0, - "stim_channel": "CyanStim", - "stim_exposure": 100.0, - "stim_power": 5, - }, -} - - -# Per-scope DMD calibration profile used to instantiate ``DMD`` where -# the microscope class doesn't already do so in its constructor (only -# Jungfrau today — its DMD isn't yet wired into the cfg, so this will -# raise loudly when the SLM device is missing, surfacing the gap). -SCOPE_DMD_PROFILES: dict[str, dict] = { - "jungfrau": { - "channel_group": "TTL_ERK", - "channel_config": "CyanStim", - "device_name": "LED", - "property_name": "Cyan_Level", - "power": 5, - }, -} - - -# --------------------------------------------------------------------------- -# Scope selection -# --------------------------------------------------------------------------- - - -@pytest.fixture(scope="session") -def scope_name(request: pytest.FixtureRequest) -> str: - """Return the active scope name, skipping if none is selected.""" - name = resolve_scope(request.config) - if name is None: - pytest.skip("hardware test — pass --scope or set FARO_SCOPE") - return name - - -@pytest.fixture(scope="session") -def scope_config(scope_name: str) -> dict: - """Return the per-scope channel mapping.""" - return SCOPE_CHANNELS[scope_name] - - -# --------------------------------------------------------------------------- -# Synthetic DMD affine -# --------------------------------------------------------------------------- - - -@pytest.fixture(scope="session") -def synthetic_affine() -> np.ndarray: - """Identity 3x3 affine in skimage convention. - - Hardware tests don't validate optical alignment — they only need - the DMD code path to run end-to-end without raising. The identity - matrix lets ``skimage.transform.warp`` resample the camera image - into DMD space by direct coordinate copy (with cropping/padding - when DMD and camera differ in size). No interactive calibration - or precomputed ``.npy`` is needed on disk. - """ - return np.eye(3) - - -# --------------------------------------------------------------------------- -# Microscope factory -# --------------------------------------------------------------------------- - - -@pytest.fixture(scope="session") -def microscope(scope_name: str, synthetic_affine: np.ndarray): - """Instantiate the selected Pertzlab microscope once per session. - - Loads the Micro-Manager cfg, applies the per-scope ROI when the - class requests it, and injects a synthetic DMD affine matrix so - stim code paths run without an interactive calibration step. - - For Moench and Niesen the constructor accepts an - ``affine_calibration_matrix`` and creates the DMD inside - ``init_scope()``. Jungfrau today has no DMD setup in its - constructor — we instantiate one manually after init. If the - Jungfrau cfg lacks an SLM device this will raise with a clear - error pointing at the gap, which is the desired signal. - """ - if scope_name == "moench": - from faro.microscope.pertzlab.moench import Moench - - mic = Moench(affine_calibration_matrix=synthetic_affine) - elif scope_name == "niesen": - from faro.microscope.pertzlab.niesen import Niesen - - mic = Niesen( - affine_calibration_matrix=synthetic_affine, fast_init=True - ) - elif scope_name == "jungfrau": - from faro.core.dmd import DMD - from faro.microscope.pertzlab.jungfrau import Jungfrau - - mic = Jungfrau() - mic.dmd = DMD( - mic.mmc, - SCOPE_DMD_PROFILES["jungfrau"], - affine_matrix=synthetic_affine, - ) - mic.dmd_needs_to_be_waken = False - else: - raise ValueError(f"unknown scope: {scope_name!r}") - - # Force a known camera binning BEFORE applying the ROI — most MM - # configs reset the ROI on a binning change, so the order matters. - # 2x2 keeps the test frame small and fast. - try: - mic.mmc.setConfig("Binning", "2x2") - except Exception as e: - print(f"[hardware fixture] could not set Binning=2x2 on {scope_name}: {e}") - - # Apply per-scope ROI when production code does so. - if getattr(mic, "SET_ROI_REQUIRED", False) and hasattr(mic, "set_roi"): - mic.set_roi() - - yield mic - - # Release all hardware handles so the Python process can exit. - # Cleanup lives on the microscope class itself, not in the fixture, - # so notebooks / scripts get the same behavior. - try: - mic.shutdown() - except Exception: - pass - - -# --------------------------------------------------------------------------- -# Safe (relative) stage positions -# --------------------------------------------------------------------------- - - -def _parse_offset_env(raw: str) -> list[tuple[float, float]]: - """Parse ``"dx0,dy0;dx1,dy1;..."`` into a list of (dx, dy) tuples.""" - offsets: list[tuple[float, float]] = [] - for pair in raw.split(";"): - pair = pair.strip() - if not pair: - continue - dx_str, dy_str = pair.split(",") - offsets.append((float(dx_str), float(dy_str))) - return offsets - - -@pytest.fixture(scope="session") -def safe_positions(microscope) -> list[dict]: - """Generate FOV positions as RELATIVE offsets from the stage's - current XY so the test never moves into uncalibrated territory or - crashes the objective. - - Workflow: - 1. The user manually parks the stage on a sample area before - starting the test run. - 2. This fixture snapshots ``(start_x, start_y)`` from the - current XY stage position and ``start_z`` from the focus - drive (read-only — Z is never moved). - 3. Three nearby FOVs are returned as ``(start + offset)`` - tuples. Default offsets are ``(0,0)``, ``(40,0)``, ``(0,40)`` - microns — well inside a single 40x camera FOV (~130 µm) - so cells overlap between FOVs but no large stage motion - ever happens. - 4. At session end the stage is restored to ``(start_x, start_y)`` - so an interrupted manual session can resume seamlessly. - - Override the offsets via ``FARO_HW_TEST_OFFSETS_UM`` formatted as - ``"dx0,dy0;dx1,dy1;..."`` (in microns). Set to a single ``"0,0"`` - pair to restrict the test to a single position. - """ - mmc = microscope.mmc - start_x, start_y = mmc.getXYPosition() - try: - start_z = mmc.getPosition() - except Exception: - start_z = 0.0 - - raw_offsets = os.environ.get("FARO_HW_TEST_OFFSETS_UM") - if raw_offsets: - offsets = _parse_offset_env(raw_offsets) - else: - offsets = [(0.0, 0.0), (40.0, 0.0), (0.0, 40.0)] - - positions = [ - { - "x": start_x + dx, - "y": start_y + dy, - "z": start_z, - "name": f"fov_{i}", - } - for i, (dx, dy) in enumerate(offsets) - ] - - yield positions - - # Best-effort: return the stage to where the user left it. Swallow - # exceptions so a teardown failure can't mask a test failure above. - try: - mmc.setXYPosition(start_x, start_y) - except Exception: - pass - - -# --------------------------------------------------------------------------- -# Shared post-run assertions -# --------------------------------------------------------------------------- - - -def assert_clean_run(controller, tmp_path: Path, *, expect_tracks: bool) -> None: - """Post-run smoke checks shared by every hardware test. - - Fails loudly on any background-thread error (experiments log-and- - continue, but a hardware test is meaningless if it swallows them) - and confirms the run produced a napari-loadable OME-Zarr store. - """ - assert not controller.background_errors, ( - "Background errors during acquisition:\n" - + "\n".join( - f" [{e.source}] {e.exc_type}: {e.message}" - for e in controller.background_errors - ) - ) - - zarr_path = tmp_path / "acquisition.ome.zarr" - assert zarr_path.is_dir(), f"OME-Zarr store not created at {zarr_path}" - - grp = zarr.open_group(str(zarr_path), mode="r") - assert "ome" in grp.attrs, ( - "OME metadata missing on root group — store will not load in napari" - ) - - assert (tmp_path / "events.json").is_file(), "events.json not written" - - if expect_tracks: - tracks_dir = tmp_path / "tracks" - assert tracks_dir.is_dir(), "tracks/ folder not created" - assert list(tracks_dir.glob("*.parquet")), "no track parquet files written" diff --git a/tests/hardware/pertzlab/test_cell_migration.py b/tests/hardware/pertzlab/test_cell_migration.py index 0ea6328..af75c40 100644 --- a/tests/hardware/pertzlab/test_cell_migration.py +++ b/tests/hardware/pertzlab/test_cell_migration.py @@ -24,8 +24,8 @@ server being reachable. * The DMD affine matrix is the synthetic identity from ``synthetic_affine`` — no interactive calibration step. - * Frame count and interval are scaled down (4 frames × 5 s) so - the whole test takes about a minute. + * Frame count and interval are scaled down (4 frames × 2 s) so + the whole test stays short. The test is gated by ``--scope`` / ``FARO_SCOPE`` and skipped by default. See ``tests/conftest.py`` for the gating logic. @@ -56,7 +56,7 @@ N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 +TIME_BETWEEN_TIMESTEPS_S = 2.0 STIM_CELL_PERCENTAGE = 0.3 diff --git a/tests/hardware/pertzlab/test_empty_fov_no_crash.py b/tests/hardware/pertzlab/test_empty_fov_no_crash.py index 5240fcc..be82452 100644 --- a/tests/hardware/pertzlab/test_empty_fov_no_crash.py +++ b/tests/hardware/pertzlab/test_empty_fov_no_crash.py @@ -37,7 +37,7 @@ N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 +TIME_BETWEEN_TIMESTEPS_S = 2.0 STIM_FRACTION = 0.3 diff --git a/tests/hardware/pertzlab/test_line_stimulation.py b/tests/hardware/pertzlab/test_line_stimulation.py index 0b3db5d..62bcbdf 100644 --- a/tests/hardware/pertzlab/test_line_stimulation.py +++ b/tests/hardware/pertzlab/test_line_stimulation.py @@ -23,8 +23,8 @@ a hardcoded drive letter. * The DMD affine matrix is the synthetic identity from ``synthetic_affine`` — no interactive calibration step. - * Frame count and interval are scaled down (4 frames × 5 s) so - the whole test takes about half a minute. + * Frame count and interval are scaled down (4 frames × 2 s) so + the whole test stays short. The test is gated by ``--scope`` / ``FARO_SCOPE`` and skipped by default. See ``tests/conftest.py`` for the gating logic. @@ -48,7 +48,7 @@ N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 +TIME_BETWEEN_TIMESTEPS_S = 2.0 @pytest.mark.hardware diff --git a/tests/hardware/pertzlab/test_pipeline_lag.py b/tests/hardware/pertzlab/test_pipeline_lag.py index 1a46bfc..7cd4541 100644 --- a/tests/hardware/pertzlab/test_pipeline_lag.py +++ b/tests/hardware/pertzlab/test_pipeline_lag.py @@ -34,12 +34,16 @@ ) -# Long enough to cover lag recovery; short enough to stay under ~2 min. -N_FRAMES = 12 -TIME_BETWEEN_TIMESTEPS_S = 5.0 -# Pipeline artificial latency — picked to sit between one and two frame -# intervals so the pipeline consistently lags acquisition by ~2 frames. -SLOW_PIPELINE_DELAY_S = 7.0 +# Enough frames to build up *and* drain sustained lag, but scaled to +# finish in well under a minute on the rig (was 12 @ 5 s + 7 s delay). +N_FRAMES = 6 +TIME_BETWEEN_TIMESTEPS_S = 2.0 +# Pipeline artificial latency — kept between one and two frame intervals +# (interval < delay < 2*interval) so the pipeline still consistently lags +# acquisition by ~1.5 frames, exercising backpressure and the dispenser's +# walk-past-skipped path. The ratio, not the absolute value, is what makes +# this a lag test, so shrinking both keeps the coverage identical. +SLOW_PIPELINE_DELAY_S = 3.0 @pytest.mark.hardware diff --git a/tests/hardware/pertzlab/test_ref_channel_no_duplicate_pipeline_runs.py b/tests/hardware/pertzlab/test_ref_channel_no_duplicate_pipeline_runs.py index a9aecc8..581e544 100644 --- a/tests/hardware/pertzlab/test_ref_channel_no_duplicate_pipeline_runs.py +++ b/tests/hardware/pertzlab/test_ref_channel_no_duplicate_pipeline_runs.py @@ -36,7 +36,7 @@ N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 +TIME_BETWEEN_TIMESTEPS_S = 2.0 @pytest.mark.hardware diff --git a/tests/hardware/pertzlab/test_stim_mask_timeout.py b/tests/hardware/pertzlab/test_stim_mask_timeout.py index 9d966ae..7dd4631 100644 --- a/tests/hardware/pertzlab/test_stim_mask_timeout.py +++ b/tests/hardware/pertzlab/test_stim_mask_timeout.py @@ -35,12 +35,12 @@ N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 +TIME_BETWEEN_TIMESTEPS_S = 2.0 # Pipeline sleeps much longer than the analyzer's timeout so the # controller is guaranteed to time out waiting for the mask. A # queue-based stimulator (StimWithImage / StimWithPipeline) is # required — base Stim is called synchronously and has no timeout. -SLOW_PIPELINE_DELAY_S = 10.0 +SLOW_PIPELINE_DELAY_S = 3.0 SHORT_TIMEOUT_S = 1.0 diff --git a/tests/hardware/pertzlab/test_stim_timing.py b/tests/hardware/pertzlab/test_stim_timing.py index ab15386..32887c8 100644 --- a/tests/hardware/pertzlab/test_stim_timing.py +++ b/tests/hardware/pertzlab/test_stim_timing.py @@ -44,7 +44,7 @@ N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 +TIME_BETWEEN_TIMESTEPS_S = 2.0 class _WholeFovStim(Stim): diff --git a/tests/hardware/pertzlab/test_stim_with_cellpose.py b/tests/hardware/pertzlab/test_stim_with_cellpose.py index 09fbad3..61c3f88 100644 --- a/tests/hardware/pertzlab/test_stim_with_cellpose.py +++ b/tests/hardware/pertzlab/test_stim_with_cellpose.py @@ -34,7 +34,7 @@ N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 +TIME_BETWEEN_TIMESTEPS_S = 2.0 STIM_FRACTION = 0.3 diff --git a/tests/hardware/test_cell_migration.py b/tests/hardware/test_cell_migration.py deleted file mode 100644 index f859562..0000000 --- a/tests/hardware/test_cell_migration.py +++ /dev/null @@ -1,134 +0,0 @@ -"""Hardware smoke test: end-to-end cell migration acquisition. - -Converted from ``experiments/21_cell_migration/cell_migration.ipynb``. -Runs a short multi-FOV / multi-timestep acquisition with cellpose -segmentation, trackpy tracking, ``StimPercentageOfCell`` DMD -stimulation, and an optocheck reference channel on the last frame -(exercises the ref-channel write path). - -Why this test exists: - The notebook is the canonical end-to-end demo for the segmentation - + tracking + per-cell stimulation pipeline. Converting it to a - pytest target lets us validate the whole stack against real - hardware in CI-style runs without needing napari or interactive - FOV selection. - -Differences from the notebook (intentional, for test ergonomics): - * No napari / napari-micromanager. FOV positions come from the - ``safe_positions`` fixture as relative offsets from the stage's - current XY (max 40 µm), so the stage never makes a large move. - * Output goes to pytest's ``tmp_path`` (auto-cleaned) instead of - a hardcoded drive letter. - * Segmentation is local (cellpose) instead of remote - (imaging-server-kit) so the test doesn't depend on a separate - server being reachable. - * The DMD affine matrix is the synthetic identity from - ``synthetic_affine`` — no interactive calibration step. - * Frame count and interval are scaled down (4 frames × 5 s) so - the whole test takes about a minute. - -The test is gated by ``--scope`` / ``FARO_SCOPE`` and skipped by -default. See ``tests/conftest.py`` for the gating logic. -""" - -from __future__ import annotations - -import pytest -from useq import Position, TIntervalLoops - -from faro.core.controller import Controller -from faro.core.data_structures import ( - Channel as RTMChannel, - PowerChannel, - RTMSequence, - SegmentationMethod, -) -from faro.core.pipeline import ImageProcessingPipeline -from faro.core.writers import OmeZarrWriter -from faro.feature_extraction.optocheck import OptoCheckFE -from faro.feature_extraction.simple import SimpleFE -from faro.stimulation.percentage_of_cell import StimPercentageOfCell -from faro.tracking.trackpy import TrackerTrackpy -from tests.hardware.conftest import assert_clean_run - - -N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 -STIM_CELL_PERCENTAGE = 0.3 - - -@pytest.mark.hardware -def test_cell_migration_smoke( - microscope, scope_config, safe_positions, tmp_path -) -> None: - """End-to-end smoke test: segmentation + tracking + stim + ref.""" - - cfg = scope_config - - imaging = RTMChannel( - config=cfg["imaging_channel"], - exposure=cfg["imaging_exposure"], - group=cfg["channel_group"], - ) - optocheck = RTMChannel( - config=cfg["optocheck_channel"], - exposure=cfg["optocheck_exposure"], - group=cfg["channel_group"], - ) - stim = PowerChannel( - config=cfg["stim_channel"], - exposure=cfg["stim_exposure"], - group=cfg["channel_group"], - power=cfg["stim_power"], - ) - - sequence = RTMSequence( - stage_positions=[ - Position(x=p["x"], y=p["y"], z=p["z"], name=p["name"]) - for p in safe_positions - ], - time_plan=TIntervalLoops( - interval=TIME_BETWEEN_TIMESTEPS_S, - loops=N_FRAMES, - ), - channels=[imaging], - stim_channels=(stim,), - # Stim every frame except the first (no prior segmentation yet). - stim_frames=frozenset(range(1, N_FRAMES)), - ref_channels=(optocheck,), - # ``-1`` resolves to the last timepoint via _resolve_frame_set. - ref_frames=frozenset({-1}), - # StimPercentageOfCell reads this from per-event metadata. - rtm_metadata={"stim_cell_percentage": STIM_CELL_PERCENTAGE}, - ) - - from faro.segmentation.cellpose_v4 import CellposeV4 - - pipeline = ImageProcessingPipeline( - storage_path=str(tmp_path), - segmentators=[ - SegmentationMethod( - name="labels", - segmentation_class=CellposeV4(min_size=50, gpu=True), - use_channel=0, - save_tracked=True, - ), - ], - feature_extractor=SimpleFE("labels"), - feature_extractor_ref=OptoCheckFE(used_mask="labels"), - stimulator=StimPercentageOfCell(), - tracker=TrackerTrackpy(), - ) - - writer = OmeZarrWriter( - storage_path=str(tmp_path), - store_stim_images=True, - ) - - controller = Controller(microscope, pipeline, writer=writer) - try: - controller.run_experiment(list(sequence), stim_mode="current") - finally: - controller.finish_experiment() - - assert_clean_run(controller, tmp_path, expect_tracks=True) diff --git a/tests/hardware/test_line_stimulation.py b/tests/hardware/test_line_stimulation.py deleted file mode 100644 index 876fabf..0000000 --- a/tests/hardware/test_line_stimulation.py +++ /dev/null @@ -1,123 +0,0 @@ -"""Hardware smoke test: end-to-end line-stimulation acquisition. - -Converted from ``experiments/22_line_stimulation/line_stimulation.ipynb``. -Runs a short multi-FOV / multi-timestep acquisition with a moving-line -DMD pattern. No segmentation, tracking, or feature extraction — this -exercises the geometric ``StimLine`` path on its own. The optocheck -reference channel is acquired on the last frame to validate ref-channel -handling without segmentation. - -Why this test exists: - The notebook is the canonical demo for the "stim independent of - cell labels" pipeline shape. It's the simplest hardware path — - image, stim with a precomputed mask, image, repeat — and a useful - early signal that the camera + DMD + filter wheel + LED + writer - chain is wired correctly. - -Differences from the notebook (intentional, for test ergonomics): - * No napari / napari-micromanager. FOV positions come from the - ``safe_positions`` fixture as relative offsets from the stage's - current XY (max 40 µm), so the stage never makes a large move. - * No ``fovs.json`` file dependency. - * Output goes to pytest's ``tmp_path`` (auto-cleaned) instead of - a hardcoded drive letter. - * The DMD affine matrix is the synthetic identity from - ``synthetic_affine`` — no interactive calibration step. - * Frame count and interval are scaled down (4 frames × 5 s) so - the whole test takes about half a minute. - -The test is gated by ``--scope`` / ``FARO_SCOPE`` and skipped by -default. See ``tests/conftest.py`` for the gating logic. -""" - -from __future__ import annotations - -import pytest -from useq import Position, TIntervalLoops - -from faro.core.controller import Controller -from faro.core.data_structures import ( - Channel as RTMChannel, - PowerChannel, - RTMSequence, -) -from faro.core.pipeline import ImageProcessingPipeline -from faro.core.writers import OmeZarrWriter -from faro.stimulation.moving_line_20x import StimLine -from tests.hardware.conftest import assert_clean_run - - -N_FRAMES = 4 -TIME_BETWEEN_TIMESTEPS_S = 5.0 - - -@pytest.mark.hardware -def test_line_stimulation_smoke( - microscope, scope_config, safe_positions, tmp_path -) -> None: - """End-to-end smoke test: geometric line stim, no segmentation.""" - - cfg = scope_config - - imaging = RTMChannel( - config=cfg["imaging_channel"], - exposure=cfg["imaging_exposure"], - group=cfg["channel_group"], - ) - optocheck = RTMChannel( - config=cfg["optocheck_channel"], - exposure=cfg["optocheck_exposure"], - group=cfg["channel_group"], - ) - stim = PowerChannel( - config=cfg["stim_channel"], - exposure=cfg["stim_exposure"], - group=cfg["channel_group"], - power=cfg["stim_power"], - ) - - image_height = microscope.mmc.getImageHeight() - image_width = microscope.mmc.getImageWidth() - - sequence = RTMSequence( - stage_positions=[ - Position(x=p["x"], y=p["y"], z=p["z"], name=p["name"]) - for p in safe_positions - ], - time_plan=TIntervalLoops( - interval=TIME_BETWEEN_TIMESTEPS_S, - loops=N_FRAMES, - ), - channels=[imaging], - stim_channels=(stim,), - stim_frames=frozenset(range(1, N_FRAMES)), - ref_channels=(optocheck,), - ref_frames=frozenset({-1}), - ) - - pipeline = ImageProcessingPipeline( - storage_path=str(tmp_path), - # No segmentator/tracker/FE — pure geometric stim from a - # closed-form mask, dispatched by Analyzer's metadata-only path. - stimulator=StimLine( - first_stim_frame=1, - frames_for_1_loop=N_FRAMES, - stripe_width=image_width // 4, - n_frames_total=N_FRAMES, - mask_height=image_height, - mask_width=image_width, - ), - ) - - writer = OmeZarrWriter( - storage_path=str(tmp_path), - store_stim_images=True, - ) - - controller = Controller(microscope, pipeline, writer=writer) - try: - controller.run_experiment(list(sequence), stim_mode="current") - finally: - controller.finish_experiment() - - assert_clean_run(controller, tmp_path, expect_tracks=False) diff --git a/tests/test_events_to_dataframe.py b/tests/test_events_to_dataframe.py index e7e31cf..234e3e8 100644 --- a/tests/test_events_to_dataframe.py +++ b/tests/test_events_to_dataframe.py @@ -4,7 +4,7 @@ from useq import MDASequence -from faro.core.data_structures import Channel, ImgType, RTMSequence, combine +from faro.core.data_structures import Channel, ImgType, RTMSequence, combine, wait from faro.core.utils import events_to_dataframe @@ -51,6 +51,29 @@ def test_events_to_dataframe_works_for_both(self): assert (df_rtm["timestep"] == df_mda["timestep"]).all() +class TestWaitEventInDataframe: + """WaitEvents are timed gaps, not acquired frames — they must not + appear as rows in events_to_dataframe.""" + + def test_wait_event_dropped(self): + phase1 = RTMSequence( + time_plan={"interval": 1.0, "loops": 3}, + stage_positions=[(0.0, 0.0, 0.0)], + channels=[{"config": "phase-contrast", "exposure": 50}], + ) + phase2 = RTMSequence( + time_plan={"interval": 1.0, "loops": 2}, + stage_positions=[(0.0, 0.0, 0.0)], + channels=[{"config": "phase-contrast", "exposure": 50}], + ) + events = combine(phase1, wait(10.0), phase2, axis="t") + df = events_to_dataframe(events) + + # 3 + 2 frames; the wait contributes no row. + assert len(df) == 5 + assert sorted(df["timestep"].tolist()) == [0, 1, 2, 3, 4] + + class TestRefPhaseInDataframe: """Ref as a separate phase shows up correctly in events_to_dataframe.""" diff --git a/tests/test_pause_and_wait.py b/tests/test_pause_and_wait.py new file mode 100644 index 0000000..21f6a4b --- /dev/null +++ b/tests/test_pause_and_wait.py @@ -0,0 +1,229 @@ +"""Tests for interactive pause (queue-drain) and fixed-duration WaitEvents. + +Two features pinned here: + +* **Interactive pause** drains the engine's backpressure window into a + held buffer and refills on resume. The invariant: pausing/resuming a + run changes *when* frames are acquired, never *what* — same frame + count, same indices, byte-identical OME-Zarr output. + +* **WaitEvents** insert a timed gap between phases. They claim no t/p + index (so downstream indices are unchanged vs. no wait), emit no + MDAEvents (so they add no frames), and shift subsequent events' + ``min_start_time`` later by at least their duration. + +Pause is driven from the main thread by polling ``handle.status()`` so +the tests are deterministic; events are spaced via ``min_start_time`` so +the real MDA engine is slow enough to observe the paused state. +""" + +from __future__ import annotations + +import os +import time + +import numpy as np +import pytest +import zarr + +from faro.core.controller import Controller +from faro.core.data_structures import RTMEvent, WaitEvent, combine, wait +from faro.core.writers import OmeZarrWriter +from faro.tracking.trackpy import TrackerTrackpy + +from tests.fake_microscope import FakeMicroscope +from tests.fixtures import CircleScene, make_events, make_pipeline + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _spaced(events: list[RTMEvent], dt: float) -> list[RTMEvent]: + """Stamp ``min_start_time = i*dt`` so the MDA engine paces itself.""" + return [ + e.model_copy(update={"min_start_time": i * dt}) + for i, e in enumerate(events) + ] + + +def _wait_until(predicate, *, timeout: float = 5.0, poll: float = 0.005) -> bool: + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + if predicate(): + return True + time.sleep(poll) + return False + + +def _trackpy(): + return TrackerTrackpy(search_range=50, memory=3) + + +def _raw_tiff_names(path: str) -> list[str]: + raw_dir = os.path.join(path, "raw") + if not os.path.isdir(raw_dir): + return [] + return sorted(f for f in os.listdir(raw_dir) if f.endswith(".tiff")) + + +def _run_capture_zarr(path: str, events, *, pause: bool) -> np.ndarray: + """Run ``events`` into an OME-Zarr store, optionally pausing once + mid-run, then return the raw array (t, c, y, x).""" + os.makedirs(path, exist_ok=True) + writer = OmeZarrWriter(path, store_stim_images=False) + pipeline = make_pipeline(path, tracker=_trackpy(), with_stim=False) + ctrl = Controller(FakeMicroscope(CircleScene()), pipeline, writer=writer) + + handle = ctrl.run_experiment(events, validate=False) + if pause: + assert _wait_until(lambda: handle.status().n_events_consumed >= 2), ( + "run finished before it could be paused — widen spacing" + ) + handle.pause() + assert _wait_until(lambda: handle.status().state == "paused"), ( + "feed loop never reported the paused state" + ) + handle.resume() + handle.wait() + ctrl._analyzer.wait_idle() + ctrl._analyzer.shutdown(wait=True) # closes the writer + + root = zarr.open_group(os.path.join(path, "acquisition.ome.zarr"), mode="r") + return np.asarray(root["0"]) + + +# --------------------------------------------------------------------------- +# WaitEvent semantics (combine-level, no acquisition) +# --------------------------------------------------------------------------- + + +class TestWaitEventSemantics: + def test_wait_constructs_waitevent(self): + w = wait(5.0) + assert isinstance(w, WaitEvent) + assert w.duration_s == 5.0 + + def test_wait_emits_no_mda_events(self): + assert wait(5.0).plan_events() == [] + + def test_wait_claims_no_index_and_drops_no_frames(self): + """combine with/without a wait yields identical frame indices — + the wait must not consume a t-slot.""" + a, b = make_events(3), make_events(3) + no_wait = combine(a, b, axis="t") + with_wait = combine(make_events(3), wait(10.0), make_events(3), axis="t") + + frames_no = [e.index for e in no_wait if not isinstance(e, WaitEvent)] + frames_with = [e.index for e in with_wait if not isinstance(e, WaitEvent)] + assert frames_no == frames_with + assert sum(isinstance(e, WaitEvent) for e in with_wait) == 1 + + def test_wait_shifts_subsequent_min_start_time(self): + duration = 10.0 + no_wait = combine(make_events(3), make_events(3), axis="t") + with_wait = combine( + make_events(3), wait(duration), make_events(3), axis="t" + ) + + # The second phase begins at the first event with t == 3. + def first_second_phase_time(events): + return next( + e.min_start_time + for e in events + if not isinstance(e, WaitEvent) and e.index.get("t") == 3 + ) + + shift = first_second_phase_time(with_wait) - first_second_phase_time(no_wait) + assert shift >= duration + + +# --------------------------------------------------------------------------- +# WaitEvent in a real run — adds time, not frames +# --------------------------------------------------------------------------- + + +class TestWaitEventRun: + def test_wait_adds_no_frames(self, tmp_dir): + """A wait between two 2-frame phases yields exactly 4 raw frames.""" + events = combine( + make_events(2), wait(0.05), make_events(2), axis="t" + ) + pipeline = make_pipeline(tmp_dir, tracker=_trackpy(), with_stim=False) + ctrl = Controller(FakeMicroscope(CircleScene()), pipeline) + handle = ctrl.run_experiment(events, validate=False) + handle.wait() + ctrl._analyzer.wait_idle() + ctrl._analyzer.shutdown(wait=True) + assert len(_raw_tiff_names(tmp_dir)) == 4 + + def test_wait_passes_through_waiting_state(self, tmp_dir): + events = combine(make_events(2), wait(0.3), make_events(2), axis="t") + pipeline = make_pipeline(tmp_dir, tracker=_trackpy(), with_stim=False) + ctrl = Controller(FakeMicroscope(CircleScene()), pipeline) + + seen_waiting = [] + handle = ctrl.run_experiment(events, validate=False) + handle.statusChanged.connect( + lambda s: seen_waiting.append(s.state == "waiting") if s.state == "waiting" else None + ) + handle.wait() + ctrl.finish_experiment() + assert any(seen_waiting), "run never entered the 'waiting' state" + + +# --------------------------------------------------------------------------- +# Interactive pause — output equivalence + state machine +# --------------------------------------------------------------------------- + + +class TestInteractivePause: + def test_pause_resume_preserves_frame_count(self, tmp_dir): + events = _spaced(make_events(8), dt=0.1) + pipeline = make_pipeline(tmp_dir, tracker=_trackpy(), with_stim=False) + ctrl = Controller(FakeMicroscope(CircleScene()), pipeline) + + handle = ctrl.run_experiment(events, validate=False) + assert _wait_until(lambda: handle.status().n_events_consumed >= 2) + handle.pause() + assert _wait_until(lambda: handle.status().state == "paused") + handle.resume() + final = handle.wait() + ctrl._analyzer.wait_idle() + ctrl._analyzer.shutdown(wait=True) + + assert final.state == "done" + assert len(_raw_tiff_names(tmp_dir)) == 8 + assert final.n_events_acquired == 8 + + def test_pause_produces_identical_zarr(self, tmp_dir): + """Paused and unpaused runs of the same events must yield + byte-identical OME-Zarr raw data.""" + events = _spaced(make_events(8), dt=0.1) + raw_no_pause = _run_capture_zarr( + os.path.join(tmp_dir, "nopause"), events, pause=False + ) + raw_paused = _run_capture_zarr( + os.path.join(tmp_dir, "paused"), events, pause=True + ) + np.testing.assert_array_equal(raw_no_pause, raw_paused) + + def test_cancel_during_pause_exits_cleanly(self, tmp_dir): + events = _spaced(make_events(8), dt=0.1) + pipeline = make_pipeline(tmp_dir, tracker=_trackpy(), with_stim=False) + ctrl = Controller(FakeMicroscope(CircleScene()), pipeline) + + handle = ctrl.run_experiment(events, validate=False) + assert _wait_until(lambda: handle.status().n_events_consumed >= 2) + handle.pause() + assert _wait_until(lambda: handle.status().state == "paused") + handle.cancel() + assert _wait_until(lambda: not handle.is_running(), timeout=10) + ctrl.finish_experiment() + # The worker drains and exits cleanly to a terminal "done" state; + # cancellation is proven by stopping early (not all 8 acquired) + # with no fatal error rather than by the transient "cancelling". + final = handle.status() + assert final.fatal_error is None + assert final.n_events_acquired < 8 diff --git a/tests/test_validate_events.py b/tests/test_validate_events.py index c3de837..9ce8248 100644 --- a/tests/test_validate_events.py +++ b/tests/test_validate_events.py @@ -23,6 +23,7 @@ RTMEvent, RTMSequence, SegmentationMethod, + wait, ) from faro.core.pipeline import ImageProcessingPipeline from faro.segmentation.base import Segmentator @@ -346,6 +347,15 @@ def test_fe_metadata_present_passes(self, tmp_path_cleanup): events = _make_events(metadata={"fe_threshold": 0.5}) assert pipeline.validate_pipeline(events) is True + def test_wait_event_skips_metadata_check(self, tmp_path_cleanup): + """A WaitEvent carries no metadata and must not trip the + required-metadata check that applies to acquired events.""" + pipeline = _make_pipeline( + tmp_path_cleanup, tracker=TrackerNeedsCondition(), + ) + events = _make_events(metadata={"condition": "control"}) + [wait(5.0)] + assert pipeline.validate_pipeline(events) is True + # --- Multiple components with metadata requirements --- def test_multiple_components_all_missing(self, tmp_path_cleanup): diff --git a/tests/test_validate_hardware.py b/tests/test_validate_hardware.py index a7410a6..a4ed69f 100644 --- a/tests/test_validate_hardware.py +++ b/tests/test_validate_hardware.py @@ -10,7 +10,7 @@ import pytest -from faro.core.data_structures import Channel, PowerChannel, RTMEvent +from faro.core.data_structures import Channel, PowerChannel, RTMEvent, wait from faro.core.utils import validate_hardware from tests.fake_mmc import build_validation_core as _core @@ -67,6 +67,12 @@ def test_stim_channel_unknown_fails(self): assert result is False assert any("nonexistent-laser" in str(warning.message) for warning in w) + def test_wait_event_ignored(self): + """A WaitEvent has no channels and must not trip config checks.""" + mmc = _core() + events = _make_events(channels=[Channel("phase-contrast", 50)]) + [wait(5.0)] + assert validate_hardware(events, mmc) is True + def test_multiple_groups_searched(self): """Config can be in any group — not just 'Channel'.""" mmc = _core(config_groups={ diff --git a/uv.lock b/uv.lock index 0c5d8e9..c7db5b0 100644 --- a/uv.lock +++ b/uv.lock @@ -868,6 +868,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/09/f8d8f8f31e4483c10a906437b4ce31bdf3d6d417b73fe33f1a8b59e34228/einops-0.8.2-py3-none-any.whl", hash = "sha256:54058201ac7087911181bfec4af6091bb59380360f069276601256a76af08193", size = 65638, upload-time = "2026-01-26T04:13:18.546Z" }, ] +[[package]] +name = "execnet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, +] + [[package]] name = "executing" version = "2.2.1" @@ -916,6 +925,9 @@ convpaint = [ { name = "napari-convpaint" }, { name = "scipy" }, ] +motile = [ + { name = "motile" }, +] remote-segmentation = [ { name = "imaging-server-kit" }, ] @@ -925,7 +937,9 @@ stardist = [ { name = "tensorflow" }, ] test = [ + { name = "motile" }, { name = "pytest" }, + { name = "pytest-xdist" }, ] virtual-microscope = [ { name = "imageio", extra = ["ffmpeg"] }, @@ -937,11 +951,13 @@ virtual-microscope = [ requires-dist = [ { name = "cellpose", marker = "extra == 'cellpose'", specifier = ">=4.1.1" }, { name = "csbdeep", marker = "extra == 'stardist'" }, + { name = "faro", extras = ["motile"], marker = "extra == 'test'" }, { name = "imageio", extras = ["ffmpeg"], marker = "extra == 'virtual-microscope'" }, { name = "imaging-server-kit", marker = "extra == 'remote-segmentation'" }, { name = "ipykernel" }, { name = "ipywidgets" }, { name = "matplotlib" }, + { name = "motile", marker = "extra == 'motile'" }, { name = "napari", extras = ["pyqt6"] }, { name = "napari-convpaint", marker = "extra == 'convpaint'" }, { name = "napari-micromanager" }, @@ -956,6 +972,7 @@ requires-dist = [ { name = "pymmcore-plus", specifier = ">=0.17.3" }, { name = "pymmcore-widgets", git = "https://github.com/pymmcore-plus/pymmcore-widgets.git" }, { name = "pytest", marker = "extra == 'test'" }, + { name = "pytest-xdist", marker = "extra == 'test'" }, { name = "scikit-image" }, { name = "scipy", marker = "extra == 'convpaint'" }, { name = "stardist", marker = "extra == 'stardist'" }, @@ -967,7 +984,7 @@ requires-dist = [ { name = "virtual-microscope", marker = "extra == 'virtual-microscope'", git = "https://github.com/hinderling/virtual-microscope.git" }, { name = "zarr", specifier = ">=3" }, ] -provides-extras = ["test", "stardist", "cellpose", "convpaint", "remote-segmentation", "virtual-microscope", "api74", "api75"] +provides-extras = ["test", "motile", "stardist", "cellpose", "convpaint", "remote-segmentation", "virtual-microscope", "api74", "api75"] [[package]] name = "fastapi" @@ -1537,6 +1554,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] +[[package]] +name = "ilpy" +version = "0.5.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyscipopt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/cd/03e6701419beb1c50e3e425d2378dd3f00dd8423e49dcdf6c893bc16b77e/ilpy-0.5.3.tar.gz", hash = "sha256:ec762291186ea92b2b6c5650fe9ad3f61492d832d67d591162a68575e23cbc80", size = 28778, upload-time = "2026-04-17T15:27:25.092Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/1d/45feda02c92a2d1fa6bd456fa01dcf954b2f495158bdc19dc3e9ce971fbb/ilpy-0.5.3-py3-none-any.whl", hash = "sha256:c96afcbf0d850ad7f00176f91463b827bdfaf93490a8e9658a1d834a334dd5b2", size = 26026, upload-time = "2026-04-17T15:27:23.816Z" }, +] + [[package]] name = "imagecodecs" version = "2025.11.11" @@ -2286,6 +2315,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ad/3f/3d42e9a78fe5edf792a83c074b13b9b770092a4fbf3462872f4303135f09/ml_dtypes-0.5.4-cp314-cp314t-win_arm64.whl", hash = "sha256:11942cbf2cf92157db91e5022633c0d9474d4dfd813a909383bd23ce828a4b7d", size = 168825, upload-time = "2025-11-17T22:32:23.766Z" }, ] +[[package]] +name = "motile" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ilpy" }, + { name = "networkx" }, + { name = "numpy" }, + { name = "structsvm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/17/4817d148419f77df3e0fdcb41916d67cc77dc6d5b05ed0cb4865a3f69918/motile-0.4.0.tar.gz", hash = "sha256:10dd7dd3bcf586ef389148ca91aadeb163f05f50020b8acafcd4050b574f385d", size = 44576, upload-time = "2026-03-27T18:49:38.354Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/04/6b9c88ea5f874564838688485f79a8540458d81d0125d6cf5c5d8139ca24/motile-0.4.0-py3-none-any.whl", hash = "sha256:d4f7d6570f67bac2e7963904e78f938d9dad3222f6e2363a33621e77cdecaa86", size = 32941, upload-time = "2026-03-27T18:49:37.496Z" }, +] + [[package]] name = "mpmath" version = "1.3.0" @@ -3806,8 +3850,8 @@ cli = [ [[package]] name = "pymmcore-widgets" -version = "0.12.2.dev8+g8c8f76e5d" -source = { git = "https://github.com/pymmcore-plus/pymmcore-widgets.git#8c8f76e5d0778af14b63b3e03206a93eac4664b3" } +version = "0.12.2.dev12+g48ff41416" +source = { git = "https://github.com/pymmcore-plus/pymmcore-widgets.git#48ff4141619304fe5a58827ead62cc8d01e5f134" } dependencies = [ { name = "pymmcore-plus", extra = ["cli"] }, { name = "pyopengl", marker = "sys_platform == 'darwin' or (extra == 'extra-4-faro-api74' and extra == 'extra-4-faro-api75')" }, @@ -3898,6 +3942,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8d/42/efb7ced69f7d1d31eb8f19b2d778aeb182be7e070569d02b9057ac478e3e/pyqt6_sip-13.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:42b62530a9b6a9c6e29c2941b8ab78258652da0aeae4eb1fc9a0631d19a7a7b2", size = 49597, upload-time = "2026-03-09T13:01:34.49Z" }, ] +[[package]] +name = "pyscipopt" +version = "6.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/b9/ef40e260c3e722d9d4617dd70548c1e3c51b065decd341cf9b9031957bf1/pyscipopt-6.2.1.tar.gz", hash = "sha256:3da1634ff341c8665fcf100486f7968ddbbf160dc56d83e99338717d2245ef6a", size = 1683168, upload-time = "2026-05-16T15:06:54.486Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/dc/347f5b1a30972fb86759d6975acab3cb0fcbd1df6ea0f26873a8a46ddc32/pyscipopt-6.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fbfbc9fce11f8ee0383e64fcfef4bb1e7b5ae6a1063dd964008cf20f906fdd4d", size = 8411318, upload-time = "2026-05-16T15:05:01.205Z" }, + { url = "https://files.pythonhosted.org/packages/79/70/319ef747c8b639165e78a5013c65eae9fa265f364abd6d85cb932719aa30/pyscipopt-6.2.1-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:df9581445061a58c8681e884b4f00801f4ee1dc150d9e5d30faa3cd05f6f5c7c", size = 12259796, upload-time = "2026-05-16T15:05:03.887Z" }, + { url = "https://files.pythonhosted.org/packages/1c/d9/cdecac650bbab6c8d5fcf9577b77bda53d8bbe972b6285e12530b4782d77/pyscipopt-6.2.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7839074b1dff5cd6e243ea86c0f43cd9f7e9e19257b1fdc5549cf9c9cff0fa6d", size = 16214522, upload-time = "2026-05-16T15:05:07.189Z" }, + { url = "https://files.pythonhosted.org/packages/7e/5b/3ce96f3ed012d3f17556748b27d49ba42b3662283ecb02ae45c70ed19de1/pyscipopt-6.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:faf86357d83772508c5b1925570ee7e08385fa1a736e0ee33bf0e5c421dd845f", size = 17566755, upload-time = "2026-05-16T15:05:11.138Z" }, + { url = "https://files.pythonhosted.org/packages/8a/50/9fceeb125674c0e955b2175cbba24f2b32ba5f8b635c3484648eb802d090/pyscipopt-6.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:784d8fbee8134c7c1cf590a60972008159033938a5044d9ed28cde9abf4f86be", size = 48216285, upload-time = "2026-05-16T15:05:17.131Z" }, + { url = "https://files.pythonhosted.org/packages/76/ac/251c595d0eddd4e5480717298118bd252c3d8e5c169d2d95efc862e259ab/pyscipopt-6.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:353725a8f65c86299502aadca12c3a1c7622a64746ea12251906ae0165c843ae", size = 8405270, upload-time = "2026-05-16T15:05:20.386Z" }, + { url = "https://files.pythonhosted.org/packages/95/34/28ae4af84b6d372404da9d5ff636f1341826f80b793d98f86cac03bd0aa4/pyscipopt-6.2.1-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:fdba06632975280df18e684aa4b9867b1167cb3a6aa9a201e7ee3b108985af51", size = 12257430, upload-time = "2026-05-16T15:05:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/fa/6f/5173067773b5e650566f90c3356bd3a71c02349e6644222a8971c0196687/pyscipopt-6.2.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8860afb9d43c93b653c7295ef674ad1ba156c731591fb7e33b5991c1136b0dc6", size = 16207762, upload-time = "2026-05-16T15:05:26.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/76/59288c92b7ee914c351c6003b63249e0702d990d1fdd9ff97e65ffc1c57b/pyscipopt-6.2.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:725503ea90fd0962f1111a5b46ee3e271b7375e1b0dfda708ce223dbebaeff5e", size = 17560629, upload-time = "2026-05-16T15:05:30.298Z" }, + { url = "https://files.pythonhosted.org/packages/0d/42/2b1d48d11311c2fda215c8da83f8f8cabec3b5a82936a7229919ad9141e5/pyscipopt-6.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a5621ddcb59f7816e87c3deeb1bf52f8693e016a1a29148201b712adb84956e3", size = 48215647, upload-time = "2026-05-16T15:05:36.5Z" }, + { url = "https://files.pythonhosted.org/packages/fc/af/4ddfd3802ff69ad58f44e6d96878265c4ea55cac2313aae1994611b0d6aa/pyscipopt-6.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:299dbff65d60853d545788457d02720e3693df19ade4aaba1bbe8b575239ff4b", size = 8418209, upload-time = "2026-05-16T15:05:40.166Z" }, + { url = "https://files.pythonhosted.org/packages/9a/53/61ab5575a6e29547b6d13c37d7005b3f348897b48dd6cbcd4261196f2e25/pyscipopt-6.2.1-cp314-cp314-macosx_11_0_x86_64.whl", hash = "sha256:8bd6fb0f2a6c8bf4ef49e524d4c022b7b539098193ce312e94d29c6254658ff6", size = 12267358, upload-time = "2026-05-16T15:05:43.17Z" }, + { url = "https://files.pythonhosted.org/packages/c9/fd/851dedcabdb6d6168eae0e2c31008d02f20cf018b05d091a5bda6f5da6a1/pyscipopt-6.2.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bb7858ceececa09658c3bfa58476862255353fea52d4f512ff97160f138f92cd", size = 16171696, upload-time = "2026-05-16T15:05:46.851Z" }, + { url = "https://files.pythonhosted.org/packages/86/7e/ac663246709e6ab94b225c40e9dac863a91b1b86e12c2ea65c951f944bea/pyscipopt-6.2.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9cdf0e460b834f06ea68a13e59f581f7ecbec5a466a76bbf1267ac5b4573bb52", size = 17430536, upload-time = "2026-05-16T15:05:50.267Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ca/05d80040767d1d2443ea6cd6cc42985cdd532feeaecfcc19f103c8b45a1b/pyscipopt-6.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:6aed03b621decb09b38f399773bf8cf2c707e965990b778a24d28c8cc90a0756", size = 49375214, upload-time = "2026-05-16T15:05:56.493Z" }, + { url = "https://files.pythonhosted.org/packages/05/d4/caa18165a2faf876d8d482b0b92bd75abf284af2b51b64ebee62c1b47065/pyscipopt-6.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:18c6283b8fc47929787a043204e7bb26f41e414d1e8597d394057bcc60fc3ee0", size = 8528074, upload-time = "2026-05-16T15:05:59.776Z" }, + { url = "https://files.pythonhosted.org/packages/0f/3c/f6593bf4459e788f2302878369c5eb65ec5b04fd6e18524296fe05365c6b/pyscipopt-6.2.1-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:622e9640cdfc22632079ed4f73d88653d6170ee89ca6bdb6459d0db334fa7a87", size = 12341833, upload-time = "2026-05-16T15:06:02.402Z" }, + { url = "https://files.pythonhosted.org/packages/49/db/bc80dfa03ef13701b818aca26428fe05c389a71a8ec5654e1e4ea60ef3a4/pyscipopt-6.2.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a85fb7f73fd06fad9a0358b2eb47d94dbe94ee52baf85e045beb5e216022b6c7", size = 16735540, upload-time = "2026-05-16T15:06:05.522Z" }, + { url = "https://files.pythonhosted.org/packages/58/ee/97cd080513efdedea2fcd1f9b71d02e775f5e445ab39f8f012c14e4b4c5e/pyscipopt-6.2.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d323fa83b855308587794cd0ab04ae6dd341c227202d0ddaec2761917034e972", size = 17628571, upload-time = "2026-05-16T15:06:09.608Z" }, + { url = "https://files.pythonhosted.org/packages/7b/75/e280c162ae55a5db7f9031c4b92774964a8eebef94d2d463a389c9f6294b/pyscipopt-6.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:138e312cd692b7c853e7eab572986bc6d2dd28acd6e16347d73c96c225613056", size = 49551043, upload-time = "2026-05-16T15:06:15.368Z" }, +] + [[package]] name = "pytest" version = "9.0.3" @@ -3914,6 +3989,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, ] +[[package]] +name = "pytest-xdist" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -4660,6 +4748,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, ] +[[package]] +name = "structsvm" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ilpy" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/93/6f/7116252e13ce88a3fe4d04a3197afa12eeb60ca54daaaa6ccf442f53e361/structsvm-0.2.0.tar.gz", hash = "sha256:f457dc12718f886b604c461e3970bd186056e14f2eb403b1a27dfac165b6f581", size = 7380, upload-time = "2025-04-16T12:59:56.337Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/2c/6a37fa71d82ea628c3c1ce4a034df78e9b81a2b724de3af1f36a8b93ab18/structsvm-0.2.0-py3-none-any.whl", hash = "sha256:fa42375c863e08f5d431cd16f1515b2436d89ad56a85101a75b95825b51ed262", size = 6945, upload-time = "2025-04-16T12:59:54.693Z" }, +] + [[package]] name = "superqt" version = "0.7.6" @@ -4890,21 +4991,21 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp312-cp312-manylinux_2_28_aarch64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp312-cp312-manylinux_2_28_x86_64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp312-cp312-win_amd64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313-manylinux_2_28_aarch64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313-manylinux_2_28_x86_64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313-win_amd64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313t-manylinux_2_28_aarch64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313t-manylinux_2_28_x86_64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313t-win_amd64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314-manylinux_2_28_aarch64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314-manylinux_2_28_x86_64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314-win_amd64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314t-manylinux_2_28_aarch64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314t-manylinux_2_28_x86_64.whl" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314t-win_amd64.whl" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:252f237d417fac3ba59b1635815c1f035a8241f2af038f2c076ed430932d89f1", upload-time = "2026-04-27T20:01:46Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:96911323dcfcd42028c7e8edde7bdf25bb187753234e8775f0f3f112e86a22db", upload-time = "2026-04-27T20:02:14Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp312-cp312-win_amd64.whl", hash = "sha256:ef8beae16d781c3244ef28dc7bee6d8871c26bbde65d5bf66e902cb61972c4ab", upload-time = "2026-04-27T20:03:28Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c3d60f79666b9101e3914a2e5dec2e81eac834e13cae0bcf59e94dc1a465f756", upload-time = "2026-04-27T20:04:49Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:554461b76f21211927c776056bcb0b00fb42972364794b686d768ebb0b586366", upload-time = "2026-04-27T20:05:21Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313-win_amd64.whl", hash = "sha256:339801f2163698a53c7fb3c91883e7f44331d22c34d45acfbce4eff71f2332fa", upload-time = "2026-04-27T20:06:44Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:a33905bc3e093b25d2b019181cf834f7f7d4c562739e13dd36a798ecb2e411b0", upload-time = "2026-04-27T20:08:23Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6fd10ed484eb695312ae829719888bb9f6c7f5e8503528e3e8ad1b98a45296c2", upload-time = "2026-04-27T20:08:56Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp313-cp313t-win_amd64.whl", hash = "sha256:21d2734fd02af45d19bb88c0ff2e86b238ce73f7bde6003ade7f1454ae299198", upload-time = "2026-04-27T20:10:20Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:efcdfe08ec2c9db28b50cc7329fed0c90bb74fa6fbce0f7eb12e20db2279a40f", upload-time = "2026-04-27T20:11:48Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6ccc36928fd17c86011b46fb81bd2c85475f1fbf967dde758672d6a8d83a212a", upload-time = "2026-04-27T20:12:18Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314-win_amd64.whl", hash = "sha256:d886f1c2f4406d7ad0c59f254ceb0a9c47a03e97a7c704b778a2066d752dde29", upload-time = "2026-04-27T20:13:41Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:bdb20f8b04e9fcaba2f354c3026667bebb74de8a92526b706aa735e2df334c24", upload-time = "2026-04-27T20:15:02Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:28f952cd4a927616ad9d77644a93237d1ca50bf30d0cf26962b9162d8a00ffa0", upload-time = "2026-04-27T20:15:30Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.11.0%2Bcu130-cp314-cp314t-win_amd64.whl", hash = "sha256:d0a857adc487f275bfc9e7cdc51d12940613ba18b6362da214e20e9e3871f817", upload-time = "2026-04-27T20:16:48Z" }, ] [[package]] @@ -4917,21 +5018,21 @@ dependencies = [ { name = "torch" }, ] wheels = [ - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e2b39db78be674ee4ce7e921f54b70e5c281594c9267d981c061684ed38df936" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:0f030a9bd8ada1a31b7111ea1589c1ecb5fa0884fee700a203e731b4cf378a98" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp312-cp312-win_amd64.whl", hash = "sha256:a3578f7c8e8a2724306c68c56873a1675fa7ce45471e18235c720a2ed242fe44" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:3af2c699719cc0e2518bf317664200e5a987fb75a25b9b3bf3817a4796ddd64f" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:441a98bed4fff1d54b8450499e377e1a605bec31f2ecb1a38a340f95dcc83897" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313-win_amd64.whl", hash = "sha256:64de855465d6de60583e776889fad9412480f9f9e04fdd8d17ae96fa93864e9a" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c3ac485da79552b4f579c525c826f7a63288b0d1cafc1201b16e1148bfdea69a" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:110659ff38cd1d2ca0ac6e6a0f2c842fcb5fe739dfe65ff7456a12b2c4dce775" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313t-win_amd64.whl", hash = "sha256:a7e19c3ab5c6d8e3c9f8c6d427f6b8862dfb8227ea4a758ea7a709951daf2f0d" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:13fe3dee74a9ee31b551b10a8b4113d9bc5212bb0572a07af88b34a5d25d9701" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:8d6a83a639d14f7e84f6b838a17e26f9ce41cdbe3dfe0c29ef74b32eb398ba28" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314-win_amd64.whl", hash = "sha256:ab671ffe837aff470baad6af97133ea5a49f8ea2383832550e510a63caf711e4" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:cd89effa98de436ec22ccbbd278cdadc0fdec8eb81a396150f50b321c2230866" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:aacac4d990ac794f3abeca66cc26affb42fbeba9789e5c351183665bab4902d2" }, - { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314t-win_amd64.whl", hash = "sha256:23b9666084c72d07fc715001880b648e6a410796d1925c10f054f1ee034f5cc7" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e2b39db78be674ee4ce7e921f54b70e5c281594c9267d981c061684ed38df936", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:0f030a9bd8ada1a31b7111ea1589c1ecb5fa0884fee700a203e731b4cf378a98", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp312-cp312-win_amd64.whl", hash = "sha256:a3578f7c8e8a2724306c68c56873a1675fa7ce45471e18235c720a2ed242fe44", upload-time = "2026-04-09T23:21:53Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:3af2c699719cc0e2518bf317664200e5a987fb75a25b9b3bf3817a4796ddd64f", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:441a98bed4fff1d54b8450499e377e1a605bec31f2ecb1a38a340f95dcc83897", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313-win_amd64.whl", hash = "sha256:64de855465d6de60583e776889fad9412480f9f9e04fdd8d17ae96fa93864e9a", upload-time = "2026-04-09T23:21:54Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c3ac485da79552b4f579c525c826f7a63288b0d1cafc1201b16e1148bfdea69a", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:110659ff38cd1d2ca0ac6e6a0f2c842fcb5fe739dfe65ff7456a12b2c4dce775", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp313-cp313t-win_amd64.whl", hash = "sha256:a7e19c3ab5c6d8e3c9f8c6d427f6b8862dfb8227ea4a758ea7a709951daf2f0d", upload-time = "2026-04-09T23:21:55Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:13fe3dee74a9ee31b551b10a8b4113d9bc5212bb0572a07af88b34a5d25d9701", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:8d6a83a639d14f7e84f6b838a17e26f9ce41cdbe3dfe0c29ef74b32eb398ba28", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314-win_amd64.whl", hash = "sha256:ab671ffe837aff470baad6af97133ea5a49f8ea2383832550e510a63caf711e4", upload-time = "2026-04-09T23:21:56Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:cd89effa98de436ec22ccbbd278cdadc0fdec8eb81a396150f50b321c2230866", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:aacac4d990ac794f3abeca66cc26affb42fbeba9789e5c351183665bab4902d2", upload-time = "2026-03-23T15:36:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torchvision-0.26.0%2Bcu130-cp314-cp314t-win_amd64.whl", hash = "sha256:23b9666084c72d07fc715001880b648e6a410796d1925c10f054f1ee034f5cc7", upload-time = "2026-04-09T23:21:57Z" }, ] [[package]] @@ -5133,7 +5234,7 @@ wheels = [ [[package]] name = "virtual-microscope" version = "0.1.0" -source = { git = "https://github.com/hinderling/virtual-microscope.git#e2aca8da2a71c9a0298a485ba69f115366860392" } +source = { git = "https://github.com/hinderling/virtual-microscope.git#bd4ac3e3c24c78605a1921093fe647daaf181dc6" } dependencies = [ { name = "numba" }, { name = "numpy" },