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::auto_ptr<FEDRawDataCollection> rawColl;
185  if(produceRaw_){
186  if(mergeRaw_){
187  rawColl = auto_ptr<FEDRawDataCollection>(new FEDRawDataCollection(*sourceColl));
188  } else{
189  rawColl = auto_ptr<FEDRawDataCollection>(new FEDRawDataCollection());
190  }
191  }
192 
193  std::auto_ptr<EcalMatacqDigiCollection>
194  digiColl(new EcalMatacqDigiCollection());
195 
196  if(eventSkipCounter_==0){
197  if(sourceColl->FEDData(matacqFedId_).size()>4 && !produceRaw_){
198  //input raw data collection already contains matacqData
199  formatter_.interpretRawData(sourceColl->FEDData(matacqFedId_),
200  *digiColl);
201  } else{
202  bool isLaserEvent = (getCalibTriggerType(event) == laserType);
203 
204 
205  // cout << "---> " << (ignoreTriggerType_?"yes":"no") << " " << getCalibTriggerType(event) << endl;
206 
207  if(isLaserEvent || ignoreTriggerType_){
208 
209  const uint32_t runNumber = getRunNumber(event);
210  const uint32_t orbitId = getOrbitId(event);
211 
212  LogInfo("Matacq") << "Run " << runNumber << "\t Orbit " << orbitId << "\n";
213 
214  bool fileChange;
215  if(doOrbitOffset_){
216  map<uint32_t,uint32_t>::iterator it = orbitOffset_.find(runNumber);
217  if(it == orbitOffset_.end()){
218  LogWarning("Matacq") << "Orbit offset not found for run "
219  << runNumber
220  << ". No orbit correction will be applied.";
221  }
222  }
223 
224  if(getMatacqFile(runNumber, orbitId, &fileChange)){
225  //matacq file retrieval succeeded
226  LogInfo("Matacq") << "Matacq data file found for "
227  << "run " << runNumber << " orbit " << orbitId;
228  if(getMatacqEvent(runNumber, orbitId, fileChange)){
229  if(produceDigis_){
230  formatter_.interpretRawData(matacq_, *digiColl);
231  }
232  if(produceRaw_){
233  uint32_t dataLen64 = matacq_.getParsedLen();
234  if(dataLen64 > bufferSize*8 || matacq_.getDccLen()!= dataLen64){
235  LogWarning("Matacq") << " Error in Matacq event fragment length! "
236  << "DCC len: " << matacq_.getDccLen()
237  << "*8 Bytes, Parsed len: "
238  << matacq_.getParsedLen() << "*8 Bytes. "
239  << "Matacq data will not be included for this event.\n";
240  } else{
241  rawColl->FEDData(matacqFedId_).resize(dataLen64*8);
242  copy(data_.begin(), data_.begin() + dataLen64*8,
243  rawColl->FEDData(matacqFedId_).data());
244  }
245  }
246  LogInfo("Matacq") << "Associating matacq data with orbit id "
247  << matacq_.getOrbitId()
248  << " to dcc event with orbit id "
249  << orbitId << std::endl;
250  if(isLaserEvent){
252  } else{
254  }
255  } else{
256  if(isLaserEvent){
257  LogWarning("Matacq") << "No matacq data found for laser event "
258  << "of run " << runNumber << " orbit "
259  << orbitId;
260  }
261  }
262  } else{
263  LogWarning("Matacq") << "No matacq file found for event "
264  << event.id();
265  }
266  }
267  }
268  if(eventSkipCounter_>0){ //error occured for this events
269  // and some events will be skipped following
270  // to this error.
271  LogInfo("Matacq") << " [" << now() << "] "
273  << " next events will be skipped, following to an "
274  << "error on the last processed event, "
275  << "which is expected to be persistant.";
276  }
277  } else{
279  }
280 
281  if(produceRaw_){
282  if(verbosity_>1) cout << "[Matacq " << now() << "] "
283  << "Adding FEDRawDataCollection collection "
284  << " to event.\n";
285  event.put(rawColl, rawInstanceName_);
286  }
287 
288  if(produceDigis_){
289  if(verbosity_>1) cout << "[Matacq " << now() << "] "
290  << "Adding EcalMatacqDigiCollection collection "
291  << " to event.\n";
292  event.put(digiColl, digiInstanceName_);
293  }
294 }
295 
296 // #if 0
297 // bool
298 // MatacqProducer::getMatacqEvent(std::ifstream& f,
299 // uint32_t runNumber,
300 // uint32_t orbitId,
301 // bool doWrap,
302 // std::streamoff maxPos){
303 // bool found = false;
304 // streampos startPos = f.tellg();
305 
306 // while(!f.eof()
307 // && !found
308 // && (maxPos<0 || f.tellg()<=maxPos)){
309 // const streamsize headerSize = 8*8;
310 // f.read((char*)&data_[0], headerSize);
311 // if(f.eof()) break;
312 // int32_t orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
313 // uint32_t len = MatacqRawEvent::getDccLen(&data_[0], headerSize);
314 // uint32_t run = MatacqRawEvent::getRunNum(&data_[0], headerSize);
315 // // cout << "Matacq: orbit = " << orb
316 // // << " len = " << len
317 // // << " run = " << run << endl;
318 // if((abs(orb-(int32_t)orbitId) < orbitTolerance_)
319 // && (runNumber==0 || runNumber==run)){
320 // found = true;
321 // //reads the rest of the event:
322 // if(data_.size() < len*8){
323 // throw cms::Exception("Matacq") << "Buffer overflow";
324 // }
325 // f.read((char*)&data_[0]+headerSize, len*8-headerSize);
326 // matacq_ = MatacqRawEvent((unsigned char*)&data_[0], len*8);
327 // } else{
328 // //moves to next event:
329 // f.seekg(len*8 - headerSize, ios::cur);
330 // }
331 // }
332 
333 // f.clear(); //clears eof error to allow seekg
334 // if(doWrap && !found){
335 // f.seekg(0, ios::beg);
336 // found = getMatacqEvent(f, runNumber, orbitId, false, startPos);
337 // }
338 // return found;
339 // }
340 //#endif
341 
342 bool
344  int32_t orbitId,
345  bool fileChange){
346  filepos_t startPos;
347  if(!mtell(startPos)) return false;
348 
349  int32_t startOrb = -1;
350  const size_t headerSize = 8*8;
351  if(mread((char*)&data_[0], headerSize, "Reading matacq header", true)){
352  startOrb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
353  if(startOrb<0) startOrb = 0;
354  } else{
355  if(verbosity_>2){
356  cout << "[Matacq " << now() << "] Failed to read matacq header. Moved to start of "
357  " the file.\n";
358  }
359  mrewind();
360  if(mread((char*)&data_[0], headerSize, "Reading matacq header", true)){
361  startPos = 0;
362  startOrb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
363  } else{
364  if(verbosity_>2) cout << "[Matacq " << now() << "] Looks like matacq file is empty"
365  << "\n";
366  return false;
367  }
368  }
369 
370  if(verbosity_>2) cout << "[Matacq " << now() << "] Last read orbit: " << lastOrb_
371  << " looking for orbit " << orbitId
372  << ". Current file position: " << startPos
373  << " Orbit at current position: " << startOrb << "\n";
374 
375  // f.clear();
376  bool didCoarseMove = false;
377 
378  //FIXME: case where posEtim_.invalid() is false
379  if(!posEstim_.invalid()
380  && (abs(lastOrb_-orbitId) > fastRetrievalThresh_)){
381  filepos_t pos = posEstim_.pos(orbitId);
382 
383  // struct stat st;
384  filepos_t fsize;
385  // if(0==stat(inFileName_.c_str(), &st)){
386  if(msize(fsize)){
387  // const int64_t fsize = st.st_size;
388  if(0!=posEstim_.eventLength() && pos > fsize){
389  //estimated position is beyong end of file
390  //-> move to beginning of last event:
391  int64_t evtSize = posEstim_.eventLength()*sizeof(uint64_t);
392  pos = ((int64_t)fsize/evtSize-1)*evtSize;
393  if(verbosity_>2){
394  cout << "[Matacq " << now() << "] Estimated position was beyond end of file. "
395  "Changed to " << pos << "\n";
396  }
397  }
398  } else{
399  LogWarning("Matacq") << "Failed to access file " << inFileName_ << ".";
400  }
401  if(pos>=0){
402  if(verbosity_>2) cout << "[Matacq " << now() << "] jumping to estimated position "
403  << pos << "\n";
404  mseek(pos, SEEK_SET, "Jumping to estimated event position");
405  if(mread((char*)&data_[0], headerSize, "Reading matacq header", true)){
406  didCoarseMove = true;
407  } else{
408  //estimated position might have been beyond the end of the file,
409  //try, with original position:
410  didCoarseMove = false;
411  if(!mread((char*)&data_[0], headerSize, "Reading event header", true)){
412  return false;
413  }
414  }
415  } else{
416  if(verbosity_) cout << "[Matacq " << now() << "] Event orbit outside of orbit range "
417  "of matacq data file events\n";
418  return false;
419  }
420  }
421 
422  int32_t orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
423 
424  if(didCoarseMove){
425  //autoadjustement of threshold for coarse move:
426  if(abs(orb-orbitId) > fastRetrievalThresh_){
427  if(verbosity_>2) cout << "[Matacq " << now() << "] Fast retrieval threshold increased from "
429  fastRetrievalThresh_ = 2*abs(orb-orbitId);
430  if(verbosity_>2) cout << " to " << fastRetrievalThresh_ << "\n";
431  }
432 
433  //if coarse move did not improve situation, rolls back:
434  if(startOrb > 0
435  && (abs(orb-orbitId) > abs(startOrb-orbitId))){
436  if(verbosity_>2) cout << "[Matacq " << now() << "] Estimation (-> orbit " << orb << ") "
437  "was worst than original position (-> orbit "
438  << startOrb
439  << "). Restoring position (" << startPos << ").\n";
440  mseek(startPos, SEEK_SET);
441  mread((char*)&data_[0], headerSize, "Reading event header", true);
442  orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
443  }
444  }
445 
446  bool searchBackward = (orb>orbitId)?true:false;
447  //BEWARE: len must be signed, because we are using latter in the code (-len)
448  //expression
449  int len = (int)MatacqRawEvent::getDccLen(&data_[0], headerSize);
450 
451  if(len==0){
452  cout << "[Matacq " << now() << "] read DCC length is null! Cancels matacq event search "
453  << " and move matacq file pointer to beginning of the file. "
454  << "(" << __FILE__ << ":" << __LINE__ << ")."
455  << "\n";
456  //rewind(f);
457  mrewind();
458  return false;
459  }
460 
461  enum state_t { searching, found, failed } state = searching;
462 
463  while(state == searching){
464  orb = MatacqRawEvent::getOrbitId(&data_[0], headerSize);
465  len = (int)MatacqRawEvent::getDccLen(&data_[0], headerSize);
466  uint32_t run = MatacqRawEvent::getRunNum(&data_[0], headerSize);
467  if(verbosity_>3){
468  filepos_t pos = -1;
469  mtell(pos);
470  cout << "[Matacq " << now() << "] Header read at file position "
471  << pos
472  << ": orbit = " << orb
473  << " len = " << len << "x8 Byte"
474  << " run = " << run << "\n";
475  }
476  if((abs(orb-orbitId) < orbitTolerance_)
477  && (runNumber==0 || runNumber==run)){
478  state = found;
479  lastOrb_ = orb;
480  //reads the rest of the event:
481  if((int)data_.size() < len*8){
482  throw cms::Exception("Matacq") << "Buffer overflow";
483  }
484  if(verbosity_>2) cout << "[Matacq " << now() << "] Event found. Reading "
485  " matacq event." << "\n";
486  if(!mread((char*)&data_[0], len*8, "Reading matacq event")){
487  if(verbosity_>2) cout << "[Matacq " << now() << "] Failed to read matacq event."
488  << "\n";
489  state = failed;
490  }
491  matacq_ = MatacqRawEvent((unsigned char*)&data_[0], len*8);
492  } else {
493  if((searchBackward && (orb < orbitId))
494  || (!searchBackward && (orb > orbitId))){ //search ended
495  lastOrb_ = orb;
496  state = failed;
497  if(verbosity_>2) cout << "[Matacq " << now()
498  << "] No matacq data found for run " << run
499  << ", orbit ID " << orbitId << "." << "\n";
500  } else{
501  off_t offset = (searchBackward?-len:len)*8;
502  lastOrb_ = orb;
503  if(verbosity_>3){
504  cout << "[Matacq " << now() << "] In matacq file, moving "
505  << abs(offset) << " byte " << (offset>0?"forward":"backward")
506  << ".\n";
507  }
508 
509  if(mseek(offset, SEEK_CUR,
510  (searchBackward?"Moving to previous event":
511  "Moving to next event"))
512  && mread((char*)&data_[0], headerSize, "Reading event header",
513  true)){
514  } else{
515  if(!searchBackward) mseek(-len*8, SEEK_CUR,
516  "Moving to start of last complete event");
517  state = failed;
518  }
519  }
520  }
521  }
522 
523  if(state==found){
524  filepos_t pos = -1;
525  filepos_t fsize = -1;
526  mtell(pos);
527  msize(fsize);
528  if(pos==fsize-1){ //last byte.
529  if(verbosity_>2){
530  cout << "[Matacq " << now() << "] Event found was at the end of the file. Moving "
531  "stream position to beginning of this event."
532  << "\n";
533  }
534  mseek(-(int)len*8-1, SEEK_CUR,
535  "Moving to beginning of last matacq event");
536  }
537  }
538  return (state==found);
539 }
540 
541 
542 bool
543 MatacqProducer::getMatacqFile(uint32_t runNumber, uint32_t orbitId,
544  bool* fileChange){
546  && openedFileRunNumber_==runNumber){
547  if(fileChange!=0) *fileChange = false;
548  return misOpened();
549  }
550 
551  if(fileNames_.size()==0) return 0;
552 
553  const string runNumberFormat = "%08d";
554  string sRunNumber = str(boost::format(runNumberFormat) % runNumber);
555  //cout << "Run number string: " << sRunNumber << "\n";
556  bool found = false;
557  string fname;
558  for(unsigned i=0; i < fileNames_.size() && !found; ++i){
559  fname = fileNames_[i];
560  boost::algorithm::replace_all(fname, "%run_subdir%",
561  runSubDir(runNumber));
562  boost::algorithm::replace_all(fname, "%run_number%", sRunNumber);
563 
564  if(verbosity_>0) cout << "[Matacq " << now() << "] "
565  << "Looking for a file with path "
566  << fname << "\n";
567 
568  if(mcheck(fname)){
569  LogInfo("Matacq") << "Uses matacq data file: '" << fname << "'\n";
570  found = true;
571  }
572  }
573  if(!found){
574  if(verbosity_>=0) cout << "[Matacq " << now() << "] no matacq file found "
575  "for run " << runNumber << "\n";
578  if(fileChange!=0) *fileChange = false;
579  return 0;
580  }
581 
582  if(!mopen(fname)){
583  LogWarning("Matacq") << "Failed to open file " << fname << "\n";
586  if(fileChange!=0) *fileChange = false;
587  return false;
588  } else{
590  lastOrb_ = 0;
591  posEstim_.init(this);
592  if(fileChange!=0) *fileChange = true;
593  return true;
594  }
595 }
596 
597 
599  return ev.run();
600 }
601 
603  //on CVS HEAD (June 4, 08), class Event has a method orbitNumber()
604  //we could use here. The code would be shorten to:
605  //return ev.orbitNumber();
606  //we have to deal with what we have in current CMSSW releases:
609  if(!(rawdata.isValid())){
610  throw cms::Exception("NotFound")
611  << "No FED raw data collection found. ECAL raw data are "
612  "required to retrieve the orbit ID";
613  }
614 
615  int orbit = 0;
616  for(int id=601; id<=654; ++id){
617  if(!FEDNumbering::inRange(id)) continue;
618  const FEDRawData& data = rawdata->FEDData(id);
619  const int orbitIdOffset64 = 3;
620  if(data.size()>=8*(orbitIdOffset64+1)){//orbit id is in 4th 64-bit word
621  const unsigned char* pOrbit = data.data() + orbitIdOffset64*8;
622  int thisOrbit = pOrbit[0]
623  | (pOrbit[1] <<8)
624  | (pOrbit[2] <<16)
625  | (pOrbit[3] <<24);
626  if(orbit!=0 && thisOrbit!=0 && abs(orbit-thisOrbit)>orbitTolerance_){
627  //throw cms::Exception("EventCorruption")
628  // << "Orbit ID inconsitency in DCC headers";
629  LogWarning("EventCorruption")
630  << "Orbit ID inconsitency in DCC headers";
631  orbit = 0;
632  break;
633  }
634  if(thisOrbit!=0) orbit = thisOrbit;
635  }
636  }
637 
638  if(orbit==0){
639  // throw cms::Exception("NotFound")
640  // << "Failed to retrieve orbit ID of event "<< ev.id();
641  LogWarning("NotFound") << "Failed to retrieve orbit ID of event "
642  << ev.id();
643  }
644  return orbit;
645 }
646 
650  if(!(rawdata.isValid())){
651  throw cms::Exception("NotFound")
652  << "No FED raw data collection found. ECAL raw data are "
653  "required to retrieve the trigger type";
654  }
655 
656  Majority<int> stat;
657  for(int id=601; id<=654; ++id){
658  if(!FEDNumbering::inRange(id)) continue;
659  const FEDRawData& data = rawdata->FEDData(id);
660  const int detailedTrigger32 = 5;
661  if(data.size()>=4*(detailedTrigger32+1)){
662  const unsigned char* pTType = data.data() + detailedTrigger32*4;
663  int tType = pTType[1] & 0x7;
664  stat.add(tType);
665  }
666  }
667  double p;
668  int tType = stat.result(&p);
669  if(p<0){
670  //throw cms::Exception("NotFound") << "No ECAL DCC data found\n";
671  LogWarning("NotFound") << "No ECAL DCC data found\n";
672  tType = -1;
673  }
674  if(p<.8){
675  //throw cms::Exception("EventCorruption") << "Inconsitency in detailed trigger type indicated in ECAL DCC data headers\n";
676  LogWarning("EventCorruption") << "Inconsitency in detailed trigger type indicated in ECAL DCC data headers\n";
677  tType = -1;
678  }
679  return tType;
680 }
681 
683  mp->mrewind();
684 
685  const size_t headerSize = 8*8;
686  unsigned char data[headerSize];
687  if(!mp->mread((char*)data, headerSize)){
688  if(verbosity_) cout << "[Matacq " << now() << "] reached end of file!\n";
690  return;
691  } else{
692  firstOrbit_ = MatacqRawEvent::getOrbitId(data, headerSize);
693  eventLength_ = MatacqRawEvent::getDccLen(data, headerSize);
694  if(verbosity_>1) cout << "[Matacq " << now() << "] First event orbit: " << firstOrbit_
695  << " event length: " << eventLength_
696  << "*8 byte\n";
697  }
698 
699  mp->mrewind();
700 
701  if(eventLength_==0){
702  if(verbosity_) cout << "[Matacq " << now() << "] event length is null!" << endl;
703  return;
704  }
705 
706  filepos_t s;
707  mp->msize(s);
708 
709  //number of complete events:
710  const unsigned nEvents = s/eventLength_/8;
711 
712  if(nEvents==0){
713  if(verbosity_) cout << "[Matacq " << now() << "] File is empty!" << endl;
714  orbitStepMean_ = 0;
715  return;
716  }
717 
718  if(verbosity_>1) cout << "[Matacq " << now() << "] File size: " << s
719  << " Number of events: " << nEvents << endl;
720 
721  //position of last complete events:
722  off_t last = (nEvents-1)*(off_t)eventLength_*8;
723  mp->mseek(last, SEEK_SET, "Moving to beginning of last complete "
724  "matacq event");
725  if(!mp->mread((char*) data, headerSize, "Reading matacq header", true)){
726  LogWarning("Matacq") << "Fast matacq event retrieval failure. "
727  "Falling back to safe retrieval mode.";
728  orbitStepMean_ = 0;
729  }
730 
731  int32_t lastOrb = MatacqRawEvent::getOrbitId(data, headerSize);
732  int32_t lastLen = MatacqRawEvent::getDccLen(data, headerSize);
733 
734  if(verbosity_>1) cout << "[Matacq " << now() << "] Last event orbit: " << lastOrb
735  << " last event length: " << lastLen << endl;
736 
737  //some consistency check
738  if(lastLen!=eventLength_){
739  LogWarning("Matacq")
740  //throw cms::Exception("Matacq")
741  << "Fast matacq event retrieval failure: it looks like "
742  "the matacq file contains events of different sizes.";
743  // " Falling back to safe retrieval mode.";
744  invalid_ = false; //true;
745  orbitStepMean_ = 112; //0;
746  return;
747  }
748 
749  orbitStepMean_ = (lastOrb - firstOrbit_)/nEvents;
750 
751  if(verbosity_>1) cout << "[Matacq " << now() << "] Orbit step mean: " << orbitStepMean_
752  << "\n";
753 
754  invalid_ = false;
755 }
756 
757 int64_t MatacqProducer::PosEstimator::pos(int orb) const{
758  if(orb<firstOrbit_) return -1;
759  uint64_t r = orbitStepMean_!=0?
760  (((uint64_t)(orb-firstOrbit_))/orbitStepMean_)*eventLength_*8
761  :0;
762  if(verbosity_>2) cout << "[Matacq " << now() << "] Estimated Position for orbit " << orb
763  << ": " << r << endl;
764  return r;
765 }
766 
768  mclose();
769  timeval t;
770  gettimeofday(&t, 0);
771  if(logTiming_ && startTime_.tv_sec!=0){
772  //not using logger, to allow timing with different logging options
773  cout << "[Matacq " << now() << "] Time elapsed between first event and "
774  "destruction of MatacqProducer: "
775  << ((t.tv_sec-startTime_.tv_sec)*1.
776  + (t.tv_usec-startTime_.tv_usec)*1.e-6) << "s\n";
777  }
778 }
779 
781  std::ifstream f(orbitOffsetFile_.c_str());
782  if(f.bad()){
783  throw cms::Exception("Matacq")
784  << "Failed to open orbit ID correction file '"
785  << orbitOffsetFile_ << "'\n";
786  }
787 
788  cout << "[Matacq " << now() << "] "
789  << "Offset to substract to Matacq events Orbit ID: \n"
790  << "#Run Number\t Offset\n";
791 
792  int iline = 0;
793  string s;
794  stringstream buf;
795  while(f.eof()){
796  getline(f, s);
797  ++iline;
798  if(s[0]=='#'){//comment
799  //skip line:
800  f.ignore(numeric_limits<streamsize>::max(), '\n');
801  continue;
802  }
803  buf.str("");
804  buf << s;
805  int run;
806  int orbit;
807  buf >> run;
808  buf >> orbit;
809  if(buf.bad()){
810  throw cms::Exception("Matacq")
811  << "Syntax error in Orbit offset file '"
812  << orbitOffsetFile_ << "'";
813  }
814  cout << run << "\t" << orbit << "\n";
815  orbitOffset_.insert(pair<int, int>(run, orbit));
816  }
817 }
818 
819 #ifdef USE_STORAGE_MANAGER
820 bool MatacqProducer::mseek(filepos_t offset, int whence, const char* mess){
821  if(0==inFile_.get()) return false;
822  try{
824  if(whence==SEEK_SET) wh = Storage::SET;
825  else if(whence==SEEK_CUR) wh = Storage::CURRENT;
826  else if(whence==SEEK_END) wh = Storage::END;
827  else throw cms::Exception("Bug") << "Bug found in "
828  << __FILE__ << ": "<< __LINE__ << "\n";
829 
830  inFile_->position(offset, wh);
831  } catch(cms::Exception& e){
832  if(verbosity_){
833  cout << "[Matacq " << now() << "] ";
834  if(mess) cout << mess << ". ";
835  cout << "Random access error on input matacq file. ";
836  if(whence==SEEK_SET) cout << "Failed to seek absolute position " << offset;
837  else if(whence==SEEK_CUR) cout << "Failed to move " << offset << " bytes forward";
838  else if(whence==SEEK_END) cout << "Failed to seek position at " << offset << " bytes before end of file";
839  cout << ". Reopening file. " << e.what() << "\n";
841  return false;
842  }
843  }
844  return true;
845 }
846 
848  if(0==inFile_.get()) return false;
849  pos = inFile_->position();
850  return true;
851 }
852 
853 bool MatacqProducer::mread(char* buf, size_t n, const char* mess, bool peek){
854  if(0==inFile_.get()) return false;
855 
856  filepos_t pos = -1;
857  if(!mtell(pos)) return false;
858 
859  bool rc = false;
860  try{
861  rc = (n==inFile_->xread(buf, n));
862  } catch(cms::Exception& e){
863  if(verbosity_){
864  cout << "[Matacq " << now() << "] ";
865  if(mess) cout << mess << ". ";
866  cout << "Read failure from input matacq file: "
867  << e.what() << "\n";
868  }
869  //recovering from error:
871  mseek(pos);
872  return false;
873  }
874  if(peek){//asked to restore original file position
875  mseek(pos);
876  }
877  return rc;
878 }
879 
881  if(inFile_.get()==0) return false;
882  s = inFile_.get()->size();
883  return true;
884 }
885 
887  Storage* file = inFile_.get();
888  if(file==0) return false;
889  try{
890  file->rewind();
891  } catch(cms::Exception e){
892  if(verbosity_) cout << "Exception cautgh while rewinding file "
893  << inFileName_ << ": " << e.what() << ". "
894  << "File will be reopened.";
895  return mopen(inFileName_);
896  }
897  return true;
898 }
899 
901  return StorageFactory::get()->check(name);
902 }
903 
904 bool MatacqProducer::mopen(const std::string& name){
905  //close already opened file if any:
906  mclose();
907 
908  try{
909  inFile_
910  = auto_ptr<Storage>(StorageFactory::get()->open(name,
912  inFileName_ = name;
913  } catch(cms::Exception& e){
914  LogWarning("Matacq") << e.what();
915  inFile_.reset();
916  inFileName_ = "";
917  return false;
918  }
919  return true;
920 }
921 
923  if(inFile_.get()!=0){
924  inFile_->close();
925  inFile_.reset();
926  }
927 }
928 
930  return inFile_.get()!=0;
931 }
932 
933 bool MatacqProducer::meof(){
934  if(inFile_.get()==0) return true;
935  return inFile_->eof();
936 }
937 
938 #else //USE_STORAGE_MANAGER not defined
939 bool MatacqProducer::mseek(off_t offset, int whence, const char* mess){
940  if(0==inFile_) return false;
941  const int rc = fseeko(inFile_, offset, whence);
942  if(rc!=0 && verbosity_){
943  cout << "[Matacq " << now() << "] ";
944  if(mess) cout << mess << ". ";
945  cout << "Random access error on input matacq file. "
946  "Rewind file.\n";
947  mrewind();
948  }
949  return rc==0;
950 }
951 
953  if(0==inFile_) return false;
954  pos = ftello(inFile_);
955  return pos != -1;
956 
957 }
958 
959 bool MatacqProducer::mread(char* buf, size_t n, const char* mess, bool peek){
960  if(0==inFile_) return false;
961  off_t pos = ftello(inFile_);
962  bool rc = (pos!=-1) && (1==fread(buf, n, 1, inFile_));
963  if(!rc){
964  if(verbosity_){
965  cout << "[Matacq " << now() << "] ";
966  if(mess) cout << mess << ". ";
967  cout << "Read failure from input matacq file.\n";
968  }
969  clearerr(inFile_);
970  }
971  if(peek || !rc){//need to restore file position
972  if(0!=fseeko(inFile_, pos, SEEK_SET)){
973  if(verbosity_){
974  cout << "[Matacq " << now() << "] ";
975  if(mess) cout << mess << ". ";
976  cout << "Failed to restore file position of "
977  "before read error. Rewind file.\n";
978  }
979  //rewind(inFile_.get());
980  mrewind();
981  lastOrb_ = 0;
982  }
983  }
984  return rc;
985 }
986 
988  if(0==inFile_) return false;
989  struct stat buf;
990  if(0!=fstat(fileno(inFile_), &buf)){
991  s = 0;
992  return false;
993  } else{
994  s = buf.st_size;
995  return true;
996  }
997 }
998 
1000  if(0==inFile_) return false;
1001  clearerr(inFile_);
1002  return fseeko(inFile_, 0, SEEK_SET)!=0;
1003 }
1004 
1006  struct stat dummy;
1007  return 0==stat(name.c_str(), &dummy);
1008 // if(stat(name.c_str(), &dummy)==0){
1009 // return true;
1010 // } else{
1011 // cout << "[Matacq " << now() << "] Failed to stat file '"
1012 // << name.c_str() << "'. "
1013 // << "Error " << errno << ": " << strerror(errno) << "\n";
1014 // return false;
1015 // }
1016 }
1017 
1019  if(inFile_!=0) mclose();
1020  inFile_ = fopen(name.c_str(), "r");
1021  if(inFile_!=0){
1022  inFileName_ = name;
1023  return true;
1024  } else{
1025  inFileName_ = "";
1026  return false;
1027  }
1028 }
1029 
1031  if(inFile_!=0) fclose(inFile_);
1032  inFile_ = 0;
1033 }
1034 
1036  return inFile_!=0;
1037 }
1038 
1040  if(0==inFile_) return true;
1041  return feof(inFile_)==0;
1042 }
1043 
1044 #endif //USE_STORAGE_MANAGER defined
1045 
1047  int millions = runNumber / (1000*1000);
1048  int thousands = (runNumber-millions*1000*1000) / 1000;
1049  int units = runNumber-millions*1000*1000 - thousands*1000;
1050  return str(boost::format("%03d/%03d/%03d") % millions % thousands % units);
1051 }
1052 
1053 void MatacqProducer::newRun(int prevRun, int newRun){
1054  runNumber_ = newRun;
1055  eventSkipCounter_ = 0;
1056  logFile_ << "[" << now() << "] Event count for run "
1057  << runNumber_ << ": "
1058  << "total: " << stats_.nEvents << ", "
1059  << "Laser event with Matacq data: "
1060  << stats_.nLaserEventsWithMatacq << ", "
1061  << "Non laser event (according to DCC header) with Matacq data: "
1062  << stats_.nNonLaserEventsWithMatacq << "\n" << flush;
1063 
1064  stats_.nEvents = 0;
1067 
1068 
1069 }
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_
edm::SortedCollection< EcalMatacqDigi > EcalMatacqDigiCollection
unsigned getRunNum() const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:462
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)
RunNumber_t run() const
Definition: Event.h:93
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:59
TString units(TString variable, Char_t axis)
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)