Warning, /jana2/src/examples/InteractiveStreamingExample/README.md is written in an unsupported language. File is not indexed.
0001
0002 ## Streaming Detector Plugin
0003
0004 ### Overview
0005
0006 The stream detector (streamDet) plugin facilitates both the online and offline analysis of streaming data. Simulated
0007 data is generated by the `streamDetSource.py` script which produces a flat text (data) file. The format of
0008 the simulated data is available in a variety of formats and is discussed in further detail below.
0009
0010 Moreover, the `streamDet` JANA2 plugin facilitates the decoding of SAMPA streaming data by either reading from the
0011 file directly or by subscribing to ZMQ messages published in the INDRA messaging format which is discussed
0012 in further detail below. The plugin decodes SAMPA streaming data and produces a ROOT file `outFile.root` which
0013 contains leaves with the corresponding ADC and TDC data. In addition, the plugin can publish INDRA
0014 messages via. ZMQ so that the data can be monitored interactively and in real time via a Jupyter Notebook whose
0015 infrastructure is contained in the `jupyter` sub directory. Further details of the underlying infrastructure
0016 is discussed below.
0017
0018 ### Simulating Streaming Data via streamDetSource.py
0019
0020 Below are the parameters which govern the simulated streaming data :
0021
0022 | **Parameter (short)** | **Parameter (long)** | **Description** | **Suggested Value** | **Required?** |
0023 | --------------------- | -------------------- | -------------------------------------------------------------- | ------------------- | ------------- |
0024 | -sr | --sampleRate | Sampling rate in MHz | 5 | true |
0025 | -nc | --numChans | Number of channels to simulate ADC data for | 80 | true |
0026 | -ne | --numEvents | Number of events to simulate for each channel | 100 | true |
0027 | -spec | --spectra | ADC spectra to simulate (gumbel or sampa) | sampa | true |
0028 | -m | --mode | SAMPA DAQ mode to simulate (das or dsp) | das | false |
0029
0030 #### Streaming Gumbel ADC & TDC Data
0031
0032 In this mode, data are assumed to be comprised of 1024 ADC and TDC samples per readout window. Each readout window
0033 has been defined as an "event". The simulated TDC data is a continuous stream of sampled TDC pulses whose frequency
0034 depends on the sampling rate. The ADC data is a sampled analog signal whose shape is governed by a Gumbel distribution
0035 whose parameters are randomized from pulse to pulse. Each sample of the ADC data is directly correlated with the
0036 continuous stream of TDC pulses ergo, there exists a one to one mapping between the sampled data. The streamDet plugin
0037 no longer supports the decoding of this particular streaming data file format. It is merely a pedagogical tool for
0038 those who are interested.
0039
0040 Example usage for producing a "stream" of ADC and TDC data according to a Gumbel distribution is as follows:
0041
0042 ```
0043 python streamDetSource.py -sr 10 -nc 100 -ne 100 -spec gumbel
0044 ```
0045
0046 #### Streaming SAMPA ADC Data in DAS Mode
0047
0048 In direct adc serialization (DAS) mode the streaming SAMPA ADC data emanate from a 2.5 SAMPA chips sampling 80
0049 streams of ADC data at 5 MhZ (200 ns/sample). Each readout window is comprised of 1024 ADC samples
0050 (204.8 $`\mu s`$/readout window). An "event is defined to be a single readout window. The simulated ADC
0051 data is a sampled analog signal whose distribution is governed by a fourth order semi-Gaussian which is
0052 inherent to the charge shaping amplifier present in the SAMPA chip signal processing architecture.
0053 The pulse amplitude of the distribution is randomized for each pulse so that the full dynamic range
0054 of the ADC (10-bit, 1024 channels) is populated.
0055
0056 Moreover, the time in which the signal occurs in the readout window is randomized such that it can occur at
0057 any location in time in side the 204.8 $`\mu s`$ window however, it is prohibited to occur within the first
0058 25% and last 75% of the readout window. It is required to note that in DAS mode the SAMPA chips can only
0059 sample the data at 5 MHz. Higher sample rates are available in the digital signal processing (DSP) mode which
0060 is discussed in more detail below.
0061
0062 Example usage for producing a "stream" of SAMPA ADC in DAS mode is as follows:
0063
0064 ```
0065 python streamDetSource.py -sr 5 -nc 80 -ne 100 -spec sampa -m das
0066 ```
0067
0068 Upon execution the data file `run-5-mhz-80-chan-100-ev.dat` will have been created in the present working directory.
0069 Each column of the data file corresponds to a single ADC channel and each row corresponds to the ADC sample value
0070 for each of the 80 channels that were readout.
0071
0072 #### Streaming SAMPA ADC Data in DSP Mode
0073
0074 Coming soon...stay tuned!
0075
0076 ### Compiling
0077
0078 A few software prerequisites are required in order to successfully build and execute the stream detector plugin.
0079 They are the following :
0080
0081 1. The minimum required version of cmake is 3.13
0082 1. ROOT must be installed and the appropriate environment configured. Consider one of the two options listed below:
0083 - `source /path/to/root/installation/bin/thisroot.(c)sh`
0084 - Manually configure the `ROOTSYS, PATH,` and `LD_LIBRARY_PATH` environment variables
0085 1. The ZeroMQ library must be present
0086 - Use your package manager to install the libraries system wide e.g. `yum install zeromq-devel`
0087
0088 In order to compile JANA2 in conjunction with the stream detector plugin, one must execute the following commands:
0089
0090 ```
0091 git clone git@gitlab.com:indra-astra/JANA2.git
0092 cd JANA2
0093 git checkout -b my-branch-name
0094 cmake . .
0095 make -j4
0096 ```
0097
0098 ### Configuring the JANA2 Environment
0099
0100 A few environment variables are required for facilitating the JANA2 framework. In bash one should execute the
0101 following commands (or make an alias, or add to .bashrc) :
0102
0103 ```
0104 export JANA_HOME=/path/to/JANA2/
0105 export JANA_PLUGIN_PATH=$JANA_HOME
0106 export PATH=$PATH:$JANA_HOME
0107 ```
0108
0109 ### Plugin Components
0110
0111 The various classes that comprise the stream detector plugin are described in the following subsections
0112
0113 #### ADCSample
0114
0115 The class `ADCSample` defines the components, and their associated data types, of ADC sample data as a JObject.
0116 The components of the ADC data as a JObject are defined in the following table:
0117
0118 | **Object Name** | **Data Type** | **Description** |
0119 | --------------- | ------------- | ---------------------------------------------------------------------------- |
0120 | source_id | `uint32_t` | 32-bit identifier governed by the INDRA message format |
0121 | channel_id | `uint16_t` | Channel number corresponding to the ADC sample |
0122 | sample_id | `uint16_t` | Sample number corresponding to the ADC sample (analogous to a TDC sample) |
0123 | adc_value | `uint16_t` | Value of the ADC sample |
0124
0125 #### ADCSampleFactory
0126
0127 The class `ADCSampleFactory` processes a `JEvent` object and constructs a `ADCSample` object. In this instance
0128 the "event" is a `DASEventMessage` object (defined in `INDRAMESSAGE.h`) which is discussed in detail in a later
0129 section. In short, the `DASEventMessage` object is a ZMQ message which JANA2 subscribed too. A single message
0130 contains 1024 ADC sample values (a single readout window) for 80 channels along with the member variables
0131 available via the `DASEventMessage` class arsing from the INDRA messaging protocol. The payload of the message
0132 is then decoded so that the `ADCSample` object is constructed. If desired one can configure the parameters
0133 `streamDet:rawhit_ms` and `streamDet:rawhit_spread` in order to simulate a bottle neck in the processing method.
0134 The default values are 200 ms (5 Hz) $`\pm`$ 0.25 $`\sigma`$.
0135
0136 #### DecodeDASSource
0137
0138 The class `DecodeDASSource` processes a `JEvent` object and constructs a `ADCSample` object. In this instance
0139 the "event" is a vector of `ADCSample` objects which were populated from reading a data file from disk as opposed
0140 to subscribing to ZMQ messages conforming to the INDRA messaging protocol as was done in the `ADCSampleFactory`
0141 class. More specifically, this class opens the data file specified by the parameter `streamDet:data_file` and
0142 parses it. It assumes that the file conforms to the SAMPA DAS ADC data format in that each event is comprised
0143 of 1024 samples for 80 channels. Once the end of the file has been reached, the file is closed and JANA will
0144 terminate upon processing of all available events.
0145
0146 #### INDRAMessage
0147
0148 The INDRA message protocol is governed by that of the
0149 [INDRA_Stream_Test](https://github.com/JeffersonLab/INDRA_Stream_Test) libraries. Each data record begins with a
0150 header followed by the data payload. The header format is as follows :
0151
0152 | **Type** | **Name** | **Comment** |
0153 | ------------ | ----------------- | ----------------------------------------------------------------------------- |
0154 | **uint32_t** | source_id | 32-bit identifier for this data source |
0155 | **uint32_t** | magic | 32-bit marker with the hexadecimal value 0xC0DA2019 |
0156 | **uint32_t** | total_length | The length of the entire record, including the header, in units of bytes |
0157 | **uint32_t** | payload_length | The length of the data that follows the header if the payload is uncompressed |
0158 | **uint32_t** | compressed_length | The length of the data that follows the header if the payload is compressed |
0159 | **uint32_t** | format_version | An integer value that identifies the header format |
0160 | **uint32_t** | flags | 32-bit flag which provides a variety of information e.g. end of file reached |
0161 | **uint64_t** | record_counter | A count of the number of records sent since the connection opened |
0162 | **uint64_t** | timestamp_sec | 64-bit number of seconds in the 128-bit timestamp |
0163 | **uint64_t** | timestamp_nsec | 64-bit number of nanoseconds in the 128-bit timestamp |
0164
0165 The payload for each ZMQ message has been configured to contain 1024 samples of SAMPA DAS ADC data for 80
0166 channels. This corresponds to a single readout window for a 2.5 SAMPA chips whose data were transmitted via a
0167 single GBTX0 chip on an ALICE FEC.
0168
0169 The class `DASEventMessage` provides the various methods so that one can interact with the INDRA messages
0170 received via ZMQ. The `INDRAMessage` struct defined here is identical to the `stream_buffer` struct defined in
0171 `INDRA_Stream_Test/stream_tools.h`. The constructors define the invariants of the message structure e.g. number
0172 of samples in the message, buffer size, and channel count to name a few. The destructor of course destroys the
0173 message once it has been processed.
0174
0175 There are three distinct blocks of code which define the behavior of the class. The first is used by
0176 `JStreamingEventSource` in order to figure out how to emit the message as an `JEvent`. The second is a
0177 series of setter definitions that are NOT required by `JStreamingEventSource` however, they are useful
0178 for writing producers which can then be utilized for online monitoring. The third section is utilized
0179 by user-defined `JFactories` and `JEventProcessors` to access whatever data was sent. This provides a
0180 "view" into the message buffer which the user can define however they like.
0181
0182 #### JFactoryGenerator
0183
0184 The class `JFactoryGenerator` simply generates the various factories specific to the plugin. Nothing special here.
0185
0186 #### MonitoringProcessor
0187
0188 The `MonitoringProcessor` is a `JAppliction` that creates a ZMQ sink that publishes a `DASEventMessage` object to
0189 the socket specified by the parameter `streamDet:pub_socket`. For each ZMQ message that the stream detector plugin
0190 subscribes too, the `MonitoringProcessor` publishes it so that it can be utilized in the online monitoring of data.
0191
0192 #### RootProcessor
0193
0194 The `RootProcessor` is a `JApplication` that defines the structure and components of the output ROOT file. Any
0195 branches, leaves, and/or histograms are defined and filled within this class.
0196
0197 #### streamDet
0198
0199 The `streamDet` is the `JApplication` that acts as the steering script for the stream detector plugin. It is here that
0200 the plugin is initialized within the JANA2 framework. Both the plugin specific and command line parameters are
0201 handled here. Furthermore, the mode that the plugin is to be run in is handled here based on the user input, i.e.
0202 weather the plugin be subscribing to ZMQ messages or simply reading the data from a flat text file. Each `JApplication`
0203 that the user wishes to include in the analysis is also done here e.g. the `RootProccessor` application or the
0204 `MonitoringProcessor` application.
0205
0206 #### ZMQTransport
0207
0208 The `ZMQTransport` class handles the subscribing and publishing of ZMQ messages within the JANA2 framework.
0209
0210 ### Plugin Parameters
0211
0212 Below the various parameters of the `streamDet` plugin are displayed as well as their default values.
0213
0214 | **Parameter** | **Description** | **Default Value** |
0215 | ----------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------- |
0216 | streamDet:use_zmq | Subscribe to ZMQ messages for data stream? | true |
0217 | streamDet:data_file | Name of data file to read if not subscribing to zmq messages | run-5-mhz-80-chan-100-ev.dat |
0218 | streamDet:use_dummy_publisher | Reads from streamDet:data_file file and publishes ZMQ messages for JANA to subscribe to | false |
0219 | streamDet:nchannels | Number of channels in data stream | 80 |
0220 | streamDet:nsamples | Number of samples in data stream | 1024 |
0221 | streamDet:msg_print_freq | Frequency at which information should be printed to screen during analysis | 10 |
0222 | streamDet:sub_socket | ZMQ subscribing socket | tcp://127.0.0.1:5556 |
0223 | streamDet:pub_socket | ZMQ publishing socket | tcp://127.0.0.1:5557 |
0224 | streamDet:rawhit_ms | Simulate delay in processing time (ms) | 200 |
0225 | streamDet:rawhit_spread | Spread in simulated delay in processing time ($`\sigma`$) | 0.25 |
0226
0227 ### Executing the Stream Detector Plugin
0228
0229 The stream detector can operate in two functional modes. One mode utilizes a dummy publisher to read a flat text from
0230 disk and then creates a ROOT file and publishes INDRA messages via. ZMQ. The following command will read the data
0231 file `run-5-mhz-80-chan-100-ev.dat`, produce a ROOT file `outFile.root`, and publish the data as a INDRA ZMQ
0232 message on the socket `tcp://127.0.0.1:5557`:
0233
0234 ```
0235 jana -Pplugins=streamDet -PstreamDet:use_dummy_publisher=1 -PstreamDet:pub_socket=tcp://127.0.0.1:5557
0236 ```
0237
0238 In the alternate mode JANA2 subscribes to INDRA messages via. ZMQ and creates a ROOT file `outFile.root` as well as
0239 publishes those messages via ZMQ for online monitoring purposes. The following command will receive INDRA ZMQ
0240 messages on socket `tcp://127.0.0.1:5556` and publish them on socket `tcp://127.0.0.1:5557`.
0241
0242 ```
0243 jana -Pplugins=streamDet -PstreamDet:use_dummy_publisher=0 -PstreamDet:sub_socket=tcp://127.0.0.1:5556 -PstreamDet:pub_socket=tcp://127.0.0.1:5557
0244 ```
0245
0246 ### Publishing ZMQ INDRA Messages via INDRA_Stream_Test
0247
0248 To obtain the `INDRA_Stream_Test` libraries one needs to first clone the
0249 [INDRA_Stream_Test](https://github.com/JeffersonLab/INDRA_Stream_Test) repository on GitHub. A few software
0250 prerequisites are required in order to successfully build and execute the `INDRA_Stream_Test` libraries. They
0251 are the following :
0252
0253 1. The minimum required version of cmake is 3.13
0254 1. The ZeroMQ library must be present
0255 - Use your package manager to install the libraries system wide e.g. `yum install zeromq-devel`
0256 and `yum install czmq-devel`
0257
0258 In order to build the libraries one should execute the following commands :
0259
0260 ```
0261 git clone https://github.com/JeffersonLab/INDRA_Stream_Test
0262 cd INDRA_Stream_Test
0263 git checkout -b my-branch-name
0264 cmake . .
0265 make -j4
0266 ```
0267
0268 In order to utilize the `INDRA_Stream_Test` libraries to stream SAMPA data to JANA2 one must first establish the stream
0269 router that will receive data from the stream source over TCP and publish it over ZMQ to the JANA2 subscriber according
0270 to the INDRA messaging protocol outlined above. This is done with the following command :
0271
0272 ```
0273 ./stream_router -z
0274 ```
0275
0276 The router will receive a TCP stream input on port `5555` and publish the stream according to the INDRA messaging
0277 protocol via ZMQ (as dictated by the `-z` parameter) on URL `tcp://127.0.0.1:5556` by default. The ports can be
0278 configured via command line parameters as documented in the `INDRA_Stream_Test` README.
0279
0280 Once the router is successfully configured, one is required to initiate the stream source. In the instance that one
0281 would like to publish the simulated SAMPA DAS ADC data file `run-5-mhz-80-chan-100-ev.dat` discussed above, one would
0282 need to execute the following command :
0283
0284 ```
0285 ./stream_test_source -j -f run-5-mhz-80-chan-100-ev.dat
0286 ```
0287
0288 Here the `-j` parameter configures the stream source library to operate in a mode hyper-specific to the JANA2
0289 stream detector plugin. The `-f` parameter reads the source file `run-5-mhz-80-chan-100-ev.dat` and streams it over
0290 TCP on port `5555` which is in turn processed via the stream router discussed above.
0291
0292 ### Processing the INDRA Messaging Stream via JANA2
0293
0294 Once the stream router has been configured, one will want to execute JANA2 in a mode that is able to receive INDRA
0295 messages via ZMQ from the stream source via the stream router. To do this one should execute the following command :
0296
0297 ```
0298 jana -Pplugins=streamDet
0299 ```
0300
0301 This will fire up the stream detector JANA2 plugin in the default mode. In the default mode, JANA2 will subscribe to ZMQ
0302 messages on port `5556`, publish the INDRA messages via ZMQ on port `5557` for online monitoring, and write the contents
0303 of the data stream to the ROOT file `outFile.root`.
0304
0305 ### Online Monitoring via Jupyter Notebook
0306
0307 In order to monitor the streaming SAMPA ADC data one will need to first create a jupyter notebook session via
0308 entering the follow command :
0309
0310 ```
0311 jupyter notebook --ip=127.0.0.2 --port=5601
0312 ```
0313
0314 A tab should have opened within your browser of choice. Once there, navigate to the
0315 `$JANA_HOME/src/plugins/streamDet/jupyter` directory and open the `streamDet_Monitoring.ipynb` notebook. In the
0316 first cell one needs to construct the widgets via `Shift+Enter`. If successful, tabs containing the UI for port,
0317 threshold, and plot selection should be visible. By default the monitoring system will receive ZMQ messages published
0318 via the JANA2 stream detector plugin on port `5557` with a threshold set to 100 ADC channels. There are two plots
0319 available for the user to view. That is an ADC occupancy plot (loaded by default) and waveform plots which allow one
0320 to see the individual waveforms for ADC pulses that exceed the programmed threshold.
0321
0322 To begin subscribing to INDRA messages published by JANA2 via ZMQ, one simply needs to execute the second cell in the
0323 same manner that was done for cell 1 (after making their plot selection of course). With the router running, JANA2
0324 subscribing, and the monitoring system subscribing, one can execute the stream source as discussed above. If
0325 successful, the plot type you selected withing the jupyter notebook should be created and self updating.
0326
0327 Happy streaming!