Cannot pass more than 9 arguments with TMVA::DataLoader::AddVariable

Hi.

I am using a BDT to separate signal from background. When trying to define variables not available in the input trees, I have found that the new variables cannot have more than 9 arguments. To be more precise, now I am defining a function (detajjl) which has 9 parameters. I would like to define another function (let’s call it detajjll) which takes 12 parameters, but the code crashes without a meaningful error. Can somebody help?

Thanks,
Jónatan

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//  root -l TMVAClassification_VH2j.C\(\"BDT\"\)
//  root -l TMVAClassification_VH2j.C\(\"BDT,BDT4,BDT6,BDT12\"\)
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include <cstdlib>
#include <iostream>
#include <map>
#include <string>

#include "TChain.h"
#include "TFile.h"
#include "TLorentzVector.h"
#include "TObjString.h"
#include "TPluginManager.h"
#include "TROOT.h"
#include "TString.h"
#include "TSystem.h"
#include "TTree.h"

#include "TMVA/DataLoader.h"
#include "TMVA/Factory.h"
#include "TMVA/TMVAGui.h"
#include "TMVA/Tools.h"


float detajjl(float jet1_pt, float jet1_eta, float jet1_phi,
	      float jet2_pt, float jet2_eta, float jet2_phi,
	      float lep1_pt, float lep1_eta, float lep1_phi)
{
  TLorentzVector jet1_tlv;
  TLorentzVector jet2_tlv;
  TLorentzVector lep1_tlv;

  jet1_tlv.SetPtEtaPhiM(jet1_pt, jet1_eta, jet1_phi, 0.);
  jet2_tlv.SetPtEtaPhiM(jet2_pt, jet2_eta, jet2_phi, 0.);
  lep1_tlv.SetPtEtaPhiM(lep1_pt, lep1_eta, lep1_phi, 0.);

  return fabs((jet1_tlv + jet2_tlv).Eta() - lep1_tlv.Eta());
}


void TMVAClassification_VH2j(TString myMethodList = "") 
{
  // Load the library
  TMVA::Tools::Instance();

  // Default MVA methods to be trained + tested
  std::map<std::string,int> Use;

  Use["BDT"]   = 0;  // Uses Adaptive Boost
  Use["BDT4"]  = 1;  // Uses Adaptive Boost
  Use["BDT6"]  = 0;  // Uses Adaptive Boost
  Use["BDT12"] = 1;  // Uses Adaptive Boost

  if (myMethodList != "") {

    for (std::map<std::string,int>::iterator it=Use.begin(); it!=Use.end(); it++) it->second = 0;

    std::vector<TString> mlist = TMVA::gTools().SplitString(myMethodList, ',');

    for (UInt_t i=0; i<mlist.size(); i++) {

      std::string regMethod(mlist[i]);

      if (Use.find(regMethod) == Use.end()) {

	std::cout << " Method \"" << regMethod << "\" not known in TMVA under this name. Choose among the following:" << std::endl;

	for (std::map<std::string,int>::iterator it=Use.begin(); it!=Use.end(); it++) std::cout << it->first << " ";

	std::cout << std::endl;

	return;
      }

      Use[regMethod] = 1;
    }
  }


  // Output file
  //----------------------------------------------------------------------------
  TString outfileName("VH2j_TMVA.root");

  TFile* outputFile = TFile::Open(outfileName, "recreate");


  // Create the factory object. The first argument is the base of the name of all the weight files
  //----------------------------------------------------------------------------
  TString factoryName("TMVAClassification_VH2j");

  TMVA::Factory* factory = new TMVA::Factory(factoryName, outputFile,
					     "!V:!Silent:Color:DrawProgressBar:AnalysisType=Classification");

  TMVA::DataLoader* dataloader = new TMVA::DataLoader("dataset");

  dataloader->AddVariable("mll",          'F');
  dataloader->AddVariable("mjj",          'F');
  dataloader->AddVariable("mth",          'F');
  dataloader->AddVariable("Lepton_pt[0]", 'F');
  dataloader->AddVariable("Lepton_pt[1]", 'F');
  dataloader->AddVariable("detajj",       'F');
  dataloader->AddVariable("detajjl:=detajjl(CleanJet_pt[0],CleanJet_eta[0],CleanJet_phi[0],CleanJet_pt[1],CleanJet_eta[1],CleanJet_phi[1],Lepton_pt[0],Lepton_eta[0],Lepton_phi[0])", 'F');


  // Input files
  //----------------------------------------------------------------------------
  std::vector<TFile*> InputFiles_signal;
  std::vector<TFile*> InputFiles_background;

  InputFiles_signal.clear();
  InputFiles_background.clear();

  for (UInt_t k=0; k<5; k++) {
    InputFiles_signal.push_back(TFile::Open(Form("signal__part%d.root", k)));
    InputFiles_background.push_back(TFile::Open(Form("background__part%d.root", k)));
  }


  // Apply cuts on the signal and background samples (can be different)
  //----------------------------------------------------------------------------
  TCut mycuts;
  TCut mycutb;

  mycuts = "MET_pt > 20 \
            && Lepton_pt[0] > 25 \
            && Lepton_pt[1] > 10 \
            && abs(detajj) < 3.5 \
            && (mth > 60 && mth < 125)";

  mycutb = mycuts;

  
  // Create factory for signal and background samples
  double tmpWeight = 1.;

  for (UInt_t i=0; i<InputFiles_signal.size(); ++i) {
    TTree* tmpsTree = (TTree*)InputFiles_signal.at(i)->Get("Events");
    dataloader->AddSignalTree(tmpsTree, tmpWeight);
  }

  for (UInt_t k=0; k<InputFiles_background.size(); ++k) {
    TTree* tmpbTree = (TTree*)InputFiles_background.at(k)->Get("Events");
    dataloader->AddBackgroundTree(tmpbTree, tmpWeight);
  }

  dataloader->SetSignalWeightExpression    ("XSWeight");
  dataloader->SetBackgroundWeightExpression("XSWeight");

  dataloader->PrepareTrainingAndTestTree(mycuts, mycutb, "SplitMode=Random::SplitSeed=10:NormMode=EqualNumEvents");


  // Book MVA methods
  //----------------------------------------------------------------------------
  if (Use["BDT"]) factory->BookMethod(dataloader, TMVA::Types::kBDT, "BDT",
				      "!H:!V:NTrees=250:MinNodeSize=0.5%:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.1:SeparationType=GiniIndex:nCuts=20");

  if (Use["BDT4"]) factory->BookMethod(dataloader, TMVA::Types::kBDT, "BDT4",
				       "!H:!V:NTrees=800:MinNodeSize=0.5%:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.1:SeparationType=GiniIndex:nCuts=20");

  if (Use["BDT6"]) factory->BookMethod(dataloader, TMVA::Types::kBDT, "BDT6",
				       "!H:!V:NTrees=500:MinNodeSize=2.5%:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.1:SeparationType=GiniIndex:nCuts=500");

  if (Use["BDT12"]) factory->BookMethod(dataloader, TMVA::Types::kBDT, "BDT12",
					"!H:!V:NTrees=500:MinNodeSize=0.5%:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.2:SeparationType=GiniIndex:nCuts=20");


  // Now you can tell the factory to train, test, and evaluate the MVAs
  //----------------------------------------------------------------------------
  factory->TrainAllMethods();
  factory->TestAllMethods();
  factory->EvaluateAllMethods();    


  // Save the output
  //----------------------------------------------------------------------------
  outputFile->Close();

  delete factory;
  delete dataloader;

  
  // Launch the GUI for the root macros
  //----------------------------------------------------------------------------
  if (!gROOT->IsBatch()) TMVA::TMVAGui(outfileName);
}

