AnitaDataset.cxx
1 #include "AnitaDataset.h"
2 #include "UsefulAnitaEvent.h"
3 #include "RawAnitaHeader.h"
4 #include "Adu5Pat.h"
5 #include "PrettyAnitaHk.h"
6 #include "CalibratedAnitaEvent.h"
7 #include "TTreeIndex.h"
8 #include "AnitaVersion.h"
9 #include <math.h>
10 #include "TFile.h"
11 #include "TTree.h"
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include "TurfRate.h"
15 #include "TMath.h"
16 #include "SurfHk.h"
17 #include "TROOT.h"
18 #include "TEventList.h"
19 #include "TCut.h"
20 #include "TMutex.h"
21 #include "TruthAnitaEvent.h"
22 #include <dirent.h>
23 #include <algorithm>
24 #include "TEnv.h"
25 #include <iostream>
26 #include <fstream>
27 #include <sstream>
28 #include "AnitaConventions.h"
29 
30 
31 // from runToEvA*.txt
32 static std::vector<UInt_t> firstEvents[NUM_ANITAS+1];
33 static std::vector<UInt_t> lastEvents[NUM_ANITAS+1];
34 static std::vector<Int_t> runs[NUM_ANITAS+1];
35 
36 
37 static std::vector<UInt_t> hiCalEventNumbers[NUM_ANITAS+1];
38 
39 static TFile* fHiCalGpsFile;
40 static TTree* fHiCalGpsTree;
41 static Double_t fHiCalLon;
42 static Double_t fHiCalLat;
43 static Double_t fHiCalAlt;
44 static Int_t fHiCalUnixTime;
45 
46 
47 bool AnitaDataset::isKnownHiCalEvent(UInt_t eventNumber, Int_t anita){
48 
49  // @todo do this for other ANITAs
50  if(anita!=3){
51  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", only implemented for ANITA-3, not ANITA-" << anita << ", returning false!" << std::endl;
52  return false;
53  }
54 
55  if(hiCalEventNumbers[anita].size()==0){
56  static TMutex m;
57  m.Lock();
58 
59  const char* installDir = getenv("ANITA_UTIL_INSTALL_DIR");
60 
61  //hiCal1EventNumbers13Jan2018.txt
62  //hiCal1EventNumbers.txt
63  TString fileName = TString::Format("%s/share/anitaCalib/hiCal1EventNumbers13Jan2018.txt", installDir, anita);
64  std::ifstream hiCalEventListFile(fileName.Data());
65  if (!hiCalEventListFile.is_open()) {
66  std::cerr << "Error in " << __PRETTY_FUNCTION__ << " couldn't find " << fileName << std::endl;
67  }
68 
69  Int_t hcRun, isDirect, isPaired;
70  UInt_t hcEventNumber;
71 
72  while(!hiCalEventListFile.eof()){
73  // hiCalEventListFile >> hcRun >> hcEventNumber >> isDirect >> isPaired;
74  hiCalEventListFile >> hcRun >> hcEventNumber >> isDirect;
75  hiCalEventNumbers[anita].push_back(hcEventNumber);
76  }
77 
78  m.UnLock();
79  }
80 
81  return (std::find(hiCalEventNumbers[anita].begin(), hiCalEventNumbers[anita].end(), eventNumber)!=hiCalEventNumbers[anita].end());
82 }
83 
84 
85 
86 
87 
88 void AnitaDataset::loadRunToEv(int anita){
89  static TMutex m;
90  m.Lock();
91 
92  const char* installDir = getenv("ANITA_UTIL_INSTALL_DIR");
93 
94  TString fileName = TString::Format("%s/share/anitaCalib/runToEvA%d.txt", installDir, anita);
95  std::ifstream runToEv(fileName.Data());
96  if (!runToEv.is_open()) {
97  std::cerr << "Error in " << __PRETTY_FUNCTION__ << " couldn't find " << fileName << std::endl;
98  }
99  else{
100  const int hopefullyMoreThanEnoughRuns = 500;
101  runs[anita].reserve(hopefullyMoreThanEnoughRuns);
102  firstEvents[anita].reserve(hopefullyMoreThanEnoughRuns);
103  lastEvents[anita].reserve(hopefullyMoreThanEnoughRuns);
104 
105  int run, evLow,evHigh;
106  // int elem = 0;
107  while (runToEv >> run >> evLow >> evHigh){
108  runs[anita].push_back(run);
109  firstEvents[anita].push_back(evLow);
110  lastEvents[anita].push_back(evHigh);
111  // std::cout << anita << "\t" << elem << "\t" << runs[anita][elem] << "\t" << firstEvents[anita][elem] << "\t" << lastEvents[anita][elem] << std::endl;
112  // elem++;
113  }
114  // std::cout << "Finished reading in " << fileName << "!" << std::endl;
115  runToEv.close();
116  }
117  m.UnLock();
118 }
119 
120 
121 
122 
123 static bool checkIfFileExists(const char * file)
124 {
125  return access(file, R_OK) !=-1;
126 }
127 
128 static const char * checkIfFilesExist(int num, ...)
129 {
130 
131  va_list args;
132  va_start(args, num);
133 
134  for (int i = 0; i < num; i++)
135  {
136  const char * f = va_arg(args, const char *);
137 
138  if (checkIfFileExists(f))
139  {
140  return f;
141  }
142 
143  }
144 
145  va_end(args);
146 
147  return 0;
148 }
149 
150 static const char anita_root_data_dir_env[] = "ANITA_ROOT_DATA";
151 static const char anita_versioned_root_data_dir_env[] = "ANITA%d_ROOT_DATA";
152 static const char mc_root_data_dir[] = "ANITA_MC_DATA";
153 
154 const char * AnitaDataset::getDataDir(DataDirectory dir)
155 {
156  int version = (int) dir;
157 
158  //if anita version number is defined in argument
159  if (version > 0)
160  {
161 
162  char env_string[sizeof(anita_versioned_root_data_dir_env)+20];
163  sprintf(env_string,anita_versioned_root_data_dir_env, version);
164  const char * tryme = getenv(env_string);
165  if (!tryme)
166  {
167  fprintf(stderr,"%s, not defined, will try %s\n",env_string, anita_root_data_dir_env);
168  }
169  else return tryme;
170  }
171 
172  //if monte carlo
173  if (version == 0)
174  {
175  const char * tryme = getenv(mc_root_data_dir);
176  if (!tryme)
177  {
178  fprintf(stderr,"%s, not defined, will try %s\n",mc_root_data_dir, anita_root_data_dir_env);
179  }
180  else return tryme;
181  }
182 
183  //if version argument is default (-1)
184  //if ANITA_ROOT_DATA exists return that, otherwise return what AnitaVersion thinks it should be
185  if (const char * tryme = getenv(anita_root_data_dir_env))
186  {
187  return tryme;
188  }
189  else
190  {
191  char env_string[sizeof(anita_versioned_root_data_dir_env)+20];
192  sprintf(env_string,anita_versioned_root_data_dir_env, AnitaVersion::get());
193  if (const char *tryme = getenv(env_string)) {
194  return tryme;
195  }
196  else {
197  fprintf(stderr,"%s, not defined, please define it!", anita_root_data_dir_env);
198  return 0;
199  }
200  }
201 
202 
203 }
204 
205 
206 AnitaDataset::AnitaDataset(int run, bool decimated, WaveCalType::WaveCalType_t cal, DataDirectory version, BlindingStrategy strategy)
207  :
208  fHeadTree(0), fHeader(0),
209  fEventTree(0), fCalEvent(0), fRawEvent(0), fUseful(0),
210  fGpsTree(0), fGps(0),
211  fHkTree(0), fHk(0),
212  fTurfTree(0), fTurf(0),
213  fSurfTree(0), fSurf(0),
214  fTruthTree(0), fTruth(0),
215  fCutList(0), fRandy()
216 {
217  fRcoInfo = 0;
218  fClockPhiInfo = 0;
219  fTempFactorInfo = 0;
220  fClockProblemInfo = 0;
221  fClockSpikeInfo = 0;
222  fRFSpikeInfo = 0;
223  fHaveCalibInfo = false;
224  setCalType(cal);
225  setStrategy(strategy);
226  currRun = run;
227  loadRun(run, decimated, version);
228  loadedBlindTrees = false;
229  zeroBlindPointers();
230  loadBlindTrees(); // want this to come after opening the data files to try to have correct ANITA flight
231 }
232 
233 void AnitaDataset::unloadRun()
234 {
235 
236  for (unsigned i = 0; i < filesToClose.size(); i++)
237  {
238  filesToClose[i]->Close();
239  delete filesToClose[i];
240  }
241 
242  fHeadTree = 0;
243  fDecimatedHeadTree = 0;
244  fEventTree = 0;
245  fHkTree = 0;
246  fGpsTree = 0;
247  fTurfTree = 0;
248  fSurfTree = 0;
249  fCalibInfoTree = 0;
250  fRunLoaded = false;
251  filesToClose.clear();
252 
253  if (fCutList)
254  {
255  delete fCutList;
256  fCutList = 0;
257  }
258 
259 }
260 
261 
262 Adu5Pat * AnitaDataset::gps(bool force_load)
263 {
264 
265  if (fHaveGpsEvent)
266  {
267  if (fGpsTree->GetReadEntry() != fWantedEntry || force_load)
268  {
269  fGpsTree->GetEntry(fWantedEntry);
270  }
271  }
272  else
273  {
274  if (fGpsDirty || force_load)
275  {
276  //try one that matches realtime
277  int gpsEntry = fGpsTree->GetEntryNumberWithBestIndex(round(header()->triggerTime + header()->triggerTimeNs / 1e9));
278  int offset = 0;
279  fGpsTree->GetEntry(gpsEntry);
280  while (fGps->attFlag == 1 && abs(offset) < 30)
281  {
282  offset = offset >= 0 ? -(offset+1) : -offset;
283  if (gpsEntry + offset < 0) continue;
284  if (gpsEntry + offset >= fGpsTree->GetEntries()) continue;
285  fGpsTree->GetEntry(gpsEntry+offset);
286  }
287  if (fGps->attFlag==1)
288  {
289  fprintf(stderr,"WARNING: Could not find good GPS within 30 entries... reverting to closest bad one\n");
290  fGpsTree->GetEntry(gpsEntry);
291  }
292 
293  fGpsDirty = false;
294  }
295 
296  }
297 
298  return fGps;
299 
300 }
301 
303 {
304  if (fEventTree->GetReadEntry() != fWantedEntry || force_load)
305  {
306  fEventTree->GetEntry(fWantedEntry);
307  fCalDirty = true;
308  }
309 
310  if (!fHaveCalibFile && fCalDirty)
311  {
312  if (!fCalEvent)
313  {
314  fCalEvent = new CalibratedAnitaEvent;
315  }
316  fCalEvent->~CalibratedAnitaEvent();
317  fCalEvent = new (fCalEvent) CalibratedAnitaEvent(useful());
318  fCalDirty = false;
319  }
320 
321  return fCalEvent;
322 }
323 
324 
325 PrettyAnitaHk * AnitaDataset::hk(bool force_load)
326 {
327  if (fHkTree->GetReadEntry() != fWantedEntry || force_load)
328  {
329  fHkTree->GetEntry(fWantedEntry);
330  }
331  return fHk;
332 }
333 
334 
336 {
337  if (fDecimated)
338  {
339  if (force_load)
340  {
341  fDecimatedHeadTree->GetEntry(fDecimatedEntry);
342  }
343  }
344  else if ((fHeadTree->GetReadEntry() != fWantedEntry || force_load))
345  {
346  fHeadTree->GetEntry(fWantedEntry);
347  }
348 
349 
350 
351  if(theStrat & kInsertedVPolEvents){
352  Int_t fakeTreeEntry = needToOverwriteEvent(AnitaPol::kVertical, fHeader->eventNumber);
353  if(fakeTreeEntry > -1){
354  overwriteHeader(fHeader, AnitaPol::kVertical, fakeTreeEntry);
355  }
356  }
357 
358 
359  if(theStrat & kInsertedHPolEvents){
360  Int_t fakeTreeEntry = needToOverwriteEvent(AnitaPol::kHorizontal, fHeader->eventNumber);
361  if(fakeTreeEntry > -1){
362  overwriteHeader(fHeader, AnitaPol::kHorizontal, fakeTreeEntry);
363  }
364  }
365 
366  return fHeader;
367 }
368 
369 
370 RawAnitaEvent * AnitaDataset::raw(bool force_load)
371 {
372  if (fEventTree->GetReadEntry() != fWantedEntry || force_load)
373  {
374  fEventTree->GetEntry(fWantedEntry);
375  }
376  return fHaveCalibFile ? fCalEvent :
377  fRawEvent ? fRawEvent : fUseful;
378 }
379 
380 
382 {
383 
384  if (fEventTree->GetReadEntry() != fWantedEntry || force_load)
385  {
386 
387  fEventTree->GetEntry(fWantedEntry);
388  fUsefulDirty = fCalEvent || fRawEvent; //if reading UsefulEvents, then no need to do anything
389  }
390 
391  if (fUsefulDirty)
392  {
393  if (!fUseful)
394  {
395  fUseful = new UsefulAnitaEvent;
396  }
397 
398  fUseful->~UsefulAnitaEvent();
399 
400  if (fHaveCalibFile)
401  {
402  new (fUseful) UsefulAnitaEvent(fCalEvent, fCalType);
403  }
404  else if (fRawEvent)
405  {
406  if(fHaveCalibInfo) new (fUseful) UsefulAnitaEvent(fRawEvent, fCalType, header(), RcoInfo(), ClockPhiInfo(), TempFactorInfo(), ClockProblemInfo(), ClockSpikeInfo(), RFSpikeInfo());
407  else new (fUseful) UsefulAnitaEvent(fRawEvent, fCalType, header());
408  }
409  fUsefulDirty = false;
410  }
411 
412  // This is the blinding implementation for the header
413 
414  if(theStrat & kInsertedVPolEvents){
415  Int_t fakeTreeEntry = needToOverwriteEvent(AnitaPol::kVertical, fUseful->eventNumber);
416  if(fakeTreeEntry > -1){
417  overwriteEvent(fUseful, AnitaPol::kVertical, fakeTreeEntry);
418  }
419  }
420 
421 
422  if(theStrat & kInsertedHPolEvents){
423  Int_t fakeTreeEntry = needToOverwriteEvent(AnitaPol::kHorizontal, fUseful->eventNumber);
424  if(fakeTreeEntry > -1){
425  overwriteEvent(fUseful, AnitaPol::kHorizontal, fakeTreeEntry);
426  }
427  }
428 
429 
430  if ((theStrat & kRandomizePolarity) && maybeInvertPolarity(fUseful->eventNumber))
431  {
432  // std::cerr << "Inverting event " << fUseful->eventNumber << std::endl;
433  for(int surf=0; surf < NUM_SURF; surf++){
434  for(int chan=0; chan < RFCHAN_PER_SURF; chan++){
435  int chanIndex = surf*NUM_CHAN + chan;
436  for(int samp=0; samp < NUM_SAMP; samp++){
437  fUseful->fVolts[chanIndex][samp] *= -1;
438  fUseful->data[chanIndex][samp] *= -1; // do the pedestal subtracted data too
439  }
440  }
441  }
442  }
443 
444  return fUseful;
445 }
446 
447 // Calling this function on it's own is just for unblinding, please use honestly
448 Bool_t AnitaDataset::maybeInvertPolarity(UInt_t eventNumber){
449  // add additional check here for clarity, in case people call this function on it's own?
450  if((theStrat & kRandomizePolarity) > 0){
451  fRandy.SetSeed(eventNumber); // set seed from event number, makes this deterministic regardless of order events are processed
452  Double_t aboveZeroFiftyPercentOfTheTime = fRandy.Uniform(-1, 1); // uniformly distributed random number between -1 and 1
453  return (aboveZeroFiftyPercentOfTheTime < 0);
454  }
455  return false;
456 }
457 
458 int AnitaDataset::getEntry(int entryNumber)
459 {
460 
461  //invalidate the indices
462  fIndex = -1;
463  fCutIndex=-1;
464 
465 
466  if (entryNumber < 0 || entryNumber >= (fDecimated ? fDecimatedHeadTree : fHeadTree)->GetEntries())
467  {
468  fprintf(stderr,"Requested entry %d too big or small!\n", entryNumber);
469  }
470  else
471  {
472  (fDecimated ? fDecimatedEntry : fWantedEntry) = entryNumber;
473  if (fDecimated)
474  {
475  fDecimatedHeadTree->GetEntry(fDecimatedEntry);
476  fWantedEntry = fHeadTree->GetEntryNumberWithIndex(fHeader->eventNumber);
477 
478  }
479  fUsefulDirty = true;
480  fCalDirty = true;
481  fGpsDirty = true;
482  fTurfDirty = true;
483  fSurfDirty = true;
484  }
485 
486 
487  // use the header to set the ANITA version
488  AnitaVersion::setVersionFromUnixTime(header()->realTime);
489 
490  return fDecimated ? fDecimatedEntry : fWantedEntry;
491 }
492 
493 
494 int AnitaDataset::getEvent(int eventNumber, bool quiet)
495 {
496 
497  int entry = (fDecimated ? fDecimatedHeadTree : fHeadTree)->GetEntryNumberWithIndex(eventNumber);
498 
499  if (entry < 0 && (eventNumber < fHeadTree->GetMinimum("eventNumber") || eventNumber > fHeadTree->GetMaximum("eventNumber")))
500  {
501  int run = getRunContainingEventNumber(eventNumber);
502  if(run > 0)
503  {
504  loadRun(run, fDecimated,datadir);
505  if (!quiet) fprintf(stderr, "changed run to %d\n", run);
506  getEvent(eventNumber, quiet);
507  }
508  }
509  else if (entry < 0 )
510  {
511  if (!quiet) fprintf(stderr,"WARNING: event %lld not found in header tree\n", fWantedEntry);
512  if (fDecimated)
513  {
514  if (!quiet) fprintf(stderr,"\tWe are using decimated tree, so maybe that's why?\n");
515  }
516  return -1;
517  }
518 
519  getEntry(entry);
520  return fDecimated ? fDecimatedEntry : fWantedEntry;
521 }
522 
524 {
525 
526  unloadRun();
527 
528 
529 
530  if (fHeader)
531  delete fHeader;
532 
533  if (fRcoInfo)
534  delete fRcoInfo;
535 
536  if (fClockPhiInfo)
537  delete fClockPhiInfo;
538 
539  if (fTempFactorInfo)
540  delete fTempFactorInfo;
541 
542  if (fCalEvent)
543  delete fCalEvent;
544 
545  if (fUseful)
546  {
547  delete fUseful;
548  }
549 
550  if (fRawEvent)
551  delete fRawEvent;
552 
553  if (fGps)
554  delete fGps;
555 
556  if (fHk)
557  delete fHk;
558 
559  if (fTurf)
560  delete fTurf;
561 
562  if (fSurf)
563  delete fSurf;
564 
565  if (fTruth)
566  delete fTruth;
567 
568  if (fCutList)
569  delete fCutList;
570 
571  // // Since we've set the directory to 0 for these,
572  // // ROOT won't delete them when the fBlindFile is closed
573  // // So we need to do it here.
574  // for(int pol=0; pol < AnitaPol::kNotAPol; pol++){
575  // if(fBlindHeadTree[pol]){
576  // delete fBlindHeadTree[pol];
577  // fBlindHeadTree[pol] = NULL;
578  // }
579  // if(fBlindEventTree[pol]){
580  // delete fBlindEventTree[pol];
581  // fBlindEventTree[pol] = NULL;
582  // }
583  // if(fBlindHeader[pol]){
584  // delete fBlindHeader[pol];
585  // fBlindHeader[pol] = NULL;
586  // }
587  // if(fBlindEvent[pol]){
588  // delete fBlindEvent[pol];
589  // fBlindEvent[pol] = NULL;
590  // }
591  // }
592 
593  if(fBlindFile){
594  fBlindFile->Close();
595  delete fBlindFile;
596  }
597 
598 
599 }
600 
601 bool AnitaDataset::loadRun(int run, bool dec, DataDirectory dir)
602 {
603 
604  datadir = dir;
605 
606  // stop loadRun() changing the ROOT directory
607  // in case you book histograms or trees after instantiating AnitaDataset
608  const TString theRootPwd = gDirectory->GetPath();
609 
610  fDecimated = dec;
611  fIndices = 0;
612 
613  currRun = run;
614 
615  unloadRun();
616  fWantedEntry = 0;
617 
618  const char * data_dir = getDataDir(dir);
619 
620  //seems like a good idea
621 
622  int version = (int) dir;
623  if (version>0) AnitaVersion::set(version);
624 
625  //if decimated, try to load decimated tree
626 
627  if (fDecimated)
628  {
629 
630  fDecimatedEntry = 0;
631  TString fname = TString::Format("%s/run%d/decimatedHeadFile%d.root", data_dir, run, run);
632  if (checkIfFileExists(fname.Data()))
633  {
634  TFile * f = new TFile(fname.Data());
635  filesToClose.push_back(f);
636  fDecimatedHeadTree = (TTree*) f->Get("headTree");
637  fDecimatedHeadTree->BuildIndex("eventNumber");
638  fDecimatedHeadTree->SetBranchAddress("header",&fHeader);
639  fIndices = ((TTreeIndex*) fDecimatedHeadTree->GetTreeIndex())->GetIndex();
640  }
641  else
642  {
643  fprintf(stderr," Could not find decimated head file for run %d, giving up!\n", run);
644  fRunLoaded = false;
645  return false;
646  }
647  }
648  else
649  {
650  fDecimatedHeadTree = 0;
651  }
652  // try to load timed header file
653 
654  // For telemetered crap
655  TString fname0 = TString::Format("%s/run%d/eventHeadFile%d.root", data_dir, run, run);
656  TString fname1 = TString::Format("%s/run%d/timedHeadFile%dOfflineMask.root", data_dir, run, run);
657  TString fname2 = TString::Format("%s/run%d/timedHeadFile%d.root", data_dir, run, run);
658  TString fname3 = TString::Format("%s/run%d/headFile%d.root", data_dir, run, run);
659  TString fname4 = TString::Format("%s/run%d/SimulatedAnitaHeadFile%d.root", data_dir, run, run);
660 
661  bool simulated = false;
662 
663  if (const char * the_right_file = checkIfFilesExist(5, fname0.Data(), fname1.Data(), fname2.Data(), fname3.Data(), fname4.Data()))
664  {
665 
666  if (strcasestr(the_right_file,"SimulatedAnitaHeadFile")) simulated = true;
667 
668  fprintf(stderr,"Using head file: %s\n",the_right_file);
669  TFile * f = new TFile(the_right_file);
670  filesToClose.push_back(f);
671  fHeadTree = (TTree*) f->Get("headTree");
672  }
673  else
674  {
675  fprintf(stderr,"Could not find head file for run %d, giving up!\n", run);
676  fRunLoaded = false;
677  return false;
678  }
679 
680  if (!fDecimated) fHeadTree->SetBranchAddress("header",&fHeader);
681 
682  fHeadTree->BuildIndex("eventNumber");
683 
684  if (!fDecimated) fIndices = ((TTreeIndex*) fHeadTree->GetTreeIndex())->GetIndex();
685 
686  //try to load gps event file
687  TString fname = TString::Format("%s/run%d/gpsEvent%d.root", data_dir, run, run);
688  fname2 = TString::Format("%s/run%d/SimulatedAnitaGpsFile%d.root", data_dir, run, run);
689  if (const char * the_right_file = checkIfFilesExist(2,fname.Data(),fname2.Data()))
690  {
691  TFile * f = new TFile(the_right_file);
692  filesToClose.push_back(f);
693  fGpsTree = (TTree*) f->Get("adu5PatTree");
694  fHaveGpsEvent = true;
695 
696  }
697  // load gps file instead
698  else
699  {
700  fname = TString::Format("%s/run%d/gpsFile%d.root", data_dir, run, run);
701  if (const char * the_right_file = checkIfFilesExist(1, fname.Data()))
702  {
703  TFile * f = new TFile(the_right_file);
704  filesToClose.push_back(f);
705  fGpsTree = (TTree*) f->Get("adu5PatTree");
706  fGpsTree->BuildIndex("realTime");
707  fHaveGpsEvent = false;
708  }
709  else
710  {
711  fprintf(stderr,"Could not find gps file for run %d, giving up!\n",run);
712  fRunLoaded = false;
713  return false;
714  }
715  }
716 
717  fGpsTree->SetBranchAddress("pat",&fGps);
718 
719 
720  //try to load calibrated event file
721 
722  fname = TString::Format("%s/run%d/calibratedEventFile%d.root", data_dir, run, run);
723  fname2 = TString::Format("%s/run%d/calEventFile%d.root", data_dir, run, run);
724  fname3 = TString::Format("%s/run%d/SimulatedAnitaEventFile%d.root", data_dir, run, run);
725  if (const char * the_right_file = checkIfFilesExist(2, fname.Data(), fname2.Data()))
726  {
727  TFile * f = new TFile(the_right_file);
728  filesToClose.push_back(f);
729  fEventTree = (TTree*) f->Get("eventTree");
730  fHaveCalibFile = true;
731  fHaveCalibInfo = false;
732  fEventTree->SetBranchAddress("event",&fCalEvent);
733  }
734  else
735  {
736  fname = TString::Format("%s/run%d/eventFile%d.root", data_dir, run, run);
737  fname2 = TString::Format("%s/run%d/calibratedEventInfo%d.root", data_dir, run, run);
738  if (checkIfFileExists(fname.Data()))
739  {
740  TFile * f = new TFile(fname.Data());
741  filesToClose.push_back(f);
742  fEventTree = (TTree*) f->Get("eventTree");
743  fHaveCalibFile = false;
744  fHaveCalibInfo = false;
745  fEventTree->SetBranchAddress("event",&fRawEvent);
746  if(checkIfFileExists(fname2.Data()))
747  {
748  TFile * f2 = new TFile(fname2.Data());
749  filesToClose.push_back(f2);
750  fCalibInfoTree = (TTree*) f2->Get("calInfoTree");
751  fHaveCalibInfo = true;
752  fCalibInfoTree->SetBranchAddress("rcoArray", &fRcoInfo);
753  fCalibInfoTree->SetBranchAddress("clockPhiArray", &fClockPhiInfo);
754  fCalibInfoTree->SetBranchAddress("tempFactorGuesses", &fTempFactorInfo);
755  fCalibInfoTree->SetBranchAddress("clockProblem", &fClockProblemInfo);
756  fCalibInfoTree->SetBranchAddress("clockSpike", &fClockSpikeInfo);
757  fCalibInfoTree->SetBranchAddress("rfSpike", &fRFSpikeInfo);
758  }
759  }
760  else
761  {
762  if (checkIfFileExists(fname3.Data()))
763  {
764  TFile * f = new TFile(fname3.Data());
765  filesToClose.push_back(f);
766  fEventTree = (TTree*) f->Get("eventTree");
767  fHaveCalibFile = false;
768  fHaveCalibInfo = false;
769  fEventTree->SetBranchAddress("event",&fUseful);
770  } else {
771  fprintf(stderr,"Could not find event file for run %d, giving up!\n",run);
772  fRunLoaded = false;
773  return false;
774  }
775  }
776  }
777 
778  //try to load hk file
779  fname = TString::Format("%s/run%d/prettyHkFile%d.root", data_dir, run, run);
780  if (checkIfFileExists(fname.Data()))
781  {
782  TFile * f = new TFile(fname.Data());
783  filesToClose.push_back(f);
784  fHkTree = (TTree*) f->Get("prettyHkTree");
785  fHkTree->SetBranchAddress("hk",&fHk);
786  }
787  else
788  {
789  fHkTree = 0;
790  fprintf(stderr,"Could not find hk file for run %d, no HK will be available!\n",run);
791  }
792 
793 
794 
795  // try to load turf file
796  fname = TString::TString::Format("%s/run%d/turfRateFile%d.root",data_dir,run,run);
797  if (checkIfFileExists(fname.Data()))
798  {
799 
800  TFile * f = new TFile(fname.Data());
801  filesToClose.push_back(f);
802  fTurfTree = (TTree*) f->Get("turfRateTree");
803  fTurfTree->BuildIndex("realTime");
804  fTurfTree->SetBranchAddress("turf",&fTurf);
805  }
806  else
807  {
808  fTurfTree = 0;
809  fprintf(stderr,"Could not find TurfRate file for run %d, no Turf will be available!\n",run);
810  }
811 
812  // try to load surf file
813  fname = TString::TString::Format("%s/run%d/surfHkFile%d.root",data_dir,run,run);
814  if (checkIfFileExists(fname.Data()))
815  {
816 
817  TFile * f = new TFile(fname.Data());
818  filesToClose.push_back(f);
819  fSurfTree = (TTree*) f->Get("surfHkTree");
820  fSurfTree->BuildIndex("payloadTime","payloadTimeUs");
821  fSurfTree->SetBranchAddress("surf",&fSurf);
822  }
823  else
824  {
825  fSurfTree = 0;
826  fprintf(stderr,"Could not find SurfHK file for run %d, no SURF will be available!\n",run);
827  }
828 
829  //try to load truth
830  if (simulated)
831  {
832  fname = TString::TString::Format("%s/run%d/SimulatedAnitaTruthFile%d.root",data_dir,run,run);
833  if (checkIfFileExists(fname.Data()))
834  {
835  TFile * f = new TFile(fname.Data());
836  filesToClose.push_back(f);
837  fTruthTree = (TTree*) f->Get("truthAnitaTree");
838  fTruthTree->SetBranchAddress("truth",&fTruth);
839  }
840  }
841 
842  //load the first entry
843  getEntry(0);
844 
845 
846  fRunLoaded = true;
847 
848  // stop loadRun() changing the ROOT directory
849  // in case you book histograms or trees after instantiating AnitaDataset
850  gDirectory->cd(theRootPwd);
851 
852  return true;
853 }
854 
855 
857 {
858  if (fIndex < 0)
859  {
860  fIndex = TMath::BinarySearch(N(), fIndices, fDecimated ? fDecimatedEntry : fWantedEntry);
861  }
862 
863  if (fIndex >0)
864  fIndex--;
865 
866  return nthEvent(fIndex);
867 }
868 
869 
871 {
872  return nthEvent(0);
873 }
874 
876 {
877  return nthEvent(N()-1);
878 }
879 
881 {
882  int ret = getEntry(fIndices[n]);
883  fIndex = n;
884  return ret;
885 }
886 
887 
888 
890 {
891  if (fIndex < 0)
892  {
893  fIndex = TMath::BinarySearch(N(), fIndices, fDecimated ? fDecimatedEntry : fWantedEntry);
894  }
895 
896  if (fIndex < N() -1)
897  fIndex++;
898 
899  return nthEvent(fIndex);
900 }
901 
902 int AnitaDataset::N() const
903 {
904  TTree* t = fDecimated? fDecimatedHeadTree : fHeadTree;
905  return t ? t->GetEntries() : 0;
906 }
907 
909 {
910  if (fIndex < 0)
911  {
912  fIndex = TMath::BinarySearch(N(), fIndices, fDecimated ? fDecimatedEntry : fWantedEntry);
913  }
914 
915  while(fIndex >= 0)
916  {
917  fIndex--;
918  if(fIndex < 0)
919  {
920  loadRun(currRun - 1);
921  fIndex = N() - 1;
922  }
923  fHeadTree->GetEntry(fIndex);
924  if((fHeader->trigType&1) == 0) break;
925  }
926 
927  return nthEvent(fIndex);
928 }
929 
931 {
932  if (fIndex < 0)
933  {
934  fIndex = TMath::BinarySearch(N(), fIndices, fDecimated ? fDecimatedEntry : fWantedEntry);
935  }
936 
937  while(fIndex <= N()-1)
938  {
939  fIndex++;
940  if(fIndex == N())
941  {
942  loadRun(currRun + 1);
943  fIndex = 0;
944  }
945  fHeadTree->GetEntry(fIndex);
946  if((fHeader->trigType&1) == 0) break;
947  }
948 
949  return nthEvent(fIndex);
950 }
951 
952 
953 int AnitaDataset::setCut(const TCut & cut)
954 {
955  if (fCutList)
956  {
957  delete fCutList;
958  }
959 
960  int n = (fDecimated? fDecimatedHeadTree : fHeadTree)->Draw(">>evlist1",cut,"goff");
961  fCutList = (TEventList*) gDirectory->Get("evlist1");
962  return n;
963 }
964 
965 
966 
968 {
969 
970  if (fCutList)
971  {
972  return fCutList->GetN();
973  }
974 
975  return -1;
976 }
977 
979 {
980  return nthInCut(0);
981 }
982 
984 {
985  return nthInCut(NInCut()-1);
986 }
987 
988 
990 {
991  if (!fCutList)
992  return -1;
993  int ret = getEntry(fCutList->GetEntry(i));
994 
995  fCutIndex = i;
996  return ret;
997 }
998 
1000 {
1001  if (!fCutList) return -1;
1002  if (fCutIndex < 0)
1003  {
1004  fCutIndex = TMath::BinarySearch(NInCut(), fCutList->GetList(), (Long64_t) (fDecimated ? fDecimatedEntry : fWantedEntry));
1005  }
1006 
1007  if (fCutIndex < NInCut() - 1)
1008  {
1009  fCutIndex++;
1010  }
1011  return nthInCut(fCutIndex);
1012 
1013 }
1014 
1016 {
1017  if (!fCutList) return -1;
1018  if (fCutIndex < 0)
1019  {
1020  fCutIndex = TMath::BinarySearch(NInCut(), fCutList->GetList(),(Long64_t) (fDecimated ? fDecimatedEntry : fWantedEntry));
1021  }
1022 
1023  if (fCutIndex > 0)
1024  {
1025  fCutIndex--;
1026  }
1027  return nthInCut(fCutIndex);
1028 
1029 }
1030 
1031 int AnitaDataset::setPlaylist(const char* playlist)
1032 {
1033  if (!fPlaylist.empty())
1034  {
1035  fPlaylist.clear();
1036  }
1037 
1038  int n = loadPlaylist(playlist);
1039  return n;
1040 }
1041 
1043 {
1044 
1045  if (!fPlaylist.empty())
1046  {
1047  return fPlaylist.size();
1048  }
1049 
1050  return -1;
1051 }
1052 
1054 {
1055  return nthInPlaylist(0);
1056 }
1057 
1059 {
1060  return nthInPlaylist(NInPlaylist()-1);
1061 }
1062 
1063 
1065 {
1066  if (fPlaylist.empty()) return -1;
1067  fPlaylistIndex = i;
1068  if(getCurrRun() != getPlaylistRun()) loadRun(getPlaylistRun());
1069  int ret = getEvent(getPlaylistEvent());
1070 
1071  return ret;
1072 }
1073 
1075 {
1076  if (fPlaylist.empty()) return -1;
1077  if(fPlaylistIndex < 0) fPlaylistIndex = 0;
1078  if (fPlaylistIndex < NInPlaylist() - 1)
1079  {
1080  fPlaylistIndex++;
1081  }
1082  return nthInPlaylist(fPlaylistIndex);
1083 
1084 }
1085 
1087 {
1088  if (fPlaylist.empty()) return -1;
1089  if(fPlaylistIndex < 0) fPlaylistIndex = 0;
1090  if (fPlaylistIndex > 0)
1091  {
1092  fPlaylistIndex--;
1093  }
1094  return nthInPlaylist(fPlaylistIndex);
1095 
1096 }
1097 
1098 
1100 
1101  // TMutex();
1102 
1103  int anita = AnitaVersion::get();
1104 
1105  // read in runToEvA*.txt list only once
1106  if(runs[anita].size()==0){
1107  loadRunToEv(anita);
1108  // If still don't have data, loadRunToEv should have printed something
1109  // There's a problem, so just return -1
1110  if(runs[anita].size()==0){
1111  return -1;
1112  }
1113  }
1114 
1115  // Binary search to find first event number which is greater than ev
1116  std::vector<UInt_t>::iterator it = std::upper_bound(firstEvents[anita].begin(), firstEvents[anita].end(), ev);
1117 
1118  // Here we convert the iterator to an integer relative to first element, so we can read matching elements in the other array
1119  // And -1 so we have the last element isn't greater than ev.
1120  int elem = (it - firstEvents[anita].begin()) - 1;
1121 
1122  // std::cout << anita << "\t" << elem << "\t" << runs[anita][elem] << "\t" << firstEvents[anita][elem] << "\t" << lastEvents[anita][elem] << std::endl;
1123 
1124  int run = -1; // signifies error, we will set correctly after doing bounds checking...
1125 
1126  if(elem < 0){ // then we are lower than the first event in the first run
1127  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", for ANITA " << AnitaVersion::get()
1128  << " eventNumber " << ev << " is smaller than then first event in the lowest run! "
1129  << "(eventNumber " << firstEvents[anita][0] << " in run " << runs[anita][0] << ")"
1130  << std::endl;
1131  }
1132  else if(ev > lastEvents[anita].back()){ // then we are higher than the last event in the last run
1133  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", for ANITA " << AnitaVersion::get()
1134  << " eventNumber " << ev << " is larger than then last event I know about in the highest run! "
1135  << "(eventNumber " << lastEvents[anita].back() << " in run " << runs[anita].back() << ")"
1136  << std::endl;
1137  }
1138  else if(ev > lastEvents[anita][elem]){ // then we are in the eventNumber gap between two runs
1139  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", for ANITA " << AnitaVersion::get()
1140  << " eventNumber " << ev << " is larger than then last event in run " << runs[anita][elem]
1141  << " (" << lastEvents[anita][elem] << "), but smaller than the first event in run "
1142  << runs[anita][elem+1] << " (" << firstEvents[anita][elem+1] << ")" << std::endl;
1143  }
1144  else{
1145  // preliminarily set run
1146  run = runs[anita][elem];
1147  }
1148 
1149  return run;
1150 }
1151 
1152 int AnitaDataset::loadPlaylist(const char* playlist)
1153 {
1154  std::vector<std::vector<long> > runEv;
1155  int rN;
1156  int evN;
1157  std::ifstream pl(playlist);
1158  pl >> evN;
1159 
1160  // Simulated events
1161  // As iceMC generates random eventNumbers, simulated data event numbers aren't linked to actual event numbers, so ignore evN restrictions
1162  Bool_t simulatedData = false; // must be set to false for non-simulated data
1163  if(simulatedData == true)
1164  {
1165  std::cout << "Using simulated data! Turn off the simulatedData variable if you are working with real data." << std::endl;
1166  rN = evN;
1167  pl >> evN;
1168  std::vector<long> Row;
1169  Row.push_back(rN);
1170  Row.push_back(evN);
1171  runEv.push_back(Row);
1172  while(pl >> rN >> evN)
1173  {
1174  std::vector<long> newRow;
1175  newRow.push_back(rN);
1176  newRow.push_back(evN);
1177  runEv.push_back(newRow);
1178  }
1179 
1180  }
1181  else
1182  {
1183  if(evN < 400)
1184  {
1185  rN = evN;
1186  pl >> evN;
1187  std::vector<long> Row;
1188  Row.push_back(rN);
1189  Row.push_back(evN);
1190  runEv.push_back(Row);
1191  while(pl >> rN >> evN)
1192  {
1193  std::vector<long> newRow;
1194  newRow.push_back(rN);
1195  newRow.push_back(evN);
1196  runEv.push_back(newRow);
1197  }
1198  }
1199  else
1200  {
1201  rN = getRunContainingEventNumber(evN);
1202  if(rN == -1)
1203  {
1204  fprintf(stderr, "Something is wrong with your playlist\n");
1205  return -1;
1206  }
1207  std::vector<long> Row;
1208  Row.push_back(rN);
1209  Row.push_back(evN);
1210  runEv.push_back(Row);
1211  while(pl >> evN)
1212  {
1213  rN = getRunContainingEventNumber(evN);
1214  if(rN == -1)
1215  {
1216  fprintf(stderr, "Something is wrong with your playlist\n");
1217  return -1;
1218  }
1219  std::vector<long> newRow;
1220  newRow.push_back(rN);
1221  newRow.push_back(evN);
1222  runEv.push_back(newRow);
1223  }
1224  }
1225  }
1226  fPlaylist = runEv;
1227  return runEv.size();
1228 }
1229 
1230 TurfRate* AnitaDataset::turf(bool force_reload)
1231 {
1232 
1233  if (!fTurfTree) return 0;
1234 
1235  if (fTurfDirty || force_reload)
1236  {
1237  int entry = fTurfTree->GetEntryNumberWithBestIndex(round(header()->triggerTime + header()->triggerTimeNs /1e9 ) );
1238  fTurfTree->GetEntry(entry);
1239  fTurfDirty = false;
1240  }
1241 
1242  return fTurf;
1243 }
1244 
1245 SurfHk* AnitaDataset::surf(bool force_reload)
1246 {
1247 
1248  if (!fSurfTree) return 0;
1249 
1250  if (fSurfDirty || force_reload)
1251  {
1252  int entry = fSurfTree->GetEntryNumberWithBestIndex(header()->payloadTime, header()->payloadTimeUs);
1253  fSurfTree->GetEntry(entry);
1254  fSurfDirty = false;
1255  }
1256 
1257  return fSurf;
1258 }
1259 
1260 
1262 {
1263 
1264  if (!fTruthTree) return 0;
1265  if (fTruthTree->GetReadEntry() != fWantedEntry || force_reload)
1266  {
1267  fTruthTree->GetEntry(fWantedEntry);
1268  }
1269 
1270  return fTruth;
1271 }
1272 
1273 std::vector<Double_t>* AnitaDataset::RcoInfo(bool force_reload)
1274 {
1275  if (!fCalibInfoTree) return 0;
1276  if (fCalibInfoTree->GetReadEntry() != fWantedEntry || force_reload)
1277  {
1278  fCalibInfoTree->GetEntry(fWantedEntry);
1279  }
1280 
1281  return fRcoInfo;
1282 }
1283 
1284 std::vector<Double_t>* AnitaDataset::ClockPhiInfo(bool force_reload)
1285 {
1286  if (!fCalibInfoTree) return 0;
1287  if (fCalibInfoTree->GetReadEntry() != fWantedEntry || force_reload)
1288  {
1289  fCalibInfoTree->GetEntry(fWantedEntry);
1290  }
1291 
1292  return fClockPhiInfo;
1293 }
1294 
1295 std::vector<Double_t>* AnitaDataset::TempFactorInfo(bool force_reload)
1296 {
1297  if (!fCalibInfoTree) return 0;
1298  if (fCalibInfoTree->GetReadEntry() != fWantedEntry || force_reload)
1299  {
1300  fCalibInfoTree->GetEntry(fWantedEntry);
1301  }
1302 
1303  return fTempFactorInfo;
1304 }
1305 
1306 Int_t AnitaDataset::ClockProblemInfo(bool force_reload)
1307 {
1308  if (!fCalibInfoTree) return 0;
1309  if (fCalibInfoTree->GetReadEntry() != fWantedEntry || force_reload)
1310  {
1311  fCalibInfoTree->GetEntry(fWantedEntry);
1312  }
1313 
1314  return fClockProblemInfo;
1315 }
1316 
1317 Int_t AnitaDataset::ClockSpikeInfo(bool force_reload)
1318 {
1319  if (!fCalibInfoTree) return 0;
1320  if (fCalibInfoTree->GetReadEntry() != fWantedEntry || force_reload)
1321  {
1322  fCalibInfoTree->GetEntry(fWantedEntry);
1323  }
1324 
1325  return fClockSpikeInfo;
1326 }
1327 
1328 Int_t AnitaDataset::RFSpikeInfo(bool force_reload)
1329 {
1330  if (!fCalibInfoTree) return 0;
1331  if (fCalibInfoTree->GetReadEntry() != fWantedEntry || force_reload)
1332  {
1333  fCalibInfoTree->GetEntry(fWantedEntry);
1334  }
1335 
1336  return fRFSpikeInfo;
1337 }
1338 
1339 struct run_info
1340 {
1341 
1342  double start_time;
1343  double stop_time;
1344  int run;
1345 
1346  bool operator< (const run_info & other) const
1347  {
1348  return stop_time < other.stop_time;
1349  }
1350 
1351 
1352 };
1353 
1354 static std::vector<run_info> run_times[NUM_ANITAS+1];
1355 
1356 static TMutex run_at_time_mutex;
1358 {
1359 
1360  int version= AnitaVersion::getVersionFromUnixTime(t);
1361 
1362  if (!run_times[version].size())
1363  {
1364  TLockGuard lock(&run_at_time_mutex);
1365  if (!run_times[version].size())
1366  {
1367 
1368  // load from cache
1369  bool found_cache = false;
1370 
1371 
1372  TString cache_file1= TString::Format("%s/timerunmap_%d.txt", getenv("ANITA_CALIB_DIR"),version) ;
1373  TString cache_file2= TString::Format("%s/share/anitaCalib/timerunmap_%d.txt", getenv("ANITA_UTIL_INSTALL_DIR"),version) ;
1374  TString cache_file3= TString::Format("./calib/timerunmap_%d.txt",version);
1375 
1376  const char * cache_file_name = checkIfFilesExist(3, cache_file1.Data(), cache_file2.Data(), cache_file3.Data());
1377 
1378  if (checkIfFileExists(cache_file_name))
1379  {
1380 
1381  found_cache = true;
1382  FILE * cf = fopen(cache_file_name,"r");
1383  run_info r;
1384  while(!feof(cf))
1385  {
1386  fscanf(cf,"%d %lf %lf\n", &r.run, &r.start_time, &r.stop_time);
1387  run_times[version].push_back(r);
1388  }
1389  fclose(cf);
1390  }
1391 
1392 
1393  if (!found_cache)
1394  {
1395  //temporarily suppress errors and disable recovery
1396  int old_level = gErrorIgnoreLevel;
1397  int recover = gEnv->GetValue("TFile.Recover",1);
1398  gEnv->SetValue("TFile.Recover",1);
1399  gErrorIgnoreLevel = kFatal;
1400 
1401  const char * data_dir = getDataDir((DataDirectory)version);
1402  fprintf(stderr,"Couldn't find run file map. Regenerating %s from header files in %s\n", cache_file_name,data_dir);
1403  DIR * dir = opendir(data_dir);
1404 
1405  while(struct dirent * ent = readdir(dir))
1406  {
1407  int run;
1408  if (sscanf(ent->d_name,"run%d",&run))
1409  {
1410 
1411  TString fname1 = TString::Format("%s/run%d/timedHeadFile%d.root", data_dir, run, run);
1412  TString fname2 = TString::Format("%s/run%d/headFile%d.root", data_dir, run, run);
1413 
1414  if (const char * the_right_file = checkIfFilesExist(2, fname1.Data(), fname2.Data()))
1415  {
1416  TFile f(the_right_file);
1417  TTree * t = (TTree*) f.Get("headTree");
1418  if (t)
1419  {
1420  run_info ri;
1421  ri.run = run;
1422  //TODO do this to nanosecond precision
1423  ri.start_time= t->GetMinimum("triggerTime");
1424  ri.stop_time = t->GetMaximum("triggerTime") + 1;
1425  run_times[version].push_back(ri);
1426  }
1427  }
1428  }
1429  }
1430 
1431  gErrorIgnoreLevel = old_level;
1432  gEnv->SetValue("TFile.Recover",recover);
1433  std::sort(run_times[version].begin(), run_times[version].end());
1434 
1435  TString try2write;
1436  try2write.Form("./calib/timerunmap_%d.txt",version);
1437  FILE * cf = fopen(try2write.Data(),"w");
1438 
1439  if (cf)
1440  {
1441  const std::vector<run_info> & v = run_times[version];
1442  for (unsigned i = 0; i < v.size(); i++)
1443  {
1444  printf("%d %0.9f %0.9f\n", v[i].run, v[i].start_time, v[i].stop_time);
1445  fprintf(cf,"%d %0.9f %0.9f\n", v[i].run, v[i].start_time, v[i].stop_time);
1446  }
1447 
1448  fclose(cf);
1449  }
1450 
1451  }
1452  }
1453  }
1454 
1455  run_info test;
1456  test.start_time =t;
1457  test.stop_time =t;
1458  const std::vector<run_info> & v = run_times[version];
1459  std::vector<run_info>::const_iterator it = std::upper_bound(v.begin(), v.end(), test);
1460 
1461  if (it == v.end()) return -1;
1462  if (it == v.begin() && (*it).start_time >t) return -1;
1463  return (*it).run;
1464 }
1465 
1466 void AnitaDataset::zeroBlindPointers(){
1467  loadedBlindTrees = false;
1468 
1469  for(int pol=0; pol < AnitaPol::kNotAPol; pol++){
1470  fBlindHeadTree[pol] = NULL;
1471  fBlindEventTree[pol] = NULL;
1472  fBlindHeader[pol] = NULL;
1473  fBlindEvent[pol] = NULL;
1474  }
1475 
1476  fBlindFile = NULL;
1477 }
1478 
1479 TString AnitaDataset::getDescription(BlindingStrategy strat){
1480 
1481  TString description = "Current strategy: ";
1482 
1483  if(strat == kNoBlinding){
1484  description = "No blinding. ";
1485  }
1486 
1487  if(strat & kInsertedVPolEvents){
1488  description += "VPol events inserted. ";
1489  }
1490 
1491  if(strat & kInsertedHPolEvents){
1492  description += "HPol events inserted. ";
1493  }
1494 
1495  if(strat & kRandomizePolarity){
1496  description += "Polarity randomized. ";
1497  }
1498 
1499 
1500  return description;
1501 }
1502 
1503 AnitaDataset::BlindingStrategy AnitaDataset::setStrategy(BlindingStrategy newStrat){
1504  theStrat = newStrat;
1505  return theStrat;
1506 }
1507 
1508 
1509 AnitaDataset::BlindingStrategy AnitaDataset::getStrategy(){
1510  return theStrat;
1511 }
1512 
1513 void AnitaDataset::loadBlindTrees() {
1514 
1515  // std::cout << __PRETTY_FUNCTION__ << std::endl;
1516 
1517  /* for now, just A3 */
1518  if(!loadedBlindTrees && AnitaVersion::get()==3){
1519 
1520  fBlindFile = NULL;
1521 
1522  char calibDir[FILENAME_MAX];
1523  char fileName[FILENAME_MAX];
1524  char *calibEnv=getenv("ANITA_CALIB_DIR");
1525  if(!calibEnv) {
1526  char *utilEnv=getenv("ANITA_UTIL_INSTALL_DIR");
1527  if(!utilEnv){
1528  sprintf(calibDir,"calib");
1529  }
1530  else{
1531  sprintf(calibDir,"%s/share/anitaCalib",utilEnv);
1532  }
1533  }
1534  else {
1535  strncpy(calibDir,calibEnv,FILENAME_MAX);
1536  }
1537 
1538  // std::cout << __PRETTY_FUNCTION__ << ": here 2" << std::endl;
1539 
1540 
1541  // these are the fake events, that will be inserted in place of some min bias events
1542  sprintf(fileName, "%s/insertedDataFile.root", calibDir);
1543 
1544  TString theRootPwd = gDirectory->GetPath();
1545  // std::cerr << "Before opening blind file" << "\t" << gDirectory->GetPath() << std::endl;
1546  fBlindFile = TFile::Open(fileName);
1547  // std::cerr << "After opening blind file" << "\t" << gDirectory->GetPath() << std::endl;
1548 
1549  if(fBlindFile){
1550 
1551  TString polPrefix[AnitaPol::kNotAPol];
1552  polPrefix[AnitaPol::kHorizontal] = "HPol";
1553  polPrefix[AnitaPol::kVertical] = "VPol";
1554 
1555  for(int pol=0; pol < AnitaPol::kNotAPol; pol++){
1556 
1557  TString headTreeName = polPrefix[pol] + "HeadTree";
1558  fBlindHeadTree[pol] = (TTree*) fBlindFile->Get(headTreeName);
1559 
1560  TString eventTreeName = polPrefix[pol] + "EventTree";
1561  fBlindEventTree[pol] = (TTree*) fBlindFile->Get(eventTreeName);
1562 
1563  // If you found the data then prepare for data reading
1564  if(fBlindHeadTree[pol] && fBlindEventTree[pol]){
1565 
1566  fBlindHeadTree[pol]->SetBranchAddress("header", &fBlindHeader[pol]);
1567  fBlindEventTree[pol]->SetBranchAddress("event", &fBlindEvent[pol]);
1568  }
1569  else{
1570  // complain if you can't find the data
1571  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ": "
1572  << "fBlindHeadTree[" << pol << "] = " << fBlindHeadTree[pol] << ", "
1573  << "fBlindEventTree[" << pol << "] = " << fBlindEventTree[pol] << std::endl;
1574  }
1575  }
1576  }
1577  else{
1578  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ": "
1579  << "Unable to find " << fileName << " for inserted event blinding." << std::endl;
1580  }
1581 
1582  // std::cout << __PRETTY_FUNCTION__ << ": here 3" << std::endl;
1583 
1584  // these are the min bias event numbers to be overwritten, with the entry in the fakeEventTree
1585  // that is used to overwrite the event
1586  sprintf(fileName,"%s/anita%dOverwrittenEventInfo.txt",calibDir, AnitaVersion::get());
1587  std::ifstream overwrittenEventInfoFile(fileName);
1588  char firstLine[180];
1589  overwrittenEventInfoFile.getline(firstLine,179);
1590  UInt_t overwrittenEventNumber;
1591  Int_t fakeTreeEntry, pol;
1592  Int_t numEvents = 0;
1593  while(overwrittenEventInfoFile >> overwrittenEventNumber >> fakeTreeEntry >> pol){
1594  eventsToOverwrite.push_back(overwrittenEventNumber);
1595  fakeTreeEntries.push_back(fakeTreeEntry);
1597  polarityOfEventToInsert.push_back(thePol);
1598  // std::cout << overwrittenEventNumber << "\t" << fakeTreeEntry << "\t" << thePol << std::endl;
1599  numEvents++;
1600  }
1601  if(numEvents==0){
1602  std::cerr << "Warning in " << __FILE__ << std::endl;
1603  std::cerr << "Unable to find overwrittenEventInfo" << std::endl;
1604  }
1605 
1606  gDirectory->cd(theRootPwd);
1607 
1608  // const char* treeNames[4] = {"HPolHeadTree", "HPolEventTree", "VPolHeadTree", "VPolEventTree"};
1609  // for(int i=0; i < 4; i++){
1610  // std::cerr << "after close file " << "\t" << gROOT->FindObject(treeNames[i]) << std::endl;
1611  // }
1612 
1613  loadedBlindTrees = true;
1614  }
1615 
1616 // gROOT->cd(0);
1617  // std::cout << __PRETTY_FUNCTION__ << ": here 4" << std::endl;
1618 
1619 }
1620 
1621 
1622 
1623 void AnitaDataset::loadHiCalGps() {
1624  if(!fHiCalGpsFile){
1625 
1626  const TString theRootPwd = gDirectory->GetPath();
1627 
1628  TString fName = TString::Format("%s/share/anitaCalib/H1b_GPS_time_interp.root", getenv("ANITA_UTIL_INSTALL_DIR"));
1629  fHiCalGpsFile = TFile::Open(fName);
1630  fHiCalGpsTree = (TTree*) fHiCalGpsFile->Get("Tpos");
1631 
1632  fHiCalGpsTree->BuildIndex("unixTime");
1633 
1634  fHiCalGpsTree->SetBranchAddress("longitude", &fHiCalLon);
1635  fHiCalGpsTree->SetBranchAddress("latitude", &fHiCalLat);
1636  fHiCalGpsTree->SetBranchAddress("altitude", &fHiCalAlt);
1637  fHiCalGpsTree->SetBranchAddress("unixTime", &fHiCalUnixTime);
1638 
1639  gDirectory->cd(theRootPwd);
1640  }
1641 }
1642 
1643 
1644 
1652 void AnitaDataset::hiCal(Double_t& longitude, Double_t& latitude, Double_t& altitude) {
1653  UInt_t realTime = fHeader ? fHeader->realTime : 0;
1654  hiCal(realTime, longitude, latitude, altitude);
1655 }
1656 
1657 
1658 
1667 void AnitaDataset::hiCal(UInt_t realTime, Double_t& longitude, Double_t& latitude, Double_t& altitude) {
1668  loadHiCalGps();
1669  Long64_t entry = fHiCalGpsTree->GetEntryNumberWithIndex(realTime);
1670 
1671  if(entry > 0){
1672  fHiCalGpsTree->GetEntry(entry);
1673  longitude = fHiCalLon;
1674  latitude = fHiCalLat;
1675  const double feetToMeters = 0.3048;
1676  altitude = fHiCalAlt*feetToMeters;
1677  }
1678  else{
1679  longitude = -9999;
1680  latitude = -9999;
1681  altitude = -9999;
1682  }
1683 }
1684 
1685 
1686 
1687 
1688 
1689 
1699 
1700  Int_t fakeTreeEntry = -1;
1701  for(UInt_t i=0; i < polarityOfEventToInsert.size(); i++){
1702  if(polarityOfEventToInsert.at(i)==pol && eventNumber == eventsToOverwrite.at(i)){
1703  fakeTreeEntry = fakeTreeEntries.at(i);
1704  break;
1705  }
1706  }
1707  return fakeTreeEntry;
1708 }
1709 
1710 void AnitaDataset::overwriteHeader(RawAnitaHeader* header, AnitaPol::AnitaPol_t pol, Int_t fakeTreeEntry){
1711 
1712  Int_t numBytes = fBlindHeadTree[pol]->GetEntry(fakeTreeEntry);
1713 
1714  if(numBytes <= 0){
1715  std::cerr << "Warning in " << __PRETTY_FUNCTION__ << ", I read " << numBytes << " from the blinding tree " << fBlindHeadTree[pol]->GetName()
1716  << ". This probably means the salting blinding is broken" << std::endl;
1717  }
1718 
1719  // Retain some of the header data for camouflage
1720  UInt_t realTime = header->realTime;
1721  UInt_t triggerTimeNs = header->triggerTimeNs;
1722  UInt_t eventNumber = header->eventNumber;
1723  Int_t run = header->run;
1724  Int_t trigNum = header->trigNum;
1725  UInt_t turfId = header->turfEventId;
1726 
1727  (*header) = (*fBlindHeader[pol]);
1728 
1729  header->realTime = realTime;
1730  header->triggerTimeNs = triggerTimeNs;
1731  header->eventNumber = eventNumber;
1732  header->run = run;
1733  header->trigNum = trigNum;
1734  header->turfEventId = turfId;
1735 
1736 }
1737 
1738 void AnitaDataset::overwriteEvent(UsefulAnitaEvent* useful, AnitaPol::AnitaPol_t pol, Int_t fakeTreeEntry){
1739 
1740  Int_t numBytes = fBlindEventTree[pol]->GetEntry(fakeTreeEntry);
1741  if(numBytes <= 0){
1742  std::cerr << "Warning in " << __PRETTY_FUNCTION__ << ", I read " << numBytes << " from the blinding tree " << fBlindEventTree[pol]->GetName()
1743  << ". This probably means the salting blinding is broken" << std::endl;
1744  }
1745 
1746 
1747  UInt_t eventNumber = useful->eventNumber;
1748  UInt_t surfEventIds[NUM_SURF] = {0};
1749  UChar_t wrongLabs[NUM_SURF*NUM_CHAN] = {0};
1750  UChar_t rightLabs[NUM_SURF*NUM_CHAN] = {0};
1751  for(int surf=0; surf < NUM_SURF; surf++){
1752  surfEventIds[surf] = useful->surfEventId[surf];
1753 
1754  for(int chan=0; chan < NUM_CHAN; chan++){
1755  const int chanIndex = surf*NUM_CHAN + chan;
1756  wrongLabs[chanIndex] = UChar_t(fBlindEvent[pol]->getLabChip(chanIndex));
1757  rightLabs[chanIndex] = UChar_t(useful->getLabChip(chanIndex));
1758  // std::cout << chanIndex << "\t" << chipIdFlags[chanIndex] << "\t" << (chipIdFlags[chanIndex] & 0x3) << std::endl;
1759  }
1760  }
1761 
1762  (*useful) = (*fBlindEvent[pol]);
1763 
1764  useful->eventNumber = eventNumber;
1765  for(int surf=0; surf < NUM_SURF; surf++){
1766  useful->surfEventId[surf] = surfEventIds[surf];
1767 
1768  // here we manually set the bits in the chipId flag that correspond to the lab chip
1769  // this ensures that as you click through magic display the LABS will still go A->B->C->D->A...
1770  for(int chan=0; chan < NUM_CHAN; chan++){
1771 
1772  const int chanIndex = surf*NUM_CHAN + chan;
1773  // std::cerr << useful->chipIdFlag[chanIndex] << "\t";
1774  useful->chipIdFlag[chanIndex] -= wrongLabs[chanIndex];
1775  // std::cerr << useful->chipIdFlag[chanIndex] << "\t";
1776  useful->chipIdFlag[chanIndex] += rightLabs[chanIndex];
1777  // std::cerr << useful->chipIdFlag[chanIndex] << std::endl;
1778 
1779 
1780  }
1781  }
1782 
1783 }
1784 
1785 
1786 
1787 
1788 
1789 
1790 
bool loadedBlindTrees
!< for deciding whether to do polarity flipping (eventNumber is used as seed)
Definition: AnitaDataset.h:400
int nthInCut(int i)
UInt_t eventNumber
Event number from software.
Definition: RawAnitaEvent.h:33
static int getRunAtTime(double t)
int nextMinBiasEvent()
std::vector< Double_t > * RcoInfo(bool force_reload=false)
int setCut(const TCut &cut)
int nthInPlaylist(int i)
TTree * fBlindEventTree[AnitaPol::kNotAPol]
!< Pointer to file containing tree of UsefulAnitaEvents to insert
Definition: AnitaDataset.h:407
Int_t ClockSpikeInfo(bool force_reload=false)
int previousInPlaylist()
UInt_t triggerTimeNs
Trigger time in ns from TURF.
AnitaDataset(int run, bool decimated=false, WaveCalType::WaveCalType_t cal=WaveCalType::kDefault, DataDirectory dir=ANITA_ROOT_DATA, BlindingStrategy strat=AnitaDataset::kDefault)
CalibratedAnitaEvent * calibrated(bool force_reload=false)
static void hiCal(UInt_t unixTime, Double_t &longitude, Double_t &latitude, Double_t &altitude)
virtual ~AnitaDataset()
std::vector< UInt_t > eventsToOverwrite
!< Pointer to fake header
Definition: AnitaDataset.h:415
Adu5Pat – The ADU5 Position and Attitude Data.
Definition: Adu5Pat.h:26
enum WaveCalType::EWaveCalType WaveCalType_t
The calibration enumeration type.
PrettyAnitaHk – The prettified ANITA Hk.
Definition: PrettyAnitaHk.h:22
void setCalType(WaveCalType::WaveCalType_t cal)
Definition: AnitaDataset.h:157
double fVolts[12 *9][260]
Array of unwrapped (unless kNoCalib) voltages for each channel.
int getEntry(int entryNumber)
int previousMinBiasEvent()
TruthAnitaEvent * truth(bool force_reload=true)
Int_t needToOverwriteEvent(AnitaPol::AnitaPol_t pol, UInt_t eventNumber)
!< Have we loaded the tree of events to insert?
bool loadRun(int run, bool decimated=false, DataDirectory dir=ANITA_ROOT_DATA)
static bool isKnownHiCalEvent(UInt_t eventNumber, Int_t anita=AnitaVersion::get())
int getEvent(int eventNumber, bool quiet=false)
Int_t RFSpikeInfo(bool force_reload=false)
RawAnitaHeader – The Raw ANITA Event Header.
UChar_t chipIdFlag[12 *9]
chipIdFlag
Definition: RawAnitaEvent.h:47
SurfHk – The raw SURF scaler+threshold data.
Definition: SurfHk.h:24
USeful in for loops.
int N() const
Int_t run
Run number, assigned on ground.
virtual UsefulAnitaEvent * useful(bool force_reload=false)
virtual ~UsefulAnitaEvent()
Destructor.
UInt_t turfEventId
TURF Event Id (12-bit run + 20-bit event)
Short_t data[12 *9][260]
The pedestal subtracted waveform data. Note that these arrays must be unwrapped and calibrated to bec...
Definition: RawAnitaEvent.h:67
SurfHk * surf(bool force_reload=false)
UsefulAnitaEvent – The Calibrated Useful Anita Event object.
UInt_t attFlag
0 is good attitude, 1 is bad attitude
Definition: Adu5Pat.h:50
std::vector< Double_t > * TempFactorInfo(bool force_reload=false)
int NInCut() const
int nthEvent(int i)
RawAnitaEvent * raw(bool force_reload=false)
CalibratedAnitaEvent – The Calibrated Calibrated Anita Event object.
Int_t getLabChip(Int_t chanIndex) const
Returns the LABRADOR number.
Definition: RawAnitaEvent.h:69
TTree * fBlindHeadTree[AnitaPol::kNotAPol]
!< Tree of UsefulAnitaEvents to insert
Definition: AnitaDataset.h:408
TruthAnitaEvent – The Truth ANITA Event.
UsefulAnitaEvent * fBlindEvent[AnitaPol::kNotAPol]
!< Tree of headers to insert
Definition: AnitaDataset.h:410
static TString getDescription(BlindingStrategy strat)
int NInPlaylist() const
BlindingStrategy getStrategy()
virtual ~CalibratedAnitaEvent()
Destructor.
Int_t ClockProblemInfo(bool force_reload=false)
static const char * getDataDir(DataDirectory dir=ANITA_ROOT_DATA)
TurfRate – The Turf Rate data.
Definition: TurfRate.h:21
Adu5Pat * gps(bool force_reload=false)
RawAnitaHeader * fBlindHeader[AnitaPol::kNotAPol]
!< Pointer to fake UsefulAnitaEvent
Definition: AnitaDataset.h:411
TRandom3 fRandy
!< Currently selected blinding strategy
Definition: AnitaDataset.h:398
PrettyAnitaHk * hk(bool force_reload=false)
Vertical Polarisation.
int getCurrRun()
Definition: AnitaDataset.h:321
virtual RawAnitaHeader * header(bool force_reload=false)
int loadPlaylist(const char *playlist)
Where was HiCal?
std::vector< Double_t > * ClockPhiInfo(bool force_reload=false)
BlindingStrategy setStrategy(BlindingStrategy strat)
Horizontal Polarisation.
UInt_t surfEventId[12]
SURF Event Id&#39;s.
Definition: RawAnitaEvent.h:36
UInt_t realTime
unixTime of readout
UShort_t trigNum
Trigger number (since last clear all)
enum AnitaPol::EAnitaPol AnitaPol_t
Polarisation enumeration.
static int getRunContainingEventNumber(UInt_t eventNumber)
Get the run that contains the eventNumber.
int setPlaylist(const char *playlist)
UChar_t trigType
Bit 0 is RF, 1 is ADU5, 2 is G12, 3 is software/external.
RawAnitaEvent – The Raw ANITA Event Data.
Definition: RawAnitaEvent.h:22
TurfRate * turf(bool force_reload=false)