Back to home page

EIC code displayed by LXR

 
 

    


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!