Dynamique name of Histogram


ROOT Version: 6.12/06:


Dear All,
Maybe this question is a bit simple but I am struggling to do it. Actually I am creating a bunch of histograms, which have the same structure. However while looping over my Ntuple and filling histograms I would like the name of histograms to contain the name of the dataset and the name the channel. Here is an exemple of one of the histograms for instance:

 hCuts_4e_345709 = new TH1F("hCuts_4e_345709","all channel;cut;events",5,0.5,5.5);
  TAxis* ax_Cuts_4e_345709 = hCuts_4e_345709->GetXaxis();
  ax_Cuts_4e_345709->SetBinLabel(1,"all");
  ax_Cuts_4e_345709->SetBinLabel(2,"A");
  ax_Cuts_4e_345709->SetBinLabel(3,"B");
  ax_Cuts_4e_345709->SetBinLabel(4,"C");
  ax_Cuts_4e_345709->SetBinLabel(5,"D");

where the name “hCuts_4e_345709” means I am in channel 4e and 345709 is the name of the dataset.
Is someone has any idea how to proceed please ? I was thinking to use map but I am having trouble.
Thanks in advance.
Cheers,
Diallo

Where’s the “looping and filling” (i.e. how do you do it)?

Thanks for replying.
Actually I am using Tslector and my .C file looks like this:

#define abcd_method_cxx
// The class definition in abcd_method.h has been generated automatically
// by the ROOT utility TTree::MakeSelector(). This class is derived
// from the ROOT class TSelector. For more information on the TSelector
// framework see $ROOTSYS/README/README.SELECTOR or the ROOT User Manual.

// The following methods are defined in this file:
//    Begin():        called every time a loop on the tree starts,
//                    a convenient place to create your histograms.
//    SlaveBegin():   called after Begin(), when on PROOF called only on the
//                    slave servers.
//    Process():      called for each event, in this function you decide what
//                    to read and fill your histograms.
//    SlaveTerminate: called at the end of the loop on the tree, when on PROOF
//                    called only on the slave servers.
//    Terminate():    called at the end of the loop on the tree,
//                    a convenient place to draw/fit your histograms.
//
// To use this file, try the following session on your Tree T:
//
// Root > T->Process("abcd_method.C")
// Root > T->Process("abcd_method.C","some options")
// Root > T->Process("abcd_method.C+")
//

#include "abcd_method.h"
#include <TH2.h>
#include <TStyle.h>


void abcd_method::Begin(TTree * /*tree*/)
{
   // The Begin() function is called at the start of the query.
   // When running with PROOF Begin() is only called on the client.
   // The tree argument is deprecated (on PROOF 0 is passed).

   TString option = GetOption();

}

