User Guide
  Installed version 6.30 with homebrew (11-12-2023)
  $ brew install root
  
  

-------------Browser

TBrowser tb;

-------------Tipi di dati

int -> Int_t
float -> Float_t
double -> Double_t

rendono il codice platform independent

-------------Classi di Root (iniziano pet T)

TH1F istogramma 1d con dati floating
TH1D istogramma 1d con dati double precision
TFile file contenente dati persistenti (istogrammi, Nple, oggetti)
TDirectory directory contenente files
TTree Nple
TF1 funzione 1d
TString oggetto stringa

------------CINT (interprete C++)

.q quit
.! esegue comando shell (esempio: .! ls)
.? help

--------Nple e istogrammi da files

TFile signal("data/signal.root");

signal.ls();
[TTree selectedtree]
[TH1D namehisto]
[TDirectory namesubdirectory]

signal->cd("subdirectory");
[entra in una sottodirectory]

selectedtree.Print();
[lista variabili della Nple]

selectedtree.Scan();
[stampa i valori delle variabili della Nple]

selectedtree->Draw("mes");
[plot della var "mes"]

selectedtree->Draw("mes","abs(de)<0.2","same");
[plot con taglio sulla var "de" e superimpose]

pi0mass->Draw();
[plot dell'istogramma "pi0mass"]

ntuple->Draw("JetsCa_4Mom[0]->Eta()","JetsCa_4Mom[0]->Et()>10.");
[plot con taglio su un elemento di array]

----------Istogrammi 1d

dichiarazione:
TH1F nome("nome","titolo",Nbin,Xmin,Xmax);
TH1F *nome = new TH1F("nome","titolo",Nbin,Xmin,Xmax);

disegno:
nome->Draw();

riempi:
nome->Fill(1.);
nome->Fill(3,10.7);

scala logaritmica asse x:
gPad->SetLogx(1);

scala lineare asse x:
gPad->SetLinx(0);

titolo asse x:
nome.SetXTitle("asse x");

cambia range dell'asse x:
nome.SetAxisRange(Xmin,Xmax,"X");

colore linea:
nome.SetLineColor(kRed);

colore riempimento:
nome.SetFillColor(kGreen);

codici colori:
kWhite=0 kBlack=1 kRed=2 kGreen=3 kBlue=4 kYellow=5 kMagenta=6 kCyan=7

stile linea:
nome.SetLineStyle(1);

codici stile linea:
kSolid=1 kDashed=2 kDotted=3 kDashDotted=4

stile riempimento:
nome.SetFillStyle(3004);

colore simbolo:
nome.SetMarkerColor(kBlue);

dimensione simbolo:
nome.SetMarkerSize(1.);

stile simbolo:
nome.SetMarkerStyle(20);

codici simbolo:
kDot=1 kPlus=2 kStar=3 kCircle=4 kMultiply=5 kFullCircle=20 kFullTriangleUp=22 kOpenDiamond=27

disegna una linea attraverso i bin dell'istogramma
nome->Draw("l");

istogramma con marker (usando il MarkerStyle corrente)
nome->Draw("p");

istogramma con barre d'errore:
nome->Draw("e");

superimpose:
nome->Draw("same");

disegna solo gli assi:
nome->Draw("axis");

lego plot:
nome->Draw("lego");

lego plot a colori:
nome->Draw("lego2");

stampa contenuto dell'istogramma:
nome->Print("all");

rimuovi box di statistica:
gStyle->SetOptStat(0);

aggiungi box di statistica:
gStyle->SetOptStat(1111);

crea una box di testo:
TPaveText *mytext = new TPaveText(0.2,0.7,0.4,0.85,"NDC");
mytext->SetTextSize(0.04);
mytext->SetFillColor(0);
mytext->SetTextAlign(12);
mytext->AddText("Ciao");
mytext->AddText("x_{1}^{2}");
mytext->AddText("#mu");
mytext->Draw();

crea una legenda:
leg = new TLegend(0.2,0.7,0.4,0.85);
leg->AddEntry(histo1,"testo","lp");
leg->AddEntry(histo2,"testo","lp");
leg->Draw();

fit di un istogramma con funzioni predefinite:
h1->Fit("gaus");
h1->Fit("gaus","","",0,50);
h1->Fit("landau");
h1->Fit("expo");
h1->Fit("polN");

fit di un istogramma con funzione utente:
TF1 *f1 = new TF1("f1","[0]*x+[1]",0,10);
h1->Fit("f1");

inizializza i parametri di una funzione:
f1->SetParameters(1,1);

aggiungi box di fit:
gStyle->SetOptFit(1111);

apri pannello fit:
h1->FitPanel();

operazione tra istogrammi:
TH1F h3 = (*h1)/(*h2);

copia in una variabile il contenuto di un bin:
Int_t i=10;
var = h1->GetBinContent(i);

somma il contenuto dei primi 10 bin:
Float_t sum = 0;
for (Int_t i=1; i<=10; i++) {
  sum += h1->GetBinContent(i);
}

rinormalizza un istogramma:
Float_t scale = 1/h1->Integral();
h1->Scale(scale);

sovrapponi istogramma con diversa scala e asse sul lato destro:
h1->Draw();
Float_t rightmax = 1.1*h2->GetMaximum();
Float_t scale = gPad->GetUymax()/rightmax;
h2->Scale(scale);
h2->Draw("same");
TGaxis *axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),gPad->GetUxmax(),gPad->GetUymax(),0,rightmax,510,"+L");
axis->Draw();

