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