Skip to content

Commit 7f68f9e

Browse files
Conform practicum SSD
This commit should be reversed again after the practicum SSD has finished
1 parent c72c2ab commit 7f68f9e

File tree

8 files changed

+4309
-4
lines changed

8 files changed

+4309
-4
lines changed

Alia_protocol_serial.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
import numpy as np
2121
from numba import njit
2222

23-
from dvg_devices import Arduino_protocol_serial
23+
#from dvg_devices import Arduino_protocol_serial
24+
from dvg_devices import Arduino
2425
from dvg_debug_functions import dprint, print_fancy_traceback as pft
2526

2627

@@ -47,7 +48,8 @@ class Waveform(Enum):
4748
# fmt: on
4849

4950

50-
class Alia(Arduino_protocol_serial.Arduino):
51+
#class Alia(Arduino_protocol_serial.Arduino):
52+
class Alia(Arduino):
5153
"""This class manages the serial protocol for an Arduino lock-in amplifier,
5254
aka `Alia`.
5355
"""

Alia_protocol_serial_SAMD51.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
import serial
2020
import numpy as np
2121

22-
from dvg_devices import Arduino_protocol_serial
22+
#from dvg_devices import Arduino_protocol_serial
23+
from dvg_devices import Arduino
2324
from dvg_debug_functions import dprint, print_fancy_traceback as pft
2425

2526

@@ -32,7 +33,8 @@ class Waveform(Enum):
3233
# fmt: on
3334

3435

35-
class Alia(Arduino_protocol_serial.Arduino):
36+
#class Alia(Arduino_protocol_serial.Arduino):
37+
class Alia(Arduino):
3638
"""This class manages the serial protocol for an Arduino lock-in amplifier,
3739
aka `Alia`.
3840
"""

