Coverage for src/pytribeam/constants.py: 6%
85 statements
« prev ^ index » next coverage.py v7.6.1, created at 2026-06-16 18:30 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2026-06-16 18:30 +0000
1#!/usr/bin/python3
2"""
3Constants Module
4================
6This module contains various constants and conversion factors used throughout the software. The constants are organized into two main classes: `Constants` and `Conversions`.
8Classes
9-------
10Constants : NamedTuple
11 A NamedTuple containing various constants related to software versions, log files, beam parameters, detector parameters, laser parameters, FIB parameters, stage parameters, mapping parameters, test suite parameters, and error message display parameters.
13Conversions : NamedTuple
14 A NamedTuple containing various conversion factors for length, time, voltage, current, and angle.
15"""
17# Default python modules
18import math
19from typing import NamedTuple
21import numpy as np
22import h5py
24# import pytribeam.utilities as ut
25import pytribeam.types as tbt
28class Constants(NamedTuple):
29 """
30 A NamedTuple containing various constants used throughout the software.
32 Attributes
33 ----------
34 module_short_name : str
35 Short name of the module.
36 autoscript_version : str
37 Version of the AutoScript software.
38 laser_api_version : str
39 Version of the Laser API.
40 yml_schema_version : str
41 Maximum supported version of the YAML schema.
43 logfile_extension : str
44 Extension for log files.
45 settings_dataset_name : str
46 Name of the dataset for experiment settings.
47 pre_position_dataset_name : str
48 Name of the dataset for position before an event.
49 post_position_dataset_name : str
50 Name of the dataset for position after an event.
51 pre_lasing_dataset_name : str
52 Name of the dataset for laser power before an event.
53 post_lasing_dataset_name : str
54 Name of the dataset for laser power after an event.
55 specimen_current_dataset_name : str
56 Name of the dataset for specimen current.
57 settings_dtype : np.dtype
58 Data type for settings dataset.
59 position_dtype : np.dtype
60 Data type for position dataset.
61 laser_power_dtype : np.dtype
62 Data type for laser power dataset.
63 specimen_current_dtype : np.dtype
64 Data type for specimen current dataset.
66 beam_types : list of str
67 Types of beams (electron/ion).
68 voltage_tol_ratio : float
69 Tolerance ratio for voltage.
70 current_tol_ratio : float
71 Tolerance ratio for current.
72 beam_dwell_tol_ratio : float
73 Tolerance ratio for beam dwell time.
74 default_color_depth : tbt.ColorDepth
75 Default color depth.
76 scan_resolution_limit : tbt.Limit
77 Limit for scan resolution.
79 contrast_brightness_tolerance : float
80 Tolerance for contrast and brightness.
82 image_scan_rotation_for_laser_deg : float
83 Image scan rotation for laser in degrees.
84 laser_objective_limit_mm : tbt.Limit
85 Limit for laser objective in millimeters.
86 laser_objective_retracted_mm : float
87 Safe retracted position for laser objective in millimeters.
88 laser_objective_tolerance_mm : float
89 Tolerance for laser objective in millimeters.
90 laser_beam_shift_tolerance_um : float
91 Tolerance for laser beam shift in micrometers.
92 laser_energy_tol_uj : float
93 Tolerance for laser energy in microjoules.
94 laser_delay_s : float
95 Delay for measuring power and setting pulse divider/energy in seconds.
97 default_fib_rectangle_pattern : tbt.FIBRectanglePattern
98 Default FIB rectangle pattern.
99 stream_pattern_scale : int
100 Scale for stream pattern.
101 stream_pattern_y_shift : int
102 Y-axis shift for stream pattern.
103 stream_pattern_base_dwell_us : float
104 Base dwell time for stream pattern in microseconds.
106 stage_move_delay_s : float
107 Delay for stage movement in seconds.
108 stage_move_attempts : int
109 Number of attempts for stage movement.
110 default_stage_tolerance : tbt.StageTolerance
111 Default stage tolerance.
112 slice_thickness_limit_um : tbt.Limit
113 Limit for slice thickness in micrometers.
114 pre_tilt_limit_deg_generic : tbt.Limit
115 Generic limit for pre-tilt in degrees.
116 pre_tilt_limit_deg_non_Z_sectioning : tbt.Limit
117 Limit for pre-tilt in non-Z sectioning in degrees.
118 home_position : tbt.StagePositionUser
119 Home position of the stage.
120 rotation_axis_limit_deg : tbt.Limit
121 Limit for rotation axis in degrees.
122 detector_collisions : list of list of tbt.DetectorType
123 List of detector collisions.
125 min_map_time_s : int
126 Minimum mapping time in seconds.
127 specimen_current_hfw_mm : float
128 Specimen current high field width in millimeters.
129 specimen_current_delay_s : float
130 Delay for specimen current in seconds.
132 test_hardware_movement : bool
133 Flag for testing hardware movement.
134 offline_machines : list of str
135 List of offline machines.
136 microscope_machines : list of str
137 List of microscope machines.
139 default_column_count : int
140 Default number of columns for printing large lists of values.
141 default_column_width : int
142 Default width of columns in characters.
143 """
145 # Software versions
146 module_short_name = "pyTriBeam"
147 autoscript_version = "4.8.1"
148 laser_api_version = "2.2.1"
149 yml_schema_version = "1.0" # max supported version #TODO convert to float
151 # Log file constants
152 logfile_extension = ".h5"
153 settings_dataset_name = "Experiment Settings"
154 pre_position_dataset_name = "Position Before"
155 post_position_dataset_name = "Position After"
156 pre_lasing_dataset_name = "Laser Power Before"
157 post_lasing_dataset_name = "Laser Power After"
158 specimen_current_dataset_name = "Specimen Current"
159 settings_dtype = np.dtype(
160 [
161 ("Slice", "<u4"),
162 ("Step", "<u4"),
163 ("Config File", h5py.special_dtype(vlen=str)),
164 ("Timestamp", h5py.special_dtype(vlen=str)),
165 ("UNIX time", "<u8"),
166 ]
167 )
168 position_dtype = np.dtype(
169 [
170 ("Slice", "<u4"),
171 ("X", "<f8"),
172 ("Y", "<f8"),
173 ("Z", "<f8"),
174 ("T", "<f8"),
175 ("R", "<f8"),
176 ("Timestamp", h5py.special_dtype(vlen=str)),
177 ("UNIX time", "<u8"),
178 ]
179 )
180 laser_power_dtype = np.dtype(
181 [
182 ("Slice", "<u4"),
183 ("Power", "<f8"),
184 ("Timestamp", h5py.special_dtype(vlen=str)),
185 ("UNIX time", "<u8"),
186 ]
187 )
188 specimen_current_dtype = np.dtype(
189 [
190 ("Slice", "<u4"),
191 ("Current", "<f8"),
192 ("Timestamp", h5py.special_dtype(vlen=str)),
193 ("UNIX time", "<u8"),
194 ]
195 )
197 # Beam (electron/ion) constants
198 beam_types = [
199 "electron",
200 "ion",
201 ]
202 voltage_tol_ratio = 0.05
203 current_tol_ratio = 0.05
204 beam_dwell_tol_ratio = 0.001
205 default_color_depth = tbt.ColorDepth.BITS_8
206 scan_resolution_limit = tbt.Limit(min=12, max=65535) # max of 2^16 - 1
208 # Detector constants
209 contrast_brightness_tolerance = 1.0e-4 # range is 0 to 1
211 # Laser constants
212 image_scan_rotation_for_laser_deg = 180.0 # requirement by TFS for laser milling
213 laser_objective_limit_mm = tbt.Limit(min=2.0, max=29.0)
214 laser_objective_retracted_mm = 2.5 # safe retracted position
215 laser_objective_tolerance_mm = 0.005
216 laser_beam_shift_tolerance_um = 0.5
217 laser_energy_tol_uj = 0.05
218 laser_delay_s = 3.0 # for measuring power and settings pulse divider/energy
220 # FIB constants
221 default_fib_rectangle_pattern = tbt.FIBRectanglePattern(
222 center_um=tbt.Point(
223 x=0.0,
224 y=0.0,
225 ),
226 width_um=10.0,
227 height_um=5.0,
228 depth_um=0.1,
229 scan_direction=tbt.FIBPatternScanDirection.TOP_TO_BOTTOM,
230 scan_type=tbt.FIBPatternScanType.RASTER,
231 )
232 stream_pattern_scale = (
233 2**12
234 ) # upscales fib image to this value / width for higher density of points
235 stream_pattern_y_shift = int(
236 2**16 / 6
237 ) # 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
238 stream_pattern_base_dwell_us = 0.025 # can be 25 or 100 ns, defaults to 25ns
240 # Stage constants
241 stage_move_delay_s = 0.5
242 stage_move_attempts = (
243 2 # generally higher accuracy on movement with 2 attempts for non-piezo stages
244 )
245 default_stage_tolerance = tbt.StageTolerance(
246 translational_um=0.5,
247 angular_deg=0.02,
248 )
249 slice_thickness_limit_um = tbt.Limit(min=0.0, max=30.0) # TODO revert to 0.5 micron
250 pre_tilt_limit_deg_generic = tbt.Limit(min=-60.0, max=60.0)
251 pre_tilt_limit_deg_non_Z_sectioning = tbt.Limit(min=0.0, max=0.0)
252 home_position = tbt.StagePositionUser(
253 x_mm=0.0, y_mm=0.0, z_mm=0.0, r_deg=0.0, t_deg=0.0
254 )
255 rotation_axis_limit_deg = tbt.Limit(
256 min=-180.0, max=180.0
257 ) # used as right-open internal: 180.0 is not valid and should be converted to -180.0
258 detector_collisions = [
259 [tbt.DetectorType.CBS, tbt.DetectorType.EDS],
260 [tbt.DetectorType.CBS, tbt.DetectorType.EBSD],
261 ]
263 # Mapping (EBSD/EDS) constants
264 min_map_time_s = 30
265 specimen_current_hfw_mm = 1.0e-3
266 specimen_current_delay_s = 2.0
268 # Test suite constants
269 test_hardware_movement = True
270 offline_machines = [
271 "S1099177",
272 "S1125518",
273 "daasplus2130w11",
274 "daasplus2131w11",
275 "daasplus2132w11",
276 "daasplus2134w11",
277 ]
278 microscope_machines = ["HPN125v-MPC", "HPN276-MPC"]
280 # error message display constants
281 default_column_count = 3 # for printing large lists of values
282 default_column_width = 20 # characters
285class Conversions(NamedTuple):
286 """
287 A NamedTuple containing various conversion constants for length, time, voltage, current, and angle.
289 Attributes
290 ----------
291 MM_TO_M : float
292 Conversion factor from millimeters to meters.
293 UM_TO_M : float
294 Conversion factor from micrometers to meters.
295 M_TO_MM : float
296 Conversion factor from meters to millimeters.
297 M_TO_UM : float
298 Conversion factor from meters to micrometers.
299 UM_TO_MM : float
300 Conversion factor from micrometers to millimeters.
301 MM_TO_UM : float
302 Conversion factor from millimeters to micrometers.
304 US_TO_S : float
305 Conversion factor from microseconds to seconds.
306 S_TO_US : float
307 Conversion factor from seconds to microseconds.
308 S_TO_NS : float
309 Conversion factor from seconds to nanoseconds.
310 NS_TO_S : float
311 Conversion factor from nanoseconds to seconds.
312 US_TO_NS : float
313 Conversion factor from microseconds to nanoseconds.
314 NS_TO_US : float
315 Conversion factor from nanoseconds to microseconds.
317 KV_TO_V : float
318 Conversion factor from kilovolts to volts.
319 V_TO_KV : float
320 Conversion factor from volts to kilovolts.
322 UA_TO_A : float
323 Conversion factor from microamperes to amperes.
324 NA_TO_A : float
325 Conversion factor from nanoamperes to amperes.
326 PA_TO_A : float
327 Conversion factor from picoamperes to amperes.
328 A_TO_UA : float
329 Conversion factor from amperes to microamperes.
330 A_TO_NA : float
331 Conversion factor from amperes to nanoamperes.
332 A_TO_PA : float
333 Conversion factor from amperes to picoamperes.
334 PA_TO_NA : float
335 Conversion factor from picoamperes to nanoamperes.
336 PA_TO_UA : float
337 Conversion factor from picoamperes to microamperes.
338 NA_TO_UA : float
339 Conversion factor from nanoamperes to microamperes.
340 NA_TO_PA : float
341 Conversion factor from nanoamperes to picoamperes.
342 UA_TO_NA : float
343 Conversion factor from microamperes to nanoamperes.
344 UA_TO_PA : float
345 Conversion factor from microamperes to picoamperes.
347 DEG_TO_RAD : float
348 Conversion factor from degrees to radians.
349 RAD_TO_DEG : float
350 Conversion factor from radians to degrees.
351 """
353 # length
354 MM_TO_M = 1.0e-3
355 UM_TO_M = MM_TO_M / 1000.0
356 M_TO_MM = 1.0 / MM_TO_M
357 M_TO_UM = 1.0 / UM_TO_M
358 UM_TO_MM = UM_TO_M * M_TO_MM
359 MM_TO_UM = 1.0 / UM_TO_MM
361 # time
362 US_TO_S = 1.0e-6
363 S_TO_US = 1.0 / US_TO_S
364 S_TO_NS = S_TO_US * 1000.0
365 NS_TO_S = 1.0 / S_TO_NS
366 US_TO_NS = US_TO_S * S_TO_NS
367 NS_TO_US = 1.0 / US_TO_NS
369 # voltage
370 KV_TO_V = 1.0e3
371 V_TO_KV = 1.0 / KV_TO_V
373 # current
374 UA_TO_A = 1.0e-6
375 NA_TO_A = UA_TO_A / 1000.0
376 PA_TO_A = NA_TO_A / 1000.0
377 A_TO_UA = 1.0 / UA_TO_A
378 A_TO_NA = 1.0 / NA_TO_A
379 A_TO_PA = 1.0 / PA_TO_A
380 PA_TO_NA = PA_TO_A * A_TO_NA
381 PA_TO_UA = PA_TO_A * A_TO_UA
382 NA_TO_UA = NA_TO_A * A_TO_UA
383 NA_TO_PA = 1.0 / PA_TO_NA
384 UA_TO_NA = 1.0 / NA_TO_UA
385 UA_TO_PA = 1.0 / PA_TO_UA
387 # angle
388 DEG_TO_RAD = math.pi / 180.0 # convert degrees to radians
389 RAD_TO_DEG = 180.0 / math.pi