CMS 3D CMS Logo

CSCFileReader.cc
Go to the documentation of this file.
1 #include "CSCFileReader.h"
2 
3 #include <cerrno>
4 #include <cstdlib>
5 #include <cstring>
6 
8 
12 
17 
20 
22 
23 #include <vector>
24 #include <string>
25 #include <iosfwd>
26 #include <sstream>
27 #include <iostream>
28 #include <algorithm>
29 
30 #define nRUIs 40
31 #define nFUs 4
32 
34  runNumber = pset.getUntrackedParameter<unsigned int>("runNumber", 1);
35  LogDebug("CSCFileReader|ctor") << "Started ...";
36  // Below some data members are recycled for both cases: RUIs and FUs
37  // this is ok as long as eighter of RUI or FU are are provided in .cfg (not both)
38  nActiveRUIs = 0;
39  nActiveFUs = 0;
40 
44  // fFirstReadBug = true;
45  fFirstReadBug = pset.getUntrackedParameter<bool>("FirstReadBug", false);
46  for (int unit = 0; unit < nRUIs; unit++) {
47  std::ostringstream ruiName, fuName;
48  ruiName << "RUI" << (unit < 10 ? "0" : "") << unit << std::ends;
49  fuName << "FU" << unit << std::ends;
50  std::vector<std::string> ruiFiles =
51  pset.getUntrackedParameter<std::vector<std::string> >(ruiName.str().c_str(), std::vector<std::string>(0));
52  std::vector<std::string> fuFiles =
53  pset.getUntrackedParameter<std::vector<std::string> >(fuName.str().c_str(), std::vector<std::string>(0));
54  if (ruiFiles.begin() != ruiFiles.end())
55  nActiveRUIs++;
56  if (fuFiles.begin() != fuFiles.end())
57  nActiveFUs++;
58  }
59  if (nActiveFUs && nActiveRUIs)
60  throw cms::Exception("CSCFileReader|configuration")
61  << "RUIs and FUs in conflict: either RUI or FU may be defined at a time, not both";
62  if (!nActiveFUs && !nActiveRUIs)
63  throw cms::Exception("CSCFileReader|configuration") << "Module lacks configuration";
64 
65  // Get list of RUI input files from cfg file
66  for (int rui = 0; rui < nRUIs && !nActiveFUs; rui++) {
67  std::ostringstream name;
68  name << "RUI" << (rui < 10 ? "0" : "") << rui << std::ends;
69 
70  // Obtain list of files associated with current RUI
71  fileNames[rui] =
72  pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0));
73  currentFile[rui] = fileNames[rui].begin();
74 
75  // If list of files is not empty, open first file
76  if (currentFile[rui] != fileNames[rui].end()) {
77  try {
78  RUI[rui].open(currentFile[rui]->c_str());
79  } catch (std::runtime_error &err) {
80  throw cms::Exception("CSCFileReader") << "InputFileMissing: " << err.what() << " (errno=" << errno << ")";
81  }
82  nActiveRUIs++;
83  }
84 
85  // Filter out possible corruptions
87  // Do not select anything in particular
88  RUI[rui].select(0);
89 
90  currentL1A[rui] = -1;
91  }
92 
93  // Get list of FU input files from .cfg file
94  for (int fu = 0; fu < nFUs && !nActiveRUIs; fu++) {
95  std::ostringstream name;
96  name << "FU" << fu << std::ends;
97 
98  // Obtain list of files associated with current FU
99  fileNames[fu] =
100  pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0));
101  currentFile[fu] = fileNames[fu].begin();
102 
103  // If list of files is not empty, open first file
104  if (currentFile[fu] != fileNames[fu].end()) {
105  try {
106  FU[fu].open(currentFile[fu]->c_str());
107  } catch (std::runtime_error &err) {
108  throw cms::Exception("CSCFileReader") << "InputFileMissing: " << err.what() << " (errno=" << errno << ")";
109  }
110  nActiveFUs++;
111  }
112 
113  // Filter out possible corruptions
115  // Do not select anything in particular
116  FU[fu].select(0);
117 
118  currentL1A[fu] = -1;
119  }
120 
121  if (nActiveRUIs && !nActiveFUs) {
122  // Assign RUIs to FEDs
123  for (int fed = FEDNumbering::MINCSCFEDID; fed <= FEDNumbering::MAXCSCFEDID; fed++) {
124  std::ostringstream name;
125  name << "FED" << fed << std::ends;
126  std::vector<std::string> rui_list =
127  pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0));
128  for (std::vector<std::string>::const_iterator rui = rui_list.begin(); rui != rui_list.end(); rui++)
129  FED[fed].push_back((unsigned int)atoi(rui->c_str() + rui->length() - 2));
130  }
131  for (int fed = FEDNumbering::MINCSCDDUFEDID; fed <= FEDNumbering::MAXCSCDDUFEDID; fed++) {
132  std::ostringstream name;
133  name << "FED" << fed << std::ends;
134  std::vector<std::string> rui_list =
135  pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0));
136  for (std::vector<std::string>::const_iterator rui = rui_list.begin(); rui != rui_list.end(); rui++)
137  FED[fed].push_back((unsigned int)atoi(rui->c_str() + rui->length() - 2));
138  }
139 
140  // Do the same for Track-Finder FED
141  for (int fed = FEDNumbering::MINCSCTFFEDID; fed <= FEDNumbering::MAXCSCTFFEDID; fed++) {
142  std::ostringstream name;
143  name << "FED" << fed << std::ends;
144  std::vector<std::string> rui_list =
145  pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0));
146  for (std::vector<std::string>::const_iterator rui = rui_list.begin(); rui != rui_list.end(); rui++)
147  FED[fed].push_back((unsigned int)atoi(rui->c_str() + rui->length() - 2));
148  }
149  }
150  // Starting point
151  firstEvent = pset.getUntrackedParameter<int>("firstEvent", 0);
152  nEvents = 0;
153  expectedNextL1A = -1;
154 
155  // If Track-Finder was in readout specify its position in the record or set -1 otherwise
156  // Current agriment is that if there is a TF event it is first DDU record
157  tfDDUnumber = pset.getUntrackedParameter<int>("tfDDUnumber", -1);
158 
159  // For efficiency reasons create this big chunk of data only once
160  tmpBuf = new unsigned short[200000 * nRUIs + 4 * 4];
161  // Event buffer and its length for every FU
162  fuEvent[0] = nullptr;
163  fuEventSize[0] = 0;
164  fuEvent[1] = nullptr;
165  fuEventSize[1] = 0;
166  fuEvent[2] = nullptr;
167  fuEventSize[2] = 0;
168  fuEvent[3] = nullptr;
169  fuEventSize[3] = 0;
170  // Event buffer and its length for every RU
171  for (int rui = 0; rui < nRUIs; rui++) {
172  ruBuf[rui] = nullptr;
173  ruBufSize[rui] = 0;
174  }
175  LogDebug("CSCFileReader|ctor") << "... and finished";
176  produces<FEDRawDataCollection>();
177 }
178 
180  if (tmpBuf)
181  delete[] tmpBuf;
182 }
183 
184 int CSCFileReader::readRUI(int rui, const unsigned short *&buf, size_t &length) {
185  if (currentFile[rui] == fileNames[rui].end())
186  return -1;
187  do {
188  try {
189  length = RUI[rui].next(buf);
190  } catch (std::runtime_error &err) {
191  throw cms::Exception("CSCFileReader|reading") << "EndOfStream: " << err.what() << " (errno=" << errno << ")";
192  }
193  if (length == 0) // end of file, try next one
194  {
195  if (++currentFile[rui] != fileNames[rui].end()) {
196  try {
197  RUI[rui].open(currentFile[rui]->c_str());
198  } catch (std::runtime_error &err) {
199  throw cms::Exception("CSCFileReader|reading")
200  << "InputFileMissing: " << err.what() << " (errno=" << errno << ")";
201  }
202  } else
203  return -1;
204  }
205  } while (length == 0);
206  return buf[2] | ((buf[3] & 0xFF) << 16);
207 }
208 
209 int CSCFileReader::readFU(int fu, const unsigned short *&buf, size_t &length) {
210  if (currentFile[fu] == fileNames[fu].end())
211  return -1;
212  do {
213  try {
214  length = FU[fu].next(buf);
215  } catch (std::runtime_error &err) {
216  throw cms::Exception("CSCFileReader|reading") << "EndOfStream: " << err.what() << " (errno=" << errno << ")";
217  }
218  if (length == 0) // end of file, try next one
219  {
220  if (++currentFile[fu] != fileNames[fu].end()) {
221  try {
222  FU[fu].open(currentFile[fu]->c_str());
223  } catch (std::runtime_error &err) {
224  throw cms::Exception("CSCFileReader|reading")
225  << "InputFileMissing: " << err.what() << " (errno=" << errno << ")";
226  }
227  } else
228  return -1;
229  }
230  } while (length == 0);
231  // Take L1A from first DDU header in the DCC record (shift=8)
232  return buf[2 + 8] | ((buf[3 + 8] & 0xFF) << 16);
233 }
234 
236  int eventNumber = -1; // Will determine below
237 
238  do {
239  // Read next event from RUIs
240  for (int rui = 0; rui < nRUIs; rui++) {
241  // read event from the RUI only in two cases:
242  // 1) it is readable (currentL1A>0) and we expect next event from the RUI
243  // 2) it is first time (expectedNextL1A<0)
244  if ((currentL1A[rui] > 0 && currentL1A[rui] < expectedNextL1A) || expectedNextL1A < 0) {
245  currentL1A[rui] = readRUI(rui, ruBuf[rui], ruBufSize[rui]);
246  // std::cout << "read rui" << rui << " l1a: " << currentL1A[rui] << " size: " << ruBufSize[rui] << std::endl;
247  }
248  }
249  eventNumber = -1;
250 
251  // Select lowest L1A from all RUIs and don't expect next event from RUIs that currently hold higher L1A
252  for (int rui = 0; rui < nRUIs; rui++)
253  if (currentL1A[rui] >= 0 && (eventNumber > currentL1A[rui] || eventNumber == -1))
254  eventNumber = currentL1A[rui];
255  // No readable RUIs => fall out
256  if (eventNumber < 0)
257  return -1;
258  // Expect next event to be incremented by 1 wrt. to the current event
259  expectedNextL1A = eventNumber + 1;
260 
261  } while (nEvents++ < firstEvent);
262 
263  for (std::map<unsigned int, std::list<unsigned int> >::const_iterator fed = FED.begin(); fed != FED.end(); fed++)
264  if (fed->first < (unsigned int)FEDNumbering::MINCSCTFFEDID) {
265  // Now let's pretend that DDU data were wrapped with DCC Header (2 64-bit words) and Trailer (2 64-bit words):
266  unsigned short *dccBuf = tmpBuf, *dccCur = dccBuf;
267  dccCur[3] = 0x5000;
268  dccCur[2] = 0x0000;
269  dccCur[1] = 0x0000;
270  dccCur[0] = 0x005F; // Fake DCC Header 1
271  dccCur[7] = 0xD900;
272  dccCur[6] = 0x0000;
273  dccCur[5] = 0x0000;
274  dccCur[4] = 0x0017; // Fake DCC Header 2
275  dccCur += 8;
276 
277  for (std::list<unsigned int>::const_iterator rui = fed->second.begin(); rui != fed->second.end(); rui++) {
278  //cout<<"Event:"<<eventNumber<<" FED:"<<fed->first<<" RUI:"<<*(fed->second.begin())<<" currL1A:"<<currentL1A[*rui]<<endl;
279  if (currentL1A[*rui] == eventNumber) {
280  if (dccCur - dccBuf + ruBufSize[*rui] >= 200000 * nRUIs + 8)
281  throw cms::Exception("CSCFileReader|eventBuffer")
282  << "OutOfBuffer: Event size exceeds maximal size allowed!";
283  memcpy(dccCur, ruBuf[*rui], ruBufSize[*rui] * sizeof(unsigned short));
284  dccCur += ruBufSize[*rui];
285  }
286  }
287  dccCur[3] = 0xEF00;
288  dccCur[2] = 0x0000;
289  dccCur[1] = 0x0000;
290  dccCur[0] = 0x0000; // Fake DCC Trailer 2
291  dccCur[7] = 0xAF00;
292  dccCur[6] = 0x0000;
293  dccCur[5] = 0x0000;
294  dccCur[4] = 0x0007; // Fake DCC Trailer 2
295  dccCur += 8;
296 
297  FEDRawData &fedRawData = data->FEDData(fed->first);
298  fedRawData.resize((dccCur - dccBuf) * sizeof(unsigned short));
299  std::copy((unsigned char *)dccBuf, (unsigned char *)dccCur, fedRawData.data());
300  } else {
301  for (std::list<unsigned int>::const_iterator rui = fed->second.begin(); rui != fed->second.end(); rui++) {
302  FEDRawData &fedRawData = data->FEDData(fed->first);
303  fedRawData.resize(ruBufSize[*rui] * sizeof(unsigned short));
304  std::copy((unsigned char *)ruBuf[*rui], (unsigned char *)(ruBuf[*rui] + ruBufSize[*rui]), fedRawData.data());
305  }
306  }
307 
308  return eventNumber;
309 }
310 
312  int eventNumber = -1; // Will determine below
313 
314  // If this is a first time - read one event from each FU
315  if (expectedNextL1A < 0)
316  for (int fu = 0; fu < nFUs; fu++)
317  currentL1A[fu] = readFU(fu, fuEvent[fu], fuEventSize[fu]);
318 
319  // Keep buffers for every FU ready at all times
320  // When buffer from some FU is ready to go as the next event,
321  // release it, but read next one
322  int readyToGo = -1;
323  for (int fu = 0; fu < nFUs; fu++) {
324  // If FU is readable and (first loop of this cycle or current FU holds smallest L1A)
325  if (currentL1A[fu] >= 0 && (eventNumber < 0 || currentL1A[fu] < eventNumber)) {
326  readyToGo = fu;
327  eventNumber = currentL1A[fu];
328  }
329  }
330  // No readable FUs => fall out
331  if (readyToGo < 0)
332  return -1;
333 
334  expectedNextL1A = eventNumber + 1;
335 
336  // Compose event from DDC record striped of Track-Finder DDU and a separate TF DDU event
337  unsigned long long *start = (unsigned long long *)fuEvent[readyToGo];
338  unsigned long long *end = nullptr;
339  enum { Header = 1, Trailer = 2 };
340  unsigned int eventStatus = 0;
341  for (int dduRecord = 0; dduRecord <= tfDDUnumber; dduRecord++) {
342  unsigned long long word_0 = 0, word_1 = 0, word_2 = 0;
343  size_t dduWordCount = 0;
344  while (!end && dduWordCount < fuEventSize[readyToGo]) {
345  unsigned long long *dduWord = start;
346 
347  while (dduWordCount < fuEventSize[readyToGo]) {
348  word_0 = word_1; // delay by 2 DDU words
349  word_1 = word_2; // delay by 1 DDU word
350  word_2 = *dduWord; // current DDU word
351  if ((word_2 & 0xFFFFFFFFFFFF0000LL) == 0x8000000180000000LL) {
352  if (eventStatus & Header) // Second header
353  {
354  word_2 = word_1;
355  end = dduWord;
356  break;
357  }
358  start = dduWord;
359  }
360  if ((word_0 & 0xFFFFFFFFFFFF0000LL) == 0x8000FFFF80000000LL) {
361  eventStatus |= Trailer;
362  end = ++dduWord;
363  break;
364  }
365  // Increase counters by one DDU word
366  dduWord++;
367  dduWordCount++;
368  }
369  }
370  // If reach max length
371  if (dduWordCount == fuEventSize[readyToGo]) {
372  end = (unsigned long long *)(fuEvent[readyToGo] + fuEventSize[readyToGo]);
373  break;
374  }
375  }
376  // Include 0x5xxx preHeader if exists
377  if (start > (unsigned long long *)fuEvent[readyToGo] && (*(start - 1) & 0xF000000000000000LL) == 0x5000000000000000LL)
378  start--;
379 
380  // If Track-Finder DDU was in readout
381  if (tfDDUnumber >= 0) {
382  // Cut out Track-Finder DDU from the buffer
383  if (!end)
384  throw cms::Exception("CSCFileReader|lookingForTF") << " Sanity check failed (end==0)! Should never happen";
385 
386  FEDRawData &tfRawData = data->FEDData(FEDNumbering::MINCSCTFFEDID);
387  tfRawData.resize((end - start) * sizeof(unsigned long long));
388  std::copy((unsigned char *)start, (unsigned char *)end, tfRawData.data());
389 
390  // Create a new buffer from everything before and after TF DDU
391  unsigned short *event = tmpBuf;
392  memcpy(event, fuEvent[readyToGo], ((unsigned short *)start - fuEvent[readyToGo]) * sizeof(unsigned short));
393  event += ((unsigned short *)start - fuEvent[readyToGo]);
394  memcpy(event, end, (fuEvent[readyToGo] + fuEventSize[readyToGo] - (unsigned short *)end) * sizeof(unsigned short));
395  event += fuEvent[readyToGo] + fuEventSize[readyToGo] - (unsigned short *)end;
397  fedRawData.resize((fuEventSize[readyToGo] - ((unsigned short *)end - (unsigned short *)start)) *
398  sizeof(unsigned short));
399  std::copy((unsigned char *)tmpBuf, (unsigned char *)event, fedRawData.data());
400  } else {
402  fedRawData.resize((fuEventSize[readyToGo]) * sizeof(unsigned short));
403  std::copy((unsigned char *)fuEvent[readyToGo],
404  (unsigned char *)(fuEvent[readyToGo] + fuEventSize[readyToGo]),
405  fedRawData.data());
406  }
407 
408  currentL1A[readyToGo] = readFU(readyToGo, fuEvent[readyToGo], fuEventSize[readyToGo]);
409 
410  return eventNumber;
411 }
412 
413 int CSCFileReader::fillRawData(edm::Event &e, /* edm::Timestamp& tstamp,*/ FEDRawDataCollection *&data) {
414  edm::EventID eID = e.id();
415  data = new FEDRawDataCollection();
416 
417  if (fFirstReadBug) {
418  eID = edm::EventID(runNumber, 1U, 1);
419  fFirstReadBug = false;
420  return true;
421  }
422 
423  // int runNumber = 0; // Unknown at the level of EMu local DAQ
424  int eventNumber = -1; // Will determine below
425 
426  if (!nActiveFUs && nActiveRUIs) {
427  eventNumber = buildEventFromRUIs(data);
428  // std::cout << eventNumber << std::endl;
429  } else {
430  eventNumber = nextEventFromFUs(data);
431  }
432 
433  if (eventNumber < 0)
434  return false;
435 
436  eID = edm::EventID(runNumber, 1U, eventNumber);
437 
438  return true;
439 }
440 
443  FEDRawDataCollection *fedcoll = nullptr;
444  fillRawData(e, fedcoll);
445  std::unique_ptr<FEDRawDataCollection> bare_product(fedcoll);
446  e.put(std::move(bare_product));
447 }
448 
449 #undef nRUIs
450 #undef nFUs
Definition: start.py:1
const unsigned short * fuEvent[4]
Definition: CSCFileReader.h:29
int open(const char *filename)
unsigned int runNumber
Definition: CSCFileReader.h:26
void produce(edm::Event &, edm::EventSetup const &) override
std::vector< std::string > fileNames[40]
Definition: CSCFileReader.h:20
#define nRUIs
size_t ruBufSize[40]
Definition: CSCFileReader.h:32
#define nFUs
std::map< unsigned int, std::list< unsigned int > > FED
Definition: CSCFileReader.h:37
int buildEventFromRUIs(FEDRawDataCollection *data)
void select(unsigned int criteria)
Definition: FileReaderDDU.h:37
void select(unsigned int criteria)
Definition: FileReaderDCC.h:36
std::vector< std::string >::const_iterator currentFile[40]
Definition: CSCFileReader.h:21
size_t next(const unsigned short *&buf)
size_t fuEventSize[4]
Definition: CSCFileReader.h:30
int readRUI(int rui, const unsigned short *&buf, size_t &length)
Basic3DVector unit() const
FileReaderDCC FU[4]
Definition: CSCFileReader.h:35
~CSCFileReader(void) override
void reject(unsigned int criteria)
Definition: FileReaderDDU.h:41
void resize(size_t newsize, size_t wordsize=8)
Definition: FEDRawData.cc:28
virtual int fillRawData(edm::Event &e, FEDRawDataCollection *&data)
size_t next(const unsigned short *&buf, int prescaling=1)
unsigned short * tmpBuf
Definition: CSCFileReader.h:28
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
int readFU(int fu, const unsigned short *&buf, size_t &length)
void reject(unsigned int criteria)
Definition: FileReaderDCC.h:40
int currentL1A[40]
Definition: CSCFileReader.h:24
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
int nextEventFromFUs(FEDRawDataCollection *data)
FileReaderDDU RUI[40]
Definition: CSCFileReader.h:34
int open(const char *filename)
const unsigned short * ruBuf[40]
Definition: CSCFileReader.h:31
CSCFileReader(const edm::ParameterSet &pset)
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1
#define LogDebug(id)