CMS 3D CMS Logo

TriggerObjectStandAlone.cc
Go to the documentation of this file.
1 //
2 //
3 
6 
7 #include <boost/algorithm/string.hpp>
8 #include <tbb/concurrent_unordered_map.h>
11 
16 
17 using namespace pat;
18 
19 
20 // Const data members' definitions
21 
22 
24 
25 
26 // Constructors and Destructor
27 
28 
29 // Default constructor
32 {
33  filterLabels_.clear();
34  filterLabelIndices_.clear();
35  pathNames_.clear();
37  pathL3FilterAccepted_.clear();
38 }
39 
40 
41 // Constructor from pat::TriggerObject
43  TriggerObject( trigObj )
44 {
45  filterLabels_.clear();
46  filterLabelIndices_.clear();
47  pathNames_.clear();
49  pathL3FilterAccepted_.clear();
50 }
51 
52 
53 // Constructor from trigger::TriggerObject
55  TriggerObject( trigObj )
56 {
57  filterLabels_.clear();
58  filterLabelIndices_.clear();
59  pathNames_.clear();
61  pathL3FilterAccepted_.clear();
62 }
63 
64 
65 // Constructor from reco::Candidate
67  TriggerObject( leafCand )
68 {
69  filterLabels_.clear();
70  filterLabelIndices_.clear();
71  pathNames_.clear();
73  pathL3FilterAccepted_.clear();
74 }
75 
76 
77 // Constructors from Lorentz-vectors and (optional) PDG ID
79  TriggerObject( vec, id )
80 {
81  filterLabels_.clear();
82  filterLabelIndices_.clear();
83  pathNames_.clear();
85  pathL3FilterAccepted_.clear();
86 }
88  TriggerObject( vec, id )
89 {
90  filterLabels_.clear();
91  filterLabelIndices_.clear();
92  pathNames_.clear();
94  pathL3FilterAccepted_.clear();
95 }
96 
97 
98 // Private methods
99 
100 
101 // Checks a string vector for occurence of a certain string, incl. wild-card mechanism
102 bool TriggerObjectStandAlone::hasAnyName( const std::string & name, const std::vector< std::string > & nameVec ) const
103 {
104  // Special cases first
105  // Always false for empty vector to check
106  if ( nameVec.empty() ) return false;
107  // Always true for general wild-card(s)
108  if ( name.find_first_not_of( wildcard_ ) == std::string::npos ) return true;
109  // Split name to evaluate in parts, seperated by wild-cards
110  std::vector< std::string > namePartsVec;
111  boost::split( namePartsVec, name, boost::is_any_of( std::string( 1, wildcard_ ) ), boost::token_compress_on );
112  // Iterate over vector of names to search
113  for ( std::vector< std::string >::const_iterator iVec = nameVec.begin(); iVec != nameVec.end(); ++iVec ) {
114  // Not failed yet
115  bool failed( false );
116  // Start searching at the first character
117  size_type index( 0 );
118  // Iterate over evaluation name parts
119  for ( std::vector< std::string >::const_iterator iName = namePartsVec.begin(); iName != namePartsVec.end(); ++iName ) {
120  // Empty parts due to
121  // - wild-card at beginning/end or
122  // - multiple wild-cards (should be supressed by 'boost::token_compress_on')
123  if ( iName->length() == 0 ) continue;
124  // Search from current index and
125  // set index to found occurence
126  index = iVec->find( *iName, index );
127  // Failed and exit loop, if
128  // - part not found
129  // - part at beginning not found there
130  if ( index == std::string::npos || ( iName == namePartsVec.begin() && index > 0 ) ) {
131  failed = true;
132  break;
133  }
134  // Increase index by length of found part
135  index += iName->length();
136  }
137  // Failed, if end of name not reached
138  if ( index < iVec->length() && namePartsVec.back().length() != 0 ) failed = true;
139  // Match found!
140  if ( ! failed ) return true;
141  }
142  // No match found!
143  return false;
144 }
145 
146 
147 // Adds a new HLT path or L1 algorithm name
148 void TriggerObjectStandAlone::addPathOrAlgorithm( const std::string & name, bool pathLastFilterAccepted, bool pathL3FilterAccepted )
149 {
151 
152  // Check, if path is already assigned
153  if ( ! hasPathOrAlgorithm( name, false, false ) ) {
154  // The path itself
155  pathNames_.push_back( name );
156  // The corresponding usage of the trigger objects
157  pathLastFilterAccepted_.push_back( pathLastFilterAccepted );
158  pathL3FilterAccepted_.push_back( pathL3FilterAccepted );
159  // Enable status updates
160  } else if ( pathLastFilterAccepted || pathL3FilterAccepted ) {
161  // Search for path
162  unsigned index( 0 );
163  while ( index < pathNames_.size() ) {
164  if ( pathNames_.at( index ) == name ) break;
165  ++index;
166  }
167  // Status update
168  if ( index < pathNames_.size() ) {
169  pathLastFilterAccepted_.at( index ) = pathLastFilterAccepted_.at( index ) || pathLastFilterAccepted;
170  pathL3FilterAccepted_.at( index ) = pathL3FilterAccepted_.at( index ) || pathL3FilterAccepted;
171  }
172  }
173 }
174 
175 
176 // Gets all HLT path or L1 algorithm names
177 std::vector< std::string > TriggerObjectStandAlone::pathsOrAlgorithms( bool pathLastFilterAccepted, bool pathL3FilterAccepted ) const
178 {
180 
181  // Deal with older PAT-tuples, where trigger object usage is not available
182  if ( ! hasLastFilter() ) pathLastFilterAccepted = false;
183  if ( ! hasL3Filter() ) pathL3FilterAccepted = false;
184  // All path names, if usage not restricted (not required or not available)
185  if ( ! pathLastFilterAccepted && ! pathL3FilterAccepted ) return pathNames_;
186  // Temp vector of path names
187  std::vector< std::string > paths;
188  // Loop over usage vector and fill corresponding paths into temp vector
189  for ( unsigned iPath = 0; iPath < pathNames_.size(); ++iPath ) {
190  if ( ( ! pathLastFilterAccepted || pathLastFilterAccepted_.at( iPath ) ) && ( ! pathL3FilterAccepted || pathL3FilterAccepted_.at( iPath ) ) ) paths.push_back( pathNames_.at( iPath ) ); // order matters in order to protect from empty vectors in old data
191  }
192  // Return temp vector
193  return paths;
194 }
195 
196 
197 // Checks, if a certain HLT filter label or L1 condition name is assigned
199 {
201 
202  // Move to wild-card parser, if needed
203  if ( name.find( wildcard_ ) != std::string::npos ) return hasAnyName( name, filterLabels_ );
204  // Return, if filter label is assigned
205  return ( std::find( filterLabels_.begin(), filterLabels_.end(), name ) != filterLabels_.end() );
206 }
207 
208 
209 // Checks, if a certain path name is assigned
210 bool TriggerObjectStandAlone::hasPathOrAlgorithm( const std::string & name, bool pathLastFilterAccepted, bool pathL3FilterAccepted ) const
211 {
213 
214  // Move to wild-card parser, if needed
215  if ( name.find( wildcard_ ) != std::string::npos ) return hasAnyName( name, pathsOrAlgorithms( pathLastFilterAccepted, pathL3FilterAccepted ) );
216  // Deal with older PAT-tuples, where trigger object usage is not available
217  if ( ! hasLastFilter() ) pathLastFilterAccepted = false;
218  if ( ! hasL3Filter() ) pathL3FilterAccepted = false;
219  // Check, if path name is assigned at all
220  std::vector< std::string >::const_iterator match( std::find( pathNames_.begin(), pathNames_.end(), name ) );
221  // False, if path name not assigned
222  if ( match == pathNames_.end() ) return false;
223  if ( ! pathLastFilterAccepted && ! pathL3FilterAccepted ) return true;
224  bool foundLastFilter( pathLastFilterAccepted ? pathLastFilterAccepted_.at( match - pathNames_.begin() ) : true );
225  bool foundL3Filter( pathL3FilterAccepted ? pathL3FilterAccepted_.at( match - pathNames_.begin() ) : true );
226  // Return for assigned path name, if trigger object usage meets requirement
227  return ( foundLastFilter && foundL3Filter );
228 }
229 
230 
231 // Methods
232 
233 
234 // Gets the pat::TriggerObject (parent class)
236 {
237  // Create a TriggerObjects
238  TriggerObject theObj( p4(), pdgId() );
239  // Set its collection and trigger objects types (no c'tor for that)
240  theObj.setCollection( collection() );
241  for ( size_t i = 0; i < triggerObjectTypes().size(); ++i ) theObj.addTriggerObjectType( triggerObjectTypes().at( i ) );
242  // Return TriggerObject
243  return theObj;
244 }
245 
246 
247 // Checks, if a certain label of original collection is assigned (method overrides)
249 {
250  // Move to wild-card parser, if needed only
251  if ( collName.find( wildcard_ ) != std::string::npos ) {
252  // True, if collection name is simply fine
253  if ( hasAnyName( collName, std::vector< std::string >( 1, collection() ) ) ) return true;
254  // Check, if collection name possibly fits in an edm::InputTag approach
255  const edm::InputTag collectionTag( collection() );
256  const edm::InputTag collTag( collName );
257  // If evaluated collection tag contains a process name, it must have been found already by identity check
258  if ( collTag.process().empty() ) {
259  // Check instance ...
260  if ( ( collTag.instance().empty() && collectionTag.instance().empty() ) || hasAnyName( collTag.instance(), std::vector< std::string >( 1, collectionTag.instance() ) ) ) {
261  // ... and label
262  return hasAnyName( collTag.label(), std::vector< std::string >( 1, collectionTag.label() ) );
263  }
264  }
265  return false;
266  }
267  // Use parent class's method otherwise
268  return TriggerObject::hasCollection( collName );
269 }
270 
271 
272 bool TriggerObjectStandAlone::checkIfPathsAreUnpacked(bool throwIfPacked) const {
273  bool unpacked = (!pathNames_.empty() || pathIndices_.empty());
274  if (!unpacked && throwIfPacked) throw cms::Exception("RuntimeError", "This TriggerObjectStandAlone object has packed trigger path names. Before accessing path names you must call unpackPathNames with an edm::TriggerNames object. You can get the latter from the edm::Event or fwlite::Event and the TriggerResults\n");
275  return unpacked;
276 }
278  bool unpacked = filterLabelIndices_.empty();
279  if (!unpacked && throwIfPacked) throw cms::Exception("RuntimeError", "This TriggerObjectStandAlone object has packed trigger filter labels. Before accessing path names you must call unpackFilterLabels with an edm::EventBase object. Both the edm::Event or fwlite::Event are derived from edm::EventBase and can be passed\n");
280  return unpacked;
281 }
282 
283 
284 
286  if (!pathIndices_.empty()) {
287  if (!pathNames_.empty()) {
288  throw cms::Exception("RuntimeError", "Error, trying to pack a partially packed TriggerObjectStandAlone");
289  } else {
290  return;
291  }
292  }
293  bool ok = true;
294  unsigned int n = pathNames_.size(), end = names.size();
295  std::vector<uint16_t> indices(n);
296  for (unsigned int i = 0; i < n; ++i) {
297  uint16_t id = names.triggerIndex(pathNames_[i]);
298  if (id >= end) {
299  static std::atomic<int> _warn(0);
300  if (++_warn < 5) edm::LogWarning("TriggerObjectStandAlone::packPathNames()") << "Warning: can't resolve '" << pathNames_[i] << "' to a path index" << std::endl;
301  ok = false; break;
302  } else {
303  indices[i] = id;
304  }
305  }
306  if (ok) {
307  pathIndices_.swap(indices);
308  pathNames_.clear();
309  }
310 }
311 
313  if (!pathNames_.empty()) {
314  if (!pathIndices_.empty()) {
315  throw cms::Exception("RuntimeError", "Error, trying to unpack a partially unpacked TriggerObjectStandAlone");
316  } else {
317  return;
318  }
319  }
320  unsigned int n = pathIndices_.size(), end = names.size();
321  std::vector<std::string> paths(n);
322  for (unsigned int i = 0; i < n; ++i) {
323  if (pathIndices_[i] >= end) throw cms::Exception("RuntimeError", "Error, path index out of bounds");
324  paths[i] = names.triggerName(pathIndices_[i]);
325  }
326  pathIndices_.clear();
327  pathNames_.swap(paths);
328 }
329 
330 void TriggerObjectStandAlone::packFilterLabels(const std::vector<std::string> &names) {
331  if (!filterLabelIndices_.empty()) {
332  throw cms::Exception("RuntimeError", "Error, trying to pack filter labels for an already packed TriggerObjectStandAlone");
333  }
334  std::vector<std::string> unmatched;
335  std::vector<uint16_t> indices;
336  indices.reserve(filterLabels_.size());
337 
338  auto nStart = names.begin(), nEnd = names.end();
339  for (unsigned int i = 0, n = filterLabels_.size(); i < n; ++i) {
340  auto match = std::lower_bound(nStart, nEnd, filterLabels_[i]);
341  if (match != nEnd && *match == filterLabels_[i]) {
342  indices.push_back(match - nStart);
343  } else {
344  static std::atomic<int> _warn(0);
345  if(++_warn < 5) edm::LogWarning("TriggerObjectStandAlone::packFilterLabels()") << "Warning: can't resolve '" << filterLabels_[i] << "' to a label index. idx: " << i <<std::endl;
346  unmatched.push_back(std::move(filterLabels_[i]));
347  }
348  }
349  std::sort(indices.begin(), indices.end()); // try reduce enthropy
350  filterLabelIndices_.swap(indices);
351  filterLabels_.swap(unmatched);
352 }
353 
355 {
356  unpackPathNames(event.triggerNames(res));
357  unpackFilterLabels(event,res);
358 
359 }
360 
362  unpackFilterLabels(*allLabels(psetId_,event,res));
363 }
364 
365 void TriggerObjectStandAlone::unpackFilterLabels(const std::vector<std::string> &labels) {
366  if (filterLabelIndices_.empty()) return;
367 
368  std::vector<std::string> mylabels(filterLabels_);
369  for (unsigned int i = 0, n = filterLabelIndices_.size(), m = labels.size(); i < n; ++i) {
370  if (filterLabelIndices_[i] >= m) throw cms::Exception("RuntimeError", "Error, filter label index out of bounds");
371  mylabels.push_back(labels[filterLabelIndices_[i]]);
372  }
373  filterLabelIndices_.clear();
374  filterLabels_.swap(mylabels);
375 }
377  packFilterLabels(*allLabels(psetId_,event,res));
378 }
379 
380 
383  MiniFloatConverter::reduceMantissaToNbitsRounding<14>(pt()),
384  MiniFloatConverter::reduceMantissaToNbitsRounding<11>(eta()),
385  MiniFloatConverter::reduceMantissaToNbits<11>(phi()),
386  MiniFloatConverter::reduceMantissaToNbitsRounding<8>(mass()) ));
387 }
388 
389 namespace {
390  struct key_hash {
391  std::size_t operator()(edm::ParameterSetID const& iKey) const{
392  return iKey.smallHash();
393  }
394  };
395  typedef tbb::concurrent_unordered_map<edm::ParameterSetID, std::vector<std::string>, key_hash> AllLabelsMap;
396  [[cms::thread_safe]] AllLabelsMap allLabelsMap;
397 }
398 
399 std::vector<std::string> const* TriggerObjectStandAlone::allLabels(edm::ParameterSetID const& psetid, const edm::EventBase &event,const edm::TriggerResults &res) const {
400 
401  // If TriggerNames was already created and cached here in the map,
402  // then look it up and return that one
403  AllLabelsMap::const_iterator iter =
404  allLabelsMap.find(psetid);
405  if (iter != allLabelsMap.end()) {
406  return &iter->second;
407  }
408 
409  auto triggerNames= event.triggerNames(res);
410  edm::ParameterSet const* pset=nullptr;
411  //getting the ParameterSet from the event ensures that the registry is filled
412  if (nullptr!=(pset=event.parameterSet(psetid ))) {
413  using namespace std;
414  using namespace edm;
415  using namespace trigger;
416 
417 
418  const unsigned int n(triggerNames.size());
419  std::set<std::string> saveTags;
420  for (unsigned int i=0;i!=n; ++i) {
421  if (pset->existsAs<vector<string> >(triggerNames.triggerName(i),true)) {
422  auto modules = pset->getParameter<vector<string> >(triggerNames.triggerName(i));
423  for(size_t m=0; m < modules.size(); m++){
424  auto module=modules[m];
425  auto moduleStrip=module.front()!='-' ? module : module.substr(1);
426 
427  if (pset->exists(moduleStrip)) {
428  auto modulePSet= pset->getParameterSet(moduleStrip);
429  if (modulePSet.existsAs<bool>("saveTags",true) and
430  modulePSet.getParameter<bool>("saveTags") ) {
431  saveTags.insert(moduleStrip);
432  }
433  }
434  }
435  }
436  }
437  std::vector<std::string> allModules(saveTags.begin(),saveTags.end());
438  std::pair<AllLabelsMap::iterator, bool> ret =
439  allLabelsMap.insert(std::pair<edm::ParameterSetID, std::vector<std::string> >(psetid, allModules));
440  return &(ret.first->second);
441  }
442  return 0;
443  }
444 
void packFilterLabels(const edm::EventBase &event, const edm::TriggerResults &res)
T getParameter(std::string const &) const
virtual double pt() const final
transverse momentum
std::vector< std::string > pathsOrAlgorithms(bool pathLastFilterAccepted, bool pathL3FilterAccepted) const
Gets all HLT path or L1 algorithm names.
bool checkIfPathsAreUnpacked(bool throwIfPacked=true) const
Check if trigger names have been packed by calling packPathNames() and not yet unpacked.
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
virtual double mass() const final
mass
void packP4()
reduce the precision on the 4-vector
static const HistoName names[]
bool checkIfFiltersAreUnpacked(bool throwIfPacked=true) const
Check if trigger names have been packed by calling packFilterLabels() and not yet unpacked...
size_t size_type
Definition: Candidate.h:30
virtual double eta() const final
momentum pseudorapidity
bool id(trigger::TriggerObjectType triggerObjectType) const
virtual bool hasCollection(const std::string &collName) const
Checks, if a certain label of original collection is assigned (method overrides)
static const char wildcard_
Constants.
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::vector< std::string > pathNames_
Vector of names of all HLT paths or L1 algorithms the trigger objects has been used in...
void insert(bool ok_to_replace, char const *, Entry const &)
std::vector< std::string > filterLabels_
Vector of labels of all HLT filters or names of L1 conditions the trigger objects has been used in...
Strings::size_type size() const
Definition: TriggerNames.cc:39
void unpackPathNames(const edm::TriggerNames &names)
unpack trigger names into indices
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
Definition: Electron.h:4
Definition: HeavyIon.h:7
bool hasAnyName(const std::string &name, const std::vector< std::string > &nameVec) const
Private methods.
void addPathOrAlgorithm(const std::string &name, bool pathLastFilterAccepted, bool pathL3FilterAccepted)
Adds a new HLT path or L1 algorithm name.
Single trigger physics object (e.g., an isolated muon)
Definition: TriggerObject.h:22
TriggerObject triggerObject()
Gets the pat::TriggerObject (parent class)
virtual double phi() const final
momentum azimuthal angle
unsigned int triggerIndex(std::string const &name) const
Definition: TriggerNames.cc:32
void setCollection(const std::string &collName)
Methods.
Definition: TriggerObject.h:84
const_iterator end() const
last daughter const_iterator
Definition: Candidate.h:146
const std::string & collection() const
Get the label of the collection the trigger object originates from.
Definition: TriggerObject.h:92
virtual int pdgId() const final
PDG identifier.
TriggerObjectStandAlone()
Constructors and Destructor.
std::vector< std::string > const * allLabels(edm::ParameterSetID const &psetid, const edm::EventBase &event, const edm::TriggerResults &res) const
unsigned int index
Definition: LeafCandidate.h:31
std::vector< int > triggerObjectTypes() const
Get all trigger object type identifiers.
virtual edm::ParameterSet const * parameterSet(edm::ParameterSetID const &psID) const =0
bool hasLastFilter() const
Check, if the usage indicator vectors have been filled.
unsigned int index
index type
Definition: Candidate.h:51
void unpackFilterLabels(const std::vector< std::string > &labels)
unpack filter labels from indices
bool hasPathOrAlgorithm(const std::string &name, bool pathLastFilterAccepted, bool pathL3FilterAccepted) const
Checks, if a certain HLT path or L1 algorithm name is assigned.
std::vector< bool > pathL3FilterAccepted_
ParameterSet const & getParameterSet(std::string const &) const
std::string const & triggerName(unsigned int index) const
Definition: TriggerNames.cc:27
void packPathNames(const edm::TriggerNames &names)
pack trigger names into indices
size_t smallHash() const
returns a short hash which can be used with hashing containers
Definition: Hash.h:221
virtual bool hasCollection(const std::string &collName) const
Checks, if a certain label of original collection is assigned.
virtual void setP4(const LorentzVector &p4) final
set 4-momentum
std::string const & label() const
Definition: InputTag.h:36
std::string const & process() const
Definition: InputTag.h:40
HLT enums.
std::vector< uint16_t > pathIndices_
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Particle.h:23
std::vector< uint16_t > filterLabelIndices_
bool hasFilterOrCondition(const std::string &name) const
Checks, if a certain HLT filter label or L1 condition name is assigned.
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
virtual TriggerNames const & triggerNames(edm::TriggerResults const &triggerResults) const =0
virtual const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
void addTriggerObjectType(trigger::TriggerObjectType triggerObjectType)
Add a new trigger object type identifier.
Definition: TriggerObject.h:87
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:21
Definition: vlib.h:208
std::string const & instance() const
Definition: InputTag.h:37
std::vector< bool > pathLastFilterAccepted_
double split
Definition: MVATrainer.cc:139
void unpackNamesAndLabels(const edm::EventBase &event, const edm::TriggerResults &res)
unpack both filter labels and trigger names
def move(src, dest)
Definition: eostools.py:510
Definition: event.py:1