ROOT  6.06/09
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 A TSelector object is used by the TTree::Draw, TTree::Scan,
14 TTree::Process to navigate in a TTree and make selections.
15 It contains the following main methods:
16 
17 - void TSelector::Init(TTree *t). Called every time a new TTree is
18  attached.
19 
20 - void TSelector::SlaveBegin(). Create e.g. histograms in this method.
21  This method is called (with or without PROOF) before looping on the
22  entries in the Tree. When using PROOF, this method is called on
23  each worker node.
24 
25 - void TSelector::Begin(). Mostly for backward compatibility; use
26  SlaveBegin() instead. Both methods are called before looping on the
27  entries in the Tree. When using PROOF, Begin() is called on the
28  client only.
29 
30 - Bool_t TSelector::Notify(). This method is called at the first entry
31  of a new file in a chain.
32 
33 - Bool_t TSelector::Process(Long64_t entry). This method is called
34  to process an entry. It is the user's responsability to read
35  the corresponding entry in memory (may be just a partial read).
36  Once the entry is in memory one can apply a selection and if the
37  entry is selected histograms can be filled. Processing stops
38  when this function returns kFALSE. This function combines the
39  next two functions in one, avoiding to have to maintain state
40  in the class to communicate between these two functions.
41  See WARNING below about entry.
42  This method is used by PROOF.
43 
44 - Bool_t TSelector::ProcessCut(Long64_t entry). This method is called
45  before processing entry. It is the user's responsability to read
46  the corresponding entry in memory (may be just a partial read).
47  The function returns kTRUE if the entry must be processed,
48  kFALSE otherwise. This method is obsolete, use Process().
49  See WARNING below about entry.
50 
51 - void TSelector::ProcessFill(Long64_t entry). This method is called
52  for all selected entries. User fills histograms in this function.
53  This method is obsolete, use Process().
54  See WARNING below about entry.
55 
56 - void TSelector::SlaveTerminate(). This method is called at the end of
57  the loop on all PROOF worker nodes. In local mode this method is
58  called on the client too.
59 
60 - void TSelector::Terminate(). This method is called at the end of
61  the loop on all entries. When using PROOF Terminate() is call on
62  the client only. Typically one performs the fits on the produced
63  histograms or write the histograms to file in this method.
64 
65 __WARNING when a selector is used with a TChain:__
66 
67 in the Process, ProcessCut, ProcessFill function, you must use
68 the pointer to the current Tree to call `GetEntry(entry)`.
69 entry is always the local entry number in the current tree.
70 Assuming that fChain is the pointer to the TChain being processed,
71 use `fChain->GetTree()->GetEntry(entry);`
72 */
73 
74 #include "TROOT.h"
75 #include "TSystem.h"
76 #include "TTree.h"
77 #include "TError.h"
78 #include "TSelectorCint.h"
79 #include "TClass.h"
80 #include "TInterpreter.h"
81 
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 /// Default selector ctor.
86 
88 {
89  fStatus = 0;
90  fAbort = kContinue;
91  fObject = 0;
92  fInput = 0;
93  fOutput = new TSelectorList;
94  fOutput->SetOwner();
95 }
96 
97 ////////////////////////////////////////////////////////////////////////////////
98 /// Selector destructor.
99 
101 {
102  delete fOutput;
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Abort processing. If what = kAbortProcess, the Process() loop will be
107 /// aborted. If what = kAbortFile, the current file in a chain will be
108 /// aborted and the processing will continue with the next file, if there
109 /// is no next file then Process() will be aborted. Abort() can also be
110 /// called from Begin(), SlaveBegin(), Init() and Notify(). After abort
111 /// the SlaveTerminate() and Terminate() are always called. The abort flag
112 /// can be checked in these methods using GetAbort().
113 
114 void TSelector::Abort(const char *why, EAbort what)
115 {
116  fAbort = what;
117  TString mess = "Abort";
118  if (fAbort == kAbortProcess)
119  mess = "AbortProcess";
120  else if (fAbort == kAbortFile)
121  mess = "AbortFile";
122 
123  Info(mess, "%s", why);
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// The code in filename is loaded (interpreted or compiled, see below),
128 /// filename must contain a valid class implementation derived from TSelector.
129 ///
130 /// If filename is of the form file.C, the file will be interpreted.
131 /// If filename is of the form file.C++, the file file.C will be compiled
132 /// and dynamically loaded. The corresponding binary file and shared
133 /// library will be deleted at the end of the function.
134 /// If filename is of the form file.C+, the file file.C will be compiled
135 /// and dynamically loaded. At next call, if file.C is older than file.o
136 /// and file.so, the file.C is not compiled, only file.so is loaded.
137 ///
138 /// The static function returns a pointer to a TSelector object
139 
141 {
142  // If the filename does not contain "." assume class is compiled in
143  TString localname;
144  Bool_t fromFile = kFALSE;
145  if (strchr(filename, '.') != 0) {
146  //Interpret/compile filename via CINT
147  localname = ".L ";
148  localname += filename;
149  gROOT->ProcessLine(localname);
150  fromFile = kTRUE;
151  }
152 
153  //loop on all classes known to CINT to find the class on filename
154  //that derives from TSelector
155  const char *basename = gSystem->BaseName(filename);
156  if (!basename) {
157  ::Error("TSelector::GetSelector","unable to determine the classname for file %s", filename);
158  return 0;
159  }
160  TString aclicmode,args,io;
161  localname = gSystem->SplitAclicMode(basename,aclicmode,args,io);
162  if (localname.Last('.') != kNPOS)
163  localname.Remove(localname.Last('.'));
164 
165  // if a file was not specified, try to load the class via the interpreter;
166  // this returns 0 (== failure) in the case the class is already in memory
167  // but does not have a dictionary, so we just raise a flag for better
168  // diagnostic in the case the class is not found in the CINT ClassInfo table.
169  Bool_t autoloaderr = kFALSE;
170  if (!fromFile && gCling->AutoLoad(localname) != 1)
171  autoloaderr = kTRUE;
172 
173  TClass *selCl = TClass::GetClass(localname);
174  if (selCl) {
175  // We have all we need.
176  auto offset = selCl->GetBaseClassOffset(TSelector::Class());
177  if (offset == -1) {
178  // TSelector is not a based class.
179  if (fromFile)
180  ::Error("TSelector::GetSelector",
181  "The class %s in file %s does not derive from TSelector.", localname.Data(), filename);
182  else if (autoloaderr)
183  ::Error("TSelector::GetSelector", "class %s could not be loaded", filename);
184  else
185  ::Error("TSelector::GetSelector",
186  "class %s does not exist or does not derive from TSelector", filename);
187  return 0;
188  }
189  char *result = (char*)selCl->New();
190  // By adding offset, we support the case where TSelector is not the
191  // "left-most" base class (i.e. offset != 0)
192  return (TSelector*)(result+offset);
193 
194  } else {
195  ClassInfo_t *cl = gCling->ClassInfo_Factory(localname);
196  Bool_t ok = kFALSE;
197  Bool_t nameFound = kFALSE;
198  if (cl && gCling->ClassInfo_IsValid(cl)) {
199  if (localname == gCling->ClassInfo_FullName(cl)) {
200  nameFound = kTRUE;
201  if (gCling->ClassInfo_IsBase(cl,"TSelector")) ok = kTRUE;
202  }
203  }
204  if (!ok) {
205  if (fromFile) {
206  if (nameFound) {
207  ::Error("TSelector::GetSelector",
208  "The class %s in file %s does not derive from TSelector.", localname.Data(), filename);
209  } else {
210  ::Error("TSelector::GetSelector",
211  "The file %s does not define a class named %s.", filename, localname.Data());
212  }
213  } else {
214  if (autoloaderr)
215  ::Error("TSelector::GetSelector", "class %s could not be loaded", filename);
216  else
217  ::Error("TSelector::GetSelector",
218  "class %s does not exist or does not derive from TSelector", filename);
219  }
221  return 0;
222  }
223 
224  // we can now create an instance of the class
225  TSelector *selector = (TSelector*)gCling->ClassInfo_New(cl);
227  return selector;
228  }
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 /// Find out if this is a standard selection used for Draw actions
233 /// (either TSelectorDraw, TProofDraw or deriving from them).
234 
236 {
237  // Make sure we have a name
238  if (!selec) {
239  ::Info("TSelector::IsStandardDraw",
240  "selector name undefined - do nothing");
241  return kFALSE;
242  }
243 
244  Bool_t stdselec = kFALSE;
245  if (!strchr(selec, '.')) {
246  if (strstr(selec, "TSelectorDraw")) {
247  stdselec = kTRUE;
248  } else {
249  TClass *cl = TClass::GetClass(selec);
250  if (cl && (cl->InheritsFrom("TProofDraw") ||
251  cl->InheritsFrom("TSelectorDraw")))
252  stdselec = kTRUE;
253  }
254  }
255 
256  // We are done
257  return stdselec;
258 }
259 
261 {
262  // This method is called before processing entry. It is the user's responsability to read
263  // the corresponding entry in memory (may be just a partial read).
264  // The function returns kTRUE if the entry must be processed,
265  // kFALSE otherwise. This method is obsolete, use Process().
266  //
267  // WARNING when a selector is used with a TChain:
268  // in the Process, ProcessCut, ProcessFill function, you must use
269  // the pointer to the current Tree to call GetEntry(entry).
270  // entry is always the local entry number in the current tree.
271  // Assuming that fChain is the pointer to the TChain being processed,
272  // use fChain->GetTree()->GetEntry(entry);
273 
274  return kTRUE;
275 }
276 
278 {
279  // This method is called for all selected entries. User fills histograms
280  // in this function. This method is obsolete, use Process().
281  //
282  // WARNING when a selector is used with a TChain:
283  // in the Process, ProcessCut, ProcessFill function, you must use
284  // the pointer to the current Tree to call GetEntry(entry).
285  // entry is always the local entry number in the current tree.
286  // Assuming that fChain is the pointer to the TChain being processed,
287  // use fChain->GetTree()->GetEntry(entry);
288 }
289 
291  // The Process() function is called for each entry in the tree (or possibly
292  // keyed object in the case of PROOF) to be processed. The entry argument
293  // specifies which entry in the currently loaded tree is to be processed.
294  // It can be passed to either t01::GetEntry() or TBranch::GetEntry()
295  // to read either all or the required parts of the data. When processing
296  // keyed objects with PROOF, the object is already loaded and is available
297  // via the fObject pointer.
298  //
299  // This function should contain the "body" of the analysis. It can contain
300  // simple or elaborate selection criteria, run algorithms on the data
301  // of the event and typically fill histograms.
302  //
303  // The processing can be stopped by calling Abort().
304  //
305  // Use fStatus to set the return value of TTree::Process().
306  //
307  // The return value is currently not used.
308 
309  return kFALSE;
310 }
311 
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
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:4071
TSelectorList * fOutput
Definition: TSelector.h:50
long long Long64_t
Definition: RtypesCore.h:69
virtual void ClassInfo_Delete(ClassInfo_t *) const
Definition: TInterpreter.h:347
virtual Bool_t ProcessCut(Long64_t)
Definition: TSelector.cxx:260
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
virtual void * ClassInfo_New(ClassInfo_t *) const
Definition: TInterpreter.h:368
static const char * filename()
#define gROOT
Definition: TROOT.h:340
Basic string class.
Definition: TString.h:137
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
const char * Data() const
Definition: TString.h:349
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2705
virtual void ProcessFill(Long64_t)
Definition: TSelector.cxx:277
void Class()
Definition: Class.C:29
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4683
virtual ClassInfo_t * ClassInfo_Factory(Bool_t=kTRUE) const =0
virtual Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)=0
virtual Bool_t ClassInfo_IsBase(ClassInfo_t *, const char *) const
Definition: TInterpreter.h:361
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
virtual Bool_t ClassInfo_IsValid(ClassInfo_t *) const
Definition: TInterpreter.h:364
void Error(const char *location, const char *msgfmt,...)
static const char * what
Definition: stlLoader.cc:6
virtual const char * ClassInfo_FullName(ClassInfo_t *) const
Definition: TInterpreter.h:376
ClassImp(TSelector) TSelector
Default selector ctor.
Definition: TSelector.cxx:82
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
virtual void Abort(const char *why, EAbort what=kAbortProcess)
Abort processing.
Definition: TSelector.cxx:114
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:235
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
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:140
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
EAbort fAbort
Definition: TSelector.h:46
virtual ~TSelector()
Selector destructor.
Definition: TSelector.cxx:100
virtual Bool_t Process(Long64_t)
Definition: TSelector.cxx:290
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:2881
Mother of all ROOT objects.
Definition: TObject.h:58
const Ssiz_t kNPOS
Definition: Rtypes.h:115
A TList derived class that makes sure that objects added to it are not linked to the currently open f...
Definition: TSelectorList.h:33
double result[121]
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4579
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:504
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:39
const Bool_t kTRUE
Definition: Rtypes.h:91