Coverage for src/pytribeam/constants.py: 100%
86 statements
« prev ^ index » next coverage.py v7.6.1, created at 2026-09-09 18:27 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2026-09-09 18:27 +0000
1#!/usr/bin/python3
2"""Package-wide constants and unit conversion factors.
4This module centralizes shared constants used throughout `pytribeam`, including
5software version identifiers, logging dataset names and dtypes, beam and detector
6tolerances, laser and FIB defaults, stage limits, mapping defaults, and test
7configuration values.
9It also defines the unit conversion factors used by the package. Most modules
10should import conversion factors from `Conversions` rather than hard-coding
11numeric scale factors.
13## Typical usage
15```python
16from pytribeam.constants import Constants, Conversions
18width_m = width_um * Conversions.UM_TO_M
19current_a = current_pa * Conversions.PA_TO_A
21if dwell_ratio > Constants.beam_dwell_tol_ratio:
22 ...
23```
25## Main objects
27- `Constants`: package-wide configuration constants, default values, hardware
28 limits, logging dataset definitions, and test configuration values.
29- `Conversions`: scalar conversion factors for length, time, voltage, current,
30 and angle units.
32## Unit conventions
34The package uses explicit field names to indicate user-facing units, for example
35`x_mm`, `width_um`, `current_pa`, `dwell_us`, and `rotation_deg`. Values passed
36to microscope APIs are converted internally as needed using `Conversions`.
38Common conversion factors include:
40| Conversion | Factor |
41| --- | ---: |
42| micrometers to meters | `Conversions.UM_TO_M` |
43| millimeters to meters | `Conversions.MM_TO_M` |
44| microseconds to seconds | `Conversions.US_TO_S` |
45| kilovolts to volts | `Conversions.KV_TO_V` |
46| picoamperes to amperes | `Conversions.PA_TO_A` |
47| degrees to radians | `Conversions.DEG_TO_RAD` |
49> **Warning**
50>
51> Constants in this module are used across the package. Update them carefully and
52> verify downstream behavior, especially for values related to hardware limits,
53> pattern generation, stage motion, and file/log formats.
55<hr style="height: 12px; background-color: #333; border: none;">
56"""
58__all__ = [
59 "Constants",
60 "Conversions",
61]
63# Default python modules
64import math
65from typing import NamedTuple
67import numpy as np
68import h5py
70# import pytribeam.utilities as ut
71import pytribeam.types as tbt
74class Constants(NamedTuple):
75 """
76 A NamedTuple containing various constants used throughout the software.
78 ## Attributes
80 - `module_short_name` (`str`): Short name of the module.
81 - `autoscript_version` (`str`): Version of the AutoScript software.
82 - `laser_api_version` (`str`): Version of the Laser API.
83 - `yml_schema_version` (`str`): Maximum supported version of the YAML schema.
84 - `logfile_extension` (`str`): Extension for log files.
85 - `settings_dataset_name` (`str`): Name of the dataset for experiment settings.
86 - `pre_position_dataset_name` (`str`): Name of the dataset for position before an event.
87 - `post_position_dataset_name` (`str`): Name of the dataset for position after an event.
88 - `pre_lasing_dataset_name` (`str`): Name of the dataset for laser power before an event.
89 - `post_lasing_dataset_name` (`str`): Name of the dataset for laser power after an event.
90 - `specimen_current_dataset_name` (`str`): Name of the dataset for specimen current.
91 - `settings_dtype` (`np.dtype`): Data type for settings dataset.
92 - `position_dtype` (`np.dtype`): Data type for position dataset.
93 - `laser_power_dtype` (`np.dtype`): Data type for laser power dataset.
94 - `specimen_current_dtype` (`np.dtype`): Data type for specimen current dataset.
95 - `beam_types` (`list of str`): Types of beams (electron/ion).
96 - `voltage_tol_ratio` (`float`): Tolerance ratio for voltage.
97 - `current_tol_ratio` (`float`): Tolerance ratio for current.
98 - `beam_dwell_tol_ratio` (`float`): Tolerance ratio for beam dwell time.
99 - `default_color_depth` (`tbt.ColorDepth`): Default color depth.
100 - `scan_resolution_limit` (`tbt.Limit`): Limit for scan resolution.
101 - `contrast_brightness_tolerance` (`float`): Tolerance for contrast and brightness.
102 - `image_scan_rotation_for_laser_deg` (`float`): Image scan rotation for laser in degrees.
103 - `laser_objective_limit_mm` (`tbt.Limit`): Limit for laser objective in millimeters.
104 - `laser_objective_retracted_mm` (`float`): Safe retracted position for laser objective in millimeters.
105 - `laser_objective_tolerance_mm` (`float`): Tolerance for laser objective in millimeters.
106 - `laser_beam_shift_tolerance_um` (`float`): Tolerance for laser beam shift in micrometers.
107 - `laser_energy_tol_uj` (`float`): Tolerance for laser energy in microjoules.
108 - `laser_delay_s` (`float`): Delay for measuring power and setting pulse divider/energy in seconds.
109 - `default_fib_rectangle_pattern` (`tbt.FIBRectanglePattern`): Default FIB rectangle pattern.
110 - `stream_pattern_scale` (`int`): Scale for stream pattern.
111 - `stream_pattern_y_shift` (`int`): Y-axis shift for stream pattern.
112 - `stream_pattern_base_dwell_us` (`float`): Base dwell time for stream pattern in microseconds.
113 - `stage_move_delay_s` (`float`): Delay for stage movement in seconds.
114 - `stage_move_attempts` (`int`): Number of attempts for stage movement.
115 - `default_stage_tolerance` (`tbt.StageTolerance`): Default stage tolerance.
116 - `slice_thickness_limit_um` (`tbt.Limit`): Limit for slice thickness in micrometers.
117 - `pre_tilt_limit_deg_generic` (`tbt.Limit`): Generic limit for pre-tilt in degrees.
118 - `pre_tilt_limit_deg_non_Z_sectioning` (`tbt.Limit`): Limit for pre-tilt in non-Z sectioning in degrees.
119 - `home_position` (`tbt.StagePositionUser`): Home position of the stage.
120 - `rotation_axis_limit_deg` (`tbt.Limit`): Limit for rotation axis in degrees.
121 - `detector_collisions` (`list of list of tbt.DetectorType`): List of detector collisions.
122 - `min_map_time_s` (`int`): Minimum mapping time in seconds.
123 - `specimen_current_hfw_mm` (`float`): Specimen current high field width in millimeters.
124 - `specimen_current_delay_s` (`float`): Delay for specimen current in seconds.
125 - `test_hardware_movement` (`bool`): Flag for testing hardware movement.
126 - `offline_machines` (`list of str`): List of offline machines.
127 - `microscope_machines` (`list of str`): List of microscope machines.
128 - `default_column_count` (`int`): Default number of columns for printing large lists of values.
129 - `default_column_width` (`int`): Default width of columns in characters.
130 """
132 # Software versions
133 module_short_name = "pyTriBeam"
134 autoscript_version = "4.8.1"
135 laser_api_version = "2.2.1"
136 yml_schema_version = "1.0" # max supported version #TODO convert to float
138 # Log file constants
139 logfile_extension = ".h5"
140 settings_dataset_name = "Experiment Settings"
141 pre_position_dataset_name = "Position Before"
142 post_position_dataset_name = "Position After"
143 pre_lasing_dataset_name = "Laser Power Before"
144 post_lasing_dataset_name = "Laser Power After"
145 specimen_current_dataset_name = "Specimen Current"
146 settings_dtype = np.dtype(
147 [
148 ("Slice", "<u4"),
149 ("Step", "<u4"),
150 ("Config File", h5py.special_dtype(vlen=str)),
151 ("Timestamp", h5py.special_dtype(vlen=str)),
152 ("UNIX time", "<u8"),
153 ]
154 )
155 position_dtype = np.dtype(
156 [
157 ("Slice", "<u4"),
158 ("X", "<f8"),
159 ("Y", "<f8"),
160 ("Z", "<f8"),
161 ("T", "<f8"),
162 ("R", "<f8"),
163 ("Timestamp", h5py.special_dtype(vlen=str)),
164 ("UNIX time", "<u8"),
165 ]
166 )
167 laser_power_dtype = np.dtype(
168 [
169 ("Slice", "<u4"),
170 ("Power", "<f8"),
171 ("Timestamp", h5py.special_dtype(vlen=str)),
172 ("UNIX time", "<u8"),
173 ]
174 )
175 specimen_current_dtype = np.dtype(
176 [
177 ("Slice", "<u4"),
178 ("Current", "<f8"),
179 ("Timestamp", h5py.special_dtype(vlen=str)),
180 ("UNIX time", "<u8"),
181 ]
182 )
184 # Beam (electron/ion) constants
185 beam_types = [
186 "electron",
187 "ion",
188 ]
189 voltage_tol_ratio = 0.05
190 current_tol_ratio = 0.05
191 beam_dwell_tol_ratio = 0.001
192 default_color_depth = tbt.ColorDepth.BITS_8
193 scan_resolution_limit = tbt.Limit(min=12, max=65535) # max of 2^16 - 1
195 # Detector constants
196 contrast_brightness_tolerance = 1.0e-4 # range is 0 to 1
198 # Laser constants
199 image_scan_rotation_for_laser_deg = 180.0 # requirement by TFS for laser milling
200 laser_objective_limit_mm = tbt.Limit(min=2.0, max=29.0)
201 laser_objective_retracted_mm = 2.5 # safe retracted position
202 laser_objective_tolerance_mm = 0.005
203 laser_beam_shift_tolerance_um = 0.5
204 laser_energy_tol_uj = 0.05
205 laser_delay_s = 3.0 # for measuring power and settings pulse divider/energy
207 # FIB constants
208 default_fib_rectangle_pattern = tbt.FIBRectanglePattern(
209 center_um=tbt.Point(
210 x=0.0,
211 y=0.0,
212 ),
213 width_um=10.0,
214 height_um=5.0,
215 depth_um=0.1,
216 scan_direction=tbt.FIBPatternScanDirection.TOP_TO_BOTTOM,
217 scan_type=tbt.FIBPatternScanType.RASTER,
218 )
219 stream_pattern_scale = (
220 2**12
221 ) # upscales fib image to this value / width for higher density of points
222 stream_pattern_y_shift = int(
223 2**16 / 6
224 ) # for correct centering of stream patterns, with scan control available only at 16 bit depth, must account for 3:2 aspect ratio for image length:width and cut off half the discrepancy on both top and bottom. Full equation: 2^16(1-(2/3)) / 2
225 stream_pattern_base_dwell_us = 0.025 # can be 25 or 100 ns, defaults to 25ns
227 # Stage constants
228 stage_move_delay_s = 0.5
229 stage_move_attempts = (
230 2 # generally higher accuracy on movement with 2 attempts for non-piezo stages
231 )
232 default_stage_tolerance = tbt.StageTolerance(
233 translational_um=0.5,
234 angular_deg=0.02,
235 )
236 slice_thickness_limit_um = tbt.Limit(min=0.0, max=30.0) # TODO revert to 0.5 micron
237 pre_tilt_limit_deg_generic = tbt.Limit(min=-60.0, max=60.0)
238 pre_tilt_limit_deg_non_Z_sectioning = tbt.Limit(min=0.0, max=0.0)
239 home_position = tbt.StagePositionUser(
240 x_mm=0.0, y_mm=0.0, z_mm=0.0, r_deg=0.0, t_deg=0.0
241 )
242 rotation_axis_limit_deg = tbt.Limit(
243 min=-180.0, max=180.0
244 ) # used as right-open internal: 180.0 is not valid and should be converted to -180.0
245 detector_collisions = [
246 [tbt.DetectorType.CBS, tbt.DetectorType.EDS],
247 [tbt.DetectorType.CBS, tbt.DetectorType.EBSD],
248 ]
250 # Mapping (EBSD/EDS) constants
251 min_map_time_s = 30
252 specimen_current_hfw_mm = 1.0e-3
253 specimen_current_delay_s = 2.0
255 # Test suite constants
256 test_hardware_movement = True
257 offline_machines = [
258 "S1099177",
259 "S1125518",
260 "daasplus2130w11",
261 "daasplus2131w11",
262 "daasplus2132w11",
263 "daasplus2134w11",
264 ]
265 microscope_machines = ["HPN125v-MPC", "HPN276-MPC"]
267 # error message display constants
268 default_column_count = 3 # for printing large lists of values
269 default_column_width = 20 # characters
272class Conversions(NamedTuple):
273 """
274 A NamedTuple containing various conversion constants for length, time, voltage, current, and angle.
276 ## Attributes
278 - `MM_TO_M` (`float`): Conversion factor from millimeters to meters.
279 - `UM_TO_M` (`float`): Conversion factor from micrometers to meters.
280 - `M_TO_MM` (`float`): Conversion factor from meters to millimeters.
281 - `M_TO_UM` (`float`): Conversion factor from meters to micrometers.
282 - `UM_TO_MM` (`float`): Conversion factor from micrometers to millimeters.
283 - `MM_TO_UM` (`float`): Conversion factor from millimeters to micrometers.
284 - `US_TO_S` (`float`): Conversion factor from microseconds to seconds.
285 - `S_TO_US` (`float`): Conversion factor from seconds to microseconds.
286 - `S_TO_NS` (`float`): Conversion factor from seconds to nanoseconds.
287 - `NS_TO_S` (`float`): Conversion factor from nanoseconds to seconds.
288 - `US_TO_NS` (`float`): Conversion factor from microseconds to nanoseconds.
289 - `NS_TO_US` (`float`): Conversion factor from nanoseconds to microseconds.
290 - `KV_TO_V` (`float`): Conversion factor from kilovolts to volts.
291 - `V_TO_KV` (`float`): Conversion factor from volts to kilovolts.
292 - `UA_TO_A` (`float`): Conversion factor from microamperes to amperes.
293 - `NA_TO_A` (`float`): Conversion factor from nanoamperes to amperes.
294 - `PA_TO_A` (`float`): Conversion factor from picoamperes to amperes.
295 - `A_TO_UA` (`float`): Conversion factor from amperes to microamperes.
296 - `A_TO_NA` (`float`): Conversion factor from amperes to nanoamperes.
297 - `A_TO_PA` (`float`): Conversion factor from amperes to picoamperes.
298 - `PA_TO_NA` (`float`): Conversion factor from picoamperes to nanoamperes.
299 - `PA_TO_UA` (`float`): Conversion factor from picoamperes to microamperes.
300 - `NA_TO_UA` (`float`): Conversion factor from nanoamperes to microamperes.
301 - `NA_TO_PA` (`float`): Conversion factor from nanoamperes to picoamperes.
302 - `UA_TO_NA` (`float`): Conversion factor from microamperes to nanoamperes.
303 - `UA_TO_PA` (`float`): Conversion factor from microamperes to picoamperes.
304 - `DEG_TO_RAD` (`float`): Conversion factor from degrees to radians.
305 - `RAD_TO_DEG` (`float`): Conversion factor from radians to degrees.
306 """
308 # length
309 MM_TO_M = 1.0e-3
310 UM_TO_M = MM_TO_M / 1000.0
311 M_TO_MM = 1.0 / MM_TO_M
312 M_TO_UM = 1.0 / UM_TO_M
313 UM_TO_MM = UM_TO_M * M_TO_MM
314 MM_TO_UM = 1.0 / UM_TO_MM
316 # time
317 US_TO_S = 1.0e-6
318 S_TO_US = 1.0 / US_TO_S
319 S_TO_NS = S_TO_US * 1000.0
320 NS_TO_S = 1.0 / S_TO_NS
321 US_TO_NS = US_TO_S * S_TO_NS
322 NS_TO_US = 1.0 / US_TO_NS
324 # voltage
325 KV_TO_V = 1.0e3
326 V_TO_KV = 1.0 / KV_TO_V
328 # current
329 UA_TO_A = 1.0e-6
330 NA_TO_A = UA_TO_A / 1000.0
331 PA_TO_A = NA_TO_A / 1000.0
332 A_TO_UA = 1.0 / UA_TO_A
333 A_TO_NA = 1.0 / NA_TO_A
334 A_TO_PA = 1.0 / PA_TO_A
335 PA_TO_NA = PA_TO_A * A_TO_NA
336 PA_TO_UA = PA_TO_A * A_TO_UA
337 NA_TO_UA = NA_TO_A * A_TO_UA
338 NA_TO_PA = 1.0 / PA_TO_NA
339 UA_TO_NA = 1.0 / NA_TO_UA
340 UA_TO_PA = 1.0 / PA_TO_UA
342 # angle
343 DEG_TO_RAD = math.pi / 180.0 # convert degrees to radians
344 RAD_TO_DEG = 180.0 / math.pi