otsdaq  v1_01_04
 All Classes Namespaces Functions
JSONDispatcher_module.cc
1 // Class: UDPDump
3 // Module Type: analyzer
4 // File: UDPDump_module.cc
5 // Description: Prints out information about each event.
7 
8 #include "art/Framework/Core/EDAnalyzer.h"
9 #include "art/Framework/Core/ModuleMacros.h"
10 #include "art/Framework/Principal/Run.h"
11 #include "art/Framework/Principal/Event.h"
12 #include "art/Framework/Principal/Handle.h"
13 #include "canvas/Utilities/Exception.h"
14 
15 #include "artdaq-ots/Overlays/UDPFragment.hh"
16 #include "artdaq-core/Data/Fragment.hh"
17 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
18 
19 
20 #include <boost/asio.hpp>
21 using boost::asio::ip::udp;
22 
23 #include <algorithm>
24 #include <cassert>
25 #include <cmath>
26 #include <fstream>
27 #include <iomanip>
28 #include <vector>
29 #include <iostream>
30 #include <arpa/inet.h>
31 
32 
33 namespace ots {
34 
35 class JSONDispatcher : public art::EDAnalyzer {
36 public:
37  explicit JSONDispatcher(fhicl::ParameterSet const & pset);
38  virtual ~JSONDispatcher();
39 
40  virtual void analyze(art::Event const & evt) override;
41  virtual void beginRun(art::Run const & run) override;
42 
43 private:
44  int prescale_;
45  std::string raw_data_label_;
46  std::string frag_type_;
47  boost::asio::io_service io_service_;
48  udp::socket socket_;
49  udp::endpoint remote_endpoint_;
50 };
51 
52 }
53 
54 ots::JSONDispatcher::JSONDispatcher(fhicl::ParameterSet const & pset)
55 : art::EDAnalyzer(pset)
56 , prescale_(pset.get<int>("prescale",1))
57 , raw_data_label_(pset.get<std::string>("raw_data_label", "daq"))
58 , frag_type_(pset.get<std::string>("frag_type", "UDP"))
59 , io_service_()
60 , socket_(io_service_, udp::v4())
61 {
62  std::cout << __COUT_HDR_FL__ << "JSONDispatcher Constructor Start" << std::endl;
63  int port = pset.get<int>("port",35555);
64  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher port is " << std::to_string(port) << std::endl;
65  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher setting reuse_address option" << std::endl;
66  boost::system::error_code ec;
67  socket_.set_option(boost::asio::socket_base::reuse_address(true),ec);
68  if(ec) {
69  mf::LogError("JSONDispatcher") << "An error occurred setting reuse_address: " << ec.message() << std::endl;
70  }
71  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher setting broadcast option" << std::endl;
72  socket_.set_option(boost::asio::socket_base::broadcast(true),ec);
73  if(ec) {
74  mf::LogError("JSONDispatcher") << "An error occurred setting broadcast: " << ec.message() << std::endl;
75  }
76 
77  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher gettting UDP endpoint" << std::endl;
78  remote_endpoint_ = udp::endpoint(boost::asio::ip::address_v4::broadcast(), port);
79  std::cout << __COUT_HDR_FL__ << "JSONDispatcher Constructor End" << std::endl;
80 }
81 
82 ots::JSONDispatcher::~JSONDispatcher()
83 {
84 }
85 
86 void ots::JSONDispatcher::beginRun(art::Run const & run)
87 {
88  std::cout << __COUT_HDR_FL__ << "JSONDispatcher beginning run " << run.run() << std::endl;
89 }
90 
91 
92 void ots::JSONDispatcher::analyze(art::Event const & evt)
93 {
94  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher getting event number to check prescale" << std::endl;
95  art::EventNumber_t eventNumber = evt.event();
96  mf::LogInfo("JSONDispatcher") << "Received event with sequence ID " << eventNumber;
97  if((int)eventNumber % prescale_ == 0) {
98  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher dispatching event" << std::endl;
99  std::ostringstream outputJSON;
100  outputJSON << "{\"run\":" << std::to_string(evt.run()) << ",\"subrun\":"<<std::to_string(evt.subRun()) << ",\"event\":"<<std::to_string(eventNumber);
101 
102  // ***********************
103  // *** UDP Fragments ***
104  // ***********************
105 
106  // look for raw UDP data
107 
108  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher getting handle on Fragments" << std::endl;
109  art::Handle<artdaq::Fragments> raw;
110  evt.getByLabel(raw_data_label_, frag_type_, raw);
111  outputJSON <<",\"fragments\":[";
112 
113  if (raw.isValid())
114  {
115  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher dumping UDPFragments" << std::endl;
116  for (size_t idx = 0; idx < raw->size(); ++idx)
117  {
118  if(idx > 0) { outputJSON << ","; }
119  outputJSON << "{";
120  const auto& frag((*raw)[idx]);
121 
122  ots::UDPFragment bb(frag);
123  int type = 0;
124 
125  if (frag.hasMetadata())
126  {
127  outputJSON << "\"metadata\":{";
128  //std::cout << __COUT_HDR_FL__ << "Fragment metadata: " << std::endl;
129  auto md = frag.metadata<ots::UDPFragment::Metadata>();
130  outputJSON << "\"port\":"<<std::to_string(md->port)<<",";
131  char buf[sizeof(in_addr)];
132  struct sockaddr_in addr;
133  addr.sin_addr.s_addr = md->address;
134  inet_ntop(AF_INET, &(addr.sin_addr), buf, INET_ADDRSTRLEN);
135  outputJSON << "\"address\":\""<<std::string(buf) << "\"";
136  outputJSON << "},";
137  }
138  outputJSON << "\"header\":{";
139  outputJSON << "\"event_size\":"<<std::to_string(bb.hdr_event_size())<<",";
140  outputJSON << "\"data_type\":"<<std::to_string(bb.hdr_data_type());
141  type = bb.hdr_data_type();
142  outputJSON << "},";
143  outputJSON << "\"data\":";
144  if(type == 0 || type > 2)
145  {
146  outputJSON << "[";
147  auto it = bb.dataBegin();
148  outputJSON << std::hex << "\"0x" << (int)*it << "\"" << std::dec;
149  ++it;
150 
151  for(; it !=bb.dataEnd(); ++it)
152  {
153  outputJSON << "," << std::hex << "\"0x" << (int)*it << "\"" << std::dec;
154  }
155  outputJSON << "]";
156  }
157  else
158  {
159  if(type == 2) { outputJSON << "\""; }
160  std::string output = std::string((const char *)bb.dataBegin());
161  if(type == 2)
162  {
163  std::string find = "\"";
164  std::string replace = "\\\"";
165  for(std::string::size_type i = 0; (i = output.find(find, i)) != std::string::npos;)
166  {
167  output.replace(i, find.length(), replace);
168  i += replace.length();
169  }
170  }
171  outputJSON << output;
172  if(type == 2) { outputJSON << "\""; }
173  }
174  outputJSON << "}";
175  }
176  }
177  else
178  {
179  return;
180  }
181 
182  outputJSON << "]}";
183  //std::cout << __COUT_HDR_FL__ <<"JSONDispatcher filling JSON into buffer" << std::endl;
184  std::string s = outputJSON.str() + "\0";
185  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher output: " << s << std::endl;
186  auto message = boost::asio::buffer(s);
187  //std::cout << __COUT_HDR_FL__ <<"JSONDispatcher broadcasting JSON data" << std::endl;
188  socket_.send_to(message, remote_endpoint_);
189  //std::cout << __COUT_HDR_FL__ << "JSONDispatcher done with event" << std::endl;
190 
191  }
192 }
193 
194 DEFINE_ART_MODULE(ots::JSONDispatcher)