CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/DataFormats/PatCandidates/src/TriggerObjectStandAlone.cc

Go to the documentation of this file.
00001 //
00002 // $Id: TriggerObjectStandAlone.cc,v 1.15 2012/04/13 21:04:55 gpetrucc Exp $
00003 //
00004 
00005 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
00006 
00007 #include <boost/algorithm/string.hpp>
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 
00010 
00011 using namespace pat;
00012 
00013 
00014 // Const data members' definitions
00015 
00016 
00017 const char TriggerObjectStandAlone::wildcard_;
00018 
00019 
00020 // Constructors and Destructor
00021 
00022 
00023 // Default constructor
00024 TriggerObjectStandAlone::TriggerObjectStandAlone() :
00025   TriggerObject()
00026 {
00027   filterLabels_.clear();
00028   pathNames_.clear();
00029   pathLastFilterAccepted_.clear();
00030   pathL3FilterAccepted_.clear();
00031 }
00032 
00033 
00034 // Constructor from pat::TriggerObject
00035 TriggerObjectStandAlone::TriggerObjectStandAlone( const TriggerObject & trigObj ) :
00036   TriggerObject( trigObj )
00037 {
00038   filterLabels_.clear();
00039   pathNames_.clear();
00040   pathLastFilterAccepted_.clear();
00041   pathL3FilterAccepted_.clear();
00042 }
00043 
00044 
00045 // Constructor from trigger::TriggerObject
00046 TriggerObjectStandAlone::TriggerObjectStandAlone( const trigger::TriggerObject & trigObj ) :
00047   TriggerObject( trigObj )
00048 {
00049   filterLabels_.clear();
00050   pathNames_.clear();
00051   pathLastFilterAccepted_.clear();
00052   pathL3FilterAccepted_.clear();
00053 }
00054 
00055 
00056 // Constructor from reco::Candidate
00057 TriggerObjectStandAlone::TriggerObjectStandAlone( const reco::LeafCandidate & leafCand ) :
00058   TriggerObject( leafCand )
00059 {
00060   filterLabels_.clear();
00061   pathNames_.clear();
00062   pathLastFilterAccepted_.clear();
00063   pathL3FilterAccepted_.clear();
00064 }
00065 
00066 
00067 // Constructors from Lorentz-vectors and (optional) PDG ID
00068 TriggerObjectStandAlone::TriggerObjectStandAlone( const reco::Particle::LorentzVector & vec, int id ) :
00069   TriggerObject( vec, id )
00070 {
00071   filterLabels_.clear();
00072   pathNames_.clear();
00073   pathLastFilterAccepted_.clear();
00074   pathL3FilterAccepted_.clear();
00075 }
00076 TriggerObjectStandAlone::TriggerObjectStandAlone( const reco::Particle::PolarLorentzVector & vec, int id ) :
00077   TriggerObject( vec, id )
00078 {
00079   filterLabels_.clear();
00080   pathNames_.clear();
00081   pathLastFilterAccepted_.clear();
00082   pathL3FilterAccepted_.clear();
00083 }
00084 
00085 
00086 // Private methods
00087 
00088 
00089 // Checks a string vector for occurence of a certain string, incl. wild-card mechanism
00090 bool TriggerObjectStandAlone::hasAnyName( const std::string & name, const std::vector< std::string > & nameVec ) const
00091 {
00092   // Special cases first
00093   // Always false for empty vector to check
00094   if ( nameVec.empty() ) return false;
00095   // Always true for general wild-card(s)
00096   if ( name.find_first_not_of( wildcard_ ) == std::string::npos ) return true;
00097   // Split name to evaluate in parts, seperated by wild-cards
00098   std::vector< std::string > namePartsVec;
00099   boost::split( namePartsVec, name, boost::is_any_of( std::string( 1, wildcard_ ) ), boost::token_compress_on );
00100   // Iterate over vector of names to search
00101   for ( std::vector< std::string >::const_iterator iVec = nameVec.begin(); iVec != nameVec.end(); ++iVec ) {
00102     // Not failed yet
00103     bool failed( false );
00104     // Start searching at the first character
00105     size_type index( 0 );
00106     // Iterate over evaluation name parts
00107     for ( std::vector< std::string >::const_iterator iName = namePartsVec.begin(); iName != namePartsVec.end(); ++iName ) {
00108       // Empty parts due to
00109       // - wild-card at beginning/end or
00110       // - multiple wild-cards (should be supressed by 'boost::token_compress_on')
00111       if ( iName->length() == 0 ) continue;
00112       // Search from current index and
00113       // set index to found occurence
00114       index = iVec->find( *iName, index );
00115       // Failed and exit loop, if
00116       // - part not found
00117       // - part at beginning not found there
00118       if ( index == std::string::npos || ( iName == namePartsVec.begin() && index > 0 ) ) {
00119         failed = true;
00120         break;
00121       }
00122       // Increase index by length of found part
00123       index += iName->length();
00124     }
00125     // Failed, if end of name not reached
00126     if ( index < iVec->length() && namePartsVec.back().length() != 0 ) failed = true;
00127     // Match found!
00128     if ( ! failed ) return true;
00129   }
00130   // No match found!
00131   return false;
00132 }
00133 
00134 
00135 // Adds a new HLT path or L1 algorithm name
00136 void TriggerObjectStandAlone::addPathOrAlgorithm( const std::string & name, bool pathLastFilterAccepted, bool pathL3FilterAccepted )
00137 {
00138   // Check, if path is already assigned
00139   if ( ! hasPathOrAlgorithm( name, false, false ) ) {
00140     // The path itself
00141     pathNames_.push_back( name );
00142     // The corresponding usage of the trigger objects
00143     pathLastFilterAccepted_.push_back( pathLastFilterAccepted );
00144     pathL3FilterAccepted_.push_back( pathL3FilterAccepted );
00145   // Enable status updates
00146   } else if ( pathLastFilterAccepted || pathL3FilterAccepted ) {
00147     // Search for path
00148     unsigned index( 0 );
00149     while ( index < pathNames_.size() ) {
00150       if ( pathNames_.at( index ) == name ) break;
00151       ++index;
00152     }
00153     // Status update
00154     if ( index < pathNames_.size() ) {
00155       pathLastFilterAccepted_.at( index ) = pathLastFilterAccepted_.at( index ) || pathLastFilterAccepted;
00156       pathL3FilterAccepted_.at( index )   = pathL3FilterAccepted_.at( index )   || pathL3FilterAccepted;
00157     }
00158   }
00159 }
00160 
00161 
00162 // Gets all HLT path or L1 algorithm names
00163 std::vector< std::string > TriggerObjectStandAlone::pathsOrAlgorithms( bool pathLastFilterAccepted, bool pathL3FilterAccepted ) const
00164 {
00165   // Deal with older PAT-tuples, where trigger object usage is not available
00166   if ( ! hasLastFilter() ) pathLastFilterAccepted = false;
00167   if ( ! hasL3Filter() ) pathL3FilterAccepted = false;
00168   // All path names, if usage not restricted (not required or not available)
00169   if ( ! pathLastFilterAccepted && ! pathL3FilterAccepted ) return pathNames_;
00170   // Temp vector of path names
00171   std::vector< std::string > paths;
00172   // Loop over usage vector and fill corresponding paths into temp vector
00173   for ( unsigned iPath = 0; iPath < pathNames_.size(); ++iPath ) {
00174     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
00175   }
00176   // Return temp vector
00177   return paths;
00178 }
00179 
00180 
00181 // Checks, if a certain HLT filter label or L1 condition name is assigned
00182 bool TriggerObjectStandAlone::hasFilterOrCondition( const std::string & name ) const
00183 {
00184   // Move to wild-card parser, if needed
00185   if ( name.find( wildcard_ ) != std::string::npos ) return hasAnyName( name, filterLabels_ );
00186   // Return, if filter label is assigned
00187   return ( std::find( filterLabels_.begin(), filterLabels_.end(), name ) != filterLabels_.end() );
00188 }
00189 
00190 
00191 // Checks, if a certain path name is assigned
00192 bool TriggerObjectStandAlone::hasPathOrAlgorithm( const std::string & name, bool pathLastFilterAccepted, bool pathL3FilterAccepted ) const
00193 {
00194   // Move to wild-card parser, if needed
00195   if ( name.find( wildcard_ ) != std::string::npos ) return hasAnyName( name, pathsOrAlgorithms( pathLastFilterAccepted, pathL3FilterAccepted ) );
00196   // Deal with older PAT-tuples, where trigger object usage is not available
00197   if ( ! hasLastFilter() ) pathLastFilterAccepted = false;
00198   if ( ! hasL3Filter() ) pathL3FilterAccepted = false;
00199   // Check, if path name is assigned at all
00200   std::vector< std::string >::const_iterator match( std::find( pathNames_.begin(), pathNames_.end(), name ) );
00201   // False, if path name not assigned
00202   if ( match == pathNames_.end() ) return false;
00203   if ( ! pathLastFilterAccepted && ! pathL3FilterAccepted ) return true;
00204   bool foundLastFilter( pathLastFilterAccepted ? pathLastFilterAccepted_.at( match - pathNames_.begin() ) : true );
00205   bool foundL3Filter( pathL3FilterAccepted ? pathL3FilterAccepted_.at( match - pathNames_.begin() ) : true );
00206   // Return for assigned path name, if trigger object usage meets requirement
00207   return ( foundLastFilter && foundL3Filter );
00208 }
00209 
00210 
00211 // Methods
00212 
00213 
00214 // Gets the pat::TriggerObject (parent class)
00215 TriggerObject TriggerObjectStandAlone::triggerObject()
00216 {
00217   // Create a TriggerObjects
00218   TriggerObject theObj( p4(), pdgId() );
00219   // Set its collection and trigger objects types (no c'tor for that)
00220   theObj.setCollection( collection() );
00221   for ( size_t i = 0; i < triggerObjectTypes().size(); ++i ) theObj.addTriggerObjectType( triggerObjectTypes().at( i ) );
00222   // Return TriggerObject
00223   return theObj;
00224 }
00225 
00226 
00227 // Checks, if a certain label of original collection is assigned (method overrides)
00228 bool TriggerObjectStandAlone::hasCollection( const std::string & collName ) const
00229 {
00230   // Move to wild-card parser, if needed only
00231   if ( collName.find( wildcard_ ) != std::string::npos ) {
00232     // True, if collection name is simply fine
00233     if ( hasAnyName( collName, std::vector< std::string >( 1, collection() ) ) ) return true;
00234     // Check, if collection name possibly fits in an edm::InputTag approach
00235     const edm::InputTag collectionTag( collection() );
00236     const edm::InputTag collTag( collName );
00237     // If evaluated collection tag contains a process name, it must have been found already by identity check
00238     if ( collTag.process().empty() ) {
00239       // Check instance ...
00240       if ( ( collTag.instance().empty() && collectionTag.instance().empty() ) || hasAnyName( collTag.instance(), std::vector< std::string >( 1, collectionTag.instance() ) ) ) {
00241         // ... and label
00242         return hasAnyName( collTag.label(), std::vector< std::string >( 1, collectionTag.label() ) );
00243       }
00244     }
00245     return false;
00246   }
00247   // Use parent class's method otherwise
00248   return TriggerObject::hasCollection( collName );
00249 }