void abcd_method::SlaveBegin(TTree * /*tree*/)
{
   // The SlaveBegin() function is called after the Begin() function.
   // When running with PROOF SlaveBegin() is called on each slave server.
   // The tree argument is deprecated (on PROOF 0 is passed).

   TString file = GetOption();
   if (file.IsNull())
     file="summary.root";
   else {
     Ssiz_t pos = file.Last('.');
     if (pos<0) pos=file.Length();
     file.Replace(pos,20,".root");
   }
   fOut = TFile::Open(file, "RECREATE");
   hCuts_4e_345709 = new TH1F("hCuts_4e_345709","all channel;cut;events",5,0.5,5.5);
  TAxis* ax_Cuts_4e_345709 = hCuts_4e_345709->GetXaxis();
  ax_Cuts_4e_345709->SetBinLabel(1,"all");
  ax_Cuts_4e_345709->SetBinLabel(2,"A");
  ax_Cuts_4e_345709->SetBinLabel(3,"B");
  ax_Cuts_4e_345709->SetBinLabel(4,"C");
  ax_Cuts_4e_345709->SetBinLabel(5,"D");
}
Bool_t abcd_method::Process(Long64_t entry)
{
   fChain->GetEntry(entry);
     int Ncut = 1;

if ((fabs(IdLep1)==13 && d0SigLep1 < 3.) || (fabs(IdLep1)==11 && d0SigLep1 < 5.)) lepton_d0Sig[0] = true; 
     else lepton_d0Sig[0] = false;
     //  if (lepton_d0Sig[0] == 1) {std::cout << "fabs(IdLep1) = " <<fabs(IdLep1) << std::endl; std::cout << "d0SigLep1 = " << d0SigLep1 << std::endl;}
     // if (fabs(IdLep1)==11) std::cout << "d0SigLep1_electron = " << d0SigLep1 << std::endl;
     if ((fabs(IdLep2)==13 && d0SigLep2 < 3.) || (fabs(IdLep2)==11 && d0SigLep2 < 5.)) lepton_d0Sig[1] = true;
     else lepton_d0Sig[1] = false;
     if ((fabs(IdLep3)==13 && d0SigLep3 < 3.) || (fabs(IdLep3)==11 && d0SigLep3 < 5.)) lepton_d0Sig[2] = true;
     else lepton_d0Sig[2] = false;
     if ((fabs(IdLep4)==13 && d0SigLep4 < 3.) || (fabs(IdLep4)==11 && d0SigLep4 < 5.)) lepton_d0Sig[3] = true;
     else lepton_d0Sig[3] = false;
     d0SigB_allpass      =    (lepton_d0Sig[0])  && (lepton_d0Sig[1])  && (lepton_d0Sig[2])  && (lepton_d0Sig[3]);
     d0SigB_34Npass      =    (lepton_d0Sig[0])  && (lepton_d0Sig[1])  && (!lepton_d0Sig[2]) && (!lepton_d0Sig[3]) ;
     d0SigB_3pass_4Npass =    (lepton_d0Sig[0])  && (lepton_d0Sig[1])  && (lepton_d0Sig[2])  && (!lepton_d0Sig[3]);
     d0SigB_3Npass_4pass =    (lepton_d0Sig[0])  && (lepton_d0Sig[1])  && (!lepton_d0Sig[2]) && (lepton_d0Sig[3]);
     //  std::cout <<"MC_channel_number"<< MC_channel_number<<"Events_all"<<Events_all<<std::endl;
     // std::cout <<histoname<<std::endl;

    //   if(MC_channel_number==345709) Events_all_345709 = Events_all;
      //  histoName->Fill(1,EvtWeight);

        if (llll_pdgIdSum ==44)
       {
	 if(MC_channel_number==345709)  hCuts_4e_345709->Fill(1,EvtWeight);

	 if(l_isIsolFixedCutLoose==15 && d0SigB_allpass)
	   {
	   if(MC_channel_number==345709)  hCuts_4e_345709->Fill(2,EvtWeight);
	     	     
	   }
	 
	 if(l_isIsolFixedCutLoose==15 && (d0SigB_34Npass || d0SigB_3pass_4Npass ||d0SigB_3Npass_4pass))
	   {
	   if(MC_channel_number==345709)  hCuts_4e_345709->Fill(3,EvtWeight);
	     	     
	   }
	 
	 if(d0SigB_allpass && (l_isIsolFixedCutLoose==12 ||l_isIsolFixedCutLoose==14 || l_isIsolFixedCutLoose==13))
	   {
	   if(MC_channel_number==345709)  hCuts_4e_345709->Fill(4,EvtWeight);
	   }

	 if((d0SigB_34Npass || d0SigB_3pass_4Npass ||d0SigB_3Npass_4pass) && (l_isIsolFixedCutLoose==12 ||l_isIsolFixedCutLoose==14 || l_isIsolFixedCutLoose==13))
	   {
	    if(MC_channel_number==345709) hCuts_4e_345709->Fill(5,EvtWeight);
	   }
       }
 return kTRUE;
}
void abcd_method::SlaveTerminate()
{
   // The SlaveTerminate() function is called after all entries or objects
   // have been processed. When running with PROOF SlaveTerminate() is called
   // on each slave server.
   double NormFacor_345709 = crosSect_345709*kfactor_345709*genFiltEff_345709*lumi;
   hCuts_4e_345709->Scale(NormFacor_345709/Events_all_345709);
  hCuts_2e2m_345709->Scale(NormFacor_345709/Events_all_345709);
  hCuts_4m_345709->Scale(NormFacor_345709/Events_all_345709);
}

