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