00001 #ifndef HZZ2L2NU_INCLUDE_LOOPER_H_ 00002 #define HZZ2L2NU_INCLUDE_LOOPER_H_ 00003 00004 #include <algorithm> 00005 #include <string> 00006 00007 #include <boost/program_options.hpp> 00008 00009 #include <Dataset.h> 00010 #include <Logger.h> 00011 #include <Options.h> 00012 00013 00024 template<typename AnalysisClass> 00025 class Looper { 00026 public: 00028 Looper(Options const &options); 00029 00035 static boost::program_options::options_description OptionsDescription(); 00036 00038 void Run(); 00039 00040 private: 00042 Dataset dataset_; 00043 00045 AnalysisClass analysis_; 00046 00048 int64_t numEvents_; 00049 }; 00050 00051 00052 template<typename AnalysisClass> 00053 Looper<AnalysisClass>::Looper(Options const &options) 00054 : dataset_{DatasetInfo{options.GetAs<std::string>("ddf"), options}, 00055 options.GetAs<int>("skip-files"), 00056 options.GetAs<int>("max-files")}, 00057 analysis_{options, dataset_} { 00058 00059 auto const maxEvents = options.GetAs<int64_t>("max-events"); 00060 00061 if (maxEvents >= 0) 00062 numEvents_ = std::min(maxEvents, dataset_.NumEntries()); 00063 else 00064 numEvents_ = dataset_.NumEntries(); 00065 } 00066 00067 00068 template<typename AnalysisClass> 00069 boost::program_options::options_description 00070 Looper<AnalysisClass>::OptionsDescription() { 00071 namespace po = boost::program_options; 00072 00073 po::options_description optionsDescription{"Dataset"}; 00074 optionsDescription.add_options() 00075 ("ddf,d", po::value<std::string>()->required(), 00076 "Path to dataset definition file (required)") 00077 ("max-events", po::value<int64_t>()->default_value(-1), 00078 "Maximal number of events to read; -1 means all") 00079 ("skip-files", po::value<int>()->default_value(0), 00080 "Number of files to skip at the beginning of the dataset") 00081 ("max-files", po::value<int>()->default_value(-1), 00082 "Maximal number of files to read; -1 means all"); 00083 00084 optionsDescription.add(AnalysisClass::OptionsDescription()); 00085 return optionsDescription; 00086 } 00087 00088 00089 template<typename AnalysisClass> 00090 void Looper<AnalysisClass>::Run() { 00091 LOG_DEBUG << "Will run over " << numEvents_ << " events."; 00092 int64_t numSelected = 0; 00093 00094 for (int64_t iEvent = 0; iEvent < numEvents_; ++iEvent) { 00095 if (iEvent % 10000 == 0) { 00096 LOG_INFO << Logger::TimeStamp << " Event " << iEvent << " out of " 00097 << numEvents_; 00098 } 00099 dataset_.SetEntry(iEvent); 00100 if (analysis_.ProcessEvent()) 00101 ++numSelected; 00102 } 00103 00104 analysis_.PostProcessing(); 00105 LOG_INFO << Logger::TimeStamp << " Finishing. Total events selected: " 00106 << numSelected << "."; 00107 } 00108 00109 #endif // HZZ2L2NU_INCLUDE_LOOPER_H_ 00110