Skip to content

Conversation

@uellue
Copy link
Member

@uellue uellue commented Sep 2, 2025

Basics already work; currently adding a ton of tests (WIP)

Next steps after that: Port the previous code to the new model

uellue and others added 2 commits September 2, 2025 17:14
Basics already work; currently adding a ton of tests (WIP)
Simulate point charge displacement vector field in detector coordinates with model
and validate by guessing CoM parameters with `libertem.udf.com.guess_corrections()`
See LiberTEM/LiberTEM#1775 for discussion!

* Undo sign change between column and pixel y coordinates since that was
  ineffective.
* Add tests to confirm correct behavior of the model
* Add additional tests for CoM consistency
* Make inverted sign the expected behavior
Some functions in TemGymCore rely on `PixelsXY` and `CoordsYX` being arrays,
so we use newly introduced single types here
* Extract mapping matrix from model
* Fast forward simulation with that matrix
* Tests WIP
This allows to better simulate a real scan shift, rotation and scale where
the scan changes relative to the object. Previously, the scan coordinaates
vs. simulated object coordinates were fixed and always identical.

Fix handling of semiconv.

Introduce many tests, incl descan error moving aperture outlines.
@uellue
Copy link
Member Author

uellue commented Sep 10, 2025

Suggestion by @DavidLanders95 to improve numerical precision instead of np.inv()

I = jnp.eye(2, dtype=B.dtype)
B_inv = jnp.linalg.solve(B, I)

Alternatively, one can also write down the inverse explicitly since it is not a complicated transformation.

Enable float64 everywhere and manually specify inverses for good measure
WIP, flake8 skipped
* Tests for correction and back-projetion
* Adapt OverfocusUDF to work again

FIXME: How to update the parameters of an UDF without changing it? Important to keep plots alive!
* Update UDF to use new functions
* Adapt notebooks to new parameters
* Update tests
* Simulation now includes semiconv, will be important for descan error optimization
uellue and others added 10 commits September 16, 2025 13:39
The solver converges extremely quickly
The idea is a series of calibration functions to obtain
a fully calibrated parameter set from a number of test measurements.

* Wrapper function to run optax.lbfgs, which works EXTREMELY well on the model.
* High level functions that take meaningful input parameters and starting parameters,
  and return updated parameters. TODO perhaps include the residual in the return value?
* Descan error is WIP, will be based on measurements at different camera lengths.
* Overfocus, rotation and flip TBD, in particular relative to descan error.
One will first have to compensate descan error, and then
adjust other parameters such as flip_y, rotations etc.

This change starts adding functions that allow setting these parameters
while keeping the effect of descan error compensation wrt scan and
detector coordinates the same.

The transformations should be very fast for interactive use. For that reason
they are implemented directly instead of using the solver method.

TODO complete and add tests.
The `adjust_*()` methods allow first compensating the descan error
based on incorrect model parameters, and then adjusting other model
parameters while keeping the descan error compensated, i.e. they change
the descan parameters in such a way that their effect relative to
scan and detector pixel coordinates remains the same.

This is helpful since e.g. calibrating camera length based on known
diffraction angles may need descan compensation if position-averaged
diffraction patterns from a 4D STEM dataset are to be used, and coordinate system
calibration for scan step, scan rotation etc is easier as well if
descan error is removed first.

These methods are implemented as direct transformations rather than using a
solver since they need to be fast enough for immediate response in interactive use.
Also adding a trace() function to reduce boilerplate since we are
just interested in the tracing result from parameters in most cases.

Refactoring all tests WIP
@codecov
Copy link

codecov bot commented Oct 1, 2025

Codecov Report

❌ Patch coverage is 50.33727% with 589 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.36%. Comparing base (4af5ebf) to head (98c2bc0).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/microscope_calibration/ui.py 0.00% 438 Missing ⚠️
...rc/microscope_calibration/common/stem_overfocus.py 66.41% 43 Missing and 1 partial ⚠️
src/microscope_calibration/udf/stem_overfocus.py 58.02% 32 Missing and 2 partials ⚠️
src/microscope_calibration/util/optimize.py 85.37% 31 Missing ⚠️
src/microscope_calibration/common/model.py 89.60% 26 Missing and 3 partials ⚠️
.../microscope_calibration/util/stem_overfocus_sim.py 71.11% 13 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (4af5ebf) and HEAD (98c2bc0). Click for more details.

HEAD has 6 uploads less than BASE
Flag BASE (4af5ebf) HEAD (98c2bc0)
12 6
Additional details and impacted files
@@             Coverage Diff              @@
##              main      #54       +/-   ##
============================================
- Coverage   100.00%   51.36%   -48.64%     
============================================
  Files            5        7        +2     
  Lines          190     1248     +1058     
  Branches        18       72       +54     
============================================
+ Hits           190      641      +451     
- Misses           0      601      +601     
- Partials         0        6        +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

matbryan52 and others added 11 commits October 1, 2025 16:25
Works in principle, but can confuse downstream users.

I guess it could be better to try preserve the original type of the
input parameter to the optimization routine, but later(TM).
Descan error correction for single camera length works!
Currently some issue with the backprojection, details TBD...
* Include relevant projections in GUI
* Introduce corrected picking UDF
* Use stock UDFs where possible instead of re-implementing; remove unnecessary buffers
* Use flip_factor from (-1., 1.) instead of boolean flip_y to aid numerical solving.
  To be tested further! Final user-facing solution TB
* Modify the coordinate refinement to work with reference on both specimen and detector
* Complicate the GUI further

TODO: Tests for new optimization methods
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants