Setup rootcore

To setup rc you have to do:

mkdir TTHbbTuto
cd TTHbbTuto
setupATLAS
rcSetup Top,2.4.29

Note that setupATLAS is an alias. If you do not have it use this:

export ATLAS_LOCAL_ROOT_BASE=/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase
alias setupATLAS='source ${ATLAS_LOCAL_ROOT_BASE}/user/atlasLocalSetup.sh'

Checkout packages

First lets get the TTHbbNtupleAnalysis package:

rc checkout_pkg atlascppm/Higgs/ttHbb/RootCore/TTHbbNtupleAnalysis/trunk

Then lets get the packages needed by TTHbbNtupleAnalysis. These are stored in share/packages.txt or share/devPackages.txt. In the future (next week) packages.txt will contain a stable version and devPackages.txt will be used for development. For now use devPackages.txt.

rc checkout TTHbbNtupleAnalysis/share/devPackages.txt
svn might ask you several times for your password. If this is the case you might ask Timothee, Yann or me or you fellow students on how to get a ticket that avoids typing the password at each time. One package is not up-to-date in SVN (add it is mine to update it) so you have to copy it from my local area:
cp -r /atlas/aad/workarea/Higgs/ttHAna2015/rootAna/Mig/NNLOReweighter .
Or for people at cern:
cp -r /afs/cern.ch/user/a/aad/public/NNLOReweighter .

compile the code

Now we have all needed packages. Lets compile:

rc find_packages
rc compile
rc find_packages is only needed the first time you add a package to you rootcore area.

Run the code

The code is made to be very flexible and based on "JobOptions" written in C++ (live with it). The executable is called run (even if you can easily create your own). It includes other C++ files (with .h extension, arbitrary choice) that contain functions to configure the code. Run can read options also from commend line and from a configuration text file (default in share/config.txt). For now lets just run the default. The input file can be a single root file (should end with the .root extension) or a list of rootfiles in a text file (should end with a .txt). Wildcards are only supported when used in the text file following what is accepted by the ROOT TChain class.

echo /quark4/ttHbb/TopAnaOutput/00-02-03/mc/1l/group.phys-higgs.mc15_13TeV.343366.aMCNloP8_ttH125_slep.e4706s2726r7772p2952.TTHbbL022.1l.v2_out.root/group.phys-higgs.11138029._000001.out.root > input.txt
## or for people at cern: echo  /afs/cern.ch/work/a/aad/public/group.phys-higgs.11138029._000001.out.root  > input.txt
## run input.txt
## equivalent to run /quark4/ttHbb/TopAnaOutput/00-02-03/mc/1l/group.phys-higgs.mc15_13TeV.343366.aMCNloP8_ttH125_slep.e4706s2726r7772p2952.TTHbbL022.1l.v2_out.root/group.phys-higgs.11138029._000001.out.root
## lets limit the number of events to run faster
run input.txt maxEvents=10000

This will create an output file called tth_ana_output.root. You can specify the output file name by giving it as a second argument after the output. The output file name should end with .root extension (otherwise the code will switch to another output format assuming outputs will be written in independent root files and not in a single one, not covered in this tutorial).

run input.txt  output.root maxEvents=10000
Lets use the output.root (not the default from now on). You can open output.root and browse it. It contains the following structure: sampleName/systName/AlgoName/Tree_or_histoName. Also if you look at the log file you will see

Running your own stuff

share/run.cxx contains the main function. It loops over the list of systematics (configurable, for now we are only using nominal) and create a sequence of algorithms to be executed by the ApplicationMgr. You basically have to add your algorithm to a sequence to be executed. It will have access to I/O and the DataStore through the AlgoBase class. To make things easier the flag analysisName= is created and used inside run.cxx. It calls a predefined function in a separated JO file for a specific study. Default is "ttHDefaultAna". Some of you have already their JO with their name. For this tutorial I created analysisName=CPPMTuTo which calls the function runTuto in util/CPPMTuTo.h. The code to do this rudimentary:

#include "CPPMTuTo.h"
...
if("CPPMTuTo"==config.analysisName){
   runTuto(theapp, config, runOption);
}

