00001 // @(#)root/treeplayer:$Id: TSelectorEntries.cxx 31605 2009-12-07 19:50:39Z pcanal $ 00002 // Author: Philippe Canal 09/06/2006 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 // TSelectorEntries // 00015 // // 00016 // // 00017 ////////////////////////////////////////////////////////////////////////// 00018 00019 // The class is derived from the ROOT class TSelector. For more 00020 // information on the TSelector framework see 00021 // $ROOTSYS/README/README.SELECTOR or the ROOT User Manual. 00022 00023 // The following methods are defined in this file: 00024 // Begin(): called everytime a loop on the tree starts, 00025 // a convenient place to create your histograms. 00026 // SlaveBegin(): called after Begin(), when on PROOF called only on the 00027 // slave servers. 00028 // Process(): called for each event, in this function you decide what 00029 // to read and fill your histograms. 00030 // SlaveTerminate: called at the end of the loop on the tree, when on PROOF 00031 // called only on the slave servers. 00032 // Terminate(): called at the end of the loop on the tree, 00033 // a convenient place to draw/fit your histograms. 00034 // 00035 // To use this file, try the following session on your Tree T: 00036 // 00037 // Root > T->Process("TSelectorEntries.C") 00038 // Root > T->Process("TSelectorEntries.C","some options") 00039 // Root > T->Process("TSelectorEntries.C+") 00040 // 00041 00042 #include "TSelectorEntries.h" 00043 #include "TTree.h" 00044 #include "TTreeFormula.h" 00045 #include "TSelectorScalar.h" 00046 00047 //______________________________________________________________________________ 00048 TSelectorEntries::TSelectorEntries(TTree *tree, const char *selection) : 00049 fChain(tree), fSelect(0), fSelectedRows(0), fSelectMultiple(kFALSE) 00050 { 00051 // Default, constructor. 00052 00053 if (selection && selection[0]) { 00054 TSelectorEntries::SetSelection(selection); 00055 } 00056 } 00057 00058 //______________________________________________________________________________ 00059 TSelectorEntries::TSelectorEntries(const char *selection) : 00060 fSelect(0), fSelectedRows(0), fSelectMultiple(kFALSE) 00061 { 00062 // Constructor. 00063 00064 TSelectorEntries::SetSelection(selection); 00065 } 00066 00067 //______________________________________________________________________________ 00068 TSelectorEntries::~TSelectorEntries() 00069 { 00070 // Destructor. 00071 00072 delete fSelect; fSelect = 0; 00073 } 00074 00075 //______________________________________________________________________________ 00076 void TSelectorEntries::Begin(TTree *tree) 00077 { 00078 // The Begin() function is called at the start of the query. 00079 // When running with PROOF Begin() is only called on the client. 00080 // The tree argument is deprecated (on PROOF 0 is passed). 00081 00082 TString option = GetOption(); 00083 fChain = tree; 00084 } 00085 00086 //______________________________________________________________________________ 00087 void TSelectorEntries::SlaveBegin(TTree *tree) 00088 { 00089 // The SlaveBegin() function is called after the Begin() function. 00090 // When running with PROOF SlaveBegin() is called on each slave server. 00091 // The tree argument is deprecated (on PROOF 0 is passed). 00092 00093 fChain = tree; 00094 TString option = GetOption(); 00095 00096 SetStatus(0); 00097 fSelectedRows = 0; 00098 const char *selection = fInput->FindObject("selection")->GetTitle(); 00099 00100 if (strlen(selection)) { 00101 fSelect = new TTreeFormula("Selection",selection,fChain); 00102 fSelect->SetQuickLoad(kTRUE); 00103 if (!fSelect->GetNdim()) {delete fSelect; fSelect = 0; return; } 00104 } 00105 if (fSelect && fSelect->GetMultiplicity()) fSelectMultiple = kTRUE; 00106 00107 fChain->ResetBit(TTree::kForceRead); 00108 } 00109 00110 //______________________________________________________________________________ 00111 Int_t TSelectorEntries::GetEntry(Long64_t entry, Int_t getall) 00112 { 00113 //read entry 00114 return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; 00115 } 00116 00117 //______________________________________________________________________________ 00118 void TSelectorEntries::Init(TTree * /* tree */) 00119 { 00120 // The Init() function is called when the selector needs to initialize 00121 // a new tree or chain. Typically here the branch addresses and branch 00122 // pointers of the tree will be set. 00123 // It is normaly not necessary to make changes to the generated 00124 // code, but the routine can be extended by the user if needed. 00125 // Init() will be called many times when running on PROOF 00126 // (once per file to be processed). 00127 00128 } 00129 00130 //______________________________________________________________________________ 00131 Bool_t TSelectorEntries::Notify() 00132 { 00133 // This function is called at the first entry of a new tree in a chain. 00134 00135 if (fSelect) fSelect->UpdateFormulaLeaves(); 00136 return kTRUE; 00137 } 00138 00139 //______________________________________________________________________________ 00140 Bool_t TSelectorEntries::Process(Long64_t /* entry */) 00141 { 00142 // The Process() function is called for each entry in the tree (or possibly 00143 // keyed object in the case of PROOF) to be processed. The entry argument 00144 // specifies which entry in the currently loaded tree is to be processed. 00145 // It can be passed to either TSelectorEntries::GetEntry() or TBranch::GetEntry() 00146 // to read either all or the required parts of the data. When processing 00147 // keyed objects with PROOF, the object is already loaded and is available 00148 // via the fObject pointer. 00149 // 00150 // This function should contain the "body" of the analysis. It can contain 00151 // simple or elaborate selection criteria, run algorithms on the data 00152 // of the event and typically fill histograms. 00153 // 00154 // The processing can be stopped by calling Abort(). 00155 // 00156 // Use fStatus to set the return value of TTree::Process(). 00157 // 00158 // The return value is currently not used. 00159 00160 if (!fSelectMultiple) { 00161 if (fSelect) { 00162 if ( fSelect->EvalInstance(0) ) { 00163 ++fSelectedRows; 00164 } 00165 } else { 00166 ++fSelectedRows; 00167 } 00168 } else if (fSelect) { 00169 // Grab the array size of the formulas for this entry 00170 Int_t ndata = fSelect->GetNdata(); 00171 00172 // No data at all, let's move on to the next entry. 00173 if (!ndata) return kTRUE; 00174 00175 // Calculate the first values 00176 // Always call EvalInstance(0) to insure the loading 00177 // of the branches. 00178 if (fSelect->EvalInstance(0)) { 00179 ++fSelectedRows; 00180 } else { 00181 for (Int_t i=1;i<ndata;i++) { 00182 if (fSelect->EvalInstance(i)) { 00183 ++fSelectedRows; 00184 break; 00185 } 00186 } 00187 } 00188 } 00189 return kTRUE; 00190 } 00191 00192 //______________________________________________________________________________ 00193 void TSelectorEntries::SetSelection(const char *selection) 00194 { 00195 //set the selection expression 00196 if (!fInput) { 00197 fInput = new TList; 00198 } 00199 TNamed *cselection = (TNamed*)fInput->FindObject("selection"); 00200 if (!cselection) { 00201 cselection = new TNamed("selection",""); 00202 fInput->Add(cselection); 00203 } 00204 cselection->SetTitle(selection); 00205 } 00206 00207 //______________________________________________________________________________ 00208 void TSelectorEntries::SlaveTerminate() 00209 { 00210 // The SlaveTerminate() function is called after all entries or objects 00211 // have been processed. When running with PROOF SlaveTerminate() is called 00212 // on each slave server. 00213 00214 fOutput->Add(new TSelectorScalar("fSelectedRows",fSelectedRows)); 00215 } 00216 00217 //______________________________________________________________________________ 00218 void TSelectorEntries::Terminate() 00219 { 00220 // The Terminate() function is the last function to be called during 00221 // a query. It always runs on the client, it can be used to present 00222 // the results graphically or save the results to file. 00223 00224 TSelectorScalar* rows = (TSelectorScalar*)fOutput->FindObject("fSelectedRows"); 00225 if (rows) 00226 { 00227 fSelectedRows = rows->GetVal(); 00228 } else { 00229 Error("Terminate","fSelectedRows is missing in fOutput"); 00230 } 00231 }