dvg_debug_functions.py

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""Provides functions for neatly printing debug information to the terminal
4+
output, well-suited for multithreaded programs.
5+
"""
6+
__author__ = "Dennis van Gils"
7+
__authoremail__ = "[email protected]"
8+
__url__ = "https://github.com/Dennis-van-Gils/python-dvg-debug-functions"
9+
__date__ = "18-07-2020"
10+
__version__ = "2.1.1"
11+
12+
import os
13+
import sys
14+
import time
15+
import traceback
16+
import inspect
17+
18+
try:
19+
from PyQt5 import QtCore
20+
except ImportError:
21+
PYQT5_IS_PRESENT = False
22+
else:
23+
PYQT5_IS_PRESENT = True
24+
dprint_mutex = QtCore.QMutex()
25+
26+
# Setting this global module variable to `True` or `False` will overrule the
27+
# argument `show_full_paths` in `print_fancy_traceback()`.
28+
OVERRULE_SHOW_FULL_PATHS = None
29+
30+
31+
class ANSI:
32+
NONE = ""
33+
RED = "\033[1;31m"
34+
GREEN = "\033[1;32m"
35+
YELLOW = "\033[1;33m"
36+
BLUE = "\033[1;34m"
37+
PURPLE = "\033[1;35m" # aka MAGENTA
38+
MAGENTA = "\033[1;35m"
39+
CYAN = "\033[1;36m"
40+
WHITE = "\033[1;37m"
41+
42+
43+
def dprint(str_msg: str, ANSI_color: str = None):
44+
"""'Debug' print a single line to the terminal with optional ANSI color
45+
codes. There is a lot of overhead using this print statement, but it is
46+
particularly well-suited for multithreaded PyQt programs where multiple
47+
threads are each printing information to the same terminal. The ``dprint()``
48+
function ensure that each line sent to the terminal will remain as a
49+
continious single line, whereas a regular ``print()`` statement will likely
50+
result in the lines getting mixed up.
51+
52+
The line will be terminated with a newline character and the terminal output
53+
buffer is forced to flush before and after every print. In addition, if
54+
PyQt5 is present in the Python environment, then a mutex lock will be
55+
obtained and released again for each ``dprint()`` execution.
56+
"""
57+
# Explicitly ending the string with a newline '\n' character, instead
58+
# of letting the print statement end it for you (end='\n'), fixes the
59+
# problem of single lines getting printed to the terminal with
60+
# intermittently delayed newlines when coming from different threads.
61+
# I.e. it prevents:
62+
# >: Output line of thread 1Output line of thread 2 (\n)
63+
# >: (\n)
64+
# and makes sure we get:
65+
# >: Output line of thread 1 (\n)
66+
# >: Output line of thread 2 (\n)
67+
68+
if PYQT5_IS_PRESENT:
69+
locker = QtCore.QMutexLocker(dprint_mutex)
70+
71+
sys.stdout.flush()
72+
if ANSI_color is None:
73+
print("%s\n" % str_msg, end="")
74+
else:
75+
print("%s%s%s\n" % (ANSI_color, str_msg, ANSI.WHITE), end="")
76+
sys.stdout.flush()
77+
78+
if PYQT5_IS_PRESENT:
79+
locker.unlock()
80+
81+
82+
def tprint(str_msg: str, ANSI_color: str = None):
83+
"""Identical to ``dprint()``, but now prepended with a ``time.perf_counter()``
84+
timestamp.
85+
"""
86+
dprint("%.4f %s" % (time.perf_counter(), str_msg), ANSI_color)
87+
88+
89+
def print_fancy_traceback(
90+
err=None, back: int = 3, show_full_paths: bool = False
91+
):
92+
"""Print the exception or the current regular call-stack traceback to the
93+
terminal, using ANSI color codes that mimic the IPython command shell.
94+
95+
Args:
96+
err (``Exception`` | ``str`` | ``None``, optional):
97+
When ``err`` is of type ``Exception``, then an exception traceback will
98+
be printed. When ``err`` is of another type, then the current regular
99+
call-stack traceback will be printed.
100+
101+
Default: ``None``
102+
103+
back (``int``, optional):
104+
Depth of the traceback to print.
105+
106+
Default: ``3``
107+
108+
show_full_paths (``bool``, optional):
109+
Shows the full filepath in the traceback when True, otherwise just
110+
the filename.
111+
112+
Default: ``False``
113+
"""
114+
115+
def print_frame(filename, line_no, frame_name):
116+
print(
117+
(
118+
ANSI.CYAN
119+
+ "File "
120+
+ ANSI.GREEN
121+
+ '"%s"'
122+
+ ANSI.CYAN
123+
+ ", line "
124+
+ ANSI.GREEN
125+
+ "%s"
126+
+ ANSI.CYAN
127+
+ ", in "
128+
+ ANSI.PURPLE
129+
+ "%s"
130+
+ ANSI.WHITE
131+
)
132+
% (filename, line_no, frame_name)
133+
)
134+
135+
print(
136+
"\n"
137+
+ ANSI.WHITE
138+
+ "Fancy traceback "
139+
+ ANSI.CYAN
140+
+ "(most recent call last)"
141+
+ ANSI.WHITE
142+
+ ":"
143+
)
144+
145+
if isinstance(err, Exception):
146+
# Exception traceback
147+
etype, evalue, tb = sys.exc_info()
148+
stack = traceback.extract_tb(tb)
149+
stack = stack[-back:]
150+
151+
for frame in stack:
152+
if OVERRULE_SHOW_FULL_PATHS is not None:
153+
file_descr = (
154+
frame.filename
155+
if OVERRULE_SHOW_FULL_PATHS
156+
else os.path.basename(frame.filename)
157+
)
158+
else:
159+
file_descr = (
160+
frame.filename
161+
if show_full_paths
162+
else os.path.basename(frame.filename)
163+
)
164+
165+
print_frame(file_descr, frame.lineno, frame.name)
166+
167+
print("----> %s" % stack[-1].line)
168+
print(
169+
(ANSI.RED + "%s: " + ANSI.WHITE + "%s") % (etype.__name__, evalue)
170+
)
171+
172+
else:
173+
# Regular call stack traceback
174+
stack = inspect.stack()
175+
stack.reverse()
176+
stack = stack[-back - 1 : -1]
177+
178+
for frame in stack:
179+
if OVERRULE_SHOW_FULL_PATHS is not None:
180+
file_descr = (
181+
frame.filename
182+
if OVERRULE_SHOW_FULL_PATHS
183+
else os.path.basename(frame.filename)
184+
)
185+
else:
186+
file_descr = (
187+
frame.filename
188+
if show_full_paths
189+
else os.path.basename(frame.filename)
190+
)
191+
192+
print_frame(file_descr, frame.lineno, frame.function)
193+
194+
if isinstance(err, str):
195+
print((ANSI.RED + "Error: " + ANSI.WHITE + "%s") % err)

0 commit comments

Comments
 (0)