Logo ROOT   6.14/05
Reference Guide
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 
15 A TSelector object is used by the TTree::Draw, TTree::Scan,
16 TTree::Process to navigate in a TTree and make selections.
17 It 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 responsability 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 responsability 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 
69 in the Process, ProcessCut, ProcessFill function, you must use
70 the pointer to the current Tree to call `GetEntry(entry)`.
71 entry is always the local entry number in the current tree.
72 Assuming that fChain is the pointer to the TChain being processed,
73 use `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;
92  fAbort = kContinue;
93  fObject = 0;
94  fInput = 0;
95  fOutput = new TSelectorList;
96  fOutput->SetOwner();
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 
116 void 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 
142 TSelector *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 
301 {
302  // This method is called before processing entry. It is the user's responsability to read
303  // the corresponding entry in memory (may be just a partial read).
304  // The function returns kTRUE if the entry must be processed,
305  // kFALSE otherwise. This method is obsolete, use Process().
306  //
307  // WARNING when a selector is used with a TChain:
308  // in the Process, ProcessCut, ProcessFill function, you must use
309  // the pointer to the current Tree to call GetEntry(entry).
310  // entry is always the local entry number in the current tree.
311  // Assuming that fChain is the pointer to the TChain being processed,
312  // use fChain->GetTree()->GetEntry(entry);
313 
314  return kTRUE;
315 }
316 
318 {
319  // This method is called for all selected entries. User fills histograms
320  // in this function. This method is obsolete, use Process().
321  //
322  // WARNING when a selector is used with a TChain:
323  // in the Process, ProcessCut, ProcessFill function, you must use
324  // the pointer to the current Tree to call GetEntry(entry).
325  // entry is always the local entry number in the current tree.
326  // Assuming that fChain is the pointer to the TChain being processed,
327  // use fChain->GetTree()->GetEntry(entry);
328 }
329 
331  // The Process() function is called for each entry in the tree (or possibly
332  // keyed object in the case of PROOF) to be processed. The entry argument
333  // specifies which entry in the currently loaded tree is to be processed.
334  // It can be passed to either t01::GetEntry() or TBranch::GetEntry()
335  // to read either all or the required parts of the data. When processing
336  // keyed objects with PROOF, the object is already loaded and is available
337  // via the fObject pointer.
338  //
339  // This function should contain the "body" of the analysis. It can contain
340  // simple or elaborate selection criteria, run algorithms on the data
341  // of the event and typically fill histograms.
342  //
343  // The processing can be stopped by calling Abort().
344  //
345  // Use fStatus to set the return value of TTree::Process().
346  //
347  // The return value is currently not used.
348 
349  return kFALSE;
350 }
351 
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:932
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
TSelectorList * fOutput
! List of objects created during processing
Definition: TSelector.h:44
long long Long64_t
Definition: RtypesCore.h:69
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form: ~~~ {.cpp} [path/]macro.C[+|++[k|f|g|O|c|s|d|v|-]][(args)]...
Definition: TSystem.cxx:4138
virtual Bool_t ClassInfo_IsValid(ClassInfo_t *) const
Definition: TInterpreter.h:389
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
virtual Bool_t ProcessCut(Long64_t)
Definition: TSelector.cxx:300
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void ImportOutput(TList *output)
Imports the content of &#39;output&#39; in the internal output list.
Definition: TSelector.cxx:270
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:207
#define gROOT
Definition: TROOT.h:410
Basic string class.
Definition: TString.h:131
bool Bool_t
Definition: RtypesCore.h:59
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2710
virtual void ProcessFill(Long64_t)
Definition: TSelector.cxx:317
void Class()
Definition: Class.C:29
virtual ClassInfo_t * ClassInfo_Factory(Bool_t=kTRUE) const =0
virtual Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)=0
virtual void * ClassInfo_New(ClassInfo_t *) const
Definition: TInterpreter.h:393
void Error(const char *location, const char *msgfmt,...)
A doubly linked list.
Definition: TList.h:44
TObject * fObject
! Current object if processing object (vs. TTree)
Definition: TSelector.h:42
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
Long64_t fStatus
Selector status.
Definition: TSelector.h:39
virtual void Abort(const char *why, EAbort what=kAbortProcess)
Abort processing.
Definition: TSelector.cxx:116
static Bool_t IsStandardDraw(const char *selec)
Find out if this is a standard selection used for Draw actions (either TSelectorDraw, TProofDraw or deriving from them).
Definition: TSelector.cxx:237
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4688
const Bool_t kFALSE
Definition: RtypesCore.h:88
static TSelector * GetSelector(const char *filename)
The code in filename is loaded (interpreted or compiled, see below), filename must contain a valid cl...
Definition: TSelector.cxx:142
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
#define ClassImp(name)
Definition: Rtypes.h:359
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:876
EAbort fAbort
Abort status.
Definition: TSelector.h:40
virtual ~TSelector()
Selector destructor.
Definition: TSelector.cxx:102
virtual Bool_t Process(Long64_t)
Definition: TSelector.cxx:330
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:2887
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
Mother of all ROOT objects.
Definition: TObject.h:37
TSelector()
Default selector ctor.
Definition: TSelector.cxx:89
virtual void ClassInfo_Delete(ClassInfo_t *) const
Definition: TInterpreter.h:372
virtual const char * ClassInfo_FullName(ClassInfo_t *) const
Definition: TInterpreter.h:401
TList * fInput
List of objects available during processing.
Definition: TSelector.h:43
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual Bool_t ClassInfo_IsBase(ClassInfo_t *, const char *) const
Definition: TInterpreter.h:386
A TList derived class that makes sure that objects added to it are not linked to the currently open f...
Definition: TSelectorList.h:31
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:529
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:33
const Bool_t kTRUE
Definition: RtypesCore.h:87
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4792
const char * Data() const
Definition: TString.h:364