ROOT logo
// $Id$
/*
 * Drawing macro for reading the THnSparse output of the 
 * HLT/QA/tasks/AliAnalysisTaskHLTCentralBarrel.cxx task.
 * 
 * The cuts are user defined around lines 124-128 as members
 * of an array of structures. Now there are a few predefined sets of cuts.
 * 
 * The input file contains information about the run number
 * and date that will appear in the canvas title.
 * 
 * The cuts are turned into strings and incorporated in the
 * name of the output file, which contains canvases with event
 * and track properties for HLT and offline.
 *  
 * Since the run information is available, there will be a new
 * folder created and the canvas ROOT files will be saved in there.
 *
 * The macro should be compiled before running:
 *
 * root[0] .L drawTHnSparse.C++
 * root[1] drawTHnSparse("HLT-OFFLINE-CentralBarrel-comparison.root")
 *
 * In case more than 1 sets of cuts have been used, the macro creates a canvas
 * and overlays the different histograms both for HLT and OFF, if the latter
 * is available.
 * 
 * If the user wants more flexibility adding the TLegend that explains the cuts,
 * the macro HLT/QA/tasks/macros/overlayPlots.C should be used. For the current one
 * the legends of the histograms are somewhat difficult to print at the moment.
 * The text keeps appearing in the wrong location (Kelly, 17.05.2011).
 *
 * @ingroup alihlt_qa
 * @author Kalliopi.Kanaki@ift.uib.no 
 */

#if !defined(__CINT__) || defined(__MAKECINT__)
#include "TSystem.h"
#include "TROOT.h"
#include "TFile.h"
#include "TString.h"
#include "TList.h"
#include "THnSparse.h"
#include "TCanvas.h"
#include "TText.h"
#include "TPaveText.h"
#include "TPaveStats.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TH3D.h"
#include "TLegend.h"
#include "TStyle.h"
#include "TPad.h"
#include <iostream>
#include <iomanip>
#include <cstdlib>
using std::endl;
#endif

//---------- forward declerations ---------------//

struct cuts { float minEta; float maxEta; float minPt; float maxPt; float minDCAr; float maxDCAr; float minDCAz; float maxDCAz;
	      int minTPCclus; int maxTPCclus; int minITSclus; int maxITSclus; int vertexStatus; float vertexZ; int minV0cent; int maxV0cent;	 
            };
vector<TString> outputNames;
void cutStudies( TString folder,  THnSparse* htrackHLT, THnSparse* htrackOFF, TText* hText, cuts cut);
void printStats(TH1D *hlt, TH1D *off);
void defineYaxisMax(TH1D *h1, TH1D *h2);
void printLegend(TH1D *hlt, TH1D *off);
void plot2D( THnSparse* h, TText *hText, TString folder, cuts cut );
void plotEventQuantities(THnSparse* heventHLT, THnSparse* heventOFF, TText* hText, TString folder,TString fBeamType);
TString fix1DTitle(const char* c);
TString fix2DTitle(const char* c1, const char* c2);
TString cutsToString( cuts cut );
void plotTrackQuantities( THnSparse* htrackHLT, THnSparse* htrackOFF, TText* hText, TString folder, cuts cut);
void printCuts(cuts cut);	

//------------------------------------------------------------------//		

