diff --git a/src/pymodaq_plugins_teaching/daq_move_plugins/daq_move_Monochromator.py b/src/pymodaq_plugins_teaching/daq_move_plugins/daq_move_Monochromator.py index 25d721b..fbc6b46 100644 --- a/src/pymodaq_plugins_teaching/daq_move_plugins/daq_move_Monochromator.py +++ b/src/pymodaq_plugins_teaching/daq_move_plugins/daq_move_Monochromator.py @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 ... @@ -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: @@ -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): @@ -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): diff --git a/src/pymodaq_plugins_teaching/daq_viewer_plugins/plugins_0D/daq_0Dviewer_Photodiode.py b/src/pymodaq_plugins_teaching/daq_viewer_plugins/plugins_0D/daq_0Dviewer_Photodiode.py new file mode 100644 index 0000000..43129a0 --- /dev/null +++ b/src/pymodaq_plugins_teaching/daq_viewer_plugins/plugins_0D/daq_0Dviewer_Photodiode.py @@ -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__)