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