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