Source code for pzp_hardware.oceanoptics.spectrometer

# This file is a part of pzp-hardware, a library of laboratory hardware support Pieces
# for the puzzlepiece GUI & automation framework. Check out https://pzp-hardware.readthedocs.io
# Licensed under the Apache License 2.0 - https://github.com/jdranczewski/pzp-hardware/blob/main/LICENSE

r"""
:module_title:`OceanOptics Spectrometer`

Pieces for interacting with `OceanOptics spectrometers <https://www.oceanoptics.com/spectrometers/>`__
using the `python-seabreeze <https://python-seabreeze.readthedocs.io/en/latest/index.html>`__
library and the `puzzlepiece <https://puzzlepiece.readthedocs.io>`__ framework.

Example usage (see :ref:`getting-started` for more details on using Pieces in general)::

    import puzzlepiece as pzp
    from pzp_hardware.oceanoptics import spectrometer

    app = pzp.QApp()
    puzzle = pzp.Puzzle(debug=False)
    puzzle.add_piece("spectrometer", spectrometer.Piece, row=0, column=0)
    puzzle.show()
    app.exec()

Installation
------------
* If available, install OceanView from https://www.oceanoptics.com/software/ - this will
  install the drivers needed to talk to the spectrometer. Alternatively, follow
  https://python-seabreeze.readthedocs.io/en/latest/install.html for details on
  how to install the drivers with ``python-seabreeze``.
* Install the ``seabreeze`` library with pip, or wait to be prompted for automatic
  installation when first running the Piece.

Requirements
------------
.. pzp_requirements:: pzp_hardware.oceanoptics.spectrometer

Available Pieces
----------------
"""

import puzzlepiece as pzp
from puzzlepiece.extras import hardware_tools as pht
from pyqtgraph.Qt import QtWidgets
import pyqtgraph as pg
import numpy as np


[docs] class Piece(pzp.Piece): """ A very basic Piece for getting values and wavelengths from an OceanOptics spectrometer. Contributions welcome to expose more options! .. image:: ../images/pzp_hardware.oceanoptics.spectrometer.Piece.png """ custom_horizontal = True def define_params(self): @pzp.param.dropdown(self, "spectrometer", "") def list_spectrometers(): if not self.puzzle.debug: return self.imports.list_devices() @pzp.param.connect(self) def connect(): if self.puzzle.debug: return 1 self.spec = self.imports.Spectrometer.from_serial_number( self.params['spectrometer'].get_value().split(":")[1][:-1] ) @pzp.param.disconnect(self) def disconnect(): if self.puzzle.debug: return 0 if self._ensure(capture_exception=True): self.spec.close() return 0 pzp.param.array(self, 'wls', False)(None) @pzp.param.array(self, 'values') @self._ensure def values(): if self.puzzle.debug: self.params['wls'].set_value(np.arange(100)) return np.random.random(100) wls, vals = self.spec.spectrum() self.params['wls'].set_value(wls) return vals @pzp.piece.ensurer def _ensure(self): if not self.puzzle.debug and not hasattr(self, 'spec'): raise("Spectrometer not connected") def custom_layout(self): layout = QtWidgets.QVBoxLayout() # The thread runs self.get_value repeatedly, which updates the plot through the # Signal connection defined below self.timer = pzp.threads.PuzzleTimer('Live', self.puzzle, self.params['values'].get_value, 0.05) layout.addWidget(self.timer) self.pw = pg.PlotWidget() layout.addWidget(self.pw) self.plot = self.pw.getPlotItem() self.plot_line = self.plot.plot([0], [0], symbol='o', symbolSize=3) # Update the plot when the values change (through a CallLater, so the # update is done only when the GUI loop is running) def update_plot(): self.plot_line.setData( self.params['wls'].value, self.params['values'].value ) update_later = pzp.threads.CallLater(update_plot) self.params['values'].changed.connect(update_later) return layout def setup(self): pht.requirements( { "seabreeze": { "pip": "seabreeze", "url": "https://python-seabreeze.readthedocs.io/en/latest/install.html" } } ) import seabreeze.spectrometers self.imports = seabreeze.spectrometers
if __name__ == "__main__": app = pzp.QApp() puzzle = pzp.Puzzle(name="OceanOptics", debug=pht.debug_prompt()) puzzle.add_piece("spectrometer", Piece, 0, 0) puzzle.show() app.exec()