TChain and TTreeFormula

Hello experts,

When I try to use TChain and TTreeFormula, I get segmentation violation. But if I just add one root file , it will be OK!

tree_data = ROOT.TChain(“Electrons_All”)
tree_data.Add(“/afs/cern.ch/user/z/zgao/eos/my_fudge_factor/Run3/user.zgao.data22_13p6TeV_v1.tp-analyse-example_zmass-data22_13p6TeV-EGAM1- grp22_v01_p5538_20231207_110000_ANALYSIS.root/*.root”)

seven_eta_cut_select_temp=[“primary_cluster_be2_abseta__NOSYS[0]<0.6”,
“primary_cluster_be2_abseta__NOSYS[0]>0.6 && primary_cluster_be2_abseta__NOSYS[0]<0.80”,
“primary_cluster_be2_abseta__NOSYS[0]>0.80 && primary_cluster_be2_abseta__NOSYS[0]<1.15”,
“primary_cluster_be2_abseta__NOSYS[0]>1.15 && primary_cluster_be2_abseta__NOSYS[0]<1.37”,
“primary_cluster_be2_abseta__NOSYS[0]>1.52 && primary_cluster_be2_abseta__NOSYS[0]<1.81”,
“primary_cluster_be2_abseta__NOSYS[0]>1.81 && primary_cluster_be2_abseta__NOSYS[0]<2.01”,
“primary_cluster_be2_abseta__NOSYS[0]>2.01 && primary_cluster_be2_abseta__NOSYS[0]<2.37”,
]

seven_eta_cut_select_data=[ ROOT.TTreeFormula(f"seven_eta_{i}",seven_eta_cut_select_temp[i],tree_data) for i in range(len(seven_eta_cut_select_temp))]
for series in range(len(seven_eta_cut_select_data)):
tree_data.SetNotify(seven_eta_cut_select_data[series])

for obj in seven_eta_cut_select_data:
obj.UpdateFormulaLeaves()

for entry in range(entries_data):
tree_data.GetEntry(entry)

if twelve_pt_cut_select_data[int(args.input_pt)].EvalInstanceLD() != 1 :continue

think.py (20.4 KB)
The whole codes have been added ,the first 148 lines.

Could you please give me some advice how to address it ? I have used SetNotify() and UpdataFormulaLeaves(). But they don’t work. Thank you veru much !

Dear Xiang,

Thanks for the post. I am sorry you stumble in a crash.
I understand that if you take your code and run it without input you get a segfault but if you add a to the input chain at least one file, then it runs fine: is this correct? Please correct me if I am wrong!

If I am correct, what I could suggest is to add a protection based on the number of input files to continue your analysis.

Unrelated, perhaps, to that: I went through your analysis script - very sophisticated, thanks for sharing it. Did you consider or try to express the flow with RDataFrame?
That could greatly simplify your code, make it more concise and allow you to profit from optimisations such as multithreading.

Cheers,
Danilo

Hello Danilo,

Thank you for your patient answer!

I’m considering code with input files. I mean if I just add one root file to my chain. It will run successfully. But If I add more than one root file to the chain . It will have a segmentation violation even with two files.

By searching , i find several question about it .

So I think I should consider how to use TTreeformula with TChain.

By the way , I can add the error information.
I’m sorry for the long error informaiton. Thank you very much again!

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
    gdb.printing.register_pretty_printer(gdb.current_objfile(),
    gdb.printing.register_pretty_printer(gdb.current_objfile(),

Thread 2 (Thread 0x7f4f8e202700 (LWP 18484)):
#0  0x00007f4fa8b10de2 in pthread_cond_timedwait

GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00007f4fa8e662e8 in take_gil () from /lib64/libpython3.6m.so.1.0
#2  0x00007f4fa8e66429 in PyEval_RestoreThread () from /lib64/libpython3.6m.so.1.0
#3  0x00007f4fa8ebcbd5 in time_sleep () from /lib64/libpython3.6m.so.1.0
#4  0x00007f4fa8e0722e in _PyCFunction_FastCallDict () from /lib64/libpython3.6m.so.1.0
#5  0x00007f4fa8e7214f in call_function () from /lib64/libpython3.6m.so.1.0
#6  0x00007f4fa8e66a87 in _PyEval_EvalFrameDefault () from /lib64/libpython3.6m.so.1.0
#7  0x00007f4fa8e725ed in PyEval_EvalCodeEx () from /lib64/libpython3.6m.so.1.0
#8  0x00007f4fa8de1bc2 in function_call () from /lib64/libpython3.6m.so.1.0
#9  0x00007f4fa8dc9963 in PyObject_Call () from /lib64/libpython3.6m.so.1.0
#10 0x00007f4fa8e68745 in _PyEval_EvalFrameDefault () from /lib64/libpython3.6m.so.1.0
#11 0x00007f4fa8e71f3a in fast_function () from /lib64/libpython3.6m.so.1.0
#12 0x00007f4fa8e72273 in call_function () from /lib64/libpython3.6m.so.1.0
#13 0x00007f4fa8e66a87 in _PyEval_EvalFrameDefault () from /lib64/libpython3.6m.so.1.0
#14 0x00007f4fa8e71f3a in fast_function () from /lib64/libpython3.6m.so.1.0
#15 0x00007f4fa8e72273 in call_function () from /lib64/libpython3.6m.so.1.0
#16 0x00007f4fa8e66a87 in _PyEval_EvalFrameDefault () from /lib64/libpython3.6m.so.1.0
#17 0x00007f4fa8e7328a in _PyFunction_FastCallDict () from /lib64/libpython3.6m.so.1.0
#18 0x00007f4fa8dc9bde in _PyObject_FastCallDict () from /lib64/libpython3.6m.so.1.0
#19 0x00007f4fa8dc9cf1 in _PyObject_Call_Prepend () from /lib64/libpython3.6m.so.1.0
#20 0x00007f4fa8dc9963 in PyObject_Call () from /lib64/libpython3.6m.so.1.0
#21 0x00007f4fa8f031d2 in t_bootstrap () from /lib64/libpython3.6m.so.1.0
#22 0x00007f4fa8f00684 in pythread_wrapper () from /lib64/libpython3.6m.so.1.0
#23 0x00007f4fa8b0cea5 in start_thread () from /lib64/libpthread.so.0
#24 0x00007f4fa812cb0d in clone () from /lib64/libc.so.6

Thread 1 (Thread 0x7f4fa9431740 (LWP 18437)):
#0  0x00007f4fa80f3659 in waitpid () from /lib64/libc.so.6
#1  0x00007f4fa8070f62 in do_system () from /lib64/libc.so.6
#2  0x00007f4fa8071311 in system () from /lib64/libc.so.6
#3  0x00007f4fa0db03fc in TUnixSystem::StackTrace() () from /usr/lib64/root/libCore.so
#4  0x00007f4f9e7015ef in (anonymous namespace)::TExceptionHandlerImp::HandleException(int) () from /usr/lib64/root/libcppyy_backend3_6.so.6.24
#5  0x00007f4fa0db224b in TUnixSystem::DispatchSignals(ESignals) () from /usr/lib64/root/libCore.so
#6  <signal handler called>
#7  0x00007f4f8d4dd0a4 in long double TTreeFormula::EvalInstance<long double>(int, char const**) [clone .part.73] () from /usr/lib64/root/libTreePlayer.so.6.24.08
#8  0x00007f4f8d436057 in ?? ()
#9  0x0000000007aeed00 in ?? ()
#10 0x0000000007a6e440 in ?? ()
#11 0x0000000007aeed40 in ?? ()
#12 0x0000000007aeed00 in ?? ()
#13 0x0000000007aeed00 in ?? ()
#14 0x00007ffd82593ef0 in ?? ()
#15 0x00007f4f8d4eb510 in ?? () from /usr/lib64/root/libTreePlayer.so.6.24.08
#16 0x0000000000000000 in ?? ()
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum https://root.cern.ch/forum
Only if you are really convinced it is a bug in ROOT then please submit a
report at https://root.cern.ch/bugs Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#7  0x00007f4f8d4dd0a4 in long double TTreeFormula::EvalInstance<long double>(int, char const**) [clone .part.73] () from /usr/lib64/root/libTreePlayer.so.6.24.08
#8  0x00007f4f8d436057 in ?? ()
#9  0x0000000007aeed00 in ?? ()
#10 0x0000000007a6e440 in ?? ()
#11 0x0000000007aeed40 in ?? ()
#12 0x0000000007aeed00 in ?? ()
#13 0x0000000007aeed00 in ?? ()
#14 0x00007ffd82593ef0 in ?? ()
#15 0x00007f4f8d4eb510 in ?? () from /usr/lib64/root/libTreePlayer.so.6.24.08
#16 0x0000000000000000 in ?? ()
===========================================================


Traceback (most recent call last):
  File "think_formula.py", line 150, in <module>
    if twelve_pt_cut_select_data[int(args.input_pt)].EvalInstanceLD() != 1 :continue
cppyy.ll.SegmentationViolation: long double TTreeFormula::EvalInstanceLD(int i = 0, const char*[] stringStack = 0) =>
    SegmentationViolation: segfault in C++; program state was reset

SetNotify is a straight setter and thus:

for series in range(len(seven_eta_cut_select_data)):
    tree_data.SetNotify(seven_eta_cut_select_data[series])

is in practice ignoring/forgetting all but the last iteration of the loop.

A solution is provided by TNotifyLink:

seven_eta_cut_select_data=[ ROOT.TTreeFormula(f"seven_eta_{i}",seven_eta_cut_select_temp[i],tree_data) for i in range(len(seven_eta_cut_select_temp))]
seven_eta_cut_select_data_notify_link =[ ROOT.TNotifyLink["TTreeFormula"](t) for t in seven_eta_cut_select_dataROOT.TTreeFormula(f"seven_eta_{i}",seven_eta_cut_select_temp[i],tree_data) 
for series in range(len(seven_eta_cut_select_data_notify_link)):
    seven_eta_cut_select_data_notify_link[series].PrependLink(tree_data)

Also UpdateFormulaLeaves is intended to be called when the TChain’s GetEntry move the from one file to another. There is no need to call it outside of the Notify

Hello pcanal,

Thank you for you patient answer! I have tried your advice , but I got an error . Could you please give me some advice to address it ?

seven_eta_cut_select_data_notify_link =[ ROOT.TNotifyLink["TTreeFormula"](t) for t in seven_eta_cut_select_data]

IncrementalExecutor::executeFunction: symbol ‘_ZN11TNotifyLinkI12TTreeFormulaE5ClassEv’ unresolved while linking symbol ‘__cf_12’!
You are probably missing the definition of TNotifyLink::Class()
Maybe you need to load the corresponding shared library?
IncrementalExecutor::executeFunction: symbol ‘_ZN11TNotifyLinkI12TTreeFormulaE8StreamerER7TBuffer’ unresolved while linking symbol ‘__cf_12’!
You are probably missing the definition of TNotifyLink::Streamer(TBuffer&)
Maybe you need to load the corresponding shared library?
Traceback (most recent call last):
File “/eos/home-z/zgao/ee_qt/systematics/ff_ligangs/think.py”, line 72, in
seven_eta_cut_select_data_notify_link =[ ROOT.TNotifyLink[" TTreeFormula " ](t) for t in seven_eta_cut_select_data]
File “/eos/home-z/zgao/ee_qt/systematics/ff_ligangs/think.py”, line 72, in
seven_eta_cut_select_data_notify_link =[ ROOT.TNotifyLink[“TTreeFormula”](t) for t in seven_eta_cut_select_data]
TypeError: none of the 3 overloaded methods succeeded. Full details:
TNotifyLink::TNotifyLink(TNotifyLink&&) =>
ValueError: could not convert argument 1 (object is not an rvalue)
TNotifyLink constructor failed
TNotifyLink::TNotifyLink(const TNotifyLink&) =>
TypeError: could not convert argument 1

You need to generate a dictionary for TNotify<TTreeFormula> which can be done by doing this first:

gInterpreter->GenerateDictionary("TNotifyLink<TTreeFormula>","TTreeFormula.h;TNotifyLink.h");
1 Like

:wink: Ah! Thank you very much!

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