pyglaze 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyglaze/__init__.py +1 -1
- pyglaze/device/ampcom.py +23 -6
- pyglaze/devtools/mock_device.py +15 -1
- pyglaze/scanning/_asyncscanner.py +7 -5
- {pyglaze-0.2.0.dist-info → pyglaze-0.2.1.dist-info}/METADATA +1 -1
- {pyglaze-0.2.0.dist-info → pyglaze-0.2.1.dist-info}/RECORD +9 -9
- {pyglaze-0.2.0.dist-info → pyglaze-0.2.1.dist-info}/WHEEL +1 -1
- {pyglaze-0.2.0.dist-info → pyglaze-0.2.1.dist-info}/LICENSE +0 -0
- {pyglaze-0.2.0.dist-info → pyglaze-0.2.1.dist-info}/top_level.txt +0 -0
pyglaze/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.2.
|
|
1
|
+
__version__ = "0.2.1"
|
pyglaze/device/ampcom.py
CHANGED
|
@@ -32,6 +32,13 @@ if TYPE_CHECKING:
|
|
|
32
32
|
from pyglaze.helpers.types import FloatArray
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
class DeviceComError(Exception):
|
|
36
|
+
"""Raised when an error occurs in the communication with the device."""
|
|
37
|
+
|
|
38
|
+
def __init__(self: DeviceComError, message: str) -> None:
|
|
39
|
+
super().__init__(message)
|
|
40
|
+
|
|
41
|
+
|
|
35
42
|
@dataclass
|
|
36
43
|
class _ForceAmpCom:
|
|
37
44
|
config: ForceDeviceConfiguration
|
|
@@ -272,12 +279,12 @@ class _LeAmpCom:
|
|
|
272
279
|
self._raw_byte_send_ints(
|
|
273
280
|
[self.scanning_points, self.config.integration_periods, self.config.use_ema]
|
|
274
281
|
)
|
|
275
|
-
return self._get_response()
|
|
282
|
+
return self._get_response(self.SEND_SETTINGS_COMMAND)
|
|
276
283
|
|
|
277
284
|
def write_list(self: _LeAmpCom) -> str:
|
|
278
285
|
self._encode_send_response(self.SEND_LIST_COMMAND)
|
|
279
286
|
self._raw_byte_send_floats(self.scanning_list)
|
|
280
|
-
return self._get_response()
|
|
287
|
+
return self._get_response(self.SEND_LIST_COMMAND)
|
|
281
288
|
|
|
282
289
|
def start_scan(self: _LeAmpCom) -> tuple[str, np.ndarray, np.ndarray, np.ndarray]:
|
|
283
290
|
self._encode_send_response(self.START_COMMAND)
|
|
@@ -301,7 +308,7 @@ class _LeAmpCom:
|
|
|
301
308
|
|
|
302
309
|
def _encode_send_response(self: _LeAmpCom, command: str) -> str:
|
|
303
310
|
self._encode_and_send(command)
|
|
304
|
-
return self._get_response()
|
|
311
|
+
return self._get_response(command)
|
|
305
312
|
|
|
306
313
|
def _encode_and_send(self: _LeAmpCom, command: str) -> None:
|
|
307
314
|
self.__ser.write(command.encode(self.ENCODING))
|
|
@@ -326,9 +333,19 @@ class _LeAmpCom:
|
|
|
326
333
|
time.sleep(self.config._sweep_length_ms * 1e-3 * 0.01) # noqa: SLF001, access to private attribute for backwards compatibility
|
|
327
334
|
status = self._get_status()
|
|
328
335
|
|
|
329
|
-
@_BackoffRetry(
|
|
330
|
-
|
|
331
|
-
|
|
336
|
+
@_BackoffRetry(
|
|
337
|
+
backoff_base=1e-2, max_tries=3, logger=logging.getLogger(LOGGER_NAME)
|
|
338
|
+
)
|
|
339
|
+
def _get_response(self: _LeAmpCom, command: str) -> str:
|
|
340
|
+
response = self.__ser.read_until().decode(self.ENCODING).strip()
|
|
341
|
+
|
|
342
|
+
if len(response) == 0:
|
|
343
|
+
msg = f"Command: '{command}'. Empty response received"
|
|
344
|
+
raise serialutil.SerialException(msg)
|
|
345
|
+
if response[: len(self.OK_RESPONSE)] != self.OK_RESPONSE:
|
|
346
|
+
msg = f"Command: '{command}'. Expected response '{self.OK_RESPONSE}', received: '{response}'"
|
|
347
|
+
raise DeviceComError(msg)
|
|
348
|
+
return response
|
|
332
349
|
|
|
333
350
|
@_BackoffRetry(
|
|
334
351
|
backoff_base=1e-2, max_tries=5, logger=logging.getLogger(LOGGER_NAME)
|
pyglaze/devtools/mock_device.py
CHANGED
|
@@ -26,6 +26,8 @@ class MockDevice(ABC):
|
|
|
26
26
|
self: MockDevice,
|
|
27
27
|
fail_after: float = np.inf,
|
|
28
28
|
n_fails: float = np.inf,
|
|
29
|
+
*,
|
|
30
|
+
empty_responses: bool = False,
|
|
29
31
|
) -> None:
|
|
30
32
|
pass
|
|
31
33
|
|
|
@@ -183,7 +185,11 @@ class LeMockDevice(MockDevice):
|
|
|
183
185
|
DAC_BITWIDTH = 2**12
|
|
184
186
|
|
|
185
187
|
def __init__(
|
|
186
|
-
self: LeMockDevice,
|
|
188
|
+
self: LeMockDevice,
|
|
189
|
+
fail_after: float = np.inf,
|
|
190
|
+
n_fails: float = np.inf,
|
|
191
|
+
*,
|
|
192
|
+
empty_responses: bool = False,
|
|
187
193
|
) -> None:
|
|
188
194
|
self.fail_after = fail_after
|
|
189
195
|
self.fails_wanted = n_fails
|
|
@@ -197,6 +203,7 @@ class LeMockDevice(MockDevice):
|
|
|
197
203
|
self.use_ema: bool | None = None
|
|
198
204
|
self.scanning_list: list[float] | None = None
|
|
199
205
|
self._scan_start_time: float | None = None
|
|
206
|
+
self.empty_responses = empty_responses
|
|
200
207
|
|
|
201
208
|
def write(self: LeMockDevice, input_bytes: bytes) -> None:
|
|
202
209
|
"""Mock-write to the serial connection."""
|
|
@@ -217,12 +224,16 @@ class LeMockDevice(MockDevice):
|
|
|
217
224
|
|
|
218
225
|
def read(self: LeMockDevice, size: int) -> bytes:
|
|
219
226
|
"""Mock-read from the serial connection."""
|
|
227
|
+
if self.empty_responses:
|
|
228
|
+
return self._create_scan_bytes(n_bytes=0)
|
|
220
229
|
if self.state == _LeMockState.IDLE:
|
|
221
230
|
return self._create_scan_bytes(n_bytes=size)
|
|
222
231
|
raise NotImplementedError
|
|
223
232
|
|
|
224
233
|
def read_until(self: LeMockDevice, _: bytes = b"\r") -> bytes: # noqa: PLR0911
|
|
225
234
|
"""Mock-read_until from the serial connection."""
|
|
235
|
+
if self.empty_responses:
|
|
236
|
+
return "".encode(self.ENCODING)
|
|
226
237
|
if self.state == _LeMockState.WAITING_FOR_SETTINGS:
|
|
227
238
|
return "ACK: Ready to receive settings.".encode(self.ENCODING)
|
|
228
239
|
if self.state == _LeMockState.RECEIVED_SETTINGS:
|
|
@@ -353,6 +364,7 @@ def list_mock_devices() -> list[str]:
|
|
|
353
364
|
"mock_device",
|
|
354
365
|
"mock_device_scan_should_fail",
|
|
355
366
|
"mock_device_fail_first_scan",
|
|
367
|
+
"mock_device_empty_responses",
|
|
356
368
|
]
|
|
357
369
|
|
|
358
370
|
|
|
@@ -364,6 +376,8 @@ def _mock_device_factory(config: DeviceConfiguration) -> MockDevice:
|
|
|
364
376
|
return mock_class()
|
|
365
377
|
if config.amp_port == "mock_device_fail_first_scan":
|
|
366
378
|
return mock_class(fail_after=0, n_fails=1)
|
|
379
|
+
if config.amp_port == "mock_device_empty_responses":
|
|
380
|
+
return mock_class(empty_responses=True)
|
|
367
381
|
|
|
368
382
|
msg = f"Unknown mock device requested: {config.amp_port}. Valid options are: {list_mock_devices()}"
|
|
369
383
|
raise ValueError(msg)
|
|
@@ -95,13 +95,15 @@ class _AsyncScanner:
|
|
|
95
95
|
def _get_scan(self: _AsyncScanner) -> _TimestampedWaveform:
|
|
96
96
|
try:
|
|
97
97
|
return self._shared_mem.get(timeout=self._SCAN_TIMEOUT)
|
|
98
|
-
except
|
|
98
|
+
except Exception as err:
|
|
99
|
+
scanner_err: Exception | None = None
|
|
99
100
|
if self._scanner_conn.poll(timeout=self.startup_timeout):
|
|
100
101
|
msg: _ScannerHealth = self._scanner_conn.recv()
|
|
101
|
-
if not msg.is_alive:
|
|
102
|
-
self.is_scanning = False
|
|
103
102
|
if msg.error:
|
|
104
|
-
|
|
103
|
+
scanner_err = msg.error
|
|
104
|
+
self.stop_scan()
|
|
105
|
+
if scanner_err:
|
|
106
|
+
raise scanner_err from err
|
|
105
107
|
raise
|
|
106
108
|
|
|
107
109
|
@staticmethod
|
|
@@ -121,7 +123,7 @@ class _AsyncScanner:
|
|
|
121
123
|
while not stop_signal.is_set():
|
|
122
124
|
try:
|
|
123
125
|
waveform = _TimestampedWaveform(datetime.now(), scanner.scan()) # noqa: DTZ005
|
|
124
|
-
except
|
|
126
|
+
except Exception as e: # noqa: BLE001
|
|
125
127
|
parent_conn.send(
|
|
126
128
|
_ScannerHealth(is_alive=False, is_healthy=False, error=e)
|
|
127
129
|
)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
pyglaze/__init__.py,sha256=
|
|
1
|
+
pyglaze/__init__.py,sha256=HfjVOrpTnmZ-xVFCYSVmX50EXaBQeJteUHG-PD6iQs8,22
|
|
2
2
|
pyglaze/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
pyglaze/datamodels/__init__.py,sha256=DJLByl2C7pC4RM4Uh6PW-McM5RIGBjcopzGywCKhSlI,111
|
|
4
4
|
pyglaze/datamodels/pulse.py,sha256=BoW_GDvkwEpn_UYUFPoUfi5E_oCnvv8cU4nZKG7Ph2U,20911
|
|
5
5
|
pyglaze/datamodels/waveform.py,sha256=n31DhJHFeBNZ3hHqQUiCGXssm5Dc8wV6tGPkhmFYB4Q,5809
|
|
6
6
|
pyglaze/device/__init__.py,sha256=5RjCHuFKMi9g2KLUkxixO9hNpAgkUBcOURNTuhAdoUk,177
|
|
7
|
-
pyglaze/device/ampcom.py,sha256=
|
|
7
|
+
pyglaze/device/ampcom.py,sha256=6JXl7PojYr4F1_pdVItO-XbGCp8mpy4wpwaaUn8Loog,17214
|
|
8
8
|
pyglaze/device/configuration.py,sha256=gh_eerX8TdXx3LnFxHieJqOpfDfE9cV6Xgm5WYVnvO0,7994
|
|
9
9
|
pyglaze/devtools/__init__.py,sha256=9EW20idoaZv_5GuSgDmfpTPjfCZ-Rl27EV3oJebmwnQ,90
|
|
10
|
-
pyglaze/devtools/mock_device.py,sha256=
|
|
10
|
+
pyglaze/devtools/mock_device.py,sha256=3RMa-JAehbbRCmOO74aZzGPdYp2qsP-XE8ulzLXDP6Q,13994
|
|
11
11
|
pyglaze/devtools/thz_pulse.py,sha256=xp-T9psdOrUMtSUFu8HEwQJVu_aMixJdZHtg_BCVu_k,923
|
|
12
12
|
pyglaze/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
pyglaze/helpers/types.py,sha256=p9xSAP5Trr1FcCWl7ynCWqDOUZKgMQYzMUXSwDpAKHg,599
|
|
@@ -15,11 +15,11 @@ pyglaze/helpers/utilities.py,sha256=n_x9Tqm305MUorS29O6CoJM8Mi4apo2bsN_odrRaVAw,
|
|
|
15
15
|
pyglaze/interpolation/__init__.py,sha256=WCxHPsiI7zvJykp-jfytoEbO4Tla-YIF6A7fjDfcDvU,72
|
|
16
16
|
pyglaze/interpolation/interpolation.py,sha256=rQWzPD7W8TXETps7VZI0gcfAOCWO8pGL1HhhBnyxaMw,735
|
|
17
17
|
pyglaze/scanning/__init__.py,sha256=uCBaeDTufOrC9KWf30ICqcmvFg_YT85olb3M9jkvZRg,99
|
|
18
|
-
pyglaze/scanning/_asyncscanner.py,sha256=
|
|
18
|
+
pyglaze/scanning/_asyncscanner.py,sha256=SldM7XCavfugsDstxMVI_WLL6GUJutLYN0iU__mfY5A,5277
|
|
19
19
|
pyglaze/scanning/client.py,sha256=3qrQStkeLQzCeu4yMHJ_ENLGQ7E5GMc4CP9J55rk-ug,1817
|
|
20
20
|
pyglaze/scanning/scanner.py,sha256=PSjXVpSpHpYIl-sW34pIThocbM9GSHJ_E4gGcsePeTw,8139
|
|
21
|
-
pyglaze-0.2.
|
|
22
|
-
pyglaze-0.2.
|
|
23
|
-
pyglaze-0.2.
|
|
24
|
-
pyglaze-0.2.
|
|
25
|
-
pyglaze-0.2.
|
|
21
|
+
pyglaze-0.2.1.dist-info/LICENSE,sha256=LCP3sGBX7LxuQopcjeug1fW4tngWCHF4zB7QCgB28xM,1504
|
|
22
|
+
pyglaze-0.2.1.dist-info/METADATA,sha256=WETmnm6CF1_eyojd-ahfIFLJ_VCxV2jshcrbSoPLg3Y,3498
|
|
23
|
+
pyglaze-0.2.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
24
|
+
pyglaze-0.2.1.dist-info/top_level.txt,sha256=X7d5rqVVuWNmtK4-Uh4sgOLlqye8vaHZOr5RYba0REo,8
|
|
25
|
+
pyglaze-0.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|