CMS 3D CMS Logo

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