import numpy as np
import numbers
import warnings
import copy
from typing import List
from pymodaq_utils.warnings import deprecation_msg, user_warning
from pymodaq_data.data import (DataRaw, DataWithAxes, DataToExport, DataCalculated, DataDim,
DataSource, DataBase, Axis, NavAxis, DataDistribution, Q_, Unit,
) # imported here for backcompatibility. Will allow also the object serialization
# registration
from pymodaq_utils.serialize.factory import SerializableFactory, SerializableBase
ser_factory = SerializableFactory()
[docs]
@ser_factory.register_decorator()
class DataActuator(DataRaw):
"""Specialized DataWithAxes set with source as 'raw'.
To be used for raw data generated by actuator plugins"""
def __init__(self, *args, **kwargs):
if len(args) == 0 and 'name' not in kwargs:
args = ['actuator']
if 'data' not in kwargs:
kwargs['data'] = [np.array([0.])]
elif isinstance(kwargs['data'], numbers.Number): # useful formatting
kwargs['data'] = [np.array([kwargs['data']])]
super().__init__(*args, **kwargs)
def __repr__(self):
if self.dim.name == 'Data0D':
return f'<{self.__class__.__name__} ({self.data[0][0]} {self.units})>'
else:
return f'<{self.__class__.__name__} ({self.shape} {self.units})>'
def __add__(self, other: object):
if isinstance(other, numbers.Number) and self.length == 1 and self.size == 1:
new_data = copy.deepcopy(self)
new_data = new_data + DataActuator(data=other)
return new_data
else:
return super().__add__(other)
[docs]
@ser_factory.register_decorator()
class DataFromPlugins(DataRaw):
"""Specialized DataWithAxes set with source as 'raw'. To be used for raw data generated by Detector plugins
It introduces by default to extra attributes, do_plot and do_save. Their presence can be checked in the
extra_attributes list.
Parameters
----------
do_plot: bool
If True the underlying data will be plotted in the DAQViewer
do_save: bool
If True the underlying data will be saved
Attributes
----------
do_plot: bool
If True the underlying data will be plotted in the DAQViewer
do_save: bool
If True the underlying data will be saved
"""
def __init__(self, *args, **kwargs):
##### for backcompatibility
if 'plot' in kwargs:
deprecation_msg("'plot' should not be used anymore as extra_attribute, "
"please use 'do_plot'")
do_plot = kwargs.pop('plot')
kwargs['do_plot'] = do_plot
if 'save' in kwargs:
deprecation_msg("'save' should not be used anymore as extra_attribute, "
"please use 'do_save'")
do_save = kwargs.pop('save')
kwargs['do_save'] = do_save
#######
if 'do_plot' not in kwargs:
kwargs['do_plot'] = True
if 'do_save' not in kwargs:
kwargs['do_save'] = True
super().__init__(*args, **kwargs)
@ser_factory.register_decorator()
class DataScan(DataToExport):
"""Specialized DataToExport.To be used for data to be saved """
def __init__(self, name: str, data: List[DataWithAxes] = [], **kwargs):
super().__init__(name, data, **kwargs)
@ser_factory.register_decorator()
class DataToActuators(DataToExport):
""" Particular case of a DataToExport adding one named parameter to indicate what kind of change
should be applied to the actuators, absolute or relative
Attributes
----------
mode: str
Adds an attribute called mode holding a string describing the type of change:
relative or absolute
Parameters
---------
mode: str
either 'rel' or 'abs' for a relative or absolute change of the actuator's values
"""
mode: str
def __init__(self, *args, mode='rel', **kwargs):
if mode not in ['rel', 'abs']:
user_warning('Incorrect mode for the actuators, '
'switching to default relative mode: rel')
mode = 'rel'
kwargs.update({'mode': mode})
super().__init__(*args, **kwargs)
def __repr__(self):
return f'{super().__repr__()}: {self.mode}'