void abcd_method::Terminate()
{
   // The Terminate() function is the last function to be called during
   // a query. It always runs on the client, it can be used to present
   // the results graphically or save the results to file.
   TString summary = GetOption();
   if (summary.IsNull()) {
     if (fOut && fOut->IsOpen()) {
       fOut->Write();
       fOut->Close();
     }
   } else {
     Ssiz_t pos = summary.Last('.');
     if (pos<0) pos=summary.Length();
     summary.Replace(pos,20,".pdf");
   }
 if (fOut && fOut->IsOpen()) {
     fOut->Write();
     fOut->Close();
   }
  //  hCuts_4e_345709->Draw();
}

And my .h file this:

//////////////////////////////////////////////////////////
// This class has been automatically generated on
// Wed May  2 10:12:16 2018 by ROOT version 5.34/36
// from TTree myTree/myTree
// found on file: ggZZ4lNoSherpa_20180131_mc16a_Iso_Imp_ElID_NoAp.root
//////////////////////////////////////////////////////////

#ifndef abcd_method_h
#define abcd_method_h

#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TSelector.h>

// Header file for the classes stored in the TTree if any.
#include <TLorentzVector.h>

// Fixed size dimensions of array or collections stored in the TTree if any.

class abcd_method : public TSelector {
public :
   TTree          *fChain;   //!pointer to the analyzed TTree or TChain

   // Declaration of leaf types
   TFile* fOut;
   TH1F* hCuts_4e_345709;
   TH1F* hCuts_2e2m_345709;
   TH1F* hCuts_4m_345709;

   TH1F* hCuts_4e_364250;
   TH1F* hCuts_2e2m_364250;
   TH1F* hCuts_4m_364250;

   TH1F* hCuts_4e_364251;
   TH1F* hCuts_2e2m_364251;
   TH1F* hCuts_4m_364251;

   TH1F* hCuts_4e_364252;
   TH1F* hCuts_2e2m_364252;
   TH1F* hCuts_4m_364252;

   TH1F* hCuts_4e_345060;
   TH1F* hCuts_2e2m_345060;
   TH1F* hCuts_4m_345060;

   TH1F* hCuts_4e_364243;
   TH1F* hCuts_2e2m_364243;
   TH1F* hCuts_4m_364243;

   TH1F* hCuts_4e_364245;
   TH1F* hCuts_2e2m_364245;
   TH1F* hCuts_4m_364245;

   TH1F* hCuts_4e_364247;
   TH1F* hCuts_2e2m_364247;
   TH1F* hCuts_4m_364247;

   TH1F* hCuts_4e_364248;
   TH1F* hCuts_2e2m_364248;
   TH1F* hCuts_4m_364248;

   TH1F* hCuts_4e_364283;
   TH1F* hCuts_2e2m_364283;
   TH1F* hCuts_4m_364283;
   
   TH1F* hCuts_4e_361601;
   TH1F* hCuts_2e2m_361601;
   TH1F* hCuts_4m_361601;

   TH1F* hCuts_4e_361106;
   TH1F* hCuts_2e2m_361106;
   TH1F* hCuts_4m_361106;
   
   TH1F* hCuts_4e_361107;
   TH1F* hCuts_2e2m_361107;
   TH1F* hCuts_4m_361107;
   
   TH1F* hCuts_4e_361108;
   TH1F* hCuts_2e2m_361108;
   TH1F* hCuts_4m_361108;
   double lumi = 79.6;
 //gg4lNH bkg
   // double  events_all_345709 = 499792;
 double  crosSect_345709   = 10.556;
 double  kfactor_345709    = 1.0;
 double  genFiltEff_345709 = 1.000;
 Double_t  Events_all_345709;
 TString datasetID;
 TString channel;
 // void fill(int datasetID, TString regionTag, TString cutTag, double evtWeight);
 //     TH1* getHist(TString histoName);
 //     std::map<TString, TH1*> m_histos;

