wasatch 2.2.14__tar.gz → 2.2.17__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.
Files changed (93) hide show
  1. {wasatch-2.2.14 → wasatch-2.2.17}/CHANGELOG.md +16 -0
  2. {wasatch-2.2.14 → wasatch-2.2.17}/PKG-INFO +1 -1
  3. {wasatch-2.2.14 → wasatch-2.2.17}/demo.py +0 -2
  4. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/AndorDevice.py +95 -39
  5. wasatch-2.2.17/wasatch/BLEDevice.py +1032 -0
  6. wasatch-2.2.17/wasatch/DeviceFinderBLE.py +107 -0
  7. wasatch-2.2.17/wasatch/DeviceFinderTCP.py +20 -0
  8. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/DeviceFinderUSB.py +0 -4
  9. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/DeviceID.py +110 -54
  10. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/EEPROM.py +61 -67
  11. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/FeatureIdentificationDevice.py +28 -11
  12. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/FirmwareRequirements.py +1 -1
  13. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/InterfaceDevice.py +3 -4
  14. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/ROI.py +12 -4
  15. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/SpectrometerSettings.py +33 -22
  16. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/SpectrometerState.py +1 -0
  17. wasatch-2.2.17/wasatch/TCPDevice.py +410 -0
  18. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/TakeOneRequest.py +17 -11
  19. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/WasatchBus.py +40 -15
  20. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/WasatchDevice.py +12 -3
  21. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/WasatchDeviceWrapper.py +32 -35
  22. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/WrapperWorker.py +48 -37
  23. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/__init__.py +1 -1
  24. wasatch-2.2.14/wasatch/BLEDevice.py +0 -457
  25. {wasatch-2.2.14 → wasatch-2.2.17}/.example_pypirc +0 -0
  26. {wasatch-2.2.14 → wasatch-2.2.17}/.flake8 +0 -0
  27. {wasatch-2.2.14 → wasatch-2.2.17}/.gitignore +0 -0
  28. {wasatch-2.2.14 → wasatch-2.2.17}/.pylintrc +0 -0
  29. {wasatch-2.2.14 → wasatch-2.2.17}/Doxyfile +0 -0
  30. {wasatch-2.2.14 → wasatch-2.2.17}/LICENSE +0 -0
  31. {wasatch-2.2.14 → wasatch-2.2.17}/MANIFEST.in +0 -0
  32. {wasatch-2.2.14 → wasatch-2.2.17}/Makefile +0 -0
  33. {wasatch-2.2.14 → wasatch-2.2.17}/README.md +0 -0
  34. {wasatch-2.2.14 → wasatch-2.2.17}/README_PYPI.md +0 -0
  35. {wasatch-2.2.14 → wasatch-2.2.17}/README_RPI.md +0 -0
  36. {wasatch-2.2.14 → wasatch-2.2.17}/README_SETTINGS.md +0 -0
  37. {wasatch-2.2.14 → wasatch-2.2.17}/README_VIRTUAL.md +0 -0
  38. {wasatch-2.2.14 → wasatch-2.2.17}/WasatchShell/README.md +0 -0
  39. {wasatch-2.2.14 → wasatch-2.2.17}/WasatchShell/laser-test.py +0 -0
  40. {wasatch-2.2.14 → wasatch-2.2.17}/WasatchShell/load-test.py +0 -0
  41. {wasatch-2.2.14 → wasatch-2.2.17}/WasatchShell/one-shot.py +0 -0
  42. {wasatch-2.2.14 → wasatch-2.2.17}/WasatchShell/wasatch-shell.py +0 -0
  43. {wasatch-2.2.14 → wasatch-2.2.17}/demo-auto-raman.py +0 -0
  44. {wasatch-2.2.14 → wasatch-2.2.17}/demo-simple.py +0 -0
  45. {wasatch-2.2.14 → wasatch-2.2.17}/demo-virtual.py +0 -0
  46. {wasatch-2.2.14 → wasatch-2.2.17}/demo-workflow.py +0 -0
  47. {wasatch-2.2.14 → wasatch-2.2.17}/environments/conda-linux.yml +0 -0
  48. {wasatch-2.2.14 → wasatch-2.2.17}/environments/conda-macos.yml +0 -0
  49. {wasatch-2.2.14 → wasatch-2.2.17}/environments/conda-rpi.yml +0 -0
  50. {wasatch-2.2.14 → wasatch-2.2.17}/environments/conda-win10.yml +0 -0
  51. {wasatch-2.2.14 → wasatch-2.2.17}/pyproject.toml +0 -0
  52. {wasatch-2.2.14 → wasatch-2.2.17}/requirements.txt +0 -0
  53. {wasatch-2.2.14 → wasatch-2.2.17}/screenshots/multiplatform.png +0 -0
  54. {wasatch-2.2.14 → wasatch-2.2.17}/scripts/dark-vs-integ.py +0 -0
  55. {wasatch-2.2.14 → wasatch-2.2.17}/scripts/deploy +0 -0
  56. {wasatch-2.2.14 → wasatch-2.2.17}/setup.cfg +0 -0
  57. {wasatch-2.2.14 → wasatch-2.2.17}/testSpectrometers/SiG_785/eeprom/EEPROM-EM-9c65d19f4c.json +0 -0
  58. {wasatch-2.2.14 → wasatch-2.2.17}/testSpectrometers/SiG_785/readings/enlighten-20210329-094722-799520-WP-00686.csv +0 -0
  59. {wasatch-2.2.14 → wasatch-2.2.17}/testSpectrometers/SiG_785/readings/enlighten-20210329-094755-288958-WP-00686.csv +0 -0
  60. {wasatch-2.2.14 → wasatch-2.2.17}/testSpectrometers/WP-00887/eeprom/WP-00887-mock.json +0 -0
  61. {wasatch-2.2.14 → wasatch-2.2.17}/testSpectrometers/WP-00904/eeprom/WP-00904-mock.json +0 -0
  62. {wasatch-2.2.14 → wasatch-2.2.17}/testSpectrometers/WP-00913/eeprom/WP-00913-mock.json +0 -0
  63. {wasatch-2.2.14 → wasatch-2.2.17}/tests/existing_implementations.py +0 -0
  64. {wasatch-2.2.14 → wasatch-2.2.17}/tests/noise-by-setpoint.py +0 -0
  65. {wasatch-2.2.14 → wasatch-2.2.17}/tests/queues.py +0 -0
  66. {wasatch-2.2.14 → wasatch-2.2.17}/tests/unit.py +0 -0
  67. {wasatch-2.2.14 → wasatch-2.2.17}/udev/10-wasatch.rules +0 -0
  68. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/AbstractUSBDevice.py +0 -0
  69. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/AutoRaman.py +0 -0
  70. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/AutoRamanRequest.py +0 -0
  71. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/BalanceAcquisition.py +0 -0
  72. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/CSVLoader.py +0 -0
  73. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/CommandSettings.py +0 -0
  74. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/ControlObject.py +0 -0
  75. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/DetectorROI.py +0 -0
  76. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/DetectorRegions.py +0 -0
  77. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/EEPROM_multical.sav +0 -0
  78. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/FPGAOptions.py +0 -0
  79. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/HardwareInfo.py +0 -0
  80. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/IMX385.py +0 -0
  81. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/MockUSBDevice.py +0 -0
  82. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/OceanDevice.py +0 -0
  83. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/PollStatus.py +0 -0
  84. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/ProcessedReading.py +0 -0
  85. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/Reading.py +0 -0
  86. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/RealUSBDevice.py +0 -0
  87. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/SPIDevice.py +0 -0
  88. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/SpectrometerRequest.py +0 -0
  89. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/SpectrometerResponse.py +0 -0
  90. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/StatusMessage.py +0 -0
  91. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/applog.py +0 -0
  92. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/simulation_protocol.py +0 -0
  93. {wasatch-2.2.14 → wasatch-2.2.17}/wasatch/utils.py +0 -0
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ - 2025-02-11 2.2.17
4
+ - [#133] merged in Fast BatchCollection fixes, part of ENLIGHTEN [#516]
5
+ - 2025-01-20 2.2.16
6
+ - trace previous integration time, use in computing timeouts
7
+ - disable automatic laser shutoff at connection
8
+ - 2024-12-06 2.2.15
9
+ - XL Fixes
10
+ - fixed scan averaging
11
+ - fixed detector temperature readout
12
+ - support vertical ROI (successfully tested (118, 138) ie (center 128, height 20))
13
+ - flag non-downloaded Andor EEPROMs as 'stubbed'
14
+ - EEPROM
15
+ - allow MultiWavelengthCalibration.set to support any EEPROM property
16
+ - fixed Raman Intensity Calibration (broke in 2.2.14)
17
+ - raman_intensity_calibration_order (standardized on 5th-order polynomial)
18
+ - force integral ROI
3
19
  - 2024-11-25 2.2.14
4
20
  - EEPROM
5
21
  - added subformat 5 (EEPROM.MultiWavelengthCalibration)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wasatch
3
- Version: 2.2.14
3
+ Version: 2.2.17
4
4
  Summary: This package is a driver for Wasatch Photonics spectrometers
5
5
  Author-email: Wasatch Photonics <edort@wasatchphotonics.com>
6
6
  Description-Content-Type: text/markdown
@@ -6,8 +6,6 @@
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
- # INVOCATION: $ python -u demo.py #
10
- # #
11
9
  ################################################################################
12
10
 
13
11
  import os
@@ -11,6 +11,7 @@ from .SpectrometerResponse import SpectrometerResponse
11
11
  from .InterfaceDevice import InterfaceDevice
12
12
  from .DeviceID import DeviceID
13
13
  from .Reading import Reading
14
+ from .ROI import ROI
14
15
 
15
16
  log = logging.getLogger(__name__)
16
17
 
@@ -67,6 +68,8 @@ class AndorDevice(InterfaceDevice):
67
68
 
68
69
  self.immediate_mode = False
69
70
 
71
+ # An AndorDevice has-a SpectrometerSettings, which has-a EEPROM, which
72
+ # has-a MultiWavelengthCalibration
70
73
  self.settings = SpectrometerSettings(self.device_id)
71
74
  self.summed_spectra = None
72
75
  self.sum_count = 0
@@ -125,16 +128,19 @@ class AndorDevice(InterfaceDevice):
125
128
  # set Andor defaults for important "EEPROM" settings
126
129
  # (all but has_cooling can be overridden via config file)
127
130
 
128
- # Andor API doesn't have access to detector info
129
- # Note that we use non-iDus cameras, including the Newton
131
+ # Andor API doesn't(?) seem to have access to detector info.
132
+ # Note that we use non-iDus cameras, including the Newton.
130
133
  self.settings.eeprom.detector = "iDus"
131
- self.settings.eeprom.wavelength_coeffs = [0,1,0,0]
134
+
132
135
  self.settings.eeprom.has_cooling = True
133
136
  self.settings.eeprom.startup_integration_time_ms = 10
134
137
  self.settings.eeprom.startup_temp_degC = -60
135
138
  self.settings.eeprom.detector_gain = 1
136
139
  self.settings.eeprom.detector_gain_odd = 1
137
140
 
141
+ # MultiWavelengthCalibration attributes
142
+ self.settings.eeprom.multi_wavelength_calibration.set("wavelength_coeffs", [0,1,0,0,0])
143
+
138
144
  self.process_f = self._init_process_funcs()
139
145
 
140
146
  ###############################################################
@@ -144,28 +150,29 @@ class AndorDevice(InterfaceDevice):
144
150
  def _init_process_funcs(self):
145
151
  process_f = {}
146
152
 
147
- process_f["connect"] = self.connect
148
- process_f["acquire_data"] = self.acquire_data
149
- process_f["set_shutter_enable"] = self.set_shutter_enable
150
- process_f["set_integration_time_ms"] = self.set_integration_time_ms
151
- process_f["get_serial_number"] = self.get_serial_number
152
- process_f["init_tec_setpoint"] = self.init_tec_setpoint
153
- process_f["set_tec_setpoint"] = self.set_tec_setpoint
154
- process_f["init_detector_area"] = self.init_detector_area
155
- process_f["scans_to_average"] = self.scans_to_average
156
- process_f["high_gain_mode_enable"] = self.high_gain_mode_enable
157
- process_f["save_config"] = self.save_config
153
+ process_f["connect"] = self.connect
154
+ process_f["acquire_data"] = self.acquire_data
155
+ process_f["set_shutter_enable"] = self.set_shutter_enable
156
+ process_f["set_integration_time_ms"] = self.set_integration_time_ms
157
+ process_f["get_serial_number"] = self.get_serial_number
158
+ process_f["init_tec_setpoint"] = self.init_tec_setpoint
159
+ process_f["set_tec_setpoint"] = self.set_tec_setpoint
160
+ process_f["init_detector_area"] = self.init_detector_area
161
+ process_f["scans_to_average"] = self.scans_to_average
162
+ process_f["high_gain_mode_enable"] = self.high_gain_mode_enable
163
+ process_f["save_config"] = self.save_config
164
+ process_f["vertical_binning"] = self.set_vertical_binning
158
165
 
159
166
  ##################################################################
160
167
  # What follows is the old init-lambdas that are squashed into process_f
161
168
  # Long term, the upstream requests should be changed to match the new format
162
169
  # This is an easy fix for the time being to make things behave
163
170
  ##################################################################
164
- process_f["integration_time_ms"] = lambda x: self.set_integration_time_ms(x) # conversion from millisec to microsec
165
- process_f["fan_enable"] = lambda x: self.set_fan_enable(bool(x))
166
- process_f["shutter_enable"] = lambda x: self.set_shutter_enable(bool(x))
167
- process_f["detector_tec_enable"] = lambda x: self.toggle_tec(bool(x))
168
- process_f["detector_tec_setpoint_degC"] = lambda x: self.set_tec_setpoint(int(round(x)))
171
+ process_f["integration_time_ms"] = lambda x: self.set_integration_time_ms(x)
172
+ process_f["fan_enable"] = lambda x: self.set_fan_enable(bool(x))
173
+ process_f["shutter_enable"] = lambda x: self.set_shutter_enable(bool(x))
174
+ process_f["detector_tec_enable"] = lambda x: self.toggle_tec(bool(x))
175
+ process_f["detector_tec_setpoint_degC"] = lambda x: self.set_tec_setpoint(int(round(x)))
169
176
 
170
177
  return process_f
171
178
 
@@ -181,12 +188,6 @@ class AndorDevice(InterfaceDevice):
181
188
  log.debug(f"for {enabled} setting gain to {self.gain_options[0]}")
182
189
  return
183
190
 
184
- # MZ: nothing seems to call this?
185
- def _update_wavelength_coeffs(self, coeffs):
186
- self.settings.eeprom.wavelength_coeffs = coeffs
187
- self.config_values['wavelength_coeffs'] = coeffs
188
- self.save_config()
189
-
190
191
  def set_fan_enable(self, x):
191
192
  self.check_result(self.driver.SetFanMode(int(x)), f"Andor Fan On {x}")
192
193
  return SpectrometerResponse()
@@ -228,10 +229,10 @@ class AndorDevice(InterfaceDevice):
228
229
 
229
230
  return convertedSpec
230
231
 
231
- def _take_one_averaged_reading(self): # -> SpectrometerResponse
232
+ def _take_one_averaged_reading(self):
232
233
  averaging_enabled = (self.settings.state.scans_to_average > 1)
233
234
 
234
- if averaging_enabled and not self.settings.state.free_running_mode:
235
+ if averaging_enabled:
235
236
  # collect the entire averaged spectrum at once (added for
236
237
  # BatchCollection with laser delay)
237
238
  #
@@ -258,7 +259,7 @@ class AndorDevice(InterfaceDevice):
258
259
  if self.tec_enabled:
259
260
  log.debug("TEC enabled, so reading temperature")
260
261
 
261
- use_float = True # seems to work on 785XL (WP-01635)
262
+ use_float = True # seems to work on 785XL (WP-01635 and WP-01491)
262
263
 
263
264
  if use_float:
264
265
  c_temp = c_float()
@@ -269,7 +270,11 @@ class AndorDevice(InterfaceDevice):
269
270
 
270
271
  label = self.get_error_code(result)
271
272
 
272
- if label in ["DRV_SUCCESS", "DRV_TEMP_STABILIZED", "DRV_TEMP_NOT_REACHED", "DRV_TEMP_DRIFT", "DRV_TEMP_NOT_STABILIZED"]:
273
+ if label in [ "DRV_SUCCESS",
274
+ "DRV_TEMPERATURE_DRIFT",
275
+ "DRV_TEMPERATURE_STABILIZED",
276
+ "DRV_TEMPERATURE_NOT_REACHED",
277
+ "DRV_TEMPERATURE_NOT_STABILIZED" ]:
273
278
  reading.detector_temperature_degC = c_temp.value
274
279
  log.debug(f"Andor temperature {reading.detector_temperature_degC:.2f} ({label})")
275
280
  else:
@@ -380,13 +385,20 @@ class AndorDevice(InterfaceDevice):
380
385
  self.init_detector_area() # step 7
381
386
 
382
387
  if not self._check_config_file():
388
+ log.debug("stubbing Andor EEPROM")
389
+ self.settings.eeprom.stubbed = True
383
390
  self.config_values = {
384
391
  'detector_serial_number': self.serial,
385
- 'wavelength_coeffs': [0,1,0,0],
392
+ 'wavelength_coeffs': [0,1,0,0,0],
386
393
  'excitation_nm_float': 0,
387
394
  'raman_intensity_coeffs': [],
388
395
  'raman_intensity_calibration_order': 0,
389
- 'invert_x_axis': False
396
+ 'invert_x_axis': False,
397
+ 'roi_horizontal_start': 0,
398
+ 'roi_horizontal_end': 0,
399
+ 'roi_vertical_region_1_start': 0,
400
+ 'roi_vertical_region_1_end': 0,
401
+ 'stubbed': True
390
402
  }
391
403
  log.debug(f"connect: config file not found, so defaulting to these: {self.config_values}")
392
404
  self.save_config()
@@ -411,6 +423,14 @@ class AndorDevice(InterfaceDevice):
411
423
  # step 17 (WasatchNET doesn't do this)
412
424
  self._obtain_gain_info()
413
425
 
426
+ # step 18 (WasatchNET doesn't do this)
427
+ roi = ROI(self.settings.eeprom.roi_vertical_region_1_start,
428
+ self.settings.eeprom.roi_vertical_region_1_end)
429
+ if roi.start != 0 and roi.end != 0:
430
+ # although camera can probably support the (0, 0) case, it's
431
+ # convenient to treat as unconfigured defaults
432
+ self.set_vertical_binning(roi)
433
+
414
434
  # success!
415
435
  log.info("AndorDevice successfully connected")
416
436
 
@@ -419,6 +439,40 @@ class AndorDevice(InterfaceDevice):
419
439
  self.settings.eeprom.has_cooling = True
420
440
  return SpectrometerResponse(data=True)
421
441
 
442
+ def set_vertical_binning(self, roi):
443
+ """
444
+ Note that this follows the same (start, end) vertical ROI API as
445
+ FeatureInterfaceDevice.set_vertical_binning, and dynamically translates
446
+ that into the (middle, height) Andor API.
447
+ """
448
+
449
+ if isinstance(roi, ROI):
450
+ start, end = roi.start, roi.end
451
+ elif len(roi) == 2:
452
+ start, end = roi[0], roi[1]
453
+ else:
454
+ log.error("set_vertical_binning requires an ROI object or tuple of (start, stop) lines")
455
+ return SpectrometerResponse(data=False, error_msg="invalid start and stop lines")
456
+
457
+ if start < 0 or end < 0:
458
+ log.error("set_vertical_binning requires POSITIVE (start, stop) lines")
459
+ return SpectrometerResponse(data=False, error_msg="invalid start and stop lines")
460
+
461
+ # enforce ascending order
462
+ if start >= end:
463
+ log.error("set_vertical_binning requires ascending order (ignoring %d, %d)", start, end)
464
+ return SpectrometerResponse(data=False, error_msg="invalid start and stop lines")
465
+
466
+
467
+ height = end - start
468
+ center = int(round(height / 2, 0)) + start
469
+
470
+ log.debug(f"setting Single-Track vertical binning of ROI (start {start}, end {end}) (center {center}, height {height})")
471
+ self.check_result(self.driver.SetReadMode(3), "SetReadMode(single-track)")
472
+ self.check_result(self.driver.SetSingleTrack(center, height), "SetSingleTrack")
473
+
474
+ return SpectrometerResponse(data=True)
475
+
422
476
  def save_config(self, eeprom=None):
423
477
  """
424
478
  The user has edited the "virtual EEPROM", for instance using ENLIGHTEN's
@@ -428,7 +482,6 @@ class AndorDevice(InterfaceDevice):
428
482
  @param eeprom: if provided, overwrite current settings with those in the
429
483
  passed dict before writing to disk
430
484
  """
431
- log.debug("save_config: here")
432
485
  if eeprom is not None:
433
486
  self.update_config_from_eeprom(eeprom)
434
487
 
@@ -444,13 +497,13 @@ class AndorDevice(InterfaceDevice):
444
497
  # first, copy over any EEPROM fields which have a different name in
445
498
  # wasatch.EEPROM vs the external JSON file
446
499
  for json_name, python_name in self.config_names_to_eeprom.items():
447
- self.config_values[json_name] = getattr(eeprom, python_name)
500
+ self.config_values[json_name] = eeprom.multi_wavelength_calibration.get(python_name)
448
501
 
449
502
  # now do all the standard attributes of the wasatch.EEPROM, adding
450
503
  # their values into the same dict
451
- for python_name, python_value in eeprom.__dict__.items():
504
+ for python_name in eeprom.__dict__:
452
505
  if python_name in self.config_values:
453
- self.config_values[python_name] = python_value
506
+ self.config_values[python_name] = eeprom.multi_wavelength_calibration.get(python_name)
454
507
 
455
508
  def _load_config_values(self):
456
509
  """
@@ -463,10 +516,11 @@ class AndorDevice(InterfaceDevice):
463
516
  # handle wp_ prefixes
464
517
  for k, v in self.config_names_to_eeprom.items():
465
518
  if k in self.config_values:
466
- setattr(self.settings.eeprom, v, self.config_values[k])
519
+ self.settings.eeprom.multi_wavelength_calibration.set(v, self.config_values[k])
467
520
 
468
521
  # same spelling
469
522
  for k in [ 'model',
523
+ 'stubbed',
470
524
  'detector',
471
525
  'serial_number',
472
526
  'invert_x_axis',
@@ -474,17 +528,19 @@ class AndorDevice(InterfaceDevice):
474
528
  'excitation_nm_float',
475
529
  'roi_horizontal_end',
476
530
  'roi_horizontal_start',
531
+ 'roi_vertical_region_1_start',
532
+ 'roi_vertical_region_1_end',
477
533
  'raman_intensity_coeffs',
478
534
  'raman_intensity_calibration_order',
479
535
  'startup_temp_degC',
480
536
  'startup_integration_time_ms' ]:
481
537
  if k in self.config_values:
482
- setattr(self.settings.eeprom, k, self.config_values[k])
538
+ self.settings.eeprom.multi_wavelength_calibration.set(k, self.config_values[k])
483
539
 
484
540
  # default missing-but-obvious fields
485
541
  if "raman_intensity_coeffs" in self.config_values:
486
542
  if "raman_intensity_calibration_order" not in self.config_values:
487
- self.settings.eeprom.raman_intensity_calibration_order = len(self.settings.eeprom.raman_intensity_coeffs) - 1
543
+ self.settings.eeprom.multi_wavelength_calibration.set("raman_intensity_calibration_order", len(self.settings.eeprom.raman_intensity_coeffs) - 1)
488
544
 
489
545
  # post-load initialization
490
546
  if 'startup_temp_degC' in self.config_values:
@@ -570,9 +626,9 @@ class AndorDevice(InterfaceDevice):
570
626
  xPixels = c_int()
571
627
  yPixels = c_int()
572
628
  self.check_result(self.driver.GetDetector(byref(xPixels), byref(yPixels)), "GetDetector(x, y)")
573
- log.debug(f"detector {xPixels.value} width x {yPixels.value} height")
574
629
  self.pixels = xPixels.value
575
630
  self.height = yPixels.value
631
+ log.debug(f"detector {self.pixels} width x {self.height} height")
576
632
  return SpectrometerResponse(True)
577
633
 
578
634
  def _obtain_gain_info(self):