24 KiB
(user.ptychography.omny)=
OMNY
OMNY is a microscope setup for 3D mesurements via ptychographic X-ray computed tomography. The sample enviroment is in ultra-high vacuum and at a sample temperature of 90 K. The instrument is equipped with a load-lock system and allows loading and unloading of samples under cryogenic conditions. The setup is described in detail here. Samples have to be mounted on OMNY pins.
HowTo OMNY
… a step-by-step guide for beamline staff and expert users.
Change to a new sample
The sample storage, shuttles and parking positions are described in detail (here)[user.ptychography.omny.samples].
omny.otransfer_get_sample(0)remove current sample from sample stage. Watch gripper action and be ready to ctrl+c in case something is wrong.
If in doubt check that the correct sample shutte is in the active position by callingomny.otransfer_storage(). The slot can be selected byomny.otransfer_park_slot(slot).omny.otransfer_put_sample(position)put the sample to the selected shuttleomny.otransfer_get_sample(position)get the new sample from a shuttleomny.otransfer_put_sample(0), mount the sample in the sample stage
Alignment of samples
Coarse alignment
After mounting a new sample, the Xray eye will automatically be at the correct position to collect X-ray data. It can also be manually moved to the correct position by omny.oeye_xray_in().
omny.xrayeye_update_frame()obtain a new frame that will be displayed on the Windows computer, OMNY software. If you see your sample already at the approximately correct height, you can skip step 2. Otherwise adjust the height:umvr(dev.osamy, 0.01), attention: unit , move the sample stage relative up (positive) or down (negative) until the sample is approximately vertically centered in xray eye screen. After a move get a new frame byomny.xrayeye_update_frame().omny.xrayeye_alignment_start()start the coarse alignment of the sample by measuring (clicking in the X-ray eye software) the sample position at 0, 45, 90, 135, 180 degrees. Then use the matlab routineSPEC_ptycho_align.mto fit this data.omny.read_alignment_offset()read the generated alignment data.
Fine alignment
After the xrayeyealign, a fine alignment needs to be performed using ptychography. To bypass the fine alignment skip steps.
omny.tomo_parameters()adjust the ptychographic scan parameters for performing an alignment scan. Typically FOVX = FOVX(Xrayeye)+20 mu, shell step = beamsize/2.5, number of projections and tomo mode are ignored in the alignment scans.omny.optics_in()move the Fresnel zone plate and order sorting aperture into position for ptychographic measurements.omny.oeye_out()move the X-ray eye out of the beam path.omny.tomo_alignment_scan()perform the alignment scan. When the first scan is running, switch to a matlab session and runSPEC_ptycho_alignagain. Click left and right. The third click can define the height of the scan, but is not needed and ignored by default. The widest horizontal field of view will be printed at the end of the matlab session.omny.read_alignment_offset()Load alignment parameters calculated in matlab.
Tomographic Measurement
Now that the sample is aligned, the tomographic measurement can be performed.
omny.tomo_parameters()adjust the scan parameters for the tomographic scan. This includes the parameters for ptychographic scans of projections plus the strategy for angular sampling. The vertical shift adjusts the field of view, up (positive) or down (negative). After adjusting the numbers, type againomny.tomo_parameters()and verify that they are correct.omny.tomo_scan_projection(angle)perform a ptychographic scan at the rotation angle , e.g. at zero degrees. When happy with the scan parameters launch the tomographic measurement byomny.tomo_scan().- Before changing to the next sample sample, verify that all subtomograms were completely acquired using the
tomo_recons matlabscript.
If something went wrong…
Special cases:
If the gripper or another stage got stuck during transfer. Ctrl+c and then
umv(dev.otransy, -1.5) followed by
omny._otransfer_gripper_to_park_z(), which will move the gripper to its parking position.
If the above fails for the vertical movement of the gripper Ctrl+C.
Try moving up and down a bit umvr(dev.otransy,0.5), umvr(dev.otransy,-0.5), potentially requires a ctrl+C again if stuck.
Then, umv(dev.ootransy,-1.5) followed by
omny._otransfer_gripper_to_park_z(), which will move the gripper to its parking position.
If this error happens after a sample was mounted or unmounted, it is important to chech that the sample storage is correct omny.otransfer_storage().
(user.ptychography.omny.samples)=
Sample storage and transfer
Following commands will provide help within BEC:
omny.otransfer_help()print help related to sample transferdev.omny_samples.help()print help related to sample storage
Managing sample storage
The sample holders used are OMNY pins. These are instsalled in sample transfer shuttles, which can load up to six pins. These shuttles are transferred via a vacuum load lock to the vacuum chamber. The loading procedure can be handled at room temperature or under cryogenic conditions.
The thee shuttles that exist are named “A”, “B”, “C”. The pin positions within a shuttle are number 1 to 6 according to the following sketch:
OMNY sample shuttle
In addition to the shuttle positions, there are fixed positions in OMNY which have numbers larger than 10. Such fixed positions are treated as system “O”.
Each shuttle can be placed in a parking slot in OMNY. The parking slots are numbered as displayed below (oparkz slot). Slots 1 and 2 are at room temperature. Slots 3 to 6 are at cryogenic temperature.
OMNY parking station
The status of the sample storage has to be correct in BEC. This means that the status of OMNY pins within OMNY ("O") as well as the shuttles has to be correct, the pin status within the shuttles ("A", "B", "C"), as well as the status of the shuttles within the OMNY parking.
This loading status is handled via a OMNY samples device: dev.omny_samples
Within the BEC client session dev.omny_samples.help() will display all required commands with a short explanation.
To get an overview use dev.omny_samples.show_all() or omny.otransfer_storage()
Modify a slot position of systems "A", "B", "C", "O":
dev.omny_samples.unset_sample_slot('system',position) free a sample position.
dev.omny_samples.set_sample_slot('system',position,'name') set a sample position. The sample has to get a name.
There are two special sample slots:
If a sample is in the gripper and the information has to be manually changed use
dev.omny_samples.unset_sample_in_gripper()
dev.omny_samples.set_sample_in_gripper('name')
In the case of the sample stage position, the commands are
dev.omny_samples.unset_sample_in_samplestage()
dev.omny_samples.set_sample_in_samplestage('name')
The shuttles are mounted in the parking station. Typically oparkz slot 3 is used for shuttle A, slot 4 for shuttle B, slot 5 for shuttle C. If that status has to be modified, the following commands can be used:
dev.omny_samples.unset_shuttle_slot(slot_nr)
dev.omny_samples.set_shuttle_slot(container, slot_nr)
Here is an example: dev.omny_samples.set_shuttle_slot('A',2)
Sample transfer
Once the sample places are set correctly and checked by using omny.otransfer_storage(), the following commands are available for sample change. To pick a sample from a parking slot, the parking slot stage has to be moved to the correct parking slot position. If a parking position is active, this information is displayed in sample storage overview.
| Command | Explanation |
|---|---|
omny.otransfer_help() |
print a brief help |
omny.otransfer_park_slot(slot) |
drive the parking station to place for sample transfer from |
omny.otransfer_park_loadlock_slot(slot) |
drive the parking station to load with the loadlock |
omny.otransfer_get_sample(position) |
pick with the gripper from |
omny.otransfer_put_sample(position) |
put with the gripper to |
For transfer the sample stage is refered to as position 0.
Advanced commands ... in case something goes wrong
| Command | Explanation |
|---|---|
omny._otransfer_gripper_up() |
move gripper up |
omny._otransfer_gripper_to_park_z() |
move gripper up and to parking position |
omny._otransfer_ensure_shuttle_closed() |
close shuttle of parking station |
omny._oshield_ST_close() |
close shield of sample stage |
When closing a shuttle of the shield, the gripper will be moved to the parking position prior closing.
Status of OMNY
To see the status of the insrument, following commands can be used. Most of the components mentioned below are controlled via devices with naming starting with omny. TAB completion on dev.omny can be a quick way to find the commands.
Cameras
During operation the BEC GUI will show the relevant cameras or progress information. To manually switch view TAB completion on omny.omnygui_ will show all options to control the GUI. Most useful
omny.omnygui_show_omnycam_parking()omny.omnygui_show_omnycam_samplestage()omny.omnygui_show_progress()
Vacuum status
The status of the vacuum system of OMNY can be displayed by omny.vcs_show_all().
omny.vcs_valves_in_measurement_position() will report if all valves are in the correct position for X-ray beam to enter and propagate to the detector.
Temperatures
The status of all temperature measurements can be displayed by omny.temperatures_show_all()
It will display a table for the instrument and sample environment.
Example in warm state
| Channel | Name | Temperature | Setpoint | Unit | AlarmState |
|---|---|---|---|---|---|
| 8 | XEye Chamber | 22.60 | degC | ||
| 9 | Kuehlsystem RT ZufOSA | 22.80 | 23.00 | degC | |
| 10 | OSA_HaltZul_517 | 384.15 | K | ||
| 16 | XEye Air | 22.60 | degC | ||
| 17 | SampleShield_RT_440 | 23.00 | 23.00 | degC | |
| 18 | DeltaA_RT | 26.00 | 26.00 | degC | |
| 19 | DeltaB_RT | 26.00 | 26.00 | degC | |
| 20 | DeltaC_RT | 26.00 | 26.00 | degC | |
| 21 | Haube_ST_RT | 23.00 | 23.00 | degC | |
| 22 | Delta_Basisplatte | 21.40 | degC | ||
| 23 | InterfBridge | 22.50 | degC | ||
| 24 | XEye Cam | 23.30 | degC | ||
| 25 | OSA_HSupp_RT_403 | 25.00 | 25.00 | degC | |
| 27 | OSA_Supp_RT_404 | 25.00 | 25.00 | degC | |
| 28 | ST_Shield_1 | 384.15 | K | Alarm | |
| 29 | ST_Shield_2 | 384.15 | K | Alarm | |
| 30 | OSA_CoolConn_407 | 384.15 | K | Alarm | |
| 31 | OSA_Holder_406 | 384.15 | K | Alarm | |
| 35 | Gripper_Halter_460 | 25.40 | 25.00 | degC | |
| 36 | Gripper_Flex_A | -8999.00 | 25.00 | degC | Alarm |
| 37 | Gripper_Flex_B | 24.60 | 25.00 | degC | |
| 38 | Gripper_A | 384.15 | K | Alarm | |
| 39 | Gripper_B | 384.15 | K | Alarm | |
| 41 | FZP | 30.00 | 30.00 | degC | |
| 42 | Park_RT_A | 25.10 | 25.00 | degC | |
| 44 | Park_RT_B | 25.30 | 25.00 | degC | |
| 45 | BaseBlock | 21.00 | degC | ||
| 46 | Park_Cryo_R | 384.15 | K | Alarm | |
| 47 | Park_Cryo_L | 384.15 | K | Alarm |
OMNY Cryo Temperature Controller
| Channel | Name | Temperature | Setpoint | Unit |
|---|---|---|---|---|
| 1 | ChanA | 297.95 | 300.00 | K |
| 2 | ChanB | 297.61 | 299.00 | K |
| 3 | ChanC | 0.00 | 0.00 | K |
| 4 | ChanD | 294.47 | 0.00 | K |
| Cryo controller is running in open loop. |
ChanA and ChanD are sample temperatures, and ChanB is the bottom of the cryo link, meaning the head of the cryostat.
Dewar
The status of the dewar and nitrogen flow can be displayed by omny.dewar_show_all()
How to setup OMNY (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.
- Login to the computer by
ssh control@mpc3217. The password is "engine". cd OMNY/OMNY/./startOMNY
Once the loop has started, it is possible to start bec with the OMNY configuration file.
Loading the OMNY configuration (this command will load the OMNY configuration only - isolated from the beamline)
bec.config.update_session_with_file("/bec/csaxs_bec/csaxs_bec/device_configs/flomni_config.yaml")
Loading the OMNY scripts
from csaxs_bec.bec_ipython_client.plugins.omny import OMNY
omny = OMNY(bec)
If the realtime system is restarted, BEC will lose communication. To restart:
omny.rt_off() … then wait a 10 seconds
omny.rt_on()
Initialization of the stages
The stages of OMNY are referenced in respect to their endswitches and reference marks. The stages have to be initialized at the beginning of a run or when the Galil motor controllers have been reset or restarted. To see the status of the stages following commands are available:
Show the status of all galil controllers (all stepper motor and rotation stage)
dev.osamx.controller.galil_show_all()
In case referencing of the OMNY stages is required, run
omny.omny_init_stages(autoconfirm, autoretry)
The process will regularly prompt the user for OK. At safe states this can be automatically done by setting autoconfirm=1.
In case referencing fails, another attempt will be made after prompting the user. This can also be automatically done for certain number of times using the parameter autoretry.
We typically use
omny.omny_init_stages(autoconfirm=1, autoretry=2)
Interferometer
If the realtime system is restarted, BEC will lose communication. To restart:
omny.rt_off() … then wait a 10 seconds
omny.rt_on()
To show the signal of the interferometers:
omny.show_signal_strength_interferometer()
Typical values with proper alignment, sample stage at the measurement position and laser tracker running are
| Channel | Name | Value |
|---|---|---|
| 1 | OSA FZP Y | 5500 |
| 2 | ST OSA Y | 2500 |
| 3 | OSA FZP X | 4000 |
| 4 | ST OSA X | 9000 |
| 5 | Angle | 2500 |
Laser tracker commands
The horizontal interferometer is built according to the tracking interferometer. The tracker can be controlled by following commands. During commissioning of the setup it is worthy to check the status, but during general operation these commands should not be required.
omny.laser_tracker_show_all()omny.laser_tracker_on()omny.laser_tracker_off()
When the PSD signal of the tracker (PSD not signalstrength!) is too low, enabling the laser tracker will not be successful. One can use omny.interferometer_tweak_otrack() to manually tweak the coarse stages of the tracker. Once signal is reached the tracker can be enabled. This should only be required during commissioning of OMNY.
Interferometer alignment
Several mirrors in OMNY are motorized. Aligning the interferometer can thus be done via software. To enter alignment mode use
omny.interferometer_tweaking()
Select the channel by using number keys 1 to 7 and the arrow keys to tweak.
The tweaking mode can be exited by pressing q to quit.
Some mirrors are regularly automatically aligned, such as the horizontal mirror of the OSA. This automatic alignment can also be manually executed by omny.omny_interferometer_align_tracking()
Interferometer feedback commands
The closed loop control of the Piezo stages can be controlled by
omny.feedback_enable_with_reset()
There is also an enable without reset, which is used during tomography scans, when using coarse stages to increase the scan range. It should not be required to use manually.omny.feedback_disable()omny.feedback_status()
X-ray optics alignment, near-field and far-field ptychography
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.oosax.user_parameter
Update the value by (example "oosax", "in") by dev.oosax.update_user_parameter({"in":value})
For near-field and far-field separate optics parameters are stored. Example:
dev.oosax.user_parameter returns {'near_field_in': 3.2044, 'far_field_in': 3.022}
Update the value by (example "oosax", "near_field_in")
dev.oosax.update_user_parameter({"near_field_in":value})
The global variable omny.near_field controls whether near- or far-field settings are used. To switch omny.near-field=False or omny.near-field=True.
omny.ofzp_info() shows info about the available FZPs at the current energy of the beamline. Optional parameter energy in keV to get values at a different energy.
Example: omny.ofzp_info(6.2)
Laser feedback will be disabled and thus fine alignment lost if commands are used that move optics stages!
Following functions exist to move the optics in and out, with self-explaining naming.
omny.optics_in()omny.ofzp_in()omny.ofzp_out()omny.oosa_in()omny.oosa_out()omny.oosa_move_out_of_shield()
OMNY Fermat scan
The basic scan function can be called by scans.omny_fermat_scan() and offers a detailed doc string for further details (scans.omny_fermat_scan?). A prerequisite for scanning is a running feedback system. The scan has following parameters.
| Parameters | |
|---|---|
| fovx (float) | Fov in the piezo plane (i.e. piezo range). Max 200 um |
| fovy (float) | Fov in the piezo plane (i.e. piezo range). Max 100 um |
| cenx (float) | center position in x |
| ceny (float) | center position in y |
| exp_time (float) | exposure time |
| step (float) | stepsize |
| zshift (float) | shift in z |
| angle (float) | rotation angle (will rotate first) |
| corridor_size (float) | corridor size for the corridor optimization. Default 3 um |
Example:
scans.omny_fermat_scan(fovx=20, fovy=25, cenx=0.02, ceny=0, zshift=0, angle=0, step=0.5, exp_time=0.01)
Overview of the alignment steps
There are several corrections applied to maintain the sample in the FOV:
- Mirror calibration
- X-ray eye alignment
- Ptychography fine alignment (improvement of the X-ray eye alignment step)
- Vertical shifts from tomography reconstruction (for very small vertical FOV)
XrayEye and sample alignment
Within a usual work-flow the movement of the X-ray eye is mostly moved automatically to the correct position. For manual movements use
| Command | Explanation |
|---|---|
| omny.oeye_xray_in() | move to the fluorescense microscope in |
| omny.oeye_cam_in() | move the camera showing the samplestage from downstream in |
| omny.oeye_out() | move out, X-rays can reach the X-ray detector |
The in and out positions are stored as user parameters in the stage definition. Get the values by
dev.oeyex.user_parameter
dev.oeyey.user_parameter
Update the values by, example for oeyex and in position
dev.oeyex.update_user_parameter({"xray_in":value})
To refresh the frame of the xray eye windows software
omny.xrayeye_update_frame()
To start the xray eye alignment (and clear any previous alignment)
omny.xrayeye_alignment_start()
To load the fit parameters from directory dir_path computed by SPEC_ptycho_align.m in Matlab run
omny.read_alignment_offset(dir_path='',setup="omny")
To load from a specific directory, specify it as parameter. Example:
omny.read_alignment_offset(dir_path="/bec/align",setup="omny")
The loading routine uses default values for the vertical alignment for setup. This behavior can be changed (e.g. for getting new default values) by the parameter use_vertical_default_values=False.
At each projection, the angular dependent is computed by
omny.get_alignment_offset(angle), with angle in degrees.
The alignment can be cleared by
omny.reset_tomo_alignment_fit()
Fine alignment
The alginment obtained by the X-ray eye can be refinde by recording ptychography projections at 45 deg. intervals. For this, adjust the tomo parameters by
omny.tomo_parameters()
Next, run the alignment scan by
omny.tomo_alignment_scan()
Reconstruct the scan and use SPEC_ptycho_align.m to obtain improved fit parameters. The new parameters can be loaded by
omny.read_alignment_offset()
For a very tight vertical field of view, a fine vertical alignment based on outputs generated from early tomography reconstructions can be used. A corresponding file can be generated by the tomography reconstruction script and can be loaded by the following two methods:
omny.read_additional_correction_y()
omny.read_additional_correction_y2()
One important note: The first method is by default loading a mirror correction file automatically. If the tomogram is using that data, do not overwrite it, use the secondary correction instead.
The scan offsets are computed at each projection by
omny.compute_additional_correction_y(angle)
omny.compute_additional_correction_y2(angle)
The additional correct can be reset by
omny.reset_correction()
It will automatically load the default mirror correction file as primary correction! To reset and not load any correction, which might be useful to obtain a new default correction file, run
omny.reset_correction(use_default_correction=False)
Scanning of projections
At any stage of the alignment process it is possible to scan a projection.
Define the scan parameters by omny.tomo_parameters()
Run a scan at angle (in degrees, 0 to 180) by omny.tomo_scan_projection(angle)
Tomography
The tomo parameters have to be set by
omny.tomo_parameters()
Once satisfied with the alignment, the tomography scan can be started by
omny.tomo_scan()
Three modes for angular sampling are implemented and they have different optional parameters for the tomo_scan method:
| tomography mode | parameters and defaults |
|---|---|
| 2 sub-tomograms | subtomo_start=1, start_angle=None |
| Golden ratio tomography (sorted in bunches) | projection_number=None |
| Equally spaced with golden starting angle | projection_number=None |
The parameters can be used to restart an interrupted acquisition. In case of eight equally spaced sub-tomograms, an individual sub tomogram can be scanned by flomni.sub_tomo_scan(subtomo_number, start_angle). If the start angle is not specified, it will be computed depending on the subtomo_number, which is ranging from 1 to 2.
Mechanical wear is an issue with lifetime of dry vacuum stages. Thus for standard acquisitions that do not have VERY strong arguments that require a different mode, two sub-tomograms has to be performed.