[quote=“puma”]Hi ROOTers,
I’m analysing a tree using MakeSelector.
I write a huge number of histograms, so I declare an array of histograms as a global variable
When I open the file in a ROOT session every histogram is empty.
Where am I wrong?
[/quote]
You are probvably calling the copy constuctor somewhere. I wouln’t use TH1D His[5000]; – better use an array of pointers to TH1D (TH1D His[5000] or a std::vector<TH1D>! Then the histos really get initialized the moment you use “new” - and more important you don’t call the copy constructor at places where you don’t expect it
Also, when writing a selector, you should create (“new”) the histograms in SlaveBegin and add them to fOutput. And get them back in Terminate. Then your selector can also be run in PROOF.
I don’t think that it is the problem, because the same code works using MakeClass. On the other way, working with an array of pointers, I get a segmentation violation after having successfully compiled my code.
I run the code using
I have turned to MakeSelector because I want to use the code I wrote for a test tree, for all the trees I need to analyse. So, if anybody knows how to use the code written for a single tree using MakeClass for a chain I would be really happy.
Consider that I would like to put this code into a repository for everybody who wants to perform my analysis using a different version of the dataset, so I would like to write a file that everybody can use without having to modify it, but only changing the list of input trees into the chain.
Another really strange thing I noticed is that when I put these lines in the Begin()
// Test histo
TH1I *htest= new TH1I("htest","test",50,0.,100000.);
I get these errors:
In member function `virtual void testSelector::Begin(TTree*)':
[path]/testSelector.C:95: warning: unused variable `TH1I*htest'
In file included from [path]/fileFYzR7u.h:32,
from [path]/fileFYzR7u.cxx:16:
[path]/testSelector.C: In member function `virtual Bool_t testSelector::Process(long long int)':
[path]/testSelector.C:180: `htest' undeclared (first use this function)
in Process() I Fill htest with nentries, an integer declared global which I post-increment every step.
I finally draw htest in Terminate().
The most interesting thing is that, if I declare htest as a global variable, it will be filled and drawn. So what is the Begin function written for?
You have something wrong in the bookkeeping of your histogram.
The pointer(s) to your histogram(s) like htest should be a data member of your TSelector derived class. In this way you can communicate between the Begin and Process function.
Hi,
making some cross-checks I verified that the histos are build correctly.
The problem is that a data member which is a branch of my tree seems to be 0 for each entry and I use it to apply some cuts.
But if I take a look into my tree using TBrowser, I can clearly see that it is not zero for each entry.
I tried also another data member of my tree and it is read as 0 for each entry.
Here I put an example of my code:
into the .h file:
Int_t nDstar;
...
TBranch *b_nDstar; //!
into the .C file:
His[2].Fill(nDstar);
where His[2] is an histogram that I plot into the Terminate(). I guess the histograms are right because if I put His[2] before a cut that I apply on nDstar it is filled with the complete number of entries (and 0 for each entry), while if I put it after the cut it is empty.
[quote]Where am I wrong? [/quote]There is nothing obviously wrong in the snippets of example you have shown, however they leave enough for interpretation/guess that many things could be wrong. To be able to able you further you would need a completerunning example (i.e including all required source and header and root files) that reproduce the problem(s) as well as a description of what you see and what you expected to see.
I run it from ROOTv5.18(CINT/ROOT C/C++ Interpreter version 5.16.29)
root[0] TFile f(“testSample.root”);
root[1] TTree T = (TTree)f.Get(“ntp1”);
root[2] T->Process(“testSelector.C+”)
humm … your file are no longer available.
From your solution I am guessing that you customized your selector to point to a 2nd tree. TTree::Process will only control (and call GetEntry) for the tree it is called on, any additional tree will need to be handled explicit, as you did.
Please note in the documentation of the Process function itself (just above the code your entered, it mentions: ... The entry argument
// specifies which entry in the currently loaded tree is to be processed.
// It can be passed to either testSelector::GetEntry() or TBranch::GetEntry()
// to read either all or the required parts of the data. The GetEntry is not automated so that you can restrict the reading to only the part of the TTree you need (by call the branches’ GetEntry). Note that the result of TTree::MakeProxy automates this part (i.e. in that case, the access to the data member induces the reading of the corresponding branch – i.e. load on demand).
but the code crashes at runtime with the following message:
#5 0x00007f6f2c62006e in proof::Terminate() () from /raid/01/home/corsi/macros/./proof_C.so #6 0x00007f6f2c8a7660 in TProofPlayerLite::Finalize(bool, bool) () from /opt/root/v5.34.25/lib/libProofPlayer.so #7 0x00007f6f2c8a8ec8 in TProofPlayerLite::Process(TDSet*, char const*, char const*, long long, long long) () from /opt/root/v5.34.25/lib/libProofPlayer.so #8 0x00007f6f2dbb15ce in TProofLite::Process(TDSet*, char const*, char const*, long long, long long) () from /opt/root/v5.34.25/lib/libProof.so
How can I pass the array of TH1F to the output file?
Thanks in advance,
Anna
Thanks for the reply. The missing “” where an error in the post, sorry.
I tried putting in BeginSlave:
for(int i=0; i<20; i++) {
h[i] = dynamic_cast<TH1F*>(fOutput->FindObject(Form(“h%d”,i)));
}
and in Terminate
for(int i=0; i<20; i++) {
if (h[i]) h[i]->Write();
}
Is that what you meant? But still:
#5 0x00007f0f793fd07b in proof::Terminate() () from /raid/01/home/corsi/macros/./proof_C.so #6 0x00007f0f79684660 in TProofPlayerLite::Finalize(bool, bool) () from /opt/root/v5.34.25/lib/libProofPlayer.so #7 0x00007f0f79685ec8 in TProofPlayerLite::Process(TDSet*, char const*, char const*, long long, long long) () from /opt/root/v5.34.25/lib/libProofPlayer.so #8 0x00007f0f7a98e5ce in TProofLite::Process(TDSet*, char const*, char const*, long long, long long) () from /opt/root/v5.34.25/lib/libProof.so