Belle II Software  release-05-02-19
ROISenderModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2011 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Giulia Casarosa, Eugenio Paoloni, Bjoern Spruck *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <tracking/modules/pxdDataReduction/ROISenderModule.h>
12 #include <sys/stat.h>
13 #include <chrono>
14 
15 using namespace std;
16 using namespace Belle2;
17 
18 //-----------------------------------------------------------------
19 // Register the Module
20 //-----------------------------------------------------------------
21 
22 REG_MODULE(ROISender)
23 
24 //-----------------------------------------------------------------
25 // Implementation
26 //-----------------------------------------------------------------
27 
29  Module(), m_messageQueueNameCstring(NULL)
30 {
31  //Set module properties
32  setDescription("Send the ROI payload to the external ring buffer");
33 
34  addParam("MessageQueueName", m_messageQueueName, "name of the output message queue", std::string("/roi"));
35  addParam("ROIpayloadName", m_ROIpayloadName, "name of the payload of ROIs", std::string(""));
36  addParam("MessageQueueDepth", m_messageQueueDepth, "depth of the output message queue", 10);
37  addParam("MessageSize", m_messageQueueMsgSize, "max size of themessage", 8192);
38 
39  B2INFO("ROI Sender created");
40 }
41 
42 
43 void
44 ROISenderModule::initialize()
45 {
46  // Required input
47  m_eventMetaData.isRequired();
48  m_roiPayload.isRequired(m_ROIpayloadName);
49 
50  m_messageQueueNameCstring = m_messageQueueName.c_str();
51 
52  bool slashFree = (NULL == strchr(m_messageQueueNameCstring + 1 , '/'));
53 
54  if (! slashFree || m_messageQueueNameCstring[0] != '/')
55  B2FATAL(__FILE__ << ":" << __LINE__ <<
56  m_messageQueueName << " invalid. cfr: man mq_overview ");
57 
58  m_histo.resize(101, 0); // 0-99, 100 is used as overflow bin
59 
60  // unlinkMessageQueue("on initialize");
61  openMessageQueue("on initialize");
62 
63 }
64 
65 
66 void
67 ROISenderModule::event()
68 {
69 
70  int length = m_roiPayload->getPacketLengthByte();
71  const char* data = (const char*) m_roiPayload->getRootdata();
72 
73  mqd_t ret;
74 
75  if (length <= m_messageQueueMsgSize) {
76  ret = mq_send(m_messageQueue, data, length, 0 /* priority */);
77 
78  if (ret == (mqd_t) - 1) {
79  B2FATAL(std::string(__FILE__) << ":" << __LINE__ <<
80  ": error: " <<
81  strerror(errno) <<
82  " on mq_send");
83  }
84  } else {
85  B2FATAL(std::string(__FILE__) << ":" << __LINE__ <<
86  "ROI payload too long." << endl <<
87  "Payload length = " << length << endl <<
88  "Message max length = " << m_messageQueueMsgSize << endl <<
89  "We stop here, as this will result in event mismatch on EB! Please increase mqueue message length on HLT and/or check size limit in ROIPayload Assembler"
90  << endl);
91  }
92 
93  // Calculate the time difference between now and the trigger time
94  // This tells you how much delay we have summed up (it is NOT the processing time!)
96  unsigned long long int meta_time = m_eventMetaData->getTime();
97 
98  using namespace std::chrono;
99  nanoseconds ns = duration_cast< nanoseconds >(system_clock::now().time_since_epoch());
100  Float_t deltaT = (std::chrono::duration_cast<seconds> (ns - (nanoseconds)meta_time)).count();
101  if (deltaT < 0) {
102  m_histo[0]++;// just in case the clocks are slightly out of sync
103  } else if (deltaT < 100) {
104  m_histo[int(deltaT)]++;
105  } else {
106  m_histo[100]++;// overflow bin
107  }
108  if (deltaT > 60) {
109  B2ERROR("Event took too long on HLT, PXD data for Event might be lost!" << LogVar("deltaT in s", deltaT));
110  } else if (deltaT > 30) {
111  B2WARNING("Event took too long on HLT, PXD data for Event might be lost!" << LogVar("deltaT in s", deltaT));
112  }
113 }
114 
115 
116 
117 
118 void
119 ROISenderModule::terminate()
120 {
121  closeMessageQueue("on terminate");
122  // unlinkMessageQueue("on terminate");
123  string str = "HLT Delay time distribution: ( ";
124  for (auto& a : m_histo) str += to_string(a) + ";";
125  str += " )";
126  B2RESULT(str);
127 }
128 
129 void
130 ROISenderModule::openMessageQueue(const char* log_string)
131 {
132  struct mq_attr attr;
133  attr.mq_flags = 0;
134  attr.mq_maxmsg = m_messageQueueDepth;
135  attr.mq_msgsize = m_messageQueueMsgSize; // bytes
136 
137  int oflags = O_WRONLY ; //| O_CREAT | O_EXCL;
138  mode_t mode = S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP ;
139 
140 
141  mqd_t ret = mq_open(m_messageQueueNameCstring, oflags, mode, &attr);
142 
143 
144  if (ret == (mqd_t) - 1)
145  B2FATAL(std::string(__FILE__) << ":" <<
146  __LINE__ << ": error: " <<
147  strerror(errno) <<
148  " on mq_open " << log_string);
149 
150  m_messageQueue = ret;
151 
152 }
153 
154 void
155 ROISenderModule::closeMessageQueue(const char* log_string)
156 {
157  mqd_t ret;
158 
159  ret = mq_close(m_messageQueue);
160  if (ret == (mqd_t) - 1)
161  B2WARNING(std::string(__FILE__) << ":" <<
162  __LINE__ << ": error: " <<
163  strerror(errno) <<
164  " on mq_close " << log_string);
165 
166 }
167 
168 
170 void
171 ROISenderModule::unlinkMessageQueue(const char* log_string)
172 {
173  mqd_t ret;
174  ret = mq_unlink(m_messageQueueNameCstring);
175  if (ret == (mqd_t) - 1)
176  B2WARNING(std::string(__FILE__) << ":" <<
177  __LINE__ << ": error: " <<
178  strerror(errno) <<
179  " on mq_unlink " << log_string);
180 
181 }
182 
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
LogVar
Class to store variables with their name which were sent to the logging service.
Definition: LogVariableStream.h:24
Belle2::ROISenderModule
The ROI to ONSEN Module.
Definition: ROISenderModule.h:41