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