ROOT logo
// @(#)root/tree:$Id$
// Author: Rene Brun   05/02/97

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// A TSelector object is used by the TTree::Draw, TTree::Scan,            //
// TTree::Process to navigate in a TTree and make selections.             //
// It contains the following main methods:                                //
//                                                                        //
// void TSelector::Init(TTree *t). Called every time a new TTree is       //
//    attached.                                                           //
//                                                                        //
// void TSelector::SlaveBegin(). Create e.g. histograms in this method.   //
//    This method is called (with or without PROOF) before looping on the //
//    entries in the Tree. When using PROOF, this method is called on     //
//    each worker node.                                                   //
// void TSelector::Begin(). Mostly for backward compatibility; use        //
//    SlaveBegin() instead. Both methods are called before looping on the //
//    entries in the Tree. When using PROOF, Begin() is called on the     //
//    client only.                                                        //
//                                                                        //
// Bool_t TSelector::Notify(). This method is called at the first entry   //
//    of a new file in a chain.                                           //
//                                                                        //
// Bool_t TSelector::Process(Long64_t entry). This method is called       //
//    to process an entry. It is the user's responsability to read        //
//    the corresponding entry in memory (may be just a partial read).     //
//    Once the entry is in memory one can apply a selection and if the    //
//    entry is selected histograms can be filled. Processing stops        //
//    when this function returns kFALSE. This function combines the       //
//    next two functions in one, avoiding to have to maintain state       //
//    in the class to communicate between these two functions.            //
//    See WARNING below about entry.                                      //
//    This method is used by PROOF.                                       //
// Bool_t TSelector::ProcessCut(Long64_t entry). This method is called    //
//    before processing entry. It is the user's responsability to read    //
//    the corresponding entry in memory (may be just a partial read).     //
//    The function returns kTRUE if the entry must be processed,          //
//    kFALSE otherwise. This method is obsolete, use Process().           //
//    See WARNING below about entry.                                      //
// void TSelector::ProcessFill(Long64_t entry). This method is called     //
//    for all selected entries. User fills histograms in this function.   //
//    This method is obsolete, use Process().                             //
//    See WARNING below about entry.                                      //
// void TSelector::SlaveTerminate(). This method is called at the end of  //
//    the loop on all PROOF worker nodes. In local mode this method is    //
//    called on the client too.                                           //
// void TSelector::Terminate(). This method is called at the end of       //
//    the loop on all entries. When using PROOF Terminate() is call on    //
//    the client only. Typically one performs the fits on the produced    //
//    histograms or write the histograms to file in this method.          //
//                                                                        //
// WARNING when a selector is used with a TChain:                         //
//    in the Process, ProcessCut, ProcessFill function, you must use      //
//    the pointer to the current Tree to call GetEntry(entry).            //
//    entry is always the local entry number in the current tree.         //
//    Assuming that fChain is the pointer to the TChain being processed,  //
//    use fChain->GetTree()->GetEntry(entry);                             //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#include "TROOT.h"
#include "TSystem.h"
#include "TTree.h"
#include "TError.h"
#include "TSelectorCint.h"
#include "TClass.h"
#include "TInterpreter.h"


ClassImp(TSelector)

//______________________________________________________________________________
TSelector::TSelector() : TObject()
{
   // Default selector ctor.

   fStatus = 0;
   fAbort  = kContinue;
   fObject = 0;
   fInput  = 0;
   fOutput = new TSelectorList;
   fOutput->SetOwner();
}

//______________________________________________________________________________
TSelector::~TSelector()
{
   // Selector destructor.

   delete fOutput;
}

//______________________________________________________________________________
void TSelector::Abort(const char *why, EAbort what)
{
   // Abort processing. If what = kAbortProcess, the Process() loop will be
   // aborted. If what = kAbortFile, the current file in a chain will be
   // aborted and the processing will continue with the next file, if there
   // is no next file then Process() will be aborted. Abort() can also  be
   // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
   // the SlaveTerminate() and Terminate() are always called. The abort flag
   // can be checked in these methods using GetAbort().

   fAbort = what;
   TString mess = "Abort";
   if (fAbort == kAbortProcess)
      mess = "AbortProcess";
   else if (fAbort == kAbortFile)
      mess = "AbortFile";

   Info(mess, "%s", why);
}

