CMS 3D CMS Logo

FWFileEntry.cc
Go to the documentation of this file.
1 #include <boost/regex.hpp>
2 
3 #include "TFile.h"
4 #include "TEveTreeTools.h"
5 #include "TError.h"
6 #include "TMath.h"
7 #include "TEnv.h"
8 
14 
17 
23 
25 
27 
28 #include <boost/bind.hpp>
29 
30 FWFileEntry::FWFileEntry(const std::string& name, bool checkVersion) :
31  m_name(name), m_file(nullptr), m_eventTree(nullptr), m_event(nullptr),
32  m_needUpdate(true), m_globalEventList(nullptr)
33 {
34  openFile(checkVersion);
35 }
36 
38 {
39  for(std::list<Filter*>::iterator i = m_filterEntries.begin(); i != m_filterEntries.end(); ++i)
40  delete (*i)->m_eventList;
41 
42  delete m_globalEventList;
43 }
44 
45 void FWFileEntry::openFile(bool checkVersion)
46 {
47  gErrorIgnoreLevel = 3000; // suppress warnings about missing dictionaries
48 
49  TFile *newFile = TFile::Open(m_name.c_str());
50 
51  if (newFile == nullptr || newFile->IsZombie() || !newFile->Get("Events")) {
52  // std::cout << "Invalid file. Ignored." << std::endl;
53  // return false;
54  throw std::runtime_error("Invalid file. Ignored.");
55  }
56 
57  m_file = newFile;
58 
59  gErrorIgnoreLevel = -1;
60 
61  // check CMSSW relese version for compatibility
62  if (checkVersion) {
63  typedef std::vector<edm::ProcessHistory> provList;
64 
65  TTree *metaData = dynamic_cast<TTree*>(m_file->Get("MetaData"));
66  TBranch *b = metaData->GetBranch("ProcessHistory");
67  provList *x = nullptr;
68  b->SetAddress(&x);
69  b->GetEntry(0);
70 
71  const edm::ProcessConfiguration* dd = nullptr;
72  int latestVersion =0;
73  int currentVersionArr[] = {0, 0, 0};
74  for (auto const& processHistory : *x)
75  {
76  for (auto const& processConfiguration : processHistory)
77  {
78  // std::cout << processConfiguration.releaseVersion() << " " << processConfiguration.processName() << std::endl;
79  TString dcv = processConfiguration.releaseVersion();
80  fireworks::getDecomposedVersion(dcv, currentVersionArr);
81  int nvv = currentVersionArr[0]*100 + currentVersionArr[1]*10 + currentVersionArr[2];
82  if (nvv > latestVersion) {
83  latestVersion = nvv;
84  dd = &processConfiguration;
85  }
86  }
87  }
88 
89  if (latestVersion) {
90  fwLog(fwlog::kInfo) << "Checking process history. " << m_name.c_str() << " latest process \"" << dd->processName() << "\", version " << dd->releaseVersion() << std::endl;
91 
92  b->SetAddress(nullptr);
93  TString v = dd->releaseVersion();
95  {
97  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",
98  dd->releaseVersion().c_str(), di[0], di[1], di[2]);
99  msg += "Use --no-version-check option if you still want to view the file.\n";
100  throw std::runtime_error(msg.Data());
101  }
102  }
103  else {
104  TString msg = "No process history available\n";
105  msg += "Use --no-version-check option if you still want to view the file.\n";
106  throw std::runtime_error(msg.Data());
107  }
108  }
109 
110  m_eventTree = dynamic_cast<TTree*>(m_file->Get("Events"));
111 
112  if (m_eventTree == nullptr)
113  {
114  throw std::runtime_error("Cannot find TTree 'Events' in the data file");
115  }
116 
117  // Initialize caching, this helps also in the case of local file.
119  printf("FWFileEntry::openFile enabling FWTTreeCache for file class '%s'.", m_file->ClassName());
120 
121  auto tc = new FWTTreeCache(m_eventTree, FWTTreeCache::GetDefaultCacheSize());
122  m_file->SetCacheRead(tc, m_eventTree);
123  tc->SetEnablePrefetching(FWTTreeCache::IsPrefetching());
124  tc->SetLearnEntries(20);
125  tc->SetLearnPrefill(TTreeCache::kAllBranches);
126  tc->StartLearningPhase();
127 
128  // load event, set DataGetterHelper callback for branch access
129  m_event = new fwlite::Event(m_file, false, [tc](TBranch const& b){ tc->BranchAccessCallIn(&b); });
130 
131  // Connect to collection add/remove signals
133  eiMng->newItem_ .connect(boost::bind(&FWFileEntry::NewEventItemCallIn, this, _1));
134  eiMng->removingItem_.connect(boost::bind(&FWFileEntry::RemovingEventItemCallIn, this, _1));
135  // no need to connect to goingToClearItems_ ... individual removes are emitted.
136 
137  if (m_event->size() == 0)
138  throw std::runtime_error("fwlite::Event size == 0");
139 }
140 
142 {
143  if (m_file) {
144  printf("Reading %lld bytes in %d transactions.\n",
145  m_file->GetBytesRead(), m_file->GetReadCalls());
146  delete m_file->GetCacheRead(m_eventTree);
147 
148  m_file->Close();
149  delete m_file;
150  }
151  if (m_event) delete m_event;
152 }
153 
154 //______________________________________________________________________________
155 
156 bool FWFileEntry::isEventSelected(int tree_entry)
157 {
158  int idx = m_globalEventList->GetIndex(tree_entry);
159  return idx >= 0;
160 }
161 
163 {
164  return m_globalEventList->GetN() > 0;
165 }
166 
168 {
169  if (m_globalEventList->GetN() > 0)
170  {
171  return m_globalEventList->GetEntry(0);
172  }
173  else
174  {
175  return -1;
176  }
177 }
178 
180 {
181  if (m_globalEventList->GetN() > 0)
182  return m_globalEventList->GetEntry(m_globalEventList->GetN() - 1);
183  else
184  return -1;
185 }
186 
188 {
189  // Find next selected event after the current one.
190  // This returns the index in the selected event list.
191  // If none exists -1 is returned.
192 
193  const Long64_t *list = m_globalEventList->GetList();
194  Long64_t val = tree_entry;
195  Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val);
196  ++idx;
197  if (idx >= m_globalEventList->GetN() || idx < 0)
198  return -1;
199  return list[idx];
200 }
201 
203 {
204  // Find first selected event before current one.
205  // This returns the index in the selected event list.
206  // If none exists -1 is returned.
207 
208  const Long64_t *list = m_globalEventList->GetList();
209  Long64_t val = tree_entry;
210  Long64_t idx = TMath::BinarySearch(m_globalEventList->GetN(), list, val);
211  if (list[idx] == val)
212  --idx;
213  if (idx >= 0)
214  return list[idx];
215  else
216  return -1;
217 }
218 
219 //______________________________________________________________________________
221 {
222  for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it)
223  {
224  if ((*it)->m_selector->m_enabled)
225  return true;
226  }
227 
228  return false;
229 }
230 
231 //______________________________________________________________________________
232 void FWFileEntry::updateFilters(const FWEventItemsManager* eiMng, bool globalOR)
233 {
234  if (!m_needUpdate)
235  return;
236 
237  if (m_globalEventList)
238  m_globalEventList->Reset();
239  else
241 
242  for (std::list<Filter*>::iterator it = m_filterEntries.begin(); it != m_filterEntries.end(); ++it)
243  {
244  if ((*it)->m_selector->m_enabled && (*it)->m_needsUpdate)
245  {
246  runFilter(*it, eiMng);
247  }
248  // Need to re-check if enabled after filtering as it can be set to false
249  // in runFilter().
250  if ((*it)->m_selector->m_enabled)
251  {
252  if ((*it)->hasSelectedEvents())
253  {
254  if (globalOR || m_globalEventList->GetN() == 0)
255  {
256  m_globalEventList->Add((*it)->m_eventList);
257  }
258  else
259  {
260  m_globalEventList->Intersect((*it)->m_eventList);
261  }
262  }
263  else if (!globalOR)
264  {
265  m_globalEventList->Reset();
266  break;
267  }
268  }
269  }
270 
271  fwLog(fwlog::kDebug) << "FWFileEntry::updateFilters in [" << m_file->GetName() << "] global selection [" << m_globalEventList->GetN() << "/" << m_eventTree->GetEntries() << "]" << std::endl;
272 
273  m_needUpdate = false;
274 }
275 
276 //_____________________________________________________________________________
278 {
279  if (!filter->m_selector->m_triggerProcess.empty())
280  {
282  return;
283  }
284 
285  // parse selection for known Fireworks expressions
286  std::string interpretedSelection = filter->m_selector->m_expression;
287  // list of branch names to be added to tree-cache
288  std::vector<std::string> branch_names;
289 
291  end = eiMng->end(); i != end; ++i)
292  {
293  FWEventItem *item = *i;
294  if (item == nullptr)
295  continue;
296  // FIXME: hack to get full branch name filled
297  if (!item->hasEvent())
298  {
299  item->setEvent(m_event);
300  item->getPrimaryData();
301  item->setEvent(nullptr);
302  }
303 
304  boost::regex re(std::string("\\$") + (*i)->name());
305 
306  if (boost::regex_search(interpretedSelection, re))
307  {
308  const edm::TypeWithDict elementType(const_cast<TClass*>(item->type()));
309  const edm::TypeWithDict wrapperType = edm::TypeWithDict::byName(edm::wrappedClassName(elementType.name()));
310  std::string fullBranchName = m_event->getBranchNameFor(wrapperType.typeInfo(),
311  item->moduleLabel().c_str(),
312  item->productInstanceLabel().c_str(),
313  item->processName().c_str());
314 
315  interpretedSelection = boost::regex_replace(interpretedSelection, re,
316  fullBranchName + ".obj");
317 
318  branch_names.push_back(fullBranchName);
319 
320  // printf("selection after applying s/%s/%s/: %s\n",
321  // (std::string("\\$") + (*i)->name()).c_str(),
322  // ((*i)->m_fullBranchName + ".obj").c_str(),
323  // interpretedSelection.c_str());
324  }
325  }
326 
327 
328  std::size_t found = interpretedSelection.find('$');
329  if (found!=std::string::npos)
330  {
331  fwLog(fwlog::kError) << "FWFileEntry::RunFilter invalid expression " << interpretedSelection << std::endl;
332  filter->m_needsUpdate = false;
333  return;
334  }
335 
336  m_file->cd();
337  m_eventTree->SetEventList(nullptr);
338 
339  auto prevCache = m_file->GetCacheRead(m_eventTree);
340 
341  auto interCache = new TTreeCache(m_eventTree, 10*1024*1024);
342  // Do not disconnect the cache, it will be reattached after filtering.
343  m_file->SetCacheRead(interCache, m_eventTree, TFile::kDoNotDisconnect);
344  interCache->SetEnablePrefetching(FWTTreeCache::IsPrefetching());
345  for (auto & b : branch_names)
346  interCache->AddBranch(b.c_str(), true);
347  interCache->StopLearningPhase();
348 
349  // Since ROOT will leave any TBranches used in the filtering at the last event,
350  // we need to be able to reset them to what fwlite::Event expects them to be.
351  // We do this by holding onto the old buffers and create temporary new ones.
352 
353  std::map<TBranch*, void*> prevAddrs;
354 
355  {
356  TObjArray* branches = m_eventTree->GetListOfBranches();
357  std::unique_ptr<TIterator> pIt( branches->MakeIterator());
358  while (TObject* branchObj = pIt->Next())
359  {
360  TBranch* b = dynamic_cast<TBranch*> (branchObj);
361  if (nullptr!=b)
362  {
363  const char * name = b->GetName();
364  unsigned int length = strlen(name);
365  if (length > 1 && name[length-1] != '.')
366  {
367  // This is not a data branch so we should ignore it.
368  continue;
369  }
370  if (nullptr != b->GetAddress())
371  {
372  if (prevAddrs.find(b) != prevAddrs.end())
373  {
374  fwLog(fwlog::kWarning) << "FWFileEntry::runFilter branch is already in the map!\n";
375  }
376  prevAddrs.insert(std::make_pair(b, b->GetAddress()));
377 
378  // std::cout <<"Zeroing branch: "<< b->GetName() <<" "<< (void*) b->GetAddress() <<std::endl;
379  b->SetAddress(nullptr);
380  }
381  }
382  }
383  }
384 
385  if (filter->m_eventList)
386  filter->m_eventList->Reset();
387  else
388  filter->m_eventList = new FWTEventList;
389 
390  fwLog(fwlog::kInfo) << "FWFileEntry::runFilter Running filter " << interpretedSelection << "' "
391  << "for file '" << m_file->GetName() << "'.\n";
392 
393  TEveSelectorToEventList stoelist(filter->m_eventList, interpretedSelection.c_str());
394  Long64_t result = m_eventTree->Process(&stoelist);
395 
396  if (result < 0)
397  fwLog(fwlog::kWarning) << "FWFileEntry::runFilter in file [" << m_file->GetName() << "] filter [" << filter->m_selector->m_expression << "] is invalid." << std::endl;
398  else
399  fwLog(fwlog::kDebug) << "FWFileEntry::runFilter is file [" << m_file->GetName() << "], filter [" << filter->m_selector->m_expression << "] has [" << filter->m_eventList->GetN() << "] events selected" << std::endl;
400 
401  // Set back the old branch buffers.
402  {
403  for (auto i : prevAddrs)
404  {
405  // std::cout <<"Resetting branch: "<< i.first->GetName() <<" "<< i.second <<std::endl;
406  i.first->SetAddress(i.second);
407  }
408  }
409 
410  m_file->SetCacheRead(prevCache, m_eventTree);
411  delete interCache;
412 
413  filter->m_needsUpdate = false;
414 }
415 
416 //______________________________________________________________________________
417 
418 bool
420 {
422 
423  boost::regex re_spaces("\\s+");
424  selection = boost::regex_replace(selection,re_spaces,"");
425  if (selection.find("&&") != std::string::npos &&
426  selection.find("||") != std::string::npos )
427  {
428  // Combination of && and || operators not supported.
429  return false;
430  }
431 
432  fwlite::Handle<edm::TriggerResults> hTriggerResults;
433  edm::TriggerNames const* triggerNames(nullptr);
434  try
435  {
436  hTriggerResults.getByLabel(*m_event,"TriggerResults","", filterEntry->m_selector->m_triggerProcess.c_str());
437  triggerNames = &(m_event->triggerNames(*hTriggerResults));
438  }
439  catch(...)
440  {
441  fwLog(fwlog::kWarning) << " failed to get trigger results with process name "<< filterEntry->m_selector->m_triggerProcess << std::endl;
442  return false;
443  }
444 
445  // std::cout << "Number of trigger names: " << triggerNames->size() << std::endl;
446  // for (unsigned int i=0; i<triggerNames->size(); ++i)
447  // std::cout << " " << triggerNames->triggerName(i);
448  //std::cout << std::endl;
449 
450  bool junction_mode = true; // AND
451  if (selection.find("||")!=std::string::npos)
452  junction_mode = false; // OR
453 
454  boost::regex re("\\&\\&|\\|\\|");
455 
456  boost::sregex_token_iterator i(selection.begin(), selection.end(), re, -1);
457  boost::sregex_token_iterator j;
458 
459  // filters and how they enter in the logical expression
460  std::vector<std::pair<unsigned int,bool> > filters;
461 
462  while (i != j)
463  {
464  std::string filter = *i++;
465  bool flag = true;
466  if (filter[0] == '!')
467  {
468  flag = false;
469  filter.erase(filter.begin());
470  }
471  unsigned int index = triggerNames->triggerIndex(filter);
472  if (index == triggerNames->size())
473  {
474  // Trigger name not found.
475  return false;
476  }
477  filters.push_back(std::make_pair(index, flag));
478  }
479  if (filters.empty())
480  return false;
481 
482  if (filterEntry->m_eventList)
483  filterEntry->m_eventList->Reset();
484  else
485  filterEntry->m_eventList = new FWTEventList();
486  FWTEventList* list = filterEntry->m_eventList;
487 
488  // loop over events
489  edm::EventID currentEvent = m_event->id();
490  unsigned int iEvent = 0;
491 
492  for (m_event->toBegin(); !m_event->atEnd(); ++(*m_event))
493  {
494  hTriggerResults.getByLabel(*m_event,"TriggerResults","", filterEntry->m_selector->m_triggerProcess.c_str());
495  std::vector<std::pair<unsigned int,bool> >::const_iterator filter = filters.begin();
496  bool passed = hTriggerResults->accept(filter->first) == filter->second;
497  while (++filter != filters.end())
498  {
499  if (junction_mode)
500  passed &= hTriggerResults->accept(filter->first) == filter->second;
501  else
502  passed |= hTriggerResults->accept(filter->first) == filter->second;
503  }
504  if (passed)
505  list->Enter(iEvent);
506  ++iEvent;
507  }
508  m_event->to(currentEvent);
509 
510  filterEntry->m_needsUpdate = false;
511 
512  fwLog(fwlog::kDebug) << "FWFile::filterEventsWithCustomParser file [" << m_file->GetName() << "], filter [" << filterEntry->m_selector->m_expression << "], selected [" << list->GetN() << "]" << std::endl;
513 
514  return true;
515 }
516 
517 //------------------------------------------------------------------------------
518 
520 {
521  FWTTreeCache *tc = dynamic_cast<FWTTreeCache*>(m_file->GetCacheRead(m_eventTree));
522  assert(tc != nullptr && "FWFileEntry::treeCache can not access TTreeCache");
523  return tc;
524 }
525 
528 {
529  const edm::TypeWithDict elementType(const_cast<TClass*>(it->type()));
530  const edm::TypeWithDict wrapperType = edm::TypeWithDict::byName(edm::wrappedClassName(elementType.name()));
531  return m_event->getBranchNameFor(wrapperType.typeInfo(),
532  it->moduleLabel().c_str(),
533  it->productInstanceLabel().c_str(),
534  it->processName().c_str());
535 }
536 
538 {
539  auto tc = fwTreeCache();
540 
542  printf("FWFileEntry:NewEventItemCallIn FWEventItem %s, learning=%d\n", getBranchName(it).c_str(),
543  tc->IsLearning());
544 
545  tc->AddBranchTopLevel(getBranchName(it).c_str());
546 }
547 
549 {
550  auto tc = fwTreeCache();
551 
553  printf("FWFileEntry:RemovingEventItemCallIn FWEventItem %s, learning=%d\n", getBranchName(it).c_str(),
554  tc->IsLearning());
555 
556  tc->DropBranchTopLevel(getBranchName(it).c_str());
557 }
fireworks::Context * getContext()
Definition: FWGUIManager.h:155
void closeFile()
Definition: FWFileEntry.cc:141
FWEventSelector * m_selector
Definition: FWFileEntry.h:41
Event const & toBegin() override
Go to the very first Event.
Definition: Event.cc:240
void openFile(bool)
Definition: FWFileEntry.cc:45
int lastSelectedEvent()
Definition: FWFileEntry.cc:179
const FWEventItemsManager * eventItemsManager() const
Definition: Context.h:61
void setEvent(const edm::EventBase *iEvent)
Definition: FWEventItem.cc:122
void RemovingEventItemCallIn(const FWEventItem *it)
Definition: FWFileEntry.cc:548
bool hasSelectedEvents()
Definition: FWFileEntry.cc:162
bool accept() const
Has at least one path accepted the event?
selection
main part
Definition: corrVsCorr.py:99
std::string getBranchName(const FWEventItem *it) const
Definition: FWFileEntry.cc:527
FWTEventList * m_eventList
Definition: FWFileEntry.h:40
void getPrimaryData() const
Definition: FWEventItem.cc:445
std::string m_triggerProcess
FWFileEntry(const std::string &name, bool checkVersion)
Definition: FWFileEntry.cc:30
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:531
#define nullptr
std::string const getBranchNameFor(std::type_info const &, char const *iModuleLabel, char const *iProductInstanceLabel, char const *iProcessName) const override
Return the branch name in the TFile which contains the data.
Definition: Event.cc:301
Long64_t size() const
Returns number of events in the file.
Definition: Event.cc:267
bool isEventSelected(int event)
Definition: FWFileEntry.cc:156
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:82
std::string const & processName() const
void getByLabel(const P &iP, const char *iModuleLabel, const char *iProductInstanceLabel=0, const char *iProcessLabel=0)
Definition: Handle.h:91
bool atEnd() const override
Definition: Event.cc:283
int iEvent
Definition: GenABIO.cc:230
const std::string & productInstanceLabel() const
Definition: FWEventItem.cc:525
std::list< Filter * > m_filterEntries
Definition: FWFileEntry.h:107
int * supportedDataFormatsVersion()
Definition: fwPaths.cc:43
unsigned int triggerIndex(std::string const &name) const
Definition: TriggerNames.cc:32
std::string name() const
static bool IsLogging()
Definition: FWTTreeCache.cc:28
std::string m_expression
const TClass * type() const
Definition: FWEventItem.cc:508
static bool IsPrefetching()
Definition: FWTTreeCache.cc:32
sigc::signal< void, FWEventItem * > newItem_
bool filterEventsWithCustomParser(Filter *filter)
Definition: FWFileEntry.cc:419
bool to(Long64_t iIndex)
Go to the event at index iIndex.
Definition: Event.cc:210
edm::TriggerNames const & triggerNames(edm::TriggerResults const &triggerResults) const override
Definition: Event.cc:425
std::type_info const & typeInfo() const
#define end
Definition: vmac.h:39
std::list< Filter * > & filters()
Definition: FWFileEntry.h:65
static int GetDefaultCacheSize()
Definition: FWTTreeCache.cc:35
TFile * m_file
Definition: FWFileEntry.h:101
virtual ~FWFileEntry()
Definition: FWFileEntry.cc:37
bool m_needUpdate
Definition: FWFileEntry.h:105
TTree * m_eventTree
Definition: FWFileEntry.h:102
fwlite::Event * m_event
Definition: FWFileEntry.h:103
const_iterator begin() const
NOTE: iterator is allowed to return a null object for items that have been removed.
int firstSelectedEvent()
Definition: FWFileEntry.cc:167
static FWGUIManager * getGUIManager()
#define fwLog(_level_)
Definition: fwLog.h:50
ReleaseVersion const & releaseVersion() const
std::string wrappedClassName(std::string const &iFullName)
bool hasEvent() const
Definition: FWEventItem.h:143
void runFilter(Filter *fe, const FWEventItemsManager *eiMng)
Definition: FWFileEntry.cc:277
double b
Definition: hdecay.h:120
tuple msg
Definition: mps_check.py:278
gErrorIgnoreLevel
Definition: utils.py:26
int nextSelectedEvent(int event)
Definition: FWFileEntry.cc:187
Definition: Filter.py:1
bool acceptDataFormatsVersion(TString &n)
Definition: fwPaths.cc:71
edm::EventID id() const
Definition: EventBase.h:60
void updateFilters(const FWEventItemsManager *eiMng, bool isOR)
Definition: FWFileEntry.cc:232
FWTTreeCache * fwTreeCache()
Definition: FWFileEntry.cc:519
void Enter(Long64_t entry) override
Definition: FWTEventList.cc:55
Definition: DDUnits.h:8
FWTEventList * m_globalEventList
Definition: FWFileEntry.h:108
bool hasActiveFilters()
Definition: FWFileEntry.cc:220
std::string m_name
Definition: FWFileEntry.h:100
int previousSelectedEvent(int event)
Definition: FWFileEntry.cc:202
void Add(const TEventList *list) override
Definition: FWTEventList.cc:7
std::vector< FWEventItem * >::const_iterator const_iterator
void NewEventItemCallIn(const FWEventItem *it)
Definition: FWFileEntry.cc:537
const std::string & moduleLabel() const
Definition: FWEventItem.cc:520
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