docs/add file-loaded at_each_angle hook example (exposure + step size)
CI for csaxs_bec / test (push) Successful in 2m23s
CI for csaxs_bec / test (pull_request) Failing after 2m3s

Adds a worked example to both lamni.md and flomni.md showing a hook
loaded from a file that temporarily bumps tomo_countingtime and
tomo_shellstep every 5th projection within sub-tomogram 2 (tomo_type 1),
restoring both in a finally block -- demonstrating that a hook can
change any scan parameter, not just move devices like the existing
polarizer example. Notes that progress["subtomo"]/["subtomo_projection"]
work the same way for tomo_types 2/3, just with an open-ended
sub-tomogram count there instead of type 1's fixed 8.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
x01dc
2026-07-21 16:38:00 +02:00
co-authored by Claude Sonnet 5
parent 1362a63a85
commit 9198638f9b
2 changed files with 82 additions and 0 deletions
+41
View File
@@ -532,6 +532,47 @@ namespace, same as a cell). **Avoid plain `%run myhooks.py`** (without `-i`): it
executes in a fresh, throwaway namespace each time, so an edit-and-rerun is *not*
picked up automatically and the old version keeps running silently.
**Example — hook loaded from a file, changing exposure and step size for a subset of
projections:** a hook can also read `flomni.progress` and temporarily change any scan
parameter (e.g. `tomo_countingtime`, `tomo_shellstep`) just for specific projections,
then restore it. This example (tomo_type 1) takes a longer exposure at a finer
real-space step every 5th projection within sub-tomogram 2, and a normal projection
everywhere else. `~/hooks/my_hooks.py`:
```python
def high_res_every_5th(flomni, angle):
if flomni.progress["subtomo"] == 2 and flomni.progress["subtomo_projection"] % 5 == 0:
orig_countingtime = flomni.tomo_countingtime
orig_shellstep = flomni.tomo_shellstep
flomni.tomo_countingtime = 0.5 # longer exposure
flomni.tomo_shellstep = 0.2 # finer real-space step
try:
flomni.tomo_scan_projection(angle)
finally:
# restore even if the scan above raises, so a retry or the next
# projection doesn't silently keep running with these settings
flomni.tomo_countingtime = orig_countingtime
flomni.tomo_shellstep = orig_shellstep
else:
flomni.tomo_scan_projection(angle)
```
Load and use it:
```python
import my_hooks
flomni.register_at_each_angle_hook("high_res_every_5th", my_hooks.high_res_every_5th)
flomni.tomo_parameters() # set up the scan parameters as usual
flomni.at_each_angle_hook = "high_res_every_5th" # activate the hook
flomni.tomo_queue_add("subtomo 2 high-res every 5th")
flomni.at_each_angle_hook = None # reset the session default for whatever's queued next
flomni.tomo_queue_execute()
```
`progress["subtomo"]`/`progress["subtomo_projection"]` are populated the same way for
tomo_types 2/3, so the same pattern works there too — just note that unlike type 1's
fixed 8 sub-tomograms, those types have no fixed sub-tomogram count (see
[Tomography](user.ptychography.flomni.tomography) above), so "sub-tomogram 2" means
something different (and open-ended) for them.
**`tomo_scan_projection()` vs `tomo_acquire_at_angle()`:** these are not
interchangeable. `tomo_scan_projection(angle)` always runs a full Fermat-scan
projection; `tomo_acquire_at_angle(angle)` always runs a single-point acquisition.
+41
View File
@@ -299,6 +299,47 @@ namespace, same as a cell). **Avoid plain `%run myhooks.py`** (without `-i`): it
executes in a fresh, throwaway namespace each time, so an edit-and-rerun is *not*
picked up automatically and the old version keeps running silently.
**Example — hook loaded from a file, changing exposure and step size for a subset of
projections:** a hook can also read `lamni.progress` and temporarily change any scan
parameter (e.g. `tomo_countingtime`, `tomo_shellstep`) just for specific projections,
then restore it. This example (tomo_type 1) takes a longer exposure at a finer
real-space step every 5th projection within sub-tomogram 2, and a normal projection
everywhere else. `~/hooks/my_hooks.py`:
```python
def high_res_every_5th(lamni, angle):
if lamni.progress["subtomo"] == 2 and lamni.progress["subtomo_projection"] % 5 == 0:
orig_countingtime = lamni.tomo_countingtime
orig_shellstep = lamni.tomo_shellstep
lamni.tomo_countingtime = 0.5 # longer exposure
lamni.tomo_shellstep = 0.2 # finer real-space step
try:
lamni.tomo_scan_projection(angle)
finally:
# restore even if the scan above raises, so a retry or the next
# projection doesn't silently keep running with these settings
lamni.tomo_countingtime = orig_countingtime
lamni.tomo_shellstep = orig_shellstep
else:
lamni.tomo_scan_projection(angle)
```
Load and use it:
```python
import my_hooks
lamni.register_at_each_angle_hook("high_res_every_5th", my_hooks.high_res_every_5th)
lamni.tomo_parameters() # set up the scan parameters as usual
lamni.at_each_angle_hook = "high_res_every_5th" # activate the hook
lamni.tomo_queue_add("subtomo 2 high-res every 5th")
lamni.at_each_angle_hook = None # reset the session default for whatever's queued next
lamni.tomo_queue_execute()
```
`progress["subtomo"]`/`progress["subtomo_projection"]` are populated the same way for
tomo_types 2/3, so the same pattern works there too — just note that unlike type 1's
fixed 8 sub-tomograms, those types have no fixed sub-tomogram count (see
[Laminography scan](user.ptychography.lamni.laminography) above), so "sub-tomogram 2"
means something different (and open-ended) for them.
**GUI:** the tomo parameters panel has an "At-each-angle hook" dropdown, listing
whatever is currently registered from the CLI (`register_at_each_angle_hook()`) —
the GUI process can't register hooks itself, only select one by name for the job