 // std::map<std::string, std::map<string,TH1*>> m_hists;
 // std::map<std::string, TH1*> m_hists;
 // TString histoName;
 // TH1* histoname;
 // TH1* getHist(TString histoName);

 /* void fill(int datasetID, TString region, TString decayChannel, TString cutTag, double evtWeight);
 void fill(int datasetID, TString regionTag, TString cutTag, double evtWeight);
 TH1* getHist(TString histoName);
 std::map<TString, TH1*> m_histos;
 std::map<TString, TH1*> m_histosCutflow;*/

   TLorentzVector  *lep12;
   TLorentzVector  *lep34;
   TLorentzVector  *lep32;
   TLorentzVector  *lep14;
   TLorentzVector  *lep1234;
   TLorentzVector  *lep1;
   TLorentzVector  *lep2;
   TLorentzVector  *lep3;
   TLorentzVector  *lep4;
   Int_t           IdLep1;
   Int_t           IdLep2;
   Int_t           IdLep3;
   Int_t           IdLep4;
   Float_t         d0SigLep1;
   Float_t         d0SigLep2;
   Float_t         d0SigLep3;
   Float_t         d0SigLep4;
   Int_t           elIDLep1;
   Int_t           elIDLep2;
   Int_t           elIDLep3;
   Int_t           elIDLep4;
   Int_t           muID4Lep;
   Double_t        EvtWeight;
   Int_t           llll_pdgIdSum;
   ULong64_t       eventNumber;
   Int_t           RunNumber;
   Int_t           l_isIsolFixedCutLoose;
   Int_t           MC_channel_number;
   Double_t        max_el_d0Sig;
   Double_t        max_mu_d0Sig;
   Double_t        Events_all;
   Bool_t lepton_d0Sig[4];
   Bool_t d0SigB_allpass;
   Bool_t d0SigB_34Npass;
   Bool_t d0SigB_3pass_4Npass;
   Bool_t d0SigB_3Npass_4pass;

   // List of branches
   TBranch        *b_lep12;   //!
   TBranch        *b_lep34;   //!
   TBranch        *b_lep32;   //!
   TBranch        *b_lep14;   //!
   TBranch        *b_lep1234;   //!
   TBranch        *b_lep1;   //!
   TBranch        *b_lep2;   //!
   TBranch        *b_lep3;   //!
   TBranch        *b_lep4;   //!
   TBranch        *b_IdLep1;   //!
   TBranch        *b_IdLep2;   //!
   TBranch        *b_IdLep3;   //!
   TBranch        *b_IdLep4;   //!
   TBranch        *b_d0SigLep1;   //!
   TBranch        *b_d0SigLep2;   //!
   TBranch        *b_d0SigLep3;   //!
   TBranch        *b_d0SigLep4;   //!
   TBranch        *b_elIDLep1;   //!
   TBranch        *b_elIDLep2;   //!
   TBranch        *b_elIDLep3;   //!
   TBranch        *b_elIDLep4;   //!
   TBranch        *b_muID4Lep;   //!
   TBranch        *b_EvtWeight;   //!
   TBranch        *b_llll_pdgIdSum;   //!
   TBranch        *b_eventNumber;   //!
   TBranch        *b_RunNumber;   //!
   TBranch        *b_l_isIsolFixedCutLoose;   //!
   TBranch        *b_MC_channel_number;   //!
   TBranch        *b_max_el_d0Sig;   //!
   TBranch        *b_max_mu_d0Sig;   //!
   TBranch        *b_Events_all;   //!

   abcd_method(TTree * /*tree*/ =0) : fChain(0) { }
   virtual ~abcd_method() { }
   virtual Int_t   Version() const { return 2; }
   virtual void    Begin(TTree *tree);
   virtual void    SlaveBegin(TTree *tree);
   virtual void    Init(TTree *tree);
   virtual Bool_t  Notify();
   virtual Bool_t  Process(Long64_t entry);
   virtual Int_t   GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
   virtual void    SetOption(const char *option) { fOption = option; }
   virtual void    SetObject(TObject *obj) { fObject = obj; }
   virtual void    SetInputList(TList *input) { fInput = input; }
   virtual TList  *GetOutputList() const { return fOutput; }
   virtual void    SlaveTerminate();
   virtual void    Terminate();

