def _usb_init_connection(self, model): if model not in _OOModelConfig.keys(): raise _OOError('Unkown OceanOptics spectrometer model: %s' % model) vendorId, productId = _OOVendorId, _OOModelConfig[model]['ProductId'] self._EPout = _OOModelConfig[model]['EPout'] self._EPin0 = _OOModelConfig[model]['EPin0'] self._EPin1 = _OOModelConfig[model]['EPin1'] self._EPin0_size = _OOModelConfig[model]['EPin0_size'] self._EPin1_size = _OOModelConfig[model]['EPin1_size'] devices = usb.core.find(find_all=True, custom_match=lambda d: (d.idVendor==vendorId and d.idProduct in productId)) # FIXME: generator fix devices = list(devices) try: self._dev = devices.pop(0) except (AttributeError, IndexError): raise _OOError('No OceanOptics %s spectrometer found!' % model) else: if devices: warnings.warn('Currently the first device matching the ' 'Vendor/Product id is used') self._dev.set_configuration() self._USBTIMEOUT = self._dev.default_timeout * 1e-3
def _usb_init_connection(self, model): if model not in _OOModelConfig.keys(): raise _OOError('Unkown OceanOptics spectrometer model: %s' % model) # Add model self.model = model vendorId, productId = _OOVendorId, _OOModelConfig[model]['ProductId'] self._EPout = _OOModelConfig[model]['EPout'] self._EPin0 = _OOModelConfig[model]['EPin0'] self._EPin1 = _OOModelConfig[model]['EPin1'] self._EPin0_size = _OOModelConfig[model]['EPin0_size'] self._EPin1_size = _OOModelConfig[model]['EPin1_size'] self._min_integration_time, self._max_integration_time = _OOMinMaxIT[model] devices = usb.core.find(find_all=True, custom_match=lambda d: (d.idVendor==vendorId and d.idProduct in productId)) # FIXME: generator fix devices = list(devices) try: self._dev = devices.pop(0) except (AttributeError, IndexError): raise _OOError('No OceanOptics %s spectrometer found!' % model) else: if devices: warnings.warn('Currently the first device matching the ' 'Vendor/Product id is used') self._dev.set_configuration() self._USBTIMEOUT = self._dev.default_timeout * 1e-3
def _check_incoming_message_header(self, header): """message layout, see STS datasheet """ assert len( header ) == 44, "header has wrong length! len(header): %d" % len(header) data = struct.unpack(self._const.HEADER_FMT, header) assert data[ 0] == self._const.HEADER_START_BYTES, 'header start_bytes wrong: %d' % data[ 0] assert data[ 1] == self._const.HEADER_PROTOCOL_VERSION, 'header protocol version wrong: %d' % data[ 1] flags = data[2] if flags == 0: pass if flags & self._const.FLAG_RESPONSE_TO_REQUEST: pass # TODO: propagate? if flags & self._const.FLAG_ACK: pass # TODO: propagate? if flags & self._const.FLAG_REQUEST_ACK: pass # TODO: only the host should be able to set this? if (flags & self._const.FLAG_NACK) or ( flags & self._const.FLAG_HW_EXCEPTION): error = data[3] if error != 0: # != SUCCESS raise _OOError(self._const.ERROR_CODES[error]) else: pass # TODO: should we do simething here? if flags & self._const.FLAG_PROTOCOL_DEPRECATED: raise _OOError("Protocol deprecated?!?") # msgtype = data[4] # regarding = data[5] checksumtype = data[7] # TODO: implement checksums. assert checksumtype in [ self._const.CHECKSUM_TYPE_NONE, self._const.CHECKSUM_TYPE_MD5 ], 'the checksum type is unkown: %d' % checksumtype # immediate_length = data[8] # immediate_data = data[9] bytes_remaining = data[10] return bytes_remaining, checksumtype
def get_a_random_spectrometer(): ProductId = {} for model in _OOSupMod: pid = _OOModConf[model]['ProductId'] ProductId.update(zip(pid, [model] * len(pid))) devices = usb.core.find( find_all=True, custom_match=lambda d: (d.idVendor == _OOVendorId and d.idProduct in ProductId.keys())) # TODO: ??? usb.core.find can also return a generator ??? devices = list(devices) if devices: print '> found:' else: raise _OOError('no supported spectrometers found') for d in devices: print '> - %s' % ProductId[d.idProduct] mod = ProductId[devices[0].idProduct] print '>' print '> returning first %s as OceanOpticsSpectrometer' % mod spec_class = _models[mod] return spec_class()
def _query_information(self, address, raw=False): """ send command 0x05 """ ret = self._usb_query(struct.pack('<BB', 0x05, int(address))) if bool(raw): return ret if ret[0] != 0x05 or ret[1] != int(address) % 0xFF: raise _OOError('query_information: Wrong answer') return ret[2:ret[2:].index(0) + 2].tostring()
def _request_spectrum(self): """returns the spectrum array. """ # Get all data msg = self._construct_outgoing_message(self._const.MSG_GET_AND_SEND_RAW_SPECTRUM, "") self._usb_send(msg) time.sleep(max(self._integration_time - self._USBTIMEOUT, 0)) ret = self._usb_read() remaining_bytes, checksumtype = self._check_incoming_message_header(ret[:44]) length_payload_footer = remaining_bytes remaining_bytes -= len(ret[44:]) while True: if remaining_bytes <= 0: break N_bytes = min(remaining_bytes, self._EPin0_size) ret += self._usb_read(epi_size=N_bytes) remaining_bytes -= N_bytes if length_payload_footer != len(ret[44:]): raise _OOError("There is a remaining packet length error: %d vs %d" % (remaining_bytes, len(ret[44:]))) checksum = self._check_incoming_message_footer(ret[-20:]) if (checksumtype == self._const.CHECKSUM_TYPE_MD5) and (checksum != hashlib.md5(ret[:-20]).digest()): # TODO: raise Error warnings.warn("The checksums differ, but we ignore this for now.") data = self._extract_message_data(ret) spectrum = struct.unpack("<%dH" % self._pixels, data) return np.array(spectrum, dtype=np.float64)
def _extract_message_data(self, msg): """message layout, see STS datasheet """ payload_length = len(msg) - 44 - 20 # - HeaderLength - FooterLength assert payload_length >= 0, "the received message was shorter than 64 bytes: %d" % payload_length payload_fmt = "%ds" % payload_length FMT = self._const.HEADER_FMT + payload_fmt + self._const.FOOTER_FMT data = struct.unpack(FMT, msg) msgtype = data[4] immediate_length = data[8] immediate_data = data[9] payload = data[11] if (immediate_length > 0) and len(payload) > 0: raise _OOError("the device returned immediate data and payload data? cmd: %d" % msgtype) elif immediate_length > 0: return immediate_data[:immediate_length] elif payload_length > 0: return payload else: return ""
def _extract_message_data(self, msg): """message layout, see STS datasheet """ payload_length = len(msg) - 44 - 20 # - HeaderLength - FooterLength assert payload_length >= 0, "the received message was shorter than 64 bytes: %d" % payload_length payload_fmt = "%ds" % payload_length FMT = self._const.HEADER_FMT + payload_fmt + self._const.FOOTER_FMT data = struct.unpack(FMT, msg) msgtype = data[4] immediate_length = data[8] immediate_data = data[9] payload = data[11] if (immediate_length > 0) and len(payload) > 0: raise _OOError( "the device returned immediate data and payload data? cmd: %d" % msgtype) elif immediate_length > 0: return immediate_data[:immediate_length] elif payload_length > 0: return payload else: return ""
def get_a_random_spectrometer(): ProductId = {} for model in _OOSupMod: pid = _OOModConf[model]['ProductId'] ProductId.update(zip(pid, [model] * len(pid))) devices = usb.core.find(find_all=True, custom_match=lambda d: (d.idVendor == _OOVendorId and d.idProduct in ProductId.keys())) # TODO: ??? usb.core.find can also return a generator ??? devices = list(devices) if devices: print '> found:' else: raise _OOError('no supported spectrometers found') for d in devices: print '> - %s' % ProductId[d.idProduct] mod = ProductId[devices[0].idProduct] print '>' print '> returning first %s as OceanOpticsSpectrometer' % mod spec_class = _models[mod] return spec_class()
def _init_robust_spectrum(self): self.integration_time(0.005) for i in range(10): try: self._request_spectrum() break except: raise else: raise _OOError('Initialization SPECTRUM')
def _init_robust_status(self): for i in range(10): try: status = self._query_status() break except usb.core.USBError: pass else: raise _OOError('Initialization USBCOM') return status
def _read_pcb_temperature(self): """ just for compatibility with parent class """ """ 0x6C read pcb temperature """ self._usb_send(struct.pack('<B', 0x6C)) ret = self._usb_read() if (ret[0] != 0x08) | (ret[0] != 0x08): raise _OOError('read_temperatures: Wrong answer') ret = struct.unpack('<h', ret[1:3])[0] * 0.003906 return ret
def _check_incoming_message_header(self, header): """message layout, see STS datasheet """ assert len(header) == 44, "header has wrong length! len(header): %d" % len(header) data = struct.unpack(self._const.HEADER_FMT, header) assert data[0] == self._const.HEADER_START_BYTES, "header start_bytes wrong: %d" % data[0] assert data[1] == self._const.HEADER_PROTOCOL_VERSION, "header protocol version wrong: %d" % data[1] flags = data[2] if flags == 0: pass if flags & self._const.FLAG_RESPONSE_TO_REQUEST: pass # TODO: propagate? if flags & self._const.FLAG_ACK: pass # TODO: propagate? if flags & self._const.FLAG_REQUEST_ACK: pass # TODO: only the host should be able to set this? if (flags & self._const.FLAG_NACK) or (flags & self._const.FLAG_HW_EXCEPTION): error = data[3] if error != 0: # != SUCCESS raise _OOError(self._const.ERROR_CODES[error]) else: pass # TODO: should we do simething here? if flags & self._const.FLAG_PROTOCOL_DEPRECATED: raise _OOError("Protocol deprecated?!?") # msgtype = data[4] # regarding = data[5] checksumtype = data[7] # TODO: implement checksums. assert checksumtype in [self._const.CHECKSUM_TYPE_NONE, self._const.CHECKSUM_TYPE_MD5], ( "the checksum type is unkown: %d" % checksumtype ) # immediate_length = data[8] # immediate_data = data[9] bytes_remaining = data[10] return bytes_remaining, checksumtype
def integration_time(self, time_sec=None): """get or set the integration_time in seconds """ if time_sec is not None: if self._min_integration_time <= time_sec < self._max_integration_time: self._integration_time = self._set_integration_time(time_sec) else: raise _OOError("Integration time for %s required to be %f <= t < %f" % (self.model, self._min_integration_time, self._max_integration_time)) return self._integration_time
def get_spectrometer(serial_num=None): """ If serial_num is specified, then returns the object corresponding to that particular spectrometer, otherwise the first available spectrometer is returned. Parameters ---------- serial_num : string, optional the serial number of the spectrometer that you want to connect to Returns ------- spectrometer : OceanOpticsBase object the spectrometer with the requested serial number, or the first available spectrometer if serial_num=None Raises ------ OceanOpticsError: if the requested spectrometer is not available. """ spectrometers = get_available_spectrometers() if not spectrometers: raise _OOError('no available spectrometers found') if serial_num is None: #then just return the first spectrometer in the list serial_num = spectrometers.keys()[0] try: selected_spectro = spectrometers.pop(serial_num) except KeyError: raise _OOError('Spectrometer %s is not available' % serial_num) finally: for s in spectrometers.values(): s.dispose() return selected_spectro
def integration_time(self, time_sec=None): """get or set integration_time in seconds """ if not (time_sec is None): if self._min_integration_time <= time_sec < self._max_integration_time: time_us = time_sec * 1000000 self._set_integration_time(time_us) else: raise _OOError("Integration time for %s required to be %f <= t < %f" % (self.model, self._min_integration_time, self._max_integration_time)) self._integration_time = self._query_status()['integration_time']*1e-6 return self._integration_time
def _request_spectrum(self): self._usb_send(struct.pack('<B', 0x09)) time.sleep(max(self._integration_time - self._USBTIMEOUT, 0)) ret = [ self._usb_read(epi=self._EPspec, epi_size=self._packet_size) for _ in range(self._packet_N) ] ret = sum( ret[1:], ret[0] ) sync = self._usb_read(epi=self._EPspec, epi_size=1) if sync[0] != 0x69: raise _OOError('request_spectrum: Wrong sync byte') spectrum = struct.unpack('<'+'H'*self._pixels, ret) spectrum = map(self._packet_func, spectrum) return spectrum
def _request_spectrum(self): self._usb_send(struct.pack('<B', 0x09)) time.sleep(max(self._integration_time - 0.1*self._USBTIMEOUT, 0)) ret = [ self._usb_read(epi=self._EPspec, epi_size=self._packet_size) for _ in range(self._packet_N) ] ret = sum( ret[1:], ret[0] ) sync = self._usb_read(epi=self._EPspec, epi_size=1) if sync[0] != 0x69: raise _OOError('request_spectrum: Wrong sync byte') spectrum = struct.unpack('<'+'H'*self._pixels, ret) spectrum = map(self._packet_func, spectrum) return spectrum
def integration_time(self, time_sec=None): """get or set the integration_time in seconds """ if time_sec is not None: if self._min_integration_time <= time_sec < self._max_integration_time: self._integration_time = self._set_integration_time(time_sec) else: raise _OOError( "Integration time for %s required to be %f <= t < %f" % (self.model, self._min_integration_time, self._max_integration_time)) return self._integration_time
def get_temperatures(self): """ 0x6C read pcb and heatsink temperature """ self._usb_send(struct.pack('<B', 0x6C)) time.sleep(0.1) # wait 200ms ret = self._usb_read() time.sleep(0.1) if (ret[0] != 0x08) | (ret[0] != 0x08): raise _OOError('read_temperatures: Wrong answer') pcb = struct.unpack('<h', ret[1:3])[0] * 0.003906 heatsink = struct.unpack('<h', ret[4:6])[0] * 0.003906 ret = (pcb, heatsink) return ret
def integration_time(self, time_sec=None): """get or set integration_time in seconds """ if not (time_sec is None): if self._min_integration_time <= time_sec < self._max_integration_time: time_us = time_sec * 1000000 self._set_integration_time(time_us) else: raise _OOError( "Integration time for %s required to be %f <= t < %f" % (self.model, self._min_integration_time, self._max_integration_time)) self._integration_time = self._query_status( )['integration_time'] * 1e-6 return self._integration_time
def _query_data(self, msgtype, payload): """recommended query function""" msg = self._construct_outgoing_message(msgtype, payload, request_ACK=False) ret = self._usb_query(msg) remaining_bytes, checksumtype = self._check_incoming_message_header(ret[:44]) if remaining_bytes != len(ret[44:]): raise _OOError("There is a remaining packet length error: %d vs %d" % (remaining_bytes, len(ret[44:]))) checksum = self._check_incoming_message_footer(ret[-20:]) if (checksumtype == self._const.CHECKSUM_TYPE_MD5) and (checksum != hashlib.md5(ret[:-20]).digest()): # TODO: raise Error warnings.warn("The checksums differ, but we ignore this for now.") data = self._extract_message_data(ret) return data
def _request_spectrum(self): self._usb_send(struct.pack('<B', 0x09)) time.sleep(max(self._integration_time - self._USBTIMEOUT, 0)) ret = [ self._usb_read(epi=self._EPspec, epi_size=self._packet_size) for _ in range(self._packet_N) ] ret = sum( ret[1:], ret[0] ) # XXX: This sorts the the packets in the right order ret = "".join(ret[j*self._packet_size + i] + ret[(j+1)*self._packet_size + i] for j in range(self._packet_N) for i in range(self._packet_size)) sync = self._usb_read(epi=self._EPspec, epi_size=1) if sync[0] != 0x69: raise _OOError('request_spectrum: Wrong sync byte') spectrum = struct.unpack('<'+'H'*self._pixels, ret) spectrum = map(self._packet_func, spectrum) return spectrum
def _request_spectrum(self): self._usb_send(struct.pack('<B', 0x09)) time.sleep(max(self._integration_time - self._USBTIMEOUT, 0)) ret = [] for _ in range(4): ret += self._usb_read(epi=self._EPin6, epi_size=self._packet_size) for _ in range(self._packet_N - 4): ret += self._usb_read(epi=self._EPin2, epi_size=self._packet_size) ret = struct.pack('<'+'B'*(self._pixels*2), *ret) sync = self._usb_read(epi=self._EPin2, epi_size=1) if sync[0] != 0x69: raise _OOError('request_spectrum: Wrong sync byte') spectrum = struct.unpack('<'+'H'*self._pixels, ret) spectrum = map(self._packet_func, spectrum) return spectrum
def _request_spectrum(self): self._usb_send(struct.pack("<B", 0x09)) time.sleep(max(self._integration_time - self._USBTIMEOUT, 0)) ret = [self._usb_read(epi=self._EPspec, epi_size=self._packet_size) for _ in range(self._packet_N)] ret = sum(ret[1:], ret[0]) # XXX: This sorts the the packets in the right order sorted_ret = [] for j in range(0, self._packet_N, 2): for i in range(self._packet_size): sorted_ret.append(chr(ret[j * self._packet_size + i])) sorted_ret.append(chr(ret[(j + 1) * self._packet_size + i])) ret = "".join(sorted_ret) sync = self._usb_read(epi=self._EPspec, epi_size=1) if sync[0] != 0x69: raise _OOError("request_spectrum: Wrong sync byte") spectrum = struct.unpack("<" + "H" * self._pixels, ret) spectrum = map(self._packet_func, spectrum) return spectrum
def _request_spectrum(self): self._usb_send(struct.pack('<B', 0x09)) time.sleep(max(self._integration_time - self._USBTIMEOUT, 0)) ret = [ self._usb_read(epi=self._EPspec, epi_size=self._packet_size) for _ in range(self._packet_N) ] ret = sum(ret[1:], ret[0]) # XXX: This sorts the the packets in the right order sorted_ret = [] for j in range(0, self._packet_N, 2): for i in range(self._packet_size): sorted_ret.append(chr(ret[j * self._packet_size + i])) sorted_ret.append(chr(ret[(j + 1) * self._packet_size + i])) ret = "".join(sorted_ret) sync = self._usb_read(epi=self._EPspec, epi_size=1) if sync[0] != 0x69: raise _OOError('request_spectrum: Wrong sync byte') spectrum = struct.unpack('<' + 'H' * self._pixels, ret) spectrum = map(self._packet_func, spectrum) return spectrum