def __init__(self, pulser, config, configName='DDSUi', globalDict=dict(), parent=None): DDSBase.__init__(self, parent) DDSForm.__init__(self) if pulser.pulserConfiguration(): self.channelInfo = sorted(list( pulser.pulserConfiguration().ddsChannels.values()), key=lambda x: x.channel) else: self.channelInfo = [] self.numChannels = len(self.channelInfo) self.config = config self.channelConfigName = '{0}.ddsChannels'.format(configName) self.autoApplyConfigName = '{0}.autoApply'.format(configName) self.guiStateConfigName = '{0}.guiState'.format(configName) self.ad9912 = Ad9912.Ad9912(pulser) oldDDSChannels = self.config.get(self.channelConfigName, []) self.ddsChannels = [ oldDDSChannels[i] if i < len(oldDDSChannels) else DDSChannelSettings() for i in range(self.numChannels) ] self.autoApply = self.config.get(self.autoApplyConfigName, True) self.decimation = defaultdict(lambda: StaticDecimation(Q(30, 's'))) self.persistence = DBPersist() self.globalDict = globalDict self.pulser = pulser self.persistSpace = 'DDS' for index, channelinfo in enumerate(self.channelInfo): self.ddsChannels[index].channel = channelinfo.channel self.ddsChannels[index].shutter = channelinfo.shutter
def __init__(self, pulser, config, configName, globalDict, parent=None): self.isSetup = False dacBase.__init__(self, parent) dacForm.__init__(self) self.config = config self.dac = DAC(pulser) self.channelsConfigName = '{0}.dacExpressionChannels'.format( configName) self.autoApplyConfigName = '{0}.autoApply'.format(configName) self.guiStateConfigName = '{0}.guiState'.format(configName) self.dacChannels = self.config.get(self.channelsConfigName) if not self.dacChannels or len( self.dacChannels) != self.dac.numChannels: self.dacChannels = [ DACChannelSetting(globalDict=globalDict) for _ in range(self.dac.numChannels) ] for index, channel in enumerate(self.dacChannels): channel.globalDict = globalDict channel.onChange = partial(self.onChange, index) self.autoApply = self.config.get(self.autoApplyConfigName, True) self.decimation = defaultdict(lambda: StaticDecimation(Q(30, 's'))) self.persistence = DBPersist() self.globalDict = globalDict self.pulser = pulser
class DatabasePushDestination: def __init__(self, space): self.persist = DBPersist() self.space = space def update(self, pushlist, upd_time=None): upd_time = time.time() if upd_time is None else upd_time for _, variable, value in pushlist: if is_Q(value): value, unit = value.m, "{:~}".format(value.units) else: unit = None self.persist.persist(self.space, variable, upd_time, value, unit) def keys(self): return (source for (space, source) in list(self.persist.sourceDict().keys()) if space == self.space)
def __init__(self, pulser, config, configName, globalDict, parent=None): self.isSetup = False dacBase.__init__(self, parent) dacForm.__init__(self) self.config = config self.dac = DAC(pulser) self.channelsConfigName = '{0}.dacExpressionChannels'.format(configName) self.autoApplyConfigName = '{0}.autoApply'.format(configName) self.guiStateConfigName = '{0}.guiState'.format(configName) self.dacChannels = self.config.get(self.channelsConfigName) if not self.dacChannels or len(self.dacChannels)!=self.dac.numChannels: self.dacChannels = [DACChannelSetting(globalDict=globalDict) for _ in range(self.dac.numChannels) ] for index, channel in enumerate(self.dacChannels): channel.globalDict = globalDict channel.onChange = partial( self.onChange, index ) self.autoApply = self.config.get(self.autoApplyConfigName, True) self.decimation = defaultdict( lambda: StaticDecimation(Q(30, 's'))) self.persistence = DBPersist() self.globalDict = globalDict self.pulser = pulser
class DACUi(dacForm, dacBase): persistSpace = 'DAC' def __init__(self, pulser, config, configName, globalDict, parent=None): self.isSetup = False dacBase.__init__(self, parent) dacForm.__init__(self) self.config = config self.dac = DAC(pulser) self.channelsConfigName = '{0}.dacExpressionChannels'.format( configName) self.autoApplyConfigName = '{0}.autoApply'.format(configName) self.guiStateConfigName = '{0}.guiState'.format(configName) self.dacChannels = self.config.get(self.channelsConfigName) if not self.dacChannels or len( self.dacChannels) != self.dac.numChannels: self.dacChannels = [ DACChannelSetting(globalDict=globalDict) for _ in range(self.dac.numChannels) ] for index, channel in enumerate(self.dacChannels): channel.globalDict = globalDict channel.onChange = partial(self.onChange, index) self.autoApply = self.config.get(self.autoApplyConfigName, True) self.decimation = defaultdict(lambda: StaticDecimation(Q(30, 's'))) self.persistence = DBPersist() self.globalDict = globalDict self.pulser = pulser def setupUi(self, parent): dacForm.setupUi(self, parent) self.dacTableModel = DACTableModel(self.dacChannels, self.globalDict) self.tableView.setModel(self.dacTableModel) self.delegate = MagnitudeSpinBoxDelegate(self.globalDict) self.tableView.setItemDelegateForColumn(2, self.delegate) self.applyButton.clicked.connect(self.onApply) self.resetButton.clicked.connect(self.onReset) self.writeAllButton.clicked.connect(self.onWriteAll) self.autoApplyBox.setChecked(self.autoApply) self.autoApplyBox.stateChanged.connect(self.onStateChanged) try: self.onWriteAll(writeUnchecked=True) except Exception as e: logging.getLogger(__name__).warning( "Ignored error while setting dac: {0}".format(e)) self.onApply() self.dacTableModel.voltageChanged.connect(self.onVoltage) self.dacTableModel.enableChanged.connect(self.onEnableChanged) restoreGuiState(self, self.config.get(self.guiStateConfigName)) self.isSetup = True def onEnableChanged(self, channel, value): self.dac.setVoltage(channel, self.dacChannels[channel].outputVoltage) def setDisabled(self, disabled): pass def onStateChanged(self, state): self.autoApply = self.autoApplyBox.isChecked() def onVoltage(self, channel, value): self.dac.setVoltage(channel, self.dacChannels[channel].outputVoltage, autoApply=self.autoApply) self.decimation[(0, channel)].decimate( time.time(), self.dacChannels[channel].outputVoltage, partial( self.persistCallback, "Voltage:{0}".format(self.dacChannels[channel].name if self. dacChannels[channel].name else channel))) def persistCallback(self, source, data): time, value, minval, maxval = data unit = None if is_Q(value): value, unit = value.m, "{:~}".format(value.unit) self.persistence.persist(self.persistSpace, source, time, value, minval, maxval, unit) def onWriteAll(self, writeUnchecked=False): if len(self.dacChannels) > 0: with CombineWrites(self.dac) as stream: for channel, settings in enumerate(self.dacChannels): if writeUnchecked or settings.resetAfterPP: stream.setVoltage(channel, settings.outputVoltage, autoApply=self.autoApply, applyAll=True) def saveConfig(self): self.config[self.channelsConfigName] = self.dacChannels self.config[self.autoApplyConfigName] = self.autoApply self.config[self.guiStateConfigName] = saveGuiState(self) def onApply(self): if self.dacChannels: self.dac.setVoltage(0, self.dacChannels[0].outputVoltage, autoApply=True, applyAll=True) def onReset(self): self.dac.reset(0xff) def onChange(self, index, name, value, string, origin): if self.isSetup and origin != 'value': self.dacTableModel.setVoltage( self.dacTableModel.createIndex(index, 2), value)
class DDSUi(DDSForm, DDSBase): def __init__(self, pulser, config, configName='DDSUi', globalDict=dict(), parent=None): DDSBase.__init__(self, parent) DDSForm.__init__(self) if pulser.pulserConfiguration(): self.channelInfo = sorted(list( pulser.pulserConfiguration().ddsChannels.values()), key=lambda x: x.channel) else: self.channelInfo = [] self.numChannels = len(self.channelInfo) self.config = config self.channelConfigName = '{0}.ddsChannels'.format(configName) self.autoApplyConfigName = '{0}.autoApply'.format(configName) self.guiStateConfigName = '{0}.guiState'.format(configName) self.ad9912 = Ad9912.Ad9912(pulser) oldDDSChannels = self.config.get(self.channelConfigName, []) self.ddsChannels = [ oldDDSChannels[i] if i < len(oldDDSChannels) else DDSChannelSettings() for i in range(self.numChannels) ] self.autoApply = self.config.get(self.autoApplyConfigName, True) self.decimation = defaultdict(lambda: StaticDecimation(Q(30, 's'))) self.persistence = DBPersist() self.globalDict = globalDict self.pulser = pulser self.persistSpace = 'DDS' for index, channelinfo in enumerate(self.channelInfo): self.ddsChannels[index].channel = channelinfo.channel self.ddsChannels[index].shutter = channelinfo.shutter def setupUi(self, parent): DDSForm.setupUi(self, parent) self.ddsTableModel = DDSTableModel(self.ddsChannels, self.globalDict) self.tableView.setModel(self.ddsTableModel) self.delegate = MagnitudeSpinBoxDelegate(self.globalDict) self.tableView.setItemDelegateForColumn(2, self.delegate) self.tableView.setItemDelegateForColumn(3, self.delegate) self.tableView.setItemDelegateForColumn(4, self.delegate) self.applyButton.clicked.connect(self.onApply) self.resetButton.clicked.connect(self.onReset) self.writeAllButton.clicked.connect(self.onWriteAll) self.autoApplyBox.setChecked(self.autoApply) self.autoApplyBox.stateChanged.connect(self.onStateChanged) try: self.onWriteAll() except Exception as e: logging.getLogger(__name__).warning( "Ignored error while setting DDS: {0}".format(e)) self.onApply() self.ddsTableModel.frequencyChanged.connect(self.onFrequency) self.ddsTableModel.phaseChanged.connect(self.onPhase) self.ddsTableModel.amplitudeChanged.connect(self.onAmplitude) self.ddsTableModel.enableChanged.connect(self.onEnableChanged) self.ddsTableModel.squareChanged.connect(self.onSquareChanged) self.pulser.shutterChanged.connect(self.onShutterChanged) restoreGuiState(self, self.config.get(self.guiStateConfigName)) def onShutterChanged(self, shutterBitmask): for channel in self.ddsChannels: channel.enabled = bool(shutterBitmask & (1 << (channel.shutter))) self.ddsTableModel.onShutterChanged() def onEnableChanged(self, index, value): channelObj = self.ddsChannels[index] self.pulser.setShutterBit(channelObj.shutter, value) def setDisabled(self, disabled): pass def onStateChanged(self, state): self.autoApply = self.autoApplyBox.isChecked() def onFrequency(self, channel, value): channelObj = self.ddsChannels[channel] channel = channelObj.channel self.ad9912.setFrequency(channel, value) if self.autoApply: self.onApply() self.decimation[(0, channel)].decimate( time.time(), value, partial( self.persistCallback, "Frequency:{0}".format( channelObj.name if channelObj.name else channel))) def onPhase(self, channel, value): channelObj = self.ddsChannels[channel] channel = channelObj.channel self.ad9912.setPhase(channel, value) if self.autoApply: self.onApply() self.decimation[(1, channel)].decimate( time.time(), value, partial( self.persistCallback, "Phase:{0}".format( channelObj.name if channelObj.name else channel))) def onAmplitude(self, channel, value): channelObj = self.ddsChannels[channel] channel = channelObj.channel self.ad9912.setAmplitude(channel, value) if self.autoApply: self.onApply() self.decimation[(2, channel)].decimate( time.time(), value, partial( self.persistCallback, "Amplitude:{0}".format( channelObj.name if channelObj.name else channel))) def onSquareChanged(self, channel, enable): channelObj = self.ddsChannels[channel] channel = channelObj.channel self.ad9912.setSquareEnabled(channel, enable) def persistCallback(self, source, data): time, value, minval, maxval = data unit = None if is_Q(value): value, unit = value.m, "{:~}".format(value.units) self.persistence.persist(self.persistSpace, source, time, value, minval, maxval, unit) def onWriteAll(self): with Ad9912.CombineWrites(self.ad9912) as stream: for settings in self.ddsChannels: stream.setFrequency(settings.channel, settings.frequency) stream.setPhase(settings.channel, settings.phase) stream.setAmplitude(settings.channel, settings.amplitude) stream.setSquareEnabled(settings.channel, settings.squareEnabled) if self.autoApply: self.onApply() def saveConfig(self): self.config[self.channelConfigName] = self.ddsChannels self.config[self.autoApplyConfigName] = self.autoApply self.config[self.guiStateConfigName] = saveGuiState(self) def onApply(self): self.ad9912.update((1 << self.numChannels) - 1) def onReset(self): indexes = self.tableView.selectedIndexes() channels = sorted(unique([i.row() for i in indexes])) mask = 0 if channels: for ch in channels: mask |= 1 << ch else: mask = 0xff self.ad9912.reset(mask) def evaluate(self, name): for setting in self.ddsChannels: if setting.evaluateFrequency(self.globalDict): self.ad9912.setFrequency(setting.channel, setting.frequency) if setting.evaluatePhase(self.globalDict): self.ad9912.setPhase(setting.channel, setting.phase) if setting.evaluateAmplitude(self.globalDict): self.ad9912.setAmplitude(setting.channel, setting.amplitude) if self.autoApply: self.onApply() self.tableView.viewport().repaint()
def __init__(self, space): self.persist = DBPersist() self.space = space
class DACUi(dacForm, dacBase): persistSpace = 'DAC' def __init__(self, pulser, config, configName, globalDict, parent=None): self.isSetup = False dacBase.__init__(self, parent) dacForm.__init__(self) self.config = config self.dac = DAC(pulser) self.channelsConfigName = '{0}.dacExpressionChannels'.format(configName) self.autoApplyConfigName = '{0}.autoApply'.format(configName) self.guiStateConfigName = '{0}.guiState'.format(configName) self.dacChannels = self.config.get(self.channelsConfigName) if not self.dacChannels or len(self.dacChannels)!=self.dac.numChannels: self.dacChannels = [DACChannelSetting(globalDict=globalDict) for _ in range(self.dac.numChannels) ] for index, channel in enumerate(self.dacChannels): channel.globalDict = globalDict channel.onChange = partial( self.onChange, index ) self.autoApply = self.config.get(self.autoApplyConfigName, True) self.decimation = defaultdict( lambda: StaticDecimation(Q(30, 's'))) self.persistence = DBPersist() self.globalDict = globalDict self.pulser = pulser def setupUi(self, parent): dacForm.setupUi(self, parent) self.dacTableModel = DACTableModel(self.dacChannels, self.globalDict) self.tableView.setModel( self.dacTableModel ) self.delegate = MagnitudeSpinBoxDelegate(self.globalDict) self.tableView.setItemDelegateForColumn(2, self.delegate) self.applyButton.clicked.connect( self.onApply ) self.resetButton.clicked.connect( self.onReset ) self.writeAllButton.clicked.connect( self.onWriteAll ) self.autoApplyBox.setChecked( self.autoApply ) self.autoApplyBox.stateChanged.connect( self.onStateChanged ) try: self.onWriteAll( writeUnchecked=True ) except Exception as e: logging.getLogger(__name__).warning( "Ignored error while setting dac: {0}".format(e) ) self.onApply() self.dacTableModel.voltageChanged.connect( self.onVoltage ) self.dacTableModel.enableChanged.connect( self.onEnableChanged ) restoreGuiState(self, self.config.get(self.guiStateConfigName)) self.isSetup = True def onEnableChanged(self, channel, value): self.dac.setVoltage(channel, self.dacChannels[channel].outputVoltage ) def setDisabled(self, disabled): pass def onStateChanged(self, state ): self.autoApply = self.autoApplyBox.isChecked() def onVoltage(self, channel, value): self.dac.setVoltage(channel, self.dacChannels[channel].outputVoltage, autoApply=self.autoApply ) self.decimation[(0, channel)].decimate( time.time(), self.dacChannels[channel].outputVoltage, partial(self.persistCallback, "Voltage:{0}".format(self.dacChannels[channel].name if self.dacChannels[channel].name else channel)) ) def persistCallback(self, source, data): time, value, minval, maxval = data unit = None if is_Q(value): value, unit = value.m, "{:~}".format(value.units) self.persistence.persist(self.persistSpace, source, time, value, minval, maxval, unit) def onWriteAll(self, writeUnchecked=False): if len(self.dacChannels) > 0: with CombineWrites(self.dac) as stream: for channel, settings in enumerate(self.dacChannels): if writeUnchecked or settings.resetAfterPP: stream.setVoltage(channel, settings.outputVoltage, autoApply=self.autoApply, applyAll=True) def saveConfig(self): self.config[self.channelsConfigName] = self.dacChannels self.config[self.autoApplyConfigName] = self.autoApply self.config[self.guiStateConfigName] = saveGuiState( self ) def onApply(self): if self.dacChannels: self.dac.setVoltage(0, self.dacChannels[0].outputVoltage, autoApply=True, applyAll=True ) def onReset(self): self.dac.reset(0xff) def onChange(self, index, name, value, string, origin ): if self.isSetup and origin != 'value': self.dacTableModel.setVoltage(self.dacTableModel.createIndex(index, 2), value)
class GlobalVariable(QtCore.QObject): """Class for encapsulating a global variable. Attributes: valueChanged (PyQt signal): emitted when value is changed, with signature (name, new-value, origin-of-change) decimation (StaticDecimation): takes care of saving globals to database every 10 seconds history (deque): history of the last 10 values the global has been set to _value (magnitude): the global's value, accessed via 'value' property _name (str): the global's name, accessed via 'name' property categories (list[str]): the global's cateogires """ valueChanged = QtCore.pyqtSignal(object, object, object) persistSpace = 'globalVar' persistence = DBPersist() def __init__(self, name, value=Q(0), categories=None): super(GlobalVariable, self).__init__() self.decimation = StaticDecimation(Q(10, 's')) self.history = deque(maxlen=10) self._value = value self._name = name self.categories = categories @property def value(self): return self._value @value.setter def value(self, newvalue): """set the value and record the change""" if isinstance(newvalue, tuple): v, o = newvalue else: v, o = newvalue, None if self._value != v or not (type(self._value) is type(v)) or ( is_Q(v) and (type(self._value.m) is type(v.m))): self._value = v self.valueChanged.emit(self.name, v, o) self.history.appendleft((v, time.time(), o)) if o is not None: self.persistCallback((time.time(), v, None, None)) else: self.decimation.decimate(time.time(), v, self.persistCallback) @property def name(self): return self._name @name.setter def name(self, newname): """set the name and record the change in the database""" self._name, oldname = newname, self._name self.persistence.rename(self.persistSpace, oldname, newname) def __getstate__(self): return self._name, self._value, self.categories, self.history def __setstate__(self, state): super(GlobalVariable, self).__init__() self.decimation = StaticDecimation(Q(10, 's')) self._name, self._value, self.categories, self.history = state def persistCallback(self, data): time, value, minval, maxval = data unit = None if is_Q(value): value, unit = value.m, "{:~}".format(value.units) self.persistence.persist(self.persistSpace, self.name, time, value, minval, maxval, unit) def toXmlElement(self, element): e = ElementTree.SubElement( element, "GlobalVariable", attrib={ 'type': 'Magnitude', 'name': self._name, 'categories': ", ".join(self.categories) if self.categories else '' }) e.text = repr(self._value) @classmethod def fromXmlElement(cls, element): categories = [ s.strip(" ") for s in element.attrib['categories'].split(",") ] return GlobalVariable(element.attrib['name'], parse(element.text), categories)