So lets run with CPPMTuTo:

run input.txt  output.root maxEvents=10000 analysisName=CPPMTuTo
Now the output file is empty (still have the same structure but no algos but CutFlowHistoFiller which is added by default). Lets now add our sequence and add an algo to it. We will do all of this in util/CPPMTuTo.h. Open util/CPPMTuTo.h (with emacs, vi people are not allowed in this tutorial :-p, for the others well we can ignore you wink ) and add: (note that algo names should be unique so you have to follow a naming convention.
std::string localName = "cppmTuto";
  ///create our sequence and add it to application manager.
  AlgSequence* basic_seq=new AlgSequence("AlgSequence_"+localName);
  theapp.addAlgo(basic_seq);

  TuToAlgo* tutoalgo = new TuToAlgo("TuToAlgo_"+localName);
  tutoalgo->m_jetcontainername="selected_jets";
  basic_seq->addAlgo(tutoalgo);

Now lets create a new algo to the sequence. First we have to create it. Lets call it TuToAlgo. So you have to create TuToAlgo.h class in TTHbbNtupleAnalysis and TuToAlgo.cxx in Root. TuToAlgo.h will contain (have to inherit from AlgoBase):

#ifndef TuToAlgo_HH
#define TuToAlgo_HH

#include "TTHbbNtupleAnalysis/AlgoBase.h"

class TuToAlgo : public AlgoBase{

 public:

  explicit TuToAlgo(std::string);
  virtual ~TuToAlgo();

  virtual bool initialize();
  virtual bool execute();
  virtual bool finalize();
  
  std::string m_jetcontainername;

 private:
  double m_eventWeight;
  TH1* h_jet_pt;
};
#endif

And TuToAlgo.cxx contains:

#include "TTHbbNtupleAnalysis/TuToAlgo.h"

TuToAlgo::TuToAlgo(std::string name) : AlgoBase(name){
  m_jetcontainername="";
}

TuToAlgo::~TuToAlgo(){
  ////
}


bool TuToAlgo::initialize(){

  std::cout << m_name << " initialize " << endl;
  m_histoSvc->registerHisto(h_jet_pt,"h_jet_pt",60,25,250);
  m_histoSvc->sumw2();
  m_cuts->setEventWeight(m_eventWeight);

  return true;

}

bool TuToAlgo::execute(){

  m_cuts->ocount("in execute "+m_name,0);

  MetaData *meta = m_dataStore->getMetaData();
  if(!meta){
    std::cout << "WARNING " << m_name << " meta data not found " << std::endl;
    return false;
  }

  WeightData *weightData = m_dataStore->getWeightData();
  if(!weightData){
    std::cout << "WARNING " << m_name << " weight data not found " << std::endl;
    return false;
  }
  m_eventWeight = weightData->getEventWeight("lumi*weight_mc"); ///default "lumi*weight_mc*weight_leptonSF" set in run.cxx, will make default configurable from config.txt

  JetContainer* jets = m_dataStore->getJetContainer(m_jetcontainername);
  if(!jets){
    std::cout << "WARNING " << m_name << " JetContainer " << m_jetcontainername << "  not found " << std::endl;
    return false;
  }

  for(auto jet: *jets){
    h_jet_pt->Fill(jet->Pt()/1000., m_eventWeight);
  }
 
  return true;
}

bool TuToAlgo::finalize(){

  std::cout << m_name << " finalize " << endl;
  return true;

}

add in utils/run.cxx at the beginning with all other algorithm includes:

#include "TTHbbNtupleAnalysis/TuToAlgo.h"

Now compile go to the run directory that you created and run the code again. You should have your histo in the output file. Browse the output to find it. Notice that it is under a directory with your algo name.

adding histos in different regions

Now lets add several histos to the same algo with different region cuts. First we have to make the algo inherit from RegionInterface. Add to TuToAlgo.h:

#include "TTHbbMVAInterfaces/RegionInterface.h"
#include "MVAVariables/JetOrderingTool.h"
and then add "public RegionInterface," to the class definition. Lets also add JetOrderingTool m_jetOrderingTool; as private member of the class and std::string m_eventHolderKey; as public member (initialize it to ="" in the constructor in .cxx). Also add an array of histos as private member of the class:
TH1* h_jetpt1_pt[20]; /// max allowed regions is 20

Then in TuToAlgo.cxx: Add "RegionInterface()," to the constructor. Before "m_histoSvc->sumw2();" add the following to the Initialize function:

for(auto r : m_regions){
    m_histoSvc->registerHisto(h_jetpt1_pt[r.index],"h_jetpt1_pt_"+r.name,60,25,300);
  }
and in the execute function (before the return true of course):
RecoEvent* eventvar = m_dataStore->getRecoEvent(m_eventHolderKey);
  if(!eventvar){
    std::cout << "WARNING " << m_name << " RecoEvent " << m_eventHolderKey << "  not found " << std::endl;
    return false;
  }
///.....
 m_jetOrderingTool.sortPt(*jets);

  vector<int> regions;
  getRegions(regions, eventvar->nJets, eventvar->nBJets, eventvar->leptonType, eventvar);

  for(auto region : regions){
    if(jets->size()>0)h_jetpt1_pt[region]->Fill((*jets)[0]->p4().Pt()/1000.,m_eventWeight);
  }
The regions will be added in the JO. If no regions are added no histos will be created. Up to 20 regions can be added since we created an histo array of size 20 (you can make more if you want more histos, but you have to look at them all!!). There is few ways to add regions in the JO. But we need first to create an event holder in the DataStore that will contain many variables that we can cut on. Here how to do it in util/CPPMTuTo.h (before creating TuToAlgo):

std::string localEventName = "cppmEvent"; /// the name of the event in the store
  std::string defaultBtagID = "isbtagged_85"; /// the default btag cut (e.g. nBTags in the event will be @85%,nBTags_85, nBTags_77 decorations ... are also available).

  //// create an event holder (TTHbb::RecoEvent class) that will hold all event based variables including choosed reco combinations
  EventHolderCreator* evtHolder = new EventHolderCreator("EventHolderCreator_"+localName);
  evtHolder->m_inputJets = "selected_jets";
  evtHolder->m_inputLeptons = "selected_leptons";
  evtHolder->m_inputNeutrinos = "basic_neutrinos";
  evtHolder->m_eventHolderKey=localEventName;
  evtHolder->m_btagIdName=defaultBtagID; 
  basic_seq->addAlgo(evtHolder);
  /// or use prepareEventHolder(basic_seq, localEventName, defaultBtagID); /// defined in util/JobOptions/EventHolderHelperFunc.h

  /// this will add few global variable to the event holder, needed to cut on later (like nBTags_77)
  addGlobalVars(basic_seq, localEventName); 
  addObjectVars(basic_seq, localEventName);
  addMVAVars(basic_seq, localEventName, config); /// do not forget to uncomment config in the funtion declaration

Now lets add regions to the algo. There a couple of ways to do it. We can create the region and add it explicitly like this:

///configure region with cuts. Can use decoration into the EventHolder or members like nJets and nBjets (@ default cut that the event holder was created with)
  RegionInterface::RegionDefinition r_6jupr;
  r_6jupr.name="6jUPR";
  r_6jupr.intLowerCut("nBTags_77",4);
  r_6jupr.intUpperCut("nBTags_77",10000);
  r_6jupr.nJetsMin=6;
  r_6jupr.nJetsMax=10000;

  RegionInterface::RegionDefinition r_6jsig =  getRegion("6jsig", "SemilepRegions_signalRegions", 601);

  tutoalgo->addRegion(r_6jupr);
  tutoalgo->addRegion(r_6jsig);
  tutoalgo->addRegion("6ji3be",6,10000,3,3,0); /// will create region with name, njetsmin, njetsmax, nbjetsmin(@default), nbjetsmax(@default), lepton flavor (0 for no cuts).
  tutoalgo->m_eventHolderKey=localEventName;

and now compile and run and see what you get.

-- GeorgesAad - 2017-04-23

Edit | Attach | Watch | Print version | History: r3 < r2 < r1 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r3 - 2017-04-24 - YannCoadou
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Main All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback