Coverage for src\pytribeam\log.py: 98%
97 statements
« prev ^ index » next coverage.py v7.5.1, created at 2025-03-04 17:41 -0800
« prev ^ index » next coverage.py v7.5.1, created at 2025-03-04 17:41 -0800
1#!/usr/bin/python3
3# Default python modules
4# from functools import singledispatch
5import os
6from pathlib import Path
7import warnings
8import math
9from typing import NamedTuple, List, Tuple
10from functools import singledispatch
11import time
12import datetime
14# Autoscript included modules
15import numpy as np
16from matplotlib import pyplot as plt
17import h5py
18import pandas as pd
20# 3rd party module
22# Local scripts
23from pytribeam.constants import Constants
24import pytribeam.types as tbt
27def create_file(path: Path) -> bool:
28 if not path.is_file():
29 log = h5py.File(path, "w")
30 log.close()
31 if path.is_file():
32 print(f'Logfile created at "{path}".')
33 if path.is_file():
34 return True
35 raise ValueError(f'Unable to create log file at location "{path}".')
38def current_time() -> tbt.TimeStamp:
39 now = datetime.datetime.now()
40 human_readable = now.strftime("%m/%d/%Y %H:%M:%S")
41 unix_time = int(now.timestamp())
42 time = tbt.TimeStamp(human_readable=human_readable, unix=unix_time)
43 return time
46def yml_from_log(
47 log_path_h5: Path,
48 output_path_yml: Path,
49 row: int,
50 config_field: str = "Config File",
51) -> bool:
52 # TODO enforce file formats on inputs
53 with h5py.File(log_path_h5, "r") as file:
54 data = np.array(file[Constants.settings_dataset_name][:])
55 settings = data[row][Constants.settings_dtype.names.index(config_field)].decode(
56 "utf-8"
57 )
59 with open(output_path_yml, "w") as file:
60 file.write(settings)
62 return True
65def experiment_settings(
66 slice_number: int,
67 step_number: int,
68 log_filepath: Path,
69 yml_path: Path,
70) -> bool:
71 dataset_name = Constants.settings_dataset_name
72 settings_dtype = Constants.settings_dtype
73 time = current_time()
75 with open(yml_path, "r") as yml_file:
76 yml_lines = yml_file.readlines()
78 yml_data = " ".join([line for line in yml_lines])
80 if not log_filepath.exists():
81 log_filepath.touch()
83 with h5py.File(log_filepath, "r+") as log:
84 if not dataset_name in log:
85 settings = log.create_dataset(
86 dataset_name,
87 (0,),
88 settings_dtype,
89 maxshape=(None,),
90 )
91 dataset = log[dataset_name]
92 settings_data = np.array(
93 [
94 (
95 slice_number,
96 step_number,
97 yml_data,
98 time.human_readable,
99 time.unix,
100 )
101 ],
102 settings_dtype,
103 )
104 # add one row to table
105 dataset.resize(dataset.shape[0] + 1, axis=0)
106 dataset[-1:] = settings_data
108 return True
111def position(
112 step_number: int,
113 step_name: str,
114 slice_number: int,
115 log_filepath: Path,
116 dataset_name: str,
117 current_position: tbt.StagePositionUser,
118) -> bool:
119 print("\tLogging current position...")
120 dataset_location = f"{step_number:02d}_{step_name}/{dataset_name}"
121 time = current_time()
123 with h5py.File(log_filepath, "r+") as file:
124 if not dataset_location in file:
125 position = file.create_dataset(
126 dataset_location,
127 (0,),
128 Constants.position_dtype,
129 maxshape=(None,),
130 )
131 position.attrs["X Units"] = np.string_("[mm]")
132 position.attrs["Y Units"] = np.string_("[mm]")
133 position.attrs["Z Units"] = np.string_("[mm]")
134 position.attrs["T Units"] = np.string_("[degrees]")
135 position.attrs["R Units"] = np.string_("[degrees]")
137 dataset = file[dataset_location]
138 position_data = np.array(
139 [
140 (
141 slice_number,
142 round(current_position.x_mm, 6),
143 round(current_position.y_mm, 6),
144 round(current_position.z_mm, 6),
145 round(current_position.t_deg, 6),
146 round(current_position.r_deg, 6),
147 time.human_readable,
148 time.unix,
149 )
150 ],
151 Constants.position_dtype,
152 )
153 # add one row to table
154 dataset.resize(dataset.shape[0] + 1, axis=0)
155 dataset[-1:] = position_data
157 return True
160def laser_power(
161 step_number: int,
162 step_name: str,
163 slice_number: int,
164 log_filepath: Path,
165 dataset_name: str,
166 power_w: float,
167) -> bool:
168 print("\tLogging laser power...")
169 dataset_location = f"{step_number:02d}_{step_name}/{dataset_name}"
170 time = current_time()
172 with h5py.File(log_filepath, "r+") as file:
173 if not dataset_location in file:
174 laser_power = file.create_dataset(
175 dataset_location,
176 (0,),
177 Constants.laser_power_dtype,
178 maxshape=(None,),
179 )
180 laser_power.attrs["Units"] = np.string_("[W]")
182 dataset = file[dataset_location]
183 laser_power_data = np.array(
184 [
185 (
186 slice_number,
187 round(power_w, 6),
188 time.human_readable,
189 time.unix,
190 )
191 ],
192 Constants.laser_power_dtype,
193 )
194 # add one row to table
195 dataset.resize(dataset.shape[0] + 1, axis=0)
196 dataset[-1:] = laser_power_data
199def specimen_current(
200 step_number: int,
201 step_name: str,
202 slice_number: int,
203 log_filepath: Path,
204 dataset_name: str,
205 specimen_current_na: float,
206) -> bool:
207 print("\tLogging sample current...")
208 dataset_location = f"{step_number:02d}_{step_name}/{dataset_name}"
209 time = current_time()
211 with h5py.File(log_filepath, "r+") as file:
212 if not dataset_location in file:
213 specimen_current = file.create_dataset(
214 dataset_location,
215 (0,),
216 Constants.specimen_current_dtype,
217 maxshape=(None,),
218 )
219 specimen_current.attrs["Units"] = np.string_("[nA]")
221 dataset = file[dataset_location]
222 specimen_current_data = np.array(
223 [
224 (
225 slice_number,
226 round(specimen_current_na, 6),
227 time.human_readable,
228 time.unix,
229 )
230 ],
231 Constants.specimen_current_dtype,
232 )
233 # add one row to table
234 dataset.resize(dataset.shape[0] + 1, axis=0)
235 dataset[-1:] = specimen_current_data
236 print("\tLogging sample current complete...")
239if __name__ == "__main__":
240 pass