ROOT tutorialSession I: ROOT introduction.Slides can be retrieved here: introduction to root slides The code needed can be downloaded from a Repository using
| ||||||||
Deleted: | ||||||||
< < |
| |||||||
ROOT basics.Start an interactive sessionYou need to type 'root' command after having properly set the variables ROOTSYS : should point to your root installation LD_LIBRARY_PATH : should point to $ROOTSYS/lib + any other lib that you'll need (more on that below) PATH : should point to $ROOTSYS/bin [use 'set path=($path $ROOTSYS/bin)' command on tcsh]Useful files (you should know that they exist and where they are!)
Root.Style: Plain
TBrowser b; //To start the browser (GUI) .L [nomemacro] //To load file/macro .x [nomemacro] //To execute a macro interactively .! [command] //To execute a system command (like 'ls') .q //To exitFrom the browser you can open any root file and display it by clicking on it. Opening / browsing a file via command lineAs a first exercise you should:
TFile *f = new TFile ("[nomefile.root]"); f->ls(); //List the content of a file from the current directory gDirectory->ls(); //List the content of current directory f->cd("[dirname]"); //Go to a given directory TH1D * myhisto = ((TH1D)gDirectory->Get("[path_to_dir/histoname]")); myhisto->Draw(); //Open a canvas (c1) and draw the histogram on it TTree * myNtp = ((TTree*)gDirectory->Get("[path_to_dir/ntpname]")); myNtp->Draw("[varname]"); //Open a canvas and plot on it the varname distributionThe second exercise is to get access to the histograms created when Drawing a variable of an ntuple. You should:
TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // Get pointer to default 1D histo TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // Get pointer to default 2D graph myNtp->Draw("[varname]>>histo"); //Draws varname into the "histo" histogram TH1F *histo = (TH1F*)gDirectory->Get("histo"); //retrievs the histo myNtp->Draw("[varname]>>histo(500,10,20)"); //Draw varname into histo with specified binning/range.For a comprehensive review of the many capabilities of Draw method you can click here Handling basics of graphicsTo exercise the basics of graphics you can start with:
gROOT->SetStyle("Plain"); TCanvas *c = new TCanvas("c","c",600,800); c->Clear(); c->cd(); histo->Draw(); c->Print("tmp.eps"); c->Print("tmp.png"); TCanvas *c1 = new TCanvas("c1","c1",600,1200); c1->Clear(); c1->Divide(1,2); c1->cd(1); histo->SetMarkerColor(4); histo->Draw("p"); c1->cd(2); histo->SetLineColor(2); histo->SetFillColor(3); histo->Draw("h"); c1->Print("tmp1.eps"); Ntuple analysis From command lineTo exercise the ntuple analysis via command line you should:
myNtp->Print(); myNtp->Draw("[varname]"); myNtp->Draw("[var1]:[var2]"); //Plots var1 as a function of var2 myNtp->Draw("[varname]","[cuts]"); myNtp->Draw("[varname]","[cuts]","[graph options]"); myNtp->Scan(); //Scans all variables myNtp->Scan("[varname]"); //Scan the specified variableFor more informations on how to use cuts see TCut class. For more informations on graphics options see the TTree::Draw page. Using macrosYou have two possible ways to use macros inside root:
#include <iostream.h> void test() { cout<<"Hello World!!!"<<endl; //Histo inizialization TH1D * h_fa = new TH1D("h_fa","Factor histogram",100,0,1); //File reading double fact,top,err; int flag; char buffertC[200]; ifstream tsC("FinalCorrDatRightErrRms.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); cout<<"My factor: "<<fact<<endl; //Histo filling h_fa->Fill(fact); } TCanvas *c = new TCanvas("c","mycanvas",600,600); c->cd() h_fa->Draw(); c->Print("test.eps"); return; } Ntuple/file creationTo exercise the creation and filling of an ntuple you should:
void MacroRead() { //Create a new file TFile *fNewOutFile = new TFile("root_file.root", "RECREATE"); //Existing file will be overwritten. fNewOutFile->cd(); //To go into the main directory of the file int f_myInt; double f_myDou; vector<string> *f_strVct; vector<double> *f_douVct; TTree *dataTree = new TTree("data","data"); //Creates ntuple dataTree->Branch("myInt", &f_myInt , "myInt/I"); //Int dataTree->Branch("myDou", &f_myDou , "myDou/D"); //Double dataTree->Branch("myStrVct", "vector<string>" , &f_strVct,32000,0); dataTree->Branch("myDouVct" ,"vector<double>" , &f_douVct,32000,0); //Inside the reading loop double fact,top,err; int flag; char buffertC[200]; string str; ifstream tsC("FinalCorrDatRightErr.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); f_myInt = f_myDou = 0; f_strVct->clear(); f_douVct->clear(); f_myInt = fact+1; f_myDou = err; str = "Time over Press: "; f_douVct->push_back(flag); f_strVct->push_back(str); dataTree->Fill(); } fNewOutFile->Write(); //To write objects into the file fNewOutFile->Close(); //To close a file return; } Using a macro to Loop over the eventsCreating the macroTo create a macro to loop over the events in a given ntuple you should use the MakeClass method.myNtp->MakeClass("[className]");This creates [className].C and [className].h in your working directory. You can then edit [className].C to include your analysis code that needs to run on each event. Modifications should go into the Loop() method (contained in the [className].C) that looks like: Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; } Modifying the Loop() method.In order to add your particular analysis to the macro you should modify the Loop method adding three different phases:
initialization(); //Perform objects initialization Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; analysis(); //Perform analysis of each event, fill s output objects } finalization(); //Finalize the jobs (write/delete objects/file)To exercise the Loop method and the analysis using macros you should:
Remeber that:
void ClassName::initialization() { fOutFile = new TFile("root_file.root", "RECREATE"); fOutFile->cd(); //Histogram definition. my1DHisto = new TH1D("name","title",xbins,xmin,xmax); my2DHisto = new TH2D("name","title",xbins,xmin,xmax,ybins,ymin,ymax); return; }Analysis: void ClassName::analysis() { cout<<"My favourite variable value"<<myVar<<endl; my1DHisto->Fill(myvar); my2DHisto->Fill(myvar1,myvar2); return; }Finalization: void ClassName::finalization() { //Objects deletion fOutFile->Write(); //To write objects into the file fOutFile->Close(); //To close a file return; } Load and run the macroInstructions are given in the macro [className].C file itself.// In a ROOT session, you can do: // Root > .L [className].C // Load of [className] macro // Root > [className] t // Class obejct creation // Root > t.GetEntry(12); // Fill t data members with entry number 12 // Root > t.Show(); // Show values of entry 12 // Root > t.Show(16); // Read and show values of entry 16 // Root > t.Loop(); // Loop on all entriesKeep in mind that if you're using the macro to dump an ntuple into a file the ntuple will not be dumped into the file until you EXIT from root (or force the writing and closing of the file!) Creating standalone executablesIf you arrived here in less than 1 hour you can be proud of yourself.The most important part starts here. To create an executable you should:
Create a main() executableFirst of all you should create the main that you're going to compile. The main should look like:#include <iostream> #include <fstream> int main (int argc, char *argv[]) { cout<<"My First Executable!"<<endl; return 0; }Remeber to properly include the includes for the classes you're going to use! Create a makefileMakefiles are typically needed in case of complex executables. If you have just one main and you don't need to include special classes or libraries you can just compile your main using gcc syntax. But in more complex cases the Makefile really helps to take care of the executable creation.Example of such makefile is given below: you should change the Simple tag replacing the rag name and code name with the values you've used for your executable. ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB += -lMinuit GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) Exec_tag: Simple.cc # ----------------------------------------------------------------------------- $(CXX) $(CXXFLAGS) -c $< $(LD) $(LDFLAGS) -o Simple Simple.o $(GLIBB) # ============================================================================== clean: rm -f *.o SimpleThe example above can be used to compile executables that need ROOT libraries but that are not depending on external classes. If you wanto to use external classes you might want to use a more complicated template. Changes [minor] are needed for Mac osx compilers to work.... Attention: after the tag the command should start with a 'tab' separator. If you copy paste the makefile from this page you loose the tab and the making won't work. Replace the spaces with a 'tab' when indicated! ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB + -lMinuit NGLIBB + /home/asarti/macro/source/libMyClass.so GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS + $(ROOTCFLAGS) LIBS = $(ROOTLIBS) NTUPLEB = MyClass.o MyClassDict.o .SUFFIXES: .cc,.C .cc.o: tab$(CXX) $(CXXFLAGS) -c $< # ================================================================================ lib: $(NTUPLEB) #----------------------------------------------------------- $(CXX) $(SOFLAGS) $(NTUPLEB) -o libMyClass.so MyClassDict.cc: MyClass.hh $(ROOTSYS)/bin/rootcint -f MyClassDict.cc -c -I../ MyClass.hh # ================================================================================ Exec_tag: Exec.o lib # ----------------------------------------------------------------------------- $(LD) $(LDFLAGS) -o Exec Exec.o $(GLIBB) clean: rm -f *.so rm -f *.o rm -f *Dict.* rm -f Exec Compile/run/debug the executableInstructions to compile, run, debug the executable are given below:gmake -f Makefile Exec_tag ./Exec -options : to run your exec. gdb ./Exec and then run -options commands: to debug you executable Final ExerciseCreate an executable that runs on the Ntuple provided (ACQ_all_2100_8020_Cst1_plaNew.root) that:
|
ROOT tutorialSession I: ROOT introduction. | ||||||||
Changed: | ||||||||
< < | Slides can be retrieved here: SessionI.pdf | |||||||
> > | Slides can be retrieved here: introduction to root slides | |||||||
The code needed can be downloaded from a Repository using | ||||||||
Changed: | ||||||||
< < |
| |||||||
> > |
| |||||||
Added: | ||||||||
> > |
| |||||||
ROOT basics.Start an interactive sessionYou need to type 'root' command after having properly set the variables ROOTSYS : should point to your root installation LD_LIBRARY_PATH : should point to $ROOTSYS/lib + any other lib that you'll need (more on that below) PATH : should point to $ROOTSYS/bin [use 'set path=($path $ROOTSYS/bin)' command on tcsh]Useful files (you should know that they exist and where they are!)
Root.Style: Plain
TBrowser b; //To start the browser (GUI) .L [nomemacro] //To load file/macro .x [nomemacro] //To execute a macro interactively .! [command] //To execute a system command (like 'ls') .q //To exitFrom the browser you can open any root file and display it by clicking on it. Opening / browsing a file via command lineAs a first exercise you should:
TFile *f = new TFile ("[nomefile.root]"); f->ls(); //List the content of a file from the current directory gDirectory->ls(); //List the content of current directory f->cd("[dirname]"); //Go to a given directory TH1D * myhisto = ((TH1D)gDirectory->Get("[path_to_dir/histoname]")); myhisto->Draw(); //Open a canvas (c1) and draw the histogram on it TTree * myNtp = ((TTree*)gDirectory->Get("[path_to_dir/ntpname]")); myNtp->Draw("[varname]"); //Open a canvas and plot on it the varname distributionThe second exercise is to get access to the histograms created when Drawing a variable of an ntuple. You should:
TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // Get pointer to default 1D histo TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // Get pointer to default 2D graph myNtp->Draw("[varname]>>histo"); //Draws varname into the "histo" histogram TH1F *histo = (TH1F*)gDirectory->Get("histo"); //retrievs the histo myNtp->Draw("[varname]>>histo(500,10,20)"); //Draw varname into histo with specified binning/range.For a comprehensive review of the many capabilities of Draw method you can click here Handling basics of graphicsTo exercise the basics of graphics you can start with:
gROOT->SetStyle("Plain"); TCanvas *c = new TCanvas("c","c",600,800); c->Clear(); c->cd(); histo->Draw(); c->Print("tmp.eps"); c->Print("tmp.png"); TCanvas *c1 = new TCanvas("c1","c1",600,1200); c1->Clear(); c1->Divide(1,2); c1->cd(1); histo->SetMarkerColor(4); histo->Draw("p"); c1->cd(2); histo->SetLineColor(2); histo->SetFillColor(3); histo->Draw("h"); c1->Print("tmp1.eps"); Ntuple analysis From command lineTo exercise the ntuple analysis via command line you should:
myNtp->Print(); myNtp->Draw("[varname]"); myNtp->Draw("[var1]:[var2]"); //Plots var1 as a function of var2 myNtp->Draw("[varname]","[cuts]"); myNtp->Draw("[varname]","[cuts]","[graph options]"); myNtp->Scan(); //Scans all variables myNtp->Scan("[varname]"); //Scan the specified variableFor more informations on how to use cuts see TCut class. For more informations on graphics options see the TTree::Draw page. Using macrosYou have two possible ways to use macros inside root:
#include <iostream.h> void test() { cout<<"Hello World!!!"<<endl; //Histo inizialization TH1D * h_fa = new TH1D("h_fa","Factor histogram",100,0,1); //File reading double fact,top,err; int flag; char buffertC[200]; ifstream tsC("FinalCorrDatRightErrRms.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); cout<<"My factor: "<<fact<<endl; //Histo filling h_fa->Fill(fact); } TCanvas *c = new TCanvas("c","mycanvas",600,600); c->cd() h_fa->Draw(); c->Print("test.eps"); return; } Ntuple/file creationTo exercise the creation and filling of an ntuple you should:
void MacroRead() { //Create a new file TFile *fNewOutFile = new TFile("root_file.root", "RECREATE"); //Existing file will be overwritten. fNewOutFile->cd(); //To go into the main directory of the file int f_myInt; double f_myDou; vector<string> *f_strVct; vector<double> *f_douVct; TTree *dataTree = new TTree("data","data"); //Creates ntuple dataTree->Branch("myInt", &f_myInt , "myInt/I"); //Int dataTree->Branch("myDou", &f_myDou , "myDou/D"); //Double dataTree->Branch("myStrVct", "vector<string>" , &f_strVct,32000,0); dataTree->Branch("myDouVct" ,"vector<double>" , &f_douVct,32000,0); //Inside the reading loop double fact,top,err; int flag; char buffertC[200]; string str; ifstream tsC("FinalCorrDatRightErr.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); f_myInt = f_myDou = 0; f_strVct->clear(); f_douVct->clear(); f_myInt = fact+1; f_myDou = err; str = "Time over Press: "; f_douVct->push_back(flag); f_strVct->push_back(str); dataTree->Fill(); } fNewOutFile->Write(); //To write objects into the file fNewOutFile->Close(); //To close a file return; } Using a macro to Loop over the eventsCreating the macroTo create a macro to loop over the events in a given ntuple you should use the MakeClass method.myNtp->MakeClass("[className]");This creates [className].C and [className].h in your working directory. You can then edit [className].C to include your analysis code that needs to run on each event. Modifications should go into the Loop() method (contained in the [className].C) that looks like: Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; } | ||||||||
Added: | ||||||||
> > | ||||||||
Modifying the Loop() method.In order to add your particular analysis to the macro you should modify the Loop method adding three different phases:
initialization(); //Perform objects initialization Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; analysis(); //Perform analysis of each event, fill s output objects } finalization(); //Finalize the jobs (write/delete objects/file)To exercise the Loop method and the analysis using macros you should:
Remeber that:
void ClassName::initialization() { fOutFile = new TFile("root_file.root", "RECREATE"); fOutFile->cd(); //Histogram definition. my1DHisto = new TH1D("name","title",xbins,xmin,xmax); my2DHisto = new TH2D("name","title",xbins,xmin,xmax,ybins,ymin,ymax); return; }Analysis: void ClassName::analysis() { cout<<"My favourite variable value"<<myVar<<endl; my1DHisto->Fill(myvar); my2DHisto->Fill(myvar1,myvar2); return; }Finalization: void ClassName::finalization() { //Objects deletion fOutFile->Write(); //To write objects into the file fOutFile->Close(); //To close a file return; } | ||||||||
Added: | ||||||||
> > | ||||||||
Load and run the macroInstructions are given in the macro [className].C file itself.// In a ROOT session, you can do: // Root > .L [className].C // Load of [className] macro // Root > [className] t // Class obejct creation // Root > t.GetEntry(12); // Fill t data members with entry number 12 // Root > t.Show(); // Show values of entry 12 // Root > t.Show(16); // Read and show values of entry 16 // Root > t.Loop(); // Loop on all entriesKeep in mind that if you're using the macro to dump an ntuple into a file the ntuple will not be dumped into the file until you EXIT from root (or force the writing and closing of the file!) Creating standalone executablesIf you arrived here in less than 1 hour you can be proud of yourself.The most important part starts here. To create an executable you should:
Create a main() executableFirst of all you should create the main that you're going to compile. The main should look like:#include <iostream> #include <fstream> int main (int argc, char *argv[]) { cout<<"My First Executable!"<<endl; return 0; }Remeber to properly include the includes for the classes you're going to use! Create a makefileMakefiles are typically needed in case of complex executables. If you have just one main and you don't need to include special classes or libraries you can just compile your main using gcc syntax. But in more complex cases the Makefile really helps to take care of the executable creation.Example of such makefile is given below: you should change the Simple tag replacing the rag name and code name with the values you've used for your executable. ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB += -lMinuit GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) Exec_tag: Simple.cc # ----------------------------------------------------------------------------- $(CXX) $(CXXFLAGS) -c $< $(LD) $(LDFLAGS) -o Simple Simple.o $(GLIBB) # ============================================================================== clean: rm -f *.o SimpleThe example above can be used to compile executables that need ROOT libraries but that are not depending on external classes. If you wanto to use external classes you might want to use a more complicated template. Changes [minor] are needed for Mac osx compilers to work.... Attention: after the tag the command should start with a 'tab' separator. If you copy paste the makefile from this page you loose the tab and the making won't work. Replace the spaces with a 'tab' when indicated! ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB + -lMinuit NGLIBB + /home/asarti/macro/source/libMyClass.so GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS + $(ROOTCFLAGS) LIBS = $(ROOTLIBS) NTUPLEB = MyClass.o MyClassDict.o .SUFFIXES: .cc,.C .cc.o: tab$(CXX) $(CXXFLAGS) -c $< # ================================================================================ lib: $(NTUPLEB) #----------------------------------------------------------- $(CXX) $(SOFLAGS) $(NTUPLEB) -o libMyClass.so MyClassDict.cc: MyClass.hh $(ROOTSYS)/bin/rootcint -f MyClassDict.cc -c -I../ MyClass.hh # ================================================================================ Exec_tag: Exec.o lib # ----------------------------------------------------------------------------- $(LD) $(LDFLAGS) -o Exec Exec.o $(GLIBB) clean: rm -f *.so rm -f *.o rm -f *Dict.* rm -f Exec | ||||||||
Added: | ||||||||
> > | ||||||||
Compile/run/debug the executableInstructions to compile, run, debug the executable are given below:gmake -f Makefile Exec_tag ./Exec -options : to run your exec. gdb ./Exec and then run -options commands: to debug you executable | ||||||||
Added: | ||||||||
> > | ||||||||
Final ExerciseCreate an executable that runs on the Ntuple provided (ACQ_all_2100_8020_Cst1_plaNew.root) that:
|
ROOT tutorialSession I: ROOT introduction.Slides can be retrieved here: SessionI.pdf | ||||||||
Added: | ||||||||
> > |
The code needed can be downloaded from a Repository using
| |||||||
ROOT basics.Start an interactive sessionYou need to type 'root' command after having properly set the variables ROOTSYS : should point to your root installation LD_LIBRARY_PATH : should point to $ROOTSYS/lib + any other lib that you'll need (more on that below) PATH : should point to $ROOTSYS/bin [use 'set path=($path $ROOTSYS/bin)' command on tcsh]Useful files (you should know that they exist and where they are!)
Root.Style: Plain
TBrowser b; //To start the browser (GUI) .L [nomemacro] //To load file/macro .x [nomemacro] //To execute a macro interactively .! [command] //To execute a system command (like 'ls') .q //To exitFrom the browser you can open any root file and display it by clicking on it. Opening / browsing a file via command line | ||||||||
Changed: | ||||||||
< < | As a first exercise you should: * Open (in READ mode) the root file linked here * List the content of the file and find the histogram 0h_zde * Draw the histogram * Open (in READ mode) the root file linked here * Draw a variable from ntuple 42 inside the directory "MuDigitMoni" Example is given below: | |||||||
> > | As a first exercise you should: | |||||||
Added: | ||||||||
> > |
| |||||||
TFile *f = new TFile ("[nomefile.root]"); f->ls(); //List the content of a file from the current directory gDirectory->ls(); //List the content of current directory f->cd("[dirname]"); //Go to a given directory TH1D * myhisto = ((TH1D)gDirectory->Get("[path_to_dir/histoname]")); myhisto->Draw(); //Open a canvas (c1) and draw the histogram on it TTree * myNtp = ((TTree*)gDirectory->Get("[path_to_dir/ntpname]")); myNtp->Draw("[varname]"); //Open a canvas and plot on it the varname distributionThe second exercise is to get access to the histograms created when Drawing a variable of an ntuple. You should: | ||||||||
Changed: | ||||||||
< < |
| |||||||
> > |
| |||||||
TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // Get pointer to default 1D histo TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // Get pointer to default 2D graph myNtp->Draw("[varname]>>histo"); //Draws varname into the "histo" histogram TH1F *histo = (TH1F*)gDirectory->Get("histo"); //retrievs the histo myNtp->Draw("[varname]>>histo(500,10,20)"); //Draw varname into histo with specified binning/range. | ||||||||
Changed: | ||||||||
< < | For a comprehensive review of the many capabilities of Draw method you can click here | |||||||
> > | For a comprehensive review of the many capabilities of Draw method you can click here | |||||||
Handling basics of graphicsTo exercise the basics of graphics you can start with:
| ||||||||
Changed: | ||||||||
< < |
| |||||||
> > |
| |||||||
Examples are given below:
gROOT->SetStyle("Plain"); TCanvas *c = new TCanvas("c","c",600,800); c->Clear(); c->cd(); histo->Draw(); c->Print("tmp.eps"); c->Print("tmp.png"); TCanvas *c1 = new TCanvas("c1","c1",600,1200); c1->Clear(); c1->Divide(1,2); c1->cd(1); histo->SetMarkerColor(4); histo->Draw("p"); c1->cd(2); histo->SetLineColor(2); histo->SetFillColor(3); histo->Draw("h"); c1->Print("tmp1.eps"); Ntuple analysis From command lineTo exercise the ntuple analysis via command line you should:
myNtp->Print(); myNtp->Draw("[varname]"); myNtp->Draw("[var1]:[var2]"); //Plots var1 as a function of var2 myNtp->Draw("[varname]","[cuts]"); myNtp->Draw("[varname]","[cuts]","[graph options]"); myNtp->Scan(); //Scans all variables myNtp->Scan("[varname]"); //Scan the specified variable | ||||||||
Changed: | ||||||||
< < | For more informations on how to use cuts see TCut class. For more informations on graphics options see the TTree::Draw page. | |||||||
> > | For more informations on how to use cuts see TCut class. For more informations on graphics options see the TTree::Draw page. | |||||||
Using macrosYou have two possible ways to use macros inside root:
| ||||||||
Changed: | ||||||||
< < | ||||||||
> > |
| |||||||
Example is given below:
#include <iostream.h> void test() { cout<<"Hello World!!!"<<endl; //Histo inizialization TH1D * h_fa = new TH1D("h_fa","Factor histogram",100,0,1); //File reading double fact,top,err; int flag; char buffertC[200]; ifstream tsC("FinalCorrDatRightErrRms.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); cout<<"My factor: "<<fact<<endl; //Histo filling h_fa->Fill(fact); } TCanvas *c = new TCanvas("c","mycanvas",600,600); c->cd() h_fa->Draw(); c->Print("test.eps"); return; } Ntuple/file creationTo exercise the creation and filling of an ntuple you should:
| ||||||||
Changed: | ||||||||
< < |
| |||||||
> > |
| |||||||
void MacroRead() { //Create a new file TFile *fNewOutFile = new TFile("root_file.root", "RECREATE"); //Existing file will be overwritten. fNewOutFile->cd(); //To go into the main directory of the file int f_myInt; double f_myDou; vector<string> *f_strVct; vector<double> *f_douVct; TTree *dataTree = new TTree("data","data"); //Creates ntuple dataTree->Branch("myInt", &f_myInt , "myInt/I"); //Int dataTree->Branch("myDou", &f_myDou , "myDou/D"); //Double dataTree->Branch("myStrVct", "vector<string>" , &f_strVct,32000,0); dataTree->Branch("myDouVct" ,"vector<double>" , &f_douVct,32000,0); //Inside the reading loop double fact,top,err; int flag; char buffertC[200]; string str; ifstream tsC("FinalCorrDatRightErr.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); f_myInt = f_myDou = 0; f_strVct->clear(); f_douVct->clear(); f_myInt = fact+1; f_myDou = err; str = "Time over Press: "; f_douVct->push_back(flag); f_strVct->push_back(str); dataTree->Fill(); } fNewOutFile->Write(); //To write objects into the file fNewOutFile->Close(); //To close a file return; } Using a macro to Loop over the eventsCreating the macroTo create a macro to loop over the events in a given ntuple you should use the MakeClass method.myNtp->MakeClass("[className]");This creates [className].C and [className].h in your working directory. You can then edit [className].C to include your analysis code that needs to run on each event. Modifications should go into the Loop() method (contained in the [className].C) that looks like: Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; } Modifying the Loop() method.In order to add your particular analysis to the macro you should modify the Loop method adding three different phases:
initialization(); //Perform objects initialization Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; analysis(); //Perform analysis of each event, fill s output objects } finalization(); //Finalize the jobs (write/delete objects/file)To exercise the Loop method and the analysis using macros you should:
Remeber that:
void ClassName::initialization() { fOutFile = new TFile("root_file.root", "RECREATE"); fOutFile->cd(); //Histogram definition. my1DHisto = new TH1D("name","title",xbins,xmin,xmax); my2DHisto = new TH2D("name","title",xbins,xmin,xmax,ybins,ymin,ymax); return; }Analysis: void ClassName::analysis() { cout<<"My favourite variable value"<<myVar<<endl; my1DHisto->Fill(myvar); my2DHisto->Fill(myvar1,myvar2); return; }Finalization: void ClassName::finalization() { //Objects deletion fOutFile->Write(); //To write objects into the file fOutFile->Close(); //To close a file return; } | ||||||||
Deleted: | ||||||||
< < | ||||||||
Load and run the macroInstructions are given in the macro [className].C file itself.// In a ROOT session, you can do: // Root > .L [className].C // Load of [className] macro // Root > [className] t // Class obejct creation // Root > t.GetEntry(12); // Fill t data members with entry number 12 // Root > t.Show(); // Show values of entry 12 // Root > t.Show(16); // Read and show values of entry 16 // Root > t.Loop(); // Loop on all entriesKeep in mind that if you're using the macro to dump an ntuple into a file the ntuple will not be dumped into the file until you EXIT from root (or force the writing and closing of the file!) Creating standalone executablesIf you arrived here in less than 1 hour you can be proud of yourself.The most important part starts here. To create an executable you should:
Create a main() executableFirst of all you should create the main that you're going to compile. The main should look like:#include <iostream> #include <fstream> int main (int argc, char *argv[]) { cout<<"My First Executable!"<<endl; return 0; }Remeber to properly include the includes for the classes you're going to use! | ||||||||
Deleted: | ||||||||
< < | ||||||||
Create a makefileMakefiles are typically needed in case of complex executables. If you have just one main and you don't need to include special classes or libraries you can just compile your main using gcc syntax. But in more complex cases the Makefile really helps to take care of the executable creation.Example of such makefile is given below: you should change the Simple tag replacing the rag name and code name with the values you've used for your executable. ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC | ||||||||
Deleted: | ||||||||
< < | CXXFLAGS = -g -Wall -fPIC | |||||||
LD = g++
LDFLAGS = -g
SOFLAGS = -shared
NGLIBB = $(ROOTGLIBS)
NGLIBB += -lMinuit
GLIBB = $(filter-out -lNew, $(NGLIBB))
CXXFLAGS += $(ROOTCFLAGS)
LIBS = $(ROOTLIBS)
Exec_tag: Simple.cc
# -----------------------------------------------------------------------------
$(CXX) $(CXXFLAGS) -c $<
$(LD) $(LDFLAGS) -o Simple Simple.o $(GLIBB)
# ==========================================================================
clean:
rm -f *.o Simple | ||||||||
Changed: | ||||||||
< < | The example above can be used to compile executables that need ROOT libraries but that are not depending on external classes. If you wanto to use external classes you might want to use a more complicated template. | |||||||
> > | The example above can be used to compile executables that need ROOT libraries but that are not depending on external classes. If you wanto to use external classes you might want to use a more complicated template. Changes [minor] are needed for Mac osx compilers to work.... | |||||||
Attention: after the tag the command should start with a 'tab' separator. If you copy paste the makefile from this page you loose the tab and the making won't work. Replace the spaces with a 'tab' when indicated!
ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC | ||||||||
Deleted: | ||||||||
< < | CXXFLAGS = -g -Wall -fPIC | |||||||
LD = g++
LDFLAGS = -g
SOFLAGS = -shared
NGLIBB = $(ROOTGLIBS)
NGLIBB + -lMinuit
NGLIBB + /home/asarti/macro/source/libMyClass.so
GLIBB = $(filter-out -lNew, $(NGLIBB))
CXXFLAGS + $(ROOTCFLAGS)
LIBS = $(ROOTLIBS)
NTUPLEB = MyClass.o MyClassDict.o
.SUFFIXES: .cc,.C
.cc.o:
tab$(CXX) $(CXXFLAGS) -c $<
# ============================================================================
lib: $(NTUPLEB)
#-----------------------------------------------------------
$(CXX) $(SOFLAGS) $(NTUPLEB) -o libMyClass.so
MyClassDict.cc: MyClass.hh
$(ROOTSYS)/bin/rootcint -f MyClassDict.cc -c -I../ MyClass.hh
# ============================================================================
Exec_tag: Exec.o lib
# -----------------------------------------------------------------------------
$(LD) $(LDFLAGS) -o Exec Exec.o $(GLIBB)
clean:
rm -f *.so
rm -f *.o
rm -f Dict.
rm -f Exec
Compile/run/debug the executableInstructions to compile, run, debug the executable are given below:gmake -f Makefile Exec_tag ./Exec -options : to run your exec. gdb ./Exec and then run -options commands: to debug you executable Final Exercise | ||||||||
Changed: | ||||||||
< < | Create an executable that runs on the Ntuple provided here that: | |||||||
> > | Create an executable that runs on the Ntuple provided (ACQ_all_2100_8020_Cst1_plaNew.root) that: | |||||||
| ||||||||
Changed: | ||||||||
< < |
| |||||||
> > |
| |||||||
To do so: | ||||||||
Changed: | ||||||||
< < |
| |||||||
> > |
| |||||||
|
ROOT tutorialSession I: ROOT introduction.Slides can be retrieved here: SessionI.pdfROOT basics.Start an interactive sessionYou need to type 'root' command after having properly set the variables ROOTSYS : should point to your root installation LD_LIBRARY_PATH : should point to $ROOTSYS/lib + any other lib that you'll need (more on that below) PATH : should point to $ROOTSYS/bin [use 'set path=($path $ROOTSYS/bin)' command on tcsh]Useful files (you should know that they exist and where they are!)
Root.Style: Plain
TBrowser b; //To start the browser (GUI) .L [nomemacro] //To load file/macro .x [nomemacro] //To execute a macro interactively .! [command] //To execute a system command (like 'ls') .q //To exit | ||||||||
Changed: | ||||||||
< < | From the browser you can open any root file and display it by clicking on it. | |||||||
> > | From the browser you can open any root file and display it by clicking on it. | |||||||
Deleted: | ||||||||
< < | ||||||||
Opening / browsing a file via command lineAs a first exercise you should: * Open (in READ mode) the root file linked here * List the content of the file and find the histogram 0h_zde * Draw the histogram * Open (in READ mode) the root file linked here * Draw a variable from ntuple 42 inside the directory "MuDigitMoni" Example is given below: TFile *f = new TFile ("[nomefile.root]"); f->ls(); //List the content of a file from the current directory gDirectory->ls(); //List the content of current directory f->cd("[dirname]"); //Go to a given directory TH1D * myhisto = ((TH1D)gDirectory->Get("[path_to_dir/histoname]")); myhisto->Draw(); //Open a canvas (c1) and draw the histogram on it TTree * myNtp = ((TTree*)gDirectory->Get("[path_to_dir/ntpname]")); myNtp->Draw("[varname]"); //Open a canvas and plot on it the varname distribution | ||||||||
Changed: | ||||||||
< < | The second exercise is to get access to the histograms created when Drawing a variable of an ntuple. You should: | |||||||
> > | The second exercise is to get access to the histograms created when Drawing a variable of an ntuple. You should: | |||||||
| ||||||||
Changed: | ||||||||
< < | Examples are given below: <blockquote style="background-color:#f0f0f0"> <pre> TH1F htemp = (TH1F)gPad->GetPrimitive("htemp"); // Get pointer to default 1D histo TGraph graph = (TGraph)gPad->GetPrimitive("Graph"); // Get pointer to default 2D graph myNtp->Draw("[varname]>>histo"); //Draws varname into the "histo" histogram TH1F histo = (TH1F)gDirectory->Get("histo"); //retrievs the histo myNtp->Draw("[varname]>>histo(500,10,20)"); //Draw varname into histo with specified binning/range. </pre> </blockquote> For a comprehensive review of the many capabilities of Draw method you can click here ---++++ Handling basics of graphics To exercise the basics of graphics you can start with: * Setting the session style to "Plain" * Creating a TCanvas * Drawing an histogram on the given canvas and save the canvas as eps or png plot * Divide the canvas in 2 and draw 2 different ntuple variables into the canvas * Get access to axis/histo information, legend, stats, line color, marker. Documentation on methods you'd like to exercise is linked here for histograms, markers, lines and fill Examples are given below: <blockquote style="background-color:#f0f0f0"> <pre> gROOT->SetStyle("Plain"); TCanvas c = new TCanvas("c","c",600,800); c->Clear(); c->cd(); histo->Draw(); c->Print("tmp.eps"); c->Print("tmp.png"); TCanvas *c1 = new TCanvas("c1","c1",600,1200); c1->Clear(); c1->Divide(1,2); c1->cd(1); histo->SetMarkerColor(4); histo->Draw("p"); c1->cd(2); histo->SetLineColor(2); histo->SetFillColor(3); histo->Draw("h"); c1->Print("tmp1.eps"); </pre> </blockquote> ---++++ Ntuple analysis From command line To exercise the ntuple analysis via command line you should: * Get access to the ntuple pointer (e.g. using gDirectory): * Print the ntuple information * Scan the desired variable * Plot the variable as a function of a second variable * Plot the variable applying some cuts * Plot the variable specifying graphic options (like 'same' one to superimpose 2 plots) Examples are given below: <blockquote style="background-color:#f0f0f0"> <pre> myNtp->Print(); myNtp->Draw("[varname]"); myNtp->Draw("[var1]:[var2]"); //Plots var1 as a function of var2 myNtp->Draw("[varname]","[cuts]"); myNtp->Draw("[varname]","[cuts]","[graph options]"); myNtp->Scan(); //Scans all variables myNtp->Scan("[varname]"); //Scan the specified variable </pre> </blockquote> For more informations on how to use cuts see TCut class. For more informations on graphics options see the TTree::Draw page. ---++++ Using macros You have two possible ways to use macros inside root: * Interactively using the .x command to load the macro * running the macro in batch using the -b (-q) options. * -q option exits root after having executed the macro * -b run in batch mode (no graphics) As exercise: * Write a Macro that display an Hello World message: run it with the -b option * Write a Macro that read an external ASCII file and displays the content: run it with -b -q option * Write a Macro that read an external ASCII file, fill an histogram and draws it. Load it and run it interactively using .x command. Example is given below: <blockquote style="background-color:#f0f0f0"> <pre> #include <iostream.h> void test() { cout<<"Hello World!!!"<<endl; //Histo inizialization TH1D * h_fa = new TH1D("h_fa","Factor histogram",100,0,1); //File reading double fact,top,err; int flag; char buffertC[200]; ifstream tsC("FinalCorrDatRightErrRms.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); cout<<"My factor: "<<fact<<endl; //Histo filling h_fa->Fill(fact); } TCanvas *c = new TCanvas("c","mycanvas",600,600); c->cd() h_fa->Draw(); c->Print("test.eps"); return; } </pre> </blockquote> ---++++ Ntuple/file creation To exercise the creation and filling of an ntuple you should: * Add the creation of the ntuple at the top of your macro * Properly initialize the variables * Read the external ASCII file. * Set up some int, double, string variables to be written. * Add the filling of the variables and writing of ntuple * Add the writing of the ntuple into a file. * Exit and browse the created file. Examples are given below. <blockquote style="background-color:#f0f0f0"> <pre> void MacroRead() { //Create a new file TFile *fNewOutFile = new TFile("root_file.root", "RECREATE"); //Existing file will be overwritten. fNewOutFile->cd(); //To go into the main directory of the file int f_myInt; double f_myDou; vector<string> *f_strVct; vector<double> *f_douVct; TTree *dataTree = new TTree("data","data"); //Creates ntuple dataTree->Branch("myInt", &f_myInt , "myInt/I"); //Int dataTree->Branch("myDou", &f_myDou , "myDou/D"); //Double dataTree->Branch("myStrVct", "vector<string>" , &f_strVct,32000,0); dataTree->Branch("myDouVct" ,"vector<double>" , &f_douVct,32000,0); //Inside the reading loop double fact,top,err; int flag; char buffertC[200]; string str; ifstream tsC("FinalCorrDatRightErr.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); f_myInt = f_myDou = 0; f_strVct->clear(); f_douVct->clear(); f_myInt = fact+1; f_myDou = err; str = "Time over Press: "; f_douVct->push_back(flag); f_strVct->push_back(str); dataTree->Fill(); } fNewOutFile->Write(); //To write objects into the file fNewOutFile->Close(); //To close a file return; } </pre> </blockquote> ---+++ Using a macro to Loop over the events ---++++ Creating the macro To create a macro to loop over the events in a given ntuple you should use the MakeClass method. <blockquote style="background-color:#f0f0f0"> <pre> myNtp->MakeClass("[className]"); </pre> </blockquote> This creates [className].C and [className].h in your working directory. You can then edit [className].C to include your analysis code that needs to run on each event. Modifications should go into the Loop() method (contained in the [className].C) that looks like: <blockquote style="background-color:#f0f0f0"> <pre> Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; } </pre> </blockquote> ---++++ Modifying the Loop() method. In order to add your particular analysis to the macro you should modify the Loop method adding three different phases: * Initialization. Should run only once and take care of object creation and initialization. * Analysis. Should run on each event and fill the histograms, ntuples, or analyze the events in other ways.... * Finalization. Should run only once at the end of the job and take care of clean up and file/plots writing.. Example is given below. <blockquote style="background-color:#f0f0f0"> <pre> initialization(); //Perform objects initialization Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; analysis(); //Perform analysis of each event, fill s output objects } finalization(); //Finalize the jobs (write/delete objects/file) </pre> </blockquote> To exercise the Loop method and the analysis using macros you should: * Customize the initialization() method in order to include the object definition that you'll need for your analysis. * Customize the analysis() method, that should contain the code that you want to run on each event. * Customize the finalization() method, that should contain the writing of analysis objects and their deletion. Examples on how to write those methods are given below. Remeber that: * Global variables should be declared in the .h file * Ntuple variables ARE already defined in the .h file: you should not REDECLARE them Initialization: <blockquote style="background-color:#f0f0f0"> <pre> void ClassName::initialization() { fOutFile = new TFile("root_file.root", "RECREATE"); fOutFile->cd(); //Histogram definition. my1DHisto = new TH1D("name","title",xbins,xmin,xmax); my2DHisto = new TH2D("name","title",xbins,xmin,xmax,ybins,ymin,ymax); return; } </pre> </blockquote> Analysis: <blockquote style="background-color:#f0f0f0"> <pre> void ClassName::analysis() { cout<<"My favourite variable value"<<myVar<<endl; my1DHisto->Fill(myvar); my2DHisto->Fill(myvar1,myvar2); return; } </pre> </blockquote> Finalization: <blockquote style="background-color:#f0f0f0"> <pre> void ClassName::finalization() { //Objects deletion fOutFile->Write(); //To write objects into the file fOutFile->Close(); //To close a file return; } </pre> </blockquote> ---++++ Load and run the macro Instructions are given in the macro [className].C file itself. <blockquote style="background-color:#f0f0f0"> <pre> // In a ROOT session, you can do: // Root > .L [className].C // Load of [className] macro // Root > [className] t // Class obejct creation // Root > t.GetEntry(12); // Fill t data members with entry number 12 // Root > t.Show(); // Show values of entry 12 // Root > t.Show(16); // Read and show values of entry 16 // Root > t.Loop(); // Loop on all entries </pre> </blockquote> Keep in mind that if you're using the macro to dump an ntuple into a file the ntuple *will not be dumped into the file until you EXIT from root (or force the writing and closing of the file!) ---+++ Creating standalone executables If you arrived here in less than 1 hour you can be proud of yourself. The most important part starts here. To create an executable you should: * Create a main() * Include/use/call in your main your favourite classes. * Create a makefile and know where to pick up libraries * Have gcc installed * Compile the main and run it The following subsection will remind you the basics to set up your executable. The exercise is contained in the very last subsection of this paragraph! ---++++ Create a main() executable First of all you should create the main that you're going to compile. The main should look like: <blockquote style="background-color:#f0f0f0"> <pre> #include <iostream> #include <fstream> int main (int argc, char argv[]) { cout<<"My First Executable!"<<endl; return 0; } </pre> </blockquote> Remeber to properly include the includes for the classes you're going to use! ---++++ Create a makefile Makefiles are typically needed in case of complex executables. If you have just one main and you don't need to include special classes or libraries you can just compile your main using gcc syntax. But in more complex cases the Makefile really helps to take care of the executable creation. Example of such makefile is given below: you should change the Simple tag replacing the rag name and code name with the values you've used for your executable. <blockquote style="background-color:#f0f0f0"> <pre> ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB += -lMinuit GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) Exec_tag: Simple.cc # ----------------------------------------------------------------------------- $(CXX) $(CXXFLAGS) -c $< $(LD) $(LDFLAGS) -o Simple Simple.o $(GLIBB) # ============================================================================== clean: rm -f *.o Simple </pre> </blockquote> The example above can be used to compile executables that need ROOT libraries but that are not depending on external classes. If you wanto to use external classes you might want to use a more complicated template. *Attention: after the tag the command should start with a 'tab' separator. If you copy paste the makefile from this page you loose the tab and the making won't work. Replace the spaces with a 'tab' when indicated!= <blockquote style="background-color:#f0f0f0"> <pre> ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB + -lMinuit NGLIBB + /home/asarti/macro/source/libMyClass.so GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS + $(ROOTCFLAGS) LIBS = $(ROOTLIBS) NTUPLEB = MyClass.o MyClassDict.o .SUFFIXES: .cc,.C .cc.o: tab$(CXX) $(CXXFLAGS) -c $< # ================================================================================ lib: $(NTUPLEB) #--------------------------------------------------------------- tab$$(CXX) $(SOFLAGS) $(NTUPLEB) -o libMyClass.so MyClassDict.cc: MyClass.hh tab$$(ROOTSYS)/bin/rootcint -f MyClassDict.cc -c -I../ MyClass.hh # ================================================================================ Exec_tag: Exec.o lib # ----------------------------------------------------------------------------- tab$$(LD) $(LDFLAGS) -o Exec Exec.o $(GLIBB) clean: tab$rm -f *.so tab$rm -f *.o tab$rm -f *Dict.* tab$rm -f Exec </pre> </blockquote> ---++++ Compile/run/debug the executable Instructions to compile, run, debug the executable are given below: <blockquote style="background-color:#f0f0f0"> <pre> gmake -f Makefile Exec_tag ./Exec -options : to run your exec. gdb ./Exec and then run -options commands: to debug you executable </pre> </blockquote> ---++++ Final Exercise Create an executable that runs on the DecayChainNtuple provided here that: * Takes as input the number of events to process and the root file name * Print out the Energy of lab0 candidate for each event * Fill/save an histogram (in eps and png formats) with the momentum of lab1 and lab2 candidates * Save an ntuple into a ROOT file that contains the: event number, invariant mass of lab1 and lab2 candidates, momentum and mass of lab0 candidate To do so: * First of all create a myTree class using makeclass on the DecayChainNtuple Tree. * Create the main, include the myTree.h file and create the myTree ntp onject. * Use the ntp.Loop() method to loop on candidates * create the proper initialize and finalize methods to create and save histograms and ntuples. * compile it and run it! -- AlessioSarti - 18 Jun 2007 * prova.root: Ntuple for playing | |||||||
> > | Examples are given below: | |||||||
Added: | ||||||||
> > | TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // Get pointer to default 1D histo TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // Get pointer to default 2D graph myNtp->Draw("[varname]>>histo"); //Draws varname into the "histo" histogram TH1F *histo = (TH1F*)gDirectory->Get("histo"); //retrievs the histo myNtp->Draw("[varname]>>histo(500,10,20)"); //Draw varname into histo with specified binning/range. | |||||||
Changed: | ||||||||
< < | -- AlessioSarti - 2011-05-06 | |||||||
> > | For a comprehensive review of the many capabilities of Draw method you can click here | |||||||
Added: | ||||||||
> > | Handling basics of graphics | |||||||
Changed: | ||||||||
< < | * | |||||||
> > | To exercise the basics of graphics you can start with: | |||||||
Added: | ||||||||
> > |
gROOT->SetStyle("Plain"); TCanvas *c = new TCanvas("c","c",600,800); c->Clear(); c->cd(); histo->Draw(); c->Print("tmp.eps"); c->Print("tmp.png"); TCanvas *c1 = new TCanvas("c1","c1",600,1200); c1->Clear(); c1->Divide(1,2); c1->cd(1); histo->SetMarkerColor(4); histo->Draw("p"); c1->cd(2); histo->SetLineColor(2); histo->SetFillColor(3); histo->Draw("h"); c1->Print("tmp1.eps"); Ntuple analysis From command lineTo exercise the ntuple analysis via command line you should:
myNtp->Print(); myNtp->Draw("[varname]"); myNtp->Draw("[var1]:[var2]"); //Plots var1 as a function of var2 myNtp->Draw("[varname]","[cuts]"); myNtp->Draw("[varname]","[cuts]","[graph options]"); myNtp->Scan(); //Scans all variables myNtp->Scan("[varname]"); //Scan the specified variableFor more informations on how to use cuts see TCut class. For more informations on graphics options see the TTree::Draw page. Using macrosYou have two possible ways to use macros inside root:
#include <iostream.h> void test() { cout<<"Hello World!!!"<<endl; //Histo inizialization TH1D * h_fa = new TH1D("h_fa","Factor histogram",100,0,1); //File reading double fact,top,err; int flag; char buffertC[200]; ifstream tsC("FinalCorrDatRightErrRms.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); cout<<"My factor: "<<fact<<endl; //Histo filling h_fa->Fill(fact); } TCanvas *c = new TCanvas("c","mycanvas",600,600); c->cd() h_fa->Draw(); c->Print("test.eps"); return; } Ntuple/file creationTo exercise the creation and filling of an ntuple you should:
void MacroRead() { //Create a new file TFile *fNewOutFile = new TFile("root_file.root", "RECREATE"); //Existing file will be overwritten. fNewOutFile->cd(); //To go into the main directory of the file int f_myInt; double f_myDou; vector<string> *f_strVct; vector<double> *f_douVct; TTree *dataTree = new TTree("data","data"); //Creates ntuple dataTree->Branch("myInt", &f_myInt , "myInt/I"); //Int dataTree->Branch("myDou", &f_myDou , "myDou/D"); //Double dataTree->Branch("myStrVct", "vector<string>" , &f_strVct,32000,0); dataTree->Branch("myDouVct" ,"vector<double>" , &f_douVct,32000,0); //Inside the reading loop double fact,top,err; int flag; char buffertC[200]; string str; ifstream tsC("FinalCorrDatRightErr.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); f_myInt = f_myDou = 0; f_strVct->clear(); f_douVct->clear(); f_myInt = fact+1; f_myDou = err; str = "Time over Press: "; f_douVct->push_back(flag); f_strVct->push_back(str); dataTree->Fill(); } fNewOutFile->Write(); //To write objects into the file fNewOutFile->Close(); //To close a file return; } Using a macro to Loop over the eventsCreating the macroTo create a macro to loop over the events in a given ntuple you should use the MakeClass method.myNtp->MakeClass("[className]");This creates [className].C and [className].h in your working directory. You can then edit [className].C to include your analysis code that needs to run on each event. Modifications should go into the Loop() method (contained in the [className].C) that looks like: Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; } Modifying the Loop() method.In order to add your particular analysis to the macro you should modify the Loop method adding three different phases:
initialization(); //Perform objects initialization Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; analysis(); //Perform analysis of each event, fill s output objects } finalization(); //Finalize the jobs (write/delete objects/file)To exercise the Loop method and the analysis using macros you should:
Remeber that:
void ClassName::initialization() { fOutFile = new TFile("root_file.root", "RECREATE"); fOutFile->cd(); //Histogram definition. my1DHisto = new TH1D("name","title",xbins,xmin,xmax); my2DHisto = new TH2D("name","title",xbins,xmin,xmax,ybins,ymin,ymax); return; }Analysis: void ClassName::analysis() { cout<<"My favourite variable value"<<myVar<<endl; my1DHisto->Fill(myvar); my2DHisto->Fill(myvar1,myvar2); return; }Finalization: void ClassName::finalization() { //Objects deletion fOutFile->Write(); //To write objects into the file fOutFile->Close(); //To close a file return; } Load and run the macroInstructions are given in the macro [className].C file itself.// In a ROOT session, you can do: // Root > .L [className].C // Load of [className] macro // Root > [className] t // Class obejct creation // Root > t.GetEntry(12); // Fill t data members with entry number 12 // Root > t.Show(); // Show values of entry 12 // Root > t.Show(16); // Read and show values of entry 16 // Root > t.Loop(); // Loop on all entriesKeep in mind that if you're using the macro to dump an ntuple into a file the ntuple will not be dumped into the file until you EXIT from root (or force the writing and closing of the file!) Creating standalone executablesIf you arrived here in less than 1 hour you can be proud of yourself.The most important part starts here. To create an executable you should:
Create a main() executableFirst of all you should create the main that you're going to compile. The main should look like:#include <iostream> #include <fstream> int main (int argc, char *argv[]) { cout<<"My First Executable!"<<endl; return 0; }Remeber to properly include the includes for the classes you're going to use! Create a makefileMakefiles are typically needed in case of complex executables. If you have just one main and you don't need to include special classes or libraries you can just compile your main using gcc syntax. But in more complex cases the Makefile really helps to take care of the executable creation.Example of such makefile is given below: you should change the Simple tag replacing the rag name and code name with the values you've used for your executable. ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB += -lMinuit GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) Exec_tag: Simple.cc # ----------------------------------------------------------------------------- $(CXX) $(CXXFLAGS) -c $< $(LD) $(LDFLAGS) -o Simple Simple.o $(GLIBB) # ============================================================================== clean: rm -f *.o SimpleThe example above can be used to compile executables that need ROOT libraries but that are not depending on external classes. If you wanto to use external classes you might want to use a more complicated template. Attention: after the tag the command should start with a 'tab' separator. If you copy paste the makefile from this page you loose the tab and the making won't work. Replace the spaces with a 'tab' when indicated! ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB + -lMinuit NGLIBB + /home/asarti/macro/source/libMyClass.so GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS + $(ROOTCFLAGS) LIBS = $(ROOTLIBS) NTUPLEB = MyClass.o MyClassDict.o .SUFFIXES: .cc,.C .cc.o: tab$(CXX) $(CXXFLAGS) -c $< # ================================================================================ lib: $(NTUPLEB) #----------------------------------------------------------- $(CXX) $(SOFLAGS) $(NTUPLEB) -o libMyClass.so MyClassDict.cc: MyClass.hh $(ROOTSYS)/bin/rootcint -f MyClassDict.cc -c -I../ MyClass.hh # ================================================================================ Exec_tag: Exec.o lib # ----------------------------------------------------------------------------- $(LD) $(LDFLAGS) -o Exec Exec.o $(GLIBB) clean: rm -f *.so rm -f *.o rm -f *Dict.* rm -f Exec Compile/run/debug the executableInstructions to compile, run, debug the executable are given below:gmake -f Makefile Exec_tag ./Exec -options : to run your exec. gdb ./Exec and then run -options commands: to debug you executable Final ExerciseCreate an executable that runs on the Ntuple provided here that:
| |||||||
|
ROOT tutorialSession I: ROOT introduction.Slides can be retrieved here: SessionI.pdfROOT basics.Start an interactive sessionYou need to type 'root' command after having properly set the variables ROOTSYS : should point to your root installation LD_LIBRARY_PATH : should point to $ROOTSYS/lib + any other lib that you'll need (more on that below) PATH : should point to $ROOTSYS/bin [use 'set path=($path $ROOTSYS/bin)' command on tcsh]Useful files (you should know that they exist and where they are!)
Root.Style: Plain
TBrowser b; //To start the browser (GUI) .L [nomemacro] //To load file/macro .x [nomemacro] //To execute a macro interactively .! [command] //To execute a system command (like 'ls') .q //To exit From the browser you can open any root file and display it by clicking on it. Opening / browsing a file via command lineAs a first exercise you should: * Open (in READ mode) the root file linked here * List the content of the file and find the histogram 0h_zde * Draw the histogram * Open (in READ mode) the root file linked here * Draw a variable from ntuple 42 inside the directory "MuDigitMoni" Example is given below: TFile *f = new TFile ("[nomefile.root]"); f->ls(); //List the content of a file from the current directory gDirectory->ls(); //List the content of current directory f->cd("[dirname]"); //Go to a given directory TH1D * myhisto = ((TH1D)gDirectory->Get("[path_to_dir/histoname]")); myhisto->Draw(); //Open a canvas (c1) and draw the histogram on it TTree * myNtp = ((TTree*)gDirectory->Get("[path_to_dir/ntpname]")); myNtp->Draw("[varname]"); //Open a canvas and plot on it the varname distribution The second exercise is to get access to the histograms created when Drawing a variable of an ntuple. You should:
<blockquote style="background-color:#f0f0f0"> <pre> TH1F htemp = (TH1F)gPad->GetPrimitive("htemp"); // Get pointer to default 1D histo TGraph graph = (TGraph)gPad->GetPrimitive("Graph"); // Get pointer to default 2D graph myNtp->Draw("[varname]>>histo"); //Draws varname into the "histo" histogram TH1F histo = (TH1F)gDirectory->Get("histo"); //retrievs the histo myNtp->Draw("[varname]>>histo(500,10,20)"); //Draw varname into histo with specified binning/range. </pre> </blockquote> For a comprehensive review of the many capabilities of Draw method you can click here ---++++ Handling basics of graphics To exercise the basics of graphics you can start with: * Setting the session style to "Plain" * Creating a TCanvas * Drawing an histogram on the given canvas and save the canvas as eps or png plot * Divide the canvas in 2 and draw 2 different ntuple variables into the canvas * Get access to axis/histo information, legend, stats, line color, marker. Documentation on methods you'd like to exercise is linked here for histograms, markers, lines and fill Examples are given below: <blockquote style="background-color:#f0f0f0"> <pre> gROOT->SetStyle("Plain"); TCanvas c = new TCanvas("c","c",600,800); c->Clear(); c->cd(); histo->Draw(); c->Print("tmp.eps"); c->Print("tmp.png"); TCanvas *c1 = new TCanvas("c1","c1",600,1200); c1->Clear(); c1->Divide(1,2); c1->cd(1); histo->SetMarkerColor(4); histo->Draw("p"); c1->cd(2); histo->SetLineColor(2); histo->SetFillColor(3); histo->Draw("h"); c1->Print("tmp1.eps"); </pre> </blockquote> ---++++ Ntuple analysis From command line To exercise the ntuple analysis via command line you should: * Get access to the ntuple pointer (e.g. using gDirectory): * Print the ntuple information * Scan the desired variable * Plot the variable as a function of a second variable * Plot the variable applying some cuts * Plot the variable specifying graphic options (like 'same' one to superimpose 2 plots) Examples are given below: <blockquote style="background-color:#f0f0f0"> <pre> myNtp->Print(); myNtp->Draw("[varname]"); myNtp->Draw("[var1]:[var2]"); //Plots var1 as a function of var2 myNtp->Draw("[varname]","[cuts]"); myNtp->Draw("[varname]","[cuts]","[graph options]"); myNtp->Scan(); //Scans all variables myNtp->Scan("[varname]"); //Scan the specified variable </pre> </blockquote> For more informations on how to use cuts see TCut class. For more informations on graphics options see the TTree::Draw page. ---++++ Using macros You have two possible ways to use macros inside root: * Interactively using the .x command to load the macro * running the macro in batch using the -b (-q) options. * -q option exits root after having executed the macro * -b run in batch mode (no graphics) As exercise: * Write a Macro that display an Hello World message: run it with the -b option * Write a Macro that read an external ASCII file and displays the content: run it with -b -q option * Write a Macro that read an external ASCII file, fill an histogram and draws it. Load it and run it interactively using .x command. Example is given below: <blockquote style="background-color:#f0f0f0"> <pre> #include <iostream.h> void test() { cout<<"Hello World!!!"<<endl; //Histo inizialization TH1D * h_fa = new TH1D("h_fa","Factor histogram",100,0,1); //File reading double fact,top,err; int flag; char buffertC[200]; ifstream tsC("FinalCorrDatRightErrRms.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); cout<<"My factor: "<<fact<<endl; //Histo filling h_fa->Fill(fact); } TCanvas *c = new TCanvas("c","mycanvas",600,600); c->cd() h_fa->Draw(); c->Print("test.eps"); return; } </pre> </blockquote> ---++++ Ntuple/file creation To exercise the creation and filling of an ntuple you should: * Add the creation of the ntuple at the top of your macro * Properly initialize the variables * Read the external ASCII file. * Set up some int, double, string variables to be written. * Add the filling of the variables and writing of ntuple * Add the writing of the ntuple into a file. * Exit and browse the created file. Examples are given below. <blockquote style="background-color:#f0f0f0"> <pre> void MacroRead() { //Create a new file TFile *fNewOutFile = new TFile("root_file.root", "RECREATE"); //Existing file will be overwritten. fNewOutFile->cd(); //To go into the main directory of the file int f_myInt; double f_myDou; vector<string> *f_strVct; vector<double> *f_douVct; TTree *dataTree = new TTree("data","data"); //Creates ntuple dataTree->Branch("myInt", &f_myInt , "myInt/I"); //Int dataTree->Branch("myDou", &f_myDou , "myDou/D"); //Double dataTree->Branch("myStrVct", "vector<string>" , &f_strVct,32000,0); dataTree->Branch("myDouVct" ,"vector<double>" , &f_douVct,32000,0); //Inside the reading loop double fact,top,err; int flag; char buffertC[200]; string str; ifstream tsC("FinalCorrDatRightErr.dat"); while (tsC.getline(buffertC, 200, '\n')) { sscanf(buffertC, "%lf %lf %lf %d",&fact,&err,&top,&flag); f_myInt = f_myDou = 0; f_strVct->clear(); f_douVct->clear(); f_myInt = fact+1; f_myDou = err; str = "Time over Press: "; f_douVct->push_back(flag); f_strVct->push_back(str); dataTree->Fill(); } fNewOutFile->Write(); //To write objects into the file fNewOutFile->Close(); //To close a file return; } </pre> </blockquote> ---+++ Using a macro to Loop over the events ---++++ Creating the macro To create a macro to loop over the events in a given ntuple you should use the MakeClass method. <blockquote style="background-color:#f0f0f0"> <pre> myNtp->MakeClass("[className]"); </pre> </blockquote> This creates [className].C and [className].h in your working directory. You can then edit [className].C to include your analysis code that needs to run on each event. Modifications should go into the Loop() method (contained in the [className].C) that looks like: <blockquote style="background-color:#f0f0f0"> <pre> Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; } </pre> </blockquote> ---++++ Modifying the Loop() method. In order to add your particular analysis to the macro you should modify the Loop method adding three different phases: * Initialization. Should run only once and take care of object creation and initialization. * Analysis. Should run on each event and fill the histograms, ntuples, or analyze the events in other ways.... * Finalization. Should run only once at the end of the job and take care of clean up and file/plots writing.. Example is given below. <blockquote style="background-color:#f0f0f0"> <pre> initialization(); //Perform objects initialization Long64_t nentries = fChain->GetEntriesFast(); Long64_t nbytes = 0, nb = 0; for (Long64_t jentry=0; jentry<nentries;jentry++) { Long64_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; // if (Cut(ientry) < 0) continue; analysis(); //Perform analysis of each event, fill s output objects } finalization(); //Finalize the jobs (write/delete objects/file) </pre> </blockquote> To exercise the Loop method and the analysis using macros you should: * Customize the initialization() method in order to include the object definition that you'll need for your analysis. * Customize the analysis() method, that should contain the code that you want to run on each event. * Customize the finalization() method, that should contain the writing of analysis objects and their deletion. Examples on how to write those methods are given below. Remeber that: * Global variables should be declared in the .h file * Ntuple variables ARE already defined in the .h file: you should not REDECLARE them Initialization: <blockquote style="background-color:#f0f0f0"> <pre> void ClassName::initialization() { fOutFile = new TFile("root_file.root", "RECREATE"); fOutFile->cd(); //Histogram definition. my1DHisto = new TH1D("name","title",xbins,xmin,xmax); my2DHisto = new TH2D("name","title",xbins,xmin,xmax,ybins,ymin,ymax); return; } </pre> </blockquote> Analysis: <blockquote style="background-color:#f0f0f0"> <pre> void ClassName::analysis() { cout<<"My favourite variable value"<<myVar<<endl; my1DHisto->Fill(myvar); my2DHisto->Fill(myvar1,myvar2); return; } </pre> </blockquote> Finalization: <blockquote style="background-color:#f0f0f0"> <pre> void ClassName::finalization() { //Objects deletion fOutFile->Write(); //To write objects into the file fOutFile->Close(); //To close a file return; } </pre> </blockquote> ---++++ Load and run the macro Instructions are given in the macro [className].C file itself. <blockquote style="background-color:#f0f0f0"> <pre> // In a ROOT session, you can do: // Root > .L [className].C // Load of [className] macro // Root > [className] t // Class obejct creation // Root > t.GetEntry(12); // Fill t data members with entry number 12 // Root > t.Show(); // Show values of entry 12 // Root > t.Show(16); // Read and show values of entry 16 // Root > t.Loop(); // Loop on all entries </pre> </blockquote> Keep in mind that if you're using the macro to dump an ntuple into a file the ntuple *will not be dumped into the file until you EXIT from root (or force the writing and closing of the file!) ---+++ Creating standalone executables If you arrived here in less than 1 hour you can be proud of yourself. The most important part starts here. To create an executable you should: * Create a main() * Include/use/call in your main your favourite classes. * Create a makefile and know where to pick up libraries * Have gcc installed * Compile the main and run it The following subsection will remind you the basics to set up your executable. The exercise is contained in the very last subsection of this paragraph! ---++++ Create a main() executable First of all you should create the main that you're going to compile. The main should look like: <blockquote style="background-color:#f0f0f0"> <pre> #include <iostream> #include <fstream> int main (int argc, char argv[]) { cout<<"My First Executable!"<<endl; return 0; } </pre> </blockquote> Remeber to properly include the includes for the classes you're going to use! ---++++ Create a makefile Makefiles are typically needed in case of complex executables. If you have just one main and you don't need to include special classes or libraries you can just compile your main using gcc syntax. But in more complex cases the Makefile really helps to take care of the executable creation. Example of such makefile is given below: you should change the Simple tag replacing the rag name and code name with the values you've used for your executable. <blockquote style="background-color:#f0f0f0"> <pre> ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB += -lMinuit GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) Exec_tag: Simple.cc # ----------------------------------------------------------------------------- $(CXX) $(CXXFLAGS) -c $< $(LD) $(LDFLAGS) -o Simple Simple.o $(GLIBB) # ============================================================================== clean: rm -f *.o Simple </pre> </blockquote> The example above can be used to compile executables that need ROOT libraries but that are not depending on external classes. If you wanto to use external classes you might want to use a more complicated template. *Attention: after the tag the command should start with a 'tab' separator. If you copy paste the makefile from this page you loose the tab and the making won't work. Replace the spaces with a 'tab' when indicated!= <blockquote style="background-color:#f0f0f0"> <pre> ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) CXX = g++ CXXFLAGS = -g -Wall -fPIC CXXFLAGS = -g -Wall -fPIC LD = g++ LDFLAGS = -g SOFLAGS = -shared NGLIBB = $(ROOTGLIBS) NGLIBB + -lMinuit NGLIBB + /home/asarti/macro/source/libMyClass.so GLIBB = $(filter-out -lNew, $(NGLIBB)) CXXFLAGS + $(ROOTCFLAGS) LIBS = $(ROOTLIBS) NTUPLEB = MyClass.o MyClassDict.o .SUFFIXES: .cc,.C .cc.o: tab$(CXX) $(CXXFLAGS) -c $< # ================================================================================ lib: $(NTUPLEB) #--------------------------------------------------------------- tab$$(CXX) $(SOFLAGS) $(NTUPLEB) -o libMyClass.so MyClassDict.cc: MyClass.hh tab$$(ROOTSYS)/bin/rootcint -f MyClassDict.cc -c -I../ MyClass.hh # ================================================================================ Exec_tag: Exec.o lib # ----------------------------------------------------------------------------- tab$$(LD) $(LDFLAGS) -o Exec Exec.o $(GLIBB) clean: tab$rm -f *.so tab$rm -f *.o tab$rm -f *Dict.* tab$rm -f Exec </pre> </blockquote> ---++++ Compile/run/debug the executable Instructions to compile, run, debug the executable are given below: <blockquote style="background-color:#f0f0f0"> <pre> gmake -f Makefile Exec_tag ./Exec -options : to run your exec. gdb ./Exec and then run -options commands: to debug you executable </pre> </blockquote> ---++++ Final Exercise Create an executable that runs on the DecayChainNtuple provided here that: * Takes as input the number of events to process and the root file name * Print out the Energy of lab0 candidate for each event * Fill/save an histogram (in eps and png formats) with the momentum of lab1 and lab2 candidates * Save an ntuple into a ROOT file that contains the: event number, invariant mass of lab1 and lab2 candidates, momentum and mass of lab0 candidate To do so: * First of all create a myTree class using makeclass on the DecayChainNtuple Tree. * Create the main, include the myTree.h file and create the myTree ntp onject. * Use the ntp.Loop() method to loop on candidates * create the proper initialize and finalize methods to create and save histograms and ntuples. * compile it and run it! -- AlessioSarti - 18 Jun 2007 * prova.root: Ntuple for playing -- AlessioSarti - 2011-05-06 *
|