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