AcclaimClustering.cxx
1 #include "AcclaimClustering.h"
2 #include "AnitaGeomTool.h"
3 #include "SummarySet.h"
4 #include "AnitaDataset.h"
5 #include "OutputConvention.h"
6 #include "AnitaEventSummary.h"
7 #include "RootTools.h"
8 #include "ProgressBar.h"
9 #include "TGraphAntarctica.h"
10 #include "TH2DAntarctica.h"
11 #include "TArrowAntarctica.h"
12 #include "TF1.h"
13 #include "TCanvas.h"
14 #include <limits.h>
15 #include "RampdemReader.h"
16 #include "Math/Factory.h"
17 #include "AcclaimOpenMP.h"
18 #include "RootTools.h"
19 #include "DrawStrings.h"
20 #include "ThermalChain.h"
21 #include "Hical2.h"
22 #include "FFTtools.h"
23 #include "TBits.h"
24 
25 #define ANSI_COLOR_RED "\x1b[31m"
26 #define ANSI_COLOR_GREEN "\x1b[32m"
27 #define ANSI_COLOR_YELLOW "\x1b[33m"
28 #define ANSI_COLOR_BLUE "\x1b[34m"
29 #define ANSI_COLOR_MAGENTA "\x1b[35m"
30 #define ANSI_COLOR_CYAN "\x1b[36m"
31 #define ANSI_COLOR_RESET "\x1b[0m"
32 
33 
37 
38 const int nDim = 3;
39 
40 const double FITTER_INPUT_SCALING = 1e-4;
41 const double FITTER_OUTPUT_SCALING = 1./FITTER_INPUT_SCALING;
42 
43 
50 namespace ResolutionModel{
51  const int n = 6;
52  const double phiParams[n] = {-2.50414e-01, 3.02406e-01, 2.43376e-01, 5.09057, 8.01369e-01, 1.}; //A4 is the second set of 3 numbers, A3 is the first set
53  const double thetaParams[n] = {-3.83773e-01, -3.00964e-01, 1.64537e-01, 1.34307, 7.09382e-01, 1.}; //A4 is the second set of 3 numbers, A3 is the first set
54  TString formula = (AnitaVersion::get() == 3) ? "exp([0]*x + [1]) + [2]" : "[0]/(pow(x,[1]) + [2])";
55 
56 }
57 
58 
59 
69 void Acclaim::Clustering::getAngularResolution(const AnitaEventSummary* sum, AnitaPol::AnitaPol_t pol, Int_t peakInd, double& sigma_theta, double& sigma_phi){
70  const double x = sum->coherent_filtered[pol][peakInd].snr;
71  getAngularResolution(x, sigma_theta, sigma_phi);
72 }
73 
74 
83 void Acclaim::Clustering::getAngularResolution(double x, double& sigma_theta, double& sigma_phi){
84  TString formula = "[0]/(pow(x,[1]) + [2])";
85  sigma_phi = (AnitaVersion::get() == 3) ? exp(ResolutionModel::phiParams[0]*x + ResolutionModel::phiParams[1]) + ResolutionModel::phiParams[2] : ResolutionModel::phiParams[3]/(pow(x, ResolutionModel::phiParams[4]) + ResolutionModel::phiParams[5]);
86  sigma_theta = (AnitaVersion::get() == 3) ? exp(ResolutionModel::thetaParams[0]*x + ResolutionModel::thetaParams[1]) + ResolutionModel::thetaParams[2] : ResolutionModel::thetaParams[3]/(pow(x, ResolutionModel::thetaParams[4]) + ResolutionModel::thetaParams[5]);
87 }
88 
89 
90 TCanvas* Acclaim::Clustering::drawAngularResolutionModel(double maxSnr){
91  TCanvas* c1 = new TCanvas();
92 
93  TF1* fTheta = new TF1("fThetaResolutionModel", ResolutionModel::formula, 0, maxSnr);
94  TF1* fPhi = new TF1("fThetaResolutionModel", ResolutionModel::formula, 0, maxSnr);
95  int versionOffset = (AnitaVersion::get() == 3) ? 0 : 3;
96  for(int i=0; i < ResolutionModel::n; i++){
97  fTheta->SetParameter(i, ResolutionModel::thetaParams[i+versionOffset]);
98  fPhi->SetParameter(i, ResolutionModel::phiParams[i+versionOffset]);
99  }
100 
101  fPhi->Draw();
102  fPhi->SetLineColor(kRed);
103  fTheta->Draw("lsame");
104  fTheta->SetLineColor(kBlue);
105  fPhi->SetBit(kCanDelete);
106  fTheta->SetBit(kCanDelete);
107 
108  fPhi->SetMinimum(0.01);
109  c1->Modified();
110  c1->Update();
111  return c1;
112 }
113 
114 
115 
116 
125  Adu5Pat pat = anita.pat();
126  usefulPat = UsefulAdu5Pat(&pat);
128  // usefulPat.setSurfaceCloseEnoughInter(1e-3);
130  usefulPat.setMaxLoopIterations(5000); // make this arbitrarily large since it only happens once
131  // const double maxThetaAdjust = 8*TMath::DegToRad();
132 
133  if(calculateSource){
134  // if(eventNumber==10047816){ //9887706
135  // usefulPat.setDebug(true);
136  // }
137 
138  usefulPat.traceBackToContinent3(phi*TMath::DegToRad(), -theta*TMath::DegToRad(), &longitude, &latitude, &altitude, &thetaAdjustmentRequired);//, maxThetaAdjust, 10);
139 
140  if(altitude < -999){
141  usefulPat.setDebug(true);
142  usefulPat.traceBackToContinent3(phi*TMath::DegToRad(), -theta*TMath::DegToRad(), &longitude, &latitude, &altitude, &thetaAdjustmentRequired);//, maxThetaAdjust, 10);
143  }
144 
145  // std::cout << eventNumber << "\t" << longitude << "\t" << latitude << "\t" << altitude << "\t" << thetaAdjustmentRequired << std::endl;
146 
147  // if(usefulPat.getDebug()){
148  // exit(1);
149  // }
150 
153  geom->getCartesianCoords(latitude, longitude, altitude, centre);
154 
155  // std::cerr << eventNumber << "\t" << easting << "\t" << northing << std::endl;
156  if(latitude < -90){
157  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", for eventNumber " << eventNumber << "\n";
158  // std::cerr << "Doing traceBackToContinenet again in debug mode!\n";
159  // usefulPat.setDebug(true);
160  // usefulPat.traceBackToContinent(phi*TMath::DegToRad(), -theta*TMath::DegToRad(), &longitude, &latitude, &altitude, &thetaAdjustmentRequired, maxThetaAdjust, 100);
161  // usefulPat.setDebug(false);
162  // RampdemReader::LonLatToEastingNorthing(longitude, latitude, easting, northing);
163  std::cerr << "Removing event " << eventNumber << " from event-event clustering!" << std::endl;
164  eventEventClustering = false;
165  easting = -99e20;
166  northing = -99e20;
167  }
168  else{
169  eventEventClustering = true;
170  }
171 
172  // selfLogLikelihood = logLikelihoodFromPoint(longitude, latitude, altitude, false);
173  // selfLogLikelihood = logLikelihoodFromPoint(longitude, latitude, altitude, true);
174  selfLogLikelihood = logLikelihoodFromPoint(longitude, latitude, altitude, false);
175  }
176 }
177 
178 
189 Double_t Acclaim::Clustering::Event::logLikelihoodFromPoint(Double_t sourceLon, Double_t sourceLat, Double_t sourceAlt, bool addOverHorizonPenalty) const {
190 
191  Double_t thetaSource, phiSource;
192  usefulPat.getThetaAndPhiWave2(sourceLon, sourceLat, sourceAlt, thetaSource, phiSource);
193  thetaSource = -1*TMath::RadToDeg()*thetaSource;
194  phiSource = TMath::RadToDeg()*phiSource;
195 
196  Double_t dTheta = (thetaSource - theta)/sigmaTheta;
197  Double_t dPhi = Acclaim::RootTools::getDeltaAngleDeg(phiSource, phi)/sigmaPhi;
198 
199  Double_t ll = dTheta*dTheta + dPhi*dPhi;
200 
201  if(fDebug){
202  std::cerr << __PRETTY_FUNCTION__ << " for " << eventNumber << ", dTheta = " << dTheta << ", dPhi = " << dPhi << ", ll = " << ll << std::endl;
203  }
204 
205  if(addOverHorizonPenalty){
206  Double_t distM = usefulPat.getDistanceFromSource(sourceLat, sourceLon, sourceAlt);
207  if(distM >= default_horizon_distance){
208  double distOverHorizonM = fabs(distM - default_horizon_distance);
209  ll += distOverHorizonM;
210  }
211  if(fDebug){
212  std::cerr << __PRETTY_FUNCTION__ << " for " << eventNumber << ", we are " << distM/1000 << "km from the source, after horizon penalty, ll = " << ll << std::endl;
213  }
214  }
215 
216  return ll;
217 }
218 
219 
220 
221 
222  Acclaim::Clustering::Event::Event(const AnitaEventSummary* sum, AnitaPol::AnitaPol_t pol, Int_t peakInd, Int_t nT)
223 : nThresholds(0), cluster(NULL),
224  dThetaCluster(NULL), dPhiCluster(NULL)
225 {
226 
227  this->eventNumber = sum->eventNumber;
228  this->run = sum->run;
229  this->pol = pol;
230  peakIndex = peakInd;
231  const AnitaEventSummary::PointingHypothesis& peak = sum->peak[pol][peakInd];
232  latitude = peak.latitude;
233  longitude = peak.longitude;
234  altitude = peak.altitude;
235  // RampdemReader::LonLatToEastingNorthing(longitude, latitude, easting, northing);
237  geom->getCartesianCoords(latitude, longitude, altitude, centre);
238  theta = peak.theta;
239  phi = peak.phi;
241  selfLogLikelihood = -9999;
242  anita = sum->anitaLocation;
243  getAngularResolution(sum, pol, peakInd, sigmaTheta, sigmaPhi);
244  antarcticaHistBin = -1;
245  fDebug = false;
248 
249  setNThresholds(nT);
250  resetClusteringNumbers();
251  setupUsefulPat();
252 
253  // std::cout << eventNumber << "\t" << nThresholds << "\t" << cluster[0] << std::endl;
254 }
255 
256 
257 
258 
259 
260 
261 
262 
263 
264 Acclaim::Clustering::Event::Event(int pol, int peakInd, double peak_phi, double peak_theta, int nT, UInt_t eventNumber, Int_t run,
265  double anita_longitude, double anita_latitude, double anita_altitude, double anita_heading, double coherent_filtered_snr)// ,
266 // double longitude, double latitude, double altitude)
267 : nThresholds(0), cluster(NULL),
268  dThetaCluster(NULL), dPhiCluster(NULL)
269 {
270 
271  this->eventNumber = eventNumber;
272  this->run = run;
273  this->pol = (AnitaPol::AnitaPol_t) pol;
274  peakIndex = peakInd;
275  // AnitaGeomTool* geom = AnitaGeomTool::Instance();
276  // geom->getCartesianCoords(latitude, longitude, altitude, centre);
277  theta = peak_theta;
278  phi = peak_phi;
279  // thetaAdjustmentRequired = peak.theta_adjustment_needed;
280  selfLogLikelihood = -9999;
281  anita.longitude = anita_longitude;
282  anita.latitude = anita_latitude;
283  anita.altitude = anita_altitude;
284  anita.heading = anita_heading;
285 
286  getAngularResolution(coherent_filtered_snr, sigmaTheta, sigmaPhi);
287 
288  // getAngularResolution(sum, pol, peakInd, sigmaTheta, sigmaPhi);
289  antarcticaHistBin = -1;
290  fDebug = false;
293 
294  setNThresholds(nT);
295  resetClusteringNumbers();
296  setupUsefulPat();
297 
298  // getAngularResolution(sum, pol, peakInd, sigmaTheta, sigmaPhi);
299 
300  // std::cout << eventNumber << "\t" << nThresholds << "\t" << cluster[0] << std::endl;
301 }
302 
303 
304 
305 
306 
307 
308 
309 
310 
311  Acclaim::Clustering::Event::Event(Int_t nT)
312 : nThresholds(0), cluster(NULL),
313  dThetaCluster(NULL), dPhiCluster(NULL)
314 {
315 
316  latitude = 0;
317  longitude = 0;
318  altitude = 0;
319  easting = DBL_MAX;
320  northing = DBL_MAX;
321  theta = -9999;
322  phi = -9999;
323  thetaAdjustmentRequired = -9999;
324  selfLogLikelihood = -9999;
325  anita.reset();
326  eventNumber = 0;
327  run = 0;
329  peakIndex = -1;
330  sigmaTheta = default_sigma_theta;
331  sigmaPhi = default_sigma_phi;
332  for(int dim=0; dim < nDim; dim++){
333  centre[dim] = 0;
334  }
335  antarcticaHistBin = -1;
336  fDebug = false;
337 
338 
345 
346 
347 
348  setNThresholds(nT);
349  resetClusteringNumbers();
350 }
351 
352 
353 Acclaim::Clustering::Event::~Event(){
354  deleteArrays();
355 }
356 
357 
358 
359 Acclaim::Clustering::Event& Acclaim::Clustering::Event::operator=(const Event& event){
360 
361  eventNumber = event.eventNumber;
362  run = event.run;
363  pol = event.pol;
364  peakIndex = event.peakIndex;
365 
366  for(int i=0; i < 3; i++){
367  centre[i] = event.centre[i];
368  }
369  latitude = event.latitude;
370  longitude = event.longitude;
371  altitude = event.altitude;
372  easting = event.easting;
373  northing = event.northing;
374  anita = event.anita;
375 
376  theta = event.theta;
377  phi = event.phi;
378 
379  thetaAdjustmentRequired = event.thetaAdjustmentRequired;
380 
381  sigmaTheta = event.sigmaTheta;
382  sigmaPhi = event.sigmaPhi;
383 
384  if(nThresholds!=event.nThresholds){
385  deleteArrays();
386  nThresholds = event.nThresholds;
387  cluster = new Int_t[nThresholds];
388  dThetaCluster = new Double_t[nThresholds];
389  dPhiCluster = new Double_t[nThresholds];
390  }
391  for(int z=0; z < nThresholds; z++){
392  cluster[z] = event.cluster[z];
393  dThetaCluster[z] = event.dThetaCluster[z];
394  dPhiCluster[z] = event.dPhiCluster[z];
395  }
396 
397 
398  eventEventClustering = event.eventEventClustering;
399  nearestKnownBaseLogLikelihood = event.nearestKnownBaseLogLikelihood;
400  nearestKnownBaseSurfaceSeparationKm = event.nearestKnownBaseSurfaceSeparationKm;
401  nearestKnownBaseCluster = event.nearestKnownBaseCluster;
402  selfLogLikelihood = event.selfLogLikelihood;
403  nearestEventSurfaceDistanceKm = event.nearestEventSurfaceDistanceKm;
404  nearestEventSurfaceEventNumber = event.nearestEventSurfaceEventNumber;
405  nearestEventSurfaceLogLikelihood = event.nearestEventSurfaceLogLikelihood;
406 
407  antarcticaHistBin = event.antarcticaHistBin;
408  usefulPat = event.usefulPat;
409  fDebug = event.fDebug;
410 
411  return *this;
412 }
413 
414 
415  Acclaim::Clustering::Event::Event(const Event& event)
416 : nThresholds(0), cluster(NULL),
417  dThetaCluster(NULL), dPhiCluster(NULL)
418 {
419  *this = event;
420 }
421 
422 
423 
424 
425 void Acclaim::Clustering::Event::deleteArrays(){
426  if(cluster){
427  delete [] cluster;
428  cluster = NULL;
429  }
430  if(dPhiCluster){
431  delete [] dPhiCluster;
432  cluster = NULL;
433  }
434  if(dThetaCluster){
435  delete [] dThetaCluster;
436  dThetaCluster = NULL;
437  }
438  nThresholds = 0;
439 }
440 
441 
442 
450 
451  std::vector<Int_t> tempCluster;
452  std::vector<Double_t> tempDPhiCluster;
453  std::vector<Double_t> tempDThetaCluster;
454 
455  if(nThresholds){
456  tempCluster.insert(tempCluster.begin(), cluster, cluster+nThresholds);
457  tempDPhiCluster.insert(tempDPhiCluster.begin(), dPhiCluster, dPhiCluster+nThresholds);
458  tempDThetaCluster.insert(tempDThetaCluster.begin(), dThetaCluster, dThetaCluster+nThresholds);
459  }
460 
461  deleteArrays();
462  nThresholds = n;
463  cluster = new Int_t[n];
464  dPhiCluster = new Double_t[n];
465  dThetaCluster = new Double_t[n];
466 
467  int nz = TMath::Min((int)tempCluster.size(), nThresholds);
468  for(Int_t z=0; z < nz; z++){
469  cluster[z] = tempCluster[z];
470  dPhiCluster[z] = tempDPhiCluster[z];
471  dThetaCluster[z] = tempDThetaCluster[z];
472  }
473  for(Int_t z=nz; z < nThresholds; z++){
474  cluster[z] = -1;
475  dPhiCluster[z] = -999;
476  dThetaCluster[z] = -999;
477  }
478 }
479 
480 
481 
482 void Acclaim::Clustering::Event::resetClusteringNumbers(){
483 
484  for(Int_t z=0; z<nThresholds; z++){
485  cluster[z] = -1;
486  dThetaCluster[z] = -999;
487  dPhiCluster[z] = -999;
488  }
489  // nearestNeighbourEventNumber = 0;
490  // nearestNeighbourLogLikelihood = DBL_MAX;
491  // nearestKnownBaseLogLikelihood = DBL_MAX;
492  // nearestKnownBaseCluster = -1;
493  eventEventClustering = true;
494  nearestKnownBaseLogLikelihood = DBL_MAX;
495  nearestKnownBaseSurfaceSeparationKm = DBL_MAX;
496  nearestKnownBaseCluster = -1;
497  selfLogLikelihood = 0;
498  nearestEventSurfaceDistanceKm = DBL_MAX;
499  nearestEventSurfaceEventNumber = 0;
500  nearestEventSurfaceLogLikelihood = DBL_MAX;
501 
502 }
503 
504 
511  return new TArrowAntarctica(anita.longitude, anita.latitude, longitude, latitude);
512 }
513 
514 
516  : Event(nT){
517  weight = 0;
518  energy=0;
519  }
520 
521  Acclaim::Clustering::McEvent::McEvent(const AnitaEventSummary* sum, AnitaPol::AnitaPol_t pol, Int_t peakInd, Int_t nT)
522 : Event(sum, pol, peakInd, nT)
523 {
524  weight = sum->mc.weight;
525  energy = sum->mc.energy;
526  // std::cout << longitude << "\t" << latitude << "\t" << altitude << std::endl;
527 }
528 
529 
530 Acclaim::Clustering::McEvent::McEvent(double weight, double energy, int pol, int peakInd, double peak_phi, double peak_theta, int nT, UInt_t eventNumber, Int_t run,
531  double anita_longitude, double anita_latitude, double anita_altitude, double anita_heading, double coherent_filtered_snr)
532 : Event(pol, peakInd, peak_phi, peak_theta, nT, eventNumber, run,
533  anita_longitude, anita_latitude, anita_altitude, anita_heading, coherent_filtered_snr)
534 {
535  this->weight = weight;
536  this->energy = energy;
537  // std::cout << longitude << "\t" << latitude << "\t" << altitude << std::endl;
538 }
539 
540 Acclaim::Clustering::Cluster::Cluster(Int_t i) {
541  for(int dim=0; dim < nDim; dim++){
542  centre[dim] = 0;
543  }
544  latitude = 0;
545  longitude = 0;
546  altitude = 0;
547  knownBase = 0;
548  resetClusteringNumbers();
549  antarcticaHistBin = -1;
550  seedEvent = -1;
551  index = i;
552 }
553 
554 Acclaim::Clustering::Cluster::Cluster(const BaseList::base& base, Int_t i) {
555  AntarcticCoord ac = base.position.as(AntarcticCoord::WGS84);
556  latitude = ac.x;
557  longitude = ac.y;
558  altitude = ac.z;
559  knownBase = 1;
560 
561  if(altitude == -999){
562  altitude = RampdemReader::BilinearInterpolatedSurfaceAboveGeoid(longitude, latitude);
563  }
564 
566  geom->getCartesianCoords(latitude, longitude, altitude, centre);
567  resetClusteringNumbers();
568  antarcticaHistBin = -1;
569  seedEvent = -1;
570  index = i;
571  llEventCutInd = 0;
572 }
573 
574 
575 Acclaim::Clustering::Cluster::Cluster(const Event& event, Int_t i) {
576  latitude = event.longitude;
577  longitude = event.latitude;
578  altitude = event.altitude;
579  knownBase = 0;
580 
582  geom->getCartesianCoords(latitude, longitude, altitude, centre);
583  resetClusteringNumbers();
584  index = i;
585  llEventCutInd = 0;
586 }
587 
588 
590  numDataEvents = 0;
591  sumMcWeights = 0;
592 }
593 
594 
595 Acclaim::Clustering::LogLikelihoodMethod::LogLikelihoodMethod()
596 : numMcDivisions(100), fEventsAlreadyClustered(false), fMyBackground(),
597  fROOTgErrorIgnoreLevel(gErrorIgnoreLevel), fDrawNewNearbyEventsHistograms(true),
598  fReadInBaseList(false), fStoreUnclusteredHistograms(true)
599 
600 {
601  const char* sgeTaskId = getenv("SGE_TASK_ID");
602  if(!sgeTaskId){
603  mcDivision = -1; // this means to all of it, ignoring the value of numMcDivisions
604  }
605  else{
606  mcDivision = atoi(sgeTaskId);
607  std::cout << "Info in " << __PRETTY_FUNCTION__ << ", found SGE_TASK_ID=" << sgeTaskId
608  << ", setting mcDivision = " << mcDivision << std::endl;
609  }
610  // fMyBackground.SetCoarseness(100);
611  // fMyBackground.SetCoarseness(60);
612  // fMyBackground.SetCoarseness(20); // lower coarseness implies more bins...
613  fMyBackground.SetCoarseness(120); // lower coarseness implies more bins...
614  std::cout << fMyBackground.GetXaxis()->GetBinWidth(1) << "\t" << fMyBackground.GetYaxis()->GetBinWidth(1) << std::endl;
615 
616  grTestMinimizerWalk = NULL;
617  grTestMinimizerValue = NULL;
618 
619  // for(Int_t i=0; i < 20; i++){
620  // llEventCuts.push_back(1+i);
621  // }
622  surfaceDistThresholdKm = 30;
623  llEventCuts.push_back(1);
624  llEventCuts.push_back(2);
625  llEventCuts.push_back(4);
626  llEventCuts.push_back(6);
627  llEventCuts.push_back(8);
628 
629  llEventCuts.push_back(10);
630  llEventCuts.push_back(12);
631  llEventCuts.push_back(15);
632  llEventCuts.push_back(20);
633  llEventCuts.push_back(40);
634  llEventCuts.push_back(70);
635 
636  llEventCuts.push_back(100);
637 /*
638  llEventCuts.push_back(150);
639  llEventCuts.push_back(200);
640  llEventCuts.push_back(250);
641 
642  llEventCuts.push_back(350);
643  llEventCuts.push_back(400);
644  llEventCuts.push_back(450);
645  llEventCuts.push_back(500);
646 
647  llEventCuts.push_back(600);
648  llEventCuts.push_back(700);
649  llEventCuts.push_back(800);
650  llEventCuts.push_back(900);
651 
652  llEventCuts.push_back(1000);
653 
654  llEventCuts.push_back(1200);
655  llEventCuts.push_back(1400);
656  llEventCuts.push_back(1600);
657 
658  llEventCuts.push_back(2000);
659  llEventCuts.push_back(2500);
660  llEventCuts.push_back(3000);
661  llEventCuts.push_back(4000);
662 */
663 
664  for(UInt_t z=0; z < llEventCuts.size(); z++){
665  clusters.push_back(std::vector<Cluster>());
666  }
667 
668  // both above horizon; good improvement; actual test
669  fTestEvent1 = 61284883; //55510391; // 61156660; //61033430;
670  fTestEvent2 = 55352006; //61338514; //55789194; //61424151;
671 
672 
673  fKDTree = NULL;
674  fDebug = false;
675  fUseBaseList = true;
676  fPercentOfMC = 0;
677  fCut = 0;
678  fCutHical = 0;
679  fSelfLLMax = -1;
680  fEntryList = 0;
681 
682  fMaxFitterAttempts = 1;
683 
684  tr3 = new TRandom3(0);
685 
686  int nThreads = Acclaim::OpenMP::getMaxThreads();
687  fFitEvent1s.resize(nThreads, NULL);
688  fFitEvent2s.resize(nThreads, NULL);
689  fFitEastings.resize(nThreads, 0);
690  fFitNorthings.resize(nThreads, 0);
691 
692  fFunctors.reserve(nThreads);
693  fMinimizers.reserve(nThreads);
694  for(int t=0; t < nThreads; t++){
695  fMinimizers.push_back(ROOT::Math::Factory::CreateMinimizer("Minuit2"));
696  fFunctors.push_back(ROOT::Math::Functor(this, &Acclaim::Clustering::LogLikelihoodMethod::evalPairLogLikelihoodAtLonLat, 2));
697 
698  fMinimizers.at(t)->SetMaxFunctionCalls(1e5); // for Minuit/Minuit2
699  fMinimizers.at(t)->SetTolerance(0.0001);
700  fMinimizers.at(t)->SetPrintLevel(0);
701  fMinimizers.at(t)->SetFunction(fFunctors.at(t));
702  }
703 }
704 
705 
706 
707 
708 
709 Acclaim::Clustering::LogLikelihoodMethod::~LogLikelihoodMethod(){
710 
711  // delete non-NULL antarctic histograms, tgraphs
712 
713  for(UInt_t i=0; i < hUnclusteredEvents.size(); i++){
714  if(hUnclusteredEvents.at(i)){
715  delete hUnclusteredEvents.at(i);
716  hUnclusteredEvents.at(i) = NULL;
717  }
718  }
719 
720 }
721 
722 
723 
724 Double_t Acclaim::Clustering::LogLikelihoodMethod::getDistSqEventCluster(const Event& event, const Acclaim::Clustering::Cluster& cluster){
725  Double_t d2=0;
726  for(int dim=0; dim < nDim; dim++){
727  Double_t d = cluster.centre[dim] - event.centre[dim];
728  d2 += d*d;
729  }
730  return d2;
731 }
732 
733 
734 
735 void Acclaim::Clustering::LogLikelihoodMethod::getDeltaThetaDegDeltaPhiDegEventCluster(const Event& event, const Cluster& cluster, Double_t& deltaThetaDeg, Double_t& deltaPhiDeg){
736 
737  Double_t thetaWave, phiWave;
738  event.usefulPat.getThetaAndPhiWave2(cluster.longitude, cluster.latitude, cluster.altitude, thetaWave, phiWave);
739  Double_t thetaDeg = -1*TMath::RadToDeg()*thetaWave;
740  Double_t phiDeg = TMath::RadToDeg()*phiWave;
741 
742  deltaThetaDeg = (thetaDeg - event.theta);
743  deltaPhiDeg = Acclaim::RootTools::getDeltaAngleDeg(phiDeg, event.phi);
744 
745  // if(fDebug){
746  // if(event.cluster < 0 && eventInd == cluster.seedEvent){
747  // std::cout << "event theta = " << event.theta << ", cluster theta = " << thetaDeg << std::endl;
748  // std::cout << "event phi = " << event.phi << ", cluster phi = " << phiDeg << std::endl;
749  // }
750  // }
751 }
752 
753 
754 Double_t Acclaim::Clustering::LogLikelihoodMethod::evalPairLogLikelihoodAtLonLat(const Double_t* params){
755 
756  Double_t sourceEasting = FITTER_OUTPUT_SCALING*params[0];
757  Double_t sourceNorthing = FITTER_OUTPUT_SCALING*params[1];
758  int t = OpenMP::thread();
759 
760  // Double_t sourceAlt = RampdemReader::SurfaceAboveGeoidEN(sourceEasting, sourceNorthing);
761  Double_t sourceAlt = RampdemReader::BilinearInterpolatedSurfaceAboveGeoidEastingNorthing(sourceEasting, sourceNorthing);
762  Double_t sourceLon, sourceLat;
763  RampdemReader::EastingNorthingToLonLat(sourceEasting, sourceNorthing, sourceLon, sourceLat);
764 
765  Double_t ll = 0;
766  ll += fFitEvent1s.at(t)->logLikelihoodFromPoint(sourceLon, sourceLat, sourceAlt, true);
767  ll += fFitEvent2s.at(t)->logLikelihoodFromPoint(sourceLon, sourceLat, sourceAlt, true);
768  // ll += fFitEvent1s.at(t)->logLikelihoodFromPoint(sourceLon, sourceLat, sourceAlt, true);
769  // ll += fFitEvent2s.at(t)->logLikelihoodFromPoint(sourceLon, sourceLat, sourceAlt, true);
770 
771  if(fFitEvent1s.at(t)->eventNumber==fTestEvent1){
772  if(fFitEvent2s.at(t)->eventNumber==fTestEvent2){
773  if(grTestMinimizerWalk){
774  grTestMinimizerWalk->SetPoint(grTestMinimizerWalk->GetN(), sourceEasting, sourceNorthing);
775  }
776  if(grTestMinimizerValue){
777  int n = grTestMinimizerValue->GetN();
778  grTestMinimizerValue->SetPoint(n, n, ll);
779  // std::cout << n << "\t" << sourceEasting << "\t" << sourceNorthing << "\t"
780  // << sourceAlt << "\t" << RampdemReader::SurfaceAboveGeoidEN(sourceEasting, sourceNorthing)
781  // << "\t" << ll << std::endl;
782  }
783  }
784  }
785 
786 
787  if(fMinimizers.at(t)->PrintLevel() > 0){
788  std::cout << sourceEasting << "\t" << sourceNorthing << "\t" << sourceLon << "\t" << sourceLat << "\t" << ll << std::endl;
789  }
790 
791  return ll;
792 }
793 
794 
795 
796 Double_t Acclaim::Clustering::LogLikelihoodMethod::dFit(const Event* event1, const Event* event2){
797 
798  int t = Acclaim::OpenMP::thread();
799  ROOT::Math::Minimizer* minimizer = fMinimizers.at(t);
800 
801  fFitEvent1s.at(t) = event1;
802  fFitEvent2s.at(t) = event2;
803 
804  Double_t ll12 = dAsym(event1, event2);
805  Double_t ll21 = dAsym(event2, event1);
806 
807  // const Event* which = ll12 < ll21 ? fFitEvent1s.at(t) : fFitEvent2s.at(t);
808  const Event* which = ll21 < ll12 ? fFitEvent1s.at(t) : fFitEvent2s.at(t);
809 
810  if(fFitEvent1s.at(t)->eventNumber==fTestEvent1 && fFitEvent2s.at(t)->eventNumber==fTestEvent2){
811  grTestMinimizerWalk = new TGraph();
812  grTestMinimizerValue = new TGraph();
813 
814  if(fDebug){
815  event1->fDebug = true;
816  event2->fDebug = true;
817  }
818  }
819 
820 
821  minimizer->SetVariable(0, "sourceEasting", FITTER_INPUT_SCALING*which->easting, 1);
822  minimizer->SetVariable(1, "sourceNorthing", FITTER_INPUT_SCALING*which->northing, 1);
823 
824  bool validMinimum = false;
825  std::vector<double> minima;
826  for(int attempt=0; attempt < fMaxFitterAttempts && !validMinimum; attempt++){
827  validMinimum = minimizer->Minimize();
828  minima.push_back(minimizer->MinValue());
829  if(!validMinimum){
830  if(fDebug){
831  std::cerr << "Info in " << __PRETTY_FUNCTION__ << ", eventNumbers " << event1->eventNumber << " and "
832  << event2->eventNumber << " did not converge, the result was " << minimizer->MinValue() << std::endl;
833  }
834  minimizer->SetVariable(0, "sourceEasting", minimizer->X()[0], 1);
835  minimizer->SetVariable(1, "sourceNorthing", minimizer->X()[1], 1);
836  }
837  }
838  if(!validMinimum && fDebug){
839  std::cerr << "Info in " << __PRETTY_FUNCTION__ << ", eventNumbers " << event1->eventNumber << " and "
840  << event2->eventNumber << " did not converge, the result was " << minimizer->MinValue() << std::endl;
841  }
842 
843  if(fFitEvent1s.at(t)->eventNumber==fTestEvent1 && fFitEvent2s.at(t)->eventNumber==fTestEvent2){
844  if(fDebug){
845  event1->fDebug = false;
846  event2->fDebug = false;
847  }
848  }
849 
850  if(grTestMinimizerWalk){
851  grTestMinimizerWalk->SetName("grTestMinimizerWalk");
852  grTestMinimizerWalk->Write();
853  delete grTestMinimizerWalk;
854  grTestMinimizerWalk = NULL;
855  }
856  if(grTestMinimizerValue){
857  grTestMinimizerValue->SetName("grTestMinimizerValue");
858  grTestMinimizerValue->Write();
859  delete grTestMinimizerValue;
860  grTestMinimizerValue = NULL;
861  }
862 
863  if((!validMinimum && fDebug)){ // do the same thing again, this time with error messages!
864  int old_print_level = minimizer->PrintLevel();
865  gErrorIgnoreLevel = fROOTgErrorIgnoreLevel;
866  minimizer->SetPrintLevel(3);
867  minimizer->SetVariable(0, "sourceEasting", FITTER_INPUT_SCALING*which->easting, 1);
868  minimizer->SetVariable(1, "sourceNorthing", FITTER_INPUT_SCALING*which->northing, 1);
869  for(int attempt=0; attempt < fMaxFitterAttempts && !validMinimum; attempt++){
870  validMinimum = minimizer->Minimize();
871  if(!validMinimum){
872  minimizer->SetVariable(0, "sourceEasting", minimizer->X()[0], 1);
873  minimizer->SetVariable(1, "sourceNorthing", minimizer->X()[1], 1);
874  }
875  }
876  minimizer->SetPrintLevel(old_print_level);
877 
878  AnitaVersion::set(3);
879  double waisLon = AnitaLocations::getWaisLongitude();
880  double waisLat = AnitaLocations::getWaisLatitude();
881  double waisModelAlt = RampdemReader::BilinearInterpolatedSurfaceAboveGeoid(waisLon, waisLat);
882  const Event& event1 = *fFitEvent1s.at(t);
883  const Event& event2 = *fFitEvent2s.at(t);
884  Double_t llWais1 = event1.logLikelihoodFromPoint(waisLon, waisLat, waisModelAlt, false);
885  Double_t llWais2 = event2.logLikelihoodFromPoint(waisLon, waisLat, waisModelAlt, false);
886  Double_t llWais1b = event1.logLikelihoodFromPoint(waisLon, waisLat, waisModelAlt, true);
887  Double_t llWais2b = event2.logLikelihoodFromPoint(waisLon, waisLat, waisModelAlt, true);
888  std::cerr << "Debug in " << __PRETTY_FUNCTION__ << ": The fitter minimum is " << minimizer->MinValue() << std::endl;
889  std::cerr << "event 1: run " << event1.run << ", eventNumber " << event1.eventNumber << std::endl;
890  std::cerr << "event 2: run " << event2.run << ", eventNumber " << event2.eventNumber << std::endl;
891  std::cerr << "Just for fun trying true WAIS location..." << std::endl;
892  std::cerr << "llWais1 = " << llWais1 << "\t" << llWais1b << std::endl;
893  std::cerr << "llWais2 = " << llWais2 << "\t" << llWais2b << std::endl;
894  std::cerr << "Seed was at " << which->easting << "\t" << which->northing << "\t"
895  << which->longitude << "\t" << which->latitude << "\t" << TMath::Max(ll21, ll12) << std::endl;
896 
897  std::cerr << "event 1 was at " << event1.easting << "\t" << event1.northing << "\t" << event1.longitude << "\t" << event1.latitude << "\t" << ll12 << std::endl;
898  std::cerr << "event 2 was at " << event2.easting << "\t" << event2.northing << "\t" << event2.longitude << "\t" << event2.latitude << "\t" << ll21 << std::endl;
899  std::cerr << std::endl;
900  gErrorIgnoreLevel = 1001;
901  }
902 
903  fFitEastings.at(t) = minimizer->X()[0]*FITTER_OUTPUT_SCALING;
904  fFitNorthings.at(t) = minimizer->X()[1]*FITTER_OUTPUT_SCALING;
905 
906  if(fFitEvent1s.at(t)->eventNumber==fTestEvent1 && fFitEvent2s.at(t)->eventNumber==fTestEvent2){
907  grTestMinimumPosition = new TGraph(1, &fFitEastings.at(t), &fFitNorthings.at(t));
908  grTestMinimumPosition->SetName("grTestMinimumPosition");
909  grTestMinimumPosition->Write();
910  delete grTestMinimumPosition;
911  grTestMinimumPosition = NULL;
912  }
913  Double_t ll = minimizer->MinValue();
914 
915  return ll;
916 }
917 
918 
919 
920 
935 Double_t Acclaim::Clustering::LogLikelihoodMethod::dMin(const Event* event1, const Event* event2){
936  return TMath::Min(dAsym(event1, event2) + event2->selfLogLikelihood, dAsym(event2, event1) + event1->selfLogLikelihood);
937 }
938 
939 
954 Double_t Acclaim::Clustering::LogLikelihoodMethod::dSum(const Event* event1, const Event* event2){
955  return dAsym(event1, event2) + event1->selfLogLikelihood + dAsym(event2, event1) + event2->selfLogLikelihood;
956 }
957 
958 
967 Double_t Acclaim::Clustering::LogLikelihoodMethod::dAsym(const Event* event1, const Event* event2){
968  return event1->logLikelihoodFromPoint(event2->longitude, event2->latitude,event2->altitude, true);
969 }
970 
971 
972 
973 
974 
975 
976 bool Acclaim::Clustering::LogLikelihoodMethod::considerBin(const Event& event, Int_t bx, Int_t by, double& easting, double& northing){
977 
978  const double halfBinWidthNorthing = 0.5*fMyBackground.GetYaxis()->GetBinWidth(bx);
979  const double halfBinWidthEasting = 0.5*fMyBackground.GetXaxis()->GetBinWidth(by);
980 
981  northing = fMyBackground.GetXaxis()->GetBinCenter(by);
982  northing = northing > event.northing ? northing - halfBinWidthNorthing : northing + halfBinWidthNorthing;
983  double dNorthing = northing - event.northing;
984 
985  easting = fMyBackground.GetXaxis()->GetBinCenter(bx);
986  easting = easting > event.easting ? easting - halfBinWidthEasting : easting + halfBinWidthEasting;
987  double dEasting = easting - event.easting;
988 
989  const double distSq = dNorthing*dNorthing + dEasting*dEasting;
990  const double maxRangeSq = default_horizon_distance*default_horizon_distance;
991 
992  if(distSq < maxRangeSq){
993  return true;
994  }
995  return false;
996 }
997 
998 
999 
1000 // void Acclaim::Clustering::LogLikelihoodMethod::nearbyEvents2(UInt_t eventInd, std::set<UInt_t>& nearbyEventInds){
1001 void Acclaim::Clustering::LogLikelihoodMethod::nearbyEvents2(UInt_t eventInd, std::vector<UInt_t>& nearbyEventInds){
1002 
1003  nearbyEventInds.clear();
1004 
1005  const int nx = fMyBackground.GetNbinsX();
1006  const int ny = fMyBackground.GetNbinsY();
1007 
1008  const Event& event = events.at(eventInd);
1009  std::vector<bool> found(events.size(), 0);
1010 
1011 
1012  for(Int_t by=1; by <= ny; by++){
1013  for(Int_t bx=1; bx <= nx; bx++){
1014  double easting, northing;
1015  if(considerBin(event, bx, by, easting, northing)){
1016 
1017  const std::vector<UInt_t>& eventsThisBin = fLookupEN[by-1][bx-1];
1018 
1019  for(UInt_t i=0; i < eventsThisBin.size(); i++){
1020  if(eventsThisBin[i]!=eventInd){ // (that's not the same event!)
1021  // if(RootTools::vectorContainsValue(eventsThisBin, eventInd)){
1022  // nearbyEventInds.insert(eventsThisBin[i]);
1023  found[eventsThisBin[i]] = 1;
1024  // nearbyEventInds.insert(eventsThisBin[i]);
1025  // }
1026  }
1027  }
1028  }
1029  }
1030  }
1031 
1032  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1033  if(found[eventInd] > 0){
1034  nearbyEventInds.push_back(eventInd);
1035  }
1036  }
1037 
1038 
1039 }
1040 
1041 
1042 
1043 
1044 
1045 
1046 Double_t Acclaim::Clustering::LogLikelihoodMethod::getAngDistSqEventCluster(const Event& event, const Cluster& cluster){
1047 
1048  Double_t deltaThetaDeg, deltaPhiDeg;
1049  getDeltaThetaDegDeltaPhiDegEventCluster(event, cluster, deltaThetaDeg, deltaPhiDeg);
1050 
1051  Double_t dThetaNorm = deltaThetaDeg/event.sigmaTheta;
1052  Double_t dPhiNorm = deltaPhiDeg/event.sigmaPhi;
1053  Double_t angSq = dThetaNorm*dThetaNorm + dPhiNorm*dPhiNorm;
1054  // if(fDebug){
1055  // // if(event.cluster < 0 && event.antarcticaHistBin == cluster.antarcticaHistBin){
1056  // if(event.cluster < 0 && eventInd == cluster.seedEvent){
1057  // std::cout << event.eventNumber << std::endl;
1058  // std::cout << "dTheta = " << deltaThetaDeg << ", dPhi = " << deltaPhiDeg
1059  // << ", sigmaTheta = " << event.sigmaTheta << ", sigmaPhi = " << event.sigmaPhi
1060  // << ", dThetaNorm = " << dThetaNorm << ", dPhiNorm = " << dPhiNorm
1061  // << ", ll = " << angSq << std::endl;
1062  // std::cout << "cluster lon/lat/alt = " << cluster.longitude << ", " << cluster.latitude << ", " << cluster.altitude << std::endl;
1063  // std::cout << "event lon/lat/alt = " << event.longitude << ", " << event.latitude << ", " << event.altitude << std::endl;
1064  // std::cout << "anita lon/lat/alt = " << event.usefulPat.longitude << ", " << event.usefulPat.latitude << ", " << event.usefulPat.altitude << std::endl;
1065  // }
1066  // }
1067  // }
1068 
1069 
1070  return angSq;
1071 }
1072 
1073 
1074 Double_t Acclaim::Clustering::LogLikelihoodMethod::getSumOfMcWeights(){
1075  Double_t sumOfWeights = 0;
1076  for(int i=0; i < (int)mcEvents.size(); i++){
1077  sumOfWeights += mcEvents.at(i).weight;
1078  }
1079  return sumOfWeights;
1080 }
1081 
1082 
1083 
1091 Acclaim::Clustering::Event* Acclaim::Clustering::LogLikelihoodMethod::nextEvent(){
1092 
1093  // to do this, first we histogram all the events which aren't clustered (using the smallest log-likelihood threshold).
1094 
1095  if(!fStoreUnclusteredHistograms){
1096  while(hUnclusteredEvents.size() > 0){
1097  delete hUnclusteredEvents.back();
1098  hUnclusteredEvents.pop_back();
1099  }
1100  }
1101 
1102 
1103 
1104  TString name = TString::Format("hUnclusteredEvents_%lu", hUnclusteredEvents.size());
1105  TH2DAntarctica* h = new TH2DAntarctica(name, name);
1106  hUnclusteredEvents.push_back(h);
1107 
1108  h->setAcceptStereographic(true); // already have easting/northing, don't do unnecessary work
1109 
1110  // find unclustered events (using the smallest log-likelihood threshold)
1111  UInt_t numUnclustered=0;
1112  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1113  Event& event = events.at(eventInd);
1114  if(event.cluster[0] < 0){
1115  event.antarcticaHistBin = h->Fill(event.easting, event.northing);
1116  if(event.antarcticaHistBin < 0){
1117  std::cerr << event.eventNumber << "\t" << event.longitude << "\t" << event.latitude << "\t" << event.easting << "\t" << event.northing << std::endl;
1118  }
1119  numUnclustered++;
1120  }
1121  }
1122  h->setAcceptStereographic(false);
1123 
1124  Event* nextEvent = NULL;
1125 
1126  // then we're done...
1127  if(numUnclustered==0){
1128  delete h;
1129  hUnclusteredEvents.pop_back();
1130  }
1131  else{
1132 
1133  // here we pick the next event...
1134  // which is the one closest to the mean position
1135  // of all the unclustered events in this bin...
1136  // hopefully this will be close to the centre of
1137  // all unclustered events.
1138 
1139  Int_t globalMaxBin = h->GetMaximumBin();
1140  Int_t numUnclusteredInBin = h->GetBinContent(globalMaxBin);
1141 
1142  Double_t meanEasting=0;
1143  Double_t meanNorthing=0;
1144 
1145  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1146  const Event& event = events.at(eventInd);
1147  if(event.antarcticaHistBin==globalMaxBin && event.cluster[0] < 0){
1148  meanEasting += event.easting;
1149  meanNorthing += event.northing;
1150  }
1151  }
1152  meanNorthing/=numUnclusteredInBin;
1153  meanEasting/=numUnclusteredInBin;
1154 
1155  Double_t bestSurfaceSeparationSquared = DBL_MAX;
1156  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1157  Event& event = events.at(eventInd);
1158  if(event.antarcticaHistBin==globalMaxBin && event.cluster[0] < 0){
1159  Double_t dE = event.easting - meanEasting;
1160  Double_t dN = event.northing - meanNorthing;
1161  Double_t surfaceSeparationSquared = dE*dE + dN*dN;
1162 
1163  if(surfaceSeparationSquared < bestSurfaceSeparationSquared){
1164  bestSurfaceSeparationSquared = surfaceSeparationSquared;
1165  nextEvent = &event;
1166  }
1167  }
1168  }
1169  }
1170  return nextEvent;
1171 }
1172 
1173 
1174 
1175 
1176 void Acclaim::Clustering::LogLikelihoodMethod::doBaseEventClustering(){
1177 
1178  std::cout << __PRETTY_FUNCTION__ << std::endl;
1179 
1180  const int nBases = BaseList::getNumBases();
1181 
1182  const Long64_t nEvents = events.size();
1183  ProgressBar p(nEvents);
1184 
1185  // I like to call this vector constructor bullshit
1186  std::vector< std::vector<std::vector<Int_t> > > matchedClusters(llEventCuts.size(), std::vector< std::vector<Int_t > >(nBases, std::vector<Int_t>()));
1187 
1188  for(Long64_t eventInd=0; eventInd < nEvents; eventInd++){
1189  Event* event = &events.at(eventInd);
1190 
1191  std::vector<std::vector<Int_t> > matchedClustersThisEvent(llEventCuts.size(), std::vector<Int_t>());
1192  for(int clusterInd=0; clusterInd < nBases; clusterInd++){
1193  Cluster& cluster = clusters.at(0).at(clusterInd);
1194  if(cluster.knownBase){
1195  double distM = event->usefulPat.getDistanceFromSource(cluster.latitude, cluster.longitude, cluster.latitude);
1196  if(distM < default_horizon_distance){
1197  double ll = event->logLikelihoodFromPoint(cluster.longitude, cluster.latitude, cluster.altitude, true);
1198  double surfaceSeparationKm = 1e-3*event->cartesianSeparation(cluster);
1199 
1200  if(surfaceSeparationKm < surfaceDistThresholdKm){ // then true for all cluster sizes
1201  for(int z=0; z < llEventCuts.size(); z++){
1202  matchedClustersThisEvent[z].push_back(clusterInd);
1203  }
1204  }
1205  else{
1206  for(int z=0; z < llEventCuts.size(); z++){
1207  if(ll < llEventCuts.at(z)){
1208  matchedClustersThisEvent[z].push_back(clusterInd);
1209  }
1210  }
1211  }
1212 
1213  if(ll < event->nearestKnownBaseLogLikelihood){
1214  event->nearestKnownBaseLogLikelihood = ll;
1215  event->nearestKnownBaseCluster = clusterInd;
1216  }
1217  if(surfaceSeparationKm < event->nearestKnownBaseSurfaceSeparationKm){
1218  event->nearestKnownBaseSurfaceSeparationKm = surfaceSeparationKm;
1219  event->nearestKnownBaseClusterSurface = clusterInd;
1220  }
1221  }
1222  }
1223  else{
1224  std::cerr << "You shouldn't get here!!!" << std::endl;
1225  }
1226  }
1227  for(int z=0; z < llEventCuts.size(); z++){
1228  if(matchedClustersThisEvent[z].size() > 0){
1229 
1230  // for all matched clusters
1231  for(int i = 0; i < matchedClustersThisEvent[z].size(); i++){
1232  Int_t matchedCluster = matchedClustersThisEvent[z][i];
1233 
1234  // add other matched clusters to their list...
1235  for(int j = 0; j < matchedClustersThisEvent[z].size(); j++){
1236  Int_t matchedCluster2 = matchedClustersThisEvent[z][j];
1237 
1238  if(!RootTools::vectorContainsValue(matchedClusters[z][matchedCluster], matchedCluster2)){
1239  matchedClusters[z][matchedCluster].push_back(matchedCluster2);
1240  }
1241  }
1242  }
1243  }
1244  }
1245 
1246  p.inc(eventInd);
1247  }
1248 
1249 
1250  for(int z=0; z < llEventCuts.size(); z++){
1251  std::vector<Int_t> reassignedTo(0);
1252  reassignedTo.reserve(nBases);
1253  for(int i=0; i < nBases; i++){
1254  reassignedTo.push_back(i);
1255  }
1256 
1257  for(int b=0; b < nBases; b++){
1258  if(matchedClusters[z][b].size() > 0){
1259 
1260  // here we try and gather all the matched clusters...
1261  int lastNMatched = 0;
1262  int nMatches = 0;
1263  do{
1264  lastNMatched = nMatches;
1265  nMatches = matchedClusters[z][b].size();
1266  for(int i=lastNMatched; i < nMatches; i++){
1267 
1268  int b2 = matchedClusters[z][b][i];
1269 
1270  for(int j=0; j < matchedClusters[z][b2].size(); j++){
1271  int b3 = matchedClusters[z][b2][j];
1272 
1273  if(!RootTools::vectorContainsValue(matchedClusters[z][b], b3)){
1274  matchedClusters[z][b].push_back(b3);
1275  }
1276  }
1277  }
1278  }
1279  while(lastNMatched!=nMatches);
1280 
1281  if(fDebug){
1282  std::cout << "At llEventCut = " << llEventCuts[z] << ", base " << b << " was matched with: " << matchedClusters[z][b].size() << " bases" << std::endl;
1283  if(matchedClusters[z][b].size() < 20){
1284  std::cout << "They are: ";
1285  std::sort(matchedClusters[z][b].begin(), matchedClusters[z][b].end());
1286  for(UInt_t i=0; i < matchedClusters[z][b].size(); i++){
1287  std::cout << matchedClusters[z][b][i];
1288  if(i != matchedClusters[z][b].size() - 1){
1289  std::cout << ", ";
1290  }
1291  }
1292  std::cout<< std::endl;
1293  }
1294  }
1295 
1296  for(int i=0; i < matchedClusters[z][b].size(); i++){
1297  int cluster = matchedClusters[z][b][i];
1298 
1299  if(cluster < reassignedTo[b]){
1300  reassignedTo[b] = cluster;
1301  }
1302  }
1303  }
1304  }
1305 
1306 
1307  if(fDebug){
1308  bool printed = false;
1309  for(int b=0; b < nBases; b++){
1310  if(b!=reassignedTo[b]){
1311  if(printed == false){
1312  std::cout << "At llEventCut = " << llEventCuts[z] << ", the known base cluster reassignments are as follows:" << std::endl;
1313  printed = true;
1314  }
1315  std::cout << b << "->" << reassignedTo[b] << "\n";
1316  }
1317  }
1318  }
1319 
1320  for(int eventInd=0; eventInd < events.size(); eventInd++){
1321  Event& event = events.at(eventInd);
1322  int clusterInd = -1;
1323  if(event.nearestKnownBaseLogLikelihood < llEventCuts.at(z)){
1324  clusterInd = event.nearestKnownBaseCluster;
1325  }
1326  else if(event.nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm){
1327  clusterInd = event.nearestKnownBaseClusterSurface;
1328  }
1329  if(clusterInd >= 0){
1330 
1331  Int_t reassignedCluster = reassignedTo[clusterInd];
1332  event.cluster[z] = reassignedCluster;
1333  clusters.at(z).at(reassignedCluster).numDataEvents++;
1334  }
1335  }
1336  }
1337 }
1338 
1339 
1340 // void Acclaim::Clustering::LogLikelihoodMethod::doBaseEventClustering(){
1341 
1342 // std::cout << "Info in " << __PRETTY_FUNCTION__ << ", starting..." << std::endl;
1343 // ProgressBar p(clusters.at(0).size());
1344 
1345 // const Int_t nBases = BaseList::getNumBases();
1346 
1347 
1348 // for(Int_t clusterInd=0; clusterInd < nBases; clusterInd++){
1349 // const Cluster& cluster = clusters.at(0).at(clusterInd);
1350 // Double_t clusterEasting, clusterNorthing;
1351 // RampdemReader::LonLatToEastingNorthing(cluster.longitude, cluster.latitude, clusterEasting, clusterNorthing);
1352 
1353 // std::vector<Int_t> nearbyEventIndsEastingNorthing;
1354 // double lookup[2] = {clusterEasting, clusterNorthing};
1355 // fKDTree->FindInRange(lookup, default_horizon_distance, nearbyEventIndsEastingNorthing);
1356 
1357 // for(UInt_t i=0; i < nearbyEventIndsEastingNorthing.size(); i++){
1358 // UInt_t eventInd = nearbyEventIndsEastingNorthing.at(i);
1359 
1360 // Event& event = events.at(eventInd);
1361 
1362 // Double_t distToAnita = event.usefulPat.getDistanceFromSource(cluster.latitude, cluster.longitude, cluster.altitude);
1363 // if(distToAnita < default_horizon_distance){
1364 
1365 // double ll = event.logLikelihoodFromPoint(clusters.at(0).at(clusterInd));
1366 // double surfaceSeparationKm = 1e-3*event.cartesianSeparation(clusters.at(0).at(clusterInd));
1367 
1368 // for(Int_t z=0; z < llEventCuts.size(); z++){
1369 // std::vector<Int_t> matchedClusters;
1370 // if(ll < llEventCuts.at(z)){
1371 // matchedClusters.push_back(clusterInd);
1372 // }
1373 // else if(surfaceSeparationKm < surfaceDistThresholdKm){
1374 // matchedClusters.push_back(clusterInd);
1375 // }
1376 
1377 
1378 // if(ll < event.nearestKnownBaseLogLikelihood){
1379 // event.nearestKnownBaseLogLikelihood = ll;
1380 // event.nearestKnownBaseCluster = clusterInd;
1381 // }
1382 
1383 // if(surfaceSeparationKm < event.nearestKnownBaseSurfaceSeparationKm){
1384 // event.nearestKnownBaseSurfaceSeparationKm = surfaceSeparationKm;
1385 // event.nearestKnownBaseClusterSurface = clusterInd;
1386 // }
1387 // }
1388 // }
1389 // }
1390 // p.inc(clusterInd);
1391 // }
1392 // // double ll = event.logLikelihoodFromPoint(clusters.at(0).at(clusterInd));
1393 // // double surfaceSeparationKm = 1e-3*event.cartesianSeparation(clusters.at(0).at(clusterInd));
1394 
1395 // // if(surfaceSeparationKm < event.nearestKnownBaseSurfaceSeparationKm){
1396 // // event.nearestKnownBaseSurfaceSeparationKm = surfaceSeparationKm;
1397 
1398 // // if(event.nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm){
1399 // // event.nearestKnownBaseCluster = clusterInd;
1400 // // }
1401 // // }
1402 
1403 // // if(ll < event.nearestKnownBaseLogLikelihood){
1404 // // event.nearestKnownBaseLogLikelihood = ll;
1405 // // if(event.nearestKnownBaseSurfaceSeparationKm >= surfaceDistThresholdKm){
1406 // // event.nearestKnownBaseCluster = clusterInd;
1407 // // }
1408 // // }
1409 
1410 // // }
1411 // // p.inc(clusterInd);
1412 // // }
1413 
1414 // for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1415 // Event& event = events.at(eventInd);
1416 // // std::cout << event.eventNumber << "\t" << event.nearestKnownBaseSurfaceSeparationKm << std::endl;
1417 // for(int z=0; z < event.nThresholds; z++){
1418 // // if(event.nearestKnownBaseLogLikelihood < llEventCuts.at(z) || event.nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm){
1419 // // Int_t clusterInd = event.nearestKnownBaseCluster;
1420 // // clusters.at(z).at(clusterInd).numDataEvents++;
1421 // // event.cluster[z] = clusterInd;
1422 // // }
1423 
1424 // if(event.nearestKnownBaseLogLikelihood < llEventCuts.at(z)){
1425 // Int_t clusterInd = event.nearestKnownBaseCluster;
1426 // clusters.at(z).at(clusterInd).numDataEvents++;
1427 // event.cluster[z] = clusterInd;
1428 // }
1429 // else if(event.nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm){
1430 // Int_t clusterInd = event.nearestKnownBaseClusterSurface;
1431 // clusters.at(z).at(clusterInd).numDataEvents++;
1432 // event.cluster[z] = clusterInd;
1433 // }
1434 // // else{
1435 // // // double surfaceSeparationKm = 1e-3*event.cartesianSeparation(clusters.at(0).at(clusterInd));
1436 // // // if()
1437 // // }
1438 
1439 // }
1440 // }
1441 // }
1442 
1443 
1444 
1445 
1446 
1447 
1448 
1449 
1450 
1451 
1452 
1453 
1454 size_t Acclaim::Clustering::LogLikelihoodMethod::addMcEvent(const AnitaEventSummary* sum, AnitaPol::AnitaPol_t pol, Int_t peakInd){
1455 
1456  mcEvents.push_back(McEvent(sum, pol, peakInd, llEventCuts.size()));
1457 
1458  return mcEvents.size();
1459 }
1460 
1461 
1462 
1463 
1464 
1465 
1466 size_t Acclaim::Clustering::LogLikelihoodMethod::addEvent(const AnitaEventSummary* sum, AnitaPol::AnitaPol_t pol, Int_t peakInd){
1467 
1468  events.push_back(Event(sum, pol, peakInd, llEventCuts.size()));
1469 
1470  return events.size();
1471 }
1472 
1473 
1474 
1475 
1476 
1477 
1478 
1479 
1483 void Acclaim::Clustering::LogLikelihoodMethod::readInBaseList(){
1484 
1485  if(!fReadInBaseList){
1486  std::cout << "Info in " << __FUNCTION__ << ": Initializing base list..." << std::endl;
1487 
1488  // make a copy for each llCut, just to ease the book keeping later
1489  for(UInt_t z=0; z < llEventCuts.size(); z++){
1490  for(UInt_t clusterInd=0; clusterInd < BaseList::getNumBases(); clusterInd++){
1491  const BaseList::base& base = BaseList::getBase(clusterInd);
1492  clusters.at(z).push_back(Cluster(base, clusters.at(z).size()));
1493  clusters.at(z).back().llEventCutInd = z;
1494  clusters.at(z).back().llEventCut = llEventCuts.at(z);
1495  }
1496  }
1497  }
1498  fReadInBaseList = true;
1499 }
1500 
1501 
1502 
1503 void Acclaim::Clustering::LogLikelihoodMethod::resetClusters(){
1504 
1505  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1506  for(UInt_t z=0; z < llEventCuts.size(); z++){
1507  events.at(eventInd).cluster[z] = -1;
1508  }
1509  }
1510 
1511  for(UInt_t eventInd=0; eventInd < mcEvents.size(); eventInd++){
1512  for(UInt_t z=0; z < llEventCuts.size(); z++){
1513  mcEvents.at(eventInd).cluster[z] = -1;
1514  }
1515  }
1516 
1517  clusters.resize(0);
1518 }
1519 
1520 // TGraphAntarctica* Acclaim::Clustering::LogLikelihoodMethod::makeClusterSummaryTGraph(Int_t clusterInd){
1521 
1522 // TGraphAntarctica* gr = NULL;
1523 // if(clusterInd >= 0 && clusterInd < (Int_t)clusters.size()){
1524 
1525 // TString name = TString::Format("grCluster%d", clusterInd);
1526 // TString title = TString::Format("Cluster %d; Easting (m); Northing (m)", clusterInd);
1527 // gr = new TGraphAntarctica();
1528 // gr->SetName(name);
1529 // gr->SetTitle(title);
1530 
1531 // // AnitaGeomTool* geom = AnitaGeomTool::Instance();
1532 
1533 // for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1534 // if(events.at(eventInd).cluster[0]==clusterInd){
1535 // gr->SetPoint(gr->GetN(), events.at(eventInd).longitude, events.at(eventInd).latitude);
1536 // }
1537 // }
1538 // }
1539 // return gr;
1540 // }
1541 
1542 
1543 void Acclaim::Clustering::LogLikelihoodMethod::addToHistograms(TH2D* h, TH2D* h2){
1544  for(int i = 0; i < events.size(); i++)
1545  {
1546  const Event& event = events.at(i);
1547  h->Fill(event.nearestEventSurfaceDistanceKm, event.nearestEventSurfaceLogLikelihood);
1548  }
1549  for(int i = 0; i < clusters.size(); i++)
1550  {
1551  if(llEventCuts.at(i) > 40) continue;
1552 
1553  int n_singlets = 0;
1554  for(int j = 0; j < clusters.at(i).size(); j++)
1555  {
1556  Cluster& cluster = clusters.at(i).at(j);
1557  if(cluster.numDataEvents == 1) n_singlets++;
1558  h2->Fill(llEventCuts.at(i), double(n_singlets)/double(events.size()));
1559  }
1560  }
1561 }
1562 
1563 
1564 
1565 
1566 void Acclaim::Clustering::LogLikelihoodMethod::makeSummaryTrees(){
1567 
1568 
1569  if(!fEventsAlreadyClustered){
1570 
1571  // first set the unknown cluster locations as the mean of the
1572  // cartesian positions
1573  for(UInt_t z=0; z < clusters.size(); z++){
1574  for(UInt_t clusterInd=0; clusterInd < clusters.at(z).size(); clusterInd++){
1575  Cluster& cluster = clusters.at(z).at(clusterInd);
1576 
1577  if(cluster.knownBase==0){
1578 
1579  cluster.centre[0] = 0; // reset the
1580  cluster.centre[1] = 0; // cartesian
1581  cluster.centre[2] = 0; // coordinates
1582  int eventCounter = 0;
1583 
1584  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1585  const Event& event = events.at(eventInd);
1586  if(event.cluster[z]==(Int_t)clusterInd){
1587  cluster.centre[0] += event.centre[0];
1588  cluster.centre[1] += event.centre[1];
1589  cluster.centre[2] += event.centre[2];
1590  eventCounter++;
1591  }
1592  }
1593  if(eventCounter > 0){
1594  cluster.centre[0]/=eventCounter;
1595  cluster.centre[1]/=eventCounter;
1596  cluster.centre[2]/=eventCounter;
1597  }
1598 
1600  geom->getLatLonAltFromCartesian(cluster.centre, cluster.latitude,
1601  cluster.longitude, cluster.altitude);
1602 
1603  if(eventCounter != cluster.numDataEvents){
1604  std::cerr << "Error in " << __PRETTY_FUNCTION__
1605  << ": was expecting " << cluster.numDataEvents
1606  << " in cluster " << clusterInd << ", but counted "
1607  << eventCounter << std::endl;
1608  }
1609  }
1610  // std::cout << "in summary making " << z << "\t" << clusterInd << "\t" << cluster.numDataEvents << std::endl;
1611  }
1612  }
1613 
1614 
1615  TTree* eventTree = new TTree("eventTree", "Tree of clustered ANITA events");
1616  Event* event = NULL;
1617  eventTree->Branch("event", &event);
1618 
1619  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1620  event = &events.at(eventInd);
1621 
1622  for(UInt_t z = 0; z < llEventCuts.size(); z++){
1623  if(event->cluster[z] >= 0){
1624  const Cluster& cluster = clusters.at(z).at(event->cluster[z]);
1625  getDeltaThetaDegDeltaPhiDegEventCluster(*event, cluster, event->dThetaCluster[z], event->dPhiCluster[z]);
1626  }
1627  else {
1628  // std::cerr << "Error in " << __PRETTY_FUNCTION__
1629  // << ": eventNumber " << event->eventNumber
1630  // << " has a cluster[" << z << "] number "
1631  // << event->cluster[z] << std::endl;
1632  }
1633  }
1634  eventTree->Fill();
1635  }
1636 
1637  eventTree->Write();
1638  delete eventTree;
1639  eventTree = NULL;
1640  }
1641 
1642 
1643 
1644  // monte carlo tree
1645  if(mcEvents.size() > 0){
1646  TTree* mcEventTree = new TTree("mcEventTree", "Tree of clustered Monte Carlo ANITA events");
1647  McEvent* mcEvent = NULL;
1648  mcEventTree->Branch("mcEvent", &mcEvent);
1649 
1650  for(UInt_t j=0; j < mcEvents.size(); j++){
1651  mcEvent = &mcEvents.at(j);
1652  mcEventTree->Fill();
1653  }
1654  mcEventTree->Write();
1655  delete mcEventTree;
1656  }
1657 
1658 
1659 
1660  for(UInt_t z = 0; z < llEventCuts.size(); z++){
1661  TString treeName = TString::Format("clusterTree%u", z);
1662  TString treeTitle = TString::Format("Tree of clusters with llEventCut = %lf", llEventCuts[z]);
1663  //TTree* clusterTree = new TTree(treeName, "Tree of clusters");
1664  TTree* clusterTree = new TTree(treeName, treeTitle);
1665  Cluster* cluster = NULL;
1666  clusterTree->Branch("cluster", &cluster);
1667  std::vector<Cluster> &cs = clusters.at(z);
1668  for(Int_t k=0; k < (Int_t)clusters.at(z).size(); k++){
1669  cluster = &cs.at(k);
1670  clusterTree->Fill();
1671  }
1672  }
1673 
1674 
1675 
1676 
1677  for(UInt_t eventInd=0; eventInd < hUnclusteredEvents.size(); eventInd++){
1678  if(hUnclusteredEvents.at(eventInd)){
1679  hUnclusteredEvents.at(eventInd)->Write();
1680  }
1681  }
1682 
1683 
1684  if(!fEventsAlreadyClustered){
1685  TH2DAntarctica* hEvents = new TH2DAntarctica("hEvents", "hEvents");
1686  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1687  const Event& event = events.at(eventInd);
1688  hEvents->Fill(event.longitude, event.latitude);
1689  }
1690  hEvents->Write();
1691  delete hEvents;
1692  }
1693 
1694 
1695 
1696  if(mcEvents.size() > 0){
1697  TH2DAntarctica* hMcEvents = new TH2DAntarctica("hMcEvents", "hMcEvents");
1698 
1699  for(UInt_t eventInd=0; eventInd < mcEvents.size(); eventInd++){
1700  const McEvent& mcEvent = mcEvents.at(eventInd);
1701  hMcEvents->Fill(mcEvent.longitude, mcEvent.latitude, mcEvent.weight);
1702  }
1703  hMcEvents->Write();
1704  delete hMcEvents;
1705  }
1706 
1707 }
1708 
1709 
1710 Long64_t Acclaim::Clustering::LogLikelihoodMethod::readInSummaries(const char* summaryGlob){
1711 
1712  Long64_t n = 0;
1713  if(summaryGlob){
1719  TFile* f = TFile::Open(summaryGlob);
1720  TTree* eventTree = NULL;
1721  if(f){
1722  eventTree = (TTree*) f->Get("eventTree");
1723  }
1724 
1729  if(eventTree){
1730  std::cout << "Info in " << __PRETTY_FUNCTION__ << ": reading in already clustered events: " << summaryGlob << std::endl;
1731  Event* event = NULL;
1732  eventTree->SetBranchAddress("event", &event);
1733  n = eventTree->GetEntries();
1734  events.reserve(n);
1735  ProgressBar p(n);
1736  for(Long64_t entry=0; entry < n; entry++){
1737  eventTree->GetEntry(entry);
1738  event->setupUsefulPat(false);
1739  events.push_back(*event);
1740  p.inc(entry);
1741  }
1742  std::cout << "Read in " << n << " events." << std::endl;
1743 
1744  clusters.clear();
1745  llEventCuts.clear();
1746 
1747  Acclaim::Clustering::Cluster* cluster = NULL;
1748  TTree* clusterTree = NULL;
1749  Int_t treeInd=0;
1750  do {
1751  TString treeName = TString::Format("clusterTree%d", treeInd);
1752  clusterTree = (TTree*)f->Get(treeName);
1753  if(clusterTree){
1754  clusterTree->SetBranchAddress("cluster", &cluster);
1755  const Long64_t nC = clusterTree->GetEntries();
1756 
1757  clusters.push_back(std::vector<Cluster>());
1758  clusters.back().reserve(nC);
1759 
1760  for(Long64_t entry=0; entry < nC; entry++){
1761  clusterTree->GetEntry(entry);
1762  if(entry==0){
1763  llEventCuts.push_back(cluster->llEventCut);
1764  }
1765  clusters.back().push_back(*cluster);
1766  }
1767  treeInd++;
1768  }
1769  } while(clusterTree!=NULL);
1770  f->Close();
1771 
1772 
1773 
1774  std::cout << "Info in " << __PRETTY_FUNCTION__ << ", overwrote llEventCuts to: ";
1775  for(UInt_t z=0; z < llEventCuts.size(); z++){
1776  std::cout << llEventCuts[z];
1777  if(z < llEventCuts.size() - 1){
1778  std::cout << ", ";
1779  }
1780  }
1781  std::cout << std::endl;
1782 
1783 
1784  // make sure to not do event clustering again, or read in base list,
1785  // that hard work was already done...
1786  fEventsAlreadyClustered = true;
1787  fReadInBaseList = true;
1788  }
1789 
1790  else{
1791  ThermalChain tc(summaryGlob);
1792  ProgressBar pElist(1);
1793 
1794  // TCut hack("eventNumber==14545077||eventNumber==15202247");
1795  // TCut goodPosition = "(onContinent > 0 && onIceShelf==0)";
1796  // tc.setCut(goodPosition + !ThermalTree::isAboveHorizontal + ThermalTree::passAllQualityCuts + ThermalTree::isNotTaggedAsPulser + ThermalTree::fisherCut + !ThermalTree::closeToHiCal);
1797  // tc.setCut(!ThermalTree::isAboveHorizontal + ThermalTree::passAllQualityCuts + ThermalTree::isNotTaggedAsPulser + ThermalTree::fisherCut + !ThermalTree::closeToHiCal);
1798  // tc.setCut(!ThermalTree::isAboveHorizontal + ThermalTree::passAllQualityCuts + ThermalTree::isNotTaggedAsPulser + ThermalTree::fisherCut + !ThermalTree::closeToHiCal);
1799  // tc.setCut(!ThermalTree::isAboveHorizontal + ThermalTree::passAllQualityCuts + ThermalTree::isNotTaggedAsPulser + ThermalTree::fisherCut + !ThermalTree::closeToHiCal + ThermalTree::closeToMC);
1800  // tc.setCut(!ThermalTree::isAboveHorizontal + ThermalTree::passAllQualityCuts + ThermalTree::isNotTaggedAsPulser + ThermalTree::fisherCut + ThermalTree::closeToMC);
1801  tc.setCut(ThermalTree::isTaggedAsWaisPulser + ThermalTree::closeToWais);
1802  // tc.setCut(hack);
1803 
1804  n = tc.N();
1805  std::cout << "There are " << n << " entries matching the selection" << std::endl;
1806 
1807  ProgressBar p(n);
1808  for(Long64_t entry=0; entry < n; entry++){
1809  tc.getEntry(entry);
1810 
1811  if(entry==0){
1812  std::cout << tc.weight << std::endl;
1813  if(tc.weight == 1)
1814  events.reserve(events.size()+n);
1815  else{
1816  mcEvents.reserve(mcEvents.size()+n);
1817  }
1818  }
1819 
1820  if(tc.weight==1){
1821  events.push_back(Event(static_cast<int>(tc.pol), static_cast<int>(tc.peakInd),
1822  tc.peak_phi, tc.peak_theta,
1823  (int)llEventCuts.size(), tc.eventNumber, tc.run,
1824  tc.anita_longitude, tc.anita_latitude, tc.anita_altitude, tc.anita_heading,
1825  tc.coherent_filtered_snr));
1826  }
1827  else{
1828  mcEvents.push_back(McEvent(tc.weight, tc.mc_energy, static_cast<int>(tc.pol), static_cast<int>(tc.peakInd),
1829  tc.peak_phi, tc.peak_theta,
1830  (int)llEventCuts.size(), tc.eventNumber, tc.run,
1831  tc.anita_longitude, tc.anita_latitude, tc.anita_altitude, tc.anita_heading,
1832  tc.coherent_filtered_snr));
1833  }
1834  p.inc(entry);
1835  }
1836  }
1837  }
1838  return n;
1839 }
1840 
1841 Long64_t Acclaim::Clustering::LogLikelihoodMethod::readInTMVATreeSummaries(const char* summaryGlob, bool isMC){
1842 
1843  Long64_t n = 0;
1844  if(summaryGlob){
1850  TFile* f = TFile::Open(summaryGlob);
1851  TTree* eventTree = NULL;
1852  if(f){
1853  eventTree = (TTree*) f->Get("eventTree");
1854  }
1855 
1860  if(eventTree){
1861  std::cout << "Info in " << __PRETTY_FUNCTION__ << ": reading in already clustered events: " << summaryGlob << std::endl;
1862  Event* event = NULL;
1863  eventTree->SetBranchAddress("event", &event);
1864  n = eventTree->GetEntries();
1865  events.reserve(n);
1866  ProgressBar p(n);
1867  for(Long64_t entry=0; entry < n; entry++){
1868  eventTree->GetEntry(entry);
1869  event->setupUsefulPat(false);
1870  events.push_back(*event);
1871  p.inc(entry);
1872  }
1873  std::cout << "Read in " << n << " events." << std::endl;
1874 
1875  clusters.clear();
1876  llEventCuts.clear();
1877 
1878  Acclaim::Clustering::Cluster* cluster = NULL;
1879  TTree* clusterTree = NULL;
1880  Int_t treeInd=0;
1881  do {
1882  TString treeName = TString::Format("clusterTree%d", treeInd);
1883  clusterTree = (TTree*)f->Get(treeName);
1884  if(clusterTree){
1885  clusterTree->SetBranchAddress("cluster", &cluster);
1886  const Long64_t nC = clusterTree->GetEntries();
1887 
1888  clusters.push_back(std::vector<Cluster>());
1889  clusters.back().reserve(nC);
1890 
1891  for(Long64_t entry=0; entry < nC; entry++){
1892  clusterTree->GetEntry(entry);
1893  if(entry==0){
1894  llEventCuts.push_back(cluster->llEventCut);
1895  }
1896  clusters.back().push_back(*cluster);
1897  }
1898  treeInd++;
1899  }
1900  } while(clusterTree!=NULL);
1901  f->Close();
1902 
1903 
1904 
1905  std::cout << "Info in " << __PRETTY_FUNCTION__ << ", overwrote llEventCuts to: ";
1906  for(UInt_t z=0; z < llEventCuts.size(); z++){
1907  std::cout << llEventCuts[z];
1908  if(z < llEventCuts.size() - 1){
1909  std::cout << ", ";
1910  }
1911  }
1912  std::cout << std::endl;
1913 
1914 
1915  // make sure to not do event clustering again, or read in base list,
1916  // that hard work was already done...
1917  fEventsAlreadyClustered = true;
1918  fReadInBaseList = true;
1919  } else {
1920  TChain* t = new TChain("sumTree");
1921  t->Add(summaryGlob);
1922 
1923  float decoImpulsivity, pol, peakInd, run, anita_longitude, anita_latitude, anita_altitude, anita_heading, peak_phi, peak_theta, coherent_filtered_snr, F, lastFew, weight, mc_energy, isWais;
1924  UInt_t eventNumber;
1925  Int_t evNum;
1926 
1927  t->SetBranchAddress("pol", &pol);
1928  t->SetBranchAddress("ind", &peakInd);
1929  t->SetBranchAddress("weight", &weight);
1930  t->SetBranchAddress("energy", &mc_energy);
1931  t->SetBranchAddress("phi", &peak_phi);
1932  t->SetBranchAddress("theta", &peak_theta);
1933  t->SetBranchAddress("run", &run);
1934  t->SetBranchAddress("anita_latitude", &anita_latitude);
1935  t->SetBranchAddress("anita_longitude", &anita_longitude);
1936  t->SetBranchAddress("anita_altitude", &anita_altitude);
1937  t->SetBranchAddress("anita_heading", &anita_heading);
1938  t->SetBranchAddress("snr", &coherent_filtered_snr);
1939  t->SetBranchAddress("eventNumber", &evNum);
1940  t->SetBranchAddress("lastFewDigits", &lastFew);
1941  t->SetBranchAddress("F", &F);
1942  t->SetBranchAddress("isWais", &isWais);
1943  t->SetBranchAddress("decoImpulsivity", &decoImpulsivity);
1944 
1945  t->Draw(">>fEntryList", fCut, "entrylist");
1946  fEntryList = (TEntryList*) gDirectory->Get("fEntryList");
1947  t->SetEntryList(fEntryList);
1948  printf("%d entries loaded\n", fEntryList->GetN());
1949 
1950  for(Long64_t entry=0; entry < fEntryList->GetN(); entry++){
1951  n++;
1952  t->GetEntry(t->GetEntryNumber(entry));
1953  eventNumber = UInt_t(int(evNum/10000)*10000 + int(lastFew));
1954  if(fCutHical && Hical2::isHical(eventNumber, FFTtools::wrap(anita_heading - peak_phi, 360, 0), coherent_filtered_snr)) continue;
1955  if(!isMC && peak_theta > 0)
1956  {
1957  // switches theta convention (i used the UCorrelator convention for theta)
1958  peak_theta = -1* peak_theta;
1959  events.push_back(Event(static_cast<int>(pol), static_cast<int>(peakInd),
1960  (double)peak_phi, (double)peak_theta,
1961  (int)llEventCuts.size(), eventNumber, (int)run,
1962  (double)anita_longitude, (double)anita_latitude, (double)anita_altitude, (double)anita_heading,
1963  (double)coherent_filtered_snr));
1964  if(fSelfLLMax > 0 && events.back().selfLogLikelihood > fSelfLLMax) events.pop_back();
1965  }
1966  if(isMC)
1967  {
1968  if(tr3->Integer(1000) >= fPercentOfMC) continue;
1969  // switches theta convention
1970  peak_theta = -1* peak_theta;
1971  mcEvents.push_back(McEvent((double)weight, (double)mc_energy, static_cast<int>(pol), static_cast<int>(peakInd),
1972  (double)peak_phi, (double)peak_theta,
1973  (int)llEventCuts.size(), eventNumber, (int)run,
1974  (double)anita_longitude, (double)anita_latitude, (double)anita_altitude, (double)anita_heading,
1975  (double)coherent_filtered_snr));
1976  }
1977  }
1978  delete t;
1979  }
1980  }
1981  return n;
1982 }
1983 
1984 void Acclaim::Clustering::LogLikelihoodMethod::readInSummariesForTesting(const char* summaryGlob){
1985 
1986  Long64_t n = 0;
1987  if(summaryGlob){
1993  fChain = new TChain("sumTree");
1994  fChain->Add(summaryGlob);
1995 
1996  float decoImpulsivity, pol, peakInd, run, anita_longitude, anita_latitude, anita_altitude, anita_heading, peak_phi, peak_theta, coherent_filtered_snr, F, lastFew, weight, mc_energy, isWais;
1997  UInt_t eventNumber;
1998  Int_t evNum;
1999 
2000  fChain->SetBranchAddress("pol", &pol);
2001  fChain->SetBranchAddress("ind", &peakInd);
2002  fChain->SetBranchAddress("weight", &weight);
2003  fChain->SetBranchAddress("energy", &mc_energy);
2004  fChain->SetBranchAddress("phi", &peak_phi);
2005  fChain->SetBranchAddress("theta", &peak_theta);
2006  fChain->SetBranchAddress("run", &run);
2007  fChain->SetBranchAddress("anita_latitude", &anita_latitude);
2008  fChain->SetBranchAddress("anita_longitude", &anita_longitude);
2009  fChain->SetBranchAddress("anita_altitude", &anita_altitude);
2010  fChain->SetBranchAddress("anita_heading", &anita_heading);
2011  fChain->SetBranchAddress("snr", &coherent_filtered_snr);
2012  fChain->SetBranchAddress("eventNumber", &evNum);
2013  fChain->SetBranchAddress("lastFewDigits", &lastFew);
2014  fChain->SetBranchAddress("F", &F);
2015  fChain->SetBranchAddress("isWais", &isWais);
2016  fChain->SetBranchAddress("decoImpulsivity", &decoImpulsivity);
2017 
2018  fChain->Draw(">>fEntryList", fCut, "entrylist");
2019  fEntryList = (TEntryList*) gDirectory->Get("fEntryList");
2020  fChain->SetEntryList(fEntryList);
2021  printf("%d entries loaded\n", fEntryList->GetN());
2022  }
2023  return;
2024 }
2025 
2026 void Acclaim::Clustering::LogLikelihoodMethod::pickEventsFromList(int n_in_cluster)
2027 {
2028  float decoImpulsivity, pol, peakInd, run, anita_longitude, anita_latitude, anita_altitude, anita_heading, peak_phi, peak_theta, coherent_filtered_snr, F, lastFew, weight, mc_energy, isWais;
2029  UInt_t eventNumber;
2030  Int_t evNum;
2031 
2032  fChain->SetBranchAddress("pol", &pol);
2033  fChain->SetBranchAddress("ind", &peakInd);
2034  fChain->SetBranchAddress("weight", &weight);
2035  fChain->SetBranchAddress("energy", &mc_energy);
2036  fChain->SetBranchAddress("phi", &peak_phi);
2037  fChain->SetBranchAddress("theta", &peak_theta);
2038  fChain->SetBranchAddress("run", &run);
2039  fChain->SetBranchAddress("anita_latitude", &anita_latitude);
2040  fChain->SetBranchAddress("anita_longitude", &anita_longitude);
2041  fChain->SetBranchAddress("anita_altitude", &anita_altitude);
2042  fChain->SetBranchAddress("anita_heading", &anita_heading);
2043  fChain->SetBranchAddress("snr", &coherent_filtered_snr);
2044  fChain->SetBranchAddress("eventNumber", &evNum);
2045  fChain->SetBranchAddress("lastFewDigits", &lastFew);
2046  fChain->SetBranchAddress("F", &F);
2047  fChain->SetBranchAddress("isWais", &isWais);
2048  fChain->SetBranchAddress("decoImpulsivity", &decoImpulsivity);
2049 
2050  TBits * bits = new TBits(fEntryList->GetN());
2051 
2052  int i = 0;
2053  while(i < n_in_cluster){
2054  Int_t j = tr3->Uniform(0, fEntryList->GetN());
2055  if(bits->TestBitNumber(j)) continue;
2056  bits->SetBitNumber(j);
2057  fChain->GetEntry(fChain->GetEntryNumber(j));
2058  eventNumber = UInt_t(int(evNum/10000)*10000 + int(lastFew));
2059  if(peak_theta > 0)
2060  {
2061  i++;
2062  // switches theta convention (i used the UCorrelator convention for theta)
2063  peak_theta = -1* peak_theta;
2064  events.push_back(Event(static_cast<int>(pol), static_cast<int>(peakInd),
2065  (double)peak_phi, (double)peak_theta,
2066  (int)llEventCuts.size(), eventNumber, (int)run,
2067  (double)anita_longitude, (double)anita_latitude, (double)anita_altitude, (double)anita_heading,
2068  (double)coherent_filtered_snr));
2069  }
2070  }
2071  delete bits;
2072 }
2073 
2074 
2075 
2079 void Acclaim::Clustering::LogLikelihoodMethod::testTriangleInequality(){
2080 
2081  const int numENNeighbours = 100;
2082  std::vector<Int_t> indices;
2083  std::vector<Int_t> enSeparation;
2084 
2085  ProgressBar p(events.size());
2086  for(UInt_t i=0; i < events.size(); i++){
2087  const Event& event_i = events.at(i);
2088  for(UInt_t j=0; j < numENNeighbours; j++){
2089  const Event& event_j = events.at(j);
2090 
2091  Double_t d_ij = dMin(&event_i, &event_j);
2092 
2093  for(UInt_t k=0; k < numENNeighbours; k++){
2094  const Event& event_k = events.at(k);
2095  Double_t d_ik = dMin(&event_i, &event_k);
2096  Double_t d_jk = dMin(&event_j, &event_k);
2097 
2098  if(d_ik > d_ij + d_jk){
2099  std::cerr << i << "\t" << j << "\t" << k << " fails!" << std::endl;
2100  }
2101  }
2102  }
2103  p.inc(i, events.size());
2104  }
2105 }
2106 
2107 
2108 
2109 
2110 void Acclaim::Clustering::LogLikelihoodMethod::initKDTree(){
2111 
2112  if(fDebug){
2113  std::cout << "About to build KDTree" << std::endl;
2114  }
2115  fEventEastings.clear();
2116  fEventNorthings.clear();
2117  fEventEastings.reserve(events.size());
2118  fEventNorthings.reserve(events.size());
2119  for(UInt_t eventInd = 0; eventInd < events.size(); eventInd++){
2120  const Event& event = events.at(eventInd);
2121  if(event.eventEventClustering){
2122  fEventEastings.push_back(event.easting);
2123  fEventNorthings.push_back(event.northing);
2124  }
2125  }
2126 
2127  const int binSize = 100000; // meters... too small?
2128  if(fKDTree){
2129  delete fKDTree;
2130  }
2131  fKDTree = new TKDTreeID(events.size(), 2, binSize);
2132  fKDTree->SetData(0, &fEventEastings[0]);
2133  fKDTree->SetData(1, &fEventNorthings[0]);
2134  fKDTree->Build();
2135 
2136  if(fDebug){
2137  std::cout << "Built!" << std::endl;
2138 
2139  const int nTest = 10;
2140  std::vector<int> nns(nTest);
2141  std::vector<double> dists(nTest);
2142  fKDTree->FindNearestNeighbors(&events.at(0).easting, nTest, &nns[0], &dists[0]);
2143  std::cout << "The ten nearest neighbours of events[0] at " << events[0].longitude << "," << events[0].latitude << " are:" << std::endl;
2144  for(int i=0; i < nTest; i++){
2145  std::cout << "events[" << nns[i] << "] at " << events[nns[i]].longitude << ", " << events[nns[i]].latitude << std::endl;
2146  }
2147 
2148  std::vector<Int_t> neighbours;
2149  const double rangeEN = 1000e3;
2150  double lookup[2] = {events.at(0).easting, events.at(0).northing};
2151  fKDTree->FindInRange(lookup, rangeEN, neighbours);
2152  std::cout << "There are " << neighbours.size() << " events within a sphere of radius " << rangeEN << std::endl;
2153  }
2154 
2155 
2156 
2157 
2158  // const int n = 2;
2159  // std::vector<int> nns(n);
2160  // std::vector<double> dists(n);
2161 
2162  // Acclaim::ProgressBar p(events.size());
2163  // for(Long64_t eventInd=0; eventInd < events.size(); eventInd++){
2164  // Event& event = events.at(eventInd);
2165  // fKDTree->FindNearestNeighbors(&event.easting, n, &nns[0], &dists[0]);
2166  // event.nearestEventSurfaceDistanceKm = 1e-3*dists.at(1);
2167  // const Event& event2 = events.at(nns.at(1));
2168  // event.nearestEventSurfaceEventNumber = event2.eventNumber;
2169  // events.at(eventInd).nearestEventSurfaceLogLikelihood = dFit(&event, &event2);
2170 
2171  // p.inc(eventInd);
2172  // }
2173 }
2174 
2175 
2176 
2177 
2178 
2179 
2180 void Acclaim::Clustering::LogLikelihoodMethod::testSmallClustersFromPointSource(){
2181 
2182  UInt_t firstEventNumber = events.at(0).eventNumber;
2183  UInt_t lastEventNumber = events.at(0).eventNumber;
2184  for(UInt_t eventInd=1; eventInd < events.size(); eventInd++){
2185  UInt_t eventNumber = events.at(eventInd).eventNumber;
2186  if(eventNumber > lastEventNumber){
2187  lastEventNumber = eventNumber;
2188  }
2189  if(eventNumber < firstEventNumber){
2190  firstEventNumber = eventNumber;
2191  }
2192  }
2193  TRandom3 randy(123);
2194 
2195  const int fakeClusterSize = 2;
2196  const int nTrials = 1000;
2197 
2198  TH2D* hClusterTrials = new TH2D("hClusterTrials", "clustering trials",
2199  llEventCuts.size(), 0, llEventCuts.size(),
2200  fakeClusterSize, 1, fakeClusterSize+1);
2201 
2202 
2203  for(int threshInd=0; threshInd < llEventCuts.size(); threshInd++){
2204  TString bl = TString::Format("%4.0lf", llEventCuts.at(threshInd));
2205  hClusterTrials->GetXaxis()->SetBinLabel(threshInd+1, bl);
2206  }
2207 
2208 
2209  std::vector<Event> tempEvents;
2210  tempEvents.reserve(events.size());
2211  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
2212  tempEvents.push_back(events.at(eventInd));
2213  }
2214 
2215  // pick random numbers
2216  ProgressBar p(nTrials);
2217  for(int trialInd=0; trialInd < nTrials; trialInd++){
2218 
2219 
2220  events.clear();
2221 
2222  for(UInt_t z=0; z < clusters.size(); z++){
2223  clusters.at(z).clear();
2224  }
2225 
2226  for(UInt_t i=0; i < fakeClusterSize; i++){
2227  UInt_t eventInd = randy.Uniform(tempEvents.size());
2228  events.push_back(tempEvents.at(eventInd));
2229  }
2230  initKDTree();
2231 
2232  doEventEventClustering();
2233 
2234  for(UInt_t z=0; z < clusters.size(); z++){
2235  hClusterTrials->Fill(z, clusters.at(z).size());
2236  }
2237 
2238  p.inc(trialInd);
2239  }
2240 }
2241 
2242 
2243 
2244 
2245 
2246 void Acclaim::Clustering::LogLikelihoodMethod::makeAndWriteNSquaredEventEventHistograms(){
2247 
2248 
2249  fROOTgErrorIgnoreLevel = gErrorIgnoreLevel;
2250  gErrorIgnoreLevel = 1001;
2251 
2252  ProgressBar p(events.size());
2253  UInt_t firstEventNumber = events.at(0).eventNumber;
2254  UInt_t lastEventNumber = events.at(0).eventNumber;
2255  for(UInt_t eventInd=1; eventInd < events.size(); eventInd++){
2256  UInt_t eventNumber = events.at(eventInd).eventNumber;
2257  if(eventNumber > lastEventNumber){
2258  lastEventNumber = eventNumber;
2259  }
2260  if(eventNumber < firstEventNumber){
2261  firstEventNumber = eventNumber;
2262  }
2263  }
2264 
2265  TH1D* hWais = new TH1D("hWais", "Log-likelihood - WAIS", 2048, 0, 2048);
2266  AnitaVersion::set(3);
2267  double waisLon = AnitaLocations::getWaisLongitude();
2268  double waisLat = AnitaLocations::getWaisLatitude();
2269  double waisModelAlt = RampdemReader::BilinearInterpolatedSurfaceAboveGeoid(waisLon, waisLat);
2270 
2271  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
2272  const Event& event = events.at(eventInd);
2273  Double_t llWais = event.logLikelihoodFromPoint(waisLon, waisLat, waisModelAlt, true);
2274  hWais->Fill(llWais);
2275  }
2276 
2277  TRandom3 randy(123);
2278 
2279 
2280  const Int_t nBins = 1024; //(lastEventNumber + 1) - firstEventNumber;
2281  // const Int_t stride = 50;
2282  std::cout << nBins << "\t" << firstEventNumber << "\t" << lastEventNumber << std::endl;
2283  TH2D* hUnfit = new TH2D("hUnfit_d_vs_pointingAngle", "", 1024, 0, 180, 1024, 0, 1024);
2284  TH2D* hFit = new TH2D("hFit_d_vs_pointingAngle", "", 1024, 0, 180, 1024, 0, 1024);
2285 
2286  TH2D* hFitVsSumOfSelfLLs = new TH2D("hFit_vs_sumOfSelfLLs", "", 1024, 0, 50, 1024, 0, 1024);
2287 
2288  TH2D* hFitVsUnfitted = new TH2D("hFit_vs_unfit", "Fitted vs. unfitted WAIS event-event log-likelihood; Unfitted log-likelihood; Fitted log-likelihood", 1024, 0, 1024, 1024, 0, 1024);
2289  TH1D* hUnfitMinusFit = new TH1D("hFit_minus_unfit", "(Unfitted - fitted) WAIS event-event log-likelihood; #delta (log likelihood)", 1024, -512, 512);
2290 
2291  TH2DAntarctica* hEventPos = new TH2DAntarctica("hEventPos", "Event Position");
2292  TH2DAntarctica* hFittedPos = new TH2DAntarctica("hFittedPos", "Fitted Pair position");
2293 
2294  TGraphAntarctica* grAnita = new TGraphAntarctica();
2295  // TGraphAntarctica* grEventPos = new TGraphAntarctica();
2296  // TGraphAntarctica* grFittedPos = new TGraphAntarctica();
2297 
2298  const int fakeClusterSize = 2;
2299 
2300  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
2301  const Event& event1 = events.at(eventInd);
2302 
2303  // if(event1.eventNumber!=fTestEvent1) continue;
2304 
2305  TVector3 event1Pos = AntarcticCoord(AntarcticCoord::WGS84, event1.latitude, event1.longitude, event1.altitude).v();
2306  TVector3 anita1Pos = AntarcticCoord(AntarcticCoord::WGS84, event1.anita.latitude, event1.anita.longitude, event1.anita.altitude).v();
2307  TVector3 anitaToEvent1 = event1Pos - anita1Pos;
2308 
2309  std::vector<Int_t> event2Inds(fakeClusterSize-1);
2310  for(UInt_t eventInd2=0; eventInd2 < event2Inds.size(); eventInd2++){
2311  event2Inds.at(eventInd2) = randy.Uniform(0, events.size());
2312  }
2313 
2314  for(UInt_t eventInd2=0; eventInd2 < event2Inds.size(); eventInd2++){
2315  const Event& event2 = events.at(eventInd2);
2316 
2317  if(event1.eventNumber==fTestEvent1 && event2.eventNumber==fTestEvent2){
2318  std::cerr << "Info in " << __PRETTY_FUNCTION__ << " mapping parameter space around WAIS for event pair !"
2319  << fTestEvent1 << " and " << fTestEvent2 << std::endl;
2320  AnitaVersion::set(3);
2321  double waisEasting, waisNorthing;
2322  RampdemReader::LonLatToEastingNorthing(AnitaLocations::getWaisLongitude(), AnitaLocations::getWaisLatitude(), waisEasting, waisNorthing);
2323  double delta = 700e3;
2324  const int nBins = 256;
2325  TH2D* hParams = new TH2D("hSingleEventTest", "Event-event fitted log likelihood; Easting (m); Northing (m); L_{sum}",
2326  nBins, waisEasting-delta, waisEasting+delta,
2327  nBins, waisNorthing-delta, waisNorthing+delta);
2328  grAnita->SetPoint(grAnita->GetN(), event1.usefulPat.longitude, event1.usefulPat.latitude);
2329  grAnita->SetPoint(grAnita->GetN(), event2.usefulPat.longitude, event2.usefulPat.latitude);
2330 
2331  fFitEvent1s.at(OpenMP::thread()) = &event1;
2332  fFitEvent2s.at(OpenMP::thread()) = &event2;
2333  double params[2] = {0,0};
2334  for(int by=1; by <= hParams->GetNbinsY(); by++){
2335  params[1] = FITTER_INPUT_SCALING*hParams->GetYaxis()->GetBinCenter(by);
2336  for(int bx=1; bx <= hParams->GetNbinsX(); bx++){
2337  params[0] = FITTER_INPUT_SCALING*hParams->GetXaxis()->GetBinCenter(bx);
2338  double ll = evalPairLogLikelihoodAtLonLat(params);
2339  hParams->Fill(FITTER_OUTPUT_SCALING*params[0], FITTER_OUTPUT_SCALING*params[1], ll);
2340  }
2341  }
2342  std::cout << "done!" << std::endl;
2343  hParams->Write();
2344  delete hParams;
2345 
2346  TGraphAntarctica* grTestEvent1 = new TGraphAntarctica();
2347  grTestEvent1->SetPointEastingNorthing(0, event1.easting, event1.northing);
2348  grTestEvent1->SetName("grTestEvent1");
2349  grTestEvent1->Write();
2350  delete grTestEvent1;
2351 
2352  TGraphAntarctica* grTestEvent2 = new TGraphAntarctica();
2353  grTestEvent2->SetPointEastingNorthing(0, event2.easting, event2.northing);
2354  grTestEvent2->SetName("grTestEvent2");
2355  grTestEvent2->Write();
2356  delete grTestEvent2;
2357 
2358  TGraphAntarctica* grWaisTrue = new TGraphAntarctica();
2360  grWaisTrue->SetName("grWaisTrue");
2361  grWaisTrue->Write();
2362  delete grWaisTrue;
2363  }
2364 
2365  TVector3 event2Pos = AntarcticCoord(AntarcticCoord::WGS84, event2.latitude, event2.longitude, event2.altitude).v();
2366  TVector3 anita2Pos = AntarcticCoord(AntarcticCoord::WGS84, event2.anita.latitude, event2.anita.longitude, event2.anita.altitude).v();
2367  TVector3 anitaToEvent2 = event2Pos - anita2Pos;
2368 
2369  double dist = dMin(&event1, &event2);
2370  Double_t angleBetweenEvents = TMath::RadToDeg()*anitaToEvent1.Angle(anitaToEvent2);
2371 
2372  hUnfit->Fill(angleBetweenEvents, dist);
2373 
2374  double distFitted = dFit(&event1, &event2);
2375  hFit->Fill(angleBetweenEvents, distFitted);
2376 
2377  hFitVsSumOfSelfLLs->Fill(event1.selfLogLikelihood+event2.selfLogLikelihood, distFitted);
2378 
2379  if(event1.theta > -5.5 && event2.theta > -5.5){
2380  std::cout << event1.eventNumber << "\t" << event2.eventNumber << std::endl;
2381  }
2382 
2383  double fitLon, fitLat;
2384  int t = OpenMP::thread();
2385  RampdemReader::EastingNorthingToLonLat(fFitEastings.at(t), fFitNorthings.at(t), fitLon, fitLat);
2386  hFittedPos->Fill(fitLon, fitLat);
2387  hEventPos->Fill(event1.longitude, event1.latitude);
2388 
2389  hFitVsUnfitted->Fill(dist, distFitted);
2390  hUnfitMinusFit->Fill(dist - distFitted);
2391  }
2392  p.inc(eventInd, events.size());
2393  }
2394 
2395  grAnita->SetName("grAnita");
2396  grAnita->Write();
2397  delete grAnita;
2398 
2399  hFittedPos->Write();
2400  delete hFittedPos;
2401 
2402  hEventPos->Write();
2403  delete hEventPos;
2404 
2405  hFitVsSumOfSelfLLs->Write();
2406  delete hFitVsSumOfSelfLLs;
2407 
2408  hWais->Write();
2409  delete hWais;
2410 
2411  hUnfit->Write();
2412  delete hUnfit;
2413 
2414  hFit->Write();
2415  delete hFit;
2416 
2417  hFitVsUnfitted->Write();
2418  delete hFitVsUnfitted;
2419 
2420  hUnfitMinusFit->Write();
2421  delete hUnfitMinusFit;
2422 
2423  gErrorIgnoreLevel = fROOTgErrorIgnoreLevel;
2424 }
2425 
2426 
2427 
2428 
2429 
2433 void Acclaim::Clustering::LogLikelihoodMethod::doEventEventClustering(){
2434 
2435  double llFitThreshold = TMath::MinElement(llEventCuts.size(), &llEventCuts.at(0)); // fit if greater than this
2436  double llNearbyThreshold = TMath::MaxElement(llEventCuts.size(), &llEventCuts.at(0)); // ignore if greater than this
2437 
2438  std::cout << __PRETTY_FUNCTION__ << std::endl;
2439  std::cout << "llNearbyThreshold = " << llNearbyThreshold << ", llFitThreshold = " << llFitThreshold << std::endl;
2440  // move swapping global error level stuff out of parallelized loop
2441  // this used to be around the minimizer->minimize()
2442  fROOTgErrorIgnoreLevel = gErrorIgnoreLevel;
2443  gErrorIgnoreLevel = 1001;
2444 
2445  TStopwatch timer;
2446  timer.Start(kTRUE);
2447 
2448  Event* event1 = nextEvent();
2449  Int_t loopCount = 0;
2450 
2451  while(event1){
2452  // update number done...
2453  UInt_t numEventsProcessed = 0;
2454  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
2455  if(events.at(eventInd).cluster[0] > -1){
2456  numEventsProcessed++;
2457  }
2458  }
2459  std::cerr << "Have found a cluster for " << numEventsProcessed << " of " << events.size()
2460  << " events, " << (events.size() - numEventsProcessed) << " remaining.\n";
2461  std::cout << "Starting loop = " << loopCount << std::endl;
2462 
2463  if(event1->eventEventClustering){
2464 
2465  // first look up events close by in Easting/Northing
2466  std::vector<Int_t> nearbyEventsInds;
2467  double lookup[2] = {event1->easting, event1->northing};
2468  fKDTree->FindInRange(lookup, default_range_easting_northing, nearbyEventsInds);
2469 
2470 
2471 
2472  // prepare parallelized storage things
2473  const int mt = OpenMP::getMaxThreads();
2474  std::vector<std::vector<UInt_t> > event2Inds[mt]; // [t][z].size()==numMatchedClusters
2475  std::vector<std::vector<Int_t> > matchedClusters[mt]; // [t][z].size()==numMatchedClusters
2476  for(int t=0; t < mt; t++){
2477  matchedClusters[t] = std::vector<std::vector<Int_t> >(event1->nThresholds, std::vector<Int_t>());
2478  event2Inds[t] = std::vector<std::vector<UInt_t> >(event1->nThresholds, std::vector<UInt_t>());
2479  }
2480 
2481 
2482 
2483  // Add event1 event to the list of "matched clusters"
2484  for(int z=0; z < event1->nThresholds; z++){
2485  if(event1->cluster[z] > -1){
2486  if(z==0){
2487  std::cerr << "I think this is false for all events and this statement should never get printed..." << std::endl;
2488  std::cerr << event1->eventNumber << "\t" << event1->cluster[0] << std::endl;
2489  }
2490  for(int t=0; t < mt; t++){
2491  matchedClusters[t][z].push_back(event1->cluster[z]);
2492  }
2493  }
2494  }
2495 
2496 
2497  std::map<std::pair<Int_t, Int_t>, Double_t> bestUnfittedLogLikelihoodThisClusterThisHistBin[mt];
2498 
2499  // Loop over nearby events in easting/northing
2500  UInt_t n2 = OpenMP::isEnabled ? ceil(double(nearbyEventsInds.size())/mt) : nearbyEventsInds.size();
2501  Int_t innerLoopCounter = 0;
2502  std::cerr << "There are " << nearbyEventsInds.size() << " nearby events to process." << std::endl;
2503  ProgressBar p2(n2);
2504 
2505 #pragma omp parallel for schedule(dynamic, 1)
2506  for(UInt_t i=0; i < nearbyEventsInds.size(); i++){
2507  int event2Ind = nearbyEventsInds[i];
2508  Event& event2 = events.at(event2Ind);
2509 
2510  int t = OpenMP::thread();
2511 
2512  if(event1->eventNumber != event2.eventNumber && event2.eventEventClustering){
2513 
2514  // you must check against this if event2 isn't already in a cluster
2515  // or event2 isn't in a cluster that you've already matched with at the lowest threshold
2516 
2517  // i.e. ONLY don't do an event if you've already matched against
2518  // another event from the same cluster at the lowest threshold
2519  // if(event2.cluster[0] < 0 || std::find(matchedClusters[t][0].begin(), matchedClusters[t][0].end(), event2.cluster[0])==matchedClusters[t][0].end())
2520 
2521  // If the clustering is working like it should
2522 
2523  if(event2.cluster[0] < 0 || !RootTools::vectorContainsValue(matchedClusters[t][0], event2.cluster[0])){
2524 
2525  Double_t ll = dMin(event1, &event2);
2526  Double_t surfaceDist = 1e-3*event1->cartesianSeparation(event2);
2527 
2528  // Double_t llAsym = dAsym(&event2, event1) + event1->selfLogLikelihood;
2529 
2530  // add extra condition here?
2531  // if that's smaller than the minLL for event2's cluster on that hist-bin...
2532  // then do the fit, otherwise, no
2533  // std::pair<Int_t, Int_t> key = std::make_pair(event2.cluster[0], event2.antarcticaHistBin);
2534  // std::map<std::pair<Int_t ,Int_t>, Double_t>::iterator it = bestUnfittedLogLikelihoodThisClusterThisHistBin[t].find(key);
2535  // bool tryTheFit = false;
2536  // if(it==bestUnfittedLogLikelihoodThisClusterThisHistBin[t].end()){
2537  // bestUnfittedLogLikelihoodThisClusterThisHistBin[t][key] = llAsym;
2538  // tryTheFit = true;
2539  // }
2540  // else if(it!=bestUnfittedLogLikelihoodThisClusterThisHistBin[t].end() && llAsym < it->second){
2541  // it->second = llAsym;
2542  // tryTheFit = true;
2543  // }
2544  // if(tryTheFit && llAsym > llFitThreshold)
2545  if(ll > llFitThreshold && surfaceDist > surfaceDistThresholdKm){
2546  ll = dFit(event1, &event2);
2547  }
2548 
2549  if(ll < event1->nearestEventSurfaceLogLikelihood){
2550  event1->nearestEventSurfaceLogLikelihood = ll;
2551  event1->nearestEventSurfaceLLEventNumber = event2.eventNumber;
2552  }
2553 
2554  if(surfaceDist < event1->nearestEventSurfaceDistanceKm){
2555  event1->nearestEventSurfaceDistanceKm = surfaceDist;
2556  event1->nearestEventSurfaceEventNumber = event2.eventNumber;
2557  }
2558 
2559  if(ll < event2.nearestEventSurfaceLogLikelihood){
2560  event2.nearestEventSurfaceLogLikelihood = ll;
2561  event2.nearestEventSurfaceLLEventNumber = event1->eventNumber;
2562  }
2563 
2564  if(surfaceDist < event2.nearestEventSurfaceDistanceKm){
2565  event2.nearestEventSurfaceDistanceKm = surfaceDist;
2566  event2.nearestEventSurfaceEventNumber = event1->eventNumber;
2567  }
2568 
2569  for(int z=0; z < event1->nThresholds; z++){
2570  if(surfaceDist < surfaceDistThresholdKm || ll <= llEventCuts.at(z)){
2571  event2Inds[t][z].push_back(event2Ind); // the events to merge
2572  if(event2.cluster[z] > -1){ // the clusters to merge
2573  matchedClusters[t][z].push_back(event2.cluster[z]);
2574  }
2575  }
2576  }
2577  }
2578  }
2579  if(t==0){
2580  p2.inc(innerLoopCounter);
2581  innerLoopCounter++;
2582  }
2583  } // omp loop
2584  p2.inc(n2, n2); // finish the inner loop progress bar by hand, just in case I got the guestimate of the number of threads wrong
2585 
2586  if(OpenMP::isEnabled){
2587  for(int t=1; t < mt; t++){
2588  for(int z=0; z < event1->nThresholds; z++){
2589  for(UInt_t i=0; i < matchedClusters[t][z].size(); i++){
2590  if(!RootTools::vectorContainsValue(matchedClusters[0][z], matchedClusters[t][z][i])){
2591  matchedClusters[0][z].push_back(matchedClusters[t][z][i]);
2592  }
2593  }
2594  for(UInt_t i=0; i < event2Inds[t][z].size(); i++){
2595  event2Inds[0][z].push_back(event2Inds[t][z].at(i));
2596  }
2597  matchedClusters[t][z].clear();
2598  event2Inds[t][z].clear();
2599  }
2600  }
2601  }
2602 
2603  // Now look at the clusters of the matched events (for each threshold)
2604  for(UInt_t z=0; z < llEventCuts.size(); z++){
2605 
2606  // for speed, sort the matched event numbers
2607  std::sort(event2Inds[0][z].begin(), event2Inds[0][z].end());
2608 
2609 
2610  // Int_t canICount = 0;
2611  // for(UInt_t clusterInd=0; clusterInd < clusters.at(z).size(); clusterInd++){
2612  // const Cluster& cluster = clusters.at(z).at(clusterInd);
2613  // canICount += cluster.numDataEvents;
2614  // }
2615 
2616  // If none of the events are in a cluster, then add a new cluster!
2617  if(matchedClusters[0][z].size()==0){
2618 
2619  // make a new cluster, it's intial position is this event location
2620  // although that will be changed...
2621  Cluster nc(*event1, clusters.at(z).size());
2622  nc.llEventCutInd = z;
2623  nc.llEventCut = llEventCuts.at(z);
2624  clusters.at(z).push_back(nc);
2625  matchedClusters[0][z].push_back(nc.index);
2626  }
2627 
2635  Int_t thisCluster = TMath::MinElement(matchedClusters[0][z].size(), &matchedClusters[0][z][0]);
2636 
2637  // Mark event1 as in the minCluster
2638  Int_t oldCluster1Ind = event1->cluster[z];
2639  if(oldCluster1Ind > -1){
2640  if(z==0){
2641  std::cerr << "Do we ever get here?" << std::endl; // no we don't
2642  }
2643  clusters.at(z).at(oldCluster1Ind).numDataEvents--;
2644  }
2645  event1->cluster[z] = thisCluster;
2646  clusters.at(z).at(thisCluster).numDataEvents++;
2647 
2648  // std::cerr << event2Inds.size() << std::endl;
2649 
2650  // Now reassign all matched events or events in matched clusters to the new cluster
2651  UInt_t matchedEventIndex=0;
2652  for(UInt_t event2Ind=0; event2Ind < events.size(); event2Ind++){
2653  Event& event2 = events.at(event2Ind);
2654 
2655  // check if this event is contained in the matched events or the matched clusters
2656  bool eventMatch = matchedEventIndex < event2Inds[0][z].size() && event2Ind==event2Inds[0][z][matchedEventIndex];
2657  if(eventMatch){
2658  // std::cout << matchedEventIndex << "\t" << event2Ind << "\t" << event2Inds[0][z][matchedEventIndex] << "\t" << event2Inds[0][z].size() << std::endl;
2659  matchedEventIndex++;
2660  }
2661 
2662  if(eventMatch || RootTools::vectorContainsValue(matchedClusters[0][z], event2.cluster[z])){
2663 
2664  Int_t oldCluster2Ind = event2.cluster[z];
2665  if(oldCluster2Ind > -1){
2666  clusters.at(z).at(oldCluster2Ind).numDataEvents--;
2667  }
2668  event2.cluster[z] = thisCluster;
2669  clusters.at(z).at(thisCluster).numDataEvents++;
2670  }
2671  }
2672 
2673  // Int_t canICount2 = 0;
2674  // for(UInt_t clusterInd=0; clusterInd < clusters.at(z).size(); clusterInd++){
2675  // const Cluster& cluster = clusters.at(z).at(clusterInd);
2676  // canICount2 += cluster.numDataEvents;
2677  // }
2678 
2679  // std::cout << z << "\t" << canICount << "\t" << canICount2 << std::endl;
2680  }
2681  }
2682 
2683  Int_t seconds = Int_t(timer.RealTime());
2684  Int_t hours = seconds / 3600;
2685  hours = hours < 0 ? 0 : hours;
2686  seconds = seconds - hours * 3600;
2687  Int_t mins = seconds / 60;
2688  mins = mins < 0 ? 0 : mins;
2689  seconds = seconds - mins * 60;
2690 
2691  std::cerr << "Finished loop = " << loopCount << ", in ";
2692  fprintf(stderr, ANSI_COLOR_MAGENTA); // because, why not?
2693  fprintf(stderr, "%02d:%02d:%02d\n", hours, mins, seconds);
2694  fprintf(stderr, ANSI_COLOR_RESET);
2695  timer.Start(kFALSE);
2696 
2697  loopCount++;
2698  event1 = nextEvent();
2699  }
2700 
2701  // Set fitter error level back to default
2702  gErrorIgnoreLevel = fROOTgErrorIgnoreLevel;
2703 
2704 }
2705 
2706 
2707 
2708 
2709 
2710 
2714 void Acclaim::Clustering::LogLikelihoodMethod::doMcEventClustering(){
2715 
2716  double llFitThreshold = TMath::MinElement(llEventCuts.size(), &llEventCuts.at(0)); // fit if greater than this
2717  double llNearbyThreshold = TMath::MaxElement(llEventCuts.size(), &llEventCuts.at(0)); // ignore if greater than this
2718 
2719  std::cout << __PRETTY_FUNCTION__ << std::endl;
2720  std::cout << "llNearbyThreshold = " << llNearbyThreshold << ", llFitThreshold = " << llFitThreshold << std::endl;
2721 
2722  fROOTgErrorIgnoreLevel = gErrorIgnoreLevel;
2723  gErrorIgnoreLevel = 1001;
2724 
2725  ProgressBar p(mcEvents.size());
2726  for(UInt_t event1Ind=0; event1Ind < mcEvents.size(); event1Ind++){
2727  McEvent& event1 = mcEvents.at(event1Ind);
2728  if(event1.eventEventClustering){
2729 
2730  double lookup[2] = {event1.easting, event1.northing};
2731  // look up nearby DATA events, not MC, don't want to cluster MC to MC...
2732  std::vector<Int_t> event2Inds;
2733  std::vector<Double_t> event2EastingNorthingDistances;
2734  UInt_t lastNumNeighbours = 0;
2735  UInt_t numNeighbours = 2048;
2736 
2737  Double_t furthestConsidered = 0;
2738  Int_t numConsidered = 0;
2739 
2740  while(furthestConsidered < default_horizon_distance && event1.cluster[0] < 0){
2741  event2Inds.resize(numNeighbours, -1);
2742  event2EastingNorthingDistances.resize(numNeighbours, -1);
2743  fKDTree->FindNearestNeighbors(lookup, numNeighbours, &event2Inds[0], &event2EastingNorthingDistances[0]);
2744 
2745  for(UInt_t i=lastNumNeighbours; i < event2Inds.size() && event1.cluster[0] < 0 && furthestConsidered < default_horizon_distance; i++){
2746  UInt_t event2Ind = event2Inds.at(i);
2747  const Event& event2 = events.at(event2Ind);
2748 
2749  if(event2EastingNorthingDistances[i] > furthestConsidered){
2750  furthestConsidered = event2EastingNorthingDistances[i];
2751  }
2752 
2753  double ll = dMin(&event1, &event2);
2754  Double_t surfaceDist = 1e-3*event1.cartesianSeparation(event2);
2755 
2756  if(ll > llFitThreshold && surfaceDist > surfaceDistThresholdKm){
2757  ll = dFit(&event1, &event2);
2758  }
2759 
2760  if(ll < event1.nearestEventSurfaceLogLikelihood){
2761  event1.nearestEventSurfaceLogLikelihood = ll;
2762  event1.nearestEventSurfaceLLEventNumber = event2.eventNumber;
2763  }
2764 
2765  if(surfaceDist < event1.nearestEventSurfaceDistanceKm){
2766  event1.nearestEventSurfaceDistanceKm = surfaceDist;
2767  event1.nearestEventSurfaceEventNumber = event2.eventNumber;
2768  }
2769 
2770  for(int z=0; z < event1.nThresholds; z++){
2771  if(surfaceDist < surfaceDistThresholdKm || ll <= llEventCuts.at(z)){
2772  event1.cluster[z] = event2.cluster[z];
2773  }
2774  }
2775  numConsidered++;
2776  }
2777  lastNumNeighbours = numNeighbours;
2778  numNeighbours *= 2;
2779  }
2780  const char* prefix = event1.cluster[0] < 0 ? "Did not find" : "Found";
2781  std::cerr << prefix << " a match after " << numConsidered << " events" << std::endl;
2782  }
2783  p.inc(event1Ind);
2784  }
2785 
2786  gErrorIgnoreLevel = fROOTgErrorIgnoreLevel;
2787 }
2788 
2789 void Acclaim::Clustering::LogLikelihoodMethod::setInitialBaseClusters(){
2790 
2791  for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
2792  Event& event = events.at(eventInd);
2793  Int_t clusterInd = event.nearestKnownBaseCluster;
2794 
2795  if(clusterInd >= 0){
2796  for(int z=0; z < event.nThresholds; z++){
2797  Cluster& cluster = clusters.at(z).at(clusterInd);
2798  if(event.nearestKnownBaseLogLikelihood < cluster.llEventCut){
2799  cluster.numDataEvents++;
2800  event.cluster[z] = cluster.index;
2801  // std::cout << eventInd << "\t" << z << "\t" << cluster.index << "\t" << event.nearestKnownBaseLogLikelihood << "\t" << cluster.llEventCut << "\t" << cluster.numDataEvents << std::endl;
2802  }
2803  }
2804  }
2805  }
2806 }
2807 
2808 
2809 void Acclaim::Clustering::LogLikelihoodMethod::doMcBaseClustering(){
2810 
2811  std::cout << __PRETTY_FUNCTION__ << std::endl;
2812 
2813  ProgressBar p(mcEvents.size());
2814  const int nBases = BaseList::getNumBases();
2815 
2816  for(UInt_t eventInd=0; eventInd < mcEvents.size(); eventInd++){
2817  McEvent* mcEvent = &mcEvents.at(eventInd);
2818  for(int clusterInd=0; clusterInd < nBases; clusterInd++){
2819  Cluster& cluster = clusters.at(0).at(clusterInd);
2820  if(cluster.knownBase){
2821  double distM = mcEvent->usefulPat.getDistanceFromSource(cluster.latitude, cluster.longitude, cluster.latitude);
2822  if(distM < default_horizon_distance){
2823  double ll = mcEvent->logLikelihoodFromPoint(cluster.longitude, cluster.latitude, cluster.altitude, true);
2824  double surfaceSeparationKm = 1e-3*mcEvent->cartesianSeparation(cluster);
2825 
2826  if(surfaceSeparationKm < mcEvent->nearestKnownBaseSurfaceSeparationKm){
2827  mcEvent->nearestKnownBaseSurfaceSeparationKm = surfaceSeparationKm;
2828 
2829  if(mcEvent->nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm){
2830  mcEvent->nearestKnownBaseCluster = clusterInd;
2831  }
2832  }
2833 
2834  if(ll < mcEvent->nearestKnownBaseLogLikelihood && mcEvent->nearestKnownBaseSurfaceSeparationKm >= surfaceDistThresholdKm){
2835  mcEvent->nearestKnownBaseCluster = clusterInd;
2836  }
2837 
2838  for(int z=0; z < mcEvent->nThresholds; z++){
2839  if(mcEvent->cluster[z] < 0 && (ll < llEventCuts.at(z) || mcEvent->nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm)){
2840  clusters[z][clusterInd].sumMcWeights += mcEvent->weight;
2841  mcEvent->cluster[z] = clusterInd;
2842  }
2843  }
2844  }
2845  }
2846  }
2847  p.inc(eventInd);
2848  }
2849 }
2850 
2851 
2852 
2853 void Acclaim::Clustering::LogLikelihoodMethod::doClustering(const char* dataGlob, const char* mcGlob, const char* outFileName, bool useAcclaimFiles){
2854 
2855  useAcclaimFiles ? readInSummaries(dataGlob) : readInTMVATreeSummaries(dataGlob, 0);
2856  useAcclaimFiles ? readInSummaries(mcGlob) : readInTMVATreeSummaries(mcGlob, 1);
2857  std::cout << "Sorting events...";
2858  std::sort(events.begin(), events.end());
2859  std::cout << "done" << std::endl;
2860 
2861  const char* fakeArgv[1] = {outFileName};
2862  TFile* fOut = 0;
2863  OutputConvention oc(1, const_cast<char**>(fakeArgv));
2864  fOut = useAcclaimFiles ? oc.makeFile() : new TFile(outFileName, "RECREATE");
2865 
2866  initKDTree();
2867  // fEventsAlreadyClustered = false;
2868 
2869 
2870  if(fUseBaseList){
2871  if(!fEventsAlreadyClustered){
2872  readInBaseList();
2873  doBaseEventClustering();
2874  }
2875  doMcBaseClustering();
2876  }
2877 
2878  if(!fEventsAlreadyClustered){
2879  doEventEventClustering();
2880  }
2881  doMcEventClustering();
2882 
2883  makeSummaryTrees();
2884 
2885  // testSmallClustersFromPointSource();
2886 
2887  fOut->Write();
2888  fOut->Close();
2889  return;
2890 
2891 
2892 }
2893 
2894 void Acclaim::Clustering::LogLikelihoodMethod::testSmallClusters(const char* dataGlob, const char* outFileName, int clusterSizeMin, int clusterSizeMax, int nAttempts){
2895 
2896  TFile* fOut = 0;
2897  fOut = new TFile(outFileName, "RECREATE");
2898 
2899 
2900  TH2D* h = new TH2D("LLDist", "LLDist", 200, 0, 100, 200, 0, 100);
2901  h->GetXaxis()->SetTitle("nearest event distance");
2902  h->GetYaxis()->SetTitle("nearest event LL");
2903  TH2D* h2 = new TH2D("clusterStuff", "clusterStuff", 100, 0, 100, 100, -.005, .995);
2904  h2->GetXaxis()->SetTitle("LL threshold");
2905  h2->GetYaxis()->SetTitle("percent singlets");
2906 
2907  readInSummariesForTesting(dataGlob);
2908 
2909  for(int i = 0; i < nAttempts; i++)
2910  {
2911  Int_t n_in_cluster = tr3->Uniform(clusterSizeMin, clusterSizeMax);
2912  pickEventsFromList(n_in_cluster);
2913  std::sort(events.begin(), events.end());
2914  initKDTree();
2915  doEventEventClustering();
2916  addToHistograms(h, h2);
2917 
2918  for(int j = 0; j < clusters.size(); j++) {
2919  clusters.at(j).clear();
2920  }
2921 
2922  events.clear();
2923  }
2924 
2925  fOut->cd();
2926  h->Write();
2927  h2->Write();
2928  fOut->Write();
2929  fOut->Close();
2930  return;
2931 }
static Double_t BilinearInterpolatedSurfaceAboveGeoid(Double_t longitude, Double_t latitude, RampdemReader::dataSet=rampdem)
Double_t sigmaTheta
the adjustment from traceBackToContinent
Double_t nearestKnownBaseLogLikelihood
Remove huge clusters near MCM before doing event-to-event clustering.
Double_t thetaAdjustmentRequired
reconstructed phi
Int_t nearestKnownBaseCluster
How far to the nearest known base?
Adu5Pat – The ADU5 Position and Attitude Data.
Definition: Adu5Pat.h:26
void resetClusteringNumbers()
/// Which event seeded the cluster?
Adu5Pat pat() const
Copy the data from the pat into the object.
TArrowAntarctica * makeArrowFromAnitaToEvent()
Double_t centre[3]
Which peak in the map does this represent?
Int_t antarcticaHistBin
What&#39;s the event number of the nearest surface neighbour by LL?
Double_t nearestEventSurfaceDistanceKm
If the event is above the continent surface, this may be non-zero.
const Double_t LATITUDE_WAIS_A3
Latitude of WAIS divide pulser.
Double_t llEventCut
which entry in the llEventCut array does this correspond to?
Double_t sigmaPhi
resolution associated with this snr?
void setSurfaceCloseEnoughInter(double closeEnough=1.0)
Double_t nearestEventSurfaceLogLikelihood
What&#39;s the event number of the nearest surface neighbour?
Float_t latitude
Slightly more useful constructor.
UsefulAdu5Pat usefulPat
Which global bin in the TH2DAntarctica?
Double_t nearestKnownBaseSurfaceSeparationKm
How far to the nearest known base?
void setupUsefulPat(bool calculateNow=true)
Bool_t fDebug
/// Only construct this once
USeful in for loops.
void setDebug(bool db)
McEvent(Int_t nT=0)
MC information.
Int_t numDataEvents
cluster center altitude
Double_t theta
Anita&#39;s position.
void setMaxLoopIterations(Int_t n=50)
Parameters defining the resolution model.
virtual void SetPointEastingNorthing(Int_t i, Double_t easting, Double_t northing)
static Double_t BilinearInterpolatedSurfaceAboveGeoidEastingNorthing(Double_t easting, Double_t northing, RampdemReader::dataSet=rampdem)
UInt_t nearestEventSurfaceEventNumber
How far away to the nearest event, in kilometers?
Double_t latitude
/// Cartesian coordinates, does not persist in ROOT
Double_t theta_adjustment_needed
chisq/ndof of peak finding process, if available (otherwise zero)
Double_t selfLogLikelihood
How far to the nearest known base?
Double_t altitude
longitude
As UsefulAnitaEvent is to RawAnitaEvent, UsefulAdu5Pat is to Adu5Pat. Well not quite as useful but yo...
Definition: UsefulAdu5Pat.h:39
Same as event, but with an energy and a weight.
Double_t longitude
on continent, or -9999 if doesn&#39;t intersect
Double_t theta
peak phi, degrees
void wrap(size_t N, double *vals, double period=360)
Definition: FFTtools.cxx:2851
static void LonLatToEastingNorthing(Double_t lon, Double_t lat, Double_t &easting, Double_t &northing)
AnitaEventSummary::PayloadLocation anita
northing
A position on the continent, with which a bunch of events are associated.
Common analysis format between UCorrelator and Acclaim.
void setInterpSurfaceAboveGeoid(bool i)
AnitaPol::AnitaPol_t pol
Run.
int traceBackToContinent3(Double_t phiWave, Double_t thetaWave, Double_t *lon, Double_t *lat, Double_t *alt, Double_t *theta_adjustment_required) const
Minimum required information about an ANITA event to be clustered.
Double_t energy
MC information.
virtual void SetPoint(Int_t i, Double_t lon, Double_t lat)
Draw an arrow between two lon/lat points.
enum AnitaPol::EAnitaPol AnitaPol_t
Polarisation enumeration.
static AnitaGeomTool * Instance(int anita_version=0)
Instance generator. If version_number == 0, uses AnitaVersion::get();.
AnitaGeomTool – The ANITA Geometry Tool.
Definition: AnitaGeomTool.h:48
Double_t sumMcWeights
How many data events does this cluster contain?
static void EastingNorthingToLonLat(Double_t easting, Double_t northing, Double_t &lon, Double_t &lat)
Double_t latitude
angle with respect to triggering phi sector in opposite polarisation
const Double_t LONGITUDE_WAIS_A3
Longitude of WAIS divide pulser.
Double_t phi
reconstructed theta
Double_t easting
longitude
Double_t altitude
on continent, or -9999 if doesn&#39;t intersect
Int_t peakIndex
Polarization.