00001 #ifndef TRootanaEventLoop_hxx_seen 00002 #define TRootanaEventLoop_hxx_seen 00003 00004 // ROOTANA includes 00005 #include "TMidasFile.h" 00006 #include "TMidasOnline.h" 00007 #include "TMidasEvent.h" 00008 #include "VirtualOdb.h" 00009 #include "TDataContainer.hxx" 00010 00011 // ROOT includes 00012 #include "TApplication.h" 00013 #include "TDirectory.h" 00014 #include <TTimer.h> 00015 #include <TFile.h> 00016 00017 // C++ includes 00018 #include <stdio.h> 00019 #include <sys/time.h> 00020 #include <iostream> 00021 #include <assert.h> 00022 #include <typeinfo> 00023 00024 00025 /// This is a base class for event loops that are derived from rootana. 00026 /// 00027 /// The user should create a class that derives from this TRootanaEventLoop class 00028 /// and then fill in the methods that they want to implement. 00029 /// 00030 /// The user must implement the method ProcessMidasEvent(), which will get executed 00031 /// on each event. 00032 /// 00033 /// The user can also implement methods like Initialize, BeginRun, EndRun, Finalize 00034 /// if there are actions they want to execute at certain points. 00035 /// 00036 /// The event loop will work in both offline and online mode (online only if the user has MIDAS installed). 00037 /// 00038 /// In example of this type of event loop is shown in examples/analyzer_example.cxx 00039 /// 00040 class TRootanaEventLoop { 00041 00042 public: 00043 virtual ~TRootanaEventLoop (); 00044 00045 00046 static TRootanaEventLoop& Get(void); 00047 00048 /// Method to get the data container that event loop owns. 00049 TDataContainer* GetDataContainer(){return fDataContainer;}; 00050 00051 00052 /// The main method, called for each event. Users must implement this 00053 /// function! 00054 virtual bool ProcessMidasEvent(TDataContainer& dataContainer) = 0; 00055 //virtual bool ProcessEvent(TMidasEvent& event) = 0; 00056 00057 00058 /// Called after the arguments are processes but before reading the first 00059 /// event is read 00060 virtual void Initialize(void); 00061 00062 /// Called before the first event of a file is read, but you should prefer 00063 /// Initialize() for general initialization. This method will be called 00064 /// once for each input file. 00065 virtual void BeginRun(int transition,int run,int time); 00066 00067 /// Called after the last event of a file is read, but you should prefer 00068 /// Finalize() for general finalization. This method will be called once 00069 /// for each input file. 00070 virtual void EndRun(int transition,int run,int time); 00071 00072 /// Called after the last event has been processed, but before any open 00073 /// output files are closed. 00074 virtual void Finalize(); 00075 00076 /// Called when there is a usage error. This code should print a usage 00077 /// message and then return. 00078 virtual void Usage(void); 00079 00080 /// Check an option and return true if it is valid. 00081 /// The return value is used to flag errors during option handling. If 00082 /// the options are valid, then CheckOption should return true to indicate 00083 /// success. If there is a problem processing the options, then CheckOption 00084 /// should return false. If this returns false, then the event loop will 00085 /// print the Usage message and exit with a non zero value (i.e. indicate 00086 /// failure). 00087 virtual bool CheckOption(std::string option); 00088 00089 /// The PreFilter method allows user to specify whether to ignore a particular event. 00090 /// Specifically, if PreFilter returns 00091 /// 00092 /// true -> then ProcessMidasEvent will be called 00093 /// or 00094 /// false -> then ProcessMidasEvent will not be called 00095 /// 00096 /// This is particularly useful for the RootanaDisplay, where you might 00097 /// want to only process and plot certain events. 00098 virtual bool PreFilter(TDataContainer& dataContainer){return true;} 00099 00100 /// Are we processing online data? 00101 bool IsOnline() const {return !fIsOffline;}; 00102 00103 /// Are we processing offline data? 00104 bool IsOffline() const {return fIsOffline;}; 00105 00106 /// Current Run Number 00107 int GetCurrentRunNumber() const {return fCurrentRunNumber;}; 00108 00109 /// Current Run Number 00110 void SetCurrentRunNumber(int run) {fCurrentRunNumber = run;}; 00111 00112 /// Method to actually process the Midas information, either as file or online. 00113 int ExecuteLoop(int argc, char *argv[]); 00114 00115 int ProcessMidasFile(TApplication*app,const char*fname); 00116 00117 #ifdef HAVE_MIDAS 00118 int ProcessMidasOnline(TApplication*app, const char* hostname, const char* exptname); 00119 #endif 00120 00121 00122 /// This static templated function will make it a little easier 00123 /// for users to create the singleton instance. 00124 template<typename T> 00125 static void CreateSingleton() 00126 { 00127 if(fTRootanaEventLoop) 00128 std::cout << "Singleton has already been created" << std::endl; 00129 else 00130 fTRootanaEventLoop = new T(); 00131 } 00132 00133 00134 /// Disable automatic creation of MainWindow 00135 void DisableAutoMainWindow(){ fCreateMainWindow = false;} 00136 00137 /// Get pointer to ODB variables 00138 VirtualOdb* GetODB(){return fODB;} 00139 00140 00141 /// Open output ROOT file 00142 void OpenRootFile(int run); 00143 00144 /// Cloe output ROOT file 00145 void CloseRootFile(); 00146 00147 /// Check if output ROOT file is valid and open 00148 bool IsRootFileValid(){ 00149 if(fOutputFile) return true; 00150 return false; 00151 } 00152 00153 00154 void DisableRootOutput(bool disable=true){fDisableRootOutput = disable;}; 00155 00156 int IsRootOutputEnabled(){return !fDisableRootOutput;}; 00157 00158 /// Set the output filename. 00159 /// File name will be $(fOutputFilename)XXX.root, where XXX is run number 00160 void SetOutputFilename(std::string name){fOutputFilename = name;}; 00161 00162 void SetOnlineName(std::string name){fOnlineName = name;}; 00163 00164 /// Provide a way to force program to only process certain event IDs. 00165 /// This method can be called repeatedly to specify several different event IDs to accept. 00166 /// If the method is not called then all eventIDs are accepted. 00167 void ProcessThisEventID(int eventID){ 00168 fProcessEventIDs.push_back(eventID); 00169 }; 00170 00171 /// Little helper method to check if EventID matchs requested EventID list. 00172 bool CheckEventID(int eventId); 00173 00174 /// Suppress the warning methods regarding old timestamp events for online 00175 /// ie warnings about analyzer falling behind data taking. 00176 void SuppressTimestampWarnings(){ fSuppressTimestampWarnings = true;}; 00177 00178 /// Suppress timestamp warnings? true = suppress warnings 00179 bool GetSuppressTimestampWarnings(){ return fSuppressTimestampWarnings;}; 00180 00181 00182 protected: 00183 00184 bool CreateOutputFile(std::string name, std::string options = "RECREATE"){ 00185 00186 fOutputFile = new TFile(name.c_str(),options.c_str()); 00187 00188 return true; 00189 } 00190 00191 00192 TRootanaEventLoop (); 00193 00194 /// The static pointer to the singleton instance. 00195 static TRootanaEventLoop* fTRootanaEventLoop; 00196 00197 /// TDirectory for online histograms. 00198 TDirectory* fOnlineHistDir; 00199 00200 /// This is a special version of CheckOption that is only used by TRootanaDisplay. 00201 /// This is just so that users still have the ability to set options for 00202 /// executables derived from TRootanaDisplay. 00203 virtual bool CheckOptionRAD(std::string option); 00204 00205 /// Also a special version of usage for TRootanaDisplay. See CheckOptionRAD 00206 virtual void UsageRAD(void); 00207 00208 private: 00209 00210 /// Help Message 00211 void PrintHelp(); 00212 00213 /// Output ROOT file 00214 TFile *fOutputFile; 00215 00216 /// Base part of the output filename 00217 /// File name will be $(fOutputFilename)XXX.root, where XXX is run number 00218 std::string fOutputFilename; 00219 00220 /// Variable for disabling/enabling Root output 00221 bool fDisableRootOutput; 00222 00223 /// Pointer to the ODB access instance 00224 VirtualOdb* fODB; 00225 00226 /// Are we processing offline or online data? 00227 bool fIsOffline; 00228 00229 /// Current run number 00230 int fCurrentRunNumber; 00231 00232 00233 /// Pointer to the physics event; the physics event is what we pass to user. 00234 /// The midas event is accessible through physics event. 00235 /// We make a single instance of the physics event for whole execution, 00236 /// because sometimes the decoded information needs to persist 00237 /// across multiple midas events. 00238 TDataContainer *fDataContainer; 00239 00240 /// This is the set of eventIDs to process 00241 std::vector<int> fProcessEventIDs; 00242 00243 // ________________________________________________ 00244 // Variables for online analysis 00245 00246 /// Buffer to connect to 00247 std::string fBufferName; 00248 00249 /// Name of program, as seen by MIDAS. 00250 std::string fOnlineName; 00251 00252 /// Bool for suppressing the warnings about old timestamps. 00253 bool fSuppressTimestampWarnings; 00254 00255 // ________________________________________________ 00256 // Variables for offline analysis 00257 int fMaxEvents; 00258 00259 // The TApplication... 00260 TApplication *fApp; 00261 00262 // Should we automatically create a Main Window? 00263 bool fCreateMainWindow; 00264 00265 00266 00267 00268 }; 00269 #endif
1.6.1