From 4c151a8cd04febebd9690713042f15bcef588a4c Mon Sep 17 00:00:00 2001 From: chrin Date: Fri, 14 Oct 2022 13:48:13 +0200 Subject: [PATCH] sync git --- pvgateway.py- | 10 +- pvwidgets.py- | 310 +++++++++++++++++++++++++++----------------------- 2 files changed, 178 insertions(+), 142 deletions(-) diff --git a/pvgateway.py- b/pvgateway.py- index 2d6d64d..64a856c 100644 --- a/pvgateway.py- +++ b/pvgateway.py- @@ -96,14 +96,17 @@ class PVGateway(QWidget): notify_unison: bool = False, precision: int = 0, monitor_dbr_time: bool = False): + super().__init__() + if parent is None: return if not pv_name: return + self.connect_callback = connect_callback self.notify_freq_hz = abs(notify_freq_hz) self.notify_freq_hz_default = self.notify_freq_hz @@ -307,8 +310,11 @@ class PVGateway(QWidget): self.pv_message_in_a_box.setDefaultButton(QMessageBox.Close) self.initialize() - - #return self - previously used by pvgateway + #The __init__ method of a class is used to initialize new objects, + #not create them. As such, it should not return any value. + + + return #self # used by pvgateway in CAQStripChart def initialize(self): diff --git a/pvwidgets.py- b/pvwidgets.py- index 3e05f6d..b00eace 100644 --- a/pvwidgets.py- +++ b/pvwidgets.py- @@ -239,11 +239,9 @@ class CAQMenu(QComboBox, PVGateway): super().__init__(parent, pv_name, monitor_callback, pv_within_daq_group, color_mode, show_units, prefix, suffix, connect_callback=self.py_connect_callback) - + self.is_initialize_complete() - self.configure_widget() - #After configure:widget self.currentIndexChanged.connect(self.value_change) @@ -254,6 +252,7 @@ class CAQMenu(QComboBox, PVGateway): '''Callback function to be invoked on change of pv connection status. ''' + self.trigger_connect.emit(int(handle), str(pvname), int(status)) def configure_widget(self): @@ -269,9 +268,10 @@ class CAQMenu(QComboBox, PVGateway): enumStringList = self.cafe.getEnumStrings(self.handle) self.addItems(enumStringList) + for i in range(0, self.count()): self.setItemData(i, Qt.AlignCenter, Qt.TextAlignmentRole) - + fm = QFontMetricsF(QFont("Sans Serif", 10)) qrect = fm.boundingRect(self.suggested_text) @@ -283,9 +283,11 @@ class CAQMenu(QComboBox, PVGateway): self.qt_property_initial_values(qt_object_name=self.PV_CONTROLLER) def post_display_value(self, value): + + '''Convert value to index''' if "setCurrentIndex" in dir(self): - + if LooseVersion(QT_VERSION_STR) >= LooseVersion("5.3"): self.blockSignals(True) @@ -311,7 +313,6 @@ class CAQMenu(QComboBox, PVGateway): def value_change(self, indx): - status = self.cafe.set(self.handle, indx) if status != self.cyca.ICAFE_NORMAL: @@ -346,9 +347,8 @@ class CAQMenu(QComboBox, PVGateway): if self.pv_info.accessWrite == 0: event.ignore() return - else: - QComboBox.mousePressEvent(self, event) - + + QComboBox.mousePressEvent(self, event) self.previousIndex = self.currentIndex() def enterEvent(self, event): @@ -2431,10 +2431,17 @@ class QNoDockWidget(QDockWidget): self.topLevelChanged.connect(self._top_level_changed) self.setVisible(False) self.setFloating(True) + + x = self.geometry_from_qsettings.x() + 480 # 3500 #screen.width() - widget.width() + y = self.geometry_from_qsettings.y() + 350 #100 #screen.height() - widget.height() + self.move(x, y) + def changeEvent(self, event): if "QAbstractButton" in str(self.sender()): self.geometry_from_qsettings = self.parent.geometry() + + def _top_level_changed(self): #, is_floating): self.setVisible(False) @@ -2452,40 +2459,46 @@ class CAQStripChart(PlotWidget): monitor_callback=None, pv_within_daq_group: bool = False, color_mode=None, show_units: bool = False, prefix: str = "", suffix: str = "", notify_freq_hz: int = 0, title: str = "", - ylabel: str = ""): + ylabel: str = "", force_ts_align = True, text_label = [], + pen_color_idx = 0): super().__init__() self.no_channels = len(pv_list) - + self.pen_color_idx = pen_color_idx + self.text_label = text_label self.found = False self.time_zero = [0] * self.no_channels self.time_delta = [0] * self.no_channels - self.pv_list = pv_list + self.pv_list = pv_list self.pv2item_dict = {} self.pv_gateway = [None] * self.no_channels - + self.pvd_previous_list = [None] * self.no_channels self.val_previous = [None] * self.no_channels self.curve = [None] * self.no_channels - for i in range(0, len(self.pv_list)): + + for i in range (0, len(self.pv_list)): + print("in atripchart", i, self.pv_list[i]) self.pv_gateway[i] = PVGateway( - parent, pv_list[i], monitor_callback, pv_within_daq_group, - color_mode, show_units, prefix, suffix, + parent, self.pv_list[i], monitor_callback, pv_within_daq_group, + color_mode, show_units, prefix, suffix, #connect_callback=self.py_connect_callback, connect_triggers=False, notify_freq_hz=notify_freq_hz, - monitor_dbr_time=True) + monitor_dbr_time = True) + self.pv_gateway[i].is_initialize_complete() - + + self.pvd_previous_list[i] = self.pv_gateway[i].pvd self.pv_gateway[i].trigger_connect.connect( self.receive_connect_update) - + self.pv_gateway[i].trigger_monitor_str.connect( - self.receive_monitor_update) + self.receive_monitor_update) self.pv_gateway[i].trigger_monitor_int.connect( self.receive_monitor_update) self.pv_gateway[i].trigger_monitor_float.connect( @@ -2493,38 +2506,40 @@ class CAQStripChart(PlotWidget): self.pv_gateway[i].trigger_monitor.connect( self.receive_monitor_dbr_time) - self.pv_gateway[i].widget_class = "PlotWidget" + self.pv_gateway[i].widget_class = "PlotWidget" + self.pv2item_dict[self.pv_gateway[i]] = i self.cafe = self.pv_gateway[0].cafe self.cyca = self.pv_gateway[0].cyca - for i in range(0, len(self.pv_gateway)): + for i in range(0, len(self.pv_gateway)): if self.cafe.isConnected(self.pv_gateway[i].pv_name): self.pv_gateway[i].trigger_connect.emit( self.pv_gateway[i].handle, str(self.pv_gateway[i].pv_name), self.pv_gateway[i].cyca.ICAFE_CS_CONN) + for i in range(0, len(self.pv_gateway)): if not self.pv_gateway[i].pv_within_daq_group: self.pv_gateway[i].monitor_start() - - sampleinterval = 0.2 - ##timewindow = 1800.0 + + sampleinterval = 0.2 + timewindow = 1800.0 self.ts_delta_max = 0.6 - + # Data stuff self._interval = int(sampleinterval*1000) self._bufsize = 9000 #int(timewindow/0.33) self._bufsize2 = 9000 # int(timewindow/1.33) self.databuffer = [None] * self.no_channels self.timebuffer = [None] * self.no_channels - self.x = [None] * self.no_channels - self.y = [None] * self.no_channels + self.x = [None] * self.no_channels + self.y = [None] * self.no_channels self.x_shifted = [None] * self.no_channels self.idx = [0] * self.no_channels - + for i in range(0, self.no_channels): bsize = self._bufsize if i == 0 else self._bufsize2 self.databuffer[i] = collections.deque([None]*bsize, bsize) @@ -2532,9 +2547,9 @@ class CAQStripChart(PlotWidget): self.x[i] = np.zeros(bsize, dtype=np.float) self.y[i] = np.zeros(bsize, dtype=np.float) - ##_long_size=20 + _long_size=20 #self.data_series_buffer = collections.deque([0]*_long_size, _long_size) - #self.time_series_buffer = collections.deque([0]*_long_size, _long_size) + #self.time_series_buffer = collections.deque([0]*_long_size, _long_size) #self.data_series = [] * self.no_channels #self.time_series = [] * self.no_channels @@ -2545,98 +2560,118 @@ class CAQStripChart(PlotWidget): #self.x_series = np.zeros(_long_size, dtype=np.float) #self.y_series = np.zeros(_long_size, dtype=np.float) if title is not None: - self.setTitle(str(title)) #self.pv_gateway[0].pv_name) + self.setTitle(str(title)) #self.pv_gateway[0].pv_name) self.showGrid(x=True, y=True) self.setLabel('left', ylabel, self.pv_gateway[0].units) - self.setLabel('bottom', 'time', 's') + self.setLabel('bottom', 'time', 's') self.setBackground((60, 60, 60)) #247, 236, 249)) self.setLimits(yMin=-0.11) - self.plotItem.setMouseEnabled(y=False) # Only allow zoom in X-axis + self.plotItem.setMouseEnabled(y=True) # Only allow zoom in X-axis self.plotItem.setMouseEnabled(x=True) # Only allow zoom in Y-axis - - pen_list = [(125, 249, 255), (255, 255, 0)] + #(125, 249, 255) + if self.pen_color_idx == 0: + pen_list = [ (255, 155, 0), (255,255,0), (0, 180, 255) ] + elif self.pen_color_idx == 1: + pen_list = [ (125, 249, 255), (255,255,0), (0, 180, 255) ] + else: + pen_list = [ (0, 180, 255), (125, 249, 255), (255,255,0) ] for i in range(0, len(self.pv_gateway)): - self.curve[i] = self.plot(self.x[0], self.y[0], pen=pen_list[i]) + self.curve[i] = self.plot(self.x[0], self.y[0], pen=pen_list[i]) # (0, 253, 235)) + #self.curve[1] = self.plot(self.x[1], self.y[1], pen=(255,255,0)) + #offset=(1.0, 1.0), + l=pg.LegendItem() #horSpacing=20, verSpacing=0, labelTextColor=(205, 205, 205), + #labelTextSize='6px', colCount=1) - l = pg.LegendItem(offset=(0., 0.5), colCount=1) l.setParentItem(self.graphicsItem()) + l.anchor((0,0), (0.08, 0.0)) + #l.setLabelTextColor((205, 205, 205)) + #l.setLabelTextSize(9) does not exists(!) + #l.setOffset(-60) + for curv, label in zip(self.curve, self.text_label): + l.addItem(curv, label) - l.setLabelTextColor((255, 255, 255)) - - for curv, pv in zip(self.curve, self.pv_gateway): - l.addItem(curv, pv.pv_name) - + #for curv, pv in zip(self.curve, self.pv_gateway): + # l.addItem(curv, self.textpv.pv_name) + + #self.daq_stop() + #print(self._bufsize) + #print(len(self.x), len(self.y)) QApplication.processEvents() - - @Slot(object, int) + + @Slot(object, int) def receive_monitor_dbr_time(self, pvdata, alarm_severity): - - #Check on alarm_severity?? - _row = self.pv2item_dict[self.sender()] - + #print("row, value from pvdata==>", _row, pvdata.value[0], self.pv_gateway[_row].pv_name) + ts_now = pvdata.ts[0] + pvdata.ts[1] * 10**(-9) - ts_previous = (self.pvd_previous_list[_row].ts[0] + - self.pvd_previous_list[_row].ts[1] * 10**(-9)) - ##ts_delta = ts_now - ts_previous - + ts_previous = (self.pvd_previous_list[_row].ts[0] + + self.pvd_previous_list[_row].ts[1] * 10**(-9)) + ts_delta = ts_now - ts_previous + if (pvdata.ts[0] == self.pvd_previous_list[_row].ts[0]) and ( pvdata.ts[1] == self.pvd_previous_list[_row].ts[1]): - pvdata.show() + #pvdata.show() self.pvd_previous_list[_row].show() return - - value = pvdata.value[0] + + value = pvdata.value[0] #discard first callbacks #if ts_delta > 2.0: - # self.pvd_previous_list[_row] = _pvd + # self.pvd_previous_list[_row] = _pvd # return; self.pvd_previous_list[_row] = pvdata self.val_previous[_row] = value - #self.pvd_previous_list[_row].ts[0] = _pvd.ts[0] + #self.pvd_previous_list[_row].ts[0] = _pvd.ts[0] #self.pvd_previous_list[_row].ts[1] = _pvd.ts[1] - + self.databuffer[_row].append(value) self.timebuffer[_row].append(self.time_delta[_row]) highest_ts = self.timebuffer[0][0] \ if self.timebuffer[0][0] is not None else 0 - for i in range(1, len(self.timebuffer)): + for i in range(1, len(self.timebuffer)): if self.timebuffer[i][0] is None: continue elif self.timebuffer[i][0] > highest_ts: highest_ts = self.timebuffer[i][0] - + if self.timebuffer[_row][0] is not None: for i, val in enumerate(self.timebuffer[_row]): if val > highest_ts: self.idx[_row] = i - 1 - break + break self.y[_row][:] = self.databuffer[_row] self.x[_row][:] = self.timebuffer[_row] - + idx = self.idx[_row] - self.x_shifted[_row] = list( - map(lambda m: (m - self.time_delta[_row]), self.x[_row][idx:])) + self.x_shifted[_row] = list(map(lambda m : (m - self.time_delta[_row]), self.x[_row][idx:])) - self.curve[_row].setData(self.x_shifted[_row], self.y[_row][idx:]) + #print("idx", self.idx) + + #if 'AVG' in self.pv_gateway[_row].pv_name: + # for row in range(0, len(self.curve)): + # self.curve[row].setData(self.x_shifted[row], self.y[row][idx:]) + self.curve[_row].setData(self.x_shifted[_row], self.y[_row][idx:]) self.time_delta[_row] = ( - pvdata.ts[0] + pvdata.ts[1]*10**(-9)) - self.time_zero[0] - + pvdata.ts[0] + pvdata.ts[1]*10**(-9)) - self.time_zero[0] + + #QApplication.processEvents() + @Slot(str, int, int) @Slot(int, int, int) @Slot(float, int, int) def receive_monitor_update(self, value, status, alarm_severity): - + #self.pv_gateway.receive_monitor_update(value, status, alarm_severity) _row = self.pv2item_dict[self.sender()] - - #print("row, value===>", _row, value, self.pv_gateway[_row].pv_name) + #if _row == 1: + # return + print("row, value===>", _row, value, self.pv_gateway[_row].pv_name) _pvd = self.pv_gateway[_row].cafe.getPVCache( self.pv_gateway[_row].handle) @@ -2644,109 +2679,106 @@ class CAQStripChart(PlotWidget): _pvd2 = self.pv_gateway[_row].pvd - print("val", value, _pvd2.value[0], _pvd.value[0], - self.pvd_previous_list[_row].value[0]) + print ("val", value, _pvd2.value[0], _pvd.value[0], self.pvd_previous_list[_row].value[0]) ts_now = _pvd.ts[0] + _pvd.ts[1] * 10**(-9) - ts_previous = (self.pvd_previous_list[_row].ts[0] + - self.pvd_previous_list[_row].ts[1] * 10**(-9)) - ts_delta = ts_now - ts_previous - + ts_previous = (self.pvd_previous_list[_row].ts[0] + + self.pvd_previous_list[_row].ts[1] * 10**(-9)) + ts_delta = ts_now - ts_previous + if value == self.val_previous[_row]: + #if (_pvd.ts[0] == self.pvd_previous_list[_row].ts[0]) and ( + # _pvd.ts[1] == self.pvd_previous_list[_row].ts[1]): _pvd.show() - + #self.pvd_previous_list[_row].show() return - - + + #discard first callbacks #if ts_delta > 2.0: - # self.pvd_previous_list[_row] = _pvd + # self.pvd_previous_list[_row] = _pvd # return; self.pvd_previous_list[_row] = _pvd2 self.val_previous[_row] = value - #self.pvd_previous_list[_row].ts[0] = _pvd.ts[0] + #self.pvd_previous_list[_row].ts[0] = _pvd.ts[0] #self.pvd_previous_list[_row].ts[1] = _pvd.ts[1] - + self.databuffer[_row].append(value) self.timebuffer[_row].append(self.time_delta[_row]) highest_ts = self.timebuffer[0][0] \ if self.timebuffer[0][0] is not None else 0 - for i in range(1, len(self.timebuffer)): + for i in range(1, len(self.timebuffer)): if self.timebuffer[i][0] is None: continue elif self.timebuffer[i][0] > highest_ts: highest_ts = self.timebuffer[i][0] - - + + if self.timebuffer[_row][0] is not None: for i, val in enumerate(self.timebuffer[_row]): if val > highest_ts: self.idx[_row] = i - 1 - break - - - #for i in range(1, self.timebuffer): - # if self.timebuffer[i][0] is not None: - # a = self.timebuffer[0][0] - # for i, val in enumerate(self.timebuffer[_row]): - # if val > a: - # idx = i - 1 - # break + break + ''' + for i in range(1, self.timebuffer): + if self.timebuffer[i][0] is not None: + a = self.timebuffer[0][0] + for i, val in enumerate(self.timebuffer[_row]): + if val > a: + idx = i - 1 + break + ''' + self.y[_row][:] = self.databuffer[_row] self.x[_row][:] = self.timebuffer[_row] - + #self.y[_row][:] = self.databuffer[_row] #self.x[_row][:] = self.timebuffer[_row] ''' #print(ts_delta, value, self.pvd_previous.value[0]) - #if (ts_delta < self.ts_delta_max) and (value < - #self.pvd_previous.value[0]) : + #if (ts_delta < self.ts_delta_max) and (value < self.pvd_previous.value[0]) : if (value < self.pvd_previous.value[0]) : self.data_series_buffer.append(value) - self.time_series_buffer.append(ts_now - self.time_zero ) + self.time_series_buffer.append(ts_now - self.time_zero ) #self.time_delta) self.y_series[:] = self.data_series_buffer self.x_series[:] = self.time_series_buffer #print(self.x_series, self.y_series) #elif ts_delta < 1.0: - if len(self.data_series_buffer) > 15: + if len(self.data_series_buffer) > 15: #x_series = np.array(self.time_series, dtype=np.float) #y_series = np.array(self.data_series, dtype=np.float) _x=self.x_series.reshape((-1, 1)) - + model = LinearRegression() model.fit(_x, self.y_series) r_sq = model.score(_x, self.y_series) - ###JCprint('coefficient of determination:', - ##r_sq, "slope", model.coef_ , "lifetime:", - ###self.y_series[0]/model.coef_ / 3600) + ###JCprint('coefficient of determination:', r_sq, "slope", model.coef_ , "lifetime:", self.y_series[0]/model.coef_ / 3600) #print('intercept:', model.intercept_) #print('slope:', model.coef_) #print('max value', y_series[0], y_series[1]) if r_sq > 0.995: _I = self.y_series[0] ###JCprint("lifetime:", _I/model.coef_ / 3600) - - + + y_pred = model.predict(_x) - #print("len, y_pred, _x", len(y_pred), - #len(self.y_series), len(_x)) + #print("len, y_pred, _x", len(y_pred), len(self.y_series), len(_x)) #print('predicted response:', y_pred, sep='\n') m_sq_error = mean_squared_error(self.y_series, y_pred) #print('Mean squared error: {0:.9f}'.format( # mean_squared_error(y_series, y_pred))) #print('Coefficient of determination: {0:.9f}'.format( - # r2_score(y_series, y_pred))) + # r2_score(y_series, y_pred))) + - - self.trigger_series_sequence.emit(self.x_series, - self.y_series) + self.trigger_series_sequence.emit(self.x_series, self.y_series) #print("emit") self.data_series = [] self.time_series = [] @@ -2754,75 +2786,73 @@ class CAQStripChart(PlotWidget): else: self.data_series = [] self.time_series = [] - + ''' + - - #dt = (self.x[-1] - self.x[-2]) + #dt = (self.x[-1] - self.x[-2]) #print("dt", dt) #Lowet IPCT before trigger is set to t=0 idx = self.idx[_row] - self.x_shifted[_row] = list( - map(lambda m: (m - self.time_delta[_row]), self.x[_row][idx:])) + self.x_shifted[_row] = list(map(lambda m : (m - self.time_delta[_row]), self.x[_row][idx:])) ##self.y = np.where(self.y != self.y, 0, self.y) #test for nan - + #print("row len len ", _row, self.time_delta[0], self.time_delta[1]) - - + + self.curve[_row].setData(self.x_shifted[_row], self.y[_row][idx:]) - + self.time_delta[_row] = ( - _pvd.ts[0] + _pvd.ts[1]*10**(-9)) - self.time_zero[0] - - + _pvd.ts[0] + _pvd.ts[1]*10**(-9)) - self.time_zero[0] + + ''' - LOOK_BACK = -800 + LOOK_BACK = -800 if 'ARIDI-PCT2:CURRENT' in self.pv_gateway[_row].pv_name: LOOK_BACK = -250 - if value > self.y[-2]: + if value > self.y[-2]: if not self.found: #print(x_shifted[-240:], self.y[-240:]) #self.y = np.where(self.y != self.y, 0, self.y) #test for nan max_index = self.y[LOOK_BACK:].argmax() - + if max_index == 0: return print("max index=", max_index) - - #print(x_shifted[-600+max_index:], self.x[-600+max_index:]) - #print(self.y[-600+max_index:-2]) + + #print(x_shifted[-600+max_index:], self.x[-600+max_index:]) + #print(self.y[-600+max_index:-2]) self.found = True #print("Are Signals blocked??", self.signalsBlocked()) self.trigger_decay_sequence.emit(np.array( - x_shifted[LOOK_BACK+max_index+9:-2]), - self.y[LOOK_BACK+max_index+9:-2]) + x_shifted[LOOK_BACK+max_index+9:-2]), self.y[LOOK_BACK+max_index+9:-2]) else: self.found = False - ''' - + ''' + @Slot(int, str, int) def receive_connect_update(self, handle: int, pv_name: str, status: int): '''Triggered by connect signal''' print("pv_name==>", pv_name) - + _row = self.pv2item_dict[self.sender()] - self.pv_gateway[_row].receive_connect_update(handle, pv_name, status, + self.pv_gateway[_row].receive_connect_update(handle, pv_name, status, post_display=False) #self.pv_gateway.receive_connect_update(handle, pv_name, status) - _pvd = self.pv_gateway[_row].cafe.getPVCache( - self.pv_gateway[_row].handle) + _pvd = self.pv_gateway[_row].cafe.getPVCache(self.pv_gateway[_row].handle) if self.time_zero[_row] == 0: self.time_zero[_row] = _pvd.ts[0] + _pvd.ts[1]*10**(-9) - + self.pvd_previous = _pvd #renove highlighting which persists after mouse leaves def mouseMoveEvent(self, event): + #event.ignore() pass def leaveEvent(self, event):