//______________________________________________________________________________
TSelector *TSelector::GetSelector(const char *filename)
{
   // The code in filename is loaded (interpreted or compiled, see below),
   // filename must contain a valid class implementation derived from TSelector.
   //
   // If filename is of the form file.C, the file will be interpreted.
   // If filename is of the form file.C++, the file file.C will be compiled
   // and dynamically loaded. The corresponding binary file and shared
   // library will be deleted at the end of the function.
   // If filename is of the form file.C+, the file file.C will be compiled
   // and dynamically loaded. At next call, if file.C is older than file.o
   // and file.so, the file.C is not compiled, only file.so is loaded.
   //
   // The static function returns a pointer to a TSelector object

   // If the filename does not contain "." assume class is compiled in
   TString localname;
   Bool_t fromFile = kFALSE;
   if (strchr(filename, '.') != 0) {
      //Interpret/compile filename via CINT
      localname  = ".L ";
      localname += filename;
      gROOT->ProcessLine(localname);
      fromFile = kTRUE;
   }

   //loop on all classes known to CINT to find the class on filename
   //that derives from TSelector
   const char *basename = gSystem->BaseName(filename);
   if (!basename) {
      ::Error("TSelector::GetSelector","unable to determine the classname for file %s", filename);
      return 0;
   }
   TString aclicmode,args,io;
   localname = gSystem->SplitAclicMode(basename,aclicmode,args,io);
   Bool_t isCompiled = !fromFile || aclicmode.Length()>0;
   if (localname.Last('.') != kNPOS)
      localname.Remove(localname.Last('.'));

   // if a file was not specified, try to load the class via the interpreter;
   // this returns 0 (== failure) in the case the class is already in memory
   // but does not have a dictionary, so we just raise a flag for better
   // diagnostic in the case the class is not found in the CINT ClassInfo table.
   Bool_t autoloaderr = kFALSE;
   if (!fromFile && gCint->AutoLoad(localname) != 1)
      autoloaderr = kTRUE;

   ClassInfo_t *cl = gCint->ClassInfo_Factory();
   Bool_t ok = kFALSE;
   Bool_t nameFound = kFALSE;
   while (gCint->ClassInfo_Next(cl)) {
      if (localname == gCint->ClassInfo_FullName(cl)) {
         nameFound = kTRUE;
         if (gCint->ClassInfo_IsBase(cl,"TSelector")) ok = kTRUE;
         break;
      }
   }
   if (!ok) {
      if (fromFile) {
         if (nameFound) {
            ::Error("TSelector::GetSelector",
                    "The class %s in file %s does not derive from TSelector.", localname.Data(), filename);
         } else {
            ::Error("TSelector::GetSelector",
                    "The file %s does not define a class named %s.", filename, localname.Data());
         }
      } else {
         if (autoloaderr)
            ::Error("TSelector::GetSelector", "class %s could not be loaded", filename);
         else
            ::Error("TSelector::GetSelector",
                    "class %s does not exist or does not derive from TSelector", filename);
      }
      gCint->ClassInfo_Delete(cl);
      return 0;
   }

   // we can now create an instance of the class
   TSelector *selector = (TSelector*)gCint->ClassInfo_New(cl);
   if (!selector || isCompiled) { 
      gCint->ClassInfo_Delete(cl);
      return selector;
   }

   //interpreted selector: cannot be used as such
   //create a fake selector
   TSelectorCint *select = new TSelectorCint();
   select->Build(selector, cl);
   gCint->ClassInfo_Delete(cl);
   return select;
}