void drawTHnSparse(TString beamType="p-p", TString inputFile="HLT-OFFLINE-CentralBarrel-comparison.root"){
 
  gROOT->SetStyle("Plain");
  gStyle->SetPalette(1);
  gStyle->SetOptStat("emr");
  gStyle->SetTitleX(gStyle->GetPadLeftMargin());
  TH1::AddDirectory(kFALSE);

  TFile *file = TFile::Open(inputFile);
  if(!file){
    printf("Error: No file %s in folder.\n", inputFile.Data());
    return;
  }
  TList *list = static_cast<TList*>(file->Get("esd_thnsparse"));
  if(!list){
    printf("Error: No List contained in file %s.\n", inputFile.Data());
    return;
  }
  THnSparseF *heventHLT = (THnSparseF*)list->FindObject("fEventHLT"); 
  if(!heventHLT){
      printf("Error: There is no HLT THnSparse object in file %s\n", inputFile.Data());
      return;
  }
  THnSparseF *heventOFF = (THnSparseF*)list->FindObject("fEventOFF");  
  if(!heventOFF){
      printf("Error: There is no OFF THnSparse object in file %s\n", inputFile.Data());
      return;
  } 
  THnSparseF *htrackHLT = (THnSparseF*)list->FindObject("fTrackHLT");
  if(!htrackHLT){
      printf("Error: No HLT THnSparse object found\n");
      return;
  } 
  THnSparseF *htrackOFF = (THnSparseF*)list->FindObject("fTrackOFF");  
  if(!htrackOFF){
      printf("Error: No OFF THnSparse object found\n");
      return;
  }
      
  TText *hText = (TText*)list->FindObject("text");
  if(!hText) printf("No hText\n");

  TString folder = "CentralBarrelTask_";
  folder += hText->GetTitle();
  folder.ReplaceAll(" ",""); 
  folder.ReplaceAll(",","_");    
  gSystem->Exec("mkdir "+folder); // create a folder whose name contains run number and date of run
  
  if(heventHLT->GetEntries()>0 || heventOFF->GetEntries()>0) plotEventQuantities(heventHLT,heventOFF,hText,folder,beamType);
  else {
    if(heventHLT->GetEntries()==0) printf("\nThe HLT event THnSparse contains 0 entries\n");
    if(heventOFF->GetEntries()==0) printf("\nThe OFF event THnSparse contains 0 entries\n");
  }   
   
  cuts p[] = {                                                                                                                                                                               
         // eta    pt      DCAr     DCAz    TPCclus  ITSclus  vtxStatus  |vtxZ|   V0cent                                                                                                
       {-1, 1,  0,   10, -10, 10, -10, 10,  0, 200,   0, 10,      2,       10,   0, 100},                                                                                                    
       {-1, 1,  0.30,10,  -7,  7,  -7,  7,  0, 200,   0, 10,      2,       10,   0, 100},                                                                                                    
       {-1, 1,  0.60,10,  -7,  7,  -7,  7,  0, 200,   0, 10,      2,       10,   0, 100},                                                                                                    
       {-1, 1,  0.90,10,  -7,  7,  -7,  7,  0, 200,   0, 10,      2,       10,   0, 100}                                                                                                     
  };                                                                                                                                                                                         
  const int nCutSets = sizeof(p)/sizeof(cuts);
 
  for(int i=0; i<nCutSets; ++i) cutStudies(folder, htrackHLT, htrackOFF, hText, p[i]); 
  
  // the TString vector outputNames is filled at the end of the cutStudies() call with the name of the output name for every cut.  
  // If there is more than 1 set of cuts, then there will be 2 new canvases created, HLT and OFF respectively with the overlaid track properties
     
  if(outputNames.size()>=2){          
     TString tmp = "overlaid HLT track distributions for ";
     tmp += hText->GetTitle();
     TCanvas *ovHLT = new TCanvas("ovHLT",tmp,1200,800);
     ovHLT->Divide(4,2);
     
     tmp = "overlaid OFF track distributions for ";
     tmp += hText->GetTitle();
     TCanvas *ovOFF = new TCanvas("ovOFF",tmp,1200,800);
     ovOFF->Divide(4,2);

     TCanvas *ca; TFile *ff; TPad *pad; 
     TH1D *hlt[outputNames.size()];
     TH1D *off[outputNames.size()];
          
     for(int j=1; j<9; j++){ // loop over the pads of the canvas "ov" with dimension 3x3     
       for(UInt_t i=0; i<outputNames.size(); i++){ // loop over the files with different sets of cuts
    	      
     	   ff = TFile::Open(outputNames[i].Data());   
     	   if(!ff || ff->IsZombie()){
     	      printf("Non-existent, corrupted or zombie file %s\n", outputNames[i].Data());
     	      continue;
     	   } 
     	   ca  = (TCanvas*)ff->GetObjectUnchecked("can3");	       
     	   if(!ca){
     	      printf("Empty canvas in file %s\n", outputNames[i].Data());
     	      continue;
     	   }	   
     	   pad = (TPad*)ca->GetListOfPrimitives()->FindObject(Form("can3_%d",j));	   
     	   if(!pad){
     	      printf("Empty pad in canvas %s\n", ca->GetName());
     	      continue; 	
     	   }

     	   hlt[i] =(TH1D*)pad->FindObject(Form("fTrackHLT_proj_%d",j-1)); 	   	   	   
     	   if(!hlt[i]){
     	      printf("Empty HLT histogram for cuts i=%d, file %s\n", i, outputNames[i].Data());
     	      continue;
     	   }
	   
	   ovHLT->cd(j); 	       	  
   	   if(i==0){
	      hlt[i]->Draw();
	   }
     	   else { 
     	     hlt[i]->SetLineColor(i+1); 
     	     defineYaxisMax(hlt[0], hlt[i]); 
     	     hlt[i]->Draw("sames");
     	   }
     	   if(i>0) printStats(hlt[i-1], hlt[i]);
	   
  	   off[i] =(TH1D*)pad->FindObject(Form("fTrackOFF_proj_%d",j-1));
	   if(!off[i]){
     	      printf("Empty OFF histogram for cuts i=%d, file %s\n", i, outputNames[i].Data());
     	      continue;
     	   }
	   
	   ovOFF->cd(j);	   
     	   if(i==0){
	      off[i]->SetLineColor(kBlack); 
	      off[i]->Draw();
              TPaveStats *st = (TPaveStats*)off[i]->FindObject("stats"); 
              st->SetTextColor(kBlack);
	      ovOFF->Update();
	   }
     	   else { 
     	     off[i]->SetLineColor(i+1); 
     	     defineYaxisMax(off[0], off[i]); 
     	     off[i]->Draw("sames");
     	   }
	   if(i>0) printStats(off[i-1], off[i]);
	   
     	   ff->Close(); 				    
       } // end of loop over files 
     } // end of loop over canvas pads
     file->Close();  
     ovHLT->Update(); 
     ovHLT->SaveAs(folder+"/overlaid_HLT_track_cuts.root");
     ovHLT->Print(folder+"/overlaid_HLT_track_cuts.png");  
     ovOFF->Update();
     ovOFF->SaveAs(folder+"/overlaid_OFF_track_cuts.root");
     ovOFF->Print(folder+"/overlaid_OFF_track_cuts.png");  
     //delete ovHLT;
     //delete ovOFF;
  } // end if for counter>=2
  return;
}

// ============== main function for filling the track properties, 1D and 2D ================ //

void cutStudies( TString folder, THnSparse* htrackHLT, THnSparse* htrackOFF, TText* hText, cuts cut){
 
  printCuts(cut);
  plotTrackQuantities(htrackHLT, htrackOFF, hText, folder, cut); 
  if(htrackHLT->GetEntries()>0) plot2D(htrackHLT, hText, folder, cut);  
  if(htrackOFF->GetEntries()>0) plot2D(htrackOFF, hText, folder, cut);
   
  TString strcuts = cutsToString(cut);  
  outputNames.push_back(folder+"/track_properties_"+strcuts+".root");
  return;
}

