test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MatacqProducer.cc
Go to the documentation of this file.
12 #include <boost/algorithm/string.hpp>
13 #include <boost/format.hpp>
14 
15 #include <iostream>
16 #include <memory>
17 
18 #include <stdio.h>
19 
20 #include <fstream>
21 #include <iomanip>
22 
24 
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <sys/stat.h>
29 
30 using namespace std;
31 using namespace boost;
32 using namespace edm;
33 
34 // #undef LogInfo
35 // #define LogInfo(a) cout << "INFO " << a << ": "
36 // #undef LogWarning
37 // #define LogWarning(a) cout << "WARN " << a << ": "
38 // #undef LogDebug
39 // #define LogDebug(a) cout << "DBG " << a << ": "
40 
41 
42 //verbose mode for matacq event retrieval debugging:
43 //static const bool searchDbg = false;
44 
45 //laser freq is 1 every 112 orbit => >80 orbit
46 const int MatacqProducer::orbitTolerance_ = 80;
47 
49 
50 static std::string now(){
51  struct timeval t;
52  gettimeofday(&t, 0);
53 
54  char buf[256];
55  strftime(buf, sizeof(buf), "%F %R %S s", localtime(&t.tv_sec));
56  buf[sizeof(buf)-1] = 0;
57 
58  stringstream buf2;
59  buf2 << buf << " " << ((t.tv_usec+500)/1000) << " ms";
60 
61  return buf2.str();
62 }
63 
64 
66  fileNames_(params.getParameter<std::vector<std::string> >("fileNames")),
67  digiInstanceName_(params.getParameter<string>("digiInstanceName")),
68  rawInstanceName_(params.getParameter<string>("rawInstanceName")),
69  timing_(params.getUntrackedParameter<bool>("timing", false)),
70  disabled_(params.getParameter<bool>("disabled")),
71  verbosity_(params.getUntrackedParameter<int>("verbosity", 0)),
72  produceDigis_(params.getParameter<bool>("produceDigis")),
73  produceRaw_(params.getParameter<bool>("produceRaw")),
74  inputRawCollection_(params.getParameter<edm::InputTag>("inputRawCollection")),
75  mergeRaw_(params.getParameter<bool>("mergeRaw")),
76  ignoreTriggerType_(params.getParameter<bool>("ignoreTriggerType")),
77  matacq_(0, 0),
78  inFile_(0),
79  data_(bufferSize),
80  openedFileRunNumber_(0),
81  lastOrb_(0),
82  fastRetrievalThresh_(0),
83  orbitOffsetFile_(params.getUntrackedParameter<std::string>("orbitOffsetFile",
84  "")),
85  inFileName_(""),
86  stats_(stats_init),
87  logFileName_(params.getUntrackedParameter<std::string>("logFileName",
88  "matacqProducer.log")),
89  eventSkipCounter_(0),
90  onErrorDisablingEvtCnt_(params.getParameter<int>("onErrorDisablingEvtCnt")),
91  timeLogFile_(params.getUntrackedParameter<std::string>("timeLogFile", "")),
92  runNumber_(0)
93 {
94  if(verbosity_>=4) cout << "[Matacq " << now() << "] in MatacqProducer ctor" << endl;
95 
96  gettimeofday(&timer_, 0);
97 
98  if(timeLogFile_.size()>0){
99  timeLog_.open(timeLogFile_.c_str());
100  if(timeLog_.fail()){
101  cout << "[LaserSorter " << now() << "] "
102  << "Failed to open file " << timeLogFile_ << " to log timing.\n";
103  logTiming_ = false;
104  } else{
105  logTiming_ = true;
106  }
107  }
108 
110 
111  logFile_.open(logFileName_.c_str(), ios::app | ios::out);
112 
113  if(logFile_.bad()){
114  throw cms::Exception("FileOpen") << "Failed to open file "
115  << logFileName_ << " for logging.\n";
116  }
117 
118  inputRawCollectionToken_ = consumes<FEDRawDataCollection>(params.getParameter<InputTag>("inputRawCollection"));
119 
120 
121  if(produceDigis_){
122  if(verbosity_>0) cout << "[Matacq " << now() << "] registering new "
123  "EcalMatacqDigiCollection product with instance name '"
124  << digiInstanceName_ << "'\n";
125  produces<EcalMatacqDigiCollection>(digiInstanceName_);
126  }
127 
128  if(produceRaw_){
129  if(verbosity_>0) cout << "[Matacq " << now() << "] registering new FEDRawDataCollection "
130  "product with instance name '"
131  << rawInstanceName_ << "'\n";
132  produces<FEDRawDataCollection>(rawInstanceName_);
133  }
134 
135  startTime_.tv_sec = startTime_.tv_usec = 0;
136  if(orbitOffsetFile_.size()>0){
137  doOrbitOffset_ = true;
138  loadOrbitOffset();
139  } else{
140  doOrbitOffset_ = false;
141  }
142  if(verbosity_>=4) cout << "[Matacq " << now() << "] exiting MatacqProducer ctor" << endl;
143 }
144 
145 
146 void
148  if(verbosity_>=4) cout << "[Matacq " << now() << "] in MatacqProducer::produce" << endl;
149  if(logTiming_){
150  timeval t;
151  gettimeofday(&t, 0);
152 
153  timeLog_ << t.tv_sec << "."
154  << setfill('0') << setw(3) << (t.tv_usec+500)/1000 << setfill(' ')<< "\t"
155  << (t.tv_usec - timer_.tv_usec)*1.
156  + (t.tv_sec - timer_.tv_sec)*1.e6 << "\t";
157  timer_ = t;
158  }
159 
160  if(startTime_.tv_sec==0) gettimeofday(&startTime_, 0);
161  ++stats_.nEvents;
162  if(disabled_) return;
163  const uint32_t runNumber = getRunNumber(event);
164  if(runNumber!=runNumber_){
165  newRun(runNumber_, runNumber);
166  }
167  addMatacqData(event);
168 
169  if(logTiming_){
170  timeval t;
171  gettimeofday(&t, 0);
172  timeLog_ << (t.tv_usec - timer_.tv_usec)*1.
173  + (t.tv_sec - timer_.tv_sec)*1.e6 << "\n";
174  timer_ = t;
175  }
176 }
177 
178 void
180 
182  event.getByToken(inputRawCollectionToken_, sourceColl);
183 
184  std::unique_ptr<FEDRawDataCollection> rawColl;
185  if(produceRaw_){
186  if(mergeRaw_){
187  rawColl = std::make_unique<FEDRawDataCollection>(*sourceColl);
188  } else{
189  rawColl = std::make_unique<FEDRawDataCollection>();
190  }
191  }
192 
193  auto digiColl = std::make_unique<EcalMatacqDigiCollection>();
194 
195  if(eventSkipCounter_==0){
196  if(sourceColl->FEDData(matacqFedId_).size()>4 && !produceRaw_){
197  //input raw data collection already contains matacqData
198  formatter_.interpretRawData(sourceColl->FEDData(matacqFedId_),
199  *digiColl);
200  } else{
201  bool isLaserEvent = (getCalibTriggerType(event) == laserType);
202 
203 
204  // cout << "---> " << (ignoreTriggerType_?"yes":"no") << " " << getCalibTriggerType(event) << endl;
205 
206  if(isLaserEvent || ignoreTriggerType_){
207 
208  const uint32_t runNumber = getRunNumber(event);
209  const uint32_t orbitId = getOrbitId(event);
210 
211  LogInfo("Matacq") << "Run " << runNumber << "\t Orbit " << orbitId << "\n";
212 
213  bool fileChange;
214  if(doOrbitOffset_){
215  map<uint32_t,uint32_t>::iterator it = orbitOffset_.find(runNumber);
216  if(it == orbitOffset_.end()){
217  LogWarning("Matacq") << "Orbit offset not found for run "
218  << runNumber
219  << ". No orbit correction will be applied.";
220  }
221  }
222 
223  if(getMatacqFile(runNumber, orbitId, &fileChange)){
224  //matacq file retrieval succeeded
225  LogInfo("Matacq") << "Matacq data file found for "
226  << "run " << runNumber << " orbit " << orbitId;
227  if(getMatacqEvent(runNumber, orbitId, fileChange)){
228  if(produceDigis_){
229  formatter_.interpretRawData(matacq_, *digiColl);
230  }
231  if(produceRaw_){
232  uint32_t dataLen64 = matacq_.getParsedLen();
233  if(dataLen64 > bufferSize*8 || matacq_.getDccLen()!= dataLen64){
234  LogWarning("Matacq") << " Error in Matacq event fragment length! "
235  << "DCC len: " << matacq_.getDccLen()
236  << "*8 Bytes, Parsed len: "
237  << matacq_.getParsedLen() << "*8 Bytes. "
238  << "Matacq data will not be included for this event.\n";
239  } else{
240  rawColl->FEDData(matacqFedId_).resize(dataLen64*8);
241  copy(data_.begin(), data_.begin() + dataLen64*8,
242  rawColl->FEDData(matacqFedId_).data());
243  }
244  }
245  LogInfo("Matacq") << "Associating matacq data with orbit id "
246  << matacq_.getOrbitId()
247  << " to dcc event with orbit id "
248  << orbitId << std::endl;
249  if(isLaserEvent){
251  } else{
253  }
254  } else{
255  if(isLaserEvent){
256  LogWarning("Matacq") << "No matacq data found for laser event "
257  << "of run " << runNumber << " orbit "
258  << orbitId;
259  }
260  }
261  } else{
262  LogWarning("Matacq") << "No matacq file found for event "
263  << event.id();
264  }
265  }
266  }
267  if(eventSkipCounter_>0){ //error occured for this events
268  // and some events will be skipped following
269  // to this error.
270  LogInfo("Matacq") << " [" << now() << "] "
272  << " next events will be skipped, following to an "
273  << "error on the last processed event, "
274  << "which is expected to be persistant.";
275  }
276  } else{
278  }
279 
280  if(produceRaw_){
281  if(verbosity_>1) cout << "[Matacq " << now() << "] "
282  << "Adding FEDRawDataCollection collection "
283  << " to event.\n";
284  event.put(std::move(rawColl), rawInstanceName_);
285  }
286 
287  if(produceDigis_){
288  if(verbosity_>1) cout << "[Matacq " << now() << "] "
289  << "Adding EcalMatacqDigiCollection collection "
290  << " to event.\n";
291  event.put(std::move(digiColl), digiInstanceName_);
292  }
293 }
294 
295 // #if 0
296 // bool
297 // MatacqProducer::getMatacqEvent(std::ifstream& f,
298 // uint32_t runNumber,
299 // uint32_t orbitId,
300 // bool doWrap,
301 // std::streamoff maxPos){
302 // bool found = false;
303 // streampos startPos = f.tellg();
304 
305 // while(!f.eof()
306 // && !found
307 // && (maxPos<0 || f.tellg()<=maxPos)){
308 // const streamsize headerSize = 8*8;
309 // f.read((char*)&data_[0], headerSize);
310 // if(f.eof()) break;
311 // int32_t orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
312 // uint32_t len = MatacqRawEvent::getDccLen(&data_[0], headerSize);
313 // uint32_t run = MatacqRawEvent::getRunNum(&data_[0], headerSize);
314 // // cout << "Matacq: orbit = " << orb
315 // // << " len = " << len
316 // // << " run = " << run << endl;
317 // if((abs(orb-(int32_t)orbitId) < orbitTolerance_)
318 // && (runNumber==0 || runNumber==run)){
319 // found = true;
320 // //reads the rest of the event:
321 // if(data_.size() < len*8){
322 // throw cms::Exception("Matacq") << "Buffer overflow";
323 // }
324 // f.read((char*)&data_[0]+headerSize, len*8-headerSize);
325 // matacq_ = MatacqRawEvent((unsigned char*)&data_[0], len*8);
326 // } else{
327 // //moves to next event:
328 // f.seekg(len*8 - headerSize, ios::cur);
329 // }
330 // }
331 
332 // f.clear(); //clears eof error to allow seekg
333 // if(doWrap && !found){
334 // f.seekg(0, ios::beg);
335 // found = getMatacqEvent(f, runNumber, orbitId, false, startPos);
336 // }
337 // return found;
338 // }
339 //#endif
340 
341 bool
343  int32_t orbitId,
344  bool fileChange){
345  filepos_t startPos;
346  if(!mtell(startPos)) return false;
347 
348  int32_t startOrb = -1;
349  const size_t headerSize = 8*8;
350  if(mread((char*)&data_[0], headerSize, "Reading matacq header", true)){
351  startOrb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
352  if(startOrb<0) startOrb = 0;
353  } else{
354  if(verbosity_>2){
355  cout << "[Matacq " << now() << "] Failed to read matacq header. Moved to start of "
356  " the file.\n";
357  }
358  mrewind();
359  if(mread((char*)&data_[0], headerSize, "Reading matacq header", true)){
360  startPos = 0;
361  startOrb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
362  } else{
363  if(verbosity_>2) cout << "[Matacq " << now() << "] Looks like matacq file is empty"
364  << "\n";
365  return false;
366  }
367  }
368 
369  if(verbosity_>2) cout << "[Matacq " << now() << "] Last read orbit: " << lastOrb_
370  << " looking for orbit " << orbitId
371  << ". Current file position: " << startPos
372  << " Orbit at current position: " << startOrb << "\n";
373 
374  // f.clear();
375  bool didCoarseMove = false;
376 
377  //FIXME: case where posEtim_.invalid() is false
378  if(!posEstim_.invalid()
379  && (abs(lastOrb_-orbitId) > fastRetrievalThresh_)){
380  filepos_t pos = posEstim_.pos(orbitId);
381 
382  // struct stat st;
383  filepos_t fsize;
384  // if(0==stat(inFileName_.c_str(), &st)){
385  if(msize(fsize)){
386  // const int64_t fsize = st.st_size;
387  if(0!=posEstim_.eventLength() && pos > fsize){
388  //estimated position is beyong end of file
389  //-> move to beginning of last event:
390  int64_t evtSize = posEstim_.eventLength()*sizeof(uint64_t);
391  pos = ((int64_t)fsize/evtSize-1)*evtSize;
392  if(verbosity_>2){
393  cout << "[Matacq " << now() << "] Estimated position was beyond end of file. "
394  "Changed to " << pos << "\n";
395  }
396  }
397  } else{
398  LogWarning("Matacq") << "Failed to access file " << inFileName_ << ".";
399  }
400  if(pos>=0){
401  if(verbosity_>2) cout << "[Matacq " << now() << "] jumping to estimated position "
402  << pos << "\n";
403  mseek(pos, SEEK_SET, "Jumping to estimated event position");
404  if(mread((char*)&data_[0], headerSize, "Reading matacq header", true)){
405  didCoarseMove = true;
406  } else{
407  //estimated position might have been beyond the end of the file,
408  //try, with original position:
409  didCoarseMove = false;
410  if(!mread((char*)&data_[0], headerSize, "Reading event header", true)){
411  return false;
412  }
413  }
414  } else{
415  if(verbosity_) cout << "[Matacq " << now() << "] Event orbit outside of orbit range "
416  "of matacq data file events\n";
417  return false;
418  }
419  }
420 
421  int32_t orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
422 
423  if(didCoarseMove){
424  //autoadjustement of threshold for coarse move:
425  if(abs(orb-orbitId) > fastRetrievalThresh_){
426  if(verbosity_>2) cout << "[Matacq " << now() << "] Fast retrieval threshold increased from "
428  fastRetrievalThresh_ = 2*abs(orb-orbitId);
429  if(verbosity_>2) cout << " to " << fastRetrievalThresh_ << "\n";
430  }
431 
432  //if coarse move did not improve situation, rolls back:
433  if(startOrb > 0
434  && (abs(orb-orbitId) > abs(startOrb-orbitId))){
435  if(verbosity_>2) cout << "[Matacq " << now() << "] Estimation (-> orbit " << orb << ") "
436  "was worst than original position (-> orbit "
437  << startOrb
438  << "). Restoring position (" << startPos << ").\n";
439  mseek(startPos, SEEK_SET);
440  mread((char*)&data_[0], headerSize, "Reading event header", true);
441  orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
442  }
443  }
444 
445  bool searchBackward = (orb>orbitId)?true:false;
446  //BEWARE: len must be signed, because we are using latter in the code (-len)
447  //expression
448  int len = (int)MatacqRawEvent::getDccLen(&data_[0], headerSize);
449 
450  if(len==0){
451  cout << "[Matacq " << now() << "] read DCC length is null! Cancels matacq event search "
452  << " and move matacq file pointer to beginning of the file. "
453  << "(" << __FILE__ << ":" << __LINE__ << ")."
454  << "\n";
455  //rewind(f);
456  mrewind();
457  return false;
458  }
459 
460  enum state_t { searching, found, failed } state = searching;
461 
462  while(state == searching){
463  orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
464  len = (int)MatacqRawEvent::getDccLen(&data_[0], headerSize);
465  uint32_t run = MatacqRawEvent::getRunNum(&data_[0], headerSize);
466  if(verbosity_>3){
467  filepos_t pos = -1;
468  mtell(pos);
469  cout << "[Matacq " << now() << "] Header read at file position "
470  << pos
471  << ": orbit = " << orb
472  << " len = " << len << "x8 Byte"
473  << " run = " << run << "\n";
474  }
475  if((abs(orb-orbitId) < orbitTolerance_)
476  && (runNumber==0 || runNumber==run)){
477  state = found;
478  lastOrb_ = orb;
479  //reads the rest of the event:
480  if((int)data_.size() < len*8){
481  throw cms::Exception("Matacq") << "Buffer overflow";
482  }
483  if(verbosity_>2) cout << "[Matacq " << now() << "] Event found. Reading "
484  " matacq event." << "\n";
485  if(!mread((char*)&data_[0], len*8, "Reading matacq event")){
486  if(verbosity_>2) cout << "[Matacq " << now() << "] Failed to read matacq event."
487  << "\n";
488  state = failed;
489  }
490  matacq_ = MatacqRawEvent((unsigned char*)&data_[0], len*8);
491  } else {
492  if((searchBackward && (orb < orbitId))
493  || (!searchBackward && (orb > orbitId))){ //search ended
494  lastOrb_ = orb;
495  state = failed;
496  if(verbosity_>2) cout << "[Matacq " << now()
497  << "] No matacq data found for run " << run
498  << ", orbit ID " << orbitId << "." << "\n";
499  } else{
500  off_t offset = (searchBackward?-len:len)*8;
501  lastOrb_ = orb;
502  if(verbosity_>3){
503  cout << "[Matacq " << now() << "] In matacq file, moving "
504  << abs(offset) << " byte " << (offset>0?"forward":"backward")
505  << ".\n";
506  }
507 
508  if(mseek(offset, SEEK_CUR,
509  (searchBackward?"Moving to previous event":
510  "Moving to next event"))
511  && mread((char*)&data_[0], headerSize, "Reading event header",
512  true)){
513  } else{
514  if(!searchBackward) mseek(-len*8, SEEK_CUR,
515  "Moving to start of last complete event");
516  state = failed;
517  }
518  }
519  }
520  }
521 
522  if(state==found){
523  filepos_t pos = -1;
524  filepos_t fsize = -1;
525  mtell(pos);
526  msize(fsize);
527  if(pos==fsize-1){ //last byte.
528  if(verbosity_>2){
529  cout << "[Matacq " << now() << "] Event found was at the end of the file. Moving "
530  "stream position to beginning of this event."
531  << "\n";
532  }
533  mseek(-(int)len*8-1, SEEK_CUR,
534  "Moving to beginning of last matacq event");
535  }
536  }
537  return (state==found);
538 }
539 
540 
541 bool
542 MatacqProducer::getMatacqFile(uint32_t runNumber, uint32_t orbitId,
543  bool* fileChange){
545  && openedFileRunNumber_==runNumber){
546  if(fileChange!=0) *fileChange = false;
547  return misOpened();
548  }
549 
550  if(fileNames_.size()==0) return 0;
551 
552  const string runNumberFormat = "%08d";
553  string sRunNumber = str(boost::format(runNumberFormat) % runNumber);
554  //cout << "Run number string: " << sRunNumber << "\n";
555  bool found = false;
556  string fname;
557  for(unsigned i=0; i < fileNames_.size() && !found; ++i){
558  fname = fileNames_[i];
559  boost::algorithm::replace_all(fname, "%run_subdir%",
560  runSubDir(runNumber));
561  boost::algorithm::replace_all(fname, "%run_number%", sRunNumber);
562 
563  if(verbosity_>0) cout << "[Matacq " << now() << "] "
564  << "Looking for a file with path "
565  << fname << "\n";
566 
567  if(mcheck(fname)){
568  LogInfo("Matacq") << "Uses matacq data file: '" << fname << "'\n";
569  found = true;
570  }
571  }
572  if(!found){
573  if(verbosity_>=0) cout << "[Matacq " << now() << "] no matacq file found "
574  "for run " << runNumber << "\n";
577  if(fileChange!=0) *fileChange = false;
578  return 0;
579  }
580 
581  if(!mopen(fname)){
582  LogWarning("Matacq") << "Failed to open file " << fname << "\n";
585  if(fileChange!=0) *fileChange = false;
586  return false;
587  } else{
589  lastOrb_ = 0;
590  posEstim_.init(this);
591  if(fileChange!=0) *fileChange = true;
592  return true;
593  }
594 }
595 
596 
598  return ev.run();
599 }
600 
602  //on CVS HEAD (June 4, 08), class Event has a method orbitNumber()
603  //we could use here. The code would be shorten to:
604  //return ev.orbitNumber();
605  //we have to deal with what we have in current CMSSW releases:
608  if(!(rawdata.isValid())){
609  throw cms::Exception("NotFound")
610  << "No FED raw data collection found. ECAL raw data are "
611  "required to retrieve the orbit ID";
612  }
613 
614  int orbit = 0;
615  for(int id=601; id<=654; ++id){
616  if(!FEDNumbering::inRange(id)) continue;
617  const FEDRawData& data = rawdata->FEDData(id);
618  const int orbitIdOffset64 = 3;
619  if(data.size()>=8*(orbitIdOffset64+1)){//orbit id is in 4th 64-bit word
620  const unsigned char* pOrbit = data.data() + orbitIdOffset64*8;
621  int thisOrbit = pOrbit[0]
622  | (pOrbit[1] <<8)
623  | (pOrbit[2] <<16)
624  | (pOrbit[3] <<24);
625  if(orbit!=0 && thisOrbit!=0 && abs(orbit-thisOrbit)>orbitTolerance_){
626  //throw cms::Exception("EventCorruption")
627  // << "Orbit ID inconsitency in DCC headers";
628  LogWarning("EventCorruption")
629  << "Orbit ID inconsitency in DCC headers";
630  orbit = 0;
631  break;
632  }
633  if(thisOrbit!=0) orbit = thisOrbit;
634  }
635  }
636 
637  if(orbit==0){
638  // throw cms::Exception("NotFound")
639  // << "Failed to retrieve orbit ID of event "<< ev.id();
640  LogWarning("NotFound") << "Failed to retrieve orbit ID of event "
641  << ev.id();
642  }
643  return orbit;
644 }
645 
649  if(!(rawdata.isValid())){
650  throw cms::Exception("NotFound")
651  << "No FED raw data collection found. ECAL raw data are "
652  "required to retrieve the trigger type";
653  }
654 
655  Majority<int> stat;
656  for(int id=601; id<=654; ++id){
657  if(!FEDNumbering::inRange(id)) continue;
658  const FEDRawData& data = rawdata->FEDData(id);
659  const int detailedTrigger32 = 5;
660  if(data.size()>=4*(detailedTrigger32+1)){
661  const unsigned char* pTType = data.data() + detailedTrigger32*4;
662  int tType = pTType[1] & 0x7;
663  stat.add(tType);
664  }
665  }
666  double p;
667  int tType = stat.result(&p);
668  if(p<0){
669  //throw cms::Exception("NotFound") << "No ECAL DCC data found\n";
670  LogWarning("NotFound") << "No ECAL DCC data found\n";
671  tType = -1;
672  }
673  if(p<.8){
674  //throw cms::Exception("EventCorruption") << "Inconsitency in detailed trigger type indicated in ECAL DCC data headers\n";
675  LogWarning("EventCorruption") << "Inconsitency in detailed trigger type indicated in ECAL DCC data headers\n";
676  tType = -1;
677  }
678  return tType;
679 }
680 
682  mp->mrewind();
683 
684  const size_t headerSize = 8*8;
685  unsigned char data[headerSize];
686  if(!mp->mread((char*)data, headerSize)){
687  if(verbosity_) cout << "[Matacq " << now() << "] reached end of file!\n";
689  return;
690  } else{
691  firstOrbit_ = MatacqRawEvent::getOrbitId(data, headerSize);
692  eventLength_ = MatacqRawEvent::getDccLen(data, headerSize);
693  if(verbosity_>1) cout << "[Matacq " << now() << "] First event orbit: " << firstOrbit_
694  << " event length: " << eventLength_
695  << "*8 byte\n";
696  }
697 
698  mp->mrewind();
699 
700  if(eventLength_==0){
701  if(verbosity_) cout << "[Matacq " << now() << "] event length is null!" << endl;
702  return;
703  }
704 
705  filepos_t s;
706  mp->msize(s);
707 
708  //number of complete events:
709  const unsigned nEvents = s/eventLength_/8;
710 
711  if(nEvents==0){
712  if(verbosity_) cout << "[Matacq " << now() << "] File is empty!" << endl;
713  orbitStepMean_ = 0;
714  return;
715  }
716 
717  if(verbosity_>1) cout << "[Matacq " << now() << "] File size: " << s
718  << " Number of events: " << nEvents << endl;
719 
720  //position of last complete events:
721  off_t last = (nEvents-1)*(off_t)eventLength_*8;
722  mp->mseek(last, SEEK_SET, "Moving to beginning of last complete "
723  "matacq event");
724  if(!mp->mread((char*) data, headerSize, "Reading matacq header", true)){
725  LogWarning("Matacq") << "Fast matacq event retrieval failure. "
726  "Falling back to safe retrieval mode.";
727  orbitStepMean_ = 0;
728  }
729 
730  int32_t lastOrb = MatacqRawEvent::getOrbitId(data, headerSize);
731  int32_t lastLen = MatacqRawEvent::getDccLen(data, headerSize);
732 
733  if(verbosity_>1) cout << "[Matacq " << now() << "] Last event orbit: " << lastOrb
734  << " last event length: " << lastLen << endl;
735 
736  //some consistency check
737  if(lastLen!=eventLength_){
738  LogWarning("Matacq")
739  //throw cms::Exception("Matacq")
740  << "Fast matacq event retrieval failure: it looks like "
741  "the matacq file contains events of different sizes.";
742  // " Falling back to safe retrieval mode.";
743  invalid_ = false; //true;
744  orbitStepMean_ = 112; //0;
745  return;
746  }
747 
748  orbitStepMean_ = (lastOrb - firstOrbit_)/nEvents;
749 
750  if(verbosity_>1) cout << "[Matacq " << now() << "] Orbit step mean: " << orbitStepMean_
751  << "\n";
752 
753  invalid_ = false;
754 }
755 
756 int64_t MatacqProducer::PosEstimator::pos(int orb) const{
757  if(orb<firstOrbit_) return -1;
758  uint64_t r = orbitStepMean_!=0?
759  (((uint64_t)(orb-firstOrbit_))/orbitStepMean_)*eventLength_*8
760  :0;
761  if(verbosity_>2) cout << "[Matacq " << now() << "] Estimated Position for orbit " << orb
762  << ": " << r << endl;
763  return r;
764 }
765 
767  mclose();
768  timeval t;
769  gettimeofday(&t, 0);
770  if(logTiming_ && startTime_.tv_sec!=0){
771  //not using logger, to allow timing with different logging options
772  cout << "[Matacq " << now() << "] Time elapsed between first event and "
773  "destruction of MatacqProducer: "
774  << ((t.tv_sec-startTime_.tv_sec)*1.
775  + (t.tv_usec-startTime_.tv_usec)*1.e-6) << "s\n";
776  }
777 }
778 
780  std::ifstream f(orbitOffsetFile_.c_str());
781  if(f.bad()){
782  throw cms::Exception("Matacq")
783  << "Failed to open orbit ID correction file '"
784  << orbitOffsetFile_ << "'\n";
785  }
786 
787  cout << "[Matacq " << now() << "] "
788  << "Offset to substract to Matacq events Orbit ID: \n"
789  << "#Run Number\t Offset\n";
790 
791  int iline = 0;
792  string s;
793  stringstream buf;
794  while(f.eof()){
795  getline(f, s);
796  ++iline;
797  if(s[0]=='#'){//comment
798  //skip line:
799  f.ignore(numeric_limits<streamsize>::max(), '\n');
800  continue;
801  }
802  buf.str("");
803  buf << s;
804  int run;
805  int orbit;
806  buf >> run;
807  buf >> orbit;
808  if(buf.bad()){
809  throw cms::Exception("Matacq")
810  << "Syntax error in Orbit offset file '"
811  << orbitOffsetFile_ << "'";
812  }
813  cout << run << "\t" << orbit << "\n";
814  orbitOffset_.insert(pair<int, int>(run, orbit));
815  }
816 }
817 
818 #ifdef USE_STORAGE_MANAGER
819 bool MatacqProducer::mseek(filepos_t offset, int whence, const char* mess){
820  if(0==inFile_.get()) return false;
821  try{
823  if(whence==SEEK_SET) wh = Storage::SET;
824  else if(whence==SEEK_CUR) wh = Storage::CURRENT;
825  else if(whence==SEEK_END) wh = Storage::END;
826  else throw cms::Exception("Bug") << "Bug found in "
827  << __FILE__ << ": "<< __LINE__ << "\n";
828 
829  inFile_->position(offset, wh);
830  } catch(cms::Exception& e){
831  if(verbosity_){
832  cout << "[Matacq " << now() << "] ";
833  if(mess) cout << mess << ". ";
834  cout << "Random access error on input matacq file. ";
835  if(whence==SEEK_SET) cout << "Failed to seek absolute position " << offset;
836  else if(whence==SEEK_CUR) cout << "Failed to move " << offset << " bytes forward";
837  else if(whence==SEEK_END) cout << "Failed to seek position at " << offset << " bytes before end of file";
838  cout << ". Reopening file. " << e.what() << "\n";
840  return false;
841  }
842  }
843  return true;
844 }
845 
847  if(0==inFile_.get()) return false;
848  pos = inFile_->position();
849  return true;
850 }
851 
852 bool MatacqProducer::mread(char* buf, size_t n, const char* mess, bool peek){
853  if(0==inFile_.get()) return false;
854 
855  filepos_t pos = -1;
856  if(!mtell(pos)) return false;
857 
858  bool rc = false;
859  try{
860  rc = (n==inFile_->xread(buf, n));
861  } catch(cms::Exception& e){
862  if(verbosity_){
863  cout << "[Matacq " << now() << "] ";
864  if(mess) cout << mess << ". ";
865  cout << "Read failure from input matacq file: "
866  << e.what() << "\n";
867  }
868  //recovering from error:
870  mseek(pos);
871  return false;
872  }
873  if(peek){//asked to restore original file position
874  mseek(pos);
875  }
876  return rc;
877 }
878 
880  if(inFile_.get()==0) return false;
881  s = inFile_.get()->size();
882  return true;
883 }
884 
886  Storage* file = inFile_.get();
887  if(file==0) return false;
888  try{
889  file->rewind();
890  } catch(cms::Exception e){
891  if(verbosity_) cout << "Exception cautgh while rewinding file "
892  << inFileName_ << ": " << e.what() << ". "
893  << "File will be reopened.";
894  return mopen(inFileName_);
895  }
896  return true;
897 }
898 
900  return StorageFactory::get()->check(name);
901 }
902 
903 bool MatacqProducer::mopen(const std::string& name){
904  //close already opened file if any:
905  mclose();
906 
907  try{
908  inFile_
909  = auto_ptr<Storage>(StorageFactory::get()->open(name,
911  inFileName_ = name;
912  } catch(cms::Exception& e){
913  LogWarning("Matacq") << e.what();
914  inFile_.reset();
915  inFileName_ = "";
916  return false;
917  }
918  return true;
919 }
920 
922  if(inFile_.get()!=0){
923  inFile_->close();
924  inFile_.reset();
925  }
926 }
927 
929  return inFile_.get()!=0;
930 }
931 
932 bool MatacqProducer::meof(){
933  if(inFile_.get()==0) return true;
934  return inFile_->eof();
935 }
936 
937 #else //USE_STORAGE_MANAGER not defined
938 bool MatacqProducer::mseek(off_t offset, int whence, const char* mess){
939  if(0==inFile_) return false;
940  const int rc = fseeko(inFile_, offset, whence);
941  if(rc!=0 && verbosity_){
942  cout << "[Matacq " << now() << "] ";
943  if(mess) cout << mess << ". ";
944  cout << "Random access error on input matacq file. "
945  "Rewind file.\n";
946  mrewind();
947  }
948  return rc==0;
949 }
950 
952  if(0==inFile_) return false;
953  pos = ftello(inFile_);
954  return pos != -1;
955 
956 }
957 
958 bool MatacqProducer::mread(char* buf, size_t n, const char* mess, bool peek){
959  if(0==inFile_) return false;
960  off_t pos = ftello(inFile_);
961  bool rc = (pos!=-1) && (1==fread(buf, n, 1, inFile_));
962  if(!rc){
963  if(verbosity_){
964  cout << "[Matacq " << now() << "] ";
965  if(mess) cout << mess << ". ";
966  cout << "Read failure from input matacq file.\n";
967  }
968  clearerr(inFile_);
969  }
970  if(peek || !rc){//need to restore file position
971  if(0!=fseeko(inFile_, pos, SEEK_SET)){
972  if(verbosity_){
973  cout << "[Matacq " << now() << "] ";
974  if(mess) cout << mess << ". ";
975  cout << "Failed to restore file position of "
976  "before read error. Rewind file.\n";
977  }
978  //rewind(inFile_.get());
979  mrewind();
980  lastOrb_ = 0;
981  }
982  }
983  return rc;
984 }
985 
987  if(0==inFile_) return false;
988  struct stat buf;
989  if(0!=fstat(fileno(inFile_), &buf)){
990  s = 0;
991  return false;
992  } else{
993  s = buf.st_size;
994  return true;
995  }
996 }
997 
999  if(0==inFile_) return false;
1000  clearerr(inFile_);
1001  return fseeko(inFile_, 0, SEEK_SET)!=0;
1002 }
1003 
1005  struct stat dummy;
1006  return 0==stat(name.c_str(), &dummy);
1007 // if(stat(name.c_str(), &dummy)==0){
1008 // return true;
1009 // } else{
1010 // cout << "[Matacq " << now() << "] Failed to stat file '"
1011 // << name.c_str() << "'. "
1012 // << "Error " << errno << ": " << strerror(errno) << "\n";
1013 // return false;
1014 // }
1015 }
1016 
1018  if(inFile_!=0) mclose();
1019  inFile_ = fopen(name.c_str(), "r");
1020  if(inFile_!=0){
1021  inFileName_ = name;
1022  return true;
1023  } else{
1024  inFileName_ = "";
1025  return false;
1026  }
1027 }
1028 
1030  if(inFile_!=0) fclose(inFile_);
1031  inFile_ = 0;
1032 }
1033 
1035  return inFile_!=0;
1036 }
1037 
1039  if(0==inFile_) return true;
1040  return feof(inFile_)==0;
1041 }
1042 
1043 #endif //USE_STORAGE_MANAGER defined
1044 
1046  int millions = runNumber / (1000*1000);
1047  int thousands = (runNumber-millions*1000*1000) / 1000;
1048  int units = runNumber-millions*1000*1000 - thousands*1000;
1049  return str(boost::format("%03d/%03d/%03d") % millions % thousands % units);
1050 }
1051 
1052 void MatacqProducer::newRun(int prevRun, int newRun){
1053  runNumber_ = newRun;
1054  eventSkipCounter_ = 0;
1055  logFile_ << "[" << now() << "] Event count for run "
1056  << runNumber_ << ": "
1057  << "total: " << stats_.nEvents << ", "
1058  << "Laser event with Matacq data: "
1059  << stats_.nLaserEventsWithMatacq << ", "
1060  << "Non laser event (according to DCC header) with Matacq data: "
1061  << stats_.nNonLaserEventsWithMatacq << "\n" << flush;
1062 
1063  stats_.nEvents = 0;
1066 
1067 
1068 }
static const char runNumber_[]
virtual char const * what() const
Definition: Exception.cc:141
bool check(const std::string &url, IOOffset *size=0) const
std::string inFileName_
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
std::map< uint32_t, uint32_t > orbitOffset_
uint32_t runNumber_
std::ofstream logFile_
static const int matacqFedId_
static const int orbitTolerance_
std::ofstream timeLog_
unsigned getRunNum() const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:457
static unsigned getOrbitId(unsigned char *data, size_t size)
std::vector< std::string > fileNames_
bool ev
string format
Some error handling for the usage.
std::string digiInstanceName_
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
uint32_t getRunNumber(edm::Event &ev) const
uint32_t getOrbitId() const
unsigned getDccLen() const
uint32_t getOrbitId(edm::Event &ev) const
Relative
Definition: Storage.h:23
bool mcheck(const std::string &name)
struct MatacqProducer::stats_t stats_
void add(const T &value)
Definition: Majority.h:24
static const StorageFactory * get(void)
int64_t pos(int orb) const
edm::EDGetTokenT< FEDRawDataCollection > inputRawCollectionToken_
void addMatacqData(edm::Event &event)
static std::string runSubDir(uint32_t runNumber)
def move
Definition: eostools.py:510
RunNumber_t run() const
Definition: Event.h:94
bool mread(char *buf, size_t n, const char *mess=0, bool peek=false)
virtual void produce(edm::Event &event, const edm::EventSetup &eventSetup)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:75
std::string orbitOffsetFile_
int getCalibTriggerType(edm::Event &ev) const
std::string timeLogFile_
unsigned long long uint64_t
Definition: Time.h:15
MatacqDataFormatter formatter_
uint32_t openedFileRunNumber_
PosEstimator posEstim_
void init(MatacqProducer *mp)
bool mtell(filepos_t &pos)
string fname
main script
static const int bufferSize
static bool inRange(int)
MatacqProducer(const edm::ParameterSet &params)
edm::EventID id() const
Definition: EventBase.h:58
TString units(TString variable, Char_t axis)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
static std::string now()
bool mseek(filepos_t offset, int whence=SEEK_SET, const char *mess=0)
MatacqRawEvent matacq_
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
std::string rawInstanceName_
void interpretRawData(const FEDRawData &data, EcalMatacqDigiCollection &matacqDigiCollection)
tuple cout
Definition: gather_cfg.py:145
dictionary rawdata
Definition: lumiPlot.py:393
volatile std::atomic< bool > shutdown_flag false
T result(double *proba) const
Definition: Majority.h:29
std::string logFileName_
UInt_t nEvents
Definition: hcalCalib.cc:42
bool msize(filepos_t &s)
std::vector< unsigned char > data_
void newRun(int prevRun, int newRun)
virtual void rewind(void)
Definition: Storage.cc:114
bool getMatacqFile(uint32_t runNumber, uint32_t orbitId, bool *fileChange=0)
static const stats_t stats_init
bool mopen(const std::string &name)
std::unique_ptr< Storage > open(const std::string &url, int mode=IOFlags::OpenRead) const
bool getMatacqEvent(uint32_t runNumber, int32_t orbitId, bool fileChange)