#ifndef FairTSBufferFunctionalFunctional_H_ #define FairTSBufferFunctionalFunctional_H_ #include "FairTimeStamp.h" // for FairTimeStamp #include "Riosfwd.h" // for ostream #include "Rtypes.h" // for Int_t, Bool_t, Double_t, etc #include "TObject.h" // for TObject #include "TString.h" // for TString #include // for binary_function #include // for operator<<, basic_ostream, etc class TBranch; class TClonesArray; class TTree; /** * \class BinaryFunctor * \brief Base class for all functors which are used in the FairTSBufferFunctional * \see FairTSBufferFunctional * * The class is a base class to control which data is extracted by the FairTSBufferFunctional class for processing. * The important method to overwrite is Call. It gets the actual data which is read in from the tree and a parameter. * If the actual data is not anymore part of the data you want to have Call returns true to stop the reading of data. * Otherwise it should return false. * The method TimeOut is used to break the processing if for example always the same data is requested. */ class BinaryFunctor : public std::binary_function { public : virtual bool operator() (FairTimeStamp* a, double b) {return Call(a,b);}; virtual bool Call(FairTimeStamp* a, double b) = 0; virtual bool TimeOut() {return false;} virtual void ResetTimeOut() {}; virtual ~BinaryFunctor() {}; }; /** * \class StopTime * Gives you all the data which is older than the given parameter StopTime. * It does not return the data requested before. */ class StopTime : public BinaryFunctor { public : StopTime():fRequestTime(-1), fOldTime(-1), fSameTimeRequestCounter(0) {}; /** * \parameter b: StopTime: All data older than StopTime is returned */ bool Call(FairTimeStamp* a, double b) { fRequestTime = b; //std::cout << "StopTime: " << a->GetTimeStamp() << " > " << b << std::endl; return a->GetTimeStamp() > b; }; bool TimeOut() { if (fRequestTime != fOldTime) { fOldTime = fRequestTime; fSameTimeRequestCounter = 0; //std::cout << "RequestedTime: " << fRequestTime << std::endl; return false; } else if (fRequestTime == fOldTime) { std::cout << "-I- FairTSBufferFunctional StopTime has requested the same data as before: " << fRequestTime << std::endl; fSameTimeRequestCounter++; } else { std::cout << "-E- FairTSBufferFunctional StopTime Functor has requested time " << fRequestTime << " smaller than old time " << fOldTime << std::endl; return true; } if (fSameTimeRequestCounter > 9) { return true; } else { return false; } } void ResetTimeOut() {fSameTimeRequestCounter = 0;} private : double fRequestTime; double fOldTime; int fSameTimeRequestCounter; }; /** * \class TimeGap * Returns you all the data between two time gaps of a given length. */ class TimeGap : public BinaryFunctor { public: TimeGap():fOldTime(-1.) {}; /** * \parameter b : TimeGap: All data between two time gaps which are larger than TimeGap are returned */ bool Call(FairTimeStamp* a, double b) { double aTime = a->GetTimeStamp(); if (fOldTime < 0) { fOldTime = aTime; return false; } if (aTime - fOldTime > b) { fOldTime = aTime; return true; } else { fOldTime = aTime; return false; } }; private: double fOldTime; }; /** * \class FairTSBufferFunctional * \brief A class to access time ordered data in a root branch * * In the constructor of the class one has to give the branch name of the data, the tree the data is stored in * and a BinaryFunctor which contains the method how the data should be extracted. Several example functors already exists. * To extract the data one has to call GetData with a parameter which fits to the selected functor. * GetData returns a TClonesArray which contains the data. * * * Be careful! The buffer runs through the time ordered data in one time direction only. This means that you cannot request data which is older than the * data you have requested before. * * Addition: This is not true anymore. GetData(Double_t, Double_t) is able to get also data which is older but this only works if you request a fixed time * via StopTime functor. For other functors the behavior is unpredictable. * * Created on: Feb 18, 201 * Author: stockman */ class FairTSBufferFunctional : public TObject { public: FairTSBufferFunctional(TString branchName, TTree* sourceTree, BinaryFunctor* stopFunction, BinaryFunctor* startFunction = 0); virtual ~FairTSBufferFunctional() {}; TClonesArray* GetData(Double_t stopParameter); TClonesArray* GetData(Double_t startParameter, Double_t stopParameter); Int_t GetBranchIndex() {return fBranchIndex;} void SetStartFunction(BinaryFunctor* function) {fStartFunction=function;} void SetStopFunction(BinaryFunctor* function) {fStopFunction = function;} Bool_t AllDataProcessed(); Bool_t TimeOut() { Bool_t stopTimeOut = fStopFunction->TimeOut(); Bool_t startTimeOut = kTRUE; if (fStartFunction != 0) { startTimeOut = fStartFunction->TimeOut(); // if (startTimeOut == kTRUE && stopTimeOut == kFALSE){ // fStartFunction->ResetTimeOut(); // } // else if (startTimeOut == kFALSE && stopTimeOut == kTRUE){ // fStopFunction->ResetTimeOut(); // } } return (stopTimeOut && startTimeOut); } Int_t FindStartIndex(Double_t startParameter); private: void ReadInNextFilledEntry(); Int_t ReadInPreviousFilledEntry(Int_t startEntry); void ReadInNextEntry(); //** used only if no function is given and input data is directly passed through to the OutputArray void ReadInEntry(Int_t number); void AbsorbDataBufferArray(); //< Absorbs the complete data from fInputArray to fBufferArray TClonesArray* fOutputArray; TClonesArray* fBufferArray; TClonesArray* fInputArray; BinaryFunctor* fStartFunction; BinaryFunctor* fStopFunction; TBranch* fBranch; Int_t fBranchIndex; Int_t fStartIndex; Int_t fVerbose; FairTSBufferFunctional(const FairTSBufferFunctional&); FairTSBufferFunctional& operator=(const FairTSBufferFunctional&); ClassDef(FairTSBufferFunctional,0); }; #endif