Skip to content

Commit 3a79e16

Browse files
committed
resolved: merge conflict with main
2 parents 11b422a + 4ceef8c commit 3a79e16

41 files changed

Lines changed: 5203 additions & 1220 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.DS_Store

6 KB
Binary file not shown.

.github/workflows/deploy.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Deploy MyST Site
2+
on:
3+
push:
4+
branches: [main]
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
pages: write
10+
id-token: write
11+
12+
concurrency:
13+
group: "pages"
14+
cancel-in-progress: false
15+
16+
jobs:
17+
deploy:
18+
environment:
19+
name: github-pages
20+
url: ${{ steps.deployment.outputs.page_url }}
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '20'
28+
- name: Setup MyST
29+
run: npm install -g mystmd
30+
- name: Build site
31+
env:
32+
BASE_URL: /asyncroscopy
33+
run: |
34+
cd docs
35+
myst build --html
36+
touch _build/html/.nojekyll
37+
- name: Upload artifact
38+
uses: actions/upload-pages-artifact@v3
39+
with:
40+
path: 'docs/_build/html'
41+
- name: Deploy to GitHub Pages
42+
id: deployment
43+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,5 +206,11 @@ marimo/_static/
206206
marimo/_lsp/
207207
__marimo__/
208208

209+
.DS_Store
210+
209211
PythonPackages-AS-1.15/
210-
llm-context/
212+
llm-context/
213+
# MyST build outputs
214+
_build
215+
216+
extra-notebooks-debug/

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Asyncroscopy:
22
- Enabling smart microscopy via asynchronous servers
33

4+
![Schematic of the functional project structure](architecture.png)
5+
46
Note: `main` branch now contains the PyTango-based architecture. The previous Twisted-based implementation is preserved in the `twisted-legacy` branch for reference.
57
---
68

@@ -47,7 +49,7 @@ See - docs/dev_guide.md
4749
### Core installation (simulation mode)
4850

4951
```bash
50-
pip install .
52+
pip install --find-links ./stubs -e .
5153
```
5254

5355
or with `uv`:

architecture.png

1.64 MB
Loading

asyncroscopy/Microscope.py

Lines changed: 123 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ class Microscope(Device, metaclass=CombinedMeta):
4444
# Device properties — configure in Tango DB per deployment
4545
# ------------------------------------------------------------------
4646

47-
4847
scan_device_address = device_property(
4948
dtype=str,
5049
doc="Tango device address for the SCAN settings device. "
@@ -66,14 +65,12 @@ class Microscope(Device, metaclass=CombinedMeta):
6665
"No-DB mode: 'tango://127.0.0.1:8888/test/nodb/stage#dbase=no'",
6766
)
6867

