Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TSelector.cxx
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Rene Brun 05/02/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TSelector
13\ingroup tree
14
15A TSelector object is used by the TTree::Draw, TTree::Scan,
16TTree::Process to navigate in a TTree and make selections.
17It contains the following main methods:
18
19- void TSelector::Init(TTree *t). Called every time a new TTree is
20 attached.
21
22- void TSelector::SlaveBegin(). Create e.g. histograms in this method.
23 This method is called (with or without PROOF) before looping on the
24 entries in the Tree. When using PROOF, this method is called on
25 each worker node.
26
27- void TSelector::Begin(). Mostly for backward compatibility; use
28 SlaveBegin() instead. Both methods are called before looping on the
29 entries in the Tree. When using PROOF, Begin() is called on the
30 client only.
31
32- Bool_t TSelector::Notify(). This method is called at the first entry
33 of a new file in a chain.
34
35- Bool_t TSelector::Process(Long64_t entry). This method is called
36 to process an entry. It is the user's responsibility to read
37 the corresponding entry in memory (may be just a partial read).
38 Once the entry is in memory one can apply a selection and if the
39 entry is selected histograms can be filled. Processing stops
40 when this function returns kFALSE. This function combines the
41 next two functions in one, avoiding to have to maintain state
42 in the class to communicate between these two functions.
43 See WARNING below about entry.
44 This method is used by PROOF.
45
46- Bool_t TSelector::ProcessCut(Long64_t entry). This method is called
47 before processing entry. It is the user's responsibility to read
48 the corresponding entry in memory (may be just a partial read).
49 The function returns kTRUE if the entry must be processed,
50 kFALSE otherwise. This method is obsolete, use Process().
51 See WARNING below about entry.
52
53- void TSelector::ProcessFill(Long64_t entry). This method is called
54 for all selected entries. User fills histograms in this function.
55 This method is obsolete, use Process().
56 See WARNING below about entry.
57
58- void TSelector::SlaveTerminate(). This method is called at the end of
59 the loop on all PROOF worker nodes. In local mode this method is
60 called on the client too.
61
62- void TSelector::Terminate(). This method is called at the end of
63 the loop on all entries. When using PROOF Terminate() is call on
64 the client only. Typically one performs the fits on the produced
65 histograms or write the histograms to file in this method.
66
67__WARNING when a selector is used with a TChain:__
68
69in the Process, ProcessCut, ProcessFill function, you must use
70the pointer to the current Tree to call `GetEntry(entry)`.
71entry is always the local entry number in the current tree.
72Assuming that fChain is the pointer to the TChain being processed,
73use `fChain->GetTree()->GetEntry(entry);`
74*/
75
76#include "TROOT.h"
77#include "TSystem.h"
78#include "TTree.h"
79#include "TError.h"
80#include "TSelector.h"
81#include "TClass.h"
82#include "TInterpreter.h"
83
85
86////////////////////////////////////////////////////////////////////////////////
87/// Default selector ctor.
88
90{
91 fStatus = 0;
93 fObject = 0;
94 fInput = 0;
97}
98
99////////////////////////////////////////////////////////////////////////////////
100/// Selector destructor.
101
103{
104 delete fOutput;
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// Abort processing. If what = kAbortProcess, the Process() loop will be
109/// aborted. If what = kAbortFile, the current file in a chain will be
110/// aborted and the processing will continue with the next file, if there
111/// is no next file then Process() will be aborted. Abort() can also be
112/// called from Begin(), SlaveBegin(), Init() and Notify(). After abort
113/// the SlaveTerminate() and Terminate() are always called. The abort flag
114/// can be checked in these methods using GetAbort().
115
116void TSelector::Abort(const char *why, EAbort what)
117{
118 fAbort = what;
119 TString mess = "Abort";
120 if (fAbort == kAbortProcess)
121 mess = "AbortProcess";
122 else if (fAbort == kAbortFile)
123 mess = "AbortFile";
124
125 Info(mess, "%s", why);
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// The code in filename is loaded (interpreted or compiled, see below),
130/// filename must contain a valid class implementation derived from TSelector.
131///
132/// If filename is of the form file.C, the file will be interpreted.
133/// If filename is of the form file.C++, the file file.C will be compiled
134/// and dynamically loaded. The corresponding binary file and shared
135/// library will be deleted at the end of the function.
136/// If filename is of the form file.C+, the file file.C will be compiled
137/// and dynamically loaded. At next call, if file.C is older than file.o
138/// and file.so, the file.C is not compiled, only file.so is loaded.
139///
140/// The static function returns a pointer to a TSelector object
141
142TSelector *TSelector::GetSelector(const char *filename)
143{
144 // If the filename does not contain "." assume class is compiled in
145 TString localname;
146 Bool_t fromFile = kFALSE;
147 if (strchr(filename, '.') != 0) {
148 //Interpret/compile filename via CINT
149 localname = ".L ";
150 localname += filename;
151 gROOT->ProcessLine(localname);
152 fromFile = kTRUE;
153 }
154
155 //loop on all classes known to CINT to find the class on filename
156 //that derives from TSelector
157 const char *basename = gSystem->BaseName(filename);
158 if (!basename) {
159 ::Error("TSelector::GetSelector","unable to determine the classname for file %s", filename);
160 return 0;
161 }
162 TString aclicmode,args,io;
163 localname = gSystem->SplitAclicMode(basename,aclicmode,args,io);
164 if (localname.Last('.') != kNPOS)
165 localname.Remove(localname.Last('.'));
166
167 // if a file was not specified, try to load the class via the interpreter;
168 // this returns 0 (== failure) in the case the class is already in memory
169 // but does not have a dictionary, so we just raise a flag for better
170 // diagnostic in the case the class is not found in the CINT ClassInfo table.
171 Bool_t autoloaderr = kFALSE;
172 if (!fromFile && gCling->AutoLoad(localname) != 1)
173 autoloaderr = kTRUE;
174
175 TClass *selCl = TClass::GetClass(localname);
176 if (selCl) {
177 // We have all we need.
178 auto offset = selCl->GetBaseClassOffset(TSelector::Class());
179 if (offset == -1) {
180 // TSelector is not a based class.
181 if (fromFile)
182 ::Error("TSelector::GetSelector",
183 "The class %s in file %s does not derive from TSelector.", localname.Data(), filename);
184 else if (autoloaderr)
185 ::Error("TSelector::GetSelector", "class %s could not be loaded", filename);
186 else
187 ::Error("TSelector::GetSelector",
188 "class %s does not exist or does not derive from TSelector", filename);
189 return 0;
190 }
191 char *result = (char*)selCl->New();
192 // By adding offset, we support the case where TSelector is not the
193 // "left-most" base class (i.e. offset != 0)
194 return (TSelector*)(result+offset);
195
196 } else {
197 ClassInfo_t *cl = gCling->ClassInfo_Factory(localname);
198 Bool_t ok = kFALSE;
199 Bool_t nameFound = kFALSE;
200 if (cl && gCling->ClassInfo_IsValid(cl)) {
201 if (localname == gCling->ClassInfo_FullName(cl)) {
202 nameFound = kTRUE;
203 if (gCling->ClassInfo_IsBase(cl,"TSelector")) ok = kTRUE;
204 }
205 }
206 if (!ok) {
207 if (fromFile) {
208 if (nameFound) {
209 ::Error("TSelector::GetSelector",
210 "The class %s in file %s does not derive from TSelector.", localname.Data(), filename);
211 } else {
212 ::Error("TSelector::GetSelector",
213 "The file %s does not define a class named %s.", filename, localname.Data());
214 }
215 } else {
216 if (autoloaderr)
217 ::Error("TSelector::GetSelector", "class %s could not be loaded", filename);
218 else
219 ::Error("TSelector::GetSelector",
220 "class %s does not exist or does not derive from TSelector", filename);
221 }
223 return 0;
224 }
225
226 // we can now create an instance of the class
227 TSelector *selector = (TSelector*)gCling->ClassInfo_New(cl);
229 return selector;
230 }
231}
232
233////////////////////////////////////////////////////////////////////////////////
234/// Find out if this is a standard selection used for Draw actions
235/// (either TSelectorDraw, TProofDraw or deriving from them).
236
238{
239 // Make sure we have a name
240 if (!selec) {
241 ::Info("TSelector::IsStandardDraw",
242 "selector name undefined - do nothing");
243 return kFALSE;
244 }
245
246 Bool_t stdselec = kFALSE;
247 if (!strchr(selec, '.')) {
248 if (strstr(selec, "TSelectorDraw")) {
249 stdselec = kTRUE;
250 } else {
251 TClass *cl = TClass::GetClass(selec);
252 if (cl && (cl->InheritsFrom("TProofDraw") ||
253 cl->InheritsFrom("TSelectorDraw")))
254 stdselec = kTRUE;
255 }
256 }
257
258 // We are done
259 return stdselec;
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Imports the content of 'output' in the internal output list. Existing content
264/// in the output list is discarded (unless found also in 'output').
265/// In particular, if 'output' is nullptr or empty, reset the internal list.
266/// On return, the content of 'output' is cleared to avoid double deletion issues.
267/// (The caller is responsible of 'output' as container: its content is transferred
268/// under the selector ownership).
269
271
272 // Reset the list, if required
273 if (!output || output->GetSize() <= 0) {
274 fOutput->Delete();
275 return;
276 }
277
278 TObject *o;
279
280 // Remove from new list objects already existing locally
281 TIter nxexo(fOutput);
282 while ((o = nxexo())) {
283 if (output->FindObject(o)) output->Remove(o);
284 }
285
286 // Transfer remaining objects
287 TIter nxo(output);
288 while ((o = nxo())) {
289 fOutput->Add(o);
290 }
291
292 // Cleanup original list
293 output->SetOwner(kFALSE);
294 output->Clear("nodelete");
295
296 // Done
297 return;
298}
299
300////////////////////////////////////////////////////////////////////////////////
301/// This method is called before processing entry. It is the user's responsibility to read
302/// the corresponding entry in memory (may be just a partial read).
303/// The function returns kTRUE if the entry must be processed,
304/// kFALSE otherwise. This method is obsolete, use Process().
305///
306/// WARNING when a selector is used with a TChain:
307/// in the Process, ProcessCut, ProcessFill function, you must use
308/// the pointer to the current Tree to call GetEntry(entry).
309/// entry is always the local entry number in the current tree.
310/// Assuming that fChain is the pointer to the TChain being processed,
311/// use fChain->GetTree()->GetEntry(entry);
312
314{
315
316 return kTRUE;
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// This method is called for all selected entries. User fills histograms
321/// in this function. This method is obsolete, use Process().
322///
323/// WARNING when a selector is used with a TChain:
324/// in the Process, ProcessCut, ProcessFill function, you must use
325/// the pointer to the current Tree to call GetEntry(entry).
326/// entry is always the local entry number in the current tree.
327/// Assuming that fChain is the pointer to the TChain being processed,
328/// use fChain->GetTree()->GetEntry(entry);
329
331{
332
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// The Process() function is called for each entry in the tree (or possibly
337/// keyed object in the case of PROOF) to be processed. The entry argument
338/// specifies which entry in the currently loaded tree is to be processed.
339/// It can be passed to either t01::GetEntry() or TBranch::GetEntry()
340/// to read either all or the required parts of the data. When processing
341/// keyed objects with PROOF, the object is already loaded and is available
342/// via the fObject pointer.
343///
344/// This function should contain the "body" of the analysis. It can contain
345/// simple or elaborate selection criteria, run algorithms on the data
346/// of the event and typically fill histograms.
347///
348/// The processing can be stopped by calling Abort().
349///
350/// Use fStatus to set the return value of TTree::Process().
351///
352/// The return value is currently not used.
353///
354/// WARNING when a selector is used with a TChain, you must use
355/// the pointer to the current TTree to call GetEntry(entry).
356/// The entry is always the local entry number in the current tree.
357/// Assuming that fChain is the pointer to the TChain being processed,
358/// use: `fChain->GetTree()->GetEntry(entry)`.
359
361
362 return kFALSE;
363}
const Ssiz_t kNPOS
Definition RtypesCore.h:124
const Bool_t kFALSE
Definition RtypesCore.h:101
long long Long64_t
Definition RtypesCore.h:80
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
R__EXTERN TInterpreter * gCling
#define gROOT
Definition TROOT.h:404
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:80
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:4964
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition TClass.cxx:2789
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4860
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2966
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
virtual void * ClassInfo_New(ClassInfo_t *) const
virtual Bool_t ClassInfo_IsValid(ClassInfo_t *) const
virtual void ClassInfo_Delete(ClassInfo_t *) const
virtual Bool_t ClassInfo_IsBase(ClassInfo_t *, const char *) const
virtual const char * ClassInfo_FullName(ClassInfo_t *) const
virtual Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)=0
virtual ClassInfo_t * ClassInfo_Factory(Bool_t=kTRUE) const =0
A doubly linked list.
Definition TList.h:38
virtual void Add(TObject *obj)
Definition TList.h:81
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:937
A TList derived class that makes sure that objects added to it are not linked to the currently open f...
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition TSelector.h:31
TList * fInput
List of objects available during processing.
Definition TSelector.h:41
virtual void ProcessFill(Long64_t)
This method is called for all selected entries.
@ kAbortProcess
Definition TSelector.h:34
virtual void ImportOutput(TList *output)
Imports the content of 'output' in the internal output list.
TSelectorList * fOutput
! List of objects created during processing
Definition TSelector.h:42
virtual Bool_t Process(Long64_t)
The Process() function is called for each entry in the tree (or possibly keyed object in the case of ...
static Bool_t IsStandardDraw(const char *selec)
Find out if this is a standard selection used for Draw actions (either TSelectorDraw,...
Long64_t fStatus
Selector status.
Definition TSelector.h:37
virtual Bool_t ProcessCut(Long64_t)
This method is called before processing entry.
virtual void Abort(const char *why, EAbort what=kAbortProcess)
Abort processing.
TObject * fObject
! Current object if processing object (vs. TTree)
Definition TSelector.h:40
EAbort fAbort
Abort status.
Definition TSelector.h:38
virtual ~TSelector()
Selector destructor.
TSelector()
Default selector ctor.
Definition TSelector.cxx:89
static TSelector * GetSelector(const char *filename)
The code in filename is loaded (interpreted or compiled, see below), filename must contain a valid cl...
Basic string class.
Definition TString.h:136
const char * Data() const
Definition TString.h:369
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:916
TString & Remove(Ssiz_t pos)
Definition TString.h:673
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4252
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:935
static const char * what
Definition stlLoader.cc:6
static void output(int code)
Definition gifencode.c:226