void plotEventQuantities(THnSparse* heventHLT, THnSparse* heventOFF, TText* hText, TString folder, TString fBeamType){

  TString tmp = "vertex event properties for ";
  tmp += hText->GetTitle();
  TCanvas *can1 = new TCanvas("can1",tmp,1200,700);
  can1->Divide(3,2); 
  
  heventHLT->GetAxis(8)->SetRangeUser(1,1); // select events with existing primary vertex	
  heventOFF->GetAxis(8)->SetRangeUser(1,1);
  TH1D *hlt = NULL; 
  TH1D *off = NULL; 
  
  for(int i=0; i<6; i++){ // loop for HLT/OFF primary and SPD vertex xyz
      can1->cd(i+1);
      hlt = heventHLT->Projection(i); if(!hlt){ printf("plotEventQuantities: empty HLT histogram, projection %d\n",i); continue; }
      off = heventOFF->Projection(i); if(!off){ printf("plotEventQuantities: empty OFF histogram, projection %d\n",i); continue; }
      off->SetLineColor(2); 
      hlt->SetTitle(fix1DTitle(heventHLT->Projection(i)->GetTitle())); 
      off->SetTitle(fix1DTitle(heventOFF->Projection(i)->GetTitle()));       
      TString s = hlt->GetTitle();	
      if(s.Contains("primary")){ 
  	 s+=" (cm)";
  	 hlt->SetXTitle(s); 
  	 off->SetXTitle(s);    
      }
      if(off->GetEntries()>0) defineYaxisMax(hlt, off);
      
      if(hlt->GetEntries()>0) hlt->Draw();
      if(off->GetEntries()>0) off->Draw("sames");
      if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);
      if(off->GetEntries()>0 && i==0 ) printLegend(hlt,off);
  }
  
  tmp = "general event properties for ";
  tmp += hText->GetTitle(); 
  TCanvas *can2 = new TCanvas("can2",tmp,1200,700);
  can2->Divide(3,2);
  
  can2->cd(1); // track multiplicity
  if(fBeamType.Contains("p-p")){
    heventHLT->GetAxis(7)->SetRangeUser(0,1000);
    heventOFF->GetAxis(7)->SetRangeUser(0,1000);
  }
  hlt = heventHLT->Projection(7); 
  off = heventOFF->Projection(7); 
  off->SetLineColor(2); 
  hlt->SetTitle(fix1DTitle(heventHLT->Projection(7)->GetTitle())); 
  off->SetTitle(fix1DTitle(heventOFF->Projection(7)->GetTitle()));	 
  if(off->GetEntries()>0) defineYaxisMax(hlt, off);
  if(hlt->GetEntries()>0) hlt->Draw();
  if(off->GetEntries()>0){ off->Draw("sames"); printLegend(hlt,off); }
  if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);

  can2->cd(2); // number of contributors
  if(fBeamType.Contains("p-p")){
    heventHLT->GetAxis(6)->SetRangeUser(0,1000);
    heventOFF->GetAxis(6)->SetRangeUser(0,1000);
  }
  hlt = heventHLT->Projection(6); 
  off = heventOFF->Projection(6); 
  off->SetLineColor(2); 
  hlt->SetTitle(fix1DTitle(heventHLT->Projection(6)->GetTitle())); 
  off->SetTitle(fix1DTitle(heventOFF->Projection(6)->GetTitle()));	 
  if(off->GetEntries()>0) defineYaxisMax(hlt, off);
  if(hlt->GetEntries()>0) hlt->Draw();
  if(off->GetEntries()>0) off->Draw("sames");
  if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);
   
  can2->cd(3); // vertex status
  hlt = heventHLT->Projection(8); 
  off = heventOFF->Projection(8); 
  off->SetLineColor(2); 
  hlt->SetTitle(fix1DTitle(heventHLT->Projection(8)->GetTitle())); 
  off->SetTitle(fix1DTitle(heventOFF->Projection(8)->GetTitle()));	 
  if(off->GetEntries()>0) defineYaxisMax(hlt, off);
  if(hlt->GetEntries()>0) hlt->Draw();
  if(off->GetEntries()>0) off->Draw("sames");
  if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off); 
  
  can2->cd(4); // # of contributors vs. track multiplicity for HLT
  TH2D *h = heventHLT->Projection(6,7);
  TString s1 = fix2DTitle(heventHLT->Projection(6)->GetTitle(), heventHLT->Projection(7)->GetTitle()); s1+=" (HLT)";
  h->SetTitle(s1);
  h->Draw("colz");
  
  can2->cd(5); // # of contributors vs. track multiplicity for OFF
  TH2D *o = heventOFF->Projection(6,7);
  s1 = fix2DTitle(heventOFF->Projection(6)->GetTitle(), heventOFF->Projection(7)->GetTitle()); s1+=" (OFF)";
  o->SetTitle(s1);
  o->Draw("colz");
   
  if(heventHLT->GetNdimensions()==10){
     can2->cd(6);
     off = heventOFF->Projection(9); // V0 centrality, taken from the offline ESD
     off->SetTitle(fix1DTitle(heventOFF->Projection(9)->GetTitle()));
     off->SetLineColor(2);
     off->Draw();
  }  
  
  can1->SaveAs(folder+"/vertex_event_properties.root");
  can1->SaveAs(folder+"/vertex_event_properties.png");
  can2->SaveAs(folder+"/general_event_properties.root");
  can2->SaveAs(folder+"/general_event_properties.png");
  //delete can1;
  //delete can2;
    
  return;
}

void plotTrackQuantities( THnSparse* htrackHLT, THnSparse* htrackOFF, TText* hText, TString folder, cuts cut ){   
  
  htrackHLT->GetAxis(0)->SetRangeUser(cut.minPt,cut.maxPt);
  htrackHLT->GetAxis(1)->SetRangeUser(cut.minTPCclus,cut.maxTPCclus);
  htrackHLT->GetAxis(2)->SetRangeUser(cut.minEta, cut.maxEta);
  htrackHLT->GetAxis(4)->SetRangeUser(cut.minDCAr, cut.maxDCAr);
  htrackHLT->GetAxis(5)->SetRangeUser(cut.minDCAz, cut.maxDCAz);
  htrackHLT->GetAxis(7)->SetRangeUser(cut.minITSclus, cut.maxITSclus);
  if(cut.vertexStatus!=2) htrackHLT->GetAxis(8)->SetRangeUser(cut.vertexStatus, cut.vertexStatus);
  htrackHLT->GetAxis(9)->SetRangeUser(-TMath::Abs(cut.vertexZ), TMath::Abs(cut.vertexZ));
  if(htrackHLT->GetNdimensions()==11) htrackHLT->GetAxis(10)->SetRangeUser(cut.minV0cent, cut.maxV0cent);
  
  htrackOFF->GetAxis(0)->SetRangeUser(cut.minPt,cut.maxPt);
  htrackOFF->GetAxis(1)->SetRangeUser(cut.minTPCclus,cut.maxTPCclus);
  htrackOFF->GetAxis(2)->SetRangeUser(cut.minEta, cut.maxEta);
  htrackOFF->GetAxis(4)->SetRangeUser(cut.minDCAr, cut.maxDCAr);
  htrackOFF->GetAxis(5)->SetRangeUser(cut.minDCAz, cut.maxDCAz);
  htrackOFF->GetAxis(7)->SetRangeUser(cut.minITSclus, cut.maxITSclus);
  if(cut.vertexStatus!=2) htrackOFF->GetAxis(8)->SetRangeUser(cut.vertexStatus,cut.vertexStatus);
  htrackOFF->GetAxis(9)->SetRangeUser(-TMath::Abs(cut.vertexZ), TMath::Abs(cut.vertexZ));
  if(htrackOFF->GetNdimensions()==11) htrackOFF->GetAxis(10)->SetRangeUser(cut.minV0cent, cut.maxV0cent);
  
  TString tmp = "";
  tmp += "track properties for ";
  tmp+=hText->GetTitle();     
  TCanvas *can3 = new TCanvas("can3",tmp,1600,1000); 
  can3->Divide(4,2); 
  // the first 9 track related variables filled in the THnSparse
  //  0	    1     2    3     4      5      6     7   
  // pt  TPCcl  eta   phi   DCAr  DCAz charge  ITScl 
  
  TH1D *hlt = NULL; 
  TH1D *off = NULL;

  TLegend *leg = new TLegend(0.25,0.2,0.85,0.85);

  for(int i=0; i<8; i++){  
    hlt = htrackHLT->Projection(i); if(!hlt){ printf("plotTrackQuantities: empty HLT histogram for projection %d\n",i); continue; }
    off = htrackOFF->Projection(i); if(!off){ printf("plotTrackQuantities: empty OFF histogram for projection %d\n",i); continue; }     
    hlt->SetTitle(fix1DTitle(htrackHLT->Projection(i)->GetTitle())); 
    off->SetTitle(fix1DTitle(htrackOFF->Projection(i)->GetTitle())); // is necessary in cases where only offline data is available
  
    TString s = hlt->GetTitle();      
    if(s.Contains("p_")){ 
      s+=" (GeV/c)";
      hlt->SetXTitle(s);     
    }
    else if(s.Contains("phi")){
      s+=" (rad)"; 
      hlt->SetXTitle(s);
    }
    else if(s.Contains("DCA")){
      s+=" (cm)";
      hlt->SetXTitle(s);
    }
       
    if(off->GetEntries()>0) defineYaxisMax(hlt, off);
    off->SetLineColor(2);
   
    can3->cd(i+1);
    if(hlt->GetEntries()>0) hlt->Draw();
    if(off->GetEntries()>0) off->Draw("sames");
    if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);
    if(off->GetEntries()>0 && i==0 ) printLegend(hlt,off);
     
    if(hlt->GetEntries()>0 && i==0){
      leg->SetFillColor(kWhite);
      leg->SetLineColor(kWhite);
      leg->SetShadowColor(kWhite);
      s=""; s+=cut.minEta; s+="<#eta< "; s+=cut.maxEta;leg->AddEntry((TObject*)0, s, "");  
      s=""; s+=cut.minPt; s.Resize(4); s+="<p_{T} (GeV/c)<"; s+=cut.maxPt;  leg->AddEntry((TObject*)0, s, ""); 
      s=""; s+=cut.minDCAr; s+="<DCAr (cm)<"; s+=cut.maxDCAr; leg->AddEntry((TObject*)0, s, "");  
      s=""; s+=cut.minDCAz; s+="<DCAz (cm)<"; s+=cut.maxDCAz; leg->AddEntry((TObject*)0, s, "");  
      if(cut.minTPCclus!=0 && cut.maxTPCclus!=200){ s=""; s+=cut.minTPCclus; s+="<TPC cls/tr<"; s+=cut.maxTPCclus; leg->AddEntry((TObject*)0, s, "");}
      if(cut.minITSclus!=0 && cut.maxITSclus!=10){ s=""; s+=cut.minITSclus; s+="<ITS cls/tr<"; s+=cut.maxITSclus; leg->AddEntry((TObject*)0, s, "");}
      s=""; s+="|vertexZ| (cm)<"; s+=TMath::Abs(cut.vertexZ); leg->AddEntry((TObject*)0, s, ""); 
      if(cut.vertexStatus!=2) { s=""; s+="vertex status "; s+=cut.vertexStatus; leg->AddEntry((TObject*)0, s, ""); }
      if(htrackHLT->GetNdimensions()==11) { s=""; s+=cut.minV0cent; s+=" < V0 centr < "; s+=cut.maxV0cent; leg->AddEntry((TObject*)0, s, "");  }
      
      leg->Draw();
      
      can3->Update();
	}      
  } 
  TString strcuts = cutsToString(cut);
  
  can3->SaveAs(folder+"/track_properties_"+strcuts+".root");
  can3->SaveAs(folder+"/track_properties_"+strcuts+".png");
  delete can3;
  delete leg;

  return;
}