   ClassDef(abcd_method,0);
};

#endif

#ifdef abcd_method_cxx
void abcd_method::Init(TTree *tree)
{
   // The Init() function is called when the selector needs to initialize
   // a new tree or chain. Typically here the branch addresses and branch
   // pointers of the tree will be set.
   // It is normally not necessary to make changes to the generated
   // code, but the routine can be extended by the user if needed.
   // Init() will be called many times when running on PROOF
   // (once per file to be processed).

   // Set object pointer
   lep12 = 0;
   lep34 = 0;
   lep32 = 0;
   lep14 = 0;
   lep1234 = 0;
   lep1 = 0;
   lep2 = 0;
   lep3 = 0;
   lep4 = 0;
   // Set branch addresses and branch pointers
   if (!tree) return;
   fChain = tree;
   fChain->SetMakeClass(1);

   fChain->SetBranchAddress("lep12", &lep12, &b_lep12);
   fChain->SetBranchAddress("lep34", &lep34, &b_lep34);
   fChain->SetBranchAddress("lep32", &lep32, &b_lep32);
   fChain->SetBranchAddress("lep14", &lep14, &b_lep14);
   fChain->SetBranchAddress("lep1234", &lep1234, &b_lep1234);
   fChain->SetBranchAddress("lep1", &lep1, &b_lep1);
   fChain->SetBranchAddress("lep2", &lep2, &b_lep2);
   fChain->SetBranchAddress("lep3", &lep3, &b_lep3);
   fChain->SetBranchAddress("lep4", &lep4, &b_lep4);
   fChain->SetBranchAddress("IdLep1", &IdLep1, &b_IdLep1);
   fChain->SetBranchAddress("IdLep2", &IdLep2, &b_IdLep2);
   fChain->SetBranchAddress("IdLep3", &IdLep3, &b_IdLep3);
   fChain->SetBranchAddress("IdLep4", &IdLep4, &b_IdLep4);
   fChain->SetBranchAddress("d0SigLep1", &d0SigLep1, &b_d0SigLep1);
   fChain->SetBranchAddress("d0SigLep2", &d0SigLep2, &b_d0SigLep2);
   fChain->SetBranchAddress("d0SigLep3", &d0SigLep3, &b_d0SigLep3);
   fChain->SetBranchAddress("d0SigLep4", &d0SigLep4, &b_d0SigLep4);
   fChain->SetBranchAddress("elIDLep1", &elIDLep1, &b_elIDLep1);
   fChain->SetBranchAddress("elIDLep2", &elIDLep2, &b_elIDLep2);
   fChain->SetBranchAddress("elIDLep3", &elIDLep3, &b_elIDLep3);
   fChain->SetBranchAddress("elIDLep4", &elIDLep4, &b_elIDLep4);
   fChain->SetBranchAddress("muID4Lep", &muID4Lep, &b_muID4Lep);
   fChain->SetBranchAddress("EvtWeight", &EvtWeight, &b_EvtWeight);
   fChain->SetBranchAddress("llll_pdgIdSum", &llll_pdgIdSum, &b_llll_pdgIdSum);
   fChain->SetBranchAddress("eventNumber", &eventNumber, &b_eventNumber);
   fChain->SetBranchAddress("RunNumber", &RunNumber, &b_RunNumber);
   fChain->SetBranchAddress("l_isIsolFixedCutLoose", &l_isIsolFixedCutLoose, &b_l_isIsolFixedCutLoose);
   fChain->SetBranchAddress("MC_channel_number", &MC_channel_number, &b_MC_channel_number);
   fChain->SetBranchAddress("max_el_d0Sig", &max_el_d0Sig, &b_max_el_d0Sig);
   fChain->SetBranchAddress("max_mu_d0Sig", &max_mu_d0Sig, &b_max_mu_d0Sig);
   fChain->SetBranchAddress("Events_all", &Events_all, &b_Events_all);
}

