Go to the documentation of this file.00001 #include <boost/regex.hpp>
00002
00003 #include "TFile.h"
00004 #include "TTreeCache.h"
00005 #include "TError.h"
00006 #include "TMath.h"
00007
00008 #include "Fireworks/Core/interface/FWFileEntry.h"
00009 #include "DataFormats/FWLite/interface/Handle.h"
00010 #include "FWCore/Common/interface/TriggerNames.h"
00011 #include "DataFormats/Common/interface/TriggerResults.h"
00012
00013 #define private public
00014 #include "Fireworks/Core/interface/FWEventItem.h"
00015 #undef private
00016
00017 #include "Fireworks/Core/interface/FWEventItemsManager.h"
00018 #include "Fireworks/Core/interface/fwLog.h"
00019
00020 FWFileEntry::FWFileEntry(const std::string& name) :
00021 m_name(name), m_file(0), m_eventTree(0), m_event(0),
00022 m_needUpdate(true), m_globalEventList(0)
00023 {
00024 openFile();
00025 }
00026
00027 FWFileEntry::~FWFileEntry()
00028 {
00029 for(std::list<Filter*>::iterator i = m_filterEntries.begin(); i != m_filterEntries.end(); ++i)
00030 delete (*i)->m_eventList;
00031
00032 delete m_globalEventList;
00033 }
00034
00035 void FWFileEntry::openFile()
00036 {
00037 gErrorIgnoreLevel = 3000;
00038 TFile *newFile = TFile::Open(m_name.c_str());
00039 if (newFile == 0 || newFile->IsZombie() || !newFile->Get("Events")) {
00040
00041
00042 throw std::runtime_error("Invalid file. Ignored.");
00043 }
00044 gErrorIgnoreLevel = -1;
00045 m_file = newFile;
00046 m_event = new fwlite::Event(m_file);
00047 m_eventTree = dynamic_cast<TTree*>(m_file->Get("Events"));
00048
00049 if (m_eventTree == 0)
00050 {
00051 throw std::runtime_error("Cannot find TTree 'Events' in the data file");
00052 }
00053
00054
00055
00056
00057
00058
00059
00060 }
00061
00062 void FWFileEntry::closeFile()
00063 {
00064 if (m_file) {
00065 printf("Reading %lld bytes in %d transactions.\n",
00066 m_file->GetBytesRead(), m_file->GetReadCalls());
00067 m_file->Close();
00068 delete m_file;
00069 }
00070 if (m_event) delete m_event;
00071 }
00072
00073
00074
00075 bool FWFileEntry::isEventSelected(int tree_entry)
00076 {
00077 int idx = m_globalEventList->GetIndex(tree_entry);
00078 return idx >= 0;
00079 }
00080
00081 bool FWFileEntry::hasSelectedEvents()
00082 {
00083 return m_globalEventList->GetN() > 0;
00084 }
00085
00086 int FWFileEntry::firstSelectedEvent()
00087 {
00088 if (m_globalEventList->GetN() > 0)
00089 {
00090 return m_globalEventList->GetEntry(0);
00091 }
00092 else
00093 {
00094 return -1;
00095 }
00096 }
00097
00098 int FWFileEntry::lastSelectedEvent()
00099 {
00100 if (m_globalEventList->GetN() > 0)
00101 return m_globalEventList->GetEntry(m_globalEventList->GetN() - 1);
00102 else
00103 return -1;
00104 }
00105
00106 int FWFileEntry::nextSelectedEvent(int tree_entry)
00107 {
00108
00109
00110
00111
00112 const Long64_t *list = m_globalEventList->GetList();
00113 Long64_t val = tree_entry;
00114 Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val);
00115 ++idx;
00116 if (idx >= m_globalEventList->GetN() || idx < 0)
00117 return -1;
00118 return list[idx];
00119 }
00120
00121 int FWFileEntry::previousSelectedEvent(int tree_entry)
00122 {
00123
00124
00125
00126
00127 const Long64_t *list = m_globalEventList->GetList();
00128 Long64_t val = tree_entry;
00129 Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val);
00130 if (list[idx] == val)
00131 --idx;
00132 if (idx >= 0)
00133 return list[idx];
00134 else
00135 return -1;
00136 }
00137
00138
00139 bool FWFileEntry::hasActiveFilters()
00140 {
00141 for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it)
00142 {
00143 if ((*it)->m_selector->m_enabled)
00144 return true;
00145 }
00146
00147 return false;
00148 }
00149
00150
00151 void FWFileEntry::updateFilters(const FWEventItemsManager* eiMng, bool globalOR)
00152 {
00153 if (!m_needUpdate)
00154 return;
00155
00156 if (m_globalEventList)
00157 m_globalEventList->Reset();
00158 else
00159 m_globalEventList = new FWTEventList;
00160
00161 for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it)
00162 {
00163 if ((*it)->m_selector->m_enabled && (*it)->m_needsUpdate)
00164 {
00165 runFilter(*it, eiMng);
00166 }
00167
00168
00169 if ((*it)->m_selector->m_enabled)
00170 {
00171 if ((*it)->hasSelectedEvents())
00172 {
00173 if (globalOR || m_globalEventList->GetN() == 0)
00174 {
00175 m_globalEventList->Add((*it)->m_eventList);
00176 }
00177 else
00178 {
00179 m_globalEventList->Intersect((*it)->m_eventList);
00180 }
00181 }
00182 else if (!globalOR)
00183 {
00184 m_globalEventList->Reset();
00185 break;
00186 }
00187 }
00188 }
00189
00190 fwLog(fwlog::kDebug) << "FWFileEntry::updateFilters in [" << m_file->GetName() << "] global selection [" << m_globalEventList->GetN() << "/" << m_eventTree->GetEntries() << "]" << std::endl;
00191
00192 m_needUpdate = false;
00193 }
00194
00195
00196 void FWFileEntry::runFilter(Filter* filter, const FWEventItemsManager* eiMng)
00197 {
00198 if (!filter->m_selector->m_triggerProcess.empty())
00199 {
00200 filterEventsWithCustomParser(filter);
00201 return;
00202 }
00203
00204
00205 std::string interpretedSelection = filter->m_selector->m_expression;
00206
00207 for (FWEventItemsManager::const_iterator i = eiMng->begin(),
00208 end = eiMng->end(); i != end; ++i)
00209 {
00210 FWEventItem *item = *i;
00211 if (item == 0)
00212 continue;
00213
00214 if (item->m_event == 0)
00215 {
00216 item->m_event = m_event;
00217 item->getPrimaryData();
00218 item->m_event = 0;
00219 }
00220 boost::regex re(std::string("\\$") + (*i)->name());
00221 std::string fullBranchName = m_event->getBranchNameFor(*(item->type()->GetTypeInfo()),
00222 item->moduleLabel().c_str(),
00223 item->productInstanceLabel().c_str(),
00224 item->processName().c_str());
00225
00226 interpretedSelection = boost::regex_replace(interpretedSelection, re,
00227 fullBranchName + ".obj");
00228
00229
00230
00231
00232 }
00233
00234 m_file->cd();
00235 m_eventTree->SetEventList(0);
00236
00237
00238
00239
00240
00241 TObjArray* branches = m_eventTree->GetListOfBranches();
00242 std::vector<void*> previousBranchAddresses;
00243 previousBranchAddresses.reserve(branches->GetEntriesFast());
00244 {
00245 std::auto_ptr<TIterator> pIt( branches->MakeIterator());
00246 while(TObject* branchObj = pIt->Next()) {
00247 TBranch* b = dynamic_cast<TBranch*> (branchObj);
00248 if(0!=b) {
00249 const char * name = b->GetName();
00250 unsigned int length = strlen(name);
00251 if(length > 1 && name[length-1]!='.') {
00252
00253 previousBranchAddresses.push_back(0);
00254 continue;
00255 }
00256
00257 if(0!=b->GetAddress()) {
00258 b->SetAddress(0);
00259 }
00260 previousBranchAddresses.push_back(b->GetAddress());
00261 } else {
00262 previousBranchAddresses.push_back(0);
00263 }
00264 }
00265 }
00266
00267 FWTEventList *flist = (FWTEventList*) gDirectory->Get("fworks_filter");
00268 if (flist == 0)
00269 flist = new FWTEventList("fworks_filter");
00270
00271 Int_t result = m_eventTree->Draw(">>fworks_filter", interpretedSelection.c_str());
00272
00273 if (filter->m_eventList)
00274 filter->m_eventList->Reset();
00275 else
00276 filter->m_eventList = new FWTEventList;
00277
00278 filter->m_eventList->Add(flist);
00279
00280 if (result < 0)
00281 fwLog(fwlog::kWarning) << "FWFile::runFilter in file [" << m_file->GetName() << "] filter [" << filter->m_selector->m_expression << "] is invalid." << std::endl;
00282 else
00283 fwLog(fwlog::kDebug) << "FWFile::runFilter is file [" << m_file->GetName() << "], filter [" << filter->m_selector->m_expression << "] has [" << flist->GetN() << "] events selected" << std::endl;
00284
00285
00286 {
00287 std::auto_ptr<TIterator> pIt( branches->MakeIterator());
00288 std::vector<void*>::const_iterator itAddress = previousBranchAddresses.begin();
00289 while(TObject* branchObj = pIt->Next()) {
00290 TBranch* b = dynamic_cast<TBranch*> (branchObj);
00291 if(0!=b && 0!=*itAddress) {
00292 b->SetAddress(*itAddress);
00293 }
00294 ++itAddress;
00295 }
00296 }
00297
00298 filter->m_needsUpdate = false;
00299 }
00300
00301
00302
00303 bool
00304 FWFileEntry::filterEventsWithCustomParser(Filter* filterEntry)
00305 {
00306 std::string selection(filterEntry->m_selector->m_expression);
00307
00308 boost::regex re_spaces("\\s+");
00309 selection = boost::regex_replace(selection,re_spaces,"");
00310 if (selection.find("&&") != std::string::npos &&
00311 selection.find("||") != std::string::npos )
00312 {
00313
00314 return false;
00315 }
00316
00317 fwlite::Handle<edm::TriggerResults> hTriggerResults;
00318 edm::TriggerNames const* triggerNames(0);
00319 try
00320 {
00321 hTriggerResults.getByLabel(*m_event,"TriggerResults","", filterEntry->m_selector->m_triggerProcess.c_str());
00322 triggerNames = &(m_event->triggerNames(*hTriggerResults));
00323 }
00324 catch(...)
00325 {
00326 fwLog(fwlog::kWarning) << " failed to get trigger results with process name "<< filterEntry->m_selector->m_triggerProcess << std::endl;
00327 return false;
00328 }
00329
00330
00331
00332
00333
00334
00335 bool junction_mode = true;
00336 if (selection.find("||")!=std::string::npos)
00337 junction_mode = false;
00338
00339 boost::regex re("\\&\\&|\\|\\|");
00340
00341 boost::sregex_token_iterator i(selection.begin(), selection.end(), re, -1);
00342 boost::sregex_token_iterator j;
00343
00344
00345 std::vector<std::pair<unsigned int,bool> > filters;
00346
00347 while (i != j)
00348 {
00349 std::string filter = *i++;
00350 bool flag = true;
00351 if (filter[0] == '!')
00352 {
00353 flag = false;
00354 filter.erase(filter.begin());
00355 }
00356 unsigned int index = triggerNames->triggerIndex(filter);
00357 if (index == triggerNames->size())
00358 {
00359
00360 return false;
00361 }
00362 filters.push_back(std::make_pair(index, flag));
00363 }
00364 if (filters.empty())
00365 return false;
00366
00367 if (filterEntry->m_eventList)
00368 filterEntry->m_eventList->Reset();
00369 else
00370 filterEntry->m_eventList = new FWTEventList();
00371 FWTEventList* list = filterEntry->m_eventList;
00372
00373
00374 edm::EventID currentEvent = m_event->id();
00375 unsigned int iEvent = 0;
00376
00377 for (m_event->toBegin(); !m_event->atEnd(); ++(*m_event))
00378 {
00379 hTriggerResults.getByLabel(*m_event,"TriggerResults","", filterEntry->m_selector->m_triggerProcess.c_str());
00380 std::vector<std::pair<unsigned int,bool> >::const_iterator filter = filters.begin();
00381 bool passed = hTriggerResults->accept(filter->first) == filter->second;
00382 while (++filter != filters.end())
00383 {
00384 if (junction_mode)
00385 passed &= hTriggerResults->accept(filter->first) == filter->second;
00386 else
00387 passed |= hTriggerResults->accept(filter->first) == filter->second;
00388 }
00389 if (passed)
00390 list->Enter(iEvent);
00391 ++iEvent;
00392 }
00393 m_event->to(currentEvent);
00394
00395 filterEntry->m_needsUpdate = false;
00396
00397 fwLog(fwlog::kDebug) << "FWFile::filterEventsWithCustomParser file [" << m_file->GetName() << "], filter [" << filterEntry->m_selector->m_expression << "], selected [" << list->GetN() << "]" << std::endl;
00398
00399 return true;
00400 }