//====================== for 2D track distributions ===============================//

void plot2D( THnSparse* h, TText *hText, TString folder, cuts cut ){

  h->GetAxis(0)->SetRangeUser(cut.minPt,cut.maxPt);
  h->GetAxis(1)->SetRangeUser(cut.minTPCclus,cut.maxTPCclus);
  h->GetAxis(2)->SetRangeUser(cut.minEta, cut.maxEta);
  h->GetAxis(4)->SetRangeUser(cut.minDCAr, cut.maxDCAr);
  h->GetAxis(5)->SetRangeUser(cut.minDCAz, cut.maxDCAz);
  h->GetAxis(7)->SetRangeUser(cut.minITSclus,cut. maxITSclus);
  if(cut.vertexStatus!=2) h->GetAxis(8)->SetRangeUser(cut.vertexStatus,cut.vertexStatus);
  h->GetAxis(9)->SetRangeUser(-TMath::Abs(cut.vertexZ), TMath::Abs(cut.vertexZ));
  if(h->GetNdimensions()==11) h->GetAxis(10)->SetRangeUser(cut.minV0cent, cut.maxV0cent);
  
  TString name = h->GetName();
  TString tmp = "";
  if(name.Contains("HLT")) tmp = "HLT 2-D track distributions for ";
  else tmp = "OFF 2-D track distributions for ";

  tmp += hText->GetTitle();
  TCanvas *can4 = new TCanvas("can4",tmp,1200,800);
  can4->Divide(4,2);

  can4->cd(1);    
  TH2D *ht = h->Projection(1,0); // TPC clusters/track vs. pt
  ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(0)->GetTitle()));

  TString s = "";
  s = fix1DTitle(h->Projection(0)->GetTitle())+" (GeV/c)";
  ht->SetXTitle(s);
  ht->Draw("colz");
  
  can4->cd(2);
  ht = h->Projection(1,2); // TPC clusters/track vs. eta
  ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(2)->GetTitle()));
  ht->Draw("colz");
  
  can4->cd(3);
  ht = h->Projection(1,4); // TPC clusters/track vs. DCAr
  ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(4)->GetTitle()));
  s = fix1DTitle(h->Projection(4)->GetTitle())+" (cm)";
  ht->SetXTitle(s);
  ht->Draw("colz");
  
  can4->cd(4);
  ht = h->Projection(1,5); // TPC clusters/track vs. DCAz
  ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(5)->GetTitle()));
  s = fix1DTitle(h->Projection(5)->GetTitle())+" (cm)";
  ht->SetXTitle(s);
  ht->Draw("colz");
  
  can4->cd(5);
  ht = h->Projection(4,0); // DCAr vs. pt
  ht->SetTitle(fix2DTitle(h->Projection(4)->GetTitle(), h->Projection(0)->GetTitle()));
  s = fix1DTitle(h->Projection(0)->GetTitle())+" (GeV/c)";
  ht->SetXTitle(s);
  s = fix1DTitle(h->Projection(4)->GetTitle())+" (cm)";
  ht->SetYTitle(s);
  ht->Draw("colz");
  
  can4->cd(6);
  ht = h->Projection(5,3); // DCAz vs. pt
  ht->SetTitle(fix2DTitle(h->Projection(5)->GetTitle(), h->Projection(3)->GetTitle()));
  s = fix1DTitle(h->Projection(5)->GetTitle())+" (cm)";
  ht->SetYTitle(s);
  ht->Draw("colz");
  
  can4->cd(7);
  ht = h->Projection(2,0); // eta vs. pt
  ht->SetTitle(fix2DTitle(h->Projection(2)->GetTitle(), h->Projection(0)->GetTitle()));
  s = fix1DTitle(h->Projection(0)->GetTitle())+" (GeV/c)";
  ht->SetXTitle(s);
  ht->Draw("colz");
  
  can4->cd(8);
  ht = h->Projection(2,3); // eta vs. phi
  ht->SetTitle(fix2DTitle(h->Projection(2)->GetTitle(), h->Projection(3)->GetTitle()));
  s = fix1DTitle(h->Projection(3)->GetTitle())+" (rad)";
  ht->SetXTitle(s);
  ht->Draw("colz");
 
  TString strcuts = cutsToString(cut);
  if(name.Contains("HLT")){
     can4->SaveAs(folder+"/HLT_2D_track_correlations_"+strcuts+".root"); 
     can4->SaveAs(folder+"/HLT_2D_track_correlations_"+strcuts+".png"); 
  } else {
     can4->SaveAs(folder+"/OFF_2D_track_correlations_"+strcuts+".root"); 
     can4->SaveAs(folder+"/OFF_2D_track_correlations_"+strcuts+".png"); 
  }
  //delete can4;
  return;
}

