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 /// Use a batch mode, where we don't check ROOT status 00138 void UseBatchMode(){ fUseBatchMode = true;} 00139 00140 /// Get pointer to ODB variables 00141 VirtualOdb* GetODB(){return fODB;} 00142 00143 00144 /// Open output ROOT file 00145 void OpenRootFile(int run, std::string midasFilename = std::string("")); 00146 00147 /// Cloe output ROOT file 00148 void CloseRootFile(); 00149 00150 /// Check if output ROOT file is valid and open 00151 bool IsRootFileValid(){ 00152 if(fOutputFile) return true; 00153 return false; 00154 } 00155 00156 00157 void DisableRootOutput(bool disable=true){fDisableRootOutput = disable;}; 00158 00159 int IsRootOutputEnabled(){return !fDisableRootOutput;}; 00160 00161 /// Set the output filename. 00162 /// File name will be $(fOutputFilename)XXX.root, where XXX is run number 00163 void SetOutputFilename(std::string name){fOutputFilename = name;}; 00164 00165 /// This is an alternative, more complicated way of setting the output ROOT filename. 00166 /// In this case the user is given the run number and the midas file name and, 00167 /// from that information, constructs the output ROOT filename themselves. 00168 virtual std::string SetFullOutputFileName(int run, std::string midasFilename){ 00169 return std::string(""); 00170 } 00171 00172 void SetOnlineName(std::string name){fOnlineName = name;}; 00173 00174 /// Provide a way to force program to only process certain event IDs. 00175 /// This method can be called repeatedly to specify several different event IDs to accept. 00176 /// If the method is not called then all eventIDs are accepted. 00177 void ProcessThisEventID(int eventID){ 00178 fProcessEventIDs.push_back(eventID); 00179 }; 00180 00181 /// Little helper method to check if EventID matchs requested EventID list. 00182 bool CheckEventID(int eventId); 00183 00184 /// Suppress the warning methods regarding old timestamp events for online 00185 /// ie warnings about analyzer falling behind data taking. 00186 void SuppressTimestampWarnings(){ fSuppressTimestampWarnings = true;}; 00187 00188 /// Suppress timestamp warnings? true = suppress warnings 00189 bool GetSuppressTimestampWarnings(){ return fSuppressTimestampWarnings;}; 00190 00191 /// Method to set whether analyzer should operate in GET_RECENT mode, 00192 /// where we only process data that is less than 1 second old (this is not default). 00193 /// Setting true will use this option. 00194 void UseOnlyRecent(bool setting = true);//{ fUseOnlyRecent = setting;}; 00195 00196 protected: 00197 00198 bool CreateOutputFile(std::string name, std::string options = "RECREATE"){ 00199 00200 fOutputFile = new TFile(name.c_str(),options.c_str()); 00201 00202 return true; 00203 } 00204 00205 00206 TRootanaEventLoop (); 00207 00208 /// The static pointer to the singleton instance. 00209 static TRootanaEventLoop* fTRootanaEventLoop; 00210 00211 /// TDirectory for online histograms. 00212 TDirectory* fOnlineHistDir; 00213 00214 /// This is a special version of CheckOption that is only used by TRootanaDisplay. 00215 /// This is just so that users still have the ability to set options for 00216 /// executables derived from TRootanaDisplay. 00217 virtual bool CheckOptionRAD(std::string option); 00218 00219 /// Also a special version of usage for TRootanaDisplay. See CheckOptionRAD 00220 virtual void UsageRAD(void); 00221 00222 private: 00223 00224 /// Help Message 00225 void PrintHelp(); 00226 00227 /// Output ROOT file 00228 TFile *fOutputFile; 00229 00230 /// Base part of the output filename 00231 /// File name will be $(fOutputFilename)XXX.root, where XXX is run number 00232 std::string fOutputFilename; 00233 00234 /// Variable for disabling/enabling Root output 00235 bool fDisableRootOutput; 00236 00237 /// Pointer to the ODB access instance 00238 VirtualOdb* fODB; 00239 00240 /// Are we processing offline or online data? 00241 bool fIsOffline; 00242 00243 /// Current run number 00244 int fCurrentRunNumber; 00245 00246 00247 /// Pointer to the physics event; the physics event is what we pass to user. 00248 /// The midas event is accessible through physics event. 00249 /// We make a single instance of the physics event for whole execution, 00250 /// because sometimes the decoded information needs to persist 00251 /// across multiple midas events. 00252 TDataContainer *fDataContainer; 00253 00254 /// This is the set of eventIDs to process 00255 std::vector<int> fProcessEventIDs; 00256 00257 // ________________________________________________ 00258 // Variables for online analysis 00259 00260 /// Buffer to connect to 00261 std::string fBufferName; 00262 00263 /// Name of program, as seen by MIDAS. 00264 std::string fOnlineName; 00265 00266 /// Bool for suppressing the warnings about old timestamps. 00267 bool fSuppressTimestampWarnings; 00268 00269 // ________________________________________________ 00270 // Variables for offline analysis 00271 int fMaxEvents; 00272 00273 // The TApplication... 00274 TApplication *fApp; 00275 00276 // Should we automatically create a Main Window? 00277 bool fCreateMainWindow; 00278 00279 // Use a batch mode. 00280 bool fUseBatchMode; 00281 00282 00283 00284 00285 }; 00286 #endif