/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Fireworks/Core/src/FWFileEntry.cc
578 строк
21 KB
camolezi
replaced boost::bind for std::bind
10 июн 2020, 00:38
10 июн 2020, 00:38
75a1f51
Код
Авторство
О чём код?
#include <boost/regex.hpp> #include "TFile.h" #include "TEveTreeTools.h" #include "TError.h" #include "TMath.h" #include "TEnv.h" #include "DataFormats/FWLite/interface/Handle.h" #include "DataFormats/Common/interface/TriggerResults.h" #include "DataFormats/Provenance/interface/ProcessConfiguration.h" #include "DataFormats/Provenance/interface/ProcessHistory.h" #include "DataFormats/Provenance/interface/ReleaseVersion.h" #include "DataFormats/Provenance/interface/ParameterSetBlob.h" #include "DataFormats/Provenance/interface/ParameterSetID.h" #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h" #include "FWCore/Utilities/interface/WrappedClassName.h" #include "FWCore/Common/interface/TriggerNames.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/Registry.h" #include "Fireworks/Core/interface/FWEventItem.h" #include "Fireworks/Core/interface/FWFileEntry.h" #include "Fireworks/Core/interface/FWEventItemsManager.h" #include "Fireworks/Core/interface/fwLog.h" #include "Fireworks/Core/interface/fwPaths.h" #include "Fireworks/Core/interface/FWGUIManager.h" #include "Fireworks/Core/src/FWTTreeCache.h" #include <functional> FWFileEntry::FWFileEntry(const std::string& name, bool checkVersion, bool checkGT) : m_name(name), m_file(nullptr), m_eventTree(nullptr), m_event(nullptr), m_needUpdate(true), m_globalTag("gt_undef"), m_globalEventList(nullptr) { openFile(checkVersion, checkGT); } FWFileEntry::~FWFileEntry() { for (std::list<Filter*>::iterator i = m_filterEntries.begin(); i != m_filterEntries.end(); ++i) delete (*i)->m_eventList; delete m_globalEventList; } void FWFileEntry::openFile(bool checkVersion, bool checkGlobalTag) { gErrorIgnoreLevel = 3000; // suppress warnings about missing dictionaries TFile* newFile = TFile::Open(m_name.c_str()); if (newFile == nullptr || newFile->IsZombie() || !newFile->Get("Events")) { // std::cout << "Invalid file. Ignored." << std::endl; // return false; throw std::runtime_error("Invalid file. Ignored."); } m_file = newFile; gErrorIgnoreLevel = -1; // check CMSSW relese version for compatibility typedef std::vector<edm::ProcessHistory> provList; TTree* metaData = dynamic_cast<TTree*>(m_file->Get("MetaData")); TBranch* b = metaData->GetBranch("ProcessHistory"); edm::ProcessHistoryVector phv_; edm::ProcessHistoryVector* pPhv = &phv_; metaData->SetBranchAddress("ProcessHistory", &pPhv); b->GetEntry(0); typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> ParameterSetMap; ParameterSetMap psm_; TTree* psetTree = dynamic_cast<TTree*>(newFile->Get("ParameterSets")); typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs; IdToBlobs idToBlob; IdToBlobs* pIdToBlob = &idToBlob; psetTree->SetBranchAddress("IdToParameterSetsBlobs", &pIdToBlob); for (long long i = 0; i != psetTree->GetEntries(); ++i) { psetTree->GetEntry(i); psm_.insert(idToBlob); } edm::pset::Registry& psetRegistry = *edm::pset::Registry::instance(); for (auto const& item : psm_) { edm::ParameterSet pset(item.second.pset()); pset.setID(item.first); psetRegistry.insertMapped(pset); } const edm::ProcessConfiguration* dd = nullptr; int latestVersion = 0; int currentVersionArr[] = {0, 0, 0}; for (auto const& processHistory : phv_) { for (auto const& processConfiguration : processHistory) { // std::cout << processConfiguration.releaseVersion() << " " << processConfiguration.processName() << std::endl; TString dcv = processConfiguration.releaseVersion(); fireworks::getDecomposedVersion(dcv, currentVersionArr); int nvv = currentVersionArr[0] * 100 + currentVersionArr[1] * 10 + currentVersionArr[2]; if (nvv > latestVersion) { latestVersion = nvv; dd = &processConfiguration; } } } // read first global tag for auto detect of geomtery version if (checkGlobalTag) { std::map<edm::ProcessConfigurationID, unsigned int> simpleIDs; m_globalTag = ""; for (auto const& ph : phv_) { for (auto const& pc : ph) { unsigned int id = simpleIDs[pc.id()]; if (0 == id) { id = 1; simpleIDs[pc.id()] = id; } ParameterSetMap::const_iterator itFind = psm_.find(pc.parameterSetID()); if (itFind == psm_.end()) { std::cout << "No ParameterSetID for " << pc.parameterSetID() << std::endl; fwLog(fwlog::kInfo) << "FWFileEntry::openFile no ParameterSetID for " << pc.parameterSetID() << std::endl; } else { edm::ParameterSet processConfig(itFind->second.pset()); std::vector<std::string> sourceStrings, moduleStrings; std::vector<std::string> sources = processConfig.getParameter<std::vector<std::string>>("@all_essources"); for (auto& itM : sources) { edm::ParameterSet const& pset = processConfig.getParameterSet(itM); std::string name(pset.getParameter<std::string>("@module_label")); if (name.empty()) { name = pset.getParameter<std::string>("@module_type"); } if (name != "GlobalTag") continue; for (auto const& item : pset.tbl()) { if (item.first == "globaltag") { m_globalTag = item.second.getString(); goto gtEnd; } } } } } } gtEnd: fwLog(fwlog::kDebug) << "FWFileEntry::openFile detected global tag " << m_globalTag << "\n"; } // test compatibility of data with CMSSW if (checkVersion) { if (latestVersion) { fwLog(fwlog::kInfo) << "Checking process history. " << m_name.c_str() << " latest process \"" << dd->processName() << "\", version " << dd->releaseVersion() << std::endl; b->SetAddress(nullptr); TString v = dd->releaseVersion(); if (!fireworks::acceptDataFormatsVersion(v)) { int* di = (fireworks::supportedDataFormatsVersion()); 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", dd->releaseVersion().c_str(), di[0], di[1], di[2]); msg += "Use --no-version-check option if you still want to view the file.\n"; throw std::runtime_error(msg.Data()); } } else { TString msg = "No process history available\n"; msg += "Use --no-version-check option if you still want to view the file.\n"; throw std::runtime_error(msg.Data()); } } m_eventTree = dynamic_cast<TTree*>(m_file->Get("Events")); if (m_eventTree == nullptr) { throw std::runtime_error("Cannot find TTree 'Events' in the data file"); } // Initialize caching, this helps also in the case of local file. if (FWTTreeCache::IsLogging()) printf("FWFileEntry::openFile enabling FWTTreeCache for file class '%s'.", m_file->ClassName()); auto tc = new FWTTreeCache(m_eventTree, FWTTreeCache::GetDefaultCacheSize()); m_file->SetCacheRead(tc, m_eventTree); tc->SetEnablePrefetching(FWTTreeCache::IsPrefetching()); tc->SetLearnEntries(20); tc->SetLearnPrefill(TTreeCache::kAllBranches); tc->StartLearningPhase(); // load event, set DataGetterHelper callback for branch access m_event = new fwlite::Event(m_file, false, [tc](TBranch const& b) { tc->BranchAccessCallIn(&b); }); // Connect to collection add/remove signals FWEventItemsManager* eiMng = (FWEventItemsManager*)FWGUIManager::getGUIManager()->getContext()->eventItemsManager(); eiMng->newItem_.connect(std::bind(&FWFileEntry::NewEventItemCallIn, this, std::placeholders::_1)); eiMng->removingItem_.connect(std::bind(&FWFileEntry::RemovingEventItemCallIn, this, std::placeholders::_1)); // no need to connect to goingToClearItems_ ... individual removes are emitted. if (m_event->size() == 0) throw std::runtime_error("fwlite::Event size == 0"); } void FWFileEntry::closeFile() { if (m_file) { printf("Reading %lld bytes in %d transactions.\n", m_file->GetBytesRead(), m_file->GetReadCalls()); delete m_file->GetCacheRead(m_eventTree); m_file->Close(); delete m_file; } if (m_event) delete m_event; } //______________________________________________________________________________ bool FWFileEntry::isEventSelected(int tree_entry) { int idx = m_globalEventList->GetIndex(tree_entry); return idx >= 0; } bool FWFileEntry::hasSelectedEvents() { return m_globalEventList->GetN() > 0; } int FWFileEntry::firstSelectedEvent() { if (m_globalEventList->GetN() > 0) { return m_globalEventList->GetEntry(0); } else { return -1; } } int FWFileEntry::lastSelectedEvent() { if (m_globalEventList->GetN() > 0) return m_globalEventList->GetEntry(m_globalEventList->GetN() - 1); else return -1; } int FWFileEntry::nextSelectedEvent(int tree_entry) { // Find next selected event after the current one. // This returns the index in the selected event list. // If none exists -1 is returned. const Long64_t* list = m_globalEventList->GetList(); Long64_t val = tree_entry; Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val); ++idx; if (idx >= m_globalEventList->GetN() || idx < 0) return -1; return list[idx]; } int FWFileEntry::previousSelectedEvent(int tree_entry) { // Find first selected event before current one. // This returns the index in the selected event list. // If none exists -1 is returned. const Long64_t* list = m_globalEventList->GetList(); Long64_t val = tree_entry; Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val); if (list[idx] == val) --idx; if (idx >= 0) return list[idx]; else return -1; } //______________________________________________________________________________ bool FWFileEntry::hasActiveFilters() { for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it) { if ((*it)->m_selector->m_enabled) return true; } return false; } //______________________________________________________________________________ void FWFileEntry::updateFilters(const FWEventItemsManager* eiMng, bool globalOR) { if (!m_needUpdate) return; if (m_globalEventList) m_globalEventList->Reset(); else m_globalEventList = new FWTEventList; for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it) { if ((*it)->m_selector->m_enabled && (*it)->m_needsUpdate) { runFilter(*it, eiMng); } // Need to re-check if enabled after filtering as it can be set to false // in runFilter(). if ((*it)->m_selector->m_enabled) { if ((*it)->hasSelectedEvents()) { if (globalOR || m_globalEventList->GetN() == 0) { m_globalEventList->Add((*it)->m_eventList); } else { m_globalEventList->Intersect((*it)->m_eventList); } } else if (!globalOR) { m_globalEventList->Reset(); break; } } } fwLog(fwlog::kDebug) << "FWFileEntry::updateFilters in [" << m_file->GetName() << "] global selection [" << m_globalEventList->GetN() << "/" << m_eventTree->GetEntries() << "]" << std::endl; m_needUpdate = false; } //_____________________________________________________________________________ void FWFileEntry::runFilter(Filter* filter, const FWEventItemsManager* eiMng) { if (!filter->m_selector->m_triggerProcess.empty()) { filterEventsWithCustomParser(filter); return; } // parse selection for known Fireworks expressions std::string interpretedSelection = filter->m_selector->m_expression; // list of branch names to be added to tree-cache std::vector<std::string> branch_names; for (FWEventItemsManager::const_iterator i = eiMng->begin(), end = eiMng->end(); i != end; ++i) { FWEventItem* item = *i; if (item == nullptr) continue; // FIXME: hack to get full branch name filled if (!item->hasEvent()) { item->setEvent(m_event); item->getPrimaryData(); item->setEvent(nullptr); } boost::regex re(std::string("\\$") + (*i)->name()); if (boost::regex_search(interpretedSelection, re)) { const edm::TypeWithDict elementType(const_cast<TClass*>(item->type())); const edm::TypeWithDict wrapperType = edm::TypeWithDict::byName(edm::wrappedClassName(elementType.name())); std::string fullBranchName = m_event->getBranchNameFor(wrapperType.typeInfo(), item->moduleLabel().c_str(), item->productInstanceLabel().c_str(), item->processName().c_str()); interpretedSelection = boost::regex_replace(interpretedSelection, re, fullBranchName + ".obj"); branch_names.push_back(fullBranchName); // printf("selection after applying s/%s/%s/: %s\n", // (std::string("\\$") + (*i)->name()).c_str(), // ((*i)->m_fullBranchName + ".obj").c_str(), // interpretedSelection.c_str()); } } std::size_t found = interpretedSelection.find('$'); if (found != std::string::npos) { fwLog(fwlog::kError) << "FWFileEntry::RunFilter invalid expression " << interpretedSelection << std::endl; filter->m_needsUpdate = false; return; } m_file->cd(); m_eventTree->SetEventList(nullptr); auto prevCache = m_file->GetCacheRead(m_eventTree); auto interCache = new TTreeCache(m_eventTree, 10 * 1024 * 1024); // Do not disconnect the cache, it will be reattached after filtering. m_file->SetCacheRead(interCache, m_eventTree, TFile::kDoNotDisconnect); interCache->SetEnablePrefetching(FWTTreeCache::IsPrefetching()); for (auto& b : branch_names) interCache->AddBranch(b.c_str(), true); interCache->StopLearningPhase(); // Since ROOT will leave any TBranches used in the filtering at the last event, // we need to be able to reset them to what fwlite::Event expects them to be. // We do this by holding onto the old buffers and create temporary new ones. std::map<TBranch*, void*> prevAddrs; { TObjArray* branches = m_eventTree->GetListOfBranches(); std::unique_ptr<TIterator> pIt(branches->MakeIterator()); while (TObject* branchObj = pIt->Next()) { TBranch* b = dynamic_cast<TBranch*>(branchObj); if (nullptr != b) { const char* name = b->GetName(); unsigned int length = strlen(name); if (length > 1 && name[length - 1] != '.') { // This is not a data branch so we should ignore it. continue; } if (nullptr != b->GetAddress()) { if (prevAddrs.find(b) != prevAddrs.end()) { fwLog(fwlog::kWarning) << "FWFileEntry::runFilter branch is already in the map!\n"; } prevAddrs.insert(std::make_pair(b, b->GetAddress())); // std::cout <<"Zeroing branch: "<< b->GetName() <<" "<< (void*) b->GetAddress() <<std::endl; b->SetAddress(nullptr); } } } } if (filter->m_eventList) filter->m_eventList->Reset(); else filter->m_eventList = new FWTEventList; fwLog(fwlog::kInfo) << "FWFileEntry::runFilter Running filter " << interpretedSelection << "' " << "for file '" << m_file->GetName() << "'.\n"; TEveSelectorToEventList stoelist(filter->m_eventList, interpretedSelection.c_str()); Long64_t result = m_eventTree->Process(&stoelist); if (result < 0) fwLog(fwlog::kWarning) << "FWFileEntry::runFilter in file [" << m_file->GetName() << "] filter [" << filter->m_selector->m_expression << "] is invalid." << std::endl; else fwLog(fwlog::kDebug) << "FWFileEntry::runFilter is file [" << m_file->GetName() << "], filter [" << filter->m_selector->m_expression << "] has [" << filter->m_eventList->GetN() << "] events selected" << std::endl; // Set back the old branch buffers. { for (auto i : prevAddrs) { // std::cout <<"Resetting branch: "<< i.first->GetName() <<" "<< i.second <<std::endl; i.first->SetAddress(i.second); } } m_file->SetCacheRead(prevCache, m_eventTree); delete interCache; filter->m_needsUpdate = false; } //______________________________________________________________________________ bool FWFileEntry::filterEventsWithCustomParser(Filter* filterEntry) { std::string selection(filterEntry->m_selector->m_expression); boost::regex re_spaces("\\s+"); selection = boost::regex_replace(selection, re_spaces, ""); if (selection.find("&&") != std::string::npos && selection.find("||") != std::string::npos) { // Combination of && and || operators not supported. return false; } fwlite::Handle<edm::TriggerResults> hTriggerResults; edm::TriggerNames const* triggerNames(nullptr); try { hTriggerResults.getByLabel(*m_event, "TriggerResults", "", filterEntry->m_selector->m_triggerProcess.c_str()); triggerNames = &(m_event->triggerNames(*hTriggerResults)); } catch (...) { fwLog(fwlog::kWarning) << " failed to get trigger results with process name " << filterEntry->m_selector->m_triggerProcess << std::endl; return false; } // std::cout << "Number of trigger names: " << triggerNames->size() << std::endl; // for (unsigned int i=0; i<triggerNames->size(); ++i) // std::cout << " " << triggerNames->triggerName(i); //std::cout << std::endl; bool junction_mode = true; // AND if (selection.find("||") != std::string::npos) junction_mode = false; // OR boost::regex re("\\&\\&|\\|\\|"); boost::sregex_token_iterator i(selection.begin(), selection.end(), re, -1); boost::sregex_token_iterator j; // filters and how they enter in the logical expression std::vector<std::pair<unsigned int, bool>> filters; while (i != j) { std::string filter = *i++; bool flag = true; if (filter[0] == '!') { flag = false; filter.erase(filter.begin()); } unsigned int index = triggerNames->triggerIndex(filter); if (index == triggerNames->size()) { // Trigger name not found. return false; } filters.push_back(std::make_pair(index, flag)); } if (filters.empty()) return false; if (filterEntry->m_eventList) filterEntry->m_eventList->Reset(); else filterEntry->m_eventList = new FWTEventList(); FWTEventList* list = filterEntry->m_eventList; // loop over events edm::EventID currentEvent = m_event->id(); unsigned int iEvent = 0; for (m_event->toBegin(); !m_event->atEnd(); ++(*m_event)) { hTriggerResults.getByLabel(*m_event, "TriggerResults", "", filterEntry->m_selector->m_triggerProcess.c_str()); std::vector<std::pair<unsigned int, bool>>::const_iterator filter = filters.begin(); bool passed = hTriggerResults->accept(filter->first) == filter->second; while (++filter != filters.end()) { if (junction_mode) passed &= hTriggerResults->accept(filter->first) == filter->second; else passed |= hTriggerResults->accept(filter->first) == filter->second; } if (passed) list->Enter(iEvent); ++iEvent; } m_event->to(currentEvent); filterEntry->m_needsUpdate = false; fwLog(fwlog::kDebug) << "FWFile::filterEventsWithCustomParser file [" << m_file->GetName() << "], filter [" << filterEntry->m_selector->m_expression << "], selected [" << list->GetN() << "]" << std::endl; return true; } //------------------------------------------------------------------------------ FWTTreeCache* FWFileEntry::fwTreeCache() { FWTTreeCache* tc = dynamic_cast<FWTTreeCache*>(m_file->GetCacheRead(m_eventTree)); assert(tc != nullptr && "FWFileEntry::treeCache can not access TTreeCache"); return tc; } std::string FWFileEntry::getBranchName(const FWEventItem* it) const { const edm::TypeWithDict elementType(const_cast<TClass*>(it->type())); const edm::TypeWithDict wrapperType = edm::TypeWithDict::byName(edm::wrappedClassName(elementType.name())); return m_event->getBranchNameFor( wrapperType.typeInfo(), it->moduleLabel().c_str(), it->productInstanceLabel().c_str(), it->processName().c_str()); } void FWFileEntry::NewEventItemCallIn(const FWEventItem* it) { auto tc = fwTreeCache(); if (FWTTreeCache::IsLogging()) printf("FWFileEntry:NewEventItemCallIn FWEventItem %s, learning=%d\n", getBranchName(it).c_str(), tc->IsLearning()); tc->AddBranchTopLevel(getBranchName(it).c_str()); } void FWFileEntry::RemovingEventItemCallIn(const FWEventItem* it) { auto tc = fwTreeCache(); if (FWTTreeCache::IsLogging()) printf("FWFileEntry:RemovingEventItemCallIn FWEventItem %s, learning=%d\n", getBranchName(it).c_str(), tc->IsLearning()); tc->DropBranchTopLevel(getBranchName(it).c_str()); }