Bool_t abcd_method::Notify()
{
   // The Notify() function is called when a new file is opened. This
   // can be either for a new TTree in a TChain or when when a new TTree
   // is started when using PROOF. It is normally not necessary to make changes
   // to the generated code, but the routine can be extended by the
   // user if needed. The return value is currently not used.

   return kTRUE;
}

#endif // #ifdef abcd_method_cxx

Hope that helps otherwise I can explain more what the code is doing.
Thanks

In your “Process” method, you will probably need to use something like this:

if (llll_pdgIdSum == 44) { 44 = "4e"
  if (MC_channel_number == 345709) hCuts_4e_345709->Fill(1, EvtWeight);
  else if (MC_channel_number == 364250) hCuts_4e_364250->Fill(1, EvtWeight);
  else if (MC_channel_number == 364251) hCuts_4e_364251->Fill(1, EvtWeight);
  // ...
} else  if (llll_pdgIdSum == ...) { ... = "2e2m"
  if (MC_channel_number == 345709) hCuts_2e2m_345709->Fill(1, EvtWeight);
  else if (MC_channel_number == 364250) hCuts_2e2m_364250->Fill(1, EvtWeight);
  else if (MC_channel_number == 364251) hCuts_2e2m_364251->Fill(1, EvtWeight);
  // ...
} else  if (llll_pdgIdSum == ...) { ... = "4m"
  if (MC_channel_number == 345709) hCuts_4m_345709->Fill(1, EvtWeight);
  else if (MC_channel_number == 364250) hCuts_4m_364250->Fill(1, EvtWeight);
  else if (MC_channel_number == 364251) hCuts_4m_364251->Fill(1, EvtWeight);
  // ...
}

However, I think you code could be much more clear if, instead of creating a bunch of “TH1F* hCuts_…_…;” pointers, you created a single “TH1F *hCuts[3][3];” array. And then, in the “Process” method, you could simply use something like this:

Int_t i, j;

if (llll_pdgIdSum == 44) i = 0; // 44 = "4e"
else if (llll_pdgIdSum == ...) i = 1; // ... = "2e2m"
else if (llll_pdgIdSum == ...) i = 2; // ... = "4m"
else return kFALSE; // unexpected llll_pdgIdSum

if (MC_channel_number == 345709) j = 0;
else if (MC_channel_number == 364250) j = 1;
else if (MC_channel_number == 364251) j = 2;
else return kFALSE; // unexpected MC_channel_number

hCuts[i][j]->Fill(1, EvtWeight);
if (l_isIsolFixedCutLoose == 15 && d0SigB_allpass) hCuts[i][j]->Fill(2, EvtWeight);
// ...
if((d0SigB_34Npass || d0SigB_3pass_4Npass ||d0SigB_3Npass_4pass) && (l_isIsolFixedCutLoose==12 ||l_isIsolFixedCutLoose==14 || l_isIsolFixedCutLoose==13)) hCuts[i][j]->Fill(5, EvtWeight);

Thanks very much. Yes I will follow your last suggestion.
Cheers,
Diallo

You can create all histograms using something like this:

const char *i_name[] = { "4e", "2e2m", "4m" };
const int j_number[] = { 345709, 364250, 364251 };
for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
    hCuts[i][j] =
      new TH1F(TString::Format("hCuts_%s_%d", i_name[i], j_number[j]),
               "all channel;cut;events", 5, 0.5, 5.5);
    TAxis *a = hCuts[i][j]->GetXaxis();
    a->SetBinLabel(1, "all");
    a->SetBinLabel(2, "A");
    a->SetBinLabel(3, "B");
    a->SetBinLabel(4, "C");
    a->SetBinLabel(5, "D");
  }

Hi Wile_E_Coyote,
Thanks so much this is exactly what I was looking for, it works very well now :slight_smile:
Cheers,
Diallo.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.