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