CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FWFileEntry.cc
Go to the documentation of this file.
1 #include <boost/regex.hpp>
2 
3 #include "TFile.h"
4 #include "TTreeCache.h"
5 #include "TEveTreeTools.h"
6 #include "TError.h"
7 #include "TMath.h"
8 
14 
17 
23 
24 FWFileEntry::FWFileEntry(const std::string& name, bool checkVersion) :
25  m_name(name), m_file(0), m_eventTree(0), m_event(0),
26  m_needUpdate(true), m_globalEventList(0)
27 {
28  openFile(checkVersion);
29 }
30 
32 {
33  for(std::list<Filter*>::iterator i = m_filterEntries.begin(); i != m_filterEntries.end(); ++i)
34  delete (*i)->m_eventList;
35 
36  delete m_globalEventList;
37 }
38 
39 void FWFileEntry::openFile(bool checkVersion)
40 {
41  gErrorIgnoreLevel = 3000; // suppress warnings about missing dictionaries
42  TFile *newFile = TFile::Open(m_name.c_str());
43  if (newFile == 0 || newFile->IsZombie() || !newFile->Get("Events")) {
44  // std::cout << "Invalid file. Ignored." << std::endl;
45  // return false;
46  throw std::runtime_error("Invalid file. Ignored.");
47  }
48  gErrorIgnoreLevel = -1;
49  m_file = newFile;
50 
51 
52  // check CMSSW relese version for compatibility
53  if (checkVersion) {
54  typedef std::vector<edm::ProcessHistory> provList;
55 
56  TTree *metaData = dynamic_cast<TTree*>(m_file->Get("MetaData"));
57  TBranch *b = metaData->GetBranch("ProcessHistory");
58  provList *x = 0;
59  b->SetAddress(&x);
60  b->GetEntry(0);
61 
62  const edm::ProcessConfiguration* dd = 0;
63  int latestVersion =0;
64  int currentVersionArr[] = {0, 0, 0};
65  for (auto const& processHistory : *x)
66  {
67  for (auto const& processConfiguration : processHistory)
68  {
69  // std::cout << processConfiguration.releaseVersion() << " " << processConfiguration.processName() << std::endl;
70  TString dcv = processConfiguration.releaseVersion();
71  fireworks::getDecomposedVersion(dcv, currentVersionArr);
72  int nvv = currentVersionArr[0]*100 + currentVersionArr[1]*10 + currentVersionArr[2];
73  if (nvv > latestVersion) {
74  latestVersion = nvv;
76  }
77  }
78  }
79 
80  if (latestVersion) {
81  fwLog(fwlog::kInfo) << "Checking process history. " << m_name.c_str() << " latest process \"" << dd->processName() << "\", version " << dd->releaseVersion() << std::endl;
82 
83  b->SetAddress(0);
84  TString v = dd->releaseVersion();
86  {
88  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",
89  dd->releaseVersion().c_str(), di[0], di[1], di[2]);
90  msg += "Use --no-version-check option if you still want to view the file.\n";
91  throw std::runtime_error(msg.Data());
92  }
93  }
94  else {
95  TString msg = "No process history available\n";
96  msg += "Use --no-version-check option if you still want to view the file.\n";
97  throw std::runtime_error(msg.Data());
98  }
99  }
100 
101  // load event
103 
104  if (m_event->size() == 0)
105  throw std::runtime_error("fwlite::Event size == 0");
106 
107 
108  m_eventTree = dynamic_cast<TTree*>(m_file->Get("Events"));
109 
110  if (m_eventTree == 0)
111  {
112  throw std::runtime_error("Cannot find TTree 'Events' in the data file");
113  }
114 
115  // This now set in DataHelper
116  //TTreeCache::SetLearnEntries(2);
117  //m_eventTree->SetCacheSize(10*1024*1024);
118  //TTreeCache *tc = (TTreeCache*) m_file->GetCacheRead();
119  //tc->AddBranch(m_event->auxBranch_,kTRUE);
120  //tc->StartLearningPhase();
121 }
122 
124 {
125  if (m_file) {
126  printf("Reading %lld bytes in %d transactions.\n",
127  m_file->GetBytesRead(), m_file->GetReadCalls());
128  delete m_file->GetCacheRead(m_eventTree);
129 
130  m_file->Close();
131  delete m_file;
132  }
133  if (m_event) delete m_event;
134 }
135 
136 //______________________________________________________________________________
137 
138 bool FWFileEntry::isEventSelected(int tree_entry)
139 {
140  int idx = m_globalEventList->GetIndex(tree_entry);
141  return idx >= 0;
142 }
143 
145 {
146  return m_globalEventList->GetN() > 0;
147 }
148 
150 {
151  if (m_globalEventList->GetN() > 0)
152  {
153  return m_globalEventList->GetEntry(0);
154  }
155  else
156  {
157  return -1;
158  }
159 }
160 
162 {
163  if (m_globalEventList->GetN() > 0)
164  return m_globalEventList->GetEntry(m_globalEventList->GetN() - 1);
165  else
166  return -1;
167 }
168 
170 {
171  // Find next selected event after the current one.
172  // This returns the index in the selected event list.
173  // If none exists -1 is returned.
174 
175  const Long64_t *list = m_globalEventList->GetList();
176  Long64_t val = tree_entry;
177  Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val);
178  ++idx;
179  if (idx >= m_globalEventList->GetN() || idx < 0)
180  return -1;
181  return list[idx];
182 }
183 
185 {
186  // Find first selected event before current one.
187  // This returns the index in the selected event list.
188  // If none exists -1 is returned.
189 
190  const Long64_t *list = m_globalEventList->GetList();
191  Long64_t val = tree_entry;
192  Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val);
193  if (list[idx] == val)
194  --idx;
195  if (idx >= 0)
196  return list[idx];
197  else
198  return -1;
199 }
200 
201 //______________________________________________________________________________
203 {
204  for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it)
205  {
206  if ((*it)->m_selector->m_enabled)
207  return true;
208  }
209 
210  return false;
211 }
212 
213 //______________________________________________________________________________
214 void FWFileEntry::updateFilters(const FWEventItemsManager* eiMng, bool globalOR)
215 {
216  if (!m_needUpdate)
217  return;
218 
219  if (m_globalEventList)
220  m_globalEventList->Reset();
221  else
223 
224  for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it)
225  {
226  if ((*it)->m_selector->m_enabled && (*it)->m_needsUpdate)
227  {
228  runFilter(*it, eiMng);
229  }
230  // Need to re-check if enabled after filtering as it can be set to false
231  // in runFilter().
232  if ((*it)->m_selector->m_enabled)
233  {
234  if ((*it)->hasSelectedEvents())
235  {
236  if (globalOR || m_globalEventList->GetN() == 0)
237  {
238  m_globalEventList->Add((*it)->m_eventList);
239  }
240  else
241  {
242  m_globalEventList->Intersect((*it)->m_eventList);
243  }
244  }
245  else if (!globalOR)
246  {
247  m_globalEventList->Reset();
248  break;
249  }
250  }
251  }
252 
253  fwLog(fwlog::kDebug) << "FWFileEntry::updateFilters in [" << m_file->GetName() << "] global selection [" << m_globalEventList->GetN() << "/" << m_eventTree->GetEntries() << "]" << std::endl;
254 
255  m_needUpdate = false;
256 }
257 
258 //_____________________________________________________________________________
260 {
261  if (!filter->m_selector->m_triggerProcess.empty())
262  {
264  return;
265  }
266 
267  // parse selection for known Fireworks expressions
268  std::string interpretedSelection = filter->m_selector->m_expression;
269 
271  end = eiMng->end(); i != end; ++i)
272  {
273  FWEventItem *item = *i;
274  if (item == nullptr)
275  continue;
276  // FIXME: hack to get full branch name filled
277  if (!item->hasEvent())
278  {
279  item->setEvent(m_event);
280  item->getPrimaryData();
281  item->setEvent(nullptr);
282  }
283 
284  boost::regex re(std::string("\\$") + (*i)->name());
285 
286  if (boost::regex_search(interpretedSelection, re))
287  {
288  const edm::TypeWithDict elementType(const_cast<TClass*>(item->type()));
289  const edm::TypeWithDict wrapperType = edm::TypeWithDict::byName(edm::wrappedClassName(elementType.name()));
290  std::string fullBranchName = m_event->getBranchNameFor(wrapperType.typeInfo(),
291  item->moduleLabel().c_str(),
292  item->productInstanceLabel().c_str(),
293  item->processName().c_str());
294 
295  interpretedSelection = boost::regex_replace(interpretedSelection, re,
296  fullBranchName + ".obj");
297 
298  // printf("selection after applying s/%s/%s/: %s\n",
299  // (std::string("\\$") + (*i)->name()).c_str(),
300  // ((*i)->m_fullBranchName + ".obj").c_str(),
301  // interpretedSelection.c_str());
302  }
303  }
304 
305 
306  std::size_t found = interpretedSelection.find('$');
307  if (found!=std::string::npos)
308  {
309  fwLog(fwlog::kError) << "FWFileEntry::RunFilter invalid expression " << interpretedSelection << std::endl;
310  filter->m_needsUpdate = false;
311  return;
312  }
313 
314  m_file->cd();
315  m_eventTree->SetEventList(0);
316 
317  // Since ROOT will leave any TBranches used in the filtering at the last event,
318  // we need to be able to reset them to what fwlite::Event expects them to be
319  // we do this by holding onto the old buffers and create temporary new ones.
320 
321  std::map<TBranch*, void*> prevAddrs;
322 
323  {
324  TObjArray* branches = m_eventTree->GetListOfBranches();
325  std::auto_ptr<TIterator> pIt( branches->MakeIterator());
326  while (TObject* branchObj = pIt->Next())
327  {
328  TBranch* b = dynamic_cast<TBranch*> (branchObj);
329  if (0!=b)
330  {
331  const char * name = b->GetName();
332  unsigned int length = strlen(name);
333  if (length > 1 && name[length-1] != '.')
334  {
335  // This is not a data branch so we should ignore it.
336  continue;
337  }
338  if (0 != b->GetAddress())
339  {
340  if (prevAddrs.find(b) != prevAddrs.end())
341  {
342  fwLog(fwlog::kWarning) << "FWFileEntry::runFilter branch is already in the map!\n";
343  }
344  prevAddrs.insert(std::make_pair(b, b->GetAddress()));
345 
346  // std::cout <<"Zeroing branch: "<< b->GetName() <<" "<< (void*) b->GetAddress() <<std::endl;
347  b->SetAddress(0);
348  }
349  }
350  }
351  }
352 
353  if (filter->m_eventList)
354  filter->m_eventList->Reset();
355  else
356  filter->m_eventList = new FWTEventList;
357 
358  TEveSelectorToEventList stoelist(filter->m_eventList, interpretedSelection.c_str());
359  Long64_t result = m_eventTree->Process(&stoelist);
360 
361  if (result < 0)
362  fwLog(fwlog::kWarning) << "FWFileEntry::runFilter in file [" << m_file->GetName() << "] filter [" << filter->m_selector->m_expression << "] is invalid." << std::endl;
363  else
364  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;
365 
366  // Set back the old branch buffers.
367  {
368  for (auto i : prevAddrs)
369  {
370  // std::cout <<"Resetting branch: "<< i.first->GetName() <<" "<< i.second <<std::endl;
371  i.first->SetAddress(i.second);
372  }
373  }
374 
375  filter->m_needsUpdate = false;
376 }
377 
378 //______________________________________________________________________________
379 
380 bool
382 {
384 
385  boost::regex re_spaces("\\s+");
386  selection = boost::regex_replace(selection,re_spaces,"");
387  if (selection.find("&&") != std::string::npos &&
388  selection.find("||") != std::string::npos )
389  {
390  // Combination of && and || operators not supported.
391  return false;
392  }
393 
394  fwlite::Handle<edm::TriggerResults> hTriggerResults;
395  edm::TriggerNames const* triggerNames(0);
396  try
397  {
398  hTriggerResults.getByLabel(*m_event,"TriggerResults","", filterEntry->m_selector->m_triggerProcess.c_str());
399  triggerNames = &(m_event->triggerNames(*hTriggerResults));
400  }
401  catch(...)
402  {
403  fwLog(fwlog::kWarning) << " failed to get trigger results with process name "<< filterEntry->m_selector->m_triggerProcess << std::endl;
404  return false;
405  }
406 
407  // std::cout << "Number of trigger names: " << triggerNames->size() << std::endl;
408  // for (unsigned int i=0; i<triggerNames->size(); ++i)
409  // std::cout << " " << triggerNames->triggerName(i);
410  //std::cout << std::endl;
411 
412  bool junction_mode = true; // AND
413  if (selection.find("||")!=std::string::npos)
414  junction_mode = false; // OR
415 
416  boost::regex re("\\&\\&|\\|\\|");
417 
418  boost::sregex_token_iterator i(selection.begin(), selection.end(), re, -1);
419  boost::sregex_token_iterator j;
420 
421  // filters and how they enter in the logical expression
422  std::vector<std::pair<unsigned int,bool> > filters;
423 
424  while (i != j)
425  {
426  std::string filter = *i++;
427  bool flag = true;
428  if (filter[0] == '!')
429  {
430  flag = false;
431  filter.erase(filter.begin());
432  }
433  unsigned int index = triggerNames->triggerIndex(filter);
434  if (index == triggerNames->size())
435  {
436  // Trigger name not found.
437  return false;
438  }
439  filters.push_back(std::make_pair(index, flag));
440  }
441  if (filters.empty())
442  return false;
443 
444  if (filterEntry->m_eventList)
445  filterEntry->m_eventList->Reset();
446  else
447  filterEntry->m_eventList = new FWTEventList();
448  FWTEventList* list = filterEntry->m_eventList;
449 
450  // loop over events
451  edm::EventID currentEvent = m_event->id();
452  unsigned int iEvent = 0;
453 
454  for (m_event->toBegin(); !m_event->atEnd(); ++(*m_event))
455  {
456  hTriggerResults.getByLabel(*m_event,"TriggerResults","", filterEntry->m_selector->m_triggerProcess.c_str());
457  std::vector<std::pair<unsigned int,bool> >::const_iterator filter = filters.begin();
458  bool passed = hTriggerResults->accept(filter->first) == filter->second;
459  while (++filter != filters.end())
460  {
461  if (junction_mode)
462  passed &= hTriggerResults->accept(filter->first) == filter->second;
463  else
464  passed |= hTriggerResults->accept(filter->first) == filter->second;
465  }
466  if (passed)
467  list->Enter(iEvent);
468  ++iEvent;
469  }
470  m_event->to(currentEvent);
471 
472  filterEntry->m_needsUpdate = false;
473 
474  fwLog(fwlog::kDebug) << "FWFile::filterEventsWithCustomParser file [" << m_file->GetName() << "], filter [" << filterEntry->m_selector->m_expression << "], selected [" << list->GetN() << "]" << std::endl;
475 
476  return true;
477 }
void closeFile()
Definition: FWFileEntry.cc:123
int i
Definition: DBlmapReader.cc:9
FWEventSelector * m_selector
Definition: FWFileEntry.h:39
virtual void Enter(Long64_t entry)
Definition: FWTEventList.cc:55
virtual edm::TriggerNames const & triggerNames(edm::TriggerResults const &triggerResults) const
Definition: Event.cc:425
void openFile(bool)
Definition: FWFileEntry.cc:39
int lastSelectedEvent()
Definition: FWFileEntry.cc:161
void setEvent(const edm::EventBase *iEvent)
Definition: FWEventItem.cc:120
bool hasSelectedEvents()
Definition: FWFileEntry.cc:144
bool accept() const
Has at least one path accepted the event?
selection
main part
Definition: corrVsCorr.py:98
FWTEventList * m_eventList
Definition: FWFileEntry.h:38
void getPrimaryData() const
Definition: FWEventItem.cc:443
processConfiguration
Definition: Schedule.cc:374
std::string m_triggerProcess
FWFileEntry(const std::string &name, bool checkVersion)
Definition: FWFileEntry.cc:24
void getDecomposedVersion(const TString &s, int *out)
Definition: fwPaths.cc:30
Strings::size_type size() const
Definition: TriggerNames.cc:39
const std::string & processName() const
Definition: FWEventItem.cc:529
virtual std::string const getBranchNameFor(std::type_info const &, char const *iModuleLabel, char const *iProductInstanceLabel, char const *iProcessName) const
Return the branch name in the TFile which contains the data.
Definition: Event.cc:301
Long64_t size() const
Returns number of events in the file.
Definition: Event.cc:267
bool isEventSelected(int event)
Definition: FWFileEntry.cc:138
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:60
std::string const & processName() const
void getByLabel(const P &iP, const char *iModuleLabel, const char *iProductInstanceLabel=0, const char *iProcessLabel=0)
Definition: Handle.h:91
Event const & toBegin()
Go to the very first Event.
Definition: Event.cc:240
int iEvent
Definition: GenABIO.cc:230
const std::string & productInstanceLabel() const
Definition: FWEventItem.cc:523
std::list< Filter * > m_filterEntries
Definition: FWFileEntry.h:98
int * supportedDataFormatsVersion()
Definition: fwPaths.cc:43
unsigned int triggerIndex(std::string const &name) const
Definition: TriggerNames.cc:32
std::string name() const
virtual void Add(const TEventList *list)
Definition: FWTEventList.cc:7
std::string m_expression
const TClass * type() const
Definition: FWEventItem.cc:506
tuple result
Definition: query.py:137
bool filterEventsWithCustomParser(Filter *filter)
Definition: FWFileEntry.cc:381
int j
Definition: DBlmapReader.cc:9
bool to(Long64_t iIndex)
Go to the event at index iIndex.
Definition: Event.cc:210
std::type_info const & typeInfo() const
#define end
Definition: vmac.h:37
std::list< Filter * > & filters()
Definition: FWFileEntry.h:62
TFile * m_file
Definition: FWFileEntry.h:92
virtual ~FWFileEntry()
Definition: FWFileEntry.cc:31
virtual bool atEnd() const
Definition: Event.cc:283
bool m_needUpdate
Definition: FWFileEntry.h:96
TTree * m_eventTree
Definition: FWFileEntry.h:93
fwlite::Event * m_event
Definition: FWFileEntry.h:94
const_iterator begin() const
NOTE: iterator is allowed to return a null object for items that have been removed.
int firstSelectedEvent()
Definition: FWFileEntry.cc:149
#define fwLog(_level_)
Definition: fwLog.h:50
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
ReleaseVersion const & releaseVersion() const
std::string wrappedClassName(std::string const &iFullName)
bool hasEvent() const
Definition: FWEventItem.h:141
void runFilter(Filter *fe, const FWEventItemsManager *eiMng)
Definition: FWFileEntry.cc:259
double b
Definition: hdecay.h:120
int nextSelectedEvent(int event)
Definition: FWFileEntry.cc:169
bool acceptDataFormatsVersion(TString &n)
Definition: fwPaths.cc:71
edm::EventID id() const
Definition: EventBase.h:59
void updateFilters(const FWEventItemsManager *eiMng, bool isOR)
Definition: FWFileEntry.cc:214
FWTEventList * m_globalEventList
Definition: FWFileEntry.h:99
bool hasActiveFilters()
Definition: FWFileEntry.cc:202
std::string m_name
Definition: FWFileEntry.h:91
int previousSelectedEvent(int event)
Definition: FWFileEntry.cc:184
std::vector< FWEventItem * >::const_iterator const_iterator
const std::string & moduleLabel() const
Definition: FWEventItem.cc:518
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
const_iterator end() const