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