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
@@ -1,15 +1,10 @@

from typing import Union, List, Dict
from pymodaq.control_modules.move_utility_classes import (DAQ_Move_base, comon_parameters_fun,
main, DataActuatorType, DataActuator)
from pymodaq.control_modules.move_utility_classes import (DAQ_Move_base, comon_parameters_fun, main, DataActuatorType, DataActuator)

from pymodaq_utils.utils import ThreadCommand # object used to send info back to the main thread
from pymodaq_utils.utils import ThreadCommand
from pymodaq_gui.parameter import Parameter

# 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_template.hardware.python_wrapper_file_of_your_instrument import PythonWrapperObjectOfYourInstrument
from pymodaq_plugins_teaching.hardware.spectrometer import Spectrometer

# TODO:
# (1) change the name of the following class to DAQ_Move_TheNameOfYourChoice
Expand Down Expand Up @@ -41,10 +36,9 @@ class DAQ_Move_Monochromator(DAQ_Move_base):
# TODO add your particular attributes here if any

"""
is_multiaxes = False # TODO for your plugin set to True if this plugin is controlled for a multiaxis controller
_axis_names: Union[List[str], Dict[str, int]] = ['Axis1', 'Axis2'] # TODO for your plugin: complete the list
_controller_units: Union[str, List[str]] = 'mm' # TODO for your plugin: put the correct unit here, it could be
# TODO a single str (the same one is applied to all axes) or a list of str (as much as the number of axes)
is_multiaxes = False
_axis_names: Union[List[str], Dict[str, int]] = ['']
_controller_units: Union[str, List[str]] = 'nm'
_epsilon: Union[float, List[float]] = 0.1 # TODO replace this by a value that is correct depending on your controller
# TODO it could be a single float of a list of float (as much as the number of axes)
data_actuator_type = DataActuatorType.DataActuator # wether you use the new data style for actuator otherwise set this
Expand All @@ -58,7 +52,7 @@ class DAQ_Move_Monochromator(DAQ_Move_base):
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: PythonWrapperObjectOfYourInstrument = None
self.controller: Spectrometer = None

#TODO declare here attributes you want/need to init with a default value
pass
Expand All @@ -71,8 +65,7 @@ def get_actuator_value(self):
float: The position obtained after scaling conversion.
"""
## TODO for your custom plugin
raise NotImplementedError # when writing your own plugin remove this line
pos = DataActuator(data=self.controller.your_method_to_get_the_actuator_value(), # when writing your own plugin replace this line
pos = DataActuator(data=self.controller.get_wavelength(), # when writing your own plugin replace this line
units=self.axis_unit)
pos = self.get_position_with_scaling(pos)
return pos
Expand All @@ -94,7 +87,6 @@ def user_condition_to_reach_target(self) -> bool:
def close(self):
"""Terminate the communication protocol"""
## TODO for your custom plugin
raise NotImplementedError # when writing your own plugin remove this line
if self.is_master:
# self.controller.your_method_to_terminate_the_communication() # when writing your own plugin replace this line
...
Expand Down Expand Up @@ -133,10 +125,9 @@ def ini_stage(self, controller=None):
initialized: bool
False if initialization failed otherwise True
"""
raise NotImplementedError # TODO when writing your own plugin remove this line and modify the ones below
if self.is_master: # is needed when controller is master
self.controller = PythonWrapperObjectOfYourInstrument(arg1, arg2, ...) # arguments for instantiation!)
initialized = self.controller.a_method_or_atttribute_to_check_if_init() # todo
self.controller = Spectrometer()
initialized = self.controller.open_communication() # todo
# todo: enter here whatever is needed for your controller initialization and eventual
# opening of the communication channel
else:
Expand All @@ -153,13 +144,13 @@ def move_abs(self, value: DataActuator):
----------
value: (float) value of the absolute target positioning
"""

value = self.check_bound(value) #if user checked bounds, the defined bounds are applied here
self.target_value = value
value = self.check_bound(self.current_position + value) - self.current_position #if user checked bounds, the defined bounds are applied here
self.target_value = value + self.current_position
value = self.set_position_with_scaling(value) # apply scaling if the user specified one
## TODO for your custom plugin
raise NotImplementedError # when writing your own plugin remove this line
self.controller.your_method_to_set_an_absolute_value(value.value(self.axis_unit)) # when writing your own plugin replace this line
self.controller.set_wavelength(self.target_value.value(self.axis_unit))
self.controller.set_wavelength(value.value(self.axis_unit),
set_type='rel') # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))

def move_rel(self, value: DataActuator):
Expand All @@ -174,16 +165,14 @@ def move_rel(self, value: DataActuator):
value = self.set_position_relative_with_scaling(value)

## TODO for your custom plugin
raise NotImplementedError # when writing your own plugin remove this line
self.controller.your_method_to_set_a_relative_value(value.value(self.axis_unit)) # when writing your own plugin replace this line
self.controller.set_wavelength(value.value(self.axis_unit),set_type="rel") # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))

def move_home(self):
"""Call the reference method of the controller"""

## TODO for your custom plugin
raise NotImplementedError # when writing your own plugin remove this line
self.controller.your_method_to_get_to_a_known_reference() # when writing your own plugin replace this line
self.controller.find_reference() # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))

def stop_motion(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import numpy as np

from pymodaq_utils.utils import ThreadCommand
from pymodaq_data.data import DataToExport
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_0DViewer_TheNameOfYourChoice
# (2) change the name of this file to daq_0Dviewer_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_0D


class DAQ_0DViewer_Photodiode(DAQ_Viewer_base):
""" Instrument plugin class for a OD 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
pass

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() # when writing your own plugin replace this line
# 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
initialized = self.controller.open_communication() # TODO
else:
self.controller = controller
initialized = True

# TODO for your custom plugin (optional) initialize viewers panel with the future type of data
self.dte_signal_temp.emit(DataToExport(name='myplugin',
data=[DataFromPlugins(name='Mock1',
data=[np.array([0]), np.array([0])],
dim='Data0D',
labels=['Mock1', 'label2'])]))

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

def close(self):
"""Terminate the communication protocol"""
## TODO for your custom plugin
#raise NotImplementedError # when writing your own plugin remove this line
if self.is_master:
# 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_tot = self.controller.grab_monochromator()
self.dte_signal.emit(
DataToExport(name='Photodiode',
data=[
DataFromPlugins(name='Photodiode', data=[data_tot],
labels=['Intensity'],
units='Volt')]))

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

def stop(self):
"""Stop the current grab hardware wise if necessary"""
## TODO for your custom plugin
raise NotImplementedError # when writing your own plugin remove this line
self.controller.your_method_to_stop_acquisition() # 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__)