class PybarFEI4Histogrammer(Transceiver): def setup_transceiver(self): self.set_bidirectional_communication() # We want to be able to change the histogrammmer settings def setup_interpretation(self): self.histograming = PyDataHistograming() self.histograming.set_no_scan_parameter() self.histograming.create_occupancy_hist(True) self.histograming.create_rel_bcid_hist(True) self.histograming.create_tot_hist(True) self.histograming.create_tdc_hist(True) # Variables self.n_readouts = 0 self.readout = 0 self.fps = 0 # data frames per second self.hps = 0 # hits per second self.eps = 0 # events per second self.plot_delay = 0 self.total_hits = 0 self.total_events = 0 self.updateTime = time.time() # Histogrammes from interpretation stored for summing self.tdc_counters = None self.error_counters = None self.service_records_counters = None self.trigger_error_counters = None def deserialze_data(self, data): return jsonapi.loads(data, object_hook=utils.json_numpy_obj_hook) def interpret_data(self, data): if 'meta_data' in data[0][1]: # Meta data is directly forwarded to the receiver, only hit data, event counters are histogramed; 0 from frontend index, 1 for data dict meta_data = data[0][1]['meta_data'] now = time.time() recent_total_hits = meta_data['n_hits'] recent_total_events = meta_data['n_events'] recent_fps = 1.0 / (now - self.updateTime) # calculate FPS recent_hps = (recent_total_hits - self.total_hits) / (now - self.updateTime) recent_eps = (recent_total_events - self.total_events) / (now - self.updateTime) self.updateTime = now self.total_hits = recent_total_hits self.total_events = recent_total_events self.fps = self.fps * 0.7 + recent_fps * 0.3 self.hps = self.hps + (recent_hps - self.hps) * 0.3 / self.fps self.eps = self.eps + (recent_eps - self.eps) * 0.3 / self.fps meta_data.update({'fps': self.fps, 'hps': self.hps, 'total_hits': self.total_hits, 'eps': self.eps, 'total_events': self.total_events}) return [data[0][1]] self.readout += 1 if self.n_readouts != 0: # = 0 for infinite integration if self.readout % self.n_readouts == 0: self.histograming.reset() self.tdc_counters = np.zeros_like(self.tdc_counters) self.error_counters = np.zeros_like(self.error_counters) self.service_records_counters = np.zeros_like(self.service_records_counters) self.trigger_error_counters = np.zeros_like(self.trigger_error_counters) self.readouts = 0 interpreted_data = data[0][1] self.histograming.add_hits(interpreted_data['hits']) # Sum up interpreter histograms if self.tdc_counters is not None: self.tdc_counters += interpreted_data['tdc_counters'] else: self.tdc_counters = interpreted_data['tdc_counters'].copy() # Copy needed to give ownage to histogrammer if self.error_counters is not None: self.error_counters += interpreted_data['error_counters'] else: self.error_counters = interpreted_data['error_counters'].copy() # Copy needed to give ownage to histogrammer if self.service_records_counters is not None: self.service_records_counters += interpreted_data['service_records_counters'] else: self.service_records_counters = interpreted_data['service_records_counters'].copy() # Copy needed to give ownage to histogrammer if self.trigger_error_counters is not None: self.trigger_error_counters += interpreted_data['trigger_error_counters'] else: self.trigger_error_counters = interpreted_data['trigger_error_counters'].copy() # Copy needed to give ownage to histogrammer histogrammed_data = { 'occupancy': self.histograming.get_occupancy(), 'tot_hist': self.histograming.get_tot_hist(), 'tdc_counters': self.tdc_counters, 'error_counters': self.error_counters, 'service_records_counters': self.service_records_counters, 'trigger_error_counters': self.trigger_error_counters, 'rel_bcid_hist': self.histograming.get_rel_bcid_hist() } return [histogrammed_data] def serialze_data(self, data): return jsonapi.dumps(data, cls=utils.NumpyEncoder) def handle_command(self, command): if command[0] == 'RESET': self.histograming.reset() self.tdc_counters = np.zeros_like(self.tdc_counters) self.error_counters = np.zeros_like(self.error_counters) self.service_records_counters = np.zeros_like(self.service_records_counters) self.trigger_error_counters = np.zeros_like(self.trigger_error_counters) else: self.n_readouts = int(command[0])
class DataWorker(QtCore.QObject): run_start = QtCore.pyqtSignal() run_config_data = QtCore.pyqtSignal(dict) global_config_data = QtCore.pyqtSignal(dict) filename = QtCore.pyqtSignal(dict) interpreted_data = QtCore.pyqtSignal(dict) meta_data = QtCore.pyqtSignal(dict) finished = QtCore.pyqtSignal() def __init__(self): QtCore.QObject.__init__(self) self.integrate_readouts = 1 self.n_readout = 0 self._stop_readout = Event() self.setup_raw_data_analysis() self.reset_lock = Lock() def setup_raw_data_analysis(self): self.interpreter = PyDataInterpreter() self.histogram = PyDataHistograming() self.interpreter.set_warning_output(False) self.histogram.set_no_scan_parameter() self.histogram.create_occupancy_hist(True) self.histogram.create_rel_bcid_hist(True) self.histogram.create_tot_hist(True) self.histogram.create_tdc_hist(True) try: self.histogram.create_tdc_distance_hist(True) self.interpreter.use_tdc_trigger_time_stamp(True) except AttributeError: self.has_tdc_distance = False else: self.has_tdc_distance = True def connect(self, socket_addr): self.socket_addr = socket_addr self.context = zmq.Context() self.socket_pull = self.context.socket(zmq.SUB) # subscriber self.socket_pull.setsockopt(zmq.SUBSCRIBE, '') # do not filter any data self.socket_pull.connect(self.socket_addr) def on_set_integrate_readouts(self, value): self.integrate_readouts = value def reset(self): with self.reset_lock: self.histogram.reset() self.interpreter.reset() self.n_readout = 0 def analyze_raw_data(self, raw_data): self.interpreter.interpret_raw_data(raw_data) self.histogram.add_hits(self.interpreter.get_hits()) def process_data( self ): # infinite loop via QObject.moveToThread(), does not block event loop while (not self._stop_readout.wait(0.01) ): # use wait(), do not block here with self.reset_lock: try: meta_data = self.socket_pull.recv_json(flags=zmq.NOBLOCK) except zmq.Again: pass else: name = meta_data.pop('name') if name == 'ReadoutData': data = self.socket_pull.recv() # reconstruct numpy array buf = buffer(data) dtype = meta_data.pop('dtype') shape = meta_data.pop('shape') data_array = np.frombuffer(buf, dtype=dtype).reshape(shape) # count readouts and reset self.n_readout += 1 if self.integrate_readouts != 0 and self.n_readout % self.integrate_readouts == 0: self.histogram.reset() # we do not want to reset interpreter to keep the error counters # self.interpreter.reset() # interpreted data self.analyze_raw_data(data_array) if self.integrate_readouts == 0 or self.n_readout % self.integrate_readouts == self.integrate_readouts - 1: interpreted_data = { 'occupancy': self.histogram.get_occupancy(), 'tot_hist': self.histogram.get_tot_hist(), 'tdc_counters': self.interpreter.get_tdc_counters(), 'tdc_distance': self.interpreter.get_tdc_distance() if self.has_tdc_distance else np.zeros( (256, ), dtype=np.uint8), 'error_counters': self.interpreter.get_error_counters(), 'service_records_counters': self.interpreter.get_service_records_counters( ), 'trigger_error_counters': self.interpreter.get_trigger_error_counters(), 'rel_bcid_hist': self.histogram.get_rel_bcid_hist() } self.interpreted_data.emit(interpreted_data) # meta data meta_data.update({ 'n_hits': self.interpreter.get_n_hits(), 'n_events': self.interpreter.get_n_events() }) self.meta_data.emit(meta_data) elif name == 'RunConf': self.run_config_data.emit(meta_data) elif name == 'GlobalRegisterConf': trig_count = int(meta_data['conf']['Trig_Count']) self.interpreter.set_trig_count(trig_count) self.global_config_data.emit(meta_data) elif name == 'Reset': self.histogram.reset() self.interpreter.reset() self.run_start.emit() elif name == 'Filename': self.filename.emit(meta_data) self.finished.emit() def stop(self): self._stop_readout.set()
class PybarFEI4Histogrammer(Transceiver): def setup_transceiver(self): self.set_bidirectional_communication( ) # We want to be able to change the histogrammmer settings def setup_interpretation(self): self.histograming = PyDataHistograming() self.histograming.set_no_scan_parameter() self.histograming.create_occupancy_hist(True) self.histograming.create_rel_bcid_hist(True) self.histograming.create_tot_hist(True) self.histograming.create_tdc_hist(True) # Variables self.n_readouts = 0 self.readout = 0 self.fps = 0 # data frames per second self.hps = 0 # hits per second self.eps = 0 # events per second self.plot_delay = 0 self.total_hits = 0 self.total_events = 0 self.updateTime = time.time() # Histogrammes from interpretation stored for summing self.tdc_counters = None self.error_counters = None self.service_records_counters = None self.trigger_error_counters = None def deserialze_data(self, data): return jsonapi.loads(data, object_hook=utils.json_numpy_obj_hook) def interpret_data(self, data): # Meta data is directly forwarded to the receiver, only hit data and event counters are histogramed if 'meta_data' in data[0][1]: # 0 for frontend index, 1 for data dict meta_data = data[0][1]['meta_data'] now = time.time() recent_total_hits = meta_data['n_hits'] recent_total_events = meta_data['n_events'] recent_fps = 1.0 / (now - self.updateTime) # calculate FPS recent_hps = (recent_total_hits - self.total_hits) / (now - self.updateTime) recent_eps = (recent_total_events - self.total_events) / (now - self.updateTime) self.updateTime = now self.total_hits = recent_total_hits self.total_events = recent_total_events self.fps = self.fps * 0.7 + recent_fps * 0.3 self.hps = self.hps + (recent_hps - self.hps) * 0.3 / self.fps self.eps = self.eps + (recent_eps - self.eps) * 0.3 / self.fps meta_data.update({ 'fps': self.fps, 'hps': self.hps, 'total_hits': self.total_hits, 'eps': self.eps, 'total_events': self.total_events }) return [data[0][1]] self.readout += 1 if self.n_readouts != 0: # 0 for infinite integration if self.readout % self.n_readouts == 0: self.histograming.reset() self.tdc_counters = np.zeros_like(self.tdc_counters) self.error_counters = np.zeros_like(self.error_counters) self.service_records_counters = np.zeros_like( self.service_records_counters) self.trigger_error_counters = np.zeros_like( self.trigger_error_counters) self.readouts = 0 interpreted_data = data[0][1] self.histograming.add_hits(interpreted_data['hits']) # Sum up interpreter histograms if self.tdc_counters is not None: self.tdc_counters += interpreted_data['tdc_counters'] else: self.tdc_counters = interpreted_data['tdc_counters'].copy( ) # Copy needed to give ownage to histogrammer if self.error_counters is not None: self.error_counters += interpreted_data['error_counters'] else: self.error_counters = interpreted_data['error_counters'].copy( ) # Copy needed to give ownage to histogrammer if self.service_records_counters is not None: self.service_records_counters += interpreted_data[ 'service_records_counters'] else: self.service_records_counters = interpreted_data[ 'service_records_counters'].copy( ) # Copy needed to give ownage to histogrammer if self.trigger_error_counters is not None: self.trigger_error_counters += interpreted_data[ 'trigger_error_counters'] else: self.trigger_error_counters = interpreted_data[ 'trigger_error_counters'].copy( ) # Copy needed to give ownage to histogrammer histogrammed_data = { 'occupancy': self.histograming.get_occupancy(), 'tot_hist': self.histograming.get_tot_hist(), 'tdc_counters': self.tdc_counters, 'error_counters': self.error_counters, 'service_records_counters': self.service_records_counters, 'trigger_error_counters': self.trigger_error_counters, 'rel_bcid_hist': self.histograming.get_rel_bcid_hist() } return [histogrammed_data] def serialze_data(self, data): return jsonapi.dumps(data, cls=utils.NumpyEncoder) def handle_command(self, command): if command[0] == 'RESET': # Reset command to reset the histograms self.histograming.reset() self.tdc_counters = np.zeros_like(self.tdc_counters) self.error_counters = np.zeros_like(self.error_counters) self.service_records_counters = np.zeros_like( self.service_records_counters) self.trigger_error_counters = np.zeros_like( self.trigger_error_counters) else: self.n_readouts = int(command[0])