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