----------Istogrammi 2d

dichiarazione:
TH2F nome("nome","titolo",Xbin,Xmin,Xmax,Ybin,Ymin,Ymax);

disegna (di default viene disegnato uno scatter plot, per ogni cella viene
disegnato un numero di punti proporzionale al contenuto della cella):
nome->Draw();
nome->Draw("lego"); [lego, surf, cont, box, text, scat]

disegna una box per ogni cella con una scala di colori:
nome->Draw("colz");


-------------Istogrammi Profile

dichiarazione:
TProfile nome("nome","titolo",Xbin,Xmin,Xmax,Ymin,Ymax);

disegna (mostra il valor medio di Y e il suo RMS per ciascun bin di X):
nome->Draw();

disegna senza mostrare le barre d'errore:
nome->Draw("hist");

----------------Graph

Int_t n = 5;
Float_t x[n], y[n];
for(Int_t i=0; i<5; i++) 
{x[i]=i;
 cout << x[i] << endl;
}
y[0]=0.0;
y[1]=1.0;
y[2]=3.0;
y[3]=6.0;
y[4]=10.0;

grafico senza barre d'errore:		 
TGraph *geff = new TGraph(n,x,y);
geff->Draw("AL*");     // disegna una spezzata e una * ad ogni punto
geff->Draw("AP");     // disegna gli assi e il marker corrente

grafico con errori simmetrici	 
TGraphErrors *gerr = new TGraphErrors(n,x,y,xerr,yerr);

----------------Macro un-named

includere i comandi in un file tra parentesi {}
ecco un esempio di file macro.cc:

{
TFile signal("data/signal.root");
signal.ls();
selectedtree.SetLineColor(kRed);
selectedtree->Draw("mes");
}

esecuzione macro:
.x macro.cc

----------------Macro named

includere i comandi in una funzione che abbia
lo stesso nome del file:

#include < iostream >
void macro(int j = 1) {
cout << "Hello" << endl;
int i = j;
cout << "i = " << i << endl;
}

esecuzione macro:
.x macro.cc(10)

