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