NAGASH 0.9.8
Next Generation Analysis System
Loading...
Searching...
No Matches
Classes
Analysis Classes

Classes for constructing a analysis framework. More...

Classes

class  NAGASH::Analysis
 Provide multi-thread interface to manipulate with Job. More...
 
class  NAGASH::ConfigTool
 provide interface to config objects in NAGASH. More...
 
class  NAGASH::Job
 Virtual base class for all kinds of jobs inside NAGASH, handled by Analysis. More...
 
class  NAGASH::LoopEvent
 Virtual base class for event loops. More...
 
class  NAGASH::MSGTool
 Maniplulate all messages of NAGASH. More...
 
class  NAGASH::ResultGroup
 Used to manipulate a group of Result objects., especially inside NAGASH::Job. More...
 
class  NAGASH::Toolkit
 Manipulate the Tool classes, give them correct MSGTool inside NAGASH::Job. More...
 

Detailed Description

Classes for constructing a analysis framework.

Your First Analysis Framework

HelloWorld

Firstly, let's print out "hello world !" in the framework of NAGASH, create a file HelloWorld.cxx after you setup NAGASH with following content:

#include "NAGASH.h"
#include <iostream>
class HelloWorld : public NAGASH::Job
{
public:
// constructor of the class, inherited from NAGASH::Job
HelloWorld(const NAGASH::ConfigTool &config) : NAGASH::Job(config) {}
// User defined function
void Print();
// The function called in NAGASH::Analysis::SubmitJob, must be static
static NAGASH::StatusCode Process(const NAGASH::ConfigTool &config, std::shared_ptr<NAGASH::ResultGroup> result);
};
void HelloWorld::Print()
{
// use NAGASH::MSGTool to print messages
MSGUser()->StartTitle("HelloWorld::Print");
MSGUser()->MSG(NAGASH::MSGLevel::INFO, "Hello World ! (from Job Number ", JobNumber(), ")");
MSGUser()->EndTitle();
}
NAGASH::StatusCode HelloWorld::Process(const NAGASH::ConfigTool &config, std::shared_ptr<NAGASH::ResultGroup> result)
{
// the first argument is the ConfigTool that you should pass to constructor
// the second argument is the ResultGroup you want to save.
// you should call
// result->Merge(job.ResultGroupUser())
// after your job finishes
HelloWorld temph(config);
// add lock to avoid messy output
temph.Print();
}
int main()
{
// let the threadpool of MyAnalysis be the size of 5
config.BookPar<int>("Nthread", 5);
NAGASH::Analysis MyAnalysis(config);
for (int i = 0; i < 5; i++)
{
// submit your job
MyAnalysis.SubmitJob<HelloWorld>(false);
}
// join all the submitted jobs
MyAnalysis.Join();
}
int main(int argc, char **argv)
Provide multi-thread interface to manipulate with Job.
Definition Analysis.h:235
provide interface to config objects in NAGASH.
Definition ConfigTool.h:14
void BookPar(const TString &name, const T &value)
Book parameter with given name and value.
Definition ConfigTool.h:63
Virtual base class for all kinds of jobs inside NAGASH, handled by Analysis.
Definition Job.h:41
static std::recursive_mutex DefaultMutex
Default mutex, for multi-thread usage.
Definition Job.h:59
StatusCode
Definition Global.h:76

Then compile and run with following commands:

g++ -std=c++17 `root-config --cflags --libs` -lMinuit -lMinuit2 -lpthread -lm -lNAGASH -O3 HelloWorld.cxx -o HelloWorld
./HelloWorld

You will see a output like:

Analysis->Timer::PrintCurrent INFO Submit job 0 at 2021-02-14 19:16:57
Analysis->Timer::PrintCurrent INFO Submit job 1 at 2021-02-14 19:16:57
Analysis->Timer::PrintCurrent INFO Submit job 2 at 2021-02-14 19:16:57
Analysis->Timer::PrintCurrent INFO Submit job 3 at 2021-02-14 19:16:57
Analysis->Timer::PrintCurrent INFO Submit job 4 at 2021-02-14 19:16:57
Analysis->HelloWorld::Print INFO Hello World ! (from Job Number 0)
Analysis->HelloWorld::Print INFO Hello World ! (from Job Number 2)
Analysis->HelloWorld::Print INFO Hello World ! (from Job Number 1)
Analysis->HelloWorld::Print INFO Hello World ! (from Job Number 4)
Analysis->HelloWorld::Print INFO Hello World ! (from Job Number 3)
Analysis INFO Finished all submitted jobs
Analysis INFO Finished Time : 2021-02-14 19:16:57
Analysis->Timer::Duration INFO Duration between (First Submit) and (Finish Submitted Jobs) : 918 us

You can modify HelloWorld.cxx and see how the output changes.

Creating your first analysis framework

