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