69-
70-
corrector_device_address = device_property(
68+
camera_device_address = device_property(
7169
dtype=str,
72-
doc="Tango device address for the aberration corrector settings device. "
73-
"DB mode: 'test/hardware/corrector' "
74-
"No-DB mode: 'tango://127.0.0.1:8888/test/nodb/corrector#dbase=no'",
70+
doc="Tango device address for the CAMERA settings . "
71+
"DB mode: 'test/detector/camera' "
72+
"No-DB mode: 'tango://127.0.0.1:8888/test/nodb/camera#dbase=no'",
7573
)
76-
7774
testing_mode_bool = device_property(dtype=bool,
7875
default_value=False,
7976
doc="When True - used for running tests, passed in conftest.py")
@@ -198,6 +195,14 @@ def get_spectrum(self, detector_name: str) -> tuple[str, bytes]:
198195

199196
return json.dumps(metadata), raw_bytes
200197

198+
@command(dtype_out=DevEncoded)
199+
def get_camera_image(self) -> tuple[str, bytes]:
200+
"""
201+
get image on the camera
202+
"""
203+
204+
camera = self._detector_proxies.get("camera")
205+
# use this to get params
201206

202207
@command(dtype_out=DevEncoded)#In PyTango, DevEncoded is a special Tango data type designed to send binary data + a small description string together as a single return value.
203208
def get_scanned_image(self) -> tuple[str, bytes]:
@@ -224,18 +229,63 @@ def get_scanned_image(self) -> tuple[str, bytes]:
224229
dwell_time=scan.dwell_time
225230
imsize=scan.imsize
226231

227-
adorned_image = self._acquire_stem_image(imsize, dwell_time, ['haadf'])
232+
image = self._acquire_stem_image(imsize, dwell_time, ['haadf'])
228233

229234
metadata = {
230235
"detector": 'haadf',
231236
"shape": [imsize, imsize],
232-
"dtype": str(adorned_image.dtype),
237+
"dtype": str(image.dtype),
233238
"dwell_time": dwell_time,
234239
"timestamp": time.time(),
235240
# TODO: add metadata from adorned_image.metadata when using real AutoScript
236241
}
237242

238-
return json.dumps(metadata), adorned_image.tobytes()
243+
return json.dumps(metadata), image.tobytes()
244+
245+
246+
@command(dtype_out=DevEncoded)
247+
def get_camera_image(self) -> tuple[str, bytes]:
248+
"""
249+
Acquire a single camera image from the named detector.
250+
251+
Parameters
252+
----------
253+
detector_name:
254+
Name of the detector, e.g. "BM-Ceta". Must match a key in
255+
self._detector_proxies.
256+
257+
Returns
258+
-------
259+
DevEncoded = (json_metadata, raw_bytes)
260+
json_metadata includes: shape, dtype, dwell_time, detector,
261+
timestamp, and any other relevant metadata.
262+
raw_bytes is the flat numpy array bytes; reshape using shape from metadata.
263+
"""
264+
265+
# check active detectors
266+
camera = self._detector_proxies.get("camera")
267+
268+
# Read settings from the detector
269+
exposure_time=camera.exposure_time
270+
imsize=camera.imsize
271+
readout_area=camera.readout_area
272+
273+
image = self._acquire_camera_image(imsize=imsize, exposure_time=exposure_time,
274+
detector='BM-Ceta', readout_area=readout_area)
275+
276+
metadata = {
277+
"detector": 'Ceta',
278+
"shape": [imsize, imsize],
279+
"dtype": str(image.dtype),
280+
"exposure_time": exposure_time,
281+
"timestamp": time.time(),
282+
"readout_area": readout_area,
283+
# TODO: move this metadata packing into the _acquire_camera_image method
284+
# when usingreal AutoScript,to include metadata from adorned_image.metadata
285+
}
286+
287+
return json.dumps(metadata), image.tobytes()
288+
239289

240290
@command(dtype_in=('str',), dtype_out=str)
241291
def get_images(self, detector_names: list[str]) -> str:
@@ -328,11 +378,32 @@ def unblank_beam(self) -> None:
328378
@command(dtype_in=DevFloat)
329379
def set_fov(self, fov):
330380
"""
331-
set the field of view for the next acquisition, [0:1]
381+
set the field of view for the next acquisition
332382
"""
333383
print(fov)
334384
self._set_fov(fov)
335385

386+
@command(dtype_out=DevFloat)
387+
def get_fov(self):
388+
"""
389+
read the field of view for the next acquisition
390+
"""
391+
return self._get_fov()
392+
393+
@command(dtype_in=DevFloat)
394+
def set_screen_current(self, current):
395+
"""
396+
set the screen current in pA
397+
"""
398+
self._set_screen_current(current)
399+
400+
@command(dtype_out=DevFloat)
401+
def get_screen_current(self):
402+
"""
403+
get the screen current in pA
404+
"""
405+
return self._get_screen_current()
406+
336407
@command(dtype_out=DevVarFloatArray)
337408
def get_stage(self):
338409
"""
@@ -359,6 +430,23 @@ def move_stage(self, position):
359430
"""
360431
self._move_stage(position)
361432

433+
@command()
434+
def auto_focus(self):
435+
"""
436+
Run the microscope's autofocus routine.
437+
"""
438+
self._auto_focus()
439+
440+
@command(dtype_in=DevVarFloatArray)
441+
def set_image_shift(self, shift):
442+
"""
443+
Set the image shift to the specified values [x_shift, y_shift].
444+
445+
Parameters
446+
----------
447+
shift: list of two floats [x_shift, y_shift] specifying the desired image shift in meters.
448+
"""
449+
self._set_image_shift(shift)
362450
# ------------------------------------------------------------------
363451
# Internal acquisition helpers
364452
# ------------------------------------------------------------------
@@ -371,6 +459,9 @@ def _acquire_stem_image():
371459
def _acquire_stem_image_advanced():
372460
print("Get image with more flexible settings")
373461
pass
462+
def _acquire_camera_image():
463+
# define in the inherit class
464+
pass
374465

375466
def _place_beam():
376467
# define in the inherit class
@@ -384,6 +475,15 @@ def _unblank_beam():
384475
# define in the inherit class
385476
pass
386477

478+
@abstractmethod
479+
def _set_screen_current():
480+
# define in the inherit class
481+
pass
482+
483+
@abstractmethod
484+
def _get_screen_current():
485+
pass
486+
387487
@abstractmethod
388488
def _move_stage():
389489
# define in the inherit class
@@ -396,6 +496,18 @@ def _get_stage():
396496
@abstractmethod
397497
def _set_fov():
398498
pass
499+
500+
@abstractmethod
501+
def _get_fov():
502+
pass
503+
504+
@abstractmethod
505+
def _auto_focus():
506+
pass
507+
508+
@abstractmethod
509+
def _set_image_shift():
510+
pass
399511
# ----------------------------------------------------------------------
400512
# Server entry point
401513
# ----------------------------------------------------------------------

0 commit comments

Comments
 (0)