Double counting with TTree::Draw/Project

Hi all,

in my ntuple, I have got two branches:

....
*Br   41 :passHLT   : passHLT/I 
*Br   42 :passedTriggers : vector<string>      
....                              *

The first is just a flag for a “good” event, the second is a vector that contains for each event the names of “triggers” belonging to that event.

I would like to plot a flat variable like

*Br    1 :eventNumber : eventNumber/I       

with a TTree::Draw() or TTree::Project call, by selecting only events that pass an OR of two well defined “triggers”, i.e.,
something like:

physics->Draw("eventNumber","(  passHLT == 1 && ( passedTriggers == \"HLT_mu20_iloose_L1MU15\" || passedTriggers == \"HLT_mu50\") )")

but this (as I somehow expected…) does not seem to do what I would like to do.

In fact, just picking a single event where both the two above “triggers” are there:

root [2] physics->Scan("passedTriggers:eventNumber","( eventNumber == 8312257 && passHLT == 1 )","colsize=25")
*******************************************************************************
*    Row   * Instance *            passedTriggers *               eventNumber *
*******************************************************************************
*        8 *        0 *    HLT_mu20_iloose_L1MU15 *            8312257 *
*        8 *        1 *                  HLT_mu50 *                     8312257 *
*******************************************************************************

, when drawing a hist for eventNumber I get the event counted twice in the histogram. Guess the reason is that the cut expression evaluates to true twice.

Is there a way to avoid this double counting? Or is just something that goes beyond the scope of Draw/Project?

I see that in root.cern.ch/doc/master/classTT … TTree:Draw there are some special variables and functions available, but I can’t get my head around my specific use case.
Anything that sounds like

would be awesome :wink:

Thanks in advance for the help!

Marco

Hi Marco,

It is likely that this:physics->Draw("eventNumber","( passHLT == 1 && 0 < Sum$( (passedTriggers == \"HLT_mu20_iloose_L1MU15\") + (passedTriggers == \"HLT_mu50\") ) )")will do what you want.

Cheers,
Philippe.

Hi Philippe,

indeed that does the trick! Thanks very much :smiley:

BTW, I tried in the meantime to make a custom function:

#include <vector>
#include <iostream>
#include <sstream>
#include <algorithm>

bool containsAny( const std::vector<std::string>& inList = std::vector<string>(), const std::string& checkStr = "" )
{

  std::vector<std::string> checkList;

  std::string token;
  std::istringstream ss(checkStr);
  while ( std::getline(ss, token, ',') ) {
    checkList.push_back(token);
  }

  for ( auto itr : checkList ) {
    if ( std::find(inList.begin(), inList.end(), itr) != inList.end() ) { return true; }
  }

  return false;
}

, then load it in my PyROOT macro and use it like in the following:

physics->Draw("eventNumber","(  passHLT == 1 && containsAny(passedTriggers, \"HLT_mu20_iloose_L1MU15,HLT_mu50\") )")

However, that gives me an error:

Error in <TTreeFormula::Compile>: Bad numerical expression

Is TTreeFormula unable to work with string parameters?

Cheers

Marco

Hi,

TTreeFormula can only call function that takes simple numerical arguments and thus no strings nor any sort of collections.

Cheers,
Philippe.