Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ class DAQ_Move_Monochromator(DAQ_Move_base):
data_actuator_type = DataActuatorType.DataActuator # wether you use the new data style for actuator otherwise set this
# as DataActuatorType.float (or entirely remove the line)

params = [ # TODO for your custom plugin: elements to be added here as dicts in order to control your custom stage
params = [
{'Title':'Tau (ms)', 'name':'tau', 'type':'float','value':1234.,
'suffix':'ms','visible':True,'readonly':False},
{'Title':'Grating', 'name':'grating', 'type':'list','limits':Spectrometer.gratings,
'value':Spectrometer.gratings[0],'visible':True,'readonly':False},
# TODO for your custom plugin: elements to be added here as dicts in order to control your custom stage
] + comon_parameters_fun(is_multiaxes, axis_names=_axis_names, epsilon=_epsilon)
# _epsilon is the initial default value for the epsilon parameter allowing pymodaq to know if the controller reached
# the target value. It is the developer responsibility to put here a meaningful value
Expand Down Expand Up @@ -100,14 +105,12 @@ def commit_settings(self, param: Parameter):
A given parameter (within detector_settings) whose value has been changed by the user
"""
## TODO for your custom plugin
if param.name() == 'axis':
self.axis_unit = self.controller.your_method_to_get_correct_axis_unit()
# do this only if you can and if the units are not known beforehand, for instance
# if the motors connected to the controller are of different type (mm, µm, nm, , etc...)
# see BrushlessDCMotor from the thorlabs plugin for an exemple

elif param.name() == "a_parameter_you've_added_in_self.params":
self.controller.your_method_to_apply_this_param_change()
if param.name() == 'tau':
self.controller.tau = param.value()/1000

elif param.name() == 'grating':
self.controller.grating = param.value()

else:
pass

Expand All @@ -132,10 +135,22 @@ def ini_stage(self, controller=None):
# a_method_or_atttribute_to_check_if_init()) todo
# todo: enter here whatever is needed for your controller initialization and eventual
# opening of the communication channel
#self.controller.tau




else:
self.controller = controller
initialized = True

if initialized:
self.settings.child('tau').setValue(self.controller.tau * 1000)
self.settings.child('grating').setLimits(self.controller.gratings)
self.settings.child('grating').setValue(self.controller.grating)



info = "Whatever info you want to log"
return info, initialized

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import numpy as np

from pymodaq_utils.utils import ThreadCommand
from pymodaq_data.data import DataToExport, Axis
from pymodaq_gui.parameter import Parameter

from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main
from pymodaq.utils.data import DataFromPlugins

# TODO:
# Replace the following fake import with the import of the real Python wrapper of your instrument. Here we suppose that
# the wrapper is in the hardware directory, but it could come from an external librairy like pylablib or pymeasure.

from pymodaq_plugins_teaching.hardware.spectrometer import Spectrometer



# TODO:
# (1) change the name of the following class to DAQ_1DViewer_TheNameOfYourChoice
# (2) change the name of this file to daq_1Dviewer_TheNameOfYourChoice ("TheNameOfYourChoice" should be the SAME
# for the class name and the file name.)
# (3) this file should then be put into the right folder, namely IN THE FOLDER OF THE PLUGIN YOU ARE DEVELOPING:
# pymodaq_plugins_my_plugin/daq_viewer_plugins/plugins_1D


class DAQ_1DViewer_CCD(DAQ_Viewer_base):
""" Instrument plugin class for a 1D viewer.

This object inherits all functionalities to communicate with PyMoDAQ’s DAQ_Viewer module through inheritance via
DAQ_Viewer_base. It makes a bridge between the DAQ_Viewer module and the Python wrapper of a particular instrument.

TODO Complete the docstring of your plugin with:
* The set of instruments that should be compatible with this instrument plugin.
* With which instrument it has actually been tested.
* The version of PyMoDAQ during the test.
* The version of the operating system.
* Installation instructions: what manufacturer’s drivers should be installed to make it run?

Attributes:
-----------
controller: object
The particular object that allow the communication with the hardware, in general a python wrapper around the
hardware library.

# TODO add your particular attributes here if any

"""
params = comon_parameters+[
## TODO for your custom plugin
# elements to be added here as dicts in order to control your custom stage
############
]

def ini_attributes(self):
# TODO declare the type of the wrapper (and assign it to self.controller) you're going to use for easy
# autocompletion
self.controller: Spectrometer = None

# TODO declare here attributes you want/need to init with a default value

self.x_axis = None

def commit_settings(self, param: Parameter):
"""Apply the consequences of a change of value in the detector settings

Parameters
----------
param: Parameter
A given parameter (within detector_settings) whose value has been changed by the user
"""
## TODO for your custom plugin
if param.name() == "a_parameter_you've_added_in_self.params":
self.controller.your_method_to_apply_this_param_change()
# elif ...
##

def ini_detector(self, controller=None):
"""Detector communication initialization

Parameters
----------
controller: (object)
custom object of a PyMoDAQ plugin (Slave case). None if only one actuator/detector by controller
(Master case)

Returns
-------
info: str
initialized: bool
False if initialization failed otherwise True
"""


if self.is_master:
self.controller = Spectrometer() #instantiate you driver with whatever arguments are needed
self.controller.open_communication() # call eventual methods
initialized = self.controller.open_communication() # TODO
else:
self.controller = controller
initialized = True

## TODO for your custom plugin
# get the x_axis (you may want to to this also in the commit settings if x_axis may have changed
#data_x_axis = self.controller.your_method_to_get_the_x_axis() # if possible
#self.x_axis = Axis(data=data_x_axis, label='', units='nm', index=0)

# TODO for your custom plugin. Initialize viewers pannel with the future type of data
#self.dte_signal_temp.emit(DataToExport(name='myplugin',
# data=[DataFromPlugins(name='Mock1',
# data=[np.array([0., 0., ...]),
# np.array([0., 0., ...])],
# dim='Data1D', labels=['Mock1', 'label2'],
# axes=[self.x_axis])]))

info = "Whatever info you want to log"
return info, initialized

def close(self):
"""Terminate the communication protocol"""
## TODO for your custom plugin

if self.is_master:
self.controller.close_communication()
# self.controller.your_method_to_terminate_the_communication() # when writing your own plugin replace this line
...

def grab_data(self, Naverage=1, **kwargs):
"""Start a grab from the detector

Parameters
----------
Naverage: int
Number of hardware averaging (if hardware averaging is possible, self.hardware_averaging should be set to
True in class preamble and you should code this implementation)
kwargs: dict
others optionals arguments
"""
## TODO for your custom plugin: you should choose EITHER the synchrone or the asynchrone version following

##synchrone version (blocking function)
data_1D = self.controller.grab_spectrum()
wavelength_array=self.controller.get_wavelength_axis()

axis= Axis(label='Wavelength', units= "nm", data = wavelength_array,index=0)

self.dte_signal.emit(DataToExport('myplugin',
data=[DataFromPlugins(name='CCD', data=data_1D,
dim='Data1D', labels=['Intensity'],
axes=[axis])]))

##asynchrone version (non-blocking function with callback)
#self.controller.grab_monochromator()
#########################################################


def callback(self):
"""optional asynchrone method called when the detector has finished its acquisition of data"""
data_tot = self.controller.grab_monochromator()
self.dte_signal.emit(DataToExport('myplugin',
data=[DataFromPlugins(name='Mock1', data=data_tot,
dim='Data1D', labels=['dat0', 'data1'])]))

def stop(self):
"""Stop the current grab hardware wise if necessary"""
## TODO for your custom plugin

self.controller.stop() # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))
##############################
return ''


if __name__ == '__main__':
main(__file__)
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import numpy as np
from pymodaq.utils.data import DataFromPlugins
from qtpy.QtCore import QThread, Slot, QRectF
from qtpy import QtWidgets
import laserbeamsize as lbs

from pymodaq_plugins_mockexamples.daq_viewer_plugins.plugins_2D.daq_2Dviewer_BSCamera import DAQ_2DViewer_BSCamera

from pymodaq_utils.utils import ThreadCommand
from pymodaq_data.data import DataToExport, Axis
from pymodaq_gui.parameter import Parameter

from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main

from pymodaq_plugins_mockexamples.daq_viewer_plugins.plugins_2D.daq_2Dviewer_BSCamera import DAQ_2DViewer_BSCamera


# TODO:
# (1) change the name of the following class to DAQ_2DViewer_TheNameOfYourChoice
# (2) change the name of this file to daq_2Dviewer_TheNameOfYourChoice ("TheNameOfYourChoice" should be the SAME
# for the class name and the file name.)
# (3) this file should then be put into the right folder, namely IN THE FOLDER OF THE PLUGIN YOU ARE DEVELOPING:
# pymodaq_plugins_my_plugin/daq_viewer_plugins/plugins_2D


class DAQ_2DViewer_BeamProfiler(DAQ_2DViewer_BSCamera):
live_mode_available = False

params = DAQ_2DViewer_BSCamera.params + [
{'title': 'beam', 'name': 'beam', 'type': 'led', 'value': True},
{'title': 'position', 'name': 'position', 'type': 'bool', 'value': True},
{'title': 'width', 'name': 'width', 'type': 'bool', 'value': True},
{'title': 'Beam Angle (deg)', 'name': 'phi2', 'type': 'bool', 'value': True },

]


def grab_data(self, Naverage=1, **kwargs):
"""Start a grab from the detector

#########################################################"""
data = self.average_data(Naverage)
beam = data[0].data[0]

x,y,d_major,d_minor,phi=lbs.beam_size(beam)
#package things

dte = DataToExport('BeamProfiler',
data=[
DataFromPlugins('Beam',
data=[beam],
labels=['Raw beam'],
do_plot=self.settings['beam']),
DataFromPlugins('Position',
data=[np.atleast_1d(x), np.atleast_1d(y)],
labels=['x','y'],
do_plot=self.settings['position']),
DataFromPlugins('Size',
data=[np.atleast_1d(d_major), np.atleast_1d(d_minor)],
labels=['Major', 'Minor'],
do_plot=self.settings['width']),
DataFromPlugins('Angle',
data=[np.atleast_1d(phi)],
labels=['angle'],
do_plot=self.settings['phi2']),
])
self.dte_signal.emit(dte)

# return super().grab_data(Naverage=Naverage, **kwargs)


if __name__ == '__main__':
main(__file__)