(user.ptychography.lamni)=
# LamNI

LamNI is an instrument for 3D ptychography via ptychographic X-ray computed lamninography (PyXL). The instrument is described in detail [here](https://www.dora.lib4ri.ch/psi/islandora/object/psi:33067).

## How to LamNI 

… a step-by-step guide for _beamline staff and expert users_.

### Sample change and alignment

The access to the sample region is blocked by the flight tube during measurement. To get the flight tube out of the way use  
`lamni.leye_in()`.  
Mount the new sample. The X-ray eye is already in, but the X-ray optics needs to be moved out of the beam path by  
`lamni.loptics_out()`. Potentially a larger area needs to be illuminated to properly see the sample, which can be done by
`open slits`.

#### Coarse axis alignment

The effective position of the axis of rotation shifts with sample thickness or mounting position of the sample along the axis of rotation. The position of the axis of rotation is controlled by user parameters __center__ of the __lsamx__ and __lsamy__ stages. To observe the axis of rotation obtain the position of the Fresnel zone plate on the X-ray eye, possibly in the _ueye gui_ by:  
1. `lamni.lfzp_in()`, move the FZP in
1. `dev.rtx.controller.feedback_disable()`, disable feedback to allow lsam movements
1. `fshopen()`, open the shutter
1. `umv(dev.lsamrot,90)` to rotate the sample. One might observe the center of rotation at 0 and 180 degress.
1. `umvr(dev.lsamx,0.01)` to move lsamx and lsamy such that the center of rotation is at the center of the X-ray beam
1. `dev.lsamx` and `dev.lsamy` will print current position and the center value. Update the center value by  
`dev.lsamx.update_user_parameter({'center':8.69})`  
`dev.lsamy.update_user_parameter({'center':8.69})`  
1. close the shutter: `dev.omnyfsh.fshclose()`

#### X-ray eye alignment

The GUI on the windows computer is used to obtain a coarse sample alignment. Start the alignment process (and clear any previous alignment) by  
`lamni.align.align()`. With LamNI it can be very difficult to follow a region of interest as the sample rotates. Therefore the X-ray shutter will be open during the entire process. Therefore the windows software has to be set on __FORCE__ to continuously update frames and not freeze frames after rotation.  
- run `SPEC_ptycho_align.m` (in matlab, use __force_ptychography = 0__)
- `lamni.align.read_xray_eye_correction()` to read the alignment parameters. The correction is based on sinusoidal fits in x and y direction. The values are computed by
`lamni_compute_additional_correction_xeye_mu(angle)`
- If slits were opened during alignment, close the slits `slits 1 to around 0.3`
- `lamni.leye_out()` remove the X-ray eye and move the flight tube in
- _possibly check slit0wh, idgap_

To only see one frame on the Windows GUI run `lamni.align.update_frame()`

#### Fine alignment

The sample fine alignment can be obtained using ptychography. For this a short laminogram has to be recorded.
- `lamni.tomo_parameters()` adjust the parameters for a coarse scan: A large step size and large FOV. Especially select __FOV offset = 0__ and __number of projections = 96__ (only one sub-laminogram will be recorded).
- `lamni.sub_tomo_scan(1,0)` record one sub-laminogram
- use the corresponding scan numbers in `SPEC_ptycho_align.m`
- Record a last projection for all scans to reconstruct `lamni.tomo_scan_projection(0)` and wait for the reconstructions to be complete
- Run `SPEC_ptycho_align.m` (in Matlab, __force ptycho=1__, and __correct scan numbers__)
- Click the sample position in the Matlab GUI and then load the generated file by, for example
  `lamni.align.read_additional_correction('/sls/X12SA/data/e20632/Data10/cxs_software/ptycho/correction_lamni_um_S05389_lamni_fit.txt')`
- With this alignment a second iteration could be performed. To read the second correction file use `lamni.align.read_additional_correction_2()`

#### Shifting the FOV

- `lamni.align.tomo_fovx/y_offset=value` [mm] will shift the field of view. Perform this adjustment from projections collected at __lsamrot 0 degrees__. 

### Laminography scan

Start the laminography scan by
1. `lamni.tomo_parameters()` adjust the parameters to the desired settings.
1. for test scans run  
`lamni.tomo_scan_projection(angle)`  
`lamni.tomo_reconstruct()`  
1. `lamni.tomo_scan()` to start the lamninography scan

### Tips and Tricks

#### Reset corrections

- `lamni.align.reset_correction()`
- `lamni.align.reset_correction_2()`
- `lamni.align.reset_xray_eye_correction()`

#### Adjusting beam size with feedback running

If the beam size needs to be changed with feedback running, e.g. to switch from near-field to far-field ptychography, following steps can be taken:  
1. `dev.loptz.enable_set=True` to enable loptz movements with feedback running
1. `umvr(dev.lopz,_value_)` move loptz to the desired position. 
1. `lamni._manual_shift_x/y = _value_` correct the stage run out from motion along the optical axis (units of um). The exact value can be checked by comparing feature positions in projections before/after adjusting loptz.
1. Potentially correct the alignment of the OSA

#### BEC tips

Print all global variables `bec.global_vars()`

`dev.lsamx/y.wm` or `dev.lsamx/y` prints a motor position

## How to setup LamNI (software)

This part of the manual describes the software structure in more detail.

### start the realtime feedback loop and BEC with OMNY

The nano-positioning is controlled by a feedback loop running on a real-time linux based computer. With all related hardware connected, this loop has to be started manually.

1. Login to the computer by `ssh control@mpc2680`. The password is written on the physical machine.
1. `cd OMNY/lamni/`
1. `./startLAMNI`

Once the loop has started, it is possible to start bec with the LamNI configuration file.

Loading the LamNI scripts is done by starting bec as
`bec --session lamni`

The scripts can alternatively manually be loaded by  
`from csaxs_bec.bec_ipython_client.plugins.LamNI import LamNI`
`lamni = LamNI(bec)`

Loading the LamNI configuration (this command will load the LamNI configuration only - isolated from the beamline)  
`bec.config.update_session_with_file("/bec/csaxs_bec/csaxs_bec/device_configs/lamni_config.yaml")`

If the realtime system is restarted, BEC will lose communication. To restart:  
`lamni.rt_off()` … then wait a 10 seconds  
`lamni.rt_on()`

### Initialization of the stages

The stages of LamNI are referenced in respect to their endswitches or reference marks. The stages have to be initialized at the beginning of a run or when the Galil motor controller has been reset or restarted. To see the status of the stages following commands are available:

Show the status of all galil controllers (all stepper motors and the UPR rotation stage)  
`dev.lsamx.controller.galil_show_all()`

The same holds true for the Smaract stages which control the OSA position.  Their status can be checked by  
`dev.losax.controller.show_all()`

In case referencing of the LamNI stages is required, run  
`lamni.init.lamni_init_stages()`
This script will first verify that the stages are not in an initialized state, and then reference all stages in a safe way. The user will be warned in case of a potentially risky situation. This mainly involves a collision risk upstream with the exposure box exit window. It might be worth to check clearance prior to calling the init skript.

### Interferometer

The position feedback in LamNI is controlled in closed loop to an interferometric position measurement. To show the signal of the interferometers:
`lamni.show_signal_strength_interferometer()`  
Typical values with proper alignment are  
_TODO_

#### Interferometer feedback commands

- `dev.rtx.feedback_enable_with_reset()`
- `dev.rtx.feedback_disable()`
- `dev.rtx.feedback_enable_without_reset()` *is only used internally by lamni methods
- if reset of angle interferometer is required  
`dev.rtx.feedback_disable_and_even_reset_lamni_angle_interferometer()`
- `dev.rtx.feedback_enable_with_reset()`

_ToDo Feedback status might be helpful. Plus make accessible via lamni.methods…_

### Scanning in 2D and sample alignment

The underlying scan function can be called as  
`scans.lamni_fermat_scan()`

Use `scans.lamni_fermat_scan?`for detailed information. A prerequisite for scanning is a running feedback system.

### GUI tools

During operation the BEC GUI will show the relevant cameras or progress information. To manually switch view TAB completion on 'lamni.lamnigui_' will show all options to control the GUI. Most useful
'lamni.lamnigui_show_progress()' will show the measurement progress GUI
'lamnigui_show_xeyealign()' will show the XrayEye alignment GUI

### X-ray optics alignment

The positions of the optics stages are stored as stage parameters and are thus linked to the configuration file.  
Example: The OSAx “in” position can be reviewed by `dev.losax.user_parameter`  
Update the value by (example "losax", "in") by `dev.losax.update_user_parameter({"in":value})`

`lamni.lfzp_info()` shows info about the available FZPs at the current energy of the beamline. Optional parameter is the photon _energy_ in keV.  
Example: `lamni.lfzp_info(6.2)`

The laser feedback will be disabled and fine alignment lost if foptx/y are moved!

Following functions exist to move the optics in and out, the naming is self-explaining.
- `lamni.lfzp_in()`
- `lamni.loptics_in()`
- `lamni.loptics_out()`
- `lamni.losa_in()`
- `lamni.losa_out()`
- `lamni.lfzp_in()`

