$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 00002 // Class: UDPDump 00003 // Module Type: analyzer 00004 // File: UDPDump_module.cc 00005 // Description: Prints out information about each event. 00007 00008 #include "art/Framework/Core/EDAnalyzer.h" 00009 #include "art/Framework/Core/ModuleMacros.h" 00010 #include "art/Framework/Principal/Event.h" 00011 #include "art/Framework/Principal/Handle.h" 00012 #include "art/Framework/Principal/Run.h" 00013 #include "canvas/Utilities/Exception.h" 00014 00015 #include "artdaq-core/Data/Fragment.hh" 00016 #include "artdaq-ots/Overlays/UDPFragment.hh" 00017 #include "otsdaq-core/Macros/CoutMacros.h" 00018 00019 #include <boost/asio.hpp> 00020 using boost::asio::ip::udp; 00021 00022 #include <arpa/inet.h> 00023 #include <algorithm> 00024 #include <cassert> 00025 #include <cmath> 00026 #include <fstream> 00027 #include <iomanip> 00028 #include <iostream> 00029 #include <vector> 00030 00031 namespace ots 00032 { 00033 class JSONDispatcher : public art::EDAnalyzer 00034 { 00035 public: 00036 explicit JSONDispatcher(fhicl::ParameterSet const& pset); 00037 virtual ~JSONDispatcher(); 00038 00039 virtual void analyze(art::Event const& evt) override; 00040 virtual void beginRun(art::Run const& run) override; 00041 00042 private: 00043 int prescale_; 00044 std::string raw_data_label_; 00045 std::string frag_type_; 00046 boost::asio::io_service io_service_; 00047 udp::socket socket_; 00048 udp::endpoint remote_endpoint_; 00049 }; 00050 00051 } // namespace ots 00052 00053 ots::JSONDispatcher::JSONDispatcher(fhicl::ParameterSet const& pset) 00054 : art::EDAnalyzer(pset) 00055 , prescale_(pset.get<int>("prescale", 1)) 00056 , raw_data_label_(pset.get<std::string>("raw_data_label", "daq")) 00057 , frag_type_(pset.get<std::string>("frag_type", "UDP")) 00058 , io_service_() 00059 , socket_(io_service_, udp::v4()) 00060 { 00061 std::cout << __COUT_HDR_FL__ << "JSONDispatcher Constructor Start" << std::endl; 00062 int port = pset.get<int>("port", 35555); 00063 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher port is " << std::to_string(port) 00064 // << std::endl; std::cout << __COUT_HDR_FL__ << "JSONDispatcher setting 00065 // reuse_address option" << std::endl; 00066 boost::system::error_code ec; 00067 socket_.set_option(boost::asio::socket_base::reuse_address(true), ec); 00068 if(ec) 00069 { 00070 TLOG(TLVL_ERROR, "JSONDispatcher") 00071 << "An error occurred setting reuse_address: " << ec.message() << std::endl; 00072 } 00073 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher setting broadcast option" << 00074 // std::endl; 00075 socket_.set_option(boost::asio::socket_base::broadcast(true), ec); 00076 if(ec) 00077 { 00078 TLOG(TLVL_ERROR, "JSONDispatcher") 00079 << "An error occurred setting broadcast: " << ec.message() << std::endl; 00080 } 00081 00082 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher gettting UDP endpoint" << 00083 // std::endl; 00084 remote_endpoint_ = udp::endpoint(boost::asio::ip::address_v4::broadcast(), port); 00085 std::cout << __COUT_HDR_FL__ << "JSONDispatcher Constructor End" << std::endl; 00086 } 00087 00088 ots::JSONDispatcher::~JSONDispatcher() {} 00089 00090 void ots::JSONDispatcher::beginRun(art::Run const& run) 00091 { 00092 std::cout << __COUT_HDR_FL__ << "JSONDispatcher beginning run " << run.run() 00093 << std::endl; 00094 } 00095 00096 void ots::JSONDispatcher::analyze(art::Event const& evt) 00097 { 00098 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher getting event number to check 00099 // prescale" << std::endl; 00100 art::EventNumber_t eventNumber = evt.event(); 00101 TLOG(TLVL_INFO, "JSONDispatcher") 00102 << "Received event with sequence ID " << eventNumber; 00103 if((int)eventNumber % prescale_ == 0) 00104 { 00105 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher dispatching event" << 00106 // std::endl; 00107 std::ostringstream outputJSON; 00108 outputJSON << "{\"run\":" << std::to_string(evt.run()) 00109 << ",\"subrun\":" << std::to_string(evt.subRun()) 00110 << ",\"event\":" << std::to_string(eventNumber); 00111 00112 // *********************** 00113 // *** UDP Fragments *** 00114 // *********************** 00115 00116 // look for raw UDP data 00117 00118 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher getting handle on Fragments" << 00119 // std::endl; 00120 art::Handle<artdaq::Fragments> raw; 00121 evt.getByLabel(raw_data_label_, frag_type_, raw); 00122 outputJSON << ",\"fragments\":["; 00123 00124 if(raw.isValid()) 00125 { 00126 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher dumping UDPFragments" << 00127 // std::endl; 00128 for(size_t idx = 0; idx < raw->size(); ++idx) 00129 { 00130 if(idx > 0) 00131 { 00132 outputJSON << ","; 00133 } 00134 outputJSON << "{"; 00135 const auto& frag((*raw)[idx]); 00136 00137 ots::UDPFragment bb(frag); 00138 int type = 0; 00139 00140 if(frag.hasMetadata()) 00141 { 00142 outputJSON << "\"metadata\":{"; 00143 // std::cout << __COUT_HDR_FL__ << "Fragment metadata: " << std::endl; 00144 auto md = frag.metadata<ots::UDPFragment::Metadata>(); 00145 outputJSON << "\"port\":" << std::to_string(md->port) << ","; 00146 char buf[sizeof(in_addr)]; 00147 struct sockaddr_in addr; 00148 addr.sin_addr.s_addr = md->address; 00149 inet_ntop(AF_INET, &(addr.sin_addr), buf, INET_ADDRSTRLEN); 00150 outputJSON << "\"address\":\"" << std::string(buf) << "\""; 00151 outputJSON << "},"; 00152 } 00153 outputJSON << "\"header\":{"; 00154 outputJSON << "\"event_size\":" << std::to_string(bb.hdr_event_size()) 00155 << ","; 00156 outputJSON << "\"data_type\":" << std::to_string(bb.hdr_data_type()); 00157 type = bb.hdr_data_type(); 00158 outputJSON << "},"; 00159 outputJSON << "\"data\":"; 00160 if(type == 0 || type > 2) 00161 { 00162 outputJSON << "["; 00163 auto it = bb.dataBegin(); 00164 outputJSON << std::hex << "\"0x" << (int)*it << "\"" << std::dec; 00165 ++it; 00166 00167 for(; it != bb.dataEnd(); ++it) 00168 { 00169 outputJSON << "," << std::hex << "\"0x" << (int)*it << "\"" 00170 << std::dec; 00171 } 00172 outputJSON << "]"; 00173 } 00174 else 00175 { 00176 if(type == 2) 00177 { 00178 outputJSON << "\""; 00179 } 00180 std::string output = std::string((const char*)bb.dataBegin()); 00181 if(type == 2) 00182 { 00183 std::string find = "\""; 00184 std::string replace = "\\\""; 00185 for(std::string::size_type i = 0; 00186 (i = output.find(find, i)) != std::string::npos;) 00187 { 00188 output.replace(i, find.length(), replace); 00189 i += replace.length(); 00190 } 00191 } 00192 outputJSON << output; 00193 if(type == 2) 00194 { 00195 outputJSON << "\""; 00196 } 00197 } 00198 outputJSON << "}"; 00199 } 00200 } 00201 else 00202 { 00203 return; 00204 } 00205 00206 outputJSON << "]}"; 00207 // std::cout << __COUT_HDR_FL__ <<"JSONDispatcher filling JSON into buffer" << 00208 // std::endl; 00209 std::string s = outputJSON.str() + "\0"; 00210 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher output: " << s << std::endl; 00211 auto message = boost::asio::buffer(s); 00212 // std::cout << __COUT_HDR_FL__ <<"JSONDispatcher broadcasting JSON data" << 00213 // std::endl; 00214 socket_.send_to(message, remote_endpoint_); 00215 // std::cout << __COUT_HDR_FL__ << "JSONDispatcher done with event" << std::endl; 00216 } 00217 } 00218 00219 DEFINE_ART_MODULE(ots::JSONDispatcher)