o in alternativa
(in tal caso la funzione puo' avere anche nome diverso dal file):

.L macro.cc
macro(10)

per compilare lo script:

.L macro.cc+
macro(10)

per forzare la compilazione:

.L macro.cc++
macro(10)

----------------Scrivi su file root nuovo

Si puo' dare il comando TFile all'inizio, oppure, come nell'esempio che segue, 
alla fine dopo aver creato gli istogrammi o Nple da salvare nel file:

TH1F *istog = new TH1F("istog","titolo",10,-10.,10.);
istog->Fill(2,10.7);
istog->Fill(4,6.7);
TFile *file = new TFile("nuovofile.root","RECREATE","comment");
file->cd();
istog->Write();
file->Close();
		  
--------------------Input output con file (istruzioni C++)

ofstream myfile;           // crea un file come stream e inserisce una linea
myfile.open ("filename.txt");
myfile << "Writing this to a file.\n";
myfile.close ();	  

ifstream myfile;           // apre il file come stream e legge ciascuna linea
myfile.open("filename.txt");
   Double_t x[100] = {0.};
   Int_t j;
   j=0;
   while ( true ) {
     myfile >> x[j];
     if( myfile.eof() ) break;
     ++j;
   };   
myfile.close();
   
-------------------Nple ovvero Trees

I trees possono avere branches (sottodirectory) e 
leaves (sono le variabili che contengono dati, ordinate in colonne)

lista delle variabili:
selectedtree->Print();

stampa il contenuto delle variabili:
selectedtree->Scan();

plot di una variabile:
selectedtree->Draw("de");

scatter plot:
selectedtree->Draw("px:py");

scatter plot con taglio:
selectedtree->Draw("px:py","abs(de)<0.01");

definizione variabile di taglio:
TCut cut1 = "abs(de)<0.01";
selectedtree->Draw("px:py",cut1);

opzioni di Draw nel terzo campo:
selectedtree->Draw("px:py","","same");
selectedtree->Draw("px:py","","l");

proiezione di Nple su istogramma 1d:
selectedtree->Draw("de>>istogramma");
istogramma.Draw();

aggiungi all'istogramma gia' esistente:
selectedtree->Draw("de>>+istogramma");

-------------------Reading from ASCII file

es. filename.txt
#cost  time   type
1.46   127    2
1.56   126    11
0.82   71     3

TNtuple calls("calls","calls","cost:time:type");
calls.ReadFile("filename.txt");

-------------------Reading from Root file

TFile f("rootfile.root");
TNtuple * calls = f.Get("calls");

-------------------Istogramma da un folder aliroot/subfolder

TFile *f1 = new TFile("filename");
TFolder *f2 = (TFolder *)f1->Get("aliroot");
TH1D *h1 = (TH1D*)f2->FindObject("subfolder/histo");
h1->Draw();

TFile *f1 = new TFile("filename");
TFolder *f2 = f1->FindObjectAny("aliroot");
TFolder *f3 = f2->FindObjectAny("subfolder");
TH1D *h1 = (TH1D*)f3->FindObject("histo");
h1->Draw();

-------------------Merge di Nple contenute in file diversi

TChain catena("Nple");
catena.Add("outputfile1.root");
catena.Add("outputfile2.root");
catena.Merge("newfile.root");

in alternativa, comando da shell:
hadd newfile.root outputfile1.root outputfile2.root
hadd newfile.root outputfile*

-----------------Reading data from a Tree

si faccia uso della seguente macro:

{
TFile signal("data/signal.root");
TTree * albero = (TTree*)signal.Get("selectedtree");
Float_t de;
albero->SetBranchAddress("de", &de);
for(int iEvt = 0; iEvt < albero->GetEntries(); iEvt++)
{
  albero->GetEntry(iEvt);
  cout << "candidate iEvt = " << iEvt << "\t de = " << de << endl;
}
}

-------------------Building a tree from scratch

{
Float_t x,y;
TTree slope("slope","pendenza");
TBranch * b_x = slope.Branch("x", &x, "variabile x");
TBranch * b_y = slope.Branch("y", &y, "variabile y");
for(Int_t i = 0; i < 100; i++)
{
  x = i/2.;
  y = x*x;
  slope.Fill();
}
}

--------Grafica

crea e attiva una finestra grafica:
TCanvas *c1=new TCanvas("c1","titolo",800,600);
c1->cd();

clear della finestra:
c1->Clean();

dividi la finestra in diverse TPad:
c1->Divide(2,2);

cambia la TPad attiva:
c1->cd(1);
 
salva in un file:
c1.Write();

salva in diversi formati:
c1->SaveAs("file.ps");
c1->SaveAs("file.eps");
c1->SaveAs("file.gif");
c1->Print("file.eps");
c1->Print("file.pdf");
				 
disegna linea dal punto x1,y1 al punto x2,y2:
l = new TLine(x1, y1, x2, y2);
l->Draw();

colore linea:
l->SetLineColor(2);

disegna cerchio centrato in x,y di raggio r:
c = new TEllipse(x, y, r, r);
c->Draw();

disegna arco di ellisse centrata in x,y assi a1,a2
compresa tra gli angoli phimin,phimax:
e = new TEllipse(x, y, a1, a2, phimin, phimax);
e->Draw();

colore riempimento:
e->SetFillColor(2);

---------------------Funzioni

crea una funzione:
TF1 *f1 = new TF1("f1", "x*sin(x)", 0, 10);

plot della funzione:
f1->Draw();

cancella la funzione:
f1->Delete();

uso del valore della funzione in un punto:
Double_t a, b;
b = f1->Eval(a);
	      
crea una named macro:
crea un file hello.cc contenente le istruzioni es.
  void hello(int t)
  {
    for (int i=1; i<=t; i++) cout << "Hello World" << endl;
  }

quindi carica le funzioni col comando:
.L hello.cc
a questo punto si possono chiamare le funzioni:
hello(5);

crea una funzione con parametri:
Double_t straight_line(Double_t *x, Double_t *par)
{
  Double_t m,q; // Linear slope
  q = par[0];
  m = par[1];
  return q + m*x[0];
}
TF1 *f_line = new TF1("f_line",straight_line,0,10,2);
						      
---------------------Generazione di numeri casuali

#include 
						      
generazione distribuzione uniforme [0,1]:
TRandom3 randGen;
Double_t x = randGen.Rndm();
						      
generazione distribuzione uniforme [3,10]:
TRandom3 randGen(0);						      
Double_t uni = randGen.Uniform(3,10);					
						      
generazione distribuzione gauss (media = 0, sigma = 1):
TRandom3 r3(0);
Double_t y = r3.Gaus(0,1);

generazione distribuzione esponenziale (tau = 5):
TRandom3 rexp(0);
Double_t evar = rexp.Exp(5);
						      
---------------------MakeSelector (built in functions to analyze data from a file TFile signal("Stub_123xxx.root"); signal->cd("PATtemplate"); - apre il file da leggere e accede la directory StubFour->MakeSelector("bis.C"); - vengono generati i file .h e .C contenenti il loop sugli eventi nel Tree "StubFour" gROOT->LoadMacro("bis.C+"); - compila la macro bis *selector = new bis(); - StubFour->Process(selector); - esegui il codice con il loop sugli eventi