Logo ROOT   6.08/07
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 "TSelectorCint.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 
263 {
264  // This method is called before processing entry. It is the user's responsability to read
265  // the corresponding entry in memory (may be just a partial read).
266  // The function returns kTRUE if the entry must be processed,
267  // kFALSE otherwise. This method is obsolete, use Process().
268  //
269  // WARNING when a selector is used with a TChain:
270  // in the Process, ProcessCut, ProcessFill function, you must use
271  // the pointer to the current Tree to call GetEntry(entry).
272  // entry is always the local entry number in the current tree.
273  // Assuming that fChain is the pointer to the TChain being processed,
274  // use fChain->GetTree()->GetEntry(entry);
275 
276  return kTRUE;
277 }
278 
280 {
281  // This method is called for all selected entries. User fills histograms
282  // in this function. This method is obsolete, use Process().
283  //
284  // WARNING when a selector is used with a TChain:
285  // in the Process, ProcessCut, ProcessFill function, you must use
286  // the pointer to the current Tree to call GetEntry(entry).
287  // entry is always the local entry number in the current tree.
288  // Assuming that fChain is the pointer to the TChain being processed,
289  // use fChain->GetTree()->GetEntry(entry);
290 }
291 
293  // The Process() function is called for each entry in the tree (or possibly
294  // keyed object in the case of PROOF) to be processed. The entry argument
295  // specifies which entry in the currently loaded tree is to be processed.
296  // It can be passed to either t01::GetEntry() or TBranch::GetEntry()
297  // to read either all or the required parts of the data. When processing
298  // keyed objects with PROOF, the object is already loaded and is available
299  // via the fObject pointer.
300  //
301  // This function should contain the "body" of the analysis. It can contain
302  // simple or elaborate selection criteria, run algorithms on the data
303  // of the event and typically fill histograms.
304  //
305  // The processing can be stopped by calling Abort().
306  //
307  // Use fStatus to set the return value of TTree::Process().
308  //
309  // The return value is currently not used.
310 
311  return kFALSE;
312 }
313 
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:929
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:899
TSelectorList * fOutput
! List of objects created during processing
Definition: TSelector.h:50
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:4109
virtual Bool_t ClassInfo_IsValid(ClassInfo_t *) const
Definition: TInterpreter.h:379
virtual Bool_t ProcessCut(Long64_t)
Definition: TSelector.cxx:262
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
#define gROOT
Definition: TROOT.h:364
Basic string class.
Definition: TString.h:137
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
const char * Class
Definition: TXMLSetup.cxx:64
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2717
virtual void ProcessFill(Long64_t)
Definition: TSelector.cxx:279
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:383
void Error(const char *location, const char *msgfmt,...)
static const char * what
Definition: stlLoader.cc:6
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
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 void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4610
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:616
#define ClassImp(name)
Definition: Rtypes.h:279
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:865
EAbort fAbort
Abort status.
Definition: TSelector.h:46
virtual ~TSelector()
Selector destructor.
Definition: TSelector.cxx:102
virtual Bool_t Process(Long64_t)
Definition: TSelector.cxx:292
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:2893
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void ClassInfo_Delete(ClassInfo_t *) const
Definition: TInterpreter.h:362
virtual const char * ClassInfo_FullName(ClassInfo_t *) const
Definition: TInterpreter.h:391
const Ssiz_t kNPOS
Definition: Rtypes.h:115
virtual Bool_t ClassInfo_IsBase(ClassInfo_t *, const char *) const
Definition: TInterpreter.h:376
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]
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:519
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
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4714
const char * Data() const
Definition: TString.h:349