This page will have some useful information and advice for dealing with ROOT, focusing on the issues that I come across most often. Expect content to be added gradually and cumulatively.
The syntax highlighting for the code is being developed. Please ignore any mistakes in it for now.
Here are some links to pages written by people who know more than me:
The one thing that I always forget how to do is change the background color of a histogram without screwing everything up. There are a few other nice things too. Here's the code:
1 c1->SetBorderMode(0) ; // Remove the yellow border 2 c1->SetFillColor(kWhite) ; // Change a single canvas color 3 gStyle->SetCanvasColor(kWhite); // Change all future canvas colors
Taken from Nick West's "Plotting with Style"
ROOT has some special data types, which should be used for cross-platform support. Here are some of the more common ones, as they should be added to Crimson Editor's scheme:
[KEYWORDS1:GLOBAL]
# Add root types (2008-02-05)
TH1F TH2F TH3F TH1D TH2D TH3D TF1 Long64_t Int_t Float_t Double_t TFile TTree TString TChain THStack Bool_t
Some of the useful members of TH1F:
I include these here simply because I tend to forget which way around the x and y parameters are declared for the TH2F class.
1 TH1F * name = new TH1F(TString histogram_name, TString histogram_title, Int_t number_of_x_bins, Double_t x_axis_lower_limit, Double_t x_axis_upper_limit) ; 2 3 TH2F * name = new TH2F(TString histogram_name, TString histogram_title, Int_t number_of_x_bins, Double_t x_axis_lower_limit, Double_t x_axis_upper_limit, Int_t number_of_y_bins, Double_t y_axis_lower_limit, Double_t y_axis_upper_limit) ;
Scaling a THStack is quite common and, annoyingly, impossible to do in a single command. Here's the code I use when I need to scale a stack. Note that the histograms are copied so that when they are scaled the original histograms remain intact.
1 // Gather all the histograms into an array: 2 const Int_t number_of_stack_histograms = 5 ; 3 TH1F* stack_histograms[number_of_stack_histograms] ; 4 stack_histogram[0] = some_histogram ; //... Add the histograms 5 6 // Declare the 7 THStack* stack = new THStack("stack", "A stack") ; 8 // Add the histograms 9 for(Int_t i=0 ; i<number_of_stack_histograms ; i++) 10 { 11 stack->Add(stack_histogram[i]) ; 12 } 13 Float_t highest_stack_bin = stack->GetMaximum() ; 14 Float_t scale = desired_height/highest_stack_bin ; 15 16 // Delete and redeclare stack 17 delete stack ; 18 THStack* stack = new THStack("stack", "A stack") ; 19 20 // Scale and add histograms 21 for(Int_t i=0 ; i<number_of_stack_histograms ; i++) 22 { 23 stack_histogram[i]->Scale(scale) ; 24 stack->Add(stack_histogram[i]) ; 25 } 26 27 // And you're done! Not very elegant, but it works. 28 stack->Draw() ;
There is an alternative, but I think it's even less elegant:
1 Float_t highest_bin = 0 ; 2 for(Int_t i=1 ; i<number_of_bins+1 ; i++) 3 { 4 Float_t bin_height = 0 ; 5 for(Int_t j=0 ; j<number_of_histograms ; j++) 6 { 7 bin_height += stack_histogram[j]->GetBin(i) ; 8 } 9 if(bin_height>highest_bin) highest_bin = bin_height ; 10 } 11 Float_t scale = desired_height/highest_bin ; 12 13 // Declare the stack 14 THStack* stack = new THStack("stack", "A stack") ; 15 16 // Scale and add histograms 17 for(Int_t i=0 ; i<number_of_stack_histograms ; i++) 18 { 19 stack_histogram[i]->Scale(scale) ; 20 stack->Add(stack_histogram[i]) ; 21 } 22 23 // And you're done! 24 stack->Draw() ;
In my code I tend to need to convert numbers (Int_ts and Float_ts) to TStrings for use (for example) with histograms functions or loading files. Converting from one to another is fairly simple to do, but it's easy to get it wrong. (I tend to forget to convert from string to TString.)
1 Float_t pi_as_a_float = 3.14159 ; 2 // Declare the stringstream 3 stringstream ss (stringstream::in | stringstream::out) ; 4 5 // Feed the number into the stringstream 6 ss << pi_as_a_float ; 7 8 // If we just want the number as a just cast it: 9 TString pi_as_a_string = ss.str() ; 10 cout << pi_as_a_string << endl ; 11 12 // If we want to add to another string it must be cast as a first: 13 // This works: 14 TString pi_equals = "Pi is equal to " ; 15 pi_equals = pi_equals + pi_as_a_string ; 16 pi_equals = pi_equals + "..." ; 17 18 cout << pi_equals << endl ; 19 20 // This doesn't work: 21 TString pi_equals = "Pi is equal to " + ss.str() + "..." ; 22 23 cout << pi_equals << endl ;
In the latter example ROOT gives an ambiguous overload error because ss.str() returns a string and ROOT does not know how to add a string to a TString.
It seems that every other plot I make is an efficiency plot. Efficiency plots are time-consuming and easy to get wrong. Here's a simple script that will give an efficiency plot for a simple TH1F:
1 // Always declare number_of_bins at the start! It saves a lot of time later 2 Int_t number_of_bins = 100 ; 3 Float_t lower = -3 ; 4 Float_t upper = 3 ; 5 TH1F* random_histogram = new TH1F("random_histogram", "Random", number_of_bins, lower, upper) ; 6 random_histogram->FillRandom("gaus", 100000) ; 7 8 // Declare a histogram 9 TH1F* efficiency_histogram = new TH1F("efficiency_histogram", "#epsilon", number_of_bins, lower, upper) ; 10 for(Int_t i=0 ; i<number_of_bins ; i++) 11 { 12 Float_t number_of_entries = random_histogram->GetEntries() ; 13 Float_t effiency_cut = random_histogram->Integral(i, number_of_bins) ; 14 efficiency_histogram->SetBinContent(i, effiency_cut/number_of_entries) ; 15 } 16 efficiency_histogram->Draw() ; 17 random_histogram->Scale(efficiency_histogram->GetMaximum() / random_histogram->GetMaximum()) ; 18 random_histogram->Draw("sames") ;
I do correlation plots a lot. Here's the code for calculating correlations in a single pass:
1 for(Int_t i=0 ; i<number_of_entries ; i++) 2 { 3 // c is a chain with event selection already applied 4 // c has had its branch addresses set to variable_values 5 c->GetEntry(i) ; 6 for(Int_t j=0 ; j<number_of_variables ; j++) 7 { 8 s[j] += variable_values[j]*evWeight ; 9 for(Int_t k=0 ; k<number_of_variables ; k++) 10 { 11 ss[j][k] += variable_values[j]*variable_values[k]*evWeight ; 12 } 13 } 14 // n must be calculated thus: 15 n += evWeight ; 16 } 17 18 Float_t means[number_of_variables] ; 19 Float_t correlations[number_of_variables][number_of_variables] ; 20 21 for(Int_t i=0 ; i<number_of_variables ; i++) 22 { 23 means[i] = s[i]/n ; 24 for(Int_t j=0 ; j<number_of_variables ; j++) 25 { 26 correlations[i][j] = ((n*ss[i][j])-(s[i]*s[j])) / (sqrt((n*ss[i][i])-(s[i]*s[i]))*sqrt((n*ss[j][j])-(s[j]*s[j]))) ; 27 } 28 }