ap-- / python-seabreeze

Python module for OceanOptics spectrometers
https://python-seabreeze.readthedocs.io
MIT License
201 stars 80 forks source link

thermo_electric feature to the list of feature classes in NIRQUEST512 #223

Closed magnium closed 7 months ago

magnium commented 7 months ago

Hi, Thanks for the great job of creating this repository. I was interfacing our OceanView spectrometers one by one in raw mode until I stumbled on this. I added the thermo_electric feature to the list of feature classes in NIRQUEST512 after testing it with my spectrometer.

In theory, the strobe_lump feature should also work, but I don't know how to use it and no implementation exists yet in pyseabreeze.features for OOI protocol.

Another possible feature is the detector high gain mode, but 1) it doesn't seem to make any difference on my spectrometer, 2) I don't see anything in pyseabreeze.features that corresponds to this feature.

Also, here is result of running pytest:

================================================= test session starts =================================================
platform win32 -- Python 3.9.10, pytest-4.6.11, py-1.11.0, pluggy-0.13.1 -- C:\Users\raman\Documents\pydev\python-seabreeze\buildenv_py39_64\Scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\raman\Documents\pydev\python-seabreeze, inifile: pytest.ini
collected 28 items

tests/test_backends.py::test_seabreeze_installed PASSED                                                          [  3%]
tests/test_backends.py::test_seabreeze_wrong_backend_requested PASSED                                            [  7%]
tests/test_backends.py::test_seabreeze_any_backend_available[cseabreeze] PASSED                                  [ 10%]
tests/test_backends.py::test_seabreeze_any_backend_available[pyseabreeze] PASSED                                 [ 14%]
tests/test_backends.py::test_seabreeze_cseabreeze_backend_available PASSED                                       [ 17%]
tests/test_backends.py::test_seabreeze_pyseabreeze_backend_available PASSED                                      [ 21%]
tests/test_backends.py::test_seabreeze_cseabreeze_api_init PASSED                                                [ 25%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[any] PASSED                                          [ 28%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[openusb] PASSED                                      [ 32%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb0] PASSED                                      [ 35%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb1] PASSED                                      [ 39%]
tests/test_backends.py::test_seabreeze_compare_backend_feature_interfaces PASSED                                 [ 42%]
tests/test_protocol.py::test_pyseabreeze_protocol_messages PASSED                                                [ 46%]
tests/test_spectrometers.py::TestHardware::test_cant_find_serial[backend(any)] PASSED                            [ 50%]
tests/test_spectrometers.py::TestHardware::test_device_cleanup_on_exit[backend(any)] PASSED                      [ 53%]
tests/test_spectrometers.py::TestHardware::test_read_model[NIRQUEST512:NQ5200030-backend(any)] PASSED            [ 57%]
tests/test_spectrometers.py::TestHardware::test_read_serial_number[NIRQUEST512:NQ5200030-backend(any)] PASSED    [ 60%]
tests/test_spectrometers.py::TestHardware::test_crash_may_not_influence_following_tests[NIRQUEST512:NQ5200030-backend(any)] SKIPPED [ 64%]
tests/test_spectrometers.py::TestHardware::test_read_intensities[NIRQUEST512:NQ5200030-backend(any)] PASSED      [ 67%]
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[NIRQUEST512:NQ5200030-backend(any)] PASSED   [ 71%]
tests/test_spectrometers.py::TestHardware::test_read_wavelengths[NIRQUEST512:NQ5200030-backend(any)] PASSED      [ 75%]
tests/test_spectrometers.py::TestHardware::test_read_spectrum[NIRQUEST512:NQ5200030-backend(any)] PASSED         [ 78%]
tests/test_spectrometers.py::TestHardware::test_max_intensity[NIRQUEST512:NQ5200030-backend(any)] PASSED         [ 82%]
tests/test_spectrometers.py::TestHardware::test_integration_time_limits[NIRQUEST512:NQ5200030-backend(any)] PASSED [ 85%]
tests/test_spectrometers.py::TestHardware::test_integration_time[NIRQUEST512:NQ5200030-backend(any)] PASSED      [ 89%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode[NIRQUEST512:NQ5200030-backend(any)] PASSED          [ 92%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode_wrong[NIRQUEST512:NQ5200030-backend(any)] PASSED    [ 96%]
tests/test_spectrometers.py::TestHardware::test_list_devices_dont_close_opened_devices[backend(any)] PASSED      [100%]

================================================== warnings summary ===================================================
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[NIRQUEST512:NQ5200030-backend(any)]
  C:\Users\raman\Documents\pydev\python-seabreeze\buildenv_py39_64\lib\site-packages\numpy\core\fromnumeric.py:3504: RuntimeWarning: Mean of empty slice.
    return _methods._mean(a, axis=axis, dtype=dtype,

tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[NIRQUEST512:NQ5200030-backend(any)]
  C:\Users\raman\Documents\pydev\python-seabreeze\buildenv_py39_64\lib\site-packages\numpy\core\_methods.py:129: RuntimeWarning: invalid value encountered in scalar divide
    ret = ret.dtype.type(ret / rcount)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
=============================================== short test summary info ===============================================
SKIPPED [1] tests\test_spectrometers.py:237: FIXME: TEST BREAKS OTHER TESTS ON WINDOWS
================================== 27 passed, 1 skipped, 2 warnings in 7.24 seconds ===================================
magnium commented 7 months ago

In theory, the strobe_lump feature should also work, but I don't know how to use it and no implementation exists yet in pyseabreeze.features for OOI protocol.

Sorry, my bad. The real feature is continuous_strobe and the implementation for OOI exists. So one can add it to the list of NIRQUEST512 feature classes.

ap-- commented 7 months ago

Hi @magnium

Happy to hear that python-seabreeze is useful to you!

This PR looks good! Are you still adding the continuous_strobe feature? It sounded as if you tested it already with the NIRQUEST.

So far it adds:

Regarding the second change, could you test if this causes problems when switching from a long integration time to a shorter one and requesting a spectrum?

import seabreeze
seabreeze.use("pyseabreeze")
from seabreeze.spectrometers import Spectrometer

spec = Spectrometer.from_first_available()
spec.integration_time_micros(1_000_000)
spec.intensities()
spec.integration_time_micros(100)
spec.intensities()

Cheers, Andreas 😃

magnium commented 7 months ago

Hi Andreas,

I see now what continuous strobe feature makes (read in the manual) but I have no possibility to test it right now (I don't have a cable to connect my NIRQuest to an oscilloscope, only a trigger cable). Still, the feature is officially supported, so I think it makes sens to add it along with the thermoelectric. Can you edit the commit to add the necessary line or can I do it? Or do I have to make another commit?

In what concerns the trigger timeout, I tested your script with a NIRQuest (with and without triggered input) and a ST (without trigger input): it works perfectly in all cases (I had to change the small integration time to 2000 µs, since the ST's min integration time is 1560 µs). BTW, the reason why I can't use the max_integration_time as a timeout in NIRQuest, is because it's 120 s (cf. with 6 s in ST, which is bearable, but still too conservative).

import seabreeze
seabreeze.use("pyseabreeze")
from seabreeze.spectrometers import Spectrometer, list_devices
from seabreeze.pyseabreeze.devices import TriggerMode
from usb.core import USBTimeoutError

print(list_devices())
spec = Spectrometer.from_first_available()
spec.trigger_mode(TriggerMode.LEVEL)
spec.integration_time_micros(1_000_000)
try:
    spec.intensities()
except USBTimeoutError:
    print("Timeout")
spec.integration_time_micros(2000)
try:
    spec.intensities()
except USBTimeoutError:
    print("Timeout")

spec.trigger_mode(TriggerMode.NORMAL)
print(spec.intensities()[0])

Cheers,

Raman

ap-- commented 7 months ago

Still, the feature is officially supported, so I think it makes sens to add it along with the thermoelectric. Can you edit the commit to add the necessary line or can I do it? Or do I have to make another commit?

I'd prefer to add it once we confirm that it works. Some spectrometers might require special treatment that might not align with the datasheets.

In the meantime, I'll add your changes and cut a new release soon. We can always add more in later PRs.

Thanks again for your contribution ❤️ Cheers, Andreas

magnium commented 7 months ago

I'd prefer to add it once we confirm that it works. Some spectrometers might require special treatment that might not align with the datasheets.

I agree. Thanks for your work! Best, Raman