TSelector.cxx

Go to the documentation of this file.
00001 // @(#)root/tree:$Id: TSelector.cxx 34277 2010-07-01 10:37:08Z rdm $
00002 // Author: Rene Brun   05/02/97
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 ////////////////////////////////////////////////////////////////////////////
00013 //                                                                        //
00014 // A TSelector object is used by the TTree::Draw, TTree::Scan,            //
00015 // TTree::Process to navigate in a TTree and make selections.             //
00016 // It contains the following main methods:                                //
00017 //                                                                        //
00018 // void TSelector::Init(TTree *t). Called every time a new TTree is       //
00019 //    attached.                                                           //
00020 // void TSelector::Begin(). This method is called before looping on the   //
00021 //    events in the Tree. The user can create his histograms in this      //
00022 //    function. When using PROOF Begin() is called on the client only.    //
00023 //    Histogram creation should preferable be done in SlaveBegin() in     //
00024 //    that case.                                                          //
00025 // void TSelector::SlaveBegin(). This method is called on each PROOF      //
00026 //    worker node. The user can create his histograms in this method.     //
00027 //    In local mode this method is called on the client too.              //
00028 //                                                                        //
00029 // Bool_t TSelector::Notify(). This method is called at the first entry   //
00030 //    of a new file in a chain.                                           //
00031 //                                                                        //
00032 // Bool_t TSelector::Process(Long64_t entry). This method is called       //
00033 //    to process an event. It is the user's responsability to read        //
00034 //    the corresponding entry in memory (may be just a partial read).     //
00035 //    Once the entry is in memory one can apply a selection and if the    //
00036 //    event is selected histograms can be filled. Processing stops        //
00037 //    when this function returns kFALSE. This function combines the       //
00038 //    next two functions in one, avoiding to have to maintain state       //
00039 //    in the class to communicate between these two functions.             //
00040 //    See WARNING below about entry.                                      //
00041 //    This method is used by PROOF.                                       //
00042 // Bool_t TSelector::ProcessCut(Long64_t entry). This method is called    //
00043 //    before processing entry. It is the user's responsability to read    //
00044 //    the corresponding entry in memory (may be just a partial read).     //
00045 //    The function returns kTRUE if the entry must be processed,          //
00046 //    kFALSE otherwise. This method is obsolete, use Process().           //
00047 //    See WARNING below about entry.                                      //
00048 // void TSelector::ProcessFill(Long64_t entry). This method is called     //
00049 //    for all selected events. User fills histograms in this function.    //
00050 //    This method is obsolete, use Process().                             //
00051 //    See WARNING below about entry.                                      //
00052 // void TSelector::SlaveTerminate(). This method is called at the end of  //
00053 //    the loop on all PROOF worker nodes. In local mode this method is    //
00054 //    called on the client too.                                           //
00055 // void TSelector::Terminate(). This method is called at the end of       //
00056 //    the loop on all events. When using PROOF Terminate() is call on     //
00057 //    the client only. Typically one performs the fits on the produced    //
00058 //    histograms or write the histograms to file in this method.          //
00059 //                                                                        //
00060 // WARNING when a selector is used with a TChain:                         //
00061 //    in the Process, ProcessCut, ProcessFill function, you must use      //
00062 //    the pointer to the current Tree to call GetEntry(entry).            //
00063 //    entry is always the local entry number in the current tree.         //
00064 //    Assuming that fChain is the pointer to the TChain being processed,  //
00065 //    use fChain->GetTree()->GetEntry(entry);                             //
00066 //                                                                        //
00067 ////////////////////////////////////////////////////////////////////////////
00068 
00069 #include "TROOT.h"
00070 #include "TSystem.h"
00071 #include "TTree.h"
00072 #include "TError.h"
00073 #include "TSelectorCint.h"
00074 #include "TClass.h"
00075 #include "TInterpreter.h"
00076 
00077 
00078 ClassImp(TSelector)
00079 
00080 //______________________________________________________________________________
00081 TSelector::TSelector() : TObject()
00082 {
00083    // Default selector ctor.
00084 
00085    fStatus = 0;
00086    fAbort  = kContinue;
00087    fObject = 0;
00088    fInput  = 0;
00089    fOutput = new TSelectorList;
00090    fOutput->SetOwner();
00091 }
00092 
00093 //______________________________________________________________________________
00094 TSelector::~TSelector()
00095 {
00096    // Selector destructor.
00097 
00098    delete fOutput;
00099 }
00100 
00101 //______________________________________________________________________________
00102 void TSelector::Abort(const char *why, EAbort what)
00103 {
00104    // Abort processing. If what = kAbortProcess, the Process() loop will be
00105    // aborted. If what = kAbortFile, the current file in a chain will be
00106    // aborted and the processing will continue with the next file, if there
00107    // is no next file then Process() will be aborted. Abort() can also  be
00108    // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
00109    // the SlaveTerminate() and Terminate() are always called. The abort flag
00110    // can be checked in these methods using GetAbort().
00111 
00112    fAbort = what;
00113    TString mess = "Abort";
00114    if (fAbort == kAbortProcess)
00115       mess = "AbortProcess";
00116    else if (fAbort == kAbortFile)
00117       mess = "AbortFile";
00118 
00119    Info(mess, "%s", why);
00120 }
00121 
00122 //______________________________________________________________________________
00123 TSelector *TSelector::GetSelector(const char *filename)
00124 {
00125    // The code in filename is loaded (interpreted or compiled, see below),
00126    // filename must contain a valid class implementation derived from TSelector.
00127    //
00128    // If filename is of the form file.C, the file will be interpreted.
00129    // If filename is of the form file.C++, the file file.C will be compiled
00130    // and dynamically loaded. The corresponding binary file and shared
00131    // library will be deleted at the end of the function.
00132    // If filename is of the form file.C+, the file file.C will be compiled
00133    // and dynamically loaded. At next call, if file.C is older than file.o
00134    // and file.so, the file.C is not compiled, only file.so is loaded.
00135    //
00136    // The static function returns a pointer to a TSelector object
00137 
00138    // If the filename does not contain "." assume class is compiled in
00139    TString localname;
00140    Bool_t fromFile = kFALSE;
00141    if (strchr(filename, '.') != 0) {
00142       //Interpret/compile filename via CINT
00143       localname  = ".L ";
00144       localname += filename;
00145       gROOT->ProcessLine(localname);
00146       fromFile = kTRUE;
00147    }
00148 
00149    //loop on all classes known to CINT to find the class on filename
00150    //that derives from TSelector
00151    const char *basename = gSystem->BaseName(filename);
00152    if (!basename) {
00153       ::Error("TSelector::GetSelector","unable to determine the classname for file %s", filename);
00154       return 0;
00155    }
00156    TString aclicmode,args,io;
00157    localname = gSystem->SplitAclicMode(basename,aclicmode,args,io);
00158    Bool_t isCompiled = !fromFile || aclicmode.Length()>0;
00159    if (localname.Last('.') != kNPOS)
00160       localname.Remove(localname.Last('.'));
00161 
00162    // if a file was not specified, try to load the class via the interpreter;
00163    // this returns 0 (== failure) in the case the class is already in memory
00164    // but does not have a dictionary, so we just raise a flag for better
00165    // diagnostic in the case the class is not found in the CINT ClassInfo table.
00166    Bool_t autoloaderr = kFALSE;
00167    if (!fromFile && gCint->AutoLoad(localname) != 1)
00168       autoloaderr = kTRUE;
00169 
00170    ClassInfo_t *cl = gCint->ClassInfo_Factory();
00171    Bool_t ok = kFALSE;
00172    while (gCint->ClassInfo_Next(cl)) {
00173       if (localname == gCint->ClassInfo_FullName(cl)) {
00174          if (gCint->ClassInfo_IsBase(cl,"TSelector")) ok = kTRUE;
00175          break;
00176       }
00177    }
00178    if (!ok) {
00179       if (fromFile) {
00180          ::Error("TSelector::GetSelector",
00181          "file %s does not have a valid class deriving from TSelector", filename);
00182       } else {
00183          if (autoloaderr)
00184             ::Error("TSelector::GetSelector", "class %s could not be loaded", filename);
00185          else
00186             ::Error("TSelector::GetSelector",
00187                     "class %s does not exist or does not derive from TSelector", filename);
00188       }
00189       return 0;
00190    }
00191 
00192    // we can now create an instance of the class
00193    TSelector *selector = (TSelector*)gCint->ClassInfo_New(cl);
00194    if (!selector || isCompiled) return selector;
00195 
00196    //interpreted selector: cannot be used as such
00197    //create a fake selector
00198    TSelectorCint *select = new TSelectorCint();
00199    select->Build(selector, cl);
00200    gCint->ClassInfo_Delete(cl);
00201    return select;
00202 }
00203 
00204 //______________________________________________________________________________
00205 Bool_t TSelector::IsStandardDraw(const char *selec)
00206 {
00207    // Find out if this is a standard selection used for Draw actions
00208    // (either TSelectorDraw, TProofDraw or deriving from them).
00209 
00210    // Make sure we have a name
00211    if (!selec) {
00212       ::Info("TSelector::IsStandardDraw",
00213              "selector name undefined - do nothing");
00214       return kFALSE;
00215    }
00216 
00217    Bool_t stdselec = kFALSE;
00218    if (!strchr(selec, '.')) {
00219       if (strstr(selec, "TSelectorDraw")) {
00220          stdselec = kTRUE;
00221       } else {
00222          TClass *cl = TClass::GetClass(selec);
00223          if (cl && (cl->InheritsFrom("TProofDraw") ||
00224                     cl->InheritsFrom("TSelectorDraw")))
00225             stdselec = kTRUE;
00226       }
00227    }
00228 
00229    // We are done
00230    return stdselec;
00231 }

Generated on Tue Jul 5 15:34:08 2011 for ROOT_528-00b_version by  doxygen 1.5.1