Table of Contents

Storing Monte Carlo particle numbers in a file

Idea

When analyzing signal or background using Monte Carlo truth information, it may be useful to check the real identity of a particle that was considered a Kaon, a Muon, etc.

The following script loops through the whole tree, calculates the percentage of the respective particle and saves the output in a textfile. It needs as input the tree with the truth-information (e.g. in an nTuple) and the name of the variable. Furthermore, the name of the output-file can be specified.

Code

The code was written for a class which was added to ROOT. It should be straightforward to use it in a macro.

.hh File

Add the following prototype to your header-file:

 void storeMCNumbers(TTree* tree, const char* variablename, const char* filename = "BG_cat.txt");

The last argument in the prototype gives the default name of the textfile, that is used as an output.

.cc File

Add the following method to your .cc-File (mind the yourclass!):

void yourclass::storeMCNumbers(TTree* tree, const char* variablename, const char* filename ){
  
  // --------------------------------------------------------------------------------
  // -- Simple method to read out a histogram containing PID-numbers for particles (x-axis) and their
  // -- frequency (y-axis)
  // -- Needed inputs are: The tree containing the information and the name for the variable in the
  // -- tree. Optionally, the name of the output file can be given as the last argument.
  // --------------------------------------------------------------------------------

  gStyle->SetOptTitle(1);

  // -- Declaring some numbers and ranges
  int nbins = 2000001;
  int min = -1000000;
  int max = 1000000;
  
  // -- Creating a histogram to temporarily save the information
  TH1I* histo = new TH1I("histo", "histo", nbins, min, max);
  char out[1000];
  sprintf(out, "%s>>%s",variablename,"histo");
  tree->Draw(out, "","goff");
  

  // -- Declare a multimap to automatically sort the PID-numbers according to their frequency in %
  multimap<double,int> testmap;
  multimap<double,int>::iterator ipos;
  for(int i = min; i <= max ; i++){

    if(histo->GetBinContent(i  + TMath::Abs(min)  ) == 0) continue;
    
    std::pair<double,int> dummy;
    dummy.first = (histo->GetBinContent(i + TMath::Abs(min) ) / histo->Integral()) * 100;
    dummy.second = i-1;
    testmap.insert(dummy);
  }
  
  // -- Open a file to save the output
  // -- Note: The "ios::app" appends the output at the end of the existing file!
  fstream PIDfile(filename, ios::out | ios::app);
  
  if(!PIDfile.is_open()){
    cout << "Could not open the output file" << endl;
  }
  

  PIDfile << "\n";
  PIDfile << " ====================== " << endl;
  PIDfile << " --> " << variablename << endl;
  PIDfile << " ====================== " << endl;

  for(ipos = testmap.begin(); ipos != testmap.end(); ++ipos){

    PIDfile << "Percentage " << ipos->first << "\t Particle Number " 
           << ipos->second << endl;
  }

  
  PIDfile.close();
  delete histo;
  
}

Notes

If the output-file already exists, the output will be appended. This is useful if you call the method several times for different particles and want to store everything in one file. If you don't like this behaviour, delete the | ios::app in the code.