Hi,

I think this is a bug in defining the expression (TTreeForumula) for the Tree. The bug should have been fixed now, can you please try with the ROOT master version ?

Lorenzo

Hi Lorenzo.

Thank you for your email. I have tried with ROOT 6.16/00 (Built for linuxx8664gcc on Jan 23 2019) and it crashes. I’m using the expression below,

float detajjll(float jet1_pt, float jet1_eta, float jet1_phi,
               float jet2_pt, float jet2_eta, float jet2_phi,
               float lep1_pt, float lep1_eta, float lep1_phi,
               float lep2_pt, float lep2_eta, float lep2_phi)
{
  TLorentzVector jet1_tlv;
  TLorentzVector jet2_tlv;
  TLorentzVector lep1_tlv;
  TLorentzVector lep2_tlv;

  jet1_tlv.SetPtEtaPhiM(jet1_pt, jet1_eta, jet1_phi, 0.);
  jet2_tlv.SetPtEtaPhiM(jet2_pt, jet2_eta, jet2_phi, 0.);
  lep1_tlv.SetPtEtaPhiM(lep1_pt, lep1_eta, lep1_phi, 0.);
  lep2_tlv.SetPtEtaPhiM(lep2_pt, lep2_eta, lep2_phi, 0.);

  return fabs((jet1_tlv + jet2_tlv).Eta() - (lep1_tlv + lep2_tlv).Eta());
}

and this is where I call it,

dataloader->AddVariable("detajjll:=detajjll(CleanJet_pt[0],CleanJet_eta[0],CleanJet_phi[0],CleanJet_pt[1],CleanJet_eta[1],CleanJet_phi[1],Lepton_pt[0],Lepton_eta[0],Lepton_phi[0],Lepton_pt[1],Lepton_et\
a[1],Lepton_phi[1])", 'F');

Thanks,
Jonatan

Hi,

I think @moneta was asking if you have the possibility to try running the version available here: https://github.com/root-project/root

This requires compiling the ROOT source code on your local machine which can be time consuming. Instructions can be found here: https://root.cern/building-root

Cheers,
Kim