//______________________________________________________________________________
Bool_t TSelector::IsStandardDraw(const char *selec)
{
   // Find out if this is a standard selection used for Draw actions
   // (either TSelectorDraw, TProofDraw or deriving from them).

   // Make sure we have a name
   if (!selec) {
      ::Info("TSelector::IsStandardDraw",
             "selector name undefined - do nothing");
      return kFALSE;
   }

   Bool_t stdselec = kFALSE;
   if (!strchr(selec, '.')) {
      if (strstr(selec, "TSelectorDraw")) {
         stdselec = kTRUE;
      } else {
         TClass *cl = TClass::GetClass(selec);
         if (cl && (cl->InheritsFrom("TProofDraw") ||
                    cl->InheritsFrom("TSelectorDraw")))
            stdselec = kTRUE;
      }
   }

   // We are done
   return stdselec;
}

Bool_t TSelector::ProcessCut(Long64_t /*entry*/) 
{ 
   //    This method is called before processing entry. It is the user's responsability to read
   //    the corresponding entry in memory (may be just a partial read).     
   //    The function returns kTRUE if the entry must be processed,          
   //    kFALSE otherwise. This method is obsolete, use Process().          
   //
   // WARNING when a selector is used with a TChain:
   //    in the Process, ProcessCut, ProcessFill function, you must use
   //    the pointer to the current Tree to call GetEntry(entry).
   //    entry is always the local entry number in the current tree.
   //    Assuming that fChain is the pointer to the TChain being processed,
   //    use fChain->GetTree()->GetEntry(entry);
   
   return kTRUE; 
}

void TSelector::ProcessFill(Long64_t /*entry*/) 
{ 
   // This method is called for all selected entries. User fills histograms
   // in this function.  This method is obsolete, use Process().
   //
   // WARNING when a selector is used with a TChain:
   //    in the Process, ProcessCut, ProcessFill function, you must use
   //    the pointer to the current Tree to call GetEntry(entry).
   //    entry is always the local entry number in the current tree.
   //    Assuming that fChain is the pointer to the TChain being processed,
   //    use fChain->GetTree()->GetEntry(entry);
}

