File indexing completed on 2025-07-01 08:57:56
0001
0002
0003
0004
0005
0006 import zmq, struct, pickle, random
0007 import numpy as np
0008 import matplotlib.pyplot as plt
0009
0010
0011 subPort = 5557
0012 pubPort = 5558
0013
0014 numChans = 80
0015
0016
0017 subContext = zmq.Context()
0018 subscriber = subContext.socket(zmq.SUB)
0019 subscriber.setsockopt(zmq.SUBSCRIBE, b'')
0020 subscriber.connect('tcp://127.0.0.1:%d' % subPort)
0021 print('\nSubscribing to JANA ZMQ Messages on socket tcp://127.0.0.1:%d\n' % subPort)
0022
0023
0024
0025
0026
0027
0028
0029
0030 class IndraMessage:
0031 """Class to handle decoding of ZMQ INDRA Messages"""
0032
0033 def __init__(self, zmqMessage):
0034
0035
0036 self.dataDict = {}
0037
0038 self.messageSize = len(zmqMessage)
0039
0040 self.payloadBytes = self.messageSize - 56
0041
0042 self.message = struct.unpack('IIIIIIIQqq%ds' % self.payloadBytes, zmqMessage)
0043
0044 self.sourceId = self.message[0]
0045 self.totalBytes = self.message[1]
0046 self.payloadBytes = self.message[2]
0047 self.compressedBytes = self.message[3]
0048 self.magic = self.message[4]
0049 self.formatVersion = self.message[5]
0050 self.flags = self.message[6]
0051 self.recordCounter = self.message[7]
0052 self.timeStampSec = self.message[8]
0053 self.timeStampNanoSec = self.message[9]
0054 self.payload = self.message[10]
0055
0056 print('INDRA Message recieved -> event = %d, size = %d bytes' % (self.recordCounter, self.messageSize))
0057
0058 self.adcSamplesStr = np.frombuffer(self.payload, dtype='S5')
0059 self.adcSamples = np.reshape(self.adcSamplesStr.astype(np.int), (1024, 80))
0060
0061 for chan in range(1, numChans + 1):
0062 self.dataDict.update({'adcSamplesChan_%s' % chan: np.array([])})
0063 self.dataDict.update(
0064 {'tdcSamplesChan_%s' % chan: np.arange((self.recordCounter - 1) * 1024, self.recordCounter * 1024)})
0065
0066 for index, sample in np.ndenumerate(self.adcSamples):
0067 self.dataDict['adcSamplesChan_%s' % str(index[1] + 1)] = \
0068 np.append(self.dataDict['adcSamplesChan_%s' % str(index[1] + 1)], sample)
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 class MonitoringFigure:
0079 """Class to create figure and subplots based on user input"""
0080
0081
0082 def __init__(self, rows, cols):
0083 self.numRows = rows
0084 self.numCols = cols
0085 self.fig, self.axs = plt.subplots(self.numRows, self.numCols)
0086 self.fig.set_size_inches(18.5, 10.5, forward=True)
0087
0088 def get_num_rows(self):
0089 return self.numRows
0090
0091 def get_num_cols(self):
0092 return self.numCols
0093
0094 def get_fig_obj(self):
0095 return self.fig
0096
0097 def get_axs_obj(self):
0098 return self.axs
0099
0100
0101 class MonitoringPlots:
0102 """Class to plot streaming ADC vs. TDC data"""
0103
0104
0105 def __init__(self, dataDict, thresh, rows, cols, fig, axs):
0106
0107 self.numRows = rows
0108 self.numCols = cols
0109 self.fig = fig
0110 self.axs = axs
0111
0112 self.cl = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple',
0113 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
0114 self.ml = ['o', '^', 's', 'p', 'P', '*', 'X', 'd']
0115
0116 self.rcl = random.sample(range(1, numChans + 1), self.numRows * self.numCols)
0117 self.rcl.sort()
0118
0119 self.enl = []
0120 self.hitThresh = thresh
0121 self.ic = 0
0122 for row in range(self.numRows):
0123 for column in range(self.numCols):
0124 self.axs[row, column].cla()
0125 self.axs[row, column].plot(dataDict['tdcSamplesChan_%d' % self.rcl[self.ic]],
0126 dataDict['adcSamplesChan_%d' % self.rcl[self.ic]],
0127 color=self.cl[self.ic % len(self.cl)],
0128 marker=self.ml[self.ic % len(self.ml)],
0129 ls='', label='Channel %d' % self.rcl[self.ic])
0130 hitLoc = np.where(dataDict['adcSamplesChan_%d' % self.rcl[self.ic]] > 100)[0] + \
0131 np.min(dataDict['tdcSamplesChan_%d' % self.rcl[self.ic]])
0132 if len(hitLoc) != 0: self.axs[row, column].set_xlim(np.min(hitLoc) - 10, np.max(hitLoc) + 20)
0133 self.axs[row, column].set_ylim(0, 1024)
0134 if column == 0:
0135 self.axs[row, column].set_ylabel('ADC Value')
0136 if row == self.numRows - 1:
0137 self.axs[row, column].set_xlabel('TDC Sample Number')
0138 self.axs[row, column].legend(loc='best', markerscale=0, handletextpad=0, handlelength=0)
0139 self.ic += 1
0140 plt.tight_layout()
0141
0142 plt.pause(0.05)
0143
0144 for chan in range(1, numChans + 1):
0145 dataDict.pop('adcSamplesChan_%s' % str(chan), None)
0146 dataDict.pop('tdcSamplesChan_%s' % str(chan), None)
0147
0148
0149
0150 monFig = MonitoringFigure(2, 2)
0151
0152 while True:
0153
0154 janaMessage = subscriber.recv()
0155
0156 jevent = IndraMessage(janaMessage)
0157
0158
0159 monPlots = MonitoringPlots(jevent.dataDict, 100,
0160 monFig.get_num_rows(), monFig.get_num_cols(),
0161 monFig.get_fig_obj(), monFig.get_axs_obj())
0162
0163
0164
0165
0166
0167