Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ocean Optics Multi-Channel Spectrometry Oddities #116

Open
evantaylor opened this issue Jun 16, 2021 · 1 comment
Open

Ocean Optics Multi-Channel Spectrometry Oddities #116

evantaylor opened this issue Jun 16, 2021 · 1 comment

Comments

@evantaylor
Copy link

evantaylor commented Jun 16, 2021

spectrometer and system information

  • model: Ocean Optics Jaz
  • operating system: Any
  • python version: 3.9.5
  • python-seabreeze version: 1.3.0
  • installed-via: pip

current problem

Ocean Optics Jaz Spectrometers provide multi-channel support for spectrometry. However, the seabreeze module defaults to a single channel with the normally supplied functions.

Andreas supplied example code for changing the channel using the f.raw_usb_bus.access functionality, but there is a timeout (well it just hangs, actually) issue when querying the devices for the number of modules/channels installed on the Jaz devices.

Good News: If you know your number of installed channels you can work around this and just directly send commands to set the channel.

Bad News: If you send the wrong command the device needs to be reset.

Weird News: If you work around the issue you must reset the channel you are polling from because the Jaz device Serial changes to each submodules.

steps to reproduce

import seabreeze
seabreeze.use('cseabreeze')
from seabreeze.spectrometers import list_devices, Spectrometer
import time
import struct

def init_seabreeze():
    global devices
    devices = []
    for i in list_devices():
        device_name = str(i)[-9:][:-1]
        devices.append(device_name)
    return devices

def get_channels(device):
    spec = Spectrometer.from_serial_number(device)
    spec.f.raw_usb_bus_access.raw_usb_write(data=struct.pack('<B', 0xC0), endpoint='primary_out')
    data = spec.f.raw_usb_bus_access.raw_usb_read(endpoint='primary_in')
    num_channels = struct.unpack('<B', data)
    return num_channels

If you pass either device string from the list devices, the query will hang on spec.f.raw_usb_access.raw_usb_read(endpoint='primary_in')

work-around

To work around this issue, I have some code for selecting the device channel as per Andreas' e-mail, as well as a function to keep the USB device ID consistent by resetting the channel.

def get_spectra(device, channel):
    spec = Spectrometer.from_serial_number(device)
    spec.f.raw_usb_bus_access.raw_usb_write(data=struct.pack('<BB', 0xC1, channel), endpoint='primary_out')
    time.sleep(.5)  # Not necessary?
    wavelengths = spec.wavelengths()
    intensities = spec.intensities()
    reset_channel(spec)
    spec.close()
    data = dict(zip(wavelengths, intensities))
    return data


def reset_channel(spec):
    channel = 0
    spec.f.raw_usb_bus_access.raw_usb_write(data=struct.pack('<BB', 0xC1, channel), endpoint='primary_out')

Apologies if this is not super clear, this is my first issue/bug report/sharing of my own work-around.

@ap--
Copy link
Owner

ap-- commented Jun 17, 2021

Hi @evantaylor

Here's a few things you could try:

  • use 'secondary_in' or 'secondary_in2' as the endpoint argument for the read command
  • use the pyseabreeze backend

if none of the above work, I'll try to provide an example with the pyseabreeze backend that allows us to debug why it's not working

Cheers,
Andreas 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants