wasatch 2.2.0__tar.gz → 2.2.13__tar.gz
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.
- {wasatch-2.2.0 → wasatch-2.2.13}/CHANGELOG.md +64 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/PKG-INFO +1 -1
- wasatch-2.2.13/demo-auto-raman.py +130 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/demo.py +30 -28
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/AndorDevice.py +2 -2
- wasatch-2.2.13/wasatch/AutoRaman.py +451 -0
- wasatch-2.2.13/wasatch/AutoRamanRequest.py +76 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/BLEDevice.py +74 -56
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/ControlObject.py +3 -1
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/EEPROM.py +70 -39
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/FeatureIdentificationDevice.py +534 -371
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/FirmwareRequirements.py +14 -6
- wasatch-2.2.13/wasatch/IMX385.py +179 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/OceanDevice.py +2 -1
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/Reading.py +5 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/SPIDevice.py +3 -2
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/SpectrometerResponse.py +1 -1
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/SpectrometerSettings.py +41 -5
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/SpectrometerState.py +1 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/TakeOneRequest.py +11 -2
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/WasatchDevice.py +65 -34
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/WasatchDeviceWrapper.py +10 -11
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/WrapperWorker.py +7 -3
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/__init__.py +1 -1
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/utils.py +3 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/.example_pypirc +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/.flake8 +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/.gitignore +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/.pylintrc +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/Doxyfile +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/LICENSE +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/MANIFEST.in +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/Makefile +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/README.md +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/README_PYPI.md +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/README_RPI.md +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/README_SETTINGS.md +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/README_VIRTUAL.md +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/WasatchShell/README.md +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/WasatchShell/laser-test.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/WasatchShell/load-test.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/WasatchShell/one-shot.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/WasatchShell/wasatch-shell.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/demo-simple.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/demo-virtual.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/demo-workflow.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/environments/conda-linux.yml +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/environments/conda-macos.yml +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/environments/conda-rpi.yml +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/environments/conda-win10.yml +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/pyproject.toml +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/requirements.txt +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/screenshots/multiplatform.png +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/scripts/dark-vs-integ.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/scripts/deploy +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/setup.cfg +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/testSpectrometers/SiG_785/eeprom/EEPROM-EM-9c65d19f4c.json +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/testSpectrometers/SiG_785/readings/enlighten-20210329-094722-799520-WP-00686.csv +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/testSpectrometers/SiG_785/readings/enlighten-20210329-094755-288958-WP-00686.csv +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/testSpectrometers/WP-00887/eeprom/WP-00887-mock.json +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/testSpectrometers/WP-00904/eeprom/WP-00904-mock.json +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/testSpectrometers/WP-00913/eeprom/WP-00913-mock.json +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/tests/existing_implementations.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/tests/noise-by-setpoint.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/tests/queues.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/tests/unit.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/udev/10-wasatch.rules +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/AbstractUSBDevice.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/BalanceAcquisition.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/CSVLoader.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/CommandSettings.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/DetectorROI.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/DetectorRegions.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/DeviceFinderUSB.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/DeviceID.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/EEPROM_multical.sav +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/FPGAOptions.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/HardwareInfo.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/InterfaceDevice.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/MockUSBDevice.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/PollStatus.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/ProcessedReading.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/ROI.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/RealUSBDevice.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/SpectrometerRequest.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/StatusMessage.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/WasatchBus.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/applog.py +0 -0
- {wasatch-2.2.0 → wasatch-2.2.13}/wasatch/simulation_protocol.py +0 -0
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
- 2024-11-01 2.2.13
|
|
4
|
+
- support for InGaAs linear pixel calibration
|
|
5
|
+
- re-enable STM32 serial number
|
|
6
|
+
- 2024-10-31 2.2.12
|
|
7
|
+
- prefer new EEPROM location for startup laser TEC setpoint
|
|
8
|
+
- 2024-10-30 2.2.11
|
|
9
|
+
- IMX385.bin_4x2_avg tweak
|
|
10
|
+
- 2024-10-30 2.2.10
|
|
11
|
+
- don't configure laser TEC and laser warning delay unless laser present
|
|
12
|
+
- 2024-10-29 2.2.9
|
|
13
|
+
- add BIN_4X2_AVG
|
|
14
|
+
- add more firmware version checks around new features to avoid breaking old FW
|
|
15
|
+
- Auto-Raman
|
|
16
|
+
- support new onboard Auto-Raman opcode and parameters
|
|
17
|
+
- start refresh of BLEDevice
|
|
18
|
+
- 2024-10-16 2.2.8
|
|
19
|
+
- add alert_queue to allow caller (ENLIGHTEN) to send hints and interrupts
|
|
20
|
+
downstream into Wasatch.PY, visible even within long-running operations
|
|
21
|
+
like Auto-Raman which are encapsulated within a single call from
|
|
22
|
+
WrapperWorker and therefore unsuitable for the normal "command_queue"
|
|
23
|
+
- added AutoRaman support for new "auto_raman_cancel" alert
|
|
24
|
+
- 2024-10-15 2.2.7
|
|
25
|
+
- fixed AutoRaman on X series
|
|
26
|
+
- added IMX385.bin_4x2_interp
|
|
27
|
+
- 2024-10-14 2.2.6
|
|
28
|
+
- removed
|
|
29
|
+
- EEPROM.ssc_enabled
|
|
30
|
+
- changed
|
|
31
|
+
- EEPROM.LATEST_REV to 16
|
|
32
|
+
- EEPROM.bin_2x2 --> .horiz_binning_enabled
|
|
33
|
+
- EEPROM.actual_horizontal to .actual_pixels_horizontal
|
|
34
|
+
- EEPROM.actual_vertical to .actual_pixels_vertical
|
|
35
|
+
- added
|
|
36
|
+
- EEPROM.horiz_binning_mode
|
|
37
|
+
- EEPROM.power_timeout_sec
|
|
38
|
+
- EEPROM.detector_timeout_sec
|
|
39
|
+
- IMX385.bin_4x2
|
|
40
|
+
- 2024-10-10 2.2.5
|
|
41
|
+
- added IMX385
|
|
42
|
+
- added EEPROM.ssc_enabled
|
|
43
|
+
- added AutoRaman throwaway before dark to let laser fully disable
|
|
44
|
+
- bugfix in SpectrometerSettings.has_excitation
|
|
45
|
+
- 2024-10-03 2.2.4
|
|
46
|
+
- added EEPROM.disable_ble_power
|
|
47
|
+
- added EEPROM.disable_laser_armed_indicator
|
|
48
|
+
- added SpectrometerSettings.ble_firmware_version
|
|
49
|
+
- 2024-09-17 2.2.3
|
|
50
|
+
- ensure all queued messages are flowed upstream
|
|
51
|
+
- AutoRaman
|
|
52
|
+
- output progress bar updates
|
|
53
|
+
- support configurable Laser Warning Delay
|
|
54
|
+
- averaging bugfix
|
|
55
|
+
- trying to support non-zero initial gain dB
|
|
56
|
+
- enable saving individual spectral components via environment variable
|
|
57
|
+
- don't perform dark-correction; leave that for caller
|
|
58
|
+
- 2024-09-12 2.2.2
|
|
59
|
+
- added set/get_laser_warning_delay through change_settings
|
|
60
|
+
- updated reset_fpga to restore key FPGA settings
|
|
61
|
+
- enriched AutoRaman status messages
|
|
62
|
+
- AutoRaman bugfix
|
|
63
|
+
- 2024-09-12 2.2.1
|
|
64
|
+
- fixed get_detector_gain on XS
|
|
65
|
+
- reduced number of implicit throwaways after acquisition parameter changes
|
|
66
|
+
- added AutoRaman via TakeOneRequest
|
|
3
67
|
- 2024-08-22 2.2.0
|
|
4
68
|
- cutting release for ENLIGHTEN 4.1.0
|
|
5
69
|
- 2024-06-27 2.1.73
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
import numpy
|
|
6
|
+
import signal
|
|
7
|
+
import logging
|
|
8
|
+
import datetime
|
|
9
|
+
import argparse
|
|
10
|
+
|
|
11
|
+
import wasatch
|
|
12
|
+
from wasatch import utils
|
|
13
|
+
from wasatch import applog
|
|
14
|
+
from wasatch.WasatchBus import WasatchBus
|
|
15
|
+
from wasatch.WasatchDevice import WasatchDevice
|
|
16
|
+
from wasatch.WasatchDeviceWrapper import WasatchDeviceWrapper
|
|
17
|
+
from wasatch.TakeOneRequest import TakeOneRequest
|
|
18
|
+
from wasatch.AutoRamanRequest import AutoRamanRequest
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
class Fixture:
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
self.bus = None
|
|
26
|
+
self.device = None
|
|
27
|
+
self.outfile = None
|
|
28
|
+
self.reading_count = 0
|
|
29
|
+
|
|
30
|
+
self.parse_args()
|
|
31
|
+
|
|
32
|
+
self.logger = applog.MainLogger("DEBUG" if self.args.debug else "INFO")
|
|
33
|
+
|
|
34
|
+
def parse_args(self):
|
|
35
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
36
|
+
parser.add_argument("--debug", action="store_true", help="logging level")
|
|
37
|
+
parser.add_argument("--outfile", type=str, default=None, help="output filename (e.g. path/to/spectra.csv)")
|
|
38
|
+
parser.add_argument("--max-ms", type=int, default=10000, help="maximum measurement time (ms)")
|
|
39
|
+
parser.add_argument("--start-integ-ms", type=int, default=100, help="initial integration time (ms)")
|
|
40
|
+
parser.add_argument("--start-gain-db", type=float, default=0, help="initial gain (dB)")
|
|
41
|
+
parser.add_argument("--max-integ-ms", type=int, default=2000, help="maximum integration time (ms)")
|
|
42
|
+
parser.add_argument("--min-integ-ms", type=int, default=10, help="minimum integration time (ms)")
|
|
43
|
+
parser.add_argument("--max-gain-db", type=float, default=32, help="maximum gain (dB)")
|
|
44
|
+
parser.add_argument("--min-gain-db", type=float, default=0, help="minimum gain (dB)")
|
|
45
|
+
parser.add_argument("--target-counts", type=int, default=45000, help="target counts")
|
|
46
|
+
parser.add_argument("--max-counts", type=int, default=50000, help="max counts")
|
|
47
|
+
parser.add_argument("--min-counts", type=int, default=40000, help="min counts")
|
|
48
|
+
parser.add_argument("--max-factor", type=float, default=5, help="max scaling factor")
|
|
49
|
+
parser.add_argument("--drop-factor", type=float, default=0.5, help="factor when scaling down")
|
|
50
|
+
parser.add_argument("--saturation", type=int, default=65000, help="counts")
|
|
51
|
+
|
|
52
|
+
self.args = parser.parse_args()
|
|
53
|
+
|
|
54
|
+
def connect(self):
|
|
55
|
+
""" Connect to all discoverable Wasatch spectrometers. """
|
|
56
|
+
|
|
57
|
+
self.bus = WasatchBus()
|
|
58
|
+
if not self.bus.device_ids:
|
|
59
|
+
print("No Wasatch USB spectrometers found.")
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
for device_id in self.bus.device_ids:
|
|
63
|
+
device = WasatchDevice(device_id)
|
|
64
|
+
if not device.connect():
|
|
65
|
+
log.critical("connect: can't connect to %s", device_id)
|
|
66
|
+
continue
|
|
67
|
+
|
|
68
|
+
settings = device.settings
|
|
69
|
+
print(f"connected to {settings.full_model()} {settings.eeprom.serial_number} with {settings.pixels()} pixels " +
|
|
70
|
+
f"from ({settings.wavelengths[0]:.2f}, {settings.wavelengths[-1]:.2f}nm)" +
|
|
71
|
+
( f" ({settings.wavenumbers[0]:.2f}, {settings.wavenumbers[-1]:.2f}cm⁻¹)" if settings.has_excitation() else "") +
|
|
72
|
+
f" (Microcontroller {device.settings.microcontroller_firmware_version}," +
|
|
73
|
+
f" FPGA {settings.fpga_firmware_version})")
|
|
74
|
+
|
|
75
|
+
self.device = device
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
def run(self):
|
|
79
|
+
start_time = datetime.datetime.now()
|
|
80
|
+
|
|
81
|
+
# instantiate an AutoRamanRequest, passing in the configured options
|
|
82
|
+
arr = AutoRamanRequest(max_ms = self.args.max_ms,
|
|
83
|
+
start_integ_ms = self.args.start_integ_ms,
|
|
84
|
+
start_gain_db = self.args.start_gain_db,
|
|
85
|
+
max_integ_ms = self.args.max_integ_ms,
|
|
86
|
+
min_integ_ms = self.args.min_integ_ms,
|
|
87
|
+
max_gain_db = self.args.max_gain_db,
|
|
88
|
+
min_gain_db = self.args.min_gain_db,
|
|
89
|
+
target_counts = self.args.target_counts,
|
|
90
|
+
max_counts = self.args.max_counts,
|
|
91
|
+
min_counts = self.args.min_counts,
|
|
92
|
+
max_factor = self.args.max_factor,
|
|
93
|
+
drop_factor = self.args.drop_factor,
|
|
94
|
+
saturation = self.args.saturation)
|
|
95
|
+
log.debug(f"instantiated {arr}")
|
|
96
|
+
|
|
97
|
+
# add the AutoRamanRequest to a TakeOneRequest
|
|
98
|
+
tor = TakeOneRequest(auto_raman_request=arr)
|
|
99
|
+
log.debug(f"instantiated {tor}")
|
|
100
|
+
|
|
101
|
+
# send the TakeOneRequest to the driver
|
|
102
|
+
self.device.change_setting("take_one_request", tor)
|
|
103
|
+
log.debug("sent TakeOneRequest to spectrometer")
|
|
104
|
+
|
|
105
|
+
# block on completion of the TakeOneRequest (ignore keepalives)
|
|
106
|
+
while True:
|
|
107
|
+
log.debug("calling WasatchDevice.acquire_data")
|
|
108
|
+
reading = self.device.acquire_data().data
|
|
109
|
+
log.debug(f"WasatchDevice.acquire_data returned {reading}")
|
|
110
|
+
if reading is not None:
|
|
111
|
+
break
|
|
112
|
+
|
|
113
|
+
time.sleep(1)
|
|
114
|
+
|
|
115
|
+
elapsed_sec = (datetime.datetime.now() - start_time).total_seconds()
|
|
116
|
+
print(f"Auto-Raman measurement completed in {elapsed_sec:.2f} sec")
|
|
117
|
+
|
|
118
|
+
# process Reading
|
|
119
|
+
settings = self.device.settings
|
|
120
|
+
|
|
121
|
+
# ASCII-Art
|
|
122
|
+
print("\n".join(wasatch.utils.ascii_spectrum(reading.spectrum, rows=20, cols=80, x_axis=settings.wavenumbers, x_unit="cm⁻¹")))
|
|
123
|
+
|
|
124
|
+
if self.outfile:
|
|
125
|
+
self.outfile.write("{datetime.datetime.now()}, {aar}, {', '.join([f'.2f' for x in reading.spectrum])}\n")
|
|
126
|
+
|
|
127
|
+
# main()
|
|
128
|
+
fixture = Fixture()
|
|
129
|
+
if fixture.connect():
|
|
130
|
+
fixture.run()
|
|
@@ -6,13 +6,7 @@
|
|
|
6
6
|
# DESCRIPTION: Simple cmd-line demo to confirm that Wasatch.PY is working #
|
|
7
7
|
# and can connect to and control a spectrometer. #
|
|
8
8
|
# #
|
|
9
|
-
#
|
|
10
|
-
# $ rm -f environment.yml #
|
|
11
|
-
# $ ln -s environments/conda-linux.yml (or macos, etc) #
|
|
12
|
-
# $ conda env create -n wasatch3 #
|
|
13
|
-
# $ conda activate wasatch3 #
|
|
14
|
-
# INVOCATION: #
|
|
15
|
-
# $ python -u demo.py #
|
|
9
|
+
# INVOCATION: $ python -u demo.py #
|
|
16
10
|
# #
|
|
17
11
|
################################################################################
|
|
18
12
|
|
|
@@ -22,7 +16,6 @@ import sys
|
|
|
22
16
|
import time
|
|
23
17
|
import numpy
|
|
24
18
|
import signal
|
|
25
|
-
import psutil
|
|
26
19
|
import logging
|
|
27
20
|
import datetime
|
|
28
21
|
import argparse
|
|
@@ -33,7 +26,6 @@ from wasatch import applog
|
|
|
33
26
|
from wasatch.WasatchBus import WasatchBus
|
|
34
27
|
from wasatch.WasatchDevice import WasatchDevice
|
|
35
28
|
from wasatch.WasatchDeviceWrapper import WasatchDeviceWrapper
|
|
36
|
-
from wasatch.RealUSBDevice import RealUSBDevice
|
|
37
29
|
|
|
38
30
|
log = logging.getLogger(__name__)
|
|
39
31
|
|
|
@@ -45,7 +37,7 @@ class WasatchDemo:
|
|
|
45
37
|
# #
|
|
46
38
|
############################################################################
|
|
47
39
|
|
|
48
|
-
def __init__(self
|
|
40
|
+
def __init__(self):
|
|
49
41
|
self.bus = None
|
|
50
42
|
self.devices = {}
|
|
51
43
|
self.logger = None
|
|
@@ -53,7 +45,7 @@ class WasatchDemo:
|
|
|
53
45
|
self.exiting = False
|
|
54
46
|
self.reading_count = 0
|
|
55
47
|
|
|
56
|
-
self.args = self.parse_args(
|
|
48
|
+
self.args = self.parse_args()
|
|
57
49
|
|
|
58
50
|
if self.args.log_level != "NEVER":
|
|
59
51
|
self.logger = applog.MainLogger(self.args.log_level)
|
|
@@ -65,7 +57,7 @@ class WasatchDemo:
|
|
|
65
57
|
# #
|
|
66
58
|
############################################################################
|
|
67
59
|
|
|
68
|
-
def parse_args(self
|
|
60
|
+
def parse_args(self):
|
|
69
61
|
parser = argparse.ArgumentParser(description="Simple demo to acquire spectra from command-line interface")
|
|
70
62
|
parser.add_argument("--log-level", type=str, default="INFO", help="logging level", choices=["DEBUG","INFO","WARNING","ERROR","CRITICAL","NEVER"])
|
|
71
63
|
parser.add_argument("--integration-time-ms", type=int, default=10, help="integration time (ms, default 10)")
|
|
@@ -78,8 +70,7 @@ class WasatchDemo:
|
|
|
78
70
|
parser.add_argument("--ascii-art", action="store_true", help="graph spectra in ASCII")
|
|
79
71
|
parser.add_argument("--version", action="store_true", help="display Wasatch.PY version and exit")
|
|
80
72
|
|
|
81
|
-
|
|
82
|
-
args = parser.parse_args(argv[1:])
|
|
73
|
+
args = parser.parse_args()
|
|
83
74
|
if args.version:
|
|
84
75
|
print("Wasatch.PY %s" % wasatch.__version__)
|
|
85
76
|
sys.exit(0)
|
|
@@ -100,7 +91,7 @@ class WasatchDemo:
|
|
|
100
91
|
# lazy-load a USB bus
|
|
101
92
|
if self.bus is None:
|
|
102
93
|
log.debug("instantiating WasatchBus")
|
|
103
|
-
self.bus = WasatchBus(
|
|
94
|
+
self.bus = WasatchBus()
|
|
104
95
|
|
|
105
96
|
if not self.bus.device_ids:
|
|
106
97
|
print("No Wasatch USB spectrometers found.")
|
|
@@ -170,16 +161,30 @@ class WasatchDemo:
|
|
|
170
161
|
# read spectra until user presses Control-Break
|
|
171
162
|
while not self.exiting:
|
|
172
163
|
start_time = datetime.datetime.now()
|
|
164
|
+
|
|
173
165
|
if not self.args.non_blocking:
|
|
166
|
+
# if not non-blocking (i.e., blocking calls to Wasatch.PY), call
|
|
167
|
+
# device.acquire_data() directly -- this will block on each
|
|
168
|
+
# spectrometer in turn until we have collected one spectrum from each
|
|
169
|
+
# connected spectromter
|
|
174
170
|
for device_id, device in self.devices.items():
|
|
175
171
|
self.attempt_reading(device)
|
|
172
|
+
else:
|
|
173
|
+
# if we are non-blocking (meaning each spectrometer is free-
|
|
174
|
+
# running in its own background thread, then we don't need to do
|
|
175
|
+
# anything here -- spectra will magically "show up" at
|
|
176
|
+
# WasatchDeviceWrapper_callback without us having to do anything,
|
|
177
|
+
# and all we need to here is check whether we've collected enough
|
|
178
|
+
# spectra to shutdown
|
|
179
|
+
pass
|
|
180
|
+
|
|
176
181
|
end_time = datetime.datetime.now()
|
|
177
182
|
|
|
178
183
|
if self.args.max > 0 and self.reading_count >= self.args.max:
|
|
179
184
|
log.debug("max spectra reached, exiting")
|
|
180
185
|
self.exiting = True
|
|
181
186
|
else:
|
|
182
|
-
# compute how much longer we should wait before the next
|
|
187
|
+
# compute how much longer we should wait before the next "tick"
|
|
183
188
|
reading_time_ms = int((end_time - start_time).microseconds / 1000)
|
|
184
189
|
sleep_ms = self.args.delay_ms - reading_time_ms
|
|
185
190
|
if sleep_ms > 0:
|
|
@@ -215,11 +220,10 @@ class WasatchDemo:
|
|
|
215
220
|
self.process_reading(reading_response.data)
|
|
216
221
|
|
|
217
222
|
def acquire_reading(self, device):
|
|
218
|
-
# We want the demo to effectively block on new scans, so keep
|
|
219
|
-
#
|
|
220
|
-
#
|
|
221
|
-
#
|
|
222
|
-
# yet ready).
|
|
223
|
+
# We want the demo to effectively block on new scans, so keep polling the
|
|
224
|
+
# background thread until a reading is ready. In other apps, we could do
|
|
225
|
+
# other things (like respond to GUI events) if device.acquire_data() was
|
|
226
|
+
# None (meaning the next spectrum wasn't yet ready).
|
|
223
227
|
while True:
|
|
224
228
|
reading = device.acquire_data()
|
|
225
229
|
if reading is None:
|
|
@@ -241,8 +245,8 @@ class WasatchDemo:
|
|
|
241
245
|
|
|
242
246
|
def process_reading(self, reading):
|
|
243
247
|
if (self.exiting or
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
(self.args.scans_to_average > 1 and not reading.averaged) or
|
|
249
|
+
(self.args.max > 0 and self.reading_count >= self.args.max)):
|
|
246
250
|
return
|
|
247
251
|
|
|
248
252
|
device_id = reading.device_id
|
|
@@ -264,9 +268,8 @@ class WasatchDemo:
|
|
|
264
268
|
spectrum_max = numpy.amax(spectrum)
|
|
265
269
|
spectrum_avg = numpy.mean(spectrum)
|
|
266
270
|
spectrum_std = numpy.std (spectrum)
|
|
267
|
-
size_in_bytes = psutil.Process(os.getpid()).memory_info().rss
|
|
268
271
|
|
|
269
|
-
print("%s: %s %4d Detector: %5.2f degC Min: %8.2f Max: %8.2f Avg: %8.2f StdDev: %8.2f
|
|
272
|
+
print("%s: %s %4d Detector: %5.2f degC Min: %8.2f Max: %8.2f Avg: %8.2f StdDev: %8.2f" % (
|
|
270
273
|
reading.timestamp,
|
|
271
274
|
settings.eeprom.serial_number,
|
|
272
275
|
self.reading_count,
|
|
@@ -274,8 +277,7 @@ class WasatchDemo:
|
|
|
274
277
|
spectrum_min,
|
|
275
278
|
spectrum_max,
|
|
276
279
|
spectrum_avg,
|
|
277
|
-
spectrum_std
|
|
278
|
-
size_in_bytes))
|
|
280
|
+
spectrum_std))
|
|
279
281
|
log.debug("%s", str(reading))
|
|
280
282
|
|
|
281
283
|
if self.outfile:
|
|
@@ -313,7 +315,7 @@ demo = None
|
|
|
313
315
|
if __name__ == "__main__":
|
|
314
316
|
signal.signal(signal.SIGINT, signal_handler)
|
|
315
317
|
|
|
316
|
-
demo = WasatchDemo(
|
|
318
|
+
demo = WasatchDemo()
|
|
317
319
|
if demo.connect():
|
|
318
320
|
# Note that on Windows, Control-Break (SIGBREAK) differs from
|
|
319
321
|
# Control-C (SIGINT); see https://stackoverflow.com/a/1364199
|
|
@@ -47,7 +47,7 @@ class AndorDevice(InterfaceDevice):
|
|
|
47
47
|
SUCCESS = 20002 #!< see load_error_codes()
|
|
48
48
|
SHUTTER_SPEED_MS = 50 #!< allow time for mechanical shutter to stabilize
|
|
49
49
|
|
|
50
|
-
def __init__(self, device_id, message_queue=None): # -> None
|
|
50
|
+
def __init__(self, device_id, message_queue=None, alert_queue=None): # -> None
|
|
51
51
|
# if passed a string representation of a DeviceID, deserialize it
|
|
52
52
|
super().__init__()
|
|
53
53
|
if type(device_id) is str:
|
|
@@ -55,6 +55,7 @@ class AndorDevice(InterfaceDevice):
|
|
|
55
55
|
|
|
56
56
|
self.device_id = device_id
|
|
57
57
|
self.message_queue = message_queue
|
|
58
|
+
self.alert_queue = alert_queue
|
|
58
59
|
|
|
59
60
|
self.load_error_codes()
|
|
60
61
|
|
|
@@ -329,7 +330,6 @@ class AndorDevice(InterfaceDevice):
|
|
|
329
330
|
log.debug("completed take_one")
|
|
330
331
|
self.change_setting("cancel_take_one", True)
|
|
331
332
|
|
|
332
|
-
|
|
333
333
|
log.debug("device.take_one_averaged_reading: returning %s", reading)
|
|
334
334
|
if reading.spectrum is not None and reading.spectrum != []:
|
|
335
335
|
self.failure_count = 0
|