Too many operators for the TTree::Project conditions

Hi everyone,

In my code, I have tree->Project(Form("Hist %i", i), "Bs_MCORR", ccbarCondSoftFake); where ccbarCondSoftFake is a very long TString with a large amount of operators. But, I obtain the following error :

Error in <TTreeFormula::Compile>:  Too many operators !

Can someone help me with that ?

Thanks !

Hi @Alo,
thank you for posting on the ROOT forum!
It looks like the codebase that raises this error is related to ROOT v5, can you please tell what version of ROOT you’re using? Also, can you please provide a minimal code snipped to reproduce your error?

Cheers,
Monica

Hi,

This is my ROOT version :

   ------------------------------------------------------------------
  | Welcome to ROOT 6.30/00                        https://root.cern |
  | (c) 1995-2023, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for macosxarm64 on Nov 06 2023, 16:07:43                   |
  | From heads/v6-30-patches@tags/v6-30-00                           |
  | With Apple clang version 15.0.0 (clang-1500.0.40.1)              |
  | Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q'  |
   ------------------------------------------------------------------

Here is the header where I’m defining the conditions :
truthmatch_Conds.h (53.2 KB)

And here is the .C file where I’m calling the ccbarCondSoftFake condition :
Bs_MCORR_Plot.C (6.3 KB)

Thanks !

Can you provide the content of the string ccbarCondSoftFake ? It would help me to replicate your error with a different root file.

The content of ccbarCondSoftFake is in the truthmatch_Conds.h line 201

The maximum number of operators in TTreeFormula is fixed at ROOT compile time (I guess you could hack the ROOT to increase it if you wanted to).

To go beyond the level of complexity supported by TTreeFormula you have too avenue:

  • Make a (friend) tree with some of the partial results of the formula stored as new branches
  • Move to using RDataFrame instead of Project.
1 Like

Hi @pcanal,

Thanks for the tips. I tried to implement RDataFrame in Bs_MCORR_Plot.C (updated), but I obtain this errors in the terminal.

root [0] 
Processing Bs_MCORR_Plot.C...
In module 'ROOTDataFrame':
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterface.hxx:219:63: error: no type named 'arg_types' in 'ROOT::Detail::CallableTraitsImpl<TString, false>'
      using ColTypes_t = typename TTraits::CallableTraits<F>::arg_types;
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
/Users/acaillet/Documents/PhD/Root_stage_M2/Tools_Codes/Bs_MCORR_Plot.C:45:22: note: in instantiation of function template specialization 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager, void>::Filter<TString, 0>' requested here
        auto ht = df.Filter(conds[i]).Histo1D(h, "Bs_MCORR");
                     ^
In module 'ROOTDataFrame':
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/InterfaceUtils.hxx:311:62: error: no type named 'ret_type' in 'ROOT::Detail::CallableTraitsImpl<TString, false>'
   using FilterRet_t = typename RDF::CallableTraits<Filter>::ret_type;
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterface.hxx:218:20: note: in instantiation of function template specialization 'ROOT::Internal::RDF::CheckFilter<TString>' requested here
      RDFInternal::CheckFilter(f);
                   ^
/Users/acaillet/Documents/PhD/Root_stage_M2/Tools_Codes/Bs_MCORR_Plot.C:45:22: note: in instantiation of function template specialization 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager, void>::Filter<TString, 0>' requested here
        auto ht = df.Filter(conds[i]).Histo1D(h, "Bs_MCORR");
                     ^
In module 'ROOTDataFrame':
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RFilter.hxx:58:60: error: no type named 'arg_types' in 'ROOT::Detail::CallableTraitsImpl<TString, false>'
   using ColumnTypes_t = typename CallableTraits<FilterF>::arg_types;
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/include/c++/v1/__type_traits/is_convertible.h:30:66: note: in instantiation of template class 'ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>' requested here
    : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
                                                                 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/include/c++/v1/__type_traits/disjunction.h:28:30: note: in instantiation of template class 'std::is_convertible<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager> *, ROOT::Detail::RDF::RNodeBase *>' requested here
      typename _OrImpl<!bool(_First::value) && sizeof...(_Rest) != 0>::template _Result<_First, _Rest...>;
                             ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/include/c++/v1/__type_traits/disjunction.h:44:1: note: in instantiation of template type alias '_Result' requested here
using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>;
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/include/c++/v1/__memory/shared_ptr.h:385:7: note: in instantiation of template type alias '_Or' requested here
    : _Or<
      ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/include/c++/v1/__memory/shared_ptr.h:641:47: note: in instantiation of template class 'std::__compatible_with<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, ROOT::Detail::RDF::RNodeBase>' requested here
    template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
                                              ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/include/c++/v1/__memory/shared_ptr.h:643:5: note: in instantiation of default argument for 'shared_ptr<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager> >' required here
    shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterfaceBase.hxx:185:85: note: while substituting deduced template arguments into function template 'shared_ptr' [with _Yp = ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, $1 = (no value)]
      auto upcastNodeOnHeap = RDFInternal::MakeSharedOnHeap(RDFInternal::UpcastNode(proxiedPtr));
                                                                                    ^
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterface.hxx:1494:14: note: in instantiation of function template specialization 'ROOT::RDF::RInterfaceBase::CreateAction<ROOT::Internal::RDF::ActionTags::Histo1D, ROOT::Detail::RDF::RInferredType, TH1D, ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, TH1D, 0>' requested here
      return CreateAction<RDFInternal::ActionTags::Histo1D, V>(validatedColumns, h, h, fProxiedPtr);
             ^
/Users/acaillet/Documents/PhD/Root_stage_M2/Tools_Codes/Bs_MCORR_Plot.C:45:39: note: in instantiation of function template specialization 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, void>::Histo1D<ROOT::Detail::RDF::RInferredType>' requested here
        auto ht = df.Filter(conds[i]).Histo1D(h, "Bs_MCORR");
                                      ^
In module 'ROOTDataFrame':
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterfaceBase.hxx:188:92: error: cannot initialize object parameter of type 'const ROOT::Detail::RDF::RNodeBase' with an expression of type 'std::shared_ptr<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager> >::element_type' (aka 'ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>')
                                                                             fColRegister, proxiedPtr->GetVariations());
                                                                                           ^~~~~~~~~~~~
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterface.hxx:1494:14: note: in instantiation of function template specialization 'ROOT::RDF::RInterfaceBase::CreateAction<ROOT::Internal::RDF::ActionTags::Histo1D, ROOT::Detail::RDF::RInferredType, TH1D, ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, TH1D, 0>' requested here
      return CreateAction<RDFInternal::ActionTags::Histo1D, V>(validatedColumns, h, h, fProxiedPtr);
             ^
/Users/acaillet/Documents/PhD/Root_stage_M2/Tools_Codes/Bs_MCORR_Plot.C:45:39: note: in instantiation of function template specialization 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, void>::Histo1D<ROOT::Detail::RDF::RInferredType>' requested here
        auto ht = df.Filter(conds[i]).Histo1D(h, "Bs_MCORR");
                                      ^
In module 'std' imported from input_line_1:1:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/include/c++/v1/__memory/shared_ptr.h:644:11: error: cannot initialize a member subobject of type 'std::shared_ptr<ROOT::Detail::RDF::RNodeBase>::element_type *' (aka 'ROOT::Detail::RDF::RNodeBase *') with an lvalue of type 'std::shared_ptr<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager> >::element_type *const' (aka 'ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager> *const')
        : __ptr_(__r.__ptr_),
          ^      ~~~~~~~~~~
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterfaceBase.hxx:185:85: note: in instantiation of function template specialization 'std::shared_ptr<ROOT::Detail::RDF::RNodeBase>::shared_ptr<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, void>' requested here
      auto upcastNodeOnHeap = RDFInternal::MakeSharedOnHeap(RDFInternal::UpcastNode(proxiedPtr));
                                                                                    ^
/opt/homebrew/Cellar/root/6.30.02_1/include/root/ROOT/RDF/RInterface.hxx:1494:14: note: in instantiation of function template specialization 'ROOT::RDF::RInterfaceBase::CreateAction<ROOT::Internal::RDF::ActionTags::Histo1D, ROOT::Detail::RDF::RInferredType, TH1D, ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, TH1D, 0>' requested here
      return CreateAction<RDFInternal::ActionTags::Histo1D, V>(validatedColumns, h, h, fProxiedPtr);
             ^
/Users/acaillet/Documents/PhD/Root_stage_M2/Tools_Codes/Bs_MCORR_Plot.C:45:39: note: in instantiation of function template specialization 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RFilter<TString, ROOT::Detail::RDF::RLoopManager>, void>::Histo1D<ROOT::Detail::RDF::RInferredType>' requested here
        auto ht = df.Filter(conds[i]).Histo1D(h, "Bs_MCORR");
                                      ^

How did you transform the cond[i] strings from the TTreeFormula/TTree::Draw syntax to the RDataFrame syntax? (I.e. give a concrete example of before and after).

I changed nothing. My cond[i] has the form of the conds present in truthmatch_Conds.h.

Note that the syntax for RDataFrame is different from the syntax for TTreeFormula except for the simple cases ( arithmetic expression of columns/branches that are simple numerical type (no array or collection). Refer to the RDataFrame documentation for more details.

However the first hurdle is that RDataFrame does not automatically convert a TString into one of its input. Try

   auto ht = df.Filter(conds[i].Data()).Histo1D(h, "Bs_MCORR");
1 Like

Ok, I tried the .Data() and the loop on i is working now but I am obtaining a *** Break *** segmentation violation. With std::cout, I scouted the problematic lines. But even if I am deleting them, I am obtaining a blank canvas with no error. I think there is a problem with the histograms I am creating with RDataFrame. Here is the new code : Bs_MCORR_Plot.C

Try:

        ROOT::RDataFrame df(*tree);
        auto ht = df.Filter(conds[i].Data()).Histo1D(h, "Bs_MCORR");
        histVec[i] = ht.GetPtr();
        histVec[i]->SetDirectory(nullptr);

By passing the filename to RDataFrame, it opens the file a second time. Any histogram gets attached (and shared owed) to the “current” file which in this case is the one created (and then
deleted) by RDataFrame; that deletion lead to the deletions of the histogram.

The code snippet above those:

  • avoid second opening of the file
  • detach the histogram from the current file

I tried it, but I still obtain the same blank canvas : Bs_MCORR_Plot.C

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

humm … I seem to be able to reproduce the issue …

The source of the behavior is that the result of RDataFrame's Histo1D (ROOT::RDF::RResultPtr<TH1D>) which is stored in the variable ht in the last example, is the owner of the histogram and thus deletes at the end of the scope. So if you use:

    ROOT::RDF::RResultPtr<TH1D> histVec[sampNumb];
and
    histVec[i] = ht;

you will get the histogram properly drawn in the Canvas and if you immediate saving (using the commented out code) you will get the right result. The canvas will still empty itself out at the end of the function Bs_MCORR_Plot_Func as the array of RResultPtr will go out of scope and delete the histogram.

To also have the histograms survive the end of the function (and thus see them interactively) you have 2 choices:

  • make the array of RResultPtr a global variable
  • copy the histograms before adding them to the THStack (and to avoid a leak at the end of the process you would also need to add them to a global list (eg. ROOT’s)).