Lezione 2: Grafici e istogrammi con ROOT - INFN...
Transcript of Lezione 2: Grafici e istogrammi con ROOT - INFN...
Antonio Uras
Corso diLaboratorio I Laurea Specialistica
Dott. Corrado Cicalò a.a. 2009/2010
Università di Cagliari & INFN
Introduzione all'analisi dei dati sperimentali con il framework ROOT
Università di Cagliari – Corso di Laurea Specialistica in Fisica
Lezione 2: Grafici e istogrammi con ROOT
Sommario
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT2
Brevissimi richiami sul C++
Cos'è ROOT?
Scrivere una “macro” in ROOT
Creare un istogramma in ROOT
Creare un grafico in ROOT
/35
Due parole prima di iniziare
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT3/35
NON sono un esperto di C++ (nè di alcun altro linguaggio di programmazione...)
NON sono un esperto di ROOT
NON occorre che diventiate esperti di C++
NON occorre che diventiate esperti di ROOT
In queste lezioni non andremo oltre le competenze minime di C++ e di ROOT che occorrono per gestire l'analisi dei dati raccolti nelle semplici esperienze di laboratorio
Alcune regole generali
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT5/35
[Ci concentriamo sulle regole utili ad usare il C++ nell'ambito di ROOT]
Il C++ è case-sensitive (“Pippo” è diverso da “pippo”)
Ogni variabile va dichiarata, e possibilmente inizializzata
Per ogni variabile, avete accesso anche al suo indirizzo di memoria (puntatore), e spesso è comodo lavorare con i puntatori delle variabili piuttosto che con le variabili stesse
Ogni blocco di istruzioni va compreso fra parentesi graffe: { . . . }
Al termine di ogni istruzione va posto il carattere punto e virgola ;
http://www.cplusplus.com/doc/tutorial/
Operatori utili
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT6/35
Operatori matematici: + − * /
Operatori composti: += (a += b ↔ a = a+b)−= (a −= b ↔ a = a−b)*= (a *= b ↔ a = a*b)/= (a /= b ↔ a = a/b) ++ (a++ ↔ a = a+1) −− (a−− ↔ a = a−1)
Operatori relazionali: == (uguale a) != (diverso da) > (maggiore di)< (minore di) >= (maggiore o uguale a) <= (minore o uguale a)
Operatori logici: && (AND)|| (OR)
Tipi di variabile predefiniti
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT7/35
Usiamo il tipo double (o Double_t in ROOT) per variabili numeriche non intere
Usiamo il tipo int (o Int_t in ROOT) per variabili numeriche intere
Usiamo il tipo bool (o Bool_t in ROOT) per variabili di tipo Booleano (vero/falso)
Poche regole, senza alcuna pretesa di completezza:
Double_t a = 1.618 ;
Int_t b = 4 ;
Bool_t c = 0 ;
Potete inizializzare le variabili al momento stesso della dichiarazione. Per esempio:
Array
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT8/35
Per definire una variabile come array di valori, si deve specificare la dimensione fra parentesi quadre:
Double_t a[26] ;
Int_t b[2] ;
Bool_t c[82] ;
Il contenuto dell'array può essere inizializzato tutto insieme al momento della definizione, oppure elemento per elemento:
Double_t a[3] = {2.998e8, 6.626e−34, 6.67e−11} ;
Int_t b[2] ;b[0] = 19 ;b[1] = 23 ;
Consiglio: inizializzate sempre tutti gli array. Per inizializzare a zero basta usare: a[...] = {0}
Stringhe di caratteri
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT9/35
Le stringhe di caratteri possono essere trattate come array di caratteri. Per definirle e inizializzarle si possono usare varie alternative:
Char_t a[4] = “ciao” ;
Char_t a[] = “ciao” ;
Char_t *a = “ciao” ;
Char_t a[4] = {'c', 'i', 'a', 'o'} ;
Char_t a[4] ;sprintf(a, “ciao”) ;
Cicli
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT10/35
Ciclo for: esegue un blocco di istruzioni un numero definito di volte (in questo caso 100)
for (Int_t i = 0; i < 100; i++) {. . . ;. . . ;
}
Ciclo while: esegue un blocco di istruzioni fino a quando una condizione è vera
while (i < 100) {. . . ;. . . ;
}
Strutture di controllo
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT11/35
La più importante è la condizione di controllo “if...else” : esegue un certo blocco di istruzioni se è verificata la condizione tra parentesi
if (a > b) {. . . ;. . . ;
}else if (a < b) {
. . . ;
. . . ;}else {
. . . ;
. . . ;}
Eseguito quando a == b
Output su schermo
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT12/35
Per l'output su schermo si può usare la funzione printf(...)
printf (“ciao”) ; Scrive “ciao”
printf (“ciao\n”) ; Scrive “ciao” e va a capo
printf (“%d\n”, a) ; Scrive il valore di a (se a è un intero)
printf (“%g\n”, a) ; Scrive il valore di a (se a è un double)
printf (“%s\n”, a) ; Scrive il valore di a (se a è una stringa di caratteri)
Classi
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT13/35
Nel C++ è possibile definire nuovi tipi di variabili. Un nuovo tipo di variabile è chiamato CLASSE, e va definito secondo regole precise
Se si vuole usare un oggetto (variabile) appartenente ad una classe non predefinita, la definizione va inclusa all'inizio del programma
NON ci interessa sapere come creare nuove classi, perché sfrutteremo sempre classi aggiuntive già pronte da usare
Le uniche cose che dobbiamo sapere sugli oggetti di una classe sono:
come vanno creati
quali operazioni possiamo fare con/su di essi
Classi
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT14/35
Per esempio, se si è creata la classe “Istogramma”, un oggetto di questa classe va dichiarato come:
Istogramma hist ;
Oppure come puntatore:
Istogramma *hist ; D'ora in poi useremo questa opzione
Le operazioni che è possibile fare con/sugli oggetti della classe sono specificate nella sua definizione. Ciascuna operazione è associata a un “metodo” della classe, che:
ha un nome ben preciso
accetta una lista di argomenti (anche vuota)
esegue una serie di istruzioni
restituisce un output (opzionale)
Classi
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT15/35
Istogramma *hist ;
. . . . . .
hist -> Riempi(0.9) ;
Qui andranno inserite le istruzioni per definire il range dell'istogramma e la suddivisione in bin (tramite altri metodi)
La classe “Istogramma” potrebbe ad esempio possedere un metodo chiamato “Riempi(Double_t A)”, che:
accetta come argomenti un numero decimale A
identifica il bin dell'istogramma nel quale è compreso il valore A
aumenta di un'unità il contenuto del bin
non restituisce alcun output
Classi
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT16/35
Istogramma *hist ;
. . . . . .
hist -> Riempi(0.9) ;
La combinazione tratto-maggiore (freccia) esegue il metodo specificato alla sua destra sull'oggetto presente alla sua sinistra
La classe “Istogramma” potrebbe ad esempio possedere un metodo chiamato “Riempi(Double_t A)”, che:
accetta come argomenti un numero decimale A
identifica il bin dell'istogramma nel quale è compreso il valore A
aumenta di un'unità il contenuto del bin
non restituisce alcun output
ROOT
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT18/35
ROOT è un framework per l'analisi dati basato sul linguaggio C++
Per quanto ci riguarda, esso si compone di:
un interprete (anche interattivo) di comandi C++
una collezione di classi utili per l'analisi dati (e non solo!)
Trovate tutte le informazioni e la risposta a tutti i possibili dubbi su:
http://root.cern.ch
ROOT è fra i pacchetti predefiniti in alcune recenti distribuzioni di Linux!!!
ROOT
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT19/35
Per avviare ROOT digitate “root” nel terminale:
ROOT
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT20/35
L'interprete dei comandi C++ è già pronto. Possiamo provare a digitare qualche comando C++
ROOT – Le macro
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT21/35
L'interprete dei comandi C++ può essere più utilmente usato per processare interi blocchi di istruzioni, anziché una singola istruzione alla volta
I blocchi di istruzioni vengono scritti in un programma chiamato MACRO, memorizzato su un file esterno
Il nostro obbiettivo è imparare a scrivere delle MACRO che possano essere eseguite da ROOT per eseguire l'analisi dei nostri dati
Le macro che useremo hanno una struttura fissata:
le istruzioni sono raggruppate in “metodi”
ogni metodo possiede un nome, una lista di argomenti, una serie di istruzioni e restituisce (opzionalmente) un output
ROOT – Una macro semplice semplice
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT22/35
void PrimaProva(Int_t a) {
for (Int_t i=0; i<10; i++) {
Int_t b = a*i;
printf("%d\n", b);
}
}
Qualche commento:
la macro è costituita da un solo metodo, che accetta un intero come variabile input
il metodo è di tipo “void”, cioè non restituirà alcun argomento
Per caricare la macro in root: .L <nome-del-file>
Una volta caricata, digitare il nome del metodo specificando il valore dell'argomento fra parentesi, e premere INVIO
ROOT – Una macro un po' meno semplice
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT23/35
void PrimaProva(Double_t a) { for (Int_t i=0; i<10; i++) { Double_t b = Funzione(a*i); printf("%g\n", b); }}
Double_t Funzione(Double_t argument) { return 3.0*argument + 4.2;}
Qualche commento:
la macro è costituita da due metodi
una volta caricata la macro, possiamo eseguire entrambi i metodi, independentemente
il primo metodo fa uso del secondo: il calcolo di b risulta in questo modo “decentrato”
ROOT – Struttura generale di una macro
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT24/35
Non ci sono particolari prescrizioni sulla scrittura di una macro di ROOT – a parte il rispetto della sintassi del C++
Tipicamente, tuttavia, nelle macro si distingue fra:
metodo “principale”: un metodo “void”, cioè che esegue operazioni senza restituire alcun risultato (spesso il suo nome è quello stesso del file della macro). È il metodo che viene eseguito dopo aver caricato la macro
metodi “ausiliari”: metodi dedicati all'esecuzione di particolari operazioni richieste all'interno del motodo principale
La presenza dei metodi ausiliari permette di avere dei “moduli” di codice dedicati ad operazioni specifiche – riutilizzabili da macro a macro!!!
ROOT – Le classi
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT25/35
ROOT mette a disposizione una grande quantità di classi, per la definizione degli oggetti da usare nella nostra analisi
Tutto quello che dovete sapere per creare un oggetto appartenente ad una classe è:
come si chiama la classe
come si usa il metodo di creazione dell'oggetto
come si usano i metodi per operare sull'oggetto
Nelle prossime slide impareremo a usare due classi di ROOT: la classe per gli istogrammi e la classe per i grafici
Creare un istogramma
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT27/35
Per la gestione degli istogrammi useremo la classe TH1D. Per creare un istogramma occorre specificare:
nome dell'oggetto
titolo dell'istogramma
numero di bin
valore minimo della variabile
valore massimo della variabile
Come modello, potete assumere l'istruzione:
TH1D *hist = new TH1D("Histogram", "My Title", 10, -3.0 , 7.0) ;
che crea un [puntatore ad un] oggetto di classe TH1D avente “Histogram” come nome, “My Title” come titolo (in un immane sforzo di fantasia!) e diviso in 10 bin fra -3.0 e 7.0
Riempire e disegnare un istogramma
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT28/35
Una volta creato l'istogramma, lo vogliamo riempire con i valori dalle misurazioni. Per esempio, se abbiamo ottenuto il valore -1.5, questo ricade nell'intervallo del quinto bin: dunque vogliamo che il contenuto del quinto bin venga aumentato di una unità
La classe TH1D fa tutto in automatico. Il metodo corrispondente si chiama Fill, e chiede come argomento il valore da inserire, in formato Double_t:
hist -> Fill(1.5) ;
Possiamo ovviamente riempire l'istogramma quante volte vogliamo, inserendo tutti i valori ottenuti nelle misurazioni. Quando avete terminato la fase di riempimento, potete disegnare l'istogramma con il metodo Draw:
hist -> Draw() ;
Istogrammi – Riassunto
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT29/35
void MacroIstogramma() {
TH1D *hist = new TH1D("Histogram", "My Title", 10, -3.0 , 7.0) ;
hist -> Fill(1.5) ;
hist -> Fill(1.1) ;
hist -> Fill(-2) ;
hist -> Fill(4.8) ;
hist -> Fill(6.2) ;
hist -> Fill(0.3) ;
hist -> Fill(1.2) ;
hist -> Fill(-2.3) ;
hist -> Draw() ;}
Creare un grafico (metodo 1)
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT31/35
Per la gestione dei grafici useremo la classe TGraphErrors. Per creare un grafico occorre specificare:
numero di punti del grafico
array contenente le coordinate x di ciascun punto
array contenente le coordinate y di ciascun punto
array contenente gli errori sulla x di ciascun punto
array contenente gli errori sulla y di ciascun punto
NOTA BENE
per gli istogrammi, prima si crea l'oggetto (vuoto) e poi lo si riempie con i dati
per i grafici, con il “metodo 1” i dati devono essere a disposizione in array numerici PRIMA della creazione del grafico
!
Creare un grafico (metodo 1)
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT32/35
Ecco un esempio completo per la creazione di un grafico con cinque punti:
void MacroGrafico() {
const Int_t nPoints = 5 ;
Double_t x[nPoints] = {0.1, 0.6, 1.8, 2.4, 3.1} ;
Double_t y[nPoints] = {0.09, 0.47, 0.93, 1.12, 1.21} ;
Double_t errX[nPoints] = {0.05, 0.07, 0.10, 0.12, 0.13} ;
Double_t errY[nPoints] = {0.05, 0.05, 0.08, 0.09, 0.10} ;
TGraphErrors *graph = new TGraphErrors(nPoints, x, y, errX, errY) ;
graph -> SetName("Graph") ;
graph -> SetTitle("My Title") ;
graph -> Draw("ap") ;
}
Creare un grafico (metodo 1)
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT33/35
Ecco un esempio completo per la creazione di un grafico con cinque punti:
void MacroGrafico() {
const Int_t nPoints = 5 ;
Double_t x[nPoints] = {0.1, 0.6, 1.8, 2.4, 3.1} ;
Double_t y[nPoints] = {0.09, 0.47, 0.93, 1.12, 1.21} ;
Double_t errX[nPoints] = {0.05, 0.07, 0.10, 0.12, 0.13} ;
Double_t errY[nPoints] = {0.05, 0.05, 0.08, 0.09, 0.10} ;
TGraphErrors *graph = new TGraphErrors(nPoints, x, y, errX, errY) ;
graph -> SetName("Graph") ;
graph -> SetTitle("My Title") ;
graph -> Draw("ap") ;
}
Creare un grafico (metodo 2)
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT34/35
Un metodo alternativo per creare un grafico consiste nel:
creare un grafico “vuoto”
aggiungere i punti uno ad uno
[Potete ovviamente anche aggiungere un punto ad un grafico creato con il “metodo 1”] Ecco come si imposta il primo punto del grafico visto nella slide predente:
TGraphErrors *graph = new TGraphErrors() ;
graph -> SetPoint(0, 0.1, 0.09) ;
graph -> SetPointError(0, 0.05, 0.05) ;
Il primo argomento dei due metodi identifica il punto che state creando. Iniziate sempre dal punto numero 0. Lo stesso metodo permette di modificare le coordinate o gli errori di un punto già impostato
Creare un grafico – Istruzioni complementari
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT35/35
Qualche commento sul codice per la creazione del grafico (per entrambi i “metodi”)
Le istruzioni:
graph -> SetName("Graph") ;
graph -> SetTitle("My Title") ;
permettono di specificare rispettivamente il nome e il titolo del grafico (nel caso dell'istogramma sono specificati alla creazione dell'oggetto)
L'istruzione:
graph -> Draw("ap") ;
specifica che nel disegno dovranno comparire gli assi del grafico (lettera “a”) e i punti (lettera “p”). Non so perché, ma l'opzione predefinita (Draw senza argomenti) NON prevede il disegno degli assi e dei punti!!!
Variabili e puntatori
Antonio Uras Lezione 2: Grafici e istogrammi con ROOT37/35
Nel C++ si può accedere all'indirizzo di memoria di una variabile tramite il suo puntatore. Il puntatore è identificato da una stringa di caratteri, per esempio 0x80cb700
Se A è una variabile, il suo puntatore si ottiene chiedendo &A
Se A è il puntatore di una variabile, la variabile si ottiene chiedendo *A
A = 1.618 &A = 0x80cb700SE ALLORA
SE ALLORAB = &A *B = 1.618
Se definiamo: Double_t *A = 1.618 allora A è un puntatore, perché la variabile è *A