magscope 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- magscope-0.1.0/PKG-INFO +484 -0
- magscope-0.1.0/README.md +459 -0
- magscope-0.1.0/license +674 -0
- magscope-0.1.0/magscope/__init__.py +18 -0
- magscope-0.1.0/magscope/beadlock.py +231 -0
- magscope-0.1.0/magscope/camera.py +682 -0
- magscope-0.1.0/magscope/datatypes.py +572 -0
- magscope-0.1.0/magscope/hardware.py +45 -0
- magscope-0.1.0/magscope/processes.py +199 -0
- magscope-0.1.0/magscope/scope.py +326 -0
- magscope-0.1.0/magscope/scripting.py +305 -0
- magscope-0.1.0/magscope/utils.py +118 -0
- magscope-0.1.0/magscope/videoprocessing.py +435 -0
- magscope-0.1.0/magscope.egg-info/PKG-INFO +484 -0
- magscope-0.1.0/magscope.egg-info/SOURCES.txt +20 -0
- magscope-0.1.0/magscope.egg-info/dependency_links.txt +1 -0
- magscope-0.1.0/magscope.egg-info/requires.txt +14 -0
- magscope-0.1.0/magscope.egg-info/top_level.txt +1 -0
- magscope-0.1.0/pyproject.toml +39 -0
- magscope-0.1.0/setup.cfg +4 -0
- magscope-0.1.0/tests/test_dummy_bead_camera.py +86 -0
- magscope-0.1.0/tests/test_video_buffer.py +225 -0
magscope-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: magscope
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Live data acquisition and analysis for magnetic tweezers microscopy with only Python
|
|
5
|
+
Author-email: James London <7jameslondon@gmail.com>
|
|
6
|
+
License-Expression: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/7jameslondon/MagScope
|
|
8
|
+
Project-URL: Issues, https://github.com/7jameslondon/MagScope/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
11
|
+
Requires-Python: ==3.11
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: license
|
|
14
|
+
Requires-Dist: numpy
|
|
15
|
+
Requires-Dist: scipy
|
|
16
|
+
Requires-Dist: matplotlib
|
|
17
|
+
Requires-Dist: tifffile
|
|
18
|
+
Requires-Dist: PyYAML
|
|
19
|
+
Requires-Dist: magtrack
|
|
20
|
+
Requires-Dist: PyQt6
|
|
21
|
+
Provides-Extra: cpu
|
|
22
|
+
Provides-Extra: gpu
|
|
23
|
+
Requires-Dist: cupy-cuda12x>=13.0; sys_platform != "darwin" and extra == "gpu"
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
<h1 align="center">
|
|
27
|
+
MagScope
|
|
28
|
+
<img src="https://raw.githubusercontent.com/7jameslondon/MagScope/refs/heads/master/logo.png" width="300">
|
|
29
|
+
</h1><br>
|
|
30
|
+
|
|
31
|
+
[](https://pypi.org/project/magscope/)
|
|
32
|
+
[](https://magscope.readthedocs.io/en/latest/)
|
|
33
|
+
[](
|
|
34
|
+
https://doi.org/DOI-INSERTDOI)
|
|
35
|
+
[](https://github.com/7jameslondon/MagScope/actions/workflows/python-package.yml)
|
|
36
|
+
|
|
37
|
+
MagScope is a Python framework for live data acquisition and analysis in magnetic tweezers microscopy.
|
|
38
|
+
|
|
39
|
+
* GUI (Graphical User Interface)
|
|
40
|
+
* No setup required to give it a try
|
|
41
|
+
* Easily extended to your setup
|
|
42
|
+
* Fast, high-throughput, and high-resolution
|
|
43
|
+
* Create simple scripts to automate data-collection and motor movment for long/complex experiments
|
|
44
|
+
* CPU or GPU tracking of beads via [MagTrack](https://github.com/7jameslondon/MagTrack)
|
|
45
|
+
|
|
46
|
+
## ⏳ Install
|
|
47
|
+
### Pre-requisites
|
|
48
|
+
* Python >=3.9
|
|
49
|
+
* PyQt6
|
|
50
|
+
* matplotlib
|
|
51
|
+
* tifffile
|
|
52
|
+
* PyYAML
|
|
53
|
+
* NumPy >=1.26
|
|
54
|
+
* SciPy >=1.11.1
|
|
55
|
+
* MagTrack
|
|
56
|
+
* (Optional, but needed for GPU acceleration) CuPy-CUDA12x >=13.0
|
|
57
|
+
|
|
58
|
+
### Instructions
|
|
59
|
+
```
|
|
60
|
+
pip install magscope[gpu]
|
|
61
|
+
```
|
|
62
|
+
Or without CuPy
|
|
63
|
+
```
|
|
64
|
+
pip install magscope
|
|
65
|
+
```
|
|
66
|
+
Optional: For GPU acceleration on a computer with an NVIDIA CUDA GPU, you may need to install the CUDA Toolkit for CuPy. See details at https://docs.cupy.dev/en/stable/install.html
|
|
67
|
+
|
|
68
|
+
## ⚒ Usage
|
|
69
|
+
Start with the demo verions which include a simulated camera.
|
|
70
|
+
```
|
|
71
|
+
import magscope
|
|
72
|
+
|
|
73
|
+
scope = magscope.MagScope()
|
|
74
|
+
scope.start()
|
|
75
|
+
```
|
|
76
|
+
### More Examples
|
|
77
|
+
Coming soon
|
|
78
|
+
|
|
79
|
+
## 📖 Documentation
|
|
80
|
+
View the full documentation at [magscope.readthedocs.io](https://magscope.readthedocs.io/en/latest/)
|
|
81
|
+
|
|
82
|
+
## 💬 Support
|
|
83
|
+
Report issues, make requests, and ask questions on the [GitHub issue tracker](https://github.com/7jameslondon/MagScope/issues)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# OLD
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## Project Overview
|
|
96
|
+
|
|
97
|
+
MagScope is a modular control and analysis environment for magnetic tweezer
|
|
98
|
+
and microscopy experiments. It coordinates camera acquisition, bead tracking,
|
|
99
|
+
and hardware automation so researchers can run reproducible experiments from a
|
|
100
|
+
single desktop application. The toolkit is built to be extended – new cameras,
|
|
101
|
+
actuators, and analysis routines can plug into the same orchestration layer
|
|
102
|
+
without rewriting the core system.
|
|
103
|
+
|
|
104
|
+
**Key features**
|
|
105
|
+
|
|
106
|
+
* Multi-process managers for the camera, bead locking, video processing, GUI,
|
|
107
|
+
and scripting keep latency low while sharing data through high-performance
|
|
108
|
+
buffers.
|
|
109
|
+
* Shared-memory `VideoBuffer` and `MatrixBuffer` structures make it easy to
|
|
110
|
+
stream image stacks and time-series telemetry between producers and
|
|
111
|
+
consumers.
|
|
112
|
+
* A lightweight scripting runtime allows repeatable experiment protocols and
|
|
113
|
+
automated GUI interactions.
|
|
114
|
+
* Extensible hardware and control panel base classes simplify adding custom
|
|
115
|
+
instruments or user interface panels.
|
|
116
|
+
|
|
117
|
+
**High-level architecture**
|
|
118
|
+
|
|
119
|
+
At runtime `MagScope` instantiates manager processes for each subsystem,
|
|
120
|
+
including the `CameraManager`, `BeadLockManager`, `VideoProcessorManager`,
|
|
121
|
+
`ScriptManager`, and `WindowManager`. The core `MagScope` orchestrator loads
|
|
122
|
+
settings, allocates shared locks and buffers, and wires up inter-process pipes
|
|
123
|
+
before launching the managers. Managers exchange work and status updates via a
|
|
124
|
+
message-passing API and shared memory, while the GUI presents controls built on
|
|
125
|
+
`ControlPanelBase` widgets and time-series plots. Hardware integrations derive
|
|
126
|
+
from `HardwareManagerBase`, letting custom devices participate in the same
|
|
127
|
+
event loop and scripting hooks.
|
|
128
|
+
|
|
129
|
+
## Documentation
|
|
130
|
+
|
|
131
|
+
In-depth guides, diagrams, and usage examples now live in the
|
|
132
|
+
[`docs/`](docs/) directory. Start with the
|
|
133
|
+
[MagScope orchestrator overview](docs/scope.md) to learn how `MagScope.start()`
|
|
134
|
+
wires together managers, shared memory, and inter-process communication. The
|
|
135
|
+
documentation site is powered by MkDocs; see [`docs/index.md`](docs/index.md)
|
|
136
|
+
for instructions on building the site locally and contributing new pages.
|
|
137
|
+
|
|
138
|
+
## Quick Start Guide
|
|
139
|
+
|
|
140
|
+
Use the following condensed checklist when you simply want to get the simulated
|
|
141
|
+
scope running end-to-end:
|
|
142
|
+
|
|
143
|
+
1. **Install prerequisites** – Python 3.10+, git, and a terminal for your
|
|
144
|
+
operating system.
|
|
145
|
+
2. **Clone the repository**:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
git clone https://github.com/your-org/MagScope.git
|
|
149
|
+
cd MagScope
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
3. **Create and activate a virtual environment**:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
python3 -m venv .venv
|
|
156
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
4. **Install dependencies**:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pip install --upgrade pip
|
|
163
|
+
pip install -r requirements.txt
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
5. **Run the simulated scope**:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
python simulated_scope.py
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
When the GUI appears you should see the dummy camera streaming frames. Close the
|
|
173
|
+
window or press `Ctrl+C` in the terminal when you are finished.
|
|
174
|
+
|
|
175
|
+
## Detailed Setup Guide
|
|
176
|
+
|
|
177
|
+
The sections below expand each quick start step with more background
|
|
178
|
+
information, helpful links, and troubleshooting tips for developers who are new
|
|
179
|
+
to Python tooling.
|
|
180
|
+
|
|
181
|
+
### 0. Install the core tooling (Python, git, and a terminal)
|
|
182
|
+
|
|
183
|
+
If you are brand new to Python development, start by installing the latest
|
|
184
|
+
Python 3.10+ release from the
|
|
185
|
+
[official downloads page](https://www.python.org/downloads/). During the Windows
|
|
186
|
+
installer flow make sure the "Add python.exe to PATH" option is selected so that
|
|
187
|
+
the `python` command is available in Command Prompt and PowerShell. You will
|
|
188
|
+
also need a terminal (macOS Terminal, Windows Terminal, or any Linux shell) and
|
|
189
|
+
[git](https://git-scm.com/downloads) to clone the project repository. The
|
|
190
|
+
[Python beginner's guide to software engineering](https://docs.python.org/3/faq/programming.html)
|
|
191
|
+
explains how these pieces fit together if you need more background.
|
|
192
|
+
|
|
193
|
+
Once Python and git are installed, clone the repository and change into the
|
|
194
|
+
project directory:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
git clone https://github.com/your-org/MagScope.git
|
|
198
|
+
cd MagScope
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
If you prefer a graphical interface, GitHub Desktop and GitKraken both provide
|
|
202
|
+
point-and-click workflows that accomplish the same clone and checkout steps.
|
|
203
|
+
|
|
204
|
+
### 1. Create an isolated Python environment
|
|
205
|
+
|
|
206
|
+
MagScope targets Python 3.10 or newer. From the project root create and activate
|
|
207
|
+
a virtual environment so the project's dependencies stay separate from other
|
|
208
|
+
Python work. If you are new to the concept, the
|
|
209
|
+
[official venv tutorial](https://docs.python.org/3/tutorial/venv.html) provides a
|
|
210
|
+
gentle walkthrough.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
python3 -m venv .venv
|
|
214
|
+
source .venv/bin/activate
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
On Windows use `python -m venv .venv` followed by `.venv\Scripts\activate`. You
|
|
218
|
+
can confirm activation by checking that your shell prompt is prefixed with
|
|
219
|
+
`(.venv)` and that `which python` (macOS/Linux) or `where python` (Windows)
|
|
220
|
+
points to the `.venv` directory.
|
|
221
|
+
|
|
222
|
+
### 2. Install the dependencies
|
|
223
|
+
|
|
224
|
+
With the virtual environment activated, install the project requirements using
|
|
225
|
+
`pip`, Python's package installer. If you have never used `pip` before, the
|
|
226
|
+
[official user guide](https://pip.pypa.io/en/stable/user_guide/) explains the
|
|
227
|
+
basics and common troubleshooting steps.
|
|
228
|
+
|
|
229
|
+
Install the core requirements with pip:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
pip install --upgrade pip
|
|
233
|
+
pip install -r requirements.txt
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The list includes optional GPU-accelerated packages such as CuPy. If you do not
|
|
237
|
+
have a compatible CUDA toolkit available, comment out or remove the CuPy line
|
|
238
|
+
and install the remainder of the requirements. The
|
|
239
|
+
[Python Packaging User Guide](https://packaging.python.org/en/latest/tutorials/installing-packages/)
|
|
240
|
+
has additional background if you want to learn more about how Python packages
|
|
241
|
+
are managed.
|
|
242
|
+
|
|
243
|
+
### 3. Run the simulated scope end-to-end
|
|
244
|
+
|
|
245
|
+
When everything looks correct, start the simulated scope. The repository ships
|
|
246
|
+
with a dummy camera so you can exercise the full user interface without
|
|
247
|
+
connecting lab hardware. Launch it with:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
python simulated_scope.py
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This command starts `MagScope`, wires the `DummyBeadCamera` into the
|
|
254
|
+
`CameraManager`, and opens the Qt-based GUI. You should see the interface begin
|
|
255
|
+
streaming mock camera frames within a few seconds. If the window does not
|
|
256
|
+
appear, double-check that the virtual environment is active and that the
|
|
257
|
+
required Qt libraries were installed during the dependency step. When you are
|
|
258
|
+
ready to connect real instruments you can instead run `python main.py` and
|
|
259
|
+
configure the hardware classes described later in this document.
|
|
260
|
+
|
|
261
|
+
```mermaid
|
|
262
|
+
flowchart TD
|
|
263
|
+
subgraph Core Orchestrator
|
|
264
|
+
A[MagScope Main Process]
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
subgraph Shared Memory Buffers
|
|
268
|
+
VB[VideoBuffer]
|
|
269
|
+
MB[MatrixBuffer]
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
subgraph Manager Processes
|
|
273
|
+
CM[CameraManager]
|
|
274
|
+
BLM[BeadLockManager]
|
|
275
|
+
VPM[VideoProcessorManager]
|
|
276
|
+
SM[ScriptManager]
|
|
277
|
+
WM[WindowManager]
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
A -- spawn & configure --> CM
|
|
281
|
+
A -- spawn & configure --> BLM
|
|
282
|
+
A -- spawn & configure --> VPM
|
|
283
|
+
A -- spawn & configure --> SM
|
|
284
|
+
A -- spawn & configure --> WM
|
|
285
|
+
|
|
286
|
+
CM -- frames --> VB
|
|
287
|
+
VPM -- processed frames --> VB
|
|
288
|
+
BLM -- bead positions --> MB
|
|
289
|
+
SM -- experiment data --> MB
|
|
290
|
+
|
|
291
|
+
VB -. read/update .-> VPM
|
|
292
|
+
VB -. display frames .-> WM
|
|
293
|
+
MB -. analysis results .-> WM
|
|
294
|
+
|
|
295
|
+
WM -- GUI commands --> SM
|
|
296
|
+
SM -- IPC messages --> CM
|
|
297
|
+
SM -- IPC messages --> BLM
|
|
298
|
+
SM -- IPC messages --> VPM
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Settings
|
|
302
|
+
|
|
303
|
+
The `settings.py` module provides a convenient location for storing key user
|
|
304
|
+
preferences. Two notable parameters are `OBJECTIVE_MAG`, which determines how
|
|
305
|
+
pixels are converted to nanometers, and `ROI_WIDTH`, which defines the width of
|
|
306
|
+
the region of interest.
|
|
307
|
+
|
|
308
|
+
## Configuring a Camera
|
|
309
|
+
|
|
310
|
+
Verify your camera integration by running `test_camera.py` in the `tests`
|
|
311
|
+
directory. To add a camera, create a subclass of `CameraABC` (see
|
|
312
|
+
`camera.py`) and implement the required attributes and methods. Finally, set
|
|
313
|
+
the `ImplementedCamera` variable in `camera.py` to reference your new class.
|
|
314
|
+
|
|
315
|
+
## Shared-memory data buffers
|
|
316
|
+
|
|
317
|
+
The ``magscope.datatypes`` module defines the shared-memory-backed buffers that
|
|
318
|
+
processes use to exchange data efficiently.
|
|
319
|
+
|
|
320
|
+
* ``VideoBuffer`` stores image stacks and their capture timestamps. Create it in
|
|
321
|
+
the producer process with the desired shape information and share the
|
|
322
|
+
resulting metadata with consumer processes that instantiate the class with
|
|
323
|
+
``create=False``.
|
|
324
|
+
* ``MatrixBuffer`` stores 2D numeric data such as bead positions or motor
|
|
325
|
+
telemetry. The number of columns is fixed when the buffer is created, while
|
|
326
|
+
the number of rows written at a time can vary up to the buffer capacity.
|
|
327
|
+
|
|
328
|
+
Both buffers expect locks from ``multiprocessing`` so reads and writes can be
|
|
329
|
+
coordinated safely. See ``magscope/datatypes.py`` for detailed docstrings
|
|
330
|
+
covering their parameters and usage patterns.
|
|
331
|
+
|
|
332
|
+
## Force Calibrants (optional)
|
|
333
|
+
|
|
334
|
+
Provide force calibrants as plain-text files (for example, `force cal.txt`). You
|
|
335
|
+
may comment out the header line with `#`. Each subsequent line should map the
|
|
336
|
+
motor position in millimeters to the force in piconewtons. Include as many
|
|
337
|
+
interpolated data points as possible for the most accurate fit, e.g.:
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
# Motor Position (mm) Force (pN)
|
|
341
|
+
1.000 5.000
|
|
342
|
+
1.010 5.053
|
|
343
|
+
1.020 5.098
|
|
344
|
+
1.030 5.156
|
|
345
|
+
...
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Adding custom hardware
|
|
349
|
+
|
|
350
|
+
To add hardware, create a subclass of `HardwareManagerBase`.
|
|
351
|
+
|
|
352
|
+
* Set `buffer_shape` in `__init__`. Each row represents a time point. For
|
|
353
|
+
example, a shape of `(100000, 3)` stores 100,000 time points with three values
|
|
354
|
+
per sample (for example, time, position, and speed).
|
|
355
|
+
* Implement `connect`, which should set `self._is_connected` to `True` when the
|
|
356
|
+
connection succeeds.
|
|
357
|
+
* Implement `disconnect`.
|
|
358
|
+
* Implement `fetch`, which appends an entry to the buffer whenever the
|
|
359
|
+
program automatically polls the device.
|
|
360
|
+
|
|
361
|
+
## Scripting
|
|
362
|
+
|
|
363
|
+
MagScope ships with a lightweight scripting runtime that allows you to queue up
|
|
364
|
+
GUI interactions and hardware commands for repeatable experiments. A script is
|
|
365
|
+
an instance of `magscope.Script` where each call records a step to be executed
|
|
366
|
+
by the `ScriptManager` process:
|
|
367
|
+
|
|
368
|
+
```python
|
|
369
|
+
import magscope
|
|
370
|
+
|
|
371
|
+
script = magscope.Script()
|
|
372
|
+
script('set_acquisition_mode', magscope.AcquisitionMode.CROP_VIDEO)
|
|
373
|
+
script('sleep', 2.0) # wait for 2 seconds before running the next command
|
|
374
|
+
script('print', 'Ready for capture!')
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Save the script to a `.py` file and load it from the GUI to run it. The manager
|
|
378
|
+
validates each step to ensure the referenced method exists and that the
|
|
379
|
+
provided arguments match the registered callable.
|
|
380
|
+
|
|
381
|
+
Built-in scriptable functions include:
|
|
382
|
+
|
|
383
|
+
* `print` – display a message in the GUI log
|
|
384
|
+
* `sleep` – pause script execution for a fixed number of seconds
|
|
385
|
+
* `set_acquisition_on` – toggle processing of incoming frames
|
|
386
|
+
* `set_acquisition_dir` – choose the directory used to save acquisitions
|
|
387
|
+
* `set_acquisition_dir_on` – enable or disable saving data to disk
|
|
388
|
+
* `set_acquisition_mode` – switch between modes such as tracking or video
|
|
389
|
+
recording
|
|
390
|
+
|
|
391
|
+
See `example_script.py` for a minimal working example.
|
|
392
|
+
|
|
393
|
+
Expose additional methods to scripts by decorating a manager method with
|
|
394
|
+
`@registerwithscript('my_method_name')`. The string you provide becomes the
|
|
395
|
+
first argument when adding the step to a script, for example
|
|
396
|
+
`script('my_method_name', ...)`.
|
|
397
|
+
|
|
398
|
+
## Adding a custom process
|
|
399
|
+
|
|
400
|
+
You can extend `ManagerProcessBase` to create a separate process that manages
|
|
401
|
+
logic more complex than a single hardware device. Implement the following
|
|
402
|
+
abstract methods:
|
|
403
|
+
|
|
404
|
+
* `setup` – called when the process starts on its dedicated worker. Initialize
|
|
405
|
+
long-lived resources such as timers or hardware connections here. If no setup
|
|
406
|
+
work is required, use `pass`.
|
|
407
|
+
* `do_main_loop` – invoked repeatedly for the lifetime of the process. Place
|
|
408
|
+
autonomous process logic here. If no actions are needed, use `pass`.
|
|
409
|
+
|
|
410
|
+
## Adding a control panel
|
|
411
|
+
|
|
412
|
+
Subclass `ControlPanelBase` and implement an `__init__` method to construct the
|
|
413
|
+
PyQt6 widgets. The initializer must accept a `manager` argument and pass it to
|
|
414
|
+
`super().__init__`. Later, access `self.manager` to invoke `WindowManager`
|
|
415
|
+
functions. `ControlPanelBase` derives from `QWidget` and provides a default
|
|
416
|
+
`QVBoxLayout`. Replace the layout with `setLayout` if needed, or add elements
|
|
417
|
+
via `self.layout().addWidget()` and `self.layout().addLayout()`.
|
|
418
|
+
|
|
419
|
+
Example:
|
|
420
|
+
|
|
421
|
+
```
|
|
422
|
+
import magscope
|
|
423
|
+
|
|
424
|
+
class MyNewControlPanel(magscope.ControlPanelBase):
|
|
425
|
+
def __init__(self, manager: 'WindowManager'):
|
|
426
|
+
super().__init__(manager=manager, title='New Panel')
|
|
427
|
+
self.layout().addWidget(QLabel('This is my new panel'))
|
|
428
|
+
|
|
429
|
+
row = QHBoxLayout()
|
|
430
|
+
self.layout().addLayout(row)
|
|
431
|
+
|
|
432
|
+
row.addWidget(QLabel('A Button'))
|
|
433
|
+
button = QPushButton('Press Me')
|
|
434
|
+
button.clicked.connect(self.button_callback)
|
|
435
|
+
row.addWidget(button)
|
|
436
|
+
|
|
437
|
+
def button_callback(self):
|
|
438
|
+
print('The button was pressed')
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Sending interprocess calls (IPC)
|
|
442
|
+
|
|
443
|
+
Start by creating a `magscope.Message`. Provide at least two arguments: `to`,
|
|
444
|
+
which specifies the destination process (for example `CameraManager` or the
|
|
445
|
+
base `ManagerProcessBase` to broadcast to all managers), and `meth`, which is
|
|
446
|
+
the uninvoked method object that should be executed (for example
|
|
447
|
+
`CameraManager.set_camera_setting`). Do not call the method when constructing
|
|
448
|
+
the message. Supply positional or keyword arguments as additional parameters, or
|
|
449
|
+
explicitly pass tuples and dictionaries through the `args` and `kwargs`
|
|
450
|
+
keywords.
|
|
451
|
+
|
|
452
|
+
Send the message with `send_ipc()`. To avoid circular imports, perform local
|
|
453
|
+
imports of the destination process class immediately before use.
|
|
454
|
+
|
|
455
|
+
Example:
|
|
456
|
+
|
|
457
|
+
```
|
|
458
|
+
import magscope
|
|
459
|
+
|
|
460
|
+
class MyProcesses(magscope.ManagerProcessBase):
|
|
461
|
+
def send_camera_setting(self, setting_name, setting_value):
|
|
462
|
+
message = magscope.Message(
|
|
463
|
+
to=magscope.CameraManager,
|
|
464
|
+
meth=magscope.CameraManager.set_camera_setting,
|
|
465
|
+
args=(setting_name, setting_value),
|
|
466
|
+
)
|
|
467
|
+
self.send_ipc(message)
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## Development
|
|
471
|
+
|
|
472
|
+
To format the Python files, run the following commands:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
yapf main.py -i
|
|
476
|
+
yapf .\magscope\ -i -r
|
|
477
|
+
yapf .\tests\ -i -r
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
To install MagTrack during development, run:
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
pip install --force-reinstall --no-deps --no-cache-dir '..\MagTrack\magtrack-0.3.2-py3-none-any.whl'
|
|
484
|
+
```
|