Let's create the basic directory structure first:

mkdir MyAnalysis
cd MyAnalysis
mkdir include src control share

Then use NAGASHMakeClass to make class for processing ROOT file:

NAGASHMakeClass /Data2/whma/Pythia8_Wmunu_pp_13TeV/Pythia8_Wmunu_pp_13TeV_CT10_2M_1.root Tree LoopPythiaWSample

You will get LoopPythiaWSample.h and LoopPythiaWSample.cxx in current directory, move .h to include and .cxx to src. Then edit src/LoopPythiaWSample.cxx as follows:

#include "LoopPythiaWSample.h"
// User can use "using namespace NAGASH;" to avoid extra typing.
NAGASH::StatusCode LoopPythiaWSample::InitializeUser()
{
// In this function, User can initialize their own variables, e.g. PlotGroup
ResultGroupUser()->BookResult<NAGASH::Count>("Mass");
auto MyPlotGroup = ResultGroupUser()->BookResult<NAGASH::PlotGroup>("MassHist", "MyAnalysis_MassHist.root");
MyPlotGroup->BookPlot1D("WMass", 200, 0, 100);
MyPlotGroup->BookPlot1D("WPt", 200, 0, 100);
MyPlotGroup->BookPlot1D("WRapidity", 100, -5, 5);
}
NAGASH::StatusCode LoopPythiaWSample::Execute()
{
// In this function, User do what they want for each entry in the TTree
TLorentzVector WbosonP4;
WbosonP4.SetPxPyPzE(WbosonPx, WbosonPy, WbosonPz, WbosonE);
ResultGroupUser()->Get<NAGASH::Count>("Mass")->Add(WbosonP4.M());
// Fill booked histograms
// In real analysis, users are recommanded to store the pointer of histograms as member variables
// Since ResultGroup::Get are quite slow and will slow down your program if you call it for each entry
std::shared_ptr<NAGASH::PlotGroup> MyPlotGroup = ResultGroupUser()->Get<NAGASH::PlotGroup>("MassHist");
MyPlotGroup->GetPlot1D("WMass")->Fill(WbosonP4.M());
MyPlotGroup->GetPlot1D("WPt")->Fill(WbosonP4.Pt());
MyPlotGroup->GetPlot1D("WRapidity")->Fill(WbosonP4.Rapidity());
// Debug info
MSGUser()->MSG(NAGASH::MSGLevel::DEBUG, WbosonP4.M());
}
NAGASH::StatusCode LoopPythiaWSample::Finalize()
{
// In this function, User can do something after process the entries
}
Use CountBase with the interface of provided by NAGASH::Result.
Definition Count.h:98
Provide a base class for manipulating a group of histograms at the same time.
Definition PlotGroup.h:18
std::shared_ptr< Plot1D > GetPlot1D(const TString &name)
Get NGHist<TH1D>
Definition PlotGroup.h:175

Create control/MyAnalysis.cxx with:

#include "Analysis.h"
#include "LoopPythiaWSample.h"
using namespace NAGASH;
using namespace std;
int main(int argc, char **argv)
{
if (argc != 2)
{
cout << "Usage: " << argv[0] << " (file list) (config file)" << endl;
return 0;
}
Analysis MyAnalysis(argv[2]);
auto myresult = MyAnalysis.ProcessEventLoop<LoopPythiaWSample>(argv[1]);
}

Create makefile with the following command:

GenerateMakefile MyAnalysis

In general, you can call GenerateMakefile (project name) to generate makefile of your project in current directory.

Create share/filelist.dat with:

/Data2/whma/Pythia8_Wmunu_pp_13TeV/Pythia8_Wmunu_pp_13TeV_CT10_2M_1.root
/Data2/whma/Pythia8_Wmunu_pp_13TeV/Pythia8_Wmunu_pp_13TeV_CT10_2M_2.root
/Data2/whma/Pythia8_Wmunu_pp_13TeV/Pythia8_Wmunu_pp_13TeV_CT10_2M_3.root
/Data2/whma/Pythia8_Wmunu_pp_13TeV/Pythia8_Wmunu_pp_13TeV_CT10_2M_4.root
/Data2/whma/Pythia8_Wmunu_pp_13TeV/Pythia8_Wmunu_pp_13TeV_CT10_2M_5.root

Create share/config.dat with:

int Nthread 5 # number of threads
long EvtMax 1000 # number of entry you want to read in
bool CreateLog 0 # create log file or print to screen
string LogFileName MyAnaOut.log # log file name
string MSGLevel INFO # message level

Then run with the following command:

make -j
./bin/MyAnalysis ./share/filelist.dat ./share/config.dat

After it finishes, you will get a ROOT file MyAnalysis_MassHist.root, check its content.

Then switch CreateLog to 1 and MSGLevel to DEBUG and rerun. Check the log file you get.