docs/add file-loaded at_each_angle hook example (exposure + step size)
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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user