Belle II Software  release-08-01-10
Raw2DsModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <daq/rfarm/event/modules/Raw2DsModule.h>
10 #include <daq/dataobjects/SendHeader.h>
11 #include <daq/dataobjects/SendTrailer.h>
12 
13 #include <TSystem.h>
14 #include <stdlib.h>
15 #include <signal.h>
16 
17 #include "framework/datastore/StoreObjPtr.h"
18 #include "framework/dataobjects/EventMetaData.h"
19 #include "framework/core/Environment.h"
20 
21 // #define DESY
22 
23 namespace {
24 // Signal Handler
25  static int signalled = 0;
26  static void signalHandler(int sig)
27  {
28  signalled = sig;
29  printf("Raw2Ds : Signal received\n");
30  }
31 }
32 
33 using namespace std;
34 using namespace Belle2;
35 
36 //-----------------------------------------------------------------
37 // Register the Module
38 //-----------------------------------------------------------------
39 REG_MODULE(Raw2Ds)
40 
41 //-----------------------------------------------------------------
42 // Implementation
43 //-----------------------------------------------------------------
44 
46 {
47  //Set module properties
48  setDescription("Encode DataStore into RingBuffer");
49  setPropertyFlags(c_Input);
50 
51  addParam("RingBufferName", m_rbufname, "Name of RingBuffer",
52  string("InputRbuf"));
53 
54  m_rbuf = NULL;
55  m_nevt = -1;
56 
57  //Parameter definition
58  B2INFO("Rx: Constructor done.");
59 }
60 
61 
62 Raw2DsModule::~Raw2DsModule()
63 {
64 }
65 
66 void Raw2DsModule::initialize()
67 {
68  gSystem->Load("libdataobjects");
69 
70  m_rbuf = new RingBuffer(m_rbufname.c_str());
71 
72  // Initialize EvtMetaData
73  m_eventMetaData.registerInDataStore();
74 
75  // Initialize Array of RawCOPPER
76  m_rawDataBlock.registerInDataStore();
77  m_rawCOPPER.registerInDataStore();
78  m_rawSVD.registerInDataStore();
79  m_rawCDC.registerInDataStore();
80  m_rawTOP.registerInDataStore();
81  m_rawARICH.registerInDataStore();
82  m_rawECL.registerInDataStore();
83  m_rawKLM.registerInDataStore();
84  m_rawTRG.registerInDataStore();
85  m_rawFTSW.registerInDataStore();
86 
87  // Read the first event in RingBuffer and restore in DataStore.
88  // This is necessary to create object tables before TTree initialization
89  // if used together with SimpleOutput.
90  // ---- Prefetch the first event
91  registerRawCOPPERs();
92 
93  B2INFO("Rx initialized.");
94 }
95 
96 
97 void Raw2DsModule::beginRun()
98 {
99  if (Environment::Instance().getNumberProcesses() != 0) {
100  struct sigaction s;
101  memset(&s, '\0', sizeof(s));
102  s.sa_handler = signalHandler;
103  sigemptyset(&s.sa_mask);
104  if (sigaction(SIGINT, &s, NULL) != 0) {
105  B2FATAL("Rbuf2Ds: Error to connect signal handler");
106  }
107  printf("Raw2Ds : Signal Handler installed.\n");
108  }
109  B2INFO("beginRun called.");
110 }
111 
112 
113 void Raw2DsModule::event()
114 {
115  m_nevt++;
116  // Skip first event since it is read in initialize();
117  if (m_nevt == 0) return;
118 
119  registerRawCOPPERs();
120 }
121 
122 void Raw2DsModule::registerRawCOPPERs()
123 {
124 
125 
126  // Get a record from ringbuf
127  unsigned int error_flag = 0;
128  int size;
129  int* evtbuf = new int[MAXEVTSIZE];
130  while ((size = m_rbuf->remq((int*)evtbuf)) == 0) {
131  // usleep(100);
132  // usleep(20);
133  if (signalled != 0) return;
134  usleep(5);
135  }
136  // B2INFO("Raw2Ds: got an event from RingBuffer, size=" << size <<
137  // " (proc= " << (int)getpid() << ")");
138 
139  // Unpack SendHeader
140  SendHeader sndhdr;
141  sndhdr.SetBuffer(evtbuf);
142  int npackedevts = sndhdr.GetNumEventsinPacket();
143  if (npackedevts != 1) {
144  printf("[WARNING] strange SendHeader : ");
145  // for (int i = 0; i < sndhdr.SENDHDR_NWORDS; i++) {
146  for (int i = 0; i < 10; i++) {
147  printf("0x%.8x ", *(sndhdr.GetBuffer() + i));
148  }
149  printf("\n"); fflush(stdout);
150 
151  B2WARNING("Raw2DsModule::number of events in packet is not 1. This process gets stuck here. Please ABORT the system. (Please see discussion of daqcore channel in https://b2rc.kek.jp/ on 2017. Nov. 30. about why this is not FATAL message.");
152  sleep(86400);
153  }
154  int ncprs = sndhdr.GetNumNodesinPacket();
155  int nwords = sndhdr.GetTotalNwords() - SendHeader::SENDHDR_NWORDS - SendTrailer::SENDTRL_NWORDS;
156  // B2INFO("Raw2DS: Ncprs=" << ncprs << " Nwords=" << nwords);
157 
158 
159  // Get buffer header
160  int* bufbody = evtbuf + SendHeader::SENDHDR_NWORDS;
161 
162  // Unpack buffer
163  RawDataBlock tempdblk;
164  tempdblk.SetBuffer(bufbody, nwords, false, npackedevts, ncprs);
165 
166  unsigned int utime = 0;
167  unsigned int ctime = 0;
168  unsigned long long int mtime = 0;
169 
170  int store_time_flag = 0;
171 
172  // Store data contents in Corresponding RawXXXX
173  for (int cprid = 0; cprid < ncprs * npackedevts; cprid++) {
174  // Pick up one COPPER and copy data in a temporary buffer
175  int nwds_buf = tempdblk.GetBlockNwords(cprid);
176  int* cprbuf = new int[nwds_buf];
177  memcpy(cprbuf, tempdblk.GetBuffer(cprid), nwds_buf * 4);
178 
179  // Check FTSW
180  if (tempdblk.CheckFTSWID(cprid)) {
182  RawFTSW* ftsw = ary.appendNew();
183  ftsw->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
184 
185  // Tentative for DESY TB 2017
186  utime = (unsigned int)(ftsw->GetTTUtime(0));
187  ctime = (unsigned int)(ftsw->GetTTCtime(0));
188  mtime = 1000000000 * (unsigned long long int)utime + (unsigned long long int)(std::round(ctime / 0.127216));
189  store_time_flag = 1;
190  continue;
191  } else if (store_time_flag == 0) {
192  // Tentative until RawFTSW data stream is established. 2018.5.28
193  // Not store RawCOPPER here. 2018.11.23
194  RawCOPPER tempcpr_time;
195  tempcpr_time.SetBuffer(cprbuf, nwds_buf, false, 1, 1);
196  utime = (unsigned int)(tempcpr_time.GetTTUtime(0));
197  ctime = (unsigned int)(tempcpr_time.GetTTCtime(0));
198  mtime = 1000000000 * (unsigned long long int)utime + (unsigned long long int)(std::round(ctime / 0.127216));
199  store_time_flag = 1;
200  }
201 
202  // Set one block to RawCOPPER
203  RawCOPPER tempcpr;
204  tempcpr.SetBuffer(cprbuf, nwds_buf, false, 1, 1);
205  int subsysid = tempcpr.GetNodeID(0);
206  // if (tempcpr.GetEventCRCError(0) != 0) error_flag = 1;
207  error_flag |= (unsigned int)(tempcpr.GetDataType(0));
208 
209  // Switch to each detector and register RawXXX
210  if ((subsysid & DETECTOR_MASK) == CDC_ID) {
211  StoreArray<RawCDC> ary;
212  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
213  } else if ((subsysid & DETECTOR_MASK) == SVD_ID) {
214  StoreArray<RawSVD> ary;
215  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
216  } else if ((subsysid & DETECTOR_MASK) == BECL_ID) {
217  StoreArray<RawECL> ary;
218  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
219  } else if ((subsysid & DETECTOR_MASK) == EECL_ID) {
220  StoreArray<RawECL> ary;
221  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
222  } else if ((subsysid & DETECTOR_MASK) == TOP_ID) {
223  StoreArray<RawTOP> ary;
224  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
225  } else if ((subsysid & DETECTOR_MASK) == ARICH_ID) {
227  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
228  } else if ((subsysid & DETECTOR_MASK) == BKLM_ID) {
229  StoreArray<RawKLM> ary;
230  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
231  } else if ((subsysid & DETECTOR_MASK) == EKLM_ID) {
232  StoreArray<RawKLM> ary;
233  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
234  } else if (((subsysid & DETECTOR_MASK) & 0xF0000000) == TRGDATA_ID) {
235  StoreArray<RawTRG> ary;
236  (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
237  } else {
238 
239  // Do not store Unknown RawCOPPER object. 2018.11.25
240  printf("[WARNING] Unknown COPPER ID : ");
241  for (int i = 0; i < 12; i++) {
242  printf("0x%.8x ", cprbuf[ i ]);
243  }
244  printf("\n");
245  B2FATAL("Unknown COPPER ID is found. CPRID = " << hex << subsysid << " Please check. Exiting...");
246  exit(1);
247  // StoreArray<RawCOPPER> ary;
248  // (ary.appendNew())->SetBuffer(cprbuf, nwds_buf, 1, 1, 1);
249  }
250  // delete[] cprbuf;
251  }
252 
253  if (store_time_flag != 1) {
254  B2FATAL("No time information could be extracted from Data. That should not happen. Exiting...");
255  }
256  StoreObjPtr<EventMetaData> evtmetadata;
257  evtmetadata.create();
258  evtmetadata->setExperiment(sndhdr.GetExpNum());
259  evtmetadata->setRun(sndhdr.GetRunNum());
260  evtmetadata->setSubrun(sndhdr.GetSubRunNum());
261  evtmetadata->setEvent(sndhdr.GetEventNumber());
262  evtmetadata->setTime(mtime); //time(NULL));
263  // evtmetadata->setTime((unsigned long long int) utime);//time(NULL));
264 
265  if (error_flag) setErrorFlag(error_flag, evtmetadata);
266 
267  delete[] evtbuf;
268 
269  // B2INFO("Raw2Ds: DataStore Restored!!");
270  return;
271 }
272 
273 void Raw2DsModule::endRun()
274 {
275  //fill Run data
276 
277  B2INFO("Raw2Ds: endRun done.");
278 }
279 
280 
281 void Raw2DsModule::terminate()
282 {
283  B2INFO("Raw2Ds: terminate called");
284 }
285 
286 void Raw2DsModule::setErrorFlag(unsigned int error_flag, StoreObjPtr<EventMetaData> evtmetadata)
287 {
288  // RawHeader_latest raw_hdr;
289  int error_set = 0;
290  if (error_flag & RawHeader_latest::B2LINK_PACKET_CRC_ERROR) {
291  evtmetadata->addErrorFlag(EventMetaData::c_B2LinkPacketCRCError);
292  error_set = 1;
293  }
294  if (error_flag & RawHeader_latest::B2LINK_EVENT_CRC_ERROR) {
295  evtmetadata->addErrorFlag(EventMetaData::c_B2LinkEventCRCError);
296  error_set = 1;
297  }
298  if (error_set) B2INFO("Raw2Ds: Error flag was set in EventMetaData.");
299 }
Base class for Modules.
Definition: Module.h:72
A class definition of an input module for Sequential ROOT I/O.
Definition: Raw2DsModule.h:43
The Raw COPPER class This class stores data received by COPPER via belle2linkt Data from all detector...
Definition: RawCOPPER.h:52
void SetBuffer(int *bufin, int nwords, int delete_flag, int num_events, int num_nodes) OVERRIDE_CPP17
set buffer ( delete_flag : m_buffer is freeed( = 0 )/ not freeed( = 1 ) in Destructer )
Definition: RawCOPPER.cc:141
The RawDataBlock class Base class for rawdata handling.
Definition: RawDataBlock.h:27
virtual int CheckFTSWID(int n)
get FTSW ID to check whether this data block is FTSW data or not
Definition: RawDataBlock.h:101
virtual int * GetBuffer(int n)
get nth buffer pointer
Definition: RawDataBlock.h:53
virtual void SetBuffer(int *bufin, int nwords, int delete_flag, int num_events, int num_nodes)
set buffer ( delete_flag : m_buffer is freeed( = 0 )/ not freeed( = 1 ) in Destructer )
Definition: RawDataBlock.cc:35
virtual int GetBlockNwords(int n)
get size of a data block
Definition: RawDataBlock.h:94
The Raw FTSW class.
Definition: RawFTSW.h:30
unsigned int GetTTUtime(int n)
get unixtime of the trigger
Definition: RawFTSW.h:79
int GetTTCtime(int n)
Get ctime of the trigger.
Definition: RawFTSW.h:86
void SetBuffer(int *bufin, int nwords, int delete_flag, int num_events, int num_nodes) OVERRIDE_CPP17
set buffer ( delete_flag : m_buffer is freeed( = 0 )/ not freeed( = 1 ) in Destructer )
Definition: RawFTSW.cc:107
Class to manage a Ring Buffer placed in an IPC shared memory.
Definition: RingBuffer.h:39
void SetBuffer(int *hdr)
set buffer
Definition: SendHeader.cc:37
int GetNumEventsinPacket()
get contents of Header
Definition: SendHeader.cc:125
int * GetBuffer(void)
Get Header contents.
Definition: SendHeader.cc:32
bool create(bool replace=false)
Create a default object in the data store.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
@ c_Input
Input Process.
unsigned int GetTTUtime(int n)
Check if COPPER Magic words are correct.
Definition: RawCOPPER.h:614
int GetDataType(int n)
get contents of header
Definition: RawCOPPER.h:404
int GetTTCtime(int n)
Get ctime.
Definition: RawCOPPER.h:620
unsigned int GetNodeID(int n)
get node-ID from data
Definition: RawCOPPER.h:397
Abstract base class for different kinds of events.