Optimizing existing code to work faster

Hi guys!

I have a code with name CompareHitsToPatterns, which basically reads in two files
“HitWords_tower0_SSW16.root” and “CollectedPatterns_tower0_SSW16_0.root”. Inside HitWords is a leaf called “HitWords” and inside Patterns is a leaf “patternHitwords”. The idea is that this code match hitwords to patterns hitwords and yielding true or false. The problem is that this program works really slow! The code is

#include "../Source/Timer.h"
#include "TFile.h"
#include "TTree.h"
#include "TH1.h"
#include "TROOT.h"
#include <TEfficiency.h>

void CompareHitsToPatterns(){
  TFile    PatternFile("out/CollectedPatterns/CollectedPatterns_tower0_SSW16_0.root");
  TTree  * PatternTree = (TTree*) PatternFile.Get("patternTree");

  TFile    HitFile("out/CollectedHits/HitWords_tower0_SSW16.root");
  TTree  * HitTree = (TTree*) HitFile.Get("HitWords");
  // Preparing the containers to be filled with data from the tree:
  Long64_t HitWord  = 0;
  Int_t HitLayer = 0;
  Int_t EventNumber = 0;
  Long64_t PatternHitWords[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

  Double_t trackPt = 0;
  Double_t truthPt = 0;

  TH1F * matchedPt = new TH1F("matchedPt","p_{T} of matched patterns;p_{T} [GeV];n;",30,0,30);
  TEfficiency* PtEff = new TEfficiency("eff","my eff;trackPt;#epsilon",600,0,10);

  // Linking the local variables to the tree branches
  HitTree->SetBranchAddress("HitWord", &HitWord);
  HitTree->SetBranchAddress("HitLayer", &HitLayer);
  HitTree->SetBranchAddress("EventNumber", &EventNumber);
  HitTree->SetBranchAddress("trackPt", &trackPt);
  HitTree->SetBranchAddress("truthPt", &truthPt);

  PatternTree->SetBranchAddress("HitWord_5", &PatternHitWords[5]);
  PatternTree->SetBranchAddress("HitWord_7", &PatternHitWords[7]);
  PatternTree->SetBranchAddress("HitWord_9", &PatternHitWords[9]);
  PatternTree->SetBranchAddress("HitWord_10", &PatternHitWords[10]);
  PatternTree->SetBranchAddress("HitWord_11", &PatternHitWords[11]);
  PatternTree->SetBranchAddress("HitWord_12", &PatternHitWords[12]);
  PatternTree->SetBranchAddress("HitWord_13", &PatternHitWords[13]);
  PatternTree->SetBranchAddress("HitWord_14", &PatternHitWords[14]);

  // Create a way to see if the pattern was matched

  Int_t nMatchedPatterns = 0;
  Long64_t nEntriesPatternTree = PatternTree->GetEntries();
  Long64_t nEntriesHitTree = HitTree->GetEntries();

  HitTree ->  GetEntry(nEntriesHitTree-1);
  Int_t eventMax = EventNumber;
  cout << "maximum eventnr: " << eventMax << "\n"; 
  for(Int_t event = 0; event < eventMax; event++){

    for (Long64_t iPattern = 0; iPattern < nEntriesPatternTree; iPattern++) {


      Bool_t MatchedHits[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
      for(Long64_t iHit = 0; iHit < nEntriesHitTree; iHit++){

  	if( EventNumber < event) continue;
  	if( EventNumber > event) break;
	// std::cout << "Comparing patterHitWord " << PatternHitWords[HitLayer] << " to ";
	// std::cout << " hit " << HitWord << endl;
  	MatchedHits[HitLayer] = MatchedHits[HitLayer] || ( PatternHitWords[HitLayer] == HitWord );
      if ((MatchedHits[5]==true) && 
  	  (MatchedHits[7]==true) && 
  	  (MatchedHits[9]==true) &&
  	  (MatchedHits[10]==true) && 
  	  (MatchedHits[11]==true) && 
  	  (MatchedHits[12]==true) &&
  	  (MatchedHits[13]==true) && 
	  PtEff->Fill(true, trackPt);
      else PtEff->Fill(false, trackPt);
    cout << "One event checked; " << nMatchedPatterns << " was matched." << endl;

  cout << nMatchedPatterns << " patterns were matched" << endl;

  TCanvas* c1 = new TCanvas("example","",600,400);
  PtEff -> Draw(); 
  TFile * resultFile = new TFile("out/MatchingResults/MatchingResultsStd_visible_SSW16.root","Recreate");
  PtEff -> Write();


Any who has any idea where the slowness comes from or have any tips on flags to have when i compile ?

ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided

Maybe using RDataFrame or TTreeReader could help?

Using RDataFrame or TTreeReader would let you automate one missing part in the code you pasted. Namely you do not need to read the while entry/files:


but rather you can read just the branch you need

TBranch *br_HitWord_5 = nullptr;
PatternTree->SetBranchAddress("HitWord_5", &PatternHitWords[5], &br_HitWord_5);
auto brEntry = PatternTree->LoadTree(iPattern);


Also I am not sure why your have 3 nested loop where 2 should be enough … maybe:

for(Long64_t iHit = 0; iHit < nEntriesHitTree; iHit++){
    for (Long64_t iPattern = 0; iPattern < nEntriesPatternTree; iPattern++) {

In original code the whole HitTree is read nEntriesHitTree * nEntriesPatternTree times …

Hello ! Thanks for all of your replies, the issue is solved. The problem was basically i was re-reading stuff that was unnecessary. To see this, one actually need to see the corresponding trees and their structures.

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