TString cutsToString( cuts cut ){
 
  TString strcuts = "";
  char s[300]; sprintf(s, "eta%2g_%2g_Pt%2g_%2g_DCAr%2g_%2g_DCAz%2g_%2g_TPCclus%d_%d_ITSclus%d_%d_Zvertex%2g_cent%d_%d", 
                           cut.minEta,cut.maxEta,cut.minPt,cut.maxPt,cut.minDCAr,cut.maxDCAr,cut.minDCAz,cut.maxDCAz,cut.minTPCclus,cut.maxTPCclus,cut.minITSclus,
			   cut.maxITSclus,cut.vertexZ,cut.minV0cent,cut.maxV0cent);
  strcuts = s; strcuts.ReplaceAll(" ","");
 
  if(cut.vertexStatus!=2){
    char v[10]; 
    sprintf(v, "_VS%d",cut.vertexStatus);
    strcuts+=v;
  }
  return strcuts;
}

void printStats(TH1D *hlt, TH1D *off){  
  gPad->Update();
  TPaveStats *st1 = (TPaveStats*)hlt->FindObject("stats");
  st1->SetLineColor(0);
  //st1->SetTextSize(7);
  //st1->SetTextFont(8);

  gPad->Update();
  TPaveStats *st2 = (TPaveStats*)off->FindObject("stats");
  st2->SetY2NDC(st1->GetY1NDC()-0.05);
  st2->SetY1NDC(st2->GetY2NDC()-TMath::Abs(st1->GetY1NDC()-st1->GetY2NDC()));
  st2->SetLineColor(0);
  st2->SetTextColor(off->GetLineColor());
  st2->SetFillStyle(0);
  //st2->SetTextSize(7);
  //st2->SetTextFont(8);
  st2->Draw();
  return;
}

void defineYaxisMax(TH1D *h1, TH1D *h2){ 
  //Y axis
  if(h1->GetMaximum() > h2->GetMaximum()) h2->SetMaximum(1.1*h1->GetMaximum());
  else h1->SetMaximum(1.1*h2->GetMaximum());
  
  h1->SetMinimum(0);
  h2->SetMinimum(0);
 
  // X axis  
  double xmin, xmax;  
  if(h1->GetBinLowEdge(1) > h2->GetBinLowEdge(1)) xmin = h1->GetBinLowEdge(1);
  else xmin = h2->GetBinLowEdge(1);
  if(h1->GetBinLowEdge(h1->GetNbinsX()+1) > h2->GetBinLowEdge(h1->GetNbinsX()+1)) xmax = h1->GetBinLowEdge(h1->GetNbinsX()+1);
  else xmax = h2->GetBinLowEdge(h2->GetNbinsX()+1);
  
  h2->SetAxisRange(xmin, xmax, "X");  
  return;
}

void printLegend(TH1D *hlt, TH1D *off){  
  TLegend *l = new TLegend(0.68,0.16,0.88,0.36);
  l->SetFillColor(10); 
  l->SetLineColor(10);
  l->AddEntry(hlt, "HLT", "l");
  l->AddEntry(off, "OFF", "l");
  l->Draw("same");
  return;
}

TString fix1DTitle(const char* c){
  TString tmp = c;
  tmp.ReplaceAll("projection ","");
  return tmp;   
}

TString fix2DTitle(const char* c1, const char* c2){
  TString tmp = fix1DTitle(c1)+" vs."+fix1DTitle(c2);
  return tmp;
}

void printCuts(cuts cut){
  printf("\n %2g<eta<%2g, %2g<pt (GeV/c)<%2g, %2g<DCAr (cm)<%2g, %2g<DCAz (cm)<%2g, %d<TPCclus<%d, %d<ITSclus<%d, vertex status %d, |vertexZ| (cm)<%2g, %d<centr (%)<%d \n\n",cut.minEta, cut.maxEta, cut.minPt, cut.maxPt, cut.minDCAr, cut.maxDCAr, cut.minDCAz, cut.maxDCAz, cut.minTPCclus, cut.maxTPCclus, cut.minITSclus, cut.maxITSclus, cut.vertexStatus, cut.vertexZ, cut.minV0cent, cut.maxV0cent );
}
 drawTHnSparse.C:1
 drawTHnSparse.C:2
 drawTHnSparse.C:3
 drawTHnSparse.C:4
 drawTHnSparse.C:5
 drawTHnSparse.C:6
 drawTHnSparse.C:7
 drawTHnSparse.C:8
 drawTHnSparse.C:9
 drawTHnSparse.C:10
 drawTHnSparse.C:11
 drawTHnSparse.C:12
 drawTHnSparse.C:13
 drawTHnSparse.C:14
 drawTHnSparse.C:15
 drawTHnSparse.C:16
 drawTHnSparse.C:17
 drawTHnSparse.C:18
 drawTHnSparse.C:19
 drawTHnSparse.C:20
 drawTHnSparse.C:21
 drawTHnSparse.C:22
 drawTHnSparse.C:23
 drawTHnSparse.C:24
 drawTHnSparse.C:25
 drawTHnSparse.C:26
 drawTHnSparse.C:27
 drawTHnSparse.C:28
 drawTHnSparse.C:29
 drawTHnSparse.C:30
 drawTHnSparse.C:31
 drawTHnSparse.C:32
 drawTHnSparse.C:33
 drawTHnSparse.C:34
 drawTHnSparse.C:35
 drawTHnSparse.C:36
 drawTHnSparse.C:37
 drawTHnSparse.C:38
 drawTHnSparse.C:39
 drawTHnSparse.C:40
 drawTHnSparse.C:41
 drawTHnSparse.C:42
 drawTHnSparse.C:43
 drawTHnSparse.C:44
 drawTHnSparse.C:45
 drawTHnSparse.C:46
 drawTHnSparse.C:47
 drawTHnSparse.C:48
 drawTHnSparse.C:49
 drawTHnSparse.C:50
 drawTHnSparse.C:51
 drawTHnSparse.C:52
 drawTHnSparse.C:53
 drawTHnSparse.C:54
 drawTHnSparse.C:55
 drawTHnSparse.C:56
 drawTHnSparse.C:57
 drawTHnSparse.C:58
 drawTHnSparse.C:59
 drawTHnSparse.C:60
 drawTHnSparse.C:61
 drawTHnSparse.C:62
 drawTHnSparse.C:63
 drawTHnSparse.C:64
 drawTHnSparse.C:65
 drawTHnSparse.C:66
 drawTHnSparse.C:67
 drawTHnSparse.C:68
 drawTHnSparse.C:69
 drawTHnSparse.C:70
 drawTHnSparse.C:71
 drawTHnSparse.C:72
 drawTHnSparse.C:73
 drawTHnSparse.C:74
 drawTHnSparse.C:75
 drawTHnSparse.C:76
 drawTHnSparse.C:77
 drawTHnSparse.C:78
 drawTHnSparse.C:79
 drawTHnSparse.C:80
 drawTHnSparse.C:81
 drawTHnSparse.C:82
 drawTHnSparse.C:83
 drawTHnSparse.C:84
 drawTHnSparse.C:85
 drawTHnSparse.C:86
 drawTHnSparse.C:87
 drawTHnSparse.C:88
 drawTHnSparse.C:89
 drawTHnSparse.C:90
 drawTHnSparse.C:91
 drawTHnSparse.C:92
 drawTHnSparse.C:93
 drawTHnSparse.C:94
 drawTHnSparse.C:95
 drawTHnSparse.C:96
 drawTHnSparse.C:97
 drawTHnSparse.C:98
 drawTHnSparse.C:99
 drawTHnSparse.C:100
 drawTHnSparse.C:101
 drawTHnSparse.C:102
 drawTHnSparse.C:103
 drawTHnSparse.C:104
 drawTHnSparse.C:105
 drawTHnSparse.C:106
 drawTHnSparse.C:107
 drawTHnSparse.C:108
 drawTHnSparse.C:109
 drawTHnSparse.C:110
 drawTHnSparse.C:111
 drawTHnSparse.C:112
 drawTHnSparse.C:113
 drawTHnSparse.C:114
 drawTHnSparse.C:115
 drawTHnSparse.C:116
 drawTHnSparse.C:117
 drawTHnSparse.C:118
 drawTHnSparse.C:119
 drawTHnSparse.C:120
 drawTHnSparse.C:121
 drawTHnSparse.C:122
 drawTHnSparse.C:123
 drawTHnSparse.C:124
 drawTHnSparse.C:125
 drawTHnSparse.C:126
 drawTHnSparse.C:127
 drawTHnSparse.C:128
 drawTHnSparse.C:129
 drawTHnSparse.C:130
 drawTHnSparse.C:131
 drawTHnSparse.C:132
 drawTHnSparse.C:133
 drawTHnSparse.C:134
 drawTHnSparse.C:135
 drawTHnSparse.C:136
 drawTHnSparse.C:137
 drawTHnSparse.C:138
 drawTHnSparse.C:139
 drawTHnSparse.C:140
 drawTHnSparse.C:141
 drawTHnSparse.C:142
 drawTHnSparse.C:143
 drawTHnSparse.C:144
 drawTHnSparse.C:145
 drawTHnSparse.C:146
 drawTHnSparse.C:147
 drawTHnSparse.C:148
 drawTHnSparse.C:149
 drawTHnSparse.C:150
 drawTHnSparse.C:151
 drawTHnSparse.C:152
 drawTHnSparse.C:153
 drawTHnSparse.C:154
 drawTHnSparse.C:155
 drawTHnSparse.C:156
 drawTHnSparse.C:157
 drawTHnSparse.C:158
 drawTHnSparse.C:159
 drawTHnSparse.C:160
 drawTHnSparse.C:161
 drawTHnSparse.C:162
 drawTHnSparse.C:163
 drawTHnSparse.C:164
 drawTHnSparse.C:165
 drawTHnSparse.C:166
 drawTHnSparse.C:167
 drawTHnSparse.C:168
 drawTHnSparse.C:169
 drawTHnSparse.C:170
 drawTHnSparse.C:171
 drawTHnSparse.C:172
 drawTHnSparse.C:173
 drawTHnSparse.C:174
 drawTHnSparse.C:175
 drawTHnSparse.C:176
 drawTHnSparse.C:177
 drawTHnSparse.C:178
 drawTHnSparse.C:179
 drawTHnSparse.C:180
 drawTHnSparse.C:181
 drawTHnSparse.C:182
 drawTHnSparse.C:183
 drawTHnSparse.C:184
 drawTHnSparse.C:185
 drawTHnSparse.C:186
 drawTHnSparse.C:187
 drawTHnSparse.C:188
 drawTHnSparse.C:189
 drawTHnSparse.C:190
 drawTHnSparse.C:191
 drawTHnSparse.C:192
 drawTHnSparse.C:193
 drawTHnSparse.C:194
 drawTHnSparse.C:195
 drawTHnSparse.C:196
 drawTHnSparse.C:197
 drawTHnSparse.C:198
 drawTHnSparse.C:199
 drawTHnSparse.C:200
 drawTHnSparse.C:201
 drawTHnSparse.C:202
 drawTHnSparse.C:203
 drawTHnSparse.C:204
 drawTHnSparse.C:205
 drawTHnSparse.C:206
 drawTHnSparse.C:207
 drawTHnSparse.C:208
 drawTHnSparse.C:209
 drawTHnSparse.C:210
 drawTHnSparse.C:211
 drawTHnSparse.C:212
 drawTHnSparse.C:213
 drawTHnSparse.C:214
 drawTHnSparse.C:215
 drawTHnSparse.C:216
 drawTHnSparse.C:217
 drawTHnSparse.C:218
 drawTHnSparse.C:219
 drawTHnSparse.C:220
 drawTHnSparse.C:221
 drawTHnSparse.C:222
 drawTHnSparse.C:223
 drawTHnSparse.C:224
 drawTHnSparse.C:225
 drawTHnSparse.C:226
 drawTHnSparse.C:227
 drawTHnSparse.C:228
 drawTHnSparse.C:229
 drawTHnSparse.C:230
 drawTHnSparse.C:231
 drawTHnSparse.C:232
 drawTHnSparse.C:233
 drawTHnSparse.C:234
 drawTHnSparse.C:235
 drawTHnSparse.C:236
 drawTHnSparse.C:237
 drawTHnSparse.C:238
 drawTHnSparse.C:239
 drawTHnSparse.C:240
 drawTHnSparse.C:241
 drawTHnSparse.C:242
 drawTHnSparse.C:243
 drawTHnSparse.C:244
 drawTHnSparse.C:245
 drawTHnSparse.C:246
 drawTHnSparse.C:247
 drawTHnSparse.C:248
 drawTHnSparse.C:249
 drawTHnSparse.C:250
 drawTHnSparse.C:251
 drawTHnSparse.C:252
 drawTHnSparse.C:253
 drawTHnSparse.C:254
 drawTHnSparse.C:255
 drawTHnSparse.C:256
 drawTHnSparse.C:257
 drawTHnSparse.C:258
 drawTHnSparse.C:259
 drawTHnSparse.C:260
 drawTHnSparse.C:261
 drawTHnSparse.C:262
 drawTHnSparse.C:263
 drawTHnSparse.C:264
 drawTHnSparse.C:265
 drawTHnSparse.C:266
 drawTHnSparse.C:267
 drawTHnSparse.C:268
 drawTHnSparse.C:269
 drawTHnSparse.C:270
 drawTHnSparse.C:271
 drawTHnSparse.C:272
 drawTHnSparse.C:273
 drawTHnSparse.C:274
 drawTHnSparse.C:275
 drawTHnSparse.C:276
 drawTHnSparse.C:277
 drawTHnSparse.C:278
 drawTHnSparse.C:279
 drawTHnSparse.C:280
 drawTHnSparse.C:281
 drawTHnSparse.C:282
 drawTHnSparse.C:283
 drawTHnSparse.C:284
 drawTHnSparse.C:285
 drawTHnSparse.C:286
 drawTHnSparse.C:287
 drawTHnSparse.C:288
 drawTHnSparse.C:289
 drawTHnSparse.C:290
 drawTHnSparse.C:291
 drawTHnSparse.C:292
 drawTHnSparse.C:293
 drawTHnSparse.C:294
 drawTHnSparse.C:295
 drawTHnSparse.C:296
 drawTHnSparse.C:297
 drawTHnSparse.C:298
 drawTHnSparse.C:299
 drawTHnSparse.C:300
 drawTHnSparse.C:301
 drawTHnSparse.C:302
 drawTHnSparse.C:303
 drawTHnSparse.C:304
 drawTHnSparse.C:305
 drawTHnSparse.C:306
 drawTHnSparse.C:307
 drawTHnSparse.C:308
 drawTHnSparse.C:309
 drawTHnSparse.C:310
 drawTHnSparse.C:311
 drawTHnSparse.C:312
 drawTHnSparse.C:313
 drawTHnSparse.C:314
 drawTHnSparse.C:315
 drawTHnSparse.C:316
 drawTHnSparse.C:317
 drawTHnSparse.C:318
 drawTHnSparse.C:319
 drawTHnSparse.C:320
 drawTHnSparse.C:321
 drawTHnSparse.C:322
 drawTHnSparse.C:323
 drawTHnSparse.C:324
 drawTHnSparse.C:325
 drawTHnSparse.C:326
 drawTHnSparse.C:327
 drawTHnSparse.C:328
 drawTHnSparse.C:329
 drawTHnSparse.C:330
 drawTHnSparse.C:331
 drawTHnSparse.C:332
 drawTHnSparse.C:333
 drawTHnSparse.C:334
 drawTHnSparse.C:335
 drawTHnSparse.C:336
 drawTHnSparse.C:337
 drawTHnSparse.C:338
 drawTHnSparse.C:339
 drawTHnSparse.C:340
 drawTHnSparse.C:341
 drawTHnSparse.C:342
 drawTHnSparse.C:343
 drawTHnSparse.C:344
 drawTHnSparse.C:345
 drawTHnSparse.C:346
 drawTHnSparse.C:347
 drawTHnSparse.C:348
 drawTHnSparse.C:349
 drawTHnSparse.C:350
 drawTHnSparse.C:351
 drawTHnSparse.C:352
 drawTHnSparse.C:353
 drawTHnSparse.C:354
 drawTHnSparse.C:355
 drawTHnSparse.C:356
 drawTHnSparse.C:357
 drawTHnSparse.C:358
 drawTHnSparse.C:359
 drawTHnSparse.C:360
 drawTHnSparse.C:361
 drawTHnSparse.C:362
 drawTHnSparse.C:363
 drawTHnSparse.C:364
 drawTHnSparse.C:365
 drawTHnSparse.C:366
 drawTHnSparse.C:367
 drawTHnSparse.C:368
 drawTHnSparse.C:369
 drawTHnSparse.C:370
 drawTHnSparse.C:371
 drawTHnSparse.C:372
 drawTHnSparse.C:373
 drawTHnSparse.C:374
 drawTHnSparse.C:375
 drawTHnSparse.C:376
 drawTHnSparse.C:377
 drawTHnSparse.C:378
 drawTHnSparse.C:379
 drawTHnSparse.C:380
 drawTHnSparse.C:381
 drawTHnSparse.C:382
 drawTHnSparse.C:383
 drawTHnSparse.C:384
 drawTHnSparse.C:385
 drawTHnSparse.C:386
 drawTHnSparse.C:387
 drawTHnSparse.C:388
 drawTHnSparse.C:389
 drawTHnSparse.C:390
 drawTHnSparse.C:391
 drawTHnSparse.C:392
 drawTHnSparse.C:393
 drawTHnSparse.C:394
 drawTHnSparse.C:395
 drawTHnSparse.C:396
 drawTHnSparse.C:397
 drawTHnSparse.C:398
 drawTHnSparse.C:399
 drawTHnSparse.C:400
 drawTHnSparse.C:401
 drawTHnSparse.C:402
 drawTHnSparse.C:403
 drawTHnSparse.C:404
 drawTHnSparse.C:405
 drawTHnSparse.C:406
 drawTHnSparse.C:407
 drawTHnSparse.C:408
 drawTHnSparse.C:409
 drawTHnSparse.C:410
 drawTHnSparse.C:411
 drawTHnSparse.C:412
 drawTHnSparse.C:413
 drawTHnSparse.C:414
 drawTHnSparse.C:415
 drawTHnSparse.C:416
 drawTHnSparse.C:417
 drawTHnSparse.C:418
 drawTHnSparse.C:419
 drawTHnSparse.C:420
 drawTHnSparse.C:421
 drawTHnSparse.C:422
 drawTHnSparse.C:423
 drawTHnSparse.C:424
 drawTHnSparse.C:425
 drawTHnSparse.C:426
 drawTHnSparse.C:427
 drawTHnSparse.C:428
 drawTHnSparse.C:429
 drawTHnSparse.C:430
 drawTHnSparse.C:431
 drawTHnSparse.C:432
 drawTHnSparse.C:433
 drawTHnSparse.C:434
 drawTHnSparse.C:435
 drawTHnSparse.C:436
 drawTHnSparse.C:437
 drawTHnSparse.C:438
 drawTHnSparse.C:439
 drawTHnSparse.C:440
 drawTHnSparse.C:441
 drawTHnSparse.C:442
 drawTHnSparse.C:443
 drawTHnSparse.C:444
 drawTHnSparse.C:445
 drawTHnSparse.C:446
 drawTHnSparse.C:447
 drawTHnSparse.C:448
 drawTHnSparse.C:449
 drawTHnSparse.C:450
 drawTHnSparse.C:451
 drawTHnSparse.C:452
 drawTHnSparse.C:453
 drawTHnSparse.C:454
 drawTHnSparse.C:455
 drawTHnSparse.C:456
 drawTHnSparse.C:457
 drawTHnSparse.C:458
 drawTHnSparse.C:459
 drawTHnSparse.C:460
 drawTHnSparse.C:461
 drawTHnSparse.C:462
 drawTHnSparse.C:463
 drawTHnSparse.C:464
 drawTHnSparse.C:465
 drawTHnSparse.C:466
 drawTHnSparse.C:467
 drawTHnSparse.C:468
 drawTHnSparse.C:469
 drawTHnSparse.C:470
 drawTHnSparse.C:471
 drawTHnSparse.C:472
 drawTHnSparse.C:473
 drawTHnSparse.C:474
 drawTHnSparse.C:475
 drawTHnSparse.C:476
 drawTHnSparse.C:477
 drawTHnSparse.C:478
 drawTHnSparse.C:479
 drawTHnSparse.C:480
 drawTHnSparse.C:481
 drawTHnSparse.C:482
 drawTHnSparse.C:483
 drawTHnSparse.C:484
 drawTHnSparse.C:485
 drawTHnSparse.C:486
 drawTHnSparse.C:487
 drawTHnSparse.C:488
 drawTHnSparse.C:489
 drawTHnSparse.C:490
 drawTHnSparse.C:491
 drawTHnSparse.C:492
 drawTHnSparse.C:493
 drawTHnSparse.C:494
 drawTHnSparse.C:495
 drawTHnSparse.C:496
 drawTHnSparse.C:497
 drawTHnSparse.C:498
 drawTHnSparse.C:499
 drawTHnSparse.C:500
 drawTHnSparse.C:501
 drawTHnSparse.C:502
 drawTHnSparse.C:503
 drawTHnSparse.C:504
 drawTHnSparse.C:505
 drawTHnSparse.C:506
 drawTHnSparse.C:507
 drawTHnSparse.C:508
 drawTHnSparse.C:509
 drawTHnSparse.C:510
 drawTHnSparse.C:511
 drawTHnSparse.C:512
 drawTHnSparse.C:513
 drawTHnSparse.C:514
 drawTHnSparse.C:515
 drawTHnSparse.C:516
 drawTHnSparse.C:517
 drawTHnSparse.C:518
 drawTHnSparse.C:519
 drawTHnSparse.C:520
 drawTHnSparse.C:521
 drawTHnSparse.C:522
 drawTHnSparse.C:523
 drawTHnSparse.C:524
 drawTHnSparse.C:525
 drawTHnSparse.C:526
 drawTHnSparse.C:527
 drawTHnSparse.C:528
 drawTHnSparse.C:529
 drawTHnSparse.C:530
 drawTHnSparse.C:531
 drawTHnSparse.C:532
 drawTHnSparse.C:533
 drawTHnSparse.C:534
 drawTHnSparse.C:535
 drawTHnSparse.C:536
 drawTHnSparse.C:537
 drawTHnSparse.C:538
 drawTHnSparse.C:539
 drawTHnSparse.C:540
 drawTHnSparse.C:541
 drawTHnSparse.C:542
 drawTHnSparse.C:543
 drawTHnSparse.C:544
 drawTHnSparse.C:545
 drawTHnSparse.C:546
 drawTHnSparse.C:547
 drawTHnSparse.C:548
 drawTHnSparse.C:549
 drawTHnSparse.C:550
 drawTHnSparse.C:551
 drawTHnSparse.C:552
 drawTHnSparse.C:553
 drawTHnSparse.C:554
 drawTHnSparse.C:555
 drawTHnSparse.C:556
 drawTHnSparse.C:557
 drawTHnSparse.C:558
 drawTHnSparse.C:559
 drawTHnSparse.C:560
 drawTHnSparse.C:561
 drawTHnSparse.C:562
 drawTHnSparse.C:563
 drawTHnSparse.C:564
 drawTHnSparse.C:565
 drawTHnSparse.C:566
 drawTHnSparse.C:567
 drawTHnSparse.C:568
 drawTHnSparse.C:569
 drawTHnSparse.C:570
 drawTHnSparse.C:571
 drawTHnSparse.C:572
 drawTHnSparse.C:573
 drawTHnSparse.C:574
 drawTHnSparse.C:575
 drawTHnSparse.C:576
 drawTHnSparse.C:577
 drawTHnSparse.C:578
 drawTHnSparse.C:579
 drawTHnSparse.C:580
 drawTHnSparse.C:581
 drawTHnSparse.C:582
 drawTHnSparse.C:583
 drawTHnSparse.C:584
 drawTHnSparse.C:585
 drawTHnSparse.C:586
 drawTHnSparse.C:587
 drawTHnSparse.C:588
 drawTHnSparse.C:589
 drawTHnSparse.C:590
 drawTHnSparse.C:591
 drawTHnSparse.C:592
 drawTHnSparse.C:593
 drawTHnSparse.C:594
 drawTHnSparse.C:595
 drawTHnSparse.C:596
 drawTHnSparse.C:597
 drawTHnSparse.C:598
 drawTHnSparse.C:599
 drawTHnSparse.C:600
 drawTHnSparse.C:601
 drawTHnSparse.C:602
 drawTHnSparse.C:603
 drawTHnSparse.C:604
 drawTHnSparse.C:605
 drawTHnSparse.C:606
 drawTHnSparse.C:607
 drawTHnSparse.C:608
 drawTHnSparse.C:609
 drawTHnSparse.C:610
 drawTHnSparse.C:611
 drawTHnSparse.C:612
 drawTHnSparse.C:613
 drawTHnSparse.C:614
 drawTHnSparse.C:615
 drawTHnSparse.C:616
 drawTHnSparse.C:617
 drawTHnSparse.C:618
 drawTHnSparse.C:619
 drawTHnSparse.C:620
 drawTHnSparse.C:621
 drawTHnSparse.C:622
 drawTHnSparse.C:623
 drawTHnSparse.C:624
 drawTHnSparse.C:625