// @(#)root/treeplayer:$Id: TSelectorEntries.cxx 20882 2007-11-19 11:31:26Z rdm $
// Author: Philippe Canal 09/06/2006

/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSelectorEntries                                                     //
//                                                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

// The class is derived from the ROOT class TSelector. For more
// information on the TSelector framework see
// $ROOTSYS/README/README.SELECTOR or the ROOT User Manual.

// The following methods are defined in this file:
//    Begin():        called everytime a loop on the tree starts,
//                    a convenient place to create your histograms.
//    SlaveBegin():   called after Begin(), when on PROOF called only on the
//                    slave servers.
//    Process():      called for each event, in this function you decide what
//                    to read and fill your histograms.
//    SlaveTerminate: called at the end of the loop on the tree, when on PROOF
//                    called only on the slave servers.
//    Terminate():    called at the end of the loop on the tree,
//                    a convenient place to draw/fit your histograms.
//
// To use this file, try the following session on your Tree T:
//
// Root > T->Process("TSelectorEntries.C")
// Root > T->Process("TSelectorEntries.C","some options")
// Root > T->Process("TSelectorEntries.C+")
//

#include "TSelectorEntries.h"
#include "TTree.h"
#include "TTreeFormula.h"
#include "TSelectorScalar.h"

//______________________________________________________________________________
TSelectorEntries::TSelectorEntries(TTree *tree, const char *selection) : 
   fChain(tree), fSelect(0), fSelectedRows(0), fSelectMultiple(kFALSE) 
{ 
   // Default, constructor.   

   if (selection && selection[0]) {
      TSelectorEntries::SetSelection(selection);
   }
}

//______________________________________________________________________________
TSelectorEntries::TSelectorEntries(const char *selection) : 
   fSelect(0), fSelectedRows(0), fSelectMultiple(kFALSE) 
{ 
   // Constructor.

   TSelectorEntries::SetSelection(selection);
}

//______________________________________________________________________________
TSelectorEntries::~TSelectorEntries() 
{
   // Destructor.

   delete fSelect; fSelect = 0;
}

//______________________________________________________________________________
void TSelectorEntries::Begin(TTree *tree)
{
   // The Begin() function is called at the start of the query.
   // When running with PROOF Begin() is only called on the client.
   // The tree argument is deprecated (on PROOF 0 is passed).

   TString option = GetOption();
   fChain = tree;
}

//______________________________________________________________________________
void TSelectorEntries::SlaveBegin(TTree *tree)
{
   // The SlaveBegin() function is called after the Begin() function.
   // When running with PROOF SlaveBegin() is called on each slave server.
   // The tree argument is deprecated (on PROOF 0 is passed).

   fChain = tree;
   TString option = GetOption();

   SetStatus(0);
   fSelectedRows   = 0;
   const char *selection = fInput->FindObject("selection")->GetTitle();

   if (strlen(selection)) {
      fSelect = new TTreeFormula("Selection",selection,fChain);
      fSelect->SetQuickLoad(kTRUE);
      if (!fSelect->GetNdim()) {delete fSelect; fSelect = 0; return; }
   }
   if (fSelect && fSelect->GetMultiplicity()) fSelectMultiple = kTRUE;

   fChain->ResetBit(TTree::kForceRead);
}

//______________________________________________________________________________
Int_t TSelectorEntries::GetEntry(Long64_t entry, Int_t getall)
{
   //read entry
   return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; 
}

//______________________________________________________________________________
void TSelectorEntries::Init(TTree * /* tree */)
{
   // The Init() function is called when the selector needs to initialize
   // a new tree or chain. Typically here the branch addresses and branch
   // pointers of the tree will be set.
   // It is normaly not necessary to make changes to the generated
   // code, but the routine can be extended by the user if needed.
   // Init() will be called many times when running on PROOF
   // (once per file to be processed).

}

//______________________________________________________________________________
Bool_t TSelectorEntries::Notify()
{
   // This function is called at the first entry of a new tree in a chain.

   if (fSelect) fSelect->UpdateFormulaLeaves();
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TSelectorEntries::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 TSelectorEntries::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.

   if (!fSelectMultiple) {
      if (fSelect) {
         if ( fSelect->EvalInstance(0) ) {
            ++fSelectedRows;
         }
      } else {
         ++fSelectedRows;
      }
   } else {
      // Grab the array size of the formulas for this entry
      Int_t ndata = fSelect->GetNdata();

      // No data at all, let's move on to the next entry.
      if (!ndata) return kTRUE;

      // Calculate the first values
      if (fSelect) {
         // Always call EvalInstance(0) to insure the loading
         // of the branches.
         if (fSelect->EvalInstance(0)) {
            ++fSelectedRows;
         } else {
            for (Int_t i=1;i<ndata;i++) {
               if (fSelect->EvalInstance(i)) {
                  ++fSelectedRows;
                  break;
               }
            }
         }
      }
   }
   return kTRUE;
}

//______________________________________________________________________________
void TSelectorEntries::SetSelection(const char *selection)
{
   //set the selection expression
   if (!fInput) {
      fInput = new TList;
   }
   TNamed *cselection = (TNamed*)fInput->FindObject("selection");
   if (!cselection) {
      cselection = new TNamed("selection","");
      fInput->Add(cselection);
   }
   cselection->SetTitle(selection);
}

//______________________________________________________________________________
void TSelectorEntries::SlaveTerminate()
{
   // The SlaveTerminate() function is called after all entries or objects
   // have been processed. When running with PROOF SlaveTerminate() is called
   // on each slave server.

   fOutput->Add(new TSelectorScalar("fSelectedRows",fSelectedRows));
}

//______________________________________________________________________________
void TSelectorEntries::Terminate()
{
   // The Terminate() function is the last function to be called during
   // a query. It always runs on the client, it can be used to present
   // the results graphically or save the results to file.

   TSelectorScalar* rows = (TSelectorScalar*)fOutput->FindObject("fSelectedRows");
   if (rows)
   {
      fSelectedRows = rows->GetVal();
   } else {
      Error("Terminate","fSelectedRows is missing in fOutput");
   }
}

Last change: Wed Jun 25 08:52:47 2008
Last generated: 2008-06-25 08:52

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.