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