How to use AddFriend with MakeSelector

I have one rootfile that contains two trees, one tree contains the data (thousand of events), while the other tree contains one event only as it stores the pedestals (mean, std_dev… per each channel). I have a fully working analysis code that processes the data tree with MakeSelector, but I would need also to consider/include the pedestals from the other tree.

I produced the class for the pedtree with MakeSelector and I can certainly include the pedclass.h into the dataclass.C but how can the process() that runs on the data tree also access the pedtree? I thought I could use AddFriend somehow… is there a template I can follow?

ROOT Version: v6-24-04
Platform: CentOS Linux release 7.9.2009 (lxplus)
Compiler: gcc version 4.8.5

I think you need to modify the “Notify()” method of your “selector” (automatically called at the first entry of every new tree in a chain).
Inside this method, you should get your “other tree” (from the “currently opened” file) and retrieve its single event with “pedestals”.

I guess @ganis may give some advice, if you are using, e.g., “PROOF” or “PROOF-Lite”.

BTW. “TTree friends” are not really what you want in this case.

Since, if I understand correctly, the pedestal information is the same for all data events, in Begin() (SlaveBegin() if on PROOF) I would read the pedestal information into a dedicated member of dataclass and then use it in Process().
You can either load all the information memory or open the pedestal tree and use in Process().

The Friends approach would not work in this case because only the first event would get the info.

Hope it helps,
G Ganis

@ganis I guess the pedestals may change when one changes files with trees in a chain (that’s why I proposed to use the “Notify()” method).

Thanks @Wile_E_Coyote and @ganis I think I understood the logic, but not exactly sure what to write inside Notify(); how to point to the “currently opened file” inside Notify()?

I would write something like the following, but “myfile” is obviously not defined:
TTree* tped = dynamic_cast<TTree*>(myfile.Get(“treeped”));

p.s. I call the Process() using t->Process(“dataclass.C+”) so you are saying that notify() will be called just during the first event, right?

Notify()” will be executed right before the first event is processed.

If you are using the default ROOT 6 style selector (based on the “TTreeReader” class):
TFile *myfile = fReader.GetTree()->GetCurrentFile();

If you are using the “legacy” ROOT 5 style selector:
TFile *myfile = fChain->GetCurrentFile();

Ok Notify() seems to work (like it does not give any errors), so I guess the roofile is found and the specific pedestal tree is also loaded (I declared in the class).

But when I tried to access that pedestal tree from Begin() or Process() I get a segmentation fault. Is there anything else to be done so that the tree loaded in Notify() could be actually used in the data process()?

When “Begin()” and “SlaveBegin()” are executed, no file has been opened yet (and “Notify()” has not been executed either).

You should not get problems in your selector’s “Process” method.

yep that worked in the process(), thanks!

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