1 #include "AcclaimClustering.h" 2 #include "AnitaGeomTool.h" 3 #include "SummarySet.h" 4 #include "AnitaDataset.h" 5 #include "OutputConvention.h" 6 #include "AnitaEventSummary.h" 8 #include "ProgressBar.h" 9 #include "TGraphAntarctica.h" 10 #include "TH2DAntarctica.h" 11 #include "TArrowAntarctica.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" 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" 40 const double FITTER_INPUT_SCALING = 1e-4;
41 const double FITTER_OUTPUT_SCALING = 1./FITTER_INPUT_SCALING;
52 const double phiParams[n] = {-2.50414e-01, 3.02406e-01, 2.43376e-01, 5.09057, 8.01369e-01, 1.};
53 const double thetaParams[n] = {-3.83773e-01, -3.00964e-01, 1.64537e-01, 1.34307, 7.09382e-01, 1.};
54 TString formula = (AnitaVersion::get() == 3) ?
"exp([0]*x + [1]) + [2]" :
"[0]/(pow(x,[1]) + [2])";
70 const double x = sum->coherent_filtered[pol][peakInd].snr;
71 getAngularResolution(x, sigma_theta, sigma_phi);
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]);
90 TCanvas* Acclaim::Clustering::drawAngularResolutionModel(
double maxSnr){
91 TCanvas* c1 =
new TCanvas();
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]);
102 fPhi->SetLineColor(kRed);
103 fTheta->Draw(
"lsame");
104 fTheta->SetLineColor(kBlue);
105 fPhi->SetBit(kCanDelete);
106 fTheta->SetBit(kCanDelete);
108 fPhi->SetMinimum(0.01);
157 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", for eventNumber " << eventNumber <<
"\n";
163 std::cerr <<
"Removing event " << eventNumber <<
" from event-event clustering!" << std::endl;
164 eventEventClustering =
false;
169 eventEventClustering =
true;
189 Double_t Acclaim::Clustering::Event::logLikelihoodFromPoint(Double_t sourceLon, Double_t sourceLat, Double_t sourceAlt,
bool addOverHorizonPenalty)
const {
191 Double_t thetaSource, phiSource;
192 usefulPat.getThetaAndPhiWave2(sourceLon, sourceLat, sourceAlt, thetaSource, phiSource);
193 thetaSource = -1*TMath::RadToDeg()*thetaSource;
194 phiSource = TMath::RadToDeg()*phiSource;
196 Double_t dTheta = (thetaSource - theta)/sigmaTheta;
197 Double_t dPhi = Acclaim::RootTools::getDeltaAngleDeg(phiSource, phi)/sigmaPhi;
199 Double_t ll = dTheta*dTheta + dPhi*dPhi;
202 std::cerr << __PRETTY_FUNCTION__ <<
" for " << eventNumber <<
", dTheta = " << dTheta <<
", dPhi = " << dPhi <<
", ll = " << ll << std::endl;
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;
212 std::cerr << __PRETTY_FUNCTION__ <<
" for " << eventNumber <<
", we are " << distM/1000 <<
"km from the source, after horizon penalty, ll = " << ll << std::endl;
223 : nThresholds(0), cluster(NULL),
224 dThetaCluster(NULL), dPhiCluster(NULL)
227 this->eventNumber = sum->eventNumber;
228 this->
run = sum->run;
242 anita = sum->anitaLocation;
250 resetClusteringNumbers();
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)
267 : nThresholds(0), cluster(NULL),
268 dThetaCluster(NULL), dPhiCluster(NULL)
271 this->eventNumber = eventNumber;
281 anita.longitude = anita_longitude;
283 anita.altitude = anita_altitude;
284 anita.heading = anita_heading;
295 resetClusteringNumbers();
311 Acclaim::Clustering::Event::Event(Int_t nT)
312 : nThresholds(0), cluster(NULL),
313 dThetaCluster(NULL), dPhiCluster(NULL)
332 for(
int dim=0; dim < nDim; dim++){
349 resetClusteringNumbers();
353 Acclaim::Clustering::Event::~Event(){
361 eventNumber =
event.eventNumber;
364 peakIndex =
event.peakIndex;
366 for(
int i=0; i < 3; i++){
367 centre[i] =
event.centre[i];
369 latitude =
event.latitude;
370 longitude =
event.longitude;
371 altitude =
event.altitude;
372 easting =
event.easting;
373 northing =
event.northing;
379 thetaAdjustmentRequired =
event.thetaAdjustmentRequired;
381 sigmaTheta =
event.sigmaTheta;
382 sigmaPhi =
event.sigmaPhi;
384 if(nThresholds!=event.nThresholds){
386 nThresholds =
event.nThresholds;
387 cluster =
new Int_t[nThresholds];
388 dThetaCluster =
new Double_t[nThresholds];
389 dPhiCluster =
new Double_t[nThresholds];
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];
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;
407 antarcticaHistBin =
event.antarcticaHistBin;
408 usefulPat =
event.usefulPat;
409 fDebug =
event.fDebug;
415 Acclaim::Clustering::Event::Event(
const Event& event)
416 : nThresholds(0), cluster(NULL),
417 dThetaCluster(NULL), dPhiCluster(NULL)
425 void Acclaim::Clustering::Event::deleteArrays(){
431 delete [] dPhiCluster;
435 delete [] dThetaCluster;
436 dThetaCluster = NULL;
451 std::vector<Int_t> tempCluster;
452 std::vector<Double_t> tempDPhiCluster;
453 std::vector<Double_t> tempDThetaCluster;
456 tempCluster.insert(tempCluster.begin(), cluster, cluster+nThresholds);
457 tempDPhiCluster.insert(tempDPhiCluster.begin(), dPhiCluster, dPhiCluster+nThresholds);
458 tempDThetaCluster.insert(tempDThetaCluster.begin(), dThetaCluster, dThetaCluster+nThresholds);
463 cluster =
new Int_t[n];
464 dPhiCluster =
new Double_t[n];
465 dThetaCluster =
new Double_t[n];
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];
473 for(Int_t z=nz; z < nThresholds; z++){
475 dPhiCluster[z] = -999;
476 dThetaCluster[z] = -999;
482 void Acclaim::Clustering::Event::resetClusteringNumbers(){
484 for(Int_t z=0; z<nThresholds; z++){
486 dThetaCluster[z] = -999;
487 dPhiCluster[z] = -999;
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;
511 return new TArrowAntarctica(anita.longitude, anita.latitude, longitude, latitude);
522 :
Event(sum, pol, peakInd, nT)
524 weight = sum->mc.weight;
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)
535 this->weight = weight;
540 Acclaim::Clustering::Cluster::Cluster(Int_t i) {
541 for(
int dim=0; dim < nDim; dim++){
548 resetClusteringNumbers();
549 antarcticaHistBin = -1;
554 Acclaim::Clustering::Cluster::Cluster(
const BaseList::base& base, Int_t i) {
561 if(altitude == -999){
566 geom->getCartesianCoords(latitude, longitude, altitude, centre);
567 resetClusteringNumbers();
568 antarcticaHistBin = -1;
575 Acclaim::Clustering::Cluster::Cluster(
const Event& event, Int_t i) {
576 latitude =
event.longitude;
577 longitude =
event.latitude;
578 altitude =
event.altitude;
582 geom->getCartesianCoords(latitude, longitude, altitude, centre);
583 resetClusteringNumbers();
595 Acclaim::Clustering::LogLikelihoodMethod::LogLikelihoodMethod()
596 : numMcDivisions(100), fEventsAlreadyClustered(false), fMyBackground(),
597 fROOTgErrorIgnoreLevel(gErrorIgnoreLevel), fDrawNewNearbyEventsHistograms(true),
598 fReadInBaseList(false), fStoreUnclusteredHistograms(true)
601 const char* sgeTaskId = getenv(
"SGE_TASK_ID");
606 mcDivision = atoi(sgeTaskId);
607 std::cout <<
"Info in " << __PRETTY_FUNCTION__ <<
", found SGE_TASK_ID=" << sgeTaskId
608 <<
", setting mcDivision = " << mcDivision << std::endl;
613 fMyBackground.SetCoarseness(120);
614 std::cout << fMyBackground.GetXaxis()->GetBinWidth(1) <<
"\t" << fMyBackground.GetYaxis()->GetBinWidth(1) << std::endl;
616 grTestMinimizerWalk = NULL;
617 grTestMinimizerValue = NULL;
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);
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);
636 llEventCuts.push_back(100);
664 for(UInt_t z=0; z < llEventCuts.size(); z++){
665 clusters.push_back(std::vector<Cluster>());
669 fTestEvent1 = 61284883;
670 fTestEvent2 = 55352006;
682 fMaxFitterAttempts = 1;
684 tr3 =
new TRandom3(0);
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);
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));
698 fMinimizers.at(t)->SetMaxFunctionCalls(1e5);
699 fMinimizers.at(t)->SetTolerance(0.0001);
700 fMinimizers.at(t)->SetPrintLevel(0);
701 fMinimizers.at(t)->SetFunction(fFunctors.at(t));
709 Acclaim::Clustering::LogLikelihoodMethod::~LogLikelihoodMethod(){
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;
724 Double_t Acclaim::Clustering::LogLikelihoodMethod::getDistSqEventCluster(
const Event& event,
const Acclaim::Clustering::Cluster& cluster){
726 for(
int dim=0; dim < nDim; dim++){
727 Double_t d = cluster.centre[dim] -
event.centre[dim];
735 void Acclaim::Clustering::LogLikelihoodMethod::getDeltaThetaDegDeltaPhiDegEventCluster(
const Event& event,
const Cluster& cluster, Double_t& deltaThetaDeg, Double_t& deltaPhiDeg){
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;
742 deltaThetaDeg = (thetaDeg -
event.theta);
743 deltaPhiDeg = Acclaim::RootTools::getDeltaAngleDeg(phiDeg, event.phi);
754 Double_t Acclaim::Clustering::LogLikelihoodMethod::evalPairLogLikelihoodAtLonLat(
const Double_t* params){
756 Double_t sourceEasting = FITTER_OUTPUT_SCALING*params[0];
757 Double_t sourceNorthing = FITTER_OUTPUT_SCALING*params[1];
758 int t = OpenMP::thread();
762 Double_t sourceLon, sourceLat;
766 ll += fFitEvent1s.at(t)->logLikelihoodFromPoint(sourceLon, sourceLat, sourceAlt,
true);
767 ll += fFitEvent2s.at(t)->logLikelihoodFromPoint(sourceLon, sourceLat, sourceAlt,
true);
771 if(fFitEvent1s.at(t)->eventNumber==fTestEvent1){
772 if(fFitEvent2s.at(t)->eventNumber==fTestEvent2){
773 if(grTestMinimizerWalk){
774 grTestMinimizerWalk->SetPoint(grTestMinimizerWalk->GetN(), sourceEasting, sourceNorthing);
776 if(grTestMinimizerValue){
777 int n = grTestMinimizerValue->GetN();
778 grTestMinimizerValue->SetPoint(n, n, ll);
787 if(fMinimizers.at(t)->PrintLevel() > 0){
788 std::cout << sourceEasting <<
"\t" << sourceNorthing <<
"\t" << sourceLon <<
"\t" << sourceLat <<
"\t" << ll << std::endl;
796 Double_t Acclaim::Clustering::LogLikelihoodMethod::dFit(
const Event* event1,
const Event* event2){
798 int t = Acclaim::OpenMP::thread();
799 ROOT::Math::Minimizer* minimizer = fMinimizers.at(t);
801 fFitEvent1s.at(t) = event1;
802 fFitEvent2s.at(t) = event2;
804 Double_t ll12 = dAsym(event1, event2);
805 Double_t ll21 = dAsym(event2, event1);
808 const Event* which = ll21 < ll12 ? fFitEvent1s.at(t) : fFitEvent2s.at(t);
810 if(fFitEvent1s.at(t)->eventNumber==fTestEvent1 && fFitEvent2s.at(t)->eventNumber==fTestEvent2){
811 grTestMinimizerWalk =
new TGraph();
812 grTestMinimizerValue =
new TGraph();
815 event1->fDebug =
true;
816 event2->fDebug =
true;
821 minimizer->SetVariable(0,
"sourceEasting", FITTER_INPUT_SCALING*which->easting, 1);
822 minimizer->SetVariable(1,
"sourceNorthing", FITTER_INPUT_SCALING*which->northing, 1);
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());
831 std::cerr <<
"Info in " << __PRETTY_FUNCTION__ <<
", eventNumbers " << event1->eventNumber <<
" and " 832 << event2->eventNumber <<
" did not converge, the result was " << minimizer->MinValue() << std::endl;
834 minimizer->SetVariable(0,
"sourceEasting", minimizer->X()[0], 1);
835 minimizer->SetVariable(1,
"sourceNorthing", minimizer->X()[1], 1);
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;
843 if(fFitEvent1s.at(t)->eventNumber==fTestEvent1 && fFitEvent2s.at(t)->eventNumber==fTestEvent2){
845 event1->fDebug =
false;
846 event2->fDebug =
false;
850 if(grTestMinimizerWalk){
851 grTestMinimizerWalk->SetName(
"grTestMinimizerWalk");
852 grTestMinimizerWalk->Write();
853 delete grTestMinimizerWalk;
854 grTestMinimizerWalk = NULL;
856 if(grTestMinimizerValue){
857 grTestMinimizerValue->SetName(
"grTestMinimizerValue");
858 grTestMinimizerValue->Write();
859 delete grTestMinimizerValue;
860 grTestMinimizerValue = NULL;
863 if((!validMinimum && fDebug)){
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();
872 minimizer->SetVariable(0,
"sourceEasting", minimizer->X()[0], 1);
873 minimizer->SetVariable(1,
"sourceNorthing", minimizer->X()[1], 1);
876 minimizer->SetPrintLevel(old_print_level);
878 AnitaVersion::set(3);
879 double waisLon = AnitaLocations::getWaisLongitude();
880 double waisLat = AnitaLocations::getWaisLatitude();
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;
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;
903 fFitEastings.at(t) = minimizer->X()[0]*FITTER_OUTPUT_SCALING;
904 fFitNorthings.at(t) = minimizer->X()[1]*FITTER_OUTPUT_SCALING;
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;
913 Double_t ll = minimizer->MinValue();
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);
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;
967 Double_t Acclaim::Clustering::LogLikelihoodMethod::dAsym(
const Event* event1,
const Event* event2){
968 return event1->logLikelihoodFromPoint(event2->longitude, event2->latitude,event2->altitude,
true);
976 bool Acclaim::Clustering::LogLikelihoodMethod::considerBin(
const Event& event, Int_t bx, Int_t by,
double& easting,
double& northing){
978 const double halfBinWidthNorthing = 0.5*fMyBackground.GetYaxis()->GetBinWidth(bx);
979 const double halfBinWidthEasting = 0.5*fMyBackground.GetXaxis()->GetBinWidth(by);
981 northing = fMyBackground.GetXaxis()->GetBinCenter(by);
982 northing = northing >
event.northing ? northing - halfBinWidthNorthing : northing + halfBinWidthNorthing;
983 double dNorthing = northing -
event.northing;
985 easting = fMyBackground.GetXaxis()->GetBinCenter(bx);
986 easting = easting >
event.easting ? easting - halfBinWidthEasting : easting + halfBinWidthEasting;
987 double dEasting = easting -
event.easting;
989 const double distSq = dNorthing*dNorthing + dEasting*dEasting;
990 const double maxRangeSq = default_horizon_distance*default_horizon_distance;
992 if(distSq < maxRangeSq){
1001 void Acclaim::Clustering::LogLikelihoodMethod::nearbyEvents2(UInt_t eventInd, std::vector<UInt_t>& nearbyEventInds){
1003 nearbyEventInds.clear();
1005 const int nx = fMyBackground.GetNbinsX();
1006 const int ny = fMyBackground.GetNbinsY();
1008 const Event&
event = events.at(eventInd);
1009 std::vector<bool> found(events.size(), 0);
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)){
1017 const std::vector<UInt_t>& eventsThisBin = fLookupEN[by-1][bx-1];
1019 for(UInt_t i=0; i < eventsThisBin.size(); i++){
1020 if(eventsThisBin[i]!=eventInd){
1023 found[eventsThisBin[i]] = 1;
1032 for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1033 if(found[eventInd] > 0){
1034 nearbyEventInds.push_back(eventInd);
1046 Double_t Acclaim::Clustering::LogLikelihoodMethod::getAngDistSqEventCluster(
const Event& event,
const Cluster& cluster){
1048 Double_t deltaThetaDeg, deltaPhiDeg;
1049 getDeltaThetaDegDeltaPhiDegEventCluster(event, cluster, deltaThetaDeg, deltaPhiDeg);
1051 Double_t dThetaNorm = deltaThetaDeg/
event.sigmaTheta;
1052 Double_t dPhiNorm = deltaPhiDeg/
event.sigmaPhi;
1053 Double_t angSq = dThetaNorm*dThetaNorm + dPhiNorm*dPhiNorm;
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;
1079 return sumOfWeights;
1095 if(!fStoreUnclusteredHistograms){
1096 while(hUnclusteredEvents.size() > 0){
1097 delete hUnclusteredEvents.back();
1098 hUnclusteredEvents.pop_back();
1104 TString name = TString::Format(
"hUnclusteredEvents_%lu", hUnclusteredEvents.size());
1106 hUnclusteredEvents.push_back(h);
1108 h->setAcceptStereographic(
true);
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;
1122 h->setAcceptStereographic(
false);
1124 Event* nextEvent = NULL;
1127 if(numUnclustered==0){
1129 hUnclusteredEvents.pop_back();
1139 Int_t globalMaxBin = h->GetMaximumBin();
1140 Int_t numUnclusteredInBin = h->GetBinContent(globalMaxBin);
1142 Double_t meanEasting=0;
1143 Double_t meanNorthing=0;
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;
1152 meanNorthing/=numUnclusteredInBin;
1153 meanEasting/=numUnclusteredInBin;
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;
1163 if(surfaceSeparationSquared < bestSurfaceSeparationSquared){
1164 bestSurfaceSeparationSquared = surfaceSeparationSquared;
1176 void Acclaim::Clustering::LogLikelihoodMethod::doBaseEventClustering(){
1178 std::cout << __PRETTY_FUNCTION__ << std::endl;
1180 const int nBases = BaseList::getNumBases();
1182 const Long64_t nEvents = events.size();
1183 ProgressBar p(nEvents);
1186 std::vector< std::vector<std::vector<Int_t> > > matchedClusters(llEventCuts.size(), std::vector< std::vector<Int_t > >(nBases, std::vector<Int_t>()));
1188 for(Long64_t eventInd=0; eventInd < nEvents; eventInd++){
1189 Event*
event = &events.at(eventInd);
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);
1200 if(surfaceSeparationKm < surfaceDistThresholdKm){
1201 for(
int z=0; z < llEventCuts.size(); z++){
1202 matchedClustersThisEvent[z].push_back(clusterInd);
1206 for(
int z=0; z < llEventCuts.size(); z++){
1207 if(ll < llEventCuts.at(z)){
1208 matchedClustersThisEvent[z].push_back(clusterInd);
1213 if(ll < event->nearestKnownBaseLogLikelihood){
1214 event->nearestKnownBaseLogLikelihood = ll;
1215 event->nearestKnownBaseCluster = clusterInd;
1217 if(surfaceSeparationKm < event->nearestKnownBaseSurfaceSeparationKm){
1218 event->nearestKnownBaseSurfaceSeparationKm = surfaceSeparationKm;
1219 event->nearestKnownBaseClusterSurface = clusterInd;
1224 std::cerr <<
"You shouldn't get here!!!" << std::endl;
1227 for(
int z=0; z < llEventCuts.size(); z++){
1228 if(matchedClustersThisEvent[z].size() > 0){
1231 for(
int i = 0; i < matchedClustersThisEvent[z].size(); i++){
1232 Int_t matchedCluster = matchedClustersThisEvent[z][i];
1235 for(
int j = 0; j < matchedClustersThisEvent[z].size(); j++){
1236 Int_t matchedCluster2 = matchedClustersThisEvent[z][j];
1238 if(!RootTools::vectorContainsValue(matchedClusters[z][matchedCluster], matchedCluster2)){
1239 matchedClusters[z][matchedCluster].push_back(matchedCluster2);
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);
1257 for(
int b=0; b < nBases; b++){
1258 if(matchedClusters[z][b].size() > 0){
1261 int lastNMatched = 0;
1264 lastNMatched = nMatches;
1265 nMatches = matchedClusters[z][b].size();
1266 for(
int i=lastNMatched; i < nMatches; i++){
1268 int b2 = matchedClusters[z][b][i];
1270 for(
int j=0; j < matchedClusters[z][b2].size(); j++){
1271 int b3 = matchedClusters[z][b2][j];
1273 if(!RootTools::vectorContainsValue(matchedClusters[z][b], b3)){
1274 matchedClusters[z][b].push_back(b3);
1279 while(lastNMatched!=nMatches);
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){
1292 std::cout<< std::endl;
1296 for(
int i=0; i < matchedClusters[z][b].size(); i++){
1297 int cluster = matchedClusters[z][b][i];
1299 if(cluster < reassignedTo[b]){
1300 reassignedTo[b] = cluster;
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;
1315 std::cout << b <<
"->" << reassignedTo[b] <<
"\n";
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;
1326 else if(event.nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm){
1327 clusterInd =
event.nearestKnownBaseClusterSurface;
1329 if(clusterInd >= 0){
1331 Int_t reassignedCluster = reassignedTo[clusterInd];
1332 event.cluster[z] = reassignedCluster;
1333 clusters.at(z).at(reassignedCluster).numDataEvents++;
1456 mcEvents.push_back(McEvent(sum, pol, peakInd, llEventCuts.size()));
1458 return mcEvents.size();
1468 events.push_back(Event(sum, pol, peakInd, llEventCuts.size()));
1470 return events.size();
1483 void Acclaim::Clustering::LogLikelihoodMethod::readInBaseList(){
1485 if(!fReadInBaseList){
1486 std::cout <<
"Info in " << __FUNCTION__ <<
": Initializing base list..." << std::endl;
1489 for(UInt_t z=0; z < llEventCuts.size(); z++){
1490 for(UInt_t clusterInd=0; clusterInd < BaseList::getNumBases(); 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);
1498 fReadInBaseList =
true;
1503 void Acclaim::Clustering::LogLikelihoodMethod::resetClusters(){
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;
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;
1543 void Acclaim::Clustering::LogLikelihoodMethod::addToHistograms(TH2D* h, TH2D* h2){
1544 for(
int i = 0; i < events.size(); i++)
1546 const Event&
event = events.at(i);
1547 h->Fill(event.nearestEventSurfaceDistanceKm, event.nearestEventSurfaceLogLikelihood);
1549 for(
int i = 0; i < clusters.size(); i++)
1551 if(llEventCuts.at(i) > 40)
continue;
1554 for(
int j = 0; j < clusters.at(i).size(); j++)
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()));
1566 void Acclaim::Clustering::LogLikelihoodMethod::makeSummaryTrees(){
1569 if(!fEventsAlreadyClustered){
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);
1577 if(cluster.knownBase==0){
1579 cluster.centre[0] = 0;
1580 cluster.centre[1] = 0;
1581 cluster.centre[2] = 0;
1582 int eventCounter = 0;
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];
1593 if(eventCounter > 0){
1594 cluster.centre[0]/=eventCounter;
1595 cluster.centre[1]/=eventCounter;
1596 cluster.centre[2]/=eventCounter;
1600 geom->getLatLonAltFromCartesian(cluster.centre, cluster.latitude,
1601 cluster.longitude, cluster.altitude);
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;
1615 TTree* eventTree =
new TTree(
"eventTree",
"Tree of clustered ANITA events");
1616 Event*
event = NULL;
1617 eventTree->Branch(
"event", &event);
1619 for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1620 event = &events.at(eventInd);
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]);
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);
1650 for(UInt_t j=0; j < mcEvents.size(); j++){
1651 mcEvent = &mcEvents.at(j);
1652 mcEventTree->Fill();
1654 mcEventTree->Write();
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]);
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();
1677 for(UInt_t eventInd=0; eventInd < hUnclusteredEvents.size(); eventInd++){
1678 if(hUnclusteredEvents.at(eventInd)){
1679 hUnclusteredEvents.at(eventInd)->Write();
1684 if(!fEventsAlreadyClustered){
1686 for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
1687 const Event&
event = events.at(eventInd);
1688 hEvents->Fill(event.longitude, event.latitude);
1696 if(mcEvents.size() > 0){
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);
1710 Long64_t Acclaim::Clustering::LogLikelihoodMethod::readInSummaries(
const char* summaryGlob){
1719 TFile* f = TFile::Open(summaryGlob);
1720 TTree* eventTree = NULL;
1722 eventTree = (TTree*) f->Get(
"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();
1736 for(Long64_t entry=0; entry < n; entry++){
1737 eventTree->GetEntry(entry);
1738 event->setupUsefulPat(
false);
1739 events.push_back(*event);
1742 std::cout <<
"Read in " << n <<
" events." << std::endl;
1745 llEventCuts.clear();
1748 TTree* clusterTree = NULL;
1751 TString treeName = TString::Format(
"clusterTree%d", treeInd);
1752 clusterTree = (TTree*)f->Get(treeName);
1754 clusterTree->SetBranchAddress(
"cluster", &cluster);
1755 const Long64_t nC = clusterTree->GetEntries();
1757 clusters.push_back(std::vector<Cluster>());
1758 clusters.back().reserve(nC);
1760 for(Long64_t entry=0; entry < nC; entry++){
1761 clusterTree->GetEntry(entry);
1765 clusters.back().push_back(*cluster);
1769 }
while(clusterTree!=NULL);
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){
1781 std::cout << std::endl;
1786 fEventsAlreadyClustered =
true;
1787 fReadInBaseList =
true;
1791 ThermalChain tc(summaryGlob);
1792 ProgressBar pElist(1);
1801 tc.setCut(ThermalTree::isTaggedAsWaisPulser + ThermalTree::closeToWais);
1805 std::cout <<
"There are " << n <<
" entries matching the selection" << std::endl;
1808 for(Long64_t entry=0; entry < n; entry++){
1812 std::cout << tc.weight << std::endl;
1814 events.reserve(events.size()+n);
1816 mcEvents.reserve(mcEvents.size()+n);
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));
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));
1841 Long64_t Acclaim::Clustering::LogLikelihoodMethod::readInTMVATreeSummaries(
const char* summaryGlob,
bool isMC){
1850 TFile* f = TFile::Open(summaryGlob);
1851 TTree* eventTree = NULL;
1853 eventTree = (TTree*) f->Get(
"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();
1867 for(Long64_t entry=0; entry < n; entry++){
1868 eventTree->GetEntry(entry);
1869 event->setupUsefulPat(
false);
1870 events.push_back(*event);
1873 std::cout <<
"Read in " << n <<
" events." << std::endl;
1876 llEventCuts.clear();
1879 TTree* clusterTree = NULL;
1882 TString treeName = TString::Format(
"clusterTree%d", treeInd);
1883 clusterTree = (TTree*)f->Get(treeName);
1885 clusterTree->SetBranchAddress(
"cluster", &cluster);
1886 const Long64_t nC = clusterTree->GetEntries();
1888 clusters.push_back(std::vector<Cluster>());
1889 clusters.back().reserve(nC);
1891 for(Long64_t entry=0; entry < nC; entry++){
1892 clusterTree->GetEntry(entry);
1896 clusters.back().push_back(*cluster);
1900 }
while(clusterTree!=NULL);
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){
1912 std::cout << std::endl;
1917 fEventsAlreadyClustered =
true;
1918 fReadInBaseList =
true;
1920 TChain* t =
new TChain(
"sumTree");
1921 t->Add(summaryGlob);
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;
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);
1945 t->Draw(
">>fEntryList", fCut,
"entrylist");
1946 fEntryList = (TEntryList*) gDirectory->Get(
"fEntryList");
1947 t->SetEntryList(fEntryList);
1948 printf(
"%d entries loaded\n", fEntryList->GetN());
1950 for(Long64_t entry=0; entry < fEntryList->GetN(); entry++){
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)
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();
1968 if(tr3->Integer(1000) >= fPercentOfMC)
continue;
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));
1984 void Acclaim::Clustering::LogLikelihoodMethod::readInSummariesForTesting(
const char* summaryGlob){
1993 fChain =
new TChain(
"sumTree");
1994 fChain->Add(summaryGlob);
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;
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);
2018 fChain->Draw(
">>fEntryList", fCut,
"entrylist");
2019 fEntryList = (TEntryList*) gDirectory->Get(
"fEntryList");
2020 fChain->SetEntryList(fEntryList);
2021 printf(
"%d entries loaded\n", fEntryList->GetN());
2026 void Acclaim::Clustering::LogLikelihoodMethod::pickEventsFromList(
int n_in_cluster)
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;
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);
2050 TBits * bits =
new TBits(fEntryList->GetN());
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));
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));
2079 void Acclaim::Clustering::LogLikelihoodMethod::testTriangleInequality(){
2081 const int numENNeighbours = 100;
2082 std::vector<Int_t> indices;
2083 std::vector<Int_t> enSeparation;
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);
2091 Double_t d_ij = dMin(&event_i, &event_j);
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);
2098 if(d_ik > d_ij + d_jk){
2099 std::cerr << i <<
"\t" << j <<
"\t" << k <<
" fails!" << std::endl;
2103 p.inc(i, events.size());
2110 void Acclaim::Clustering::LogLikelihoodMethod::initKDTree(){
2113 std::cout <<
"About to build KDTree" << std::endl;
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);
2127 const int binSize = 100000;
2131 fKDTree =
new TKDTreeID(events.size(), 2, binSize);
2132 fKDTree->SetData(0, &fEventEastings[0]);
2133 fKDTree->SetData(1, &fEventNorthings[0]);
2137 std::cout <<
"Built!" << std::endl;
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;
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;
2180 void Acclaim::Clustering::LogLikelihoodMethod::testSmallClustersFromPointSource(){
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;
2189 if(eventNumber < firstEventNumber){
2190 firstEventNumber = eventNumber;
2193 TRandom3 randy(123);
2195 const int fakeClusterSize = 2;
2196 const int nTrials = 1000;
2198 TH2D* hClusterTrials =
new TH2D(
"hClusterTrials",
"clustering trials",
2199 llEventCuts.size(), 0, llEventCuts.size(),
2200 fakeClusterSize, 1, fakeClusterSize+1);
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);
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));
2216 ProgressBar p(nTrials);
2217 for(
int trialInd=0; trialInd < nTrials; trialInd++){
2222 for(UInt_t z=0; z < clusters.size(); z++){
2223 clusters.at(z).clear();
2226 for(UInt_t i=0; i < fakeClusterSize; i++){
2227 UInt_t eventInd = randy.Uniform(tempEvents.size());
2228 events.push_back(tempEvents.at(eventInd));
2232 doEventEventClustering();
2234 for(UInt_t z=0; z < clusters.size(); z++){
2235 hClusterTrials->Fill(z, clusters.at(z).size());
2246 void Acclaim::Clustering::LogLikelihoodMethod::makeAndWriteNSquaredEventEventHistograms(){
2249 fROOTgErrorIgnoreLevel = gErrorIgnoreLevel;
2250 gErrorIgnoreLevel = 1001;
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;
2260 if(eventNumber < firstEventNumber){
2261 firstEventNumber = eventNumber;
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();
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);
2277 TRandom3 randy(123);
2280 const Int_t nBins = 1024;
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);
2286 TH2D* hFitVsSumOfSelfLLs =
new TH2D(
"hFit_vs_sumOfSelfLLs",
"", 1024, 0, 50, 1024, 0, 1024);
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);
2298 const int fakeClusterSize = 2;
2300 for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
2301 const Event& event1 = events.at(eventInd);
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;
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());
2314 for(UInt_t eventInd2=0; eventInd2 < event2Inds.size(); eventInd2++){
2315 const Event& event2 = events.at(eventInd2);
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;
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);
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);
2342 std::cout <<
"done!" << std::endl;
2348 grTestEvent1->SetName(
"grTestEvent1");
2349 grTestEvent1->Write();
2350 delete grTestEvent1;
2354 grTestEvent2->SetName(
"grTestEvent2");
2355 grTestEvent2->Write();
2356 delete grTestEvent2;
2360 grWaisTrue->SetName(
"grWaisTrue");
2361 grWaisTrue->Write();
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;
2369 double dist = dMin(&event1, &event2);
2370 Double_t angleBetweenEvents = TMath::RadToDeg()*anitaToEvent1.Angle(anitaToEvent2);
2372 hUnfit->Fill(angleBetweenEvents, dist);
2374 double distFitted = dFit(&event1, &event2);
2375 hFit->Fill(angleBetweenEvents, distFitted);
2377 hFitVsSumOfSelfLLs->Fill(event1.selfLogLikelihood+event2.selfLogLikelihood, distFitted);
2379 if(event1.theta > -5.5 && event2.theta > -5.5){
2380 std::cout << event1.eventNumber <<
"\t" << event2.eventNumber << std::endl;
2383 double fitLon, fitLat;
2384 int t = OpenMP::thread();
2386 hFittedPos->Fill(fitLon, fitLat);
2387 hEventPos->Fill(event1.longitude, event1.latitude);
2389 hFitVsUnfitted->Fill(dist, distFitted);
2390 hUnfitMinusFit->Fill(dist - distFitted);
2392 p.inc(eventInd, events.size());
2395 grAnita->SetName(
"grAnita");
2399 hFittedPos->Write();
2405 hFitVsSumOfSelfLLs->Write();
2406 delete hFitVsSumOfSelfLLs;
2417 hFitVsUnfitted->Write();
2418 delete hFitVsUnfitted;
2420 hUnfitMinusFit->Write();
2421 delete hUnfitMinusFit;
2423 gErrorIgnoreLevel = fROOTgErrorIgnoreLevel;
2433 void Acclaim::Clustering::LogLikelihoodMethod::doEventEventClustering(){
2435 double llFitThreshold = TMath::MinElement(llEventCuts.size(), &llEventCuts.at(0));
2436 double llNearbyThreshold = TMath::MaxElement(llEventCuts.size(), &llEventCuts.at(0));
2438 std::cout << __PRETTY_FUNCTION__ << std::endl;
2439 std::cout <<
"llNearbyThreshold = " << llNearbyThreshold <<
", llFitThreshold = " << llFitThreshold << std::endl;
2442 fROOTgErrorIgnoreLevel = gErrorIgnoreLevel;
2443 gErrorIgnoreLevel = 1001;
2448 Event* event1 = nextEvent();
2449 Int_t loopCount = 0;
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++;
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;
2463 if(event1->eventEventClustering){
2466 std::vector<Int_t> nearbyEventsInds;
2467 double lookup[2] = {event1->easting, event1->northing};
2468 fKDTree->FindInRange(lookup, default_range_easting_northing, nearbyEventsInds);
2473 const int mt = OpenMP::getMaxThreads();
2474 std::vector<std::vector<UInt_t> > event2Inds[mt];
2475 std::vector<std::vector<Int_t> > matchedClusters[mt];
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>());
2484 for(
int z=0; z < event1->nThresholds; z++){
2485 if(event1->cluster[z] > -1){
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;
2490 for(
int t=0; t < mt; t++){
2491 matchedClusters[t][z].push_back(event1->cluster[z]);
2497 std::map<std::pair<Int_t, Int_t>, Double_t> bestUnfittedLogLikelihoodThisClusterThisHistBin[mt];
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;
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);
2510 int t = OpenMP::thread();
2512 if(event1->eventNumber != event2.eventNumber && event2.eventEventClustering){
2523 if(event2.cluster[0] < 0 || !RootTools::vectorContainsValue(matchedClusters[t][0], event2.cluster[0])){
2525 Double_t ll = dMin(event1, &event2);
2526 Double_t surfaceDist = 1e-3*event1->cartesianSeparation(event2);
2545 if(ll > llFitThreshold && surfaceDist > surfaceDistThresholdKm){
2546 ll = dFit(event1, &event2);
2549 if(ll < event1->nearestEventSurfaceLogLikelihood){
2550 event1->nearestEventSurfaceLogLikelihood = ll;
2551 event1->nearestEventSurfaceLLEventNumber = event2.eventNumber;
2554 if(surfaceDist < event1->nearestEventSurfaceDistanceKm){
2555 event1->nearestEventSurfaceDistanceKm = surfaceDist;
2556 event1->nearestEventSurfaceEventNumber = event2.eventNumber;
2559 if(ll < event2.nearestEventSurfaceLogLikelihood){
2560 event2.nearestEventSurfaceLogLikelihood = ll;
2561 event2.nearestEventSurfaceLLEventNumber = event1->eventNumber;
2564 if(surfaceDist < event2.nearestEventSurfaceDistanceKm){
2565 event2.nearestEventSurfaceDistanceKm = surfaceDist;
2566 event2.nearestEventSurfaceEventNumber = event1->eventNumber;
2569 for(
int z=0; z < event1->nThresholds; z++){
2570 if(surfaceDist < surfaceDistThresholdKm || ll <= llEventCuts.at(z)){
2571 event2Inds[t][z].push_back(event2Ind);
2572 if(event2.cluster[z] > -1){
2573 matchedClusters[t][z].push_back(event2.cluster[z]);
2580 p2.inc(innerLoopCounter);
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]);
2594 for(UInt_t i=0; i < event2Inds[t][z].size(); i++){
2595 event2Inds[0][z].push_back(event2Inds[t][z].at(i));
2597 matchedClusters[t][z].clear();
2598 event2Inds[t][z].clear();
2604 for(UInt_t z=0; z < llEventCuts.size(); z++){
2607 std::sort(event2Inds[0][z].begin(), event2Inds[0][z].end());
2617 if(matchedClusters[0][z].size()==0){
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);
2635 Int_t thisCluster = TMath::MinElement(matchedClusters[0][z].size(), &matchedClusters[0][z][0]);
2638 Int_t oldCluster1Ind = event1->cluster[z];
2639 if(oldCluster1Ind > -1){
2641 std::cerr <<
"Do we ever get here?" << std::endl;
2643 clusters.at(z).at(oldCluster1Ind).numDataEvents--;
2645 event1->cluster[z] = thisCluster;
2646 clusters.at(z).at(thisCluster).numDataEvents++;
2651 UInt_t matchedEventIndex=0;
2652 for(UInt_t event2Ind=0; event2Ind < events.size(); event2Ind++){
2653 Event& event2 = events.at(event2Ind);
2656 bool eventMatch = matchedEventIndex < event2Inds[0][z].size() && event2Ind==event2Inds[0][z][matchedEventIndex];
2659 matchedEventIndex++;
2662 if(eventMatch || RootTools::vectorContainsValue(matchedClusters[0][z], event2.cluster[z])){
2664 Int_t oldCluster2Ind = event2.cluster[z];
2665 if(oldCluster2Ind > -1){
2666 clusters.at(z).at(oldCluster2Ind).numDataEvents--;
2668 event2.cluster[z] = thisCluster;
2669 clusters.at(z).at(thisCluster).numDataEvents++;
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;
2691 std::cerr <<
"Finished loop = " << loopCount <<
", in ";
2692 fprintf(stderr, ANSI_COLOR_MAGENTA);
2693 fprintf(stderr,
"%02d:%02d:%02d\n", hours, mins, seconds);
2694 fprintf(stderr, ANSI_COLOR_RESET);
2695 timer.Start(kFALSE);
2698 event1 = nextEvent();
2702 gErrorIgnoreLevel = fROOTgErrorIgnoreLevel;
2714 void Acclaim::Clustering::LogLikelihoodMethod::doMcEventClustering(){
2716 double llFitThreshold = TMath::MinElement(llEventCuts.size(), &llEventCuts.at(0));
2717 double llNearbyThreshold = TMath::MaxElement(llEventCuts.size(), &llEventCuts.at(0));
2719 std::cout << __PRETTY_FUNCTION__ << std::endl;
2720 std::cout <<
"llNearbyThreshold = " << llNearbyThreshold <<
", llFitThreshold = " << llFitThreshold << std::endl;
2722 fROOTgErrorIgnoreLevel = gErrorIgnoreLevel;
2723 gErrorIgnoreLevel = 1001;
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){
2730 double lookup[2] = {event1.easting, event1.northing};
2732 std::vector<Int_t> event2Inds;
2733 std::vector<Double_t> event2EastingNorthingDistances;
2734 UInt_t lastNumNeighbours = 0;
2735 UInt_t numNeighbours = 2048;
2737 Double_t furthestConsidered = 0;
2738 Int_t numConsidered = 0;
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]);
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);
2749 if(event2EastingNorthingDistances[i] > furthestConsidered){
2750 furthestConsidered = event2EastingNorthingDistances[i];
2753 double ll = dMin(&event1, &event2);
2754 Double_t surfaceDist = 1e-3*event1.cartesianSeparation(event2);
2756 if(ll > llFitThreshold && surfaceDist > surfaceDistThresholdKm){
2757 ll = dFit(&event1, &event2);
2760 if(ll < event1.nearestEventSurfaceLogLikelihood){
2761 event1.nearestEventSurfaceLogLikelihood = ll;
2762 event1.nearestEventSurfaceLLEventNumber = event2.eventNumber;
2765 if(surfaceDist < event1.nearestEventSurfaceDistanceKm){
2766 event1.nearestEventSurfaceDistanceKm = surfaceDist;
2767 event1.nearestEventSurfaceEventNumber = event2.eventNumber;
2770 for(
int z=0; z < event1.nThresholds; z++){
2771 if(surfaceDist < surfaceDistThresholdKm || ll <= llEventCuts.at(z)){
2772 event1.cluster[z] = event2.cluster[z];
2777 lastNumNeighbours = numNeighbours;
2780 const char* prefix = event1.cluster[0] < 0 ?
"Did not find" :
"Found";
2781 std::cerr << prefix <<
" a match after " << numConsidered <<
" events" << std::endl;
2786 gErrorIgnoreLevel = fROOTgErrorIgnoreLevel;
2789 void Acclaim::Clustering::LogLikelihoodMethod::setInitialBaseClusters(){
2791 for(UInt_t eventInd=0; eventInd < events.size(); eventInd++){
2792 Event&
event = events.at(eventInd);
2793 Int_t clusterInd =
event.nearestKnownBaseCluster;
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){
2800 event.cluster[z] = cluster.index;
2809 void Acclaim::Clustering::LogLikelihoodMethod::doMcBaseClustering(){
2811 std::cout << __PRETTY_FUNCTION__ << std::endl;
2813 ProgressBar p(mcEvents.size());
2814 const int nBases = BaseList::getNumBases();
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);
2826 if(surfaceSeparationKm < mcEvent->nearestKnownBaseSurfaceSeparationKm){
2827 mcEvent->nearestKnownBaseSurfaceSeparationKm = surfaceSeparationKm;
2829 if(mcEvent->nearestKnownBaseSurfaceSeparationKm < surfaceDistThresholdKm){
2830 mcEvent->nearestKnownBaseCluster = clusterInd;
2834 if(ll < mcEvent->nearestKnownBaseLogLikelihood && mcEvent->nearestKnownBaseSurfaceSeparationKm >= surfaceDistThresholdKm){
2835 mcEvent->nearestKnownBaseCluster = clusterInd;
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;
2853 void Acclaim::Clustering::LogLikelihoodMethod::doClustering(
const char* dataGlob,
const char* mcGlob,
const char* outFileName,
bool useAcclaimFiles){
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;
2861 const char* fakeArgv[1] = {outFileName};
2863 OutputConvention oc(1, const_cast<char**>(fakeArgv));
2864 fOut = useAcclaimFiles ? oc.makeFile() :
new TFile(outFileName,
"RECREATE");
2871 if(!fEventsAlreadyClustered){
2873 doBaseEventClustering();
2875 doMcBaseClustering();
2878 if(!fEventsAlreadyClustered){
2879 doEventEventClustering();
2881 doMcEventClustering();
2894 void Acclaim::Clustering::LogLikelihoodMethod::testSmallClusters(
const char* dataGlob,
const char* outFileName,
int clusterSizeMin,
int clusterSizeMax,
int nAttempts){
2897 fOut =
new TFile(outFileName,
"RECREATE");
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");
2907 readInSummariesForTesting(dataGlob);
2909 for(
int i = 0; i < nAttempts; i++)
2911 Int_t n_in_cluster = tr3->Uniform(clusterSizeMin, clusterSizeMax);
2912 pickEventsFromList(n_in_cluster);
2913 std::sort(events.begin(), events.end());
2915 doEventEventClustering();
2916 addToHistograms(h, h2);
2918 for(
int j = 0; j < clusters.size(); j++) {
2919 clusters.at(j).clear();
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.
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'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'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
McEvent(Int_t nT=0)
MC information.
Int_t numDataEvents
cluster center altitude
Double_t theta
Anita'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)
Double_t longitude
latitude
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...
Same as event, but with an energy and a weight.
Double_t longitude
on continent, or -9999 if doesn't intersect
Double_t theta
peak phi, degrees
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.
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
void setNThresholds(int n)
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't intersect
Int_t peakIndex
Polarization.