Bool_t TSelector::Process(Long64_t /*entry*/) {
   // The Process() function is called for each entry in the tree (or possibly
   // keyed object in the case of PROOF) to be processed. The entry argument
   // specifies which entry in the currently loaded tree is to be processed.
   // It can be passed to either t01::GetEntry() or TBranch::GetEntry()
   // to read either all or the required parts of the data. When processing
   // keyed objects with PROOF, the object is already loaded and is available
   // via the fObject pointer.
   //
   // This function should contain the "body" of the analysis. It can contain
   // simple or elaborate selection criteria, run algorithms on the data
   // of the event and typically fill histograms.
   //
   // The processing can be stopped by calling Abort().
   //
   // Use fStatus to set the return value of TTree::Process().
   //
   // The return value is currently not used.

   return kFALSE; 
}

 TSelector.cxx:1
 TSelector.cxx:2
 TSelector.cxx:3
 TSelector.cxx:4
 TSelector.cxx:5
 TSelector.cxx:6
 TSelector.cxx:7
 TSelector.cxx:8
 TSelector.cxx:9
 TSelector.cxx:10
 TSelector.cxx:11
 TSelector.cxx:12
 TSelector.cxx:13
 TSelector.cxx:14
 TSelector.cxx:15
 TSelector.cxx:16
 TSelector.cxx:17
 TSelector.cxx:18
 TSelector.cxx:19
 TSelector.cxx:20
 TSelector.cxx:21
 TSelector.cxx:22
 TSelector.cxx:23
 TSelector.cxx:24
 TSelector.cxx:25
 TSelector.cxx:26
 TSelector.cxx:27
 TSelector.cxx:28
 TSelector.cxx:29
 TSelector.cxx:30
 TSelector.cxx:31
 TSelector.cxx:32
 TSelector.cxx:33
 TSelector.cxx:34
 TSelector.cxx:35
 TSelector.cxx:36
 TSelector.cxx:37
 TSelector.cxx:38
 TSelector.cxx:39
 TSelector.cxx:40
 TSelector.cxx:41
 TSelector.cxx:42
 TSelector.cxx:43
 TSelector.cxx:44
 TSelector.cxx:45
 TSelector.cxx:46
 TSelector.cxx:47
 TSelector.cxx:48
 TSelector.cxx:49
 TSelector.cxx:50
 TSelector.cxx:51
 TSelector.cxx:52
 TSelector.cxx:53
 TSelector.cxx:54
 TSelector.cxx:55
 TSelector.cxx:56
 TSelector.cxx:57
 TSelector.cxx:58
 TSelector.cxx:59
 TSelector.cxx:60
 TSelector.cxx:61
 TSelector.cxx:62
 TSelector.cxx:63
 TSelector.cxx:64
 TSelector.cxx:65
 TSelector.cxx:66
 TSelector.cxx:67
 TSelector.cxx:68
 TSelector.cxx:69
 TSelector.cxx:70
 TSelector.cxx:71
 TSelector.cxx:72
 TSelector.cxx:73
 TSelector.cxx:74
 TSelector.cxx:75
 TSelector.cxx:76
 TSelector.cxx:77
 TSelector.cxx:78
 TSelector.cxx:79
 TSelector.cxx:80
 TSelector.cxx:81
 TSelector.cxx:82
 TSelector.cxx:83
 TSelector.cxx:84
 TSelector.cxx:85
 TSelector.cxx:86
 TSelector.cxx:87
 TSelector.cxx:88
 TSelector.cxx:89
 TSelector.cxx:90
 TSelector.cxx:91
 TSelector.cxx:92
 TSelector.cxx:93
 TSelector.cxx:94
 TSelector.cxx:95
 TSelector.cxx:96
 TSelector.cxx:97
 TSelector.cxx:98
 TSelector.cxx:99
 TSelector.cxx:100
 TSelector.cxx:101
 TSelector.cxx:102
 TSelector.cxx:103
 TSelector.cxx:104
 TSelector.cxx:105
 TSelector.cxx:106
 TSelector.cxx:107
 TSelector.cxx:108
 TSelector.cxx:109
 TSelector.cxx:110
 TSelector.cxx:111
 TSelector.cxx:112
 TSelector.cxx:113
 TSelector.cxx:114
 TSelector.cxx:115
 TSelector.cxx:116
 TSelector.cxx:117
 TSelector.cxx:118
 TSelector.cxx:119
 TSelector.cxx:120
 TSelector.cxx:121
 TSelector.cxx:122
 TSelector.cxx:123
 TSelector.cxx:124
 TSelector.cxx:125
 TSelector.cxx:126
 TSelector.cxx:127
 TSelector.cxx:128
 TSelector.cxx:129
 TSelector.cxx:130
 TSelector.cxx:131
 TSelector.cxx:132
 TSelector.cxx:133
 TSelector.cxx:134
 TSelector.cxx:135
 TSelector.cxx:136
 TSelector.cxx:137
 TSelector.cxx:138
 TSelector.cxx:139
 TSelector.cxx:140
 TSelector.cxx:141
 TSelector.cxx:142
 TSelector.cxx:143
 TSelector.cxx:144
 TSelector.cxx:145
 TSelector.cxx:146
 TSelector.cxx:147
 TSelector.cxx:148
 TSelector.cxx:149
 TSelector.cxx:150
 TSelector.cxx:151
 TSelector.cxx:152
 TSelector.cxx:153
 TSelector.cxx:154
 TSelector.cxx:155
 TSelector.cxx:156
 TSelector.cxx:157
 TSelector.cxx:158
 TSelector.cxx:159
 TSelector.cxx:160
 TSelector.cxx:161
 TSelector.cxx:162
 TSelector.cxx:163
 TSelector.cxx:164
 TSelector.cxx:165
 TSelector.cxx:166
 TSelector.cxx:167
 TSelector.cxx:168
 TSelector.cxx:169
 TSelector.cxx:170
 TSelector.cxx:171
 TSelector.cxx:172
 TSelector.cxx:173
 TSelector.cxx:174
 TSelector.cxx:175
 TSelector.cxx:176
 TSelector.cxx:177
 TSelector.cxx:178
 TSelector.cxx:179
 TSelector.cxx:180
 TSelector.cxx:181
 TSelector.cxx:182
 TSelector.cxx:183
 TSelector.cxx:184
 TSelector.cxx:185
 TSelector.cxx:186
 TSelector.cxx:187
 TSelector.cxx:188
 TSelector.cxx:189
 TSelector.cxx:190
 TSelector.cxx:191
 TSelector.cxx:192
 TSelector.cxx:193
 TSelector.cxx:194
 TSelector.cxx:195
 TSelector.cxx:196
 TSelector.cxx:197
 TSelector.cxx:198
 TSelector.cxx:199
 TSelector.cxx:200
 TSelector.cxx:201
 TSelector.cxx:202
 TSelector.cxx:203
 TSelector.cxx:204
 TSelector.cxx:205
 TSelector.cxx:206
 TSelector.cxx:207
 TSelector.cxx:208
 TSelector.cxx:209
 TSelector.cxx:210
 TSelector.cxx:211
 TSelector.cxx:212
 TSelector.cxx:213
 TSelector.cxx:214
 TSelector.cxx:215
 TSelector.cxx:216
 TSelector.cxx:217
 TSelector.cxx:218
 TSelector.cxx:219
 TSelector.cxx:220
 TSelector.cxx:221
 TSelector.cxx:222
 TSelector.cxx:223
 TSelector.cxx:224
 TSelector.cxx:225
 TSelector.cxx:226
 TSelector.cxx:227
 TSelector.cxx:228
 TSelector.cxx:229
 TSelector.cxx:230
 TSelector.cxx:231
 TSelector.cxx:232
 TSelector.cxx:233
 TSelector.cxx:234
 TSelector.cxx:235
 TSelector.cxx:236
 TSelector.cxx:237
 TSelector.cxx:238
 TSelector.cxx:239
 TSelector.cxx:240
 TSelector.cxx:241
 TSelector.cxx:242
 TSelector.cxx:243
 TSelector.cxx:244
 TSelector.cxx:245
 TSelector.cxx:246
 TSelector.cxx:247
 TSelector.cxx:248
 TSelector.cxx:249
 TSelector.cxx:250
 TSelector.cxx:251
 TSelector.cxx:252
 TSelector.cxx:253
 TSelector.cxx:254
 TSelector.cxx:255
 TSelector.cxx:256
 TSelector.cxx:257
 TSelector.cxx:258
 TSelector.cxx:259
 TSelector.cxx:260
 TSelector.cxx:261
 TSelector.cxx:262
 TSelector.cxx:263
 TSelector.cxx:264
 TSelector.cxx:265
 TSelector.cxx:266
 TSelector.cxx:267
 TSelector.cxx:268
 TSelector.cxx:269
 TSelector.cxx:270
 TSelector.cxx:271
 TSelector.cxx:272
 TSelector.cxx:273
 TSelector.cxx:274
 TSelector.cxx:275
 TSelector.cxx:276
 TSelector.cxx:277
 TSelector.cxx:278
 TSelector.cxx:279
 TSelector.cxx:280
 TSelector.cxx:281
 TSelector.cxx:282
 TSelector.cxx:283
 TSelector.cxx:284
 TSelector.cxx:285
 TSelector.cxx:286
 TSelector.cxx:287
 TSelector.cxx:288
 TSelector.cxx:289
 TSelector.cxx:290
 TSelector.cxx:291
 TSelector.cxx:292
 TSelector.cxx:293
 TSelector.cxx:294
 TSelector.cxx:295
 TSelector.cxx:296