GRSISort
Created by P.C. Bender
Developement Team: P.C. Bender, R. Dunlop, V. Bildstein
An extension of the ROOT analysis Framework
offsetfix.cxx
Go to the documentation of this file.
1 // g++ offsetfind.cxx `root-config --cflags --libs` -I${GRSISYS}/include -L${GRSISYS}/libraries -lMidasFormat
2 // -lXMLParser -lSpectrum -ooffsetfind
3 
4 #include "TGRSIOptions.h"
5 #include "TMidasFile.h"
6 #include "TMidasEvent.h"
7 #include "TFile.h"
8 #include "TFragment.h"
9 #include "TGRSIDataParser.h"
11 #include "TTree.h"
12 #include "TSpectrum.h"
13 #include "TChannel.h"
14 #include "TH2D.h"
15 #include "TTreeIndex.h"
16 #include "TVirtualIndex.h"
17 #include "Globals.h"
18 #include "TF1.h"
19 #include "TMath.h"
20 #include "TString.h"
21 #include "TPolyMarker.h"
22 #include "TStopwatch.h"
23 #include "TSystem.h"
24 
25 #include <vector>
26 #include <iostream>
27 #include <fstream>
28 
29 Bool_t SplitMezz = false;
30 
31 class TEventTime {
32 public:
33  explicit TEventTime(std::shared_ptr<TMidasEvent> event)
34  {
35  event->SetBankList();
36 
37  void* ptr;
38  int banksize = event->LocateBank(nullptr, "GRF2", &ptr);
39  int bank = 2;
40 
41  if(banksize == 0) {
42  banksize = event->LocateBank(nullptr, "GRF1", &ptr);
43  bank = 1;
44  }
45  uint32_t type = 0xffffffff;
46  uint32_t value = 0xffffffff;
47 
48  // uint64_t time = 0;
49 
50  for(int x = 0; x < banksize; x++) {
51  value = *(reinterpret_cast<int*>(ptr) + x);
52  type = value & 0xf0000000;
53 
54  switch(type) {
55  case 0x80000000:
56  switch(bank) {
57  case 1: // header format from before May 2015 experiments
58  // Sets:
59  // The number of filters
60  // The Data Type
61  // Number of Pileups
62  // Channel Address
63  // Detector Type
64  if((value & 0xf0000000) != 0x80000000) {
65  // return false;
66  }
67  chanadd = (value & 0x0003fff0) >> 4;
68  dettype = (value & 0x0000000f);
69 
70  // if(frag-DetectorType==2)
71  // frag->ChannelAddress += 0x8000;
72  break;
73  case 2:
74  // Sets:
75  // The number of filters
76  // The Data Type
77  // Number of Pileups
78  // Channel Address
79  // Detector Type
80  if((value & 0xf0000000) != 0x80000000) {
81  // return false;
82  }
83  chanadd = (value & 0x000ffff0) >> 4;
84  dettype = (value & 0x0000000f);
85 
86  // if(frag-DetectorType==2)
87  // frag->ChannelAddress += 0x8000;
88  break;
89  default: printf("This bank not yet defined.\n"); break;
90  };
91  break;
92  case 0xa0000000: timelow = value & 0x0fffffff; break;
93  case 0xb0000000: timehigh = value & 0x00003fff; break;
94  };
95  }
96  timemidas = event->GetTimeStamp();
97 
98  SetDigitizer();
99 
100  if(!(digset.find(Digitizer())->second)) {
101  digset.find(Digitizer())->second = true;
102  if(GetTimeStamp() < lowest_time) {
103  if(Digitizer() == 0x0000 || Digitizer() == 0x0100 || Digitizer() == 0x0200 || Digitizer() == 0x0300 ||
104  Digitizer() == 0x1000 || Digitizer() == 0x1200 || Digitizer() == 0x1100 || Digitizer() == 0x1300) {
106  best_dig = Digitizer();
107  if(timemidas < low_timemidas) {
109  }
110  }
111  }
112  }
113  }
114 
115  ~TEventTime() = default;
116 
117  uint64_t GetTimeStamp()
118  {
119  uint64_t time = timehigh;
120  time = time<<28;
121  time |= timelow & 0x0fffffff;
122  return time;
123  }
124  unsigned int TimeStampHigh() { return timehigh; }
125 
126  unsigned long MidasTime() { return timemidas; }
127 
128  uint32_t Digitizer() { return digitizernum; }
129 
130  int DetectorType() { return dettype; }
131 
133  {
134  // Maybe make a map somewhere of digitizer vs address
135  digitizernum = chanadd & 0x0000ff00;
136  if(dettype > 1 && ((chanadd & 0xF) > 1) && ((chanadd & 0xF00) > 1) && SplitMezz) {
137  digitizernum += 2;
138  }
139 
140  digmap.insert(std::pair<uint32_t, int>(digitizernum, digmap.size()));
141  digset.insert(std::pair<uint32_t, bool>(digitizernum, false));
142  correctionmap.insert(std::pair<uint32_t, int64_t>(digitizernum, 0));
143  }
144 
145  static void OrderDigitizerMap()
146  {
147  std::map<uint32_t, int>::iterator it;
148  int index = 0;
149  for(it = digmap.begin(); it != digmap.end(); it++) {
150  it->second = index++;
151  }
152  }
153 
154  inline static int NDigitizers() { return digmap.size(); }
155 
156  inline static uint32_t GetBestDigitizer()
157  {
158  // return 0x1000;
159  return best_dig;
160  }
161 
162  static unsigned long GetLowestMidasTime() { return low_timemidas; }
163 
164  int DigIndex() { return digmap.find(digitizernum)->second; }
165 
166  inline static uint64_t GetLowestTime() { return lowest_time; }
167 
168  static std::map<uint32_t, int> digmap;
169  static std::map<uint32_t, bool> digset;
170  static std::map<uint32_t, int64_t> correctionmap;
171  static unsigned long low_timemidas;
172  static uint32_t best_dig;
173  static uint64_t lowest_time;
174 
175 private:
176  unsigned int timelow;
177  unsigned int timehigh;
178  unsigned long timemidas;
179  int dettype;
180  uint32_t chanadd;
181  uint32_t digitizernum{};
182 };
183 
184 unsigned long TEventTime::low_timemidas = -1;
185 uint64_t TEventTime::lowest_time = 0xffffffffffffffff;
186 uint32_t TEventTime::best_dig = 0;
187 std::map<uint32_t, int> TEventTime::digmap;
188 std::map<uint32_t, bool> TEventTime::digset;
189 std::map<uint32_t, int64_t> TEventTime::correctionmap;
190 
191 void PrintError(const std::shared_ptr<TMidasEvent>& event, int frags, bool verb)
192 {
193  if(verb) {
194  printf(DRED "\n//**********************************************//" RESET_COLOR "\n");
195  printf(DRED "\nBad things are happening. Failed on datum %i" RESET_COLOR "\n", (-1 * frags));
196  if(event) {
197  event->Print(Form("a%i", (-1 * frags) - 1));
198  }
199  printf(DRED "\n//**********************************************//" RESET_COLOR "\n");
200  }
201 }
202 
203 int QueueEvents(TMidasFile* infile, std::vector<TEventTime*>* eventQ)
204 {
205  int events_read = 0;
206  const int total_events = 1E6;
207  // const int event_start = 1E5;
208  const int event_start = 1E5;
209  std::shared_ptr<TMidasEvent> event = std::make_shared<TMidasEvent>();
210  eventQ->reserve(total_events);
211  void* ptr;
212  int banksize;
213 
214  int subrun = infile->GetSubRunNumber();
215 
216  if(subrun < 1) {
217  printf(DBLUE "Subrun 000, Starting event checker at event %d\n" RESET_COLOR, event_start);
218  printf(DBLUE "Please check that results still make sense\n" RESET_COLOR);
219  }
220 
221  // Do checks on the event
222  unsigned int mserial = 0;
223  if(event) {
224  mserial = (unsigned int)(event->GetSerialNumber());
225  }
226  unsigned int mtime = 0;
227  if(event) {
228  mtime = event->GetTimeStamp();
229  }
230  TGRSIDataParser parser;
231  while(infile->Read(event) > 0 && eventQ->size() < total_events) {
232  switch(event->GetEventId()) {
233  case 0x8000:
234  printf(DRED "start of run\n");
235  event->Print();
236  printf(RESET_COLOR);
237  break;
238  case 0x8001:
239  printf(DGREEN "end of run\n");
240  event->Print();
241  printf(RESET_COLOR);
242  break;
243  default:
244  if(event->GetEventId() != 1) {
245  break;
246  }
247  event->SetBankList();
248 
249  banksize = event->LocateBank(nullptr, "GRF2", &ptr);
250  if(banksize == 0) {
251  banksize = event->LocateBank(nullptr, "GRF1", &ptr);
252  }
253 
254  if(banksize > 0) {
255  int frags;
256  try {
257  frags = parser.GriffinDataToFragment(reinterpret_cast<uint32_t*>(ptr), banksize, TGRSIDataParser::EBank::kGRF2,
258  mserial, mtime);
259  } catch(TGRSIDataParserException& e) {
260  frags = -e.GetFailedWord();
261  }
262  if(frags > -1) {
263  events_read++;
264  if((subrun > 0) || (events_read > event_start)) {
265  eventQ->push_back(new TEventTime(
266  event)); // I'll keep 4G data in here for now in case we need to use it for time stamping
267  }
268  } else {
269  PrintError(event, frags, false);
270  }
271  }
272  break;
273  };
274  if(events_read % 250000 == 0) {
275  printf(DYELLOW "\tQUEUEING EVENT %d/%d \r" RESET_COLOR, events_read, total_events);
276  fflush(stdout);
277  }
278  }
280  printf("\n");
281  return 0;
282 }
283 
284 void CheckHighTimeStamp(std::vector<TEventTime*>* eventQ)
285 {
286  // This function should return an array of corrections
287 
288  auto* midvshigh = new TList;
289  printf(DBLUE "Correcting High time stamps...\n" RESET_COLOR);
290  // These first four are for looking to see if high time-stamp reset
291  std::map<uint32_t, int>::iterator mapit; // This is an iterator over the digitizer map
292  for(mapit = TEventTime::digmap.begin(); mapit != TEventTime::digmap.end(); mapit++) {
293  auto* midvshighhist = new TH2D(Form("midvshigh_0x%04x", mapit->first), Form("midvshigh_0x%04x", mapit->first),
294  5000, 0, 5000, 5000, 0, 5000);
295  midvshigh->Add(midvshighhist);
296  }
297 
298  unsigned int lowmidtime = TEventTime::GetLowestMidasTime();
299 
300  // MidasTimeStamp is the only time we can trust at this level.
301 
302  // int fEntries = eventQ->size();
303 
304  int FragsIn = 0;
305 
306  FragsIn++;
307  // Clear lowest hightime
308  std::map<uint32_t, int> lowest_hightime;
309  std::vector<TEventTime*>::iterator it;
310 
311  for(it = eventQ->begin(); it != eventQ->end(); it++) {
312  // This makes the plot, might not be required
313  int hightime = (*it)->TimeStampHigh();
314  unsigned long midtime = (*it)->MidasTime() - lowmidtime;
315  if(midtime > 20) {
316  break; // 20 seconds seems like plenty enough time
317  }
318  if(((*it)->Digitizer() == 0) && ((*it)->DetectorType() > 1)) {
319  continue;
320  }
321  // The next few lines are probably unnecessary
322  (dynamic_cast<TH2D*>(midvshigh->FindObject(Form("midvshigh_0x%04x", (*it)->Digitizer()))))
323  ->Fill(midtime, hightime);
324  if(lowest_hightime.find((*it)->Digitizer()) == lowest_hightime.end()) {
325  lowest_hightime[(*it)->Digitizer()] = hightime; // initialize this as the first time that is seen.
326  } else if(hightime < lowest_hightime.find((*it)->Digitizer())->second) {
327  lowest_hightime.find((*it)->Digitizer())->second = hightime;
328  }
329  }
330 
331  // find lowest digitizer
332  uint32_t lowest_dig = 0;
333  int lowtime = 999999;
334  /* for(mapit = lowest_hightime.begin(); mapit != lowest_hightime.end(); mapit++){
335  if(mapit->second < lowtime){
336  lowest_dig = mapit->first;
337  lowtime = mapit->second;
338  }
339  }*/
340 
341  lowest_dig = TEventTime::GetBestDigitizer();
342  lowtime = lowest_hightime.find(lowest_dig)->second;
343 
344  midvshigh->Print();
345  printf("The lowest digitizer is 0x%04x\n", lowest_dig);
346  printf("***** High time shifts *******\n");
347  for(mapit = lowest_hightime.begin(); mapit != lowest_hightime.end(); mapit++) {
348  if(mapit->first == lowest_dig) {
349  continue;
350  }
351  printf("0x%04x:\t %d \t %lf sec\n", mapit->first, mapit->second - lowtime,
352  static_cast<double>((static_cast<int64_t>(mapit->second - lowtime)) * (1<<28)) / 1.0E8);
353  // Calculate the shift to the first event in all digitizers
354  TEventTime::correctionmap.find(mapit->first)->second =
355  ((static_cast<uint64_t>(mapit->second - lowtime)) * (1<<28));
356  }
357  printf("********************\n");
358 
359  midvshigh->Write();
360  midvshigh->Delete();
361 }
362 
363 void GetRoughTimeDiff(std::vector<TEventTime*>* eventQ)
364 {
365  // We want the MIDAS time stamps to still be the way we index these events, but we want to index on low time stamps
366  // next
367  printf(DBLUE "Looking for rough time differences...\n" RESET_COLOR);
368 
369  auto* roughlist = new TList;
370  // These first four are for looking to see if high time-stamp reset
371 
372  std::map<uint32_t, bool> keep_filling;
373  std::map<uint32_t, int>::iterator mapit;
374  for(mapit = TEventTime::digmap.begin(); mapit != TEventTime::digmap.end(); mapit++) {
375  // TH1F *roughhist = new TH1F(Form("rough_0x%04x",mapit->first),Form("rough_0x%04x",mapit->first), 6E7,-3E8,3E8);
376  auto* roughhist =
377  new TH1D(Form("rough_0x%04x", mapit->first), Form("rough_0x%04x", mapit->first), 3E7, -3E8, 3E8);
378  roughhist->SetTitle(Form("rough_0x%04x against 0x%04x", mapit->first, TEventTime::GetBestDigitizer()));
379  roughlist->Add(roughhist);
380  keep_filling[mapit->first] = true;
381  }
382 
383  // The "best digitizer" is set when we fill the event Q
384  printf(DYELLOW "Using the best digitizer 0x%04x\n" RESET_COLOR, TEventTime::GetBestDigitizer());
385 
386  TH1D* fillhist; // This pointer is useful later to clean up a lot of messiness
387 
388  std::vector<TEventTime*>::iterator hit1;
389  std::vector<TEventTime*>::iterator hit2;
390  const int range = 5000;
391  int event1count = 0;
392  for(hit1 = (eventQ->begin()); hit1 != eventQ->end(); hit1++) { // This steps hit1 through the eventQ
393  // We want to have the first hit be in the "good digitizer"
394  if(event1count % 75000 == 0) {
395  printf("Processing Event %d /%lu \r", event1count, eventQ->size());
396  }
397  fflush(stdout);
398  event1count++;
399 
400  if(((*hit1)->Digitizer() == 0) && ((*hit1)->DetectorType() > 1)) {
401  continue;
402  }
403 
404  if((*hit1)->Digitizer() != TEventTime::GetBestDigitizer()) {
405  continue;
406  }
407 
408  int64_t time1 = static_cast<int64_t>((*hit1)->GetTimeStamp());
409 
410  if(event1count > range) {
411  hit2 = hit1 - range;
412  } else {
413  hit2 = eventQ->begin();
414  }
415  // Now that we have the best digitizer, we can start looping through the events
416  int event2count = 0;
417  while((hit2 != eventQ->end()) && (event2count < 2 * range)) {
418 
419  if(((*hit2)->Digitizer() == 0) && ((*hit2)->DetectorType() > 1)) {
420  ++hit2;
421  continue;
422  }
423  if(hit1 == hit2) {
424  ++hit2;
425  continue;
426  }
427  event2count++;
428  uint32_t digitizer = (*hit2)->Digitizer();
429  if(keep_filling[digitizer]) {
430  fillhist =
431  dynamic_cast<TH1D*>(roughlist->At((*hit2)->DigIndex())); // This is where that pointer comes in handy
432  int64_t time2 = static_cast<int64_t>((*hit2)->GetTimeStamp()) -
433  TEventTime::correctionmap.find((*hit2)->Digitizer())->second;
434  Int_t bin = static_cast<Int_t>(time2 - time1);
435 
436  if((fillhist->FindBin(bin) > 0) && (fillhist->FindBin(bin) < fillhist->GetNbinsX())) {
437  fillhist->Fill(bin);
438  }
439  }
440  ++hit2;
441  }
442  }
443 
444  for(mapit = TEventTime::digmap.begin(); mapit != TEventTime::digmap.end(); mapit++) {
445  if(mapit->first == TEventTime::GetBestDigitizer()) {
446  continue;
447  }
448  fillhist = dynamic_cast<TH1D*>(roughlist->At(mapit->second));
449  std::cout<<static_cast<int64_t>(fillhist->GetBinCenter(fillhist->GetMaximumBin()))<<std::endl;
450  TEventTime::correctionmap.find(mapit->first)->second +=
451  static_cast<int64_t>(fillhist->GetBinCenter(fillhist->GetMaximumBin()));
452  }
453 
454  printf("***** Rough time shifts *******\n");
455  std::map<uint32_t, int64_t>::iterator cit;
456  for(cit = TEventTime::correctionmap.begin(); cit != TEventTime::correctionmap.end(); cit++) {
457  if(cit->first == TEventTime::GetBestDigitizer()) {
458  printf("0x%04x:\t BEST\n", cit->first);
459  } else {
460 #ifdef OS_DARWIN
461  printf("0x%04x:\t %lld\n", cit->first, cit->second);
462 #else
463  printf("0x%04x:\t %ld\n", cit->first, cit->second);
464 #endif
465  }
466  }
467  printf("********************\n");
468 
469  roughlist->Print();
470  roughlist->Write();
471  roughlist->Delete();
472 }
473 
474 void GetTimeDiff(std::vector<TEventTime*> * eventQ)
475 {
476  // We want the MIDAS time stamps to still be the way we index these events, but we want to index on low time
477  // stamps next
478  printf(DBLUE "Looking for final time differences...\n" RESET_COLOR);
479 
480  auto* list = new TList;
481  // These first four are for looking to see if high time-stamp reset
482 
483  std::map<uint32_t, int>::iterator mapit;
484  for(mapit = TEventTime::digmap.begin(); mapit != TEventTime::digmap.end(); mapit++) {
485  auto* hist =
486  new TH1D(Form("timediff_0x%04x", mapit->first), Form("timediff_0x%04x", mapit->first), 1000, -500, 500);
487  hist->SetTitle(Form("timediff_0x%04x Against 0x%04x", mapit->first, TEventTime::GetBestDigitizer()));
488  list->Add(hist);
489  }
490 
491  // The "best digitizer" is set when we fill the event Q
492  printf(DYELLOW "Using the best digitizer 0x%04x\n" RESET_COLOR, TEventTime::GetBestDigitizer());
493 
494  TH1D* fillhist; // This pointer is useful later to clean up a lot of messiness
495 
496  std::vector<TEventTime*>::iterator hit1;
497  std::vector<TEventTime*>::iterator hit2;
498  int event1count = 0;
499  const int range = 2000;
500  for(hit1 = eventQ->begin(); hit1 != eventQ->end(); hit1++) { // This steps hit1 through the eventQ
501  // We want to have the first hit be in the "good digitizer"
502  if(event1count % 75000 == 0) {
503  printf("Processing Event %d / %lu \r", event1count, eventQ->size());
504  }
505  fflush(stdout);
506 
507  event1count++;
508  // We need to make sure that that if we have a digitizer of 0, we have a detector type of 1
509  if((*hit1)->Digitizer() == 0 && (*hit1)->DetectorType() > 1) {
510  continue;
511  }
512 
513  if((*hit1)->Digitizer() != TEventTime::GetBestDigitizer()) {
514  continue;
515  }
516 
517  int64_t time1 = static_cast<int64_t>((*hit1)->GetTimeStamp());
518 
519  if(event1count > range) {
520  hit2 = hit1 - range;
521  } else {
522  hit2 = eventQ->begin();
523  }
524  // Now that we have the best digitizer, we can start looping through the events
525  int event2count = 0;
526  while((hit2 != eventQ->end()) && (event2count < range * 2)) {
527  event2count++;
528  // We need to make sure that that if we have a digitizer of 0, we have a detector type of 1
529  if(((*hit2)->Digitizer() == 0) && ((*hit2)->DetectorType() > 1)) {
530  hit2++;
531  continue;
532  }
533 
534  if(hit1 != hit2) {
535  // uint32_t digitizer = (*hit2)->Digitizer();
536  fillhist =
537  dynamic_cast<TH1D*>(list->At((*hit2)->DigIndex())); // This is where that pointer comes in handy
538  int64_t time2 = static_cast<int64_t>((*hit2)->GetTimeStamp()) -
539  TEventTime::correctionmap.find((*hit2)->Digitizer())->second;
540  if((time2 - time1 < 2147483647) &&
541  (time2 - time1 > -2147483647)) { // Make sure we are casting this to 32 bit properly
542  Int_t bin = static_cast<Int_t>(time2 - time1);
543  fillhist->Fill(bin);
544  }
545  }
546  hit2++;
547  }
548  }
549  for(mapit = TEventTime::digmap.begin(); mapit != TEventTime::digmap.end(); mapit++) {
550  if(mapit->first == TEventTime::GetBestDigitizer()) {
551  continue;
552  }
553  fillhist = dynamic_cast<TH1D*>(list->At(mapit->second));
554  auto* spec = new TSpectrum();
555  spec->Search(fillhist);
556  double peak = spec->GetPositionX()[0];
557  std::cout<<static_cast<int64_t>(floor(peak + 0.5))<<std::endl;
558  TEventTime::correctionmap.find(mapit->first)->second += static_cast<int64_t>(floor(peak + 0.5));
559  // fillhist->Draw();
560  }
561 
562  printf("***** Rough time shifts *******\n");
563  std::map<uint32_t, int64_t>::iterator cit;
564  for(cit = TEventTime::correctionmap.begin(); cit != TEventTime::correctionmap.end(); cit++) {
565  if(cit->first == TEventTime::GetBestDigitizer()) {
566  printf("0x%04x:\t BEST\n", cit->first);
567  } else {
568 #ifdef OS_DARWIN
569  printf("0x%04x:\t %lld\n", cit->first, cit->second);
570 #else
571  printf("0x%04x:\t %ld\n", cit->first, cit->second);
572 #endif
573  }
574  // printf("0x%04x:\t %lld\n",mapit->first,correction[mapit->second]);
575  }
576  printf("********************\n");
577 
578  list->Print();
579  list->Write();
580  list->Delete();
581 }
582 
583 bool ProcessEvent(const std::shared_ptr<TMidasEvent>& event, TMidasFile* outfile)
584 {
585  if(event->GetEventId() != 1) {
586  outfile->FillBuffer(event);
587  return false;
588  }
589  event->SetBankList();
590  // int size;
591  // int data[1024];
592 
593  void* ptr;
594 
595  int banksize = event->LocateBank(nullptr, "GRF2", &ptr);
596  int bank = 2;
597  if(banksize == 0) {
598  banksize = event->LocateBank(nullptr, "GRF1", &ptr);
599  bank = 1;
600  }
601  uint32_t type = 0xffffffff;
602  uint32_t value = 0xffffffff;
603 
604  uint32_t dettype = 0;
605  uint32_t chanadd = 0;
606 
607  unsigned int timelow = 0;
608  unsigned int timehigh = 0;
609 
610  uint64_t time = 0;
611 
612  for(int x = 0; x < banksize; x++) {
613  value = *(reinterpret_cast<int*>(ptr) + x);
614  type = value & 0xf0000000;
615 
616  switch(type) {
617  case 0x80000000:
618  switch(bank) {
619  case 1: // header format from before May 2015 experiments
620  // Sets:
621  // The number of filters
622  // The Data Type
623  // Number of Pileups
624  // Channel Address
625  // Detector Type
626  if((value & 0xf0000000) != 0x80000000) {
627  return false;
628  }
629  chanadd = (value & 0x0003fff0) >> 4;
630  dettype = (value & 0x0000000f);
631 
632  // if(frag-DetectorType==2)
633  // frag->ChannelAddress += 0x8000;
634  break;
635  case 2:
636  // Sets:
637  // The number of filters
638  // The Data Type
639  // Number of Pileups
640  // Channel Address
641  // Detector Type
642  if((value & 0xf0000000) != 0x80000000) {
643  return false;
644  }
645  chanadd = (value & 0x000ffff0) >> 4;
646  dettype = (value & 0x0000000f);
647 
648  // if(frag-DetectorType==2)
649  // frag->ChannelAddress += 0x8000;
650  break;
651  default: printf("This bank not yet defined.\n"); break;
652  };
653  break;
654  case 0xa0000000: timelow = value & 0x0fffffff; break;
655  case 0xb0000000: timehigh = value & 0x00003fff; break;
656  };
657  }
658 
659  time = timehigh;
660  time = time<<28;
661  time |= timelow & 0x0fffffff;
662 
663  // if((chanadd&0x0000ff00) != TEventTime::GetBestDigitizer()){
664  // if((dettype<2) || ((chanadd&0xf) < 2) ){
665  if(dettype > 1 && ((chanadd & 0xF) > 1) && ((chanadd & 0xF00) > 1) && SplitMezz) {
666  time -= TEventTime::correctionmap.find((chanadd & 0x0000ff00) + 2)->second;
667  } else {
668  time -= TEventTime::correctionmap.find(chanadd & 0x0000ff00)->second;
669  }
670 
671  // }
672 
673  if(time > 0x3ffffffffff) {
674  time -= 0x3ffffffffff;
675  }
676 
677  // moving these inside the next switch, to account for doubly printed words.
678  // (hey, it happens.)
679  // -JKS, 14 January 2015
680  // timelow = time&0x0fffffff;
681  // timehigh = (time&0x3fff0000000) >> 28;
682 
683  // printf(DRED);
684  // event->Print("a");
685  // printf(RESET_COLOR);
686 
687  std::shared_ptr<TMidasEvent> copyevent = std::make_shared<TMidasEvent>(*event);
688  copyevent->SetBankList();
689 
690  banksize = copyevent->LocateBank(nullptr, "GRF2", &ptr);
691  if(banksize == 0) {
692  banksize = copyevent->LocateBank(nullptr, "GRF1", &ptr);
693  }
694 
695  for(int x = 0; x < banksize; x++) {
696  value = *(reinterpret_cast<int*>(ptr) + x);
697  type = value & 0xf0000000;
698 
699  switch(type) {
700  case 0xa0000000:
701  timelow = time & 0x0fffffff;
702  timelow += 0xa0000000;
703  *(reinterpret_cast<int*>(ptr) + x) = timelow;
704  break;
705  case 0xb0000000: {
706  timehigh = (time & 0x3fff0000000) >> 28;
707  int tempdead = value & 0xffffc000;
708  timehigh += tempdead;
709  *(reinterpret_cast<int*>(ptr) + x) = timehigh;
710  break;
711  }
712  };
713 
714  // printf( "0x%08x ",*((int*)ptr+x));
715  // if(x!=0 && (x%7)==0)
716  // printf("\n");
717  }
718  // printf("===================\n");
719 
720  outfile->FillBuffer(copyevent);
721 
722  // printf(DBLUE);
723  // copyevent.Print("a");
724  // printf(RESET_COLOR);
725  return true;
726 }
727 
729 {
730 
731  std::ifstream in(file->GetFilename(), std::ifstream::in | std::ifstream::binary);
732  in.seekg(0, std::ifstream::end);
733  long long filesize = in.tellg();
734  in.close();
735 
736  int bytes = 0;
737  long long bytesread = 0;
738 
739  UInt_t num_evt = 0;
740 
741  TStopwatch w;
742  w.Start();
743 
744  std::shared_ptr<TMidasEvent> event = std::make_shared<TMidasEvent>();
745 
746  while(true) {
747  bytes = file->Read(event);
748  if(bytes == 0) {
749  printf(DMAGENTA "\tfile: %s ended on %s" RESET_COLOR "\n", file->GetFilename(), file->GetLastError());
750  if(file->GetLastErrno() == -1) { // try to read some more...
751  continue;
752  }
753  break;
754  }
755  bytesread += bytes;
756 
757  switch(event->GetEventId()) {
758  case 0x8000:
759  printf("start of run\n");
760  file->FillBuffer(event);
761  printf(DGREEN);
762  event->Print();
763  printf(RESET_COLOR);
764  break;
765  case 0x8001:
766  printf("end of run\n");
767  printf(DRED);
768  event->Print();
769  printf(RESET_COLOR);
770  file->FillBuffer(event);
771  break;
772  default:
773  num_evt++;
774  ProcessEvent(event, file);
775  break;
776  };
777  if(num_evt % 5000 == 0) {
778  gSystem->ProcessEvents();
779  printf(HIDE_CURSOR " Events %d have processed %.2fMB/%.2f MB => %.1f MB/s " SHOW_CURSOR
780  "\r",
781  num_evt, (bytesread / 1000000.0), (filesize / 1000000.0), (bytesread / 1000000.0) / w.RealTime());
782  w.Continue();
783  }
784  }
785  printf("\n");
786 
787  file->WriteBuffer();
788 }
789 
790 void WriteCorrectionFile(int runnumber)
791 {
792  // I think I can directly write the map, but I was having a bit of trouble, so I'm using this Tree hack
793  char filename[64];
794  sprintf(filename, "corrections%05i.root", runnumber);
795  auto* corrfile = new TFile(filename, "RECREATE");
796 
797  // Just going to make a corrections map for now...it should be a map throughout....
798 
799  uint32_t address;
800  Long64_t correction;
801  auto* t = new TTree("correctiontree", "Tree with map");
802  t->Branch("address", &address);
803  t->Branch("correction", &correction);
804 
805  std::map<uint32_t, int64_t>::iterator it;
806  for(it = TEventTime::correctionmap.begin(); it != TEventTime::correctionmap.end(); it++) {
807  address = it->first;
808  correction = it->second;
809  t->Fill();
810  }
811  corrfile->Write();
812 
813  corrfile->Close();
814  delete corrfile;
815 }
816 
817 int CorrectionFile(int runnumber)
818 {
819  // I think I can directly write the map, but I was having a bit of trouble, so I'm using this Tree hack
820  char filename[64];
821  sprintf(filename, "corrections%05i.root", runnumber);
822  auto* corrfile = new TFile(filename, "READ");
823  if(!(corrfile->IsOpen())) {
824  delete corrfile;
825  return 0;
826  }
827 
828  printf(DGREEN "Found Correction File %s\n" RESET_COLOR, filename);
829 
830  TTree* t;
831  corrfile->GetObject("correctiontree", t);
832  TBranch* baddress = nullptr;
833  TBranch* bcorrection = nullptr;
834  uint32_t address;
835  Long64_t correction;
836  t->SetBranchAddress("address", &address, &baddress);
837  t->SetBranchAddress("correction", &correction, &bcorrection);
838 
839  int i = 0;
840  printf("Digitizer \t Correction\n");
841  while(true) {
842  Long64_t tentry = t->LoadTree(i++);
843  if(tentry < 0) {
844  break;
845  }
846  baddress->GetEntry(tentry);
847  bcorrection->GetEntry(tentry);
848  printf("0x%04x: \t\t %lld\n", address, correction);
849  TEventTime::correctionmap.insert(std::pair<uint32_t, int64_t>(address, correction));
850  }
851 
852  t->ResetBranchAddresses();
853  printf(DGREEN "Found %lu digitizers\n" RESET_COLOR, TEventTime::correctionmap.size());
854  corrfile->Close();
855  delete corrfile;
856 
857  return TEventTime::correctionmap.size();
858 }
859 
860 int main(int argc, char** argv)
861 {
862 
863  if(argc < 2) {
864  printf("Usage: ./offsetfix <input.mid> <output.mid> <y/n>(read correction file)\n");
865  return 1;
866  }
867  if(argv[1] == argv[2]) {
868  printf("ERROR: Cannot overwrite midas file %s\n", argv[1]);
869  }
870 
871  auto* midfile = new TMidasFile;
872  midfile->Open(argv[1]);
873  int runnumber = midfile->GetRunNumber();
874  int subrunnumber = midfile->GetSubRunNumber();
875  if(argc < 3) {
876  midfile->OutOpen(Form("fixrun%05d_%03d.mid", runnumber, subrunnumber));
877  } else {
878  midfile->OutOpen(argv[2]);
879  }
880  char filename[64];
881  if(subrunnumber > -1) {
882  sprintf(filename, "time_diffs%05i_%03i.root", runnumber, subrunnumber);
883  } else {
884  sprintf(filename, "time_diffs%05i.root", runnumber);
885  }
886  printf("Creating root outfile: %s\n", filename);
887 
888  int nDigitizers = 0;
889  if(argc > 3) {
890  if(strcmp(argv[3], "n") == 0) {
891  nDigitizers = 0;
892  } else {
893  nDigitizers = CorrectionFile(runnumber);
894  }
895  } else {
896  nDigitizers = CorrectionFile(runnumber);
897  }
898 
900 
901  if(nDigitizers == 0) {
902  auto* outfile = new TFile(filename, "RECREATE");
903  auto* eventQ = new std::vector<TEventTime*>;
904  QueueEvents(midfile, eventQ);
905  std::cout<<"Number of Digitizers Found: "<<TEventTime::digmap.size()<<std::endl;
906 
907  CheckHighTimeStamp(eventQ);
908  GetRoughTimeDiff(eventQ);
909  GetTimeDiff(eventQ);
910  WriteCorrectionFile(runnumber);
911  midfile->Close();
912  midfile->Open(argv[1]); // This seems like the easiest way to reset the file....
913  outfile->Close();
914  delete outfile;
915  }
916 
917  WriteEvents(midfile);
918 
919  // Have to do deleting on Q if we move to a next step of fixing the MIDAS File
920  midfile->Close();
921  midfile->OutClose();
922  delete midfile;
923 }
void GetRoughTimeDiff(std::vector< TEventTime *> *eventQ)
Definition: offsetfix.cxx:363
static std::map< uint32_t, bool > digset
Definition: offsetfix.cxx:169
TEventTime(std::shared_ptr< TMidasEvent > event)
Definition: offsetfix.cxx:33
unsigned long MidasTime()
Definition: offsetfix.cxx:126
const char * GetFilename() const override
Get the name of this file.
Definition: TMidasFile.h:61
#define DRED
Definition: Globals.h:17
static std::map< uint32_t, int64_t > correctionmap
Definition: offsetfix.cxx:170
#define RESET_COLOR
Definition: Globals.h:4
static void OrderDigitizerMap()
Definition: offsetfix.cxx:145
static std::map< int, int > digmap
Definition: offsetfind.cxx:102
void PrintError(const std::shared_ptr< TMidasEvent > &event, int frags, bool verb)
Definition: offsetfix.cxx:191
#define DGREEN
Definition: Globals.h:16
static std::map< uint32_t, int > digmap
Definition: offsetfix.cxx:168
int GetSubRunNumber() override
Definition: TMidasFile.cxx:636
unsigned int TimeStampHigh()
Definition: offsetfix.cxx:124
static int best_dig
Definition: offsetfind.cxx:104
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
static uint32_t GetBestDigitizer()
Definition: offsetfix.cxx:156
Bool_t SplitMezz
Definition: offsetfix.cxx:29
static unsigned long GetLowestMidasTime()
Definition: offsetfix.cxx:162
#define DYELLOW
Definition: Globals.h:15
int DigIndex()
Definition: offsetfix.cxx:164
int digitizernum
Definition: offsetfind.cxx:113
const char * GetLastError() const
Get error text for the last file error.
Definition: TMidasFile.h:63
int QueueEvents(TMidasFile *infile, std::vector< TEventTime *> *eventQ)
Definition: offsetfix.cxx:203
int GriffinDataToFragment(uint32_t *data, int size, EBank bank, unsigned int midasSerialNumber=0, time_t midasTime=0)
uint32_t chanadd
Definition: offsetfix.cxx:180
#define HIDE_CURSOR
Definition: Globals.h:31
static int64_t lowest_time
Definition: offsetfind.cxx:105
static int NDigitizers()
Definition: offsetfix.cxx:154
Reader for MIDAS .mid files.
Definition: TMidasFile.h:32
bool ProcessEvent(const std::shared_ptr< TMidasEvent > &event, TMidasFile *outfile)
Definition: offsetfix.cxx:583
void WriteCorrectionFile(int runnumber)
Definition: offsetfix.cxx:790
bool WriteBuffer()
Definition: TMidasFile.cxx:498
static unsigned long low_timemidas
Definition: offsetfind.cxx:103
int main(int argc, char **argv)
Definition: offsetfix.cxx:860
static int GetBestDigitizer()
Definition: offsetfind.cxx:96
void SetDigitizer()
Definition: offsetfind.cxx:78
unsigned int timelow
Definition: offsetfix.cxx:176
static uint64_t GetLowestTime()
Definition: offsetfix.cxx:166
void WriteEvents(TMidasFile *file)
Definition: offsetfix.cxx:728
uint64_t GetTimeStamp()
Definition: offsetfix.cxx:117
void CheckHighTimeStamp(std::vector< TEventTime *> *eventQ)
Definition: offsetfix.cxx:284
void GetTimeDiff(std::vector< TEventTime *> *eventQ)
Definition: offsetfix.cxx:474
int Read(std::shared_ptr< TRawEvent > event) override
Read one event from the file.
Definition: TMidasFile.cxx:330
~TEventTime()=default
void FillBuffer(const std::shared_ptr< TMidasEvent > &midasEvent, Option_t *opt="")
Definition: TMidasFile.cxx:458
int CorrectionFile(int runnumber)
Definition: offsetfix.cxx:817
int64_t GetTimeStamp()
Definition: offsetfind.cxx:63
bool Open(const char *filename) override
Open input file.
Definition: TMidasFile.cxx:116
uint32_t Digitizer()
Definition: offsetfix.cxx:128
#define DMAGENTA
Definition: Globals.h:19
unsigned int timehigh
Definition: offsetfix.cxx:177
TH1D * hist
Definition: UserFillObj.h:3
#define SHOW_CURSOR
Definition: Globals.h:32
int GetLastErrno() const
Get error value for the last file error.
Definition: TMidasFile.h:62
bool SuppressErrors() const
Definition: TGRSIOptions.h:73
unsigned long timemidas
Definition: offsetfind.cxx:110
int DetectorType()
Definition: offsetfix.cxx:130
int Digitizer()
Definition: offsetfind.cxx:74
#define DBLUE
Definition: Globals.h:14