CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/PhysicsTools/PatAlgos/plugins/PATTriggerProducer.cc

Go to the documentation of this file.
00001 //
00002 // $Id: PATTriggerProducer.cc,v 1.25.2.1 2011/03/16 16:20:15 vadler Exp $
00003 //
00004 
00005 
00006 #include "PhysicsTools/PatAlgos/plugins/PATTriggerProducer.h"
00007 
00008 #include <vector>
00009 #include <map>
00010 #include <utility>
00011 #include <cassert>
00012 
00013 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
00014 #include "CondFormats/DataRecord/interface/L1GtTriggerMenuRcd.h"
00015 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
00016 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
00017 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMapRecord.h"
00018 #include "DataFormats/Common/interface/TriggerResults.h"
00019 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
00020 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00021 #include "FWCore/ParameterSet/interface/Registry.h"
00022 
00023 #include "DataFormats/PatCandidates/interface/TriggerAlgorithm.h"
00024 #include "DataFormats/PatCandidates/interface/TriggerCondition.h"
00025 #include "DataFormats/PatCandidates/interface/TriggerPath.h"
00026 #include "DataFormats/PatCandidates/interface/TriggerFilter.h"
00027 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
00028 
00029 #include "FWCore/Framework/interface/ESHandle.h"
00030 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00031 
00032 
00033 using namespace pat;
00034 using namespace edm;
00035 
00036 
00037 // Constants' definitions
00038 const unsigned L1GlobalTriggerReadoutSetup::NumberPhysTriggers;
00039 const unsigned L1GlobalTriggerReadoutSetup::NumberPhysTriggersExtended;
00040 const unsigned L1GlobalTriggerReadoutSetup::NumberTechnicalTriggers;
00041 
00042 
00043 PATTriggerProducer::PATTriggerProducer( const ParameterSet & iConfig ) :
00044   nameProcess_( iConfig.getParameter< std::string >( "processName" ) ),
00045   autoProcessName_( nameProcess_ == "*" ),
00046   onlyStandAlone_( iConfig.getParameter< bool >( "onlyStandAlone" ) ),
00047   // L1 configuration parameters
00048   addL1Algos_( false ),
00049   tagL1GlobalTriggerObjectMapRecord_( "hltL1GtObjectMap" ),
00050   tagL1ExtraMu_(),
00051   tagL1ExtraNoIsoEG_(),
00052   tagL1ExtraIsoEG_(),
00053   tagL1ExtraCenJet_(),
00054   tagL1ExtraForJet_(),
00055   tagL1ExtraTauJet_(),
00056   tagL1ExtraETM_(),
00057   tagL1ExtraHTM_(),
00058   autoProcessNameL1ExtraMu_( false ),
00059   autoProcessNameL1ExtraNoIsoEG_( false ),
00060   autoProcessNameL1ExtraIsoEG_( false ),
00061   autoProcessNameL1ExtraCenJet_( false ),
00062   autoProcessNameL1ExtraForJet_( false ),
00063   autoProcessNameL1ExtraTauJet_( false ),
00064   autoProcessNameL1ExtraETM_( false ),
00065   autoProcessNameL1ExtraHTM_( false ),
00066   mainBxOnly_( true ),
00067   saveL1Refs_( false ),
00068   // HLT configuration parameters
00069   tagTriggerResults_( "TriggerResults" ),
00070   tagTriggerEvent_( "hltTriggerSummaryAOD" ),
00071   hltPrescaleLabel_(),
00072   labelHltPrescaleTable_(),
00073   hltPrescaleTableRun_(),
00074   hltPrescaleTableLumi_(),
00075   addPathModuleLabels_( false )
00076 {
00077 
00078   // L1 configuration parameters
00079   if ( iConfig.exists( "addL1Algos" ) ) addL1Algos_ = iConfig.getParameter< bool >( "addL1Algos" );
00080   if ( iConfig.exists( "l1GlobalTriggerObjectMapRecord" ) ) tagL1GlobalTriggerObjectMapRecord_ = iConfig.getParameter< InputTag >( "l1GlobalTriggerObjectMapRecord" );
00081   if ( iConfig.exists( "l1ExtraMu" ) ) {
00082     tagL1ExtraMu_ = iConfig.getParameter< InputTag >( "l1ExtraMu" );
00083     if ( tagL1ExtraMu_.process() == "*" ) {
00084       if ( autoProcessName_ ) autoProcessNameL1ExtraMu_ = true;
00085       else                    tagL1ExtraMu_ = InputTag( tagL1ExtraMu_.label(), tagL1ExtraMu_.instance(), nameProcess_ );
00086     }
00087   }
00088   if ( iConfig.exists( "l1ExtraNoIsoEG" ) ) {
00089     tagL1ExtraNoIsoEG_ = iConfig.getParameter< InputTag >( "l1ExtraNoIsoEG" );
00090     if ( tagL1ExtraNoIsoEG_.process() == "*" ) {
00091       if ( autoProcessName_ ) autoProcessNameL1ExtraNoIsoEG_ = true;
00092       else                    tagL1ExtraNoIsoEG_ = InputTag( tagL1ExtraNoIsoEG_.label(), tagL1ExtraNoIsoEG_.instance(), nameProcess_ );
00093     }
00094   }
00095   if ( iConfig.exists( "l1ExtraIsoEG" ) ) {
00096     tagL1ExtraIsoEG_ = iConfig.getParameter< InputTag >( "l1ExtraIsoEG" );
00097     if ( tagL1ExtraIsoEG_.process() == "*" ) {
00098       if ( autoProcessName_ ) autoProcessNameL1ExtraIsoEG_ = true;
00099       else                    tagL1ExtraIsoEG_ = InputTag( tagL1ExtraIsoEG_.label(), tagL1ExtraIsoEG_.instance(), nameProcess_ );
00100     }
00101   }
00102   if ( iConfig.exists( "l1ExtraCenJet" ) ) {
00103     tagL1ExtraCenJet_ = iConfig.getParameter< InputTag >( "l1ExtraCenJet" );
00104     if ( tagL1ExtraCenJet_.process() == "*" ) {
00105       if ( autoProcessName_ ) autoProcessNameL1ExtraCenJet_ = true;
00106       else                    tagL1ExtraCenJet_ = InputTag( tagL1ExtraCenJet_.label(), tagL1ExtraCenJet_.instance(), nameProcess_ );
00107     }
00108   }
00109   if ( iConfig.exists( "l1ExtraForJet" ) ) {
00110     tagL1ExtraForJet_ = iConfig.getParameter< InputTag >( "l1ExtraForJet" );
00111     if ( tagL1ExtraForJet_.process() == "*" ) {
00112       if ( autoProcessName_ ) autoProcessNameL1ExtraForJet_ = true;
00113       else                    tagL1ExtraForJet_ = InputTag( tagL1ExtraForJet_.label(), tagL1ExtraForJet_.instance(), nameProcess_ );
00114     }
00115   }
00116   if ( iConfig.exists( "l1ExtraTauJet" ) ) {
00117     tagL1ExtraTauJet_ = iConfig.getParameter< InputTag >( "l1ExtraTauJet" );
00118     if ( tagL1ExtraTauJet_.process() == "*" ) {
00119       if ( autoProcessName_ ) autoProcessNameL1ExtraTauJet_ = true;
00120       else                    tagL1ExtraTauJet_ = InputTag( tagL1ExtraTauJet_.label(), tagL1ExtraTauJet_.instance(), nameProcess_ );
00121     }
00122   }
00123   if ( iConfig.exists( "l1ExtraETM" ) ) {
00124     tagL1ExtraETM_ = iConfig.getParameter< InputTag >( "l1ExtraETM" );
00125     if ( tagL1ExtraETM_.process() == "*" ) {
00126       if ( autoProcessName_ ) autoProcessNameL1ExtraETM_ = true;
00127       else                    tagL1ExtraETM_ = InputTag( tagL1ExtraETM_.label(), tagL1ExtraETM_.instance(), nameProcess_ );
00128     }
00129   }
00130   if ( iConfig.exists( "l1ExtraHTM" ) ) {
00131     tagL1ExtraHTM_ = iConfig.getParameter< InputTag >( "l1ExtraHTM" );
00132     if ( tagL1ExtraHTM_.process() == "*" ) {
00133       if ( autoProcessName_ ) autoProcessNameL1ExtraHTM_ = true;
00134       else                    tagL1ExtraHTM_ = InputTag( tagL1ExtraHTM_.label(), tagL1ExtraHTM_.instance(), nameProcess_ );
00135     }
00136   }
00137   if ( iConfig.exists( "mainBxOnly" ) ) mainBxOnly_ = iConfig.getParameter< bool >( "mainBxOnly" );
00138   if ( iConfig.exists( "saveL1Refs" ) ) saveL1Refs_ = iConfig.getParameter< bool >( "saveL1Refs" );
00139 
00140   // HLT configuration parameters
00141   if ( iConfig.exists( "triggerResults" ) )      tagTriggerResults_     = iConfig.getParameter< InputTag >( "triggerResults" );
00142   if ( iConfig.exists( "triggerEvent" ) )        tagTriggerEvent_       = iConfig.getParameter< InputTag >( "triggerEvent" );
00143   if ( iConfig.exists( "hltPrescaleLabel" ) )    hltPrescaleLabel_      = iConfig.getParameter< std::string >( "hltPrescaleLabel" );
00144   if ( iConfig.exists( "hltPrescaleTable" ) )    labelHltPrescaleTable_ = iConfig.getParameter< std::string >( "hltPrescaleTable" );
00145   if ( iConfig.exists( "addPathModuleLabels" ) ) addPathModuleLabels_   = iConfig.getParameter< bool >( "addPathModuleLabels" );
00146   exludeCollections_.clear();
00147   if ( iConfig.exists( "exludeCollections" )  ) exludeCollections_      = iConfig.getParameter< std::vector< std::string > >( "exludeCollections" );
00148 
00149   if ( ! onlyStandAlone_ ) {
00150     produces< TriggerAlgorithmCollection >();
00151     produces< TriggerConditionCollection >();
00152     produces< TriggerPathCollection >();
00153     produces< TriggerFilterCollection >();
00154     produces< TriggerObjectCollection >();
00155   }
00156   produces< TriggerObjectStandAloneCollection >();
00157 
00158 }
00159 
00160 
00161 void PATTriggerProducer::beginRun( Run & iRun, const EventSetup & iSetup )
00162 {
00163 
00164   // Initialize
00165   hltConfigInit_ = false;
00166 
00167   // Initialize process name
00168   if ( autoProcessName_ ) {
00169     // reset
00170     nameProcess_ = "*";
00171     // determine process name from last run TriggerSummaryProducerAOD module in process history of input
00172     const ProcessHistory & processHistory( iRun.processHistory() );
00173     ProcessConfiguration processConfiguration;
00174     ParameterSet processPSet;
00175     // unbroken loop, which relies on time ordering (accepts the last found entry)
00176     for ( ProcessHistory::const_iterator iHist = processHistory.begin(); iHist != processHistory.end(); ++iHist ) {
00177       if ( processHistory.getConfigurationForProcess( iHist->processName(), processConfiguration )     &&
00178            pset::Registry::instance()->getMapped( processConfiguration.parameterSetID(), processPSet ) &&
00179            processPSet.exists( tagTriggerEvent_.label() )
00180          ) {
00181         nameProcess_ = iHist->processName();
00182         LogDebug( "autoProcessName" ) << "HLT process name '" << nameProcess_ << "' discovered";
00183       }
00184     }
00185     // terminate, if nothing is found
00186     if ( nameProcess_ == "*" ) {
00187       LogError( "autoProcessName" ) << "trigger::TriggerEvent product with label '" << tagTriggerEvent_.label() << "' not produced according to process history of input data\n"
00188                                     << "No trigger information produced";
00189       return;
00190     }
00191     LogInfo( "autoProcessName" ) << "HLT process name' " << nameProcess_ << "' used for PAT trigger information";
00192   }
00193   // adapt configuration of used input tags
00194   if ( tagTriggerResults_.process().empty() || tagTriggerResults_.process() == "*" ) {
00195     tagTriggerResults_ = InputTag( tagTriggerResults_.label(), tagTriggerResults_.instance(), nameProcess_ );
00196   } else if ( tagTriggerEvent_.process() != nameProcess_ ) {
00197     LogWarning( "triggerResultsTag" ) << "TriggerResults process name '" << tagTriggerResults_.process() << "' differs from HLT process name '" << nameProcess_ << "'";
00198   }
00199   if ( tagTriggerEvent_.process().empty() || tagTriggerEvent_.process()   == "*" ) {
00200     tagTriggerEvent_ = InputTag( tagTriggerEvent_.label(), tagTriggerEvent_.instance(), nameProcess_ );
00201   } else if ( tagTriggerEvent_.process() != nameProcess_ ) {
00202     LogWarning( "triggerEventTag" ) << "TriggerEvent process name '" << tagTriggerEvent_.process() << "' differs from HLT process name '" << nameProcess_ << "'";
00203   }
00204   if ( autoProcessNameL1ExtraMu_ )      tagL1ExtraMu_      = InputTag( tagL1ExtraMu_.label()     , tagL1ExtraMu_.instance()     , nameProcess_ );
00205   if ( autoProcessNameL1ExtraNoIsoEG_ ) tagL1ExtraNoIsoEG_ = InputTag( tagL1ExtraNoIsoEG_.label(), tagL1ExtraNoIsoEG_.instance(), nameProcess_ );
00206   if ( autoProcessNameL1ExtraIsoEG_ )   tagL1ExtraIsoEG_   = InputTag( tagL1ExtraIsoEG_.label()  , tagL1ExtraIsoEG_.instance()  , nameProcess_ );
00207   if ( autoProcessNameL1ExtraCenJet_ )  tagL1ExtraCenJet_  = InputTag( tagL1ExtraCenJet_.label() , tagL1ExtraCenJet_.instance() , nameProcess_ );
00208   if ( autoProcessNameL1ExtraForJet_ )  tagL1ExtraForJet_  = InputTag( tagL1ExtraForJet_.label() , tagL1ExtraForJet_.instance() , nameProcess_ );
00209   if ( autoProcessNameL1ExtraTauJet_ )  tagL1ExtraTauJet_  = InputTag( tagL1ExtraTauJet_.label() , tagL1ExtraTauJet_.instance() , nameProcess_ );
00210   if ( autoProcessNameL1ExtraETM_ )     tagL1ExtraETM_     = InputTag( tagL1ExtraETM_.label()    , tagL1ExtraETM_.instance()    , nameProcess_ );
00211   if ( autoProcessNameL1ExtraHTM_ )     tagL1ExtraHTM_     = InputTag( tagL1ExtraHTM_.label()    , tagL1ExtraHTM_.instance()    , nameProcess_ );
00212 
00213   // Initialize HLTConfigProvider
00214   bool changed( true );
00215   if ( ! hltConfig_.init( iRun, iSetup, nameProcess_, changed ) ) {
00216     LogError( "hltConfigExtraction" ) << "HLT config extraction error with process name '" << nameProcess_ << "'";
00217   } else if ( hltConfig_.size() <= 0 ) {
00218     LogError( "hltConfigSize" ) << "HLT config size error";
00219   } else hltConfigInit_ = true;
00220 
00221   // Extract pre-scales
00222   if ( hltConfigInit_ ) {
00223     // Start empty
00224     hltPrescaleTableRun_ = trigger::HLTPrescaleTable();
00225     // Try run product, if configured
00226     if ( ! labelHltPrescaleTable_.empty() ) {
00227       Handle< trigger::HLTPrescaleTable > handleHltPrescaleTable;
00228       iRun.getByLabel( InputTag( labelHltPrescaleTable_, "Run", nameProcess_ ), handleHltPrescaleTable );
00229       if ( handleHltPrescaleTable.isValid() ) {
00230         hltPrescaleTableRun_ = trigger::HLTPrescaleTable( handleHltPrescaleTable->set(), handleHltPrescaleTable->labels(), handleHltPrescaleTable->table() );
00231       }
00232     }
00233   }
00234 
00235 }
00236 
00237 
00238 void PATTriggerProducer::beginLuminosityBlock( LuminosityBlock & iLuminosityBlock, const EventSetup & iSetup )
00239 {
00240 
00241   // Terminate, if auto process name determination failed
00242   if ( nameProcess_ == "*" ) return;
00243 
00244   // Extract pre-scales
00245   if ( hltConfigInit_ ) {
00246     // Start from run
00247     hltPrescaleTableLumi_ = trigger::HLTPrescaleTable( hltPrescaleTableRun_.set(), hltPrescaleTableRun_.labels(), hltPrescaleTableRun_.table() );
00248     // Try lumi product, if configured and available
00249     if ( ! labelHltPrescaleTable_.empty() ) {
00250       Handle< trigger::HLTPrescaleTable > handleHltPrescaleTable;
00251       iLuminosityBlock.getByLabel( InputTag( labelHltPrescaleTable_, "Lumi", nameProcess_ ), handleHltPrescaleTable );
00252       if ( handleHltPrescaleTable.isValid() ) {
00253         hltPrescaleTableLumi_ = trigger::HLTPrescaleTable( handleHltPrescaleTable->set(), handleHltPrescaleTable->labels(), handleHltPrescaleTable->table() );
00254       }
00255     }
00256   }
00257 
00258 }
00259 
00260 
00261 void PATTriggerProducer::produce( Event& iEvent, const EventSetup& iSetup )
00262 {
00263 
00264   // Terminate, if auto process name determination failed
00265   if ( nameProcess_ == "*" ) return;
00266 
00267   std::auto_ptr< TriggerObjectCollection > triggerObjects( new TriggerObjectCollection() );
00268   if ( onlyStandAlone_ ) triggerObjects->reserve( 0 );
00269   std::auto_ptr< TriggerObjectStandAloneCollection > triggerObjectsStandAlone( new TriggerObjectStandAloneCollection() );
00270 
00271   // HLT
00272 
00273   // Get and check HLT event data
00274   Handle< trigger::TriggerEvent > handleTriggerEvent;
00275   iEvent.getByLabel( tagTriggerEvent_, handleTriggerEvent );
00276   Handle< TriggerResults > handleTriggerResults;
00277   iEvent.getByLabel( tagTriggerResults_, handleTriggerResults );
00278   bool goodHlt( hltConfigInit_ );
00279   if ( goodHlt ) {
00280     if( ! handleTriggerResults.isValid() ) {
00281       LogError( "triggerResultsValid" ) << "TriggerResults product with InputTag '" << tagTriggerResults_.encode() << "' not in event\n"
00282                                         << "No HLT information produced";
00283       goodHlt = false;
00284     } else if ( ! handleTriggerEvent.isValid() ) {
00285       LogError( "triggerEventValid" ) << "trigger::TriggerEvent product with InputTag '" << tagTriggerEvent_.encode() << "' not in event\n"
00286                                       << "No HLT information produced";
00287       goodHlt = false;
00288     }
00289   }
00290 
00291   // Produce HLT paths and determine status of modules
00292 
00293   if ( goodHlt ) {
00294 
00295     // Extract pre-scales
00296     // Start from lumi
00297     trigger::HLTPrescaleTable hltPrescaleTable( hltPrescaleTableLumi_.set(), hltPrescaleTableLumi_.labels(), hltPrescaleTableLumi_.table() );
00298     // Try event product, if configured and available
00299     if ( ! labelHltPrescaleTable_.empty() ) {
00300       Handle< trigger::HLTPrescaleTable > handleHltPrescaleTable;
00301       iEvent.getByLabel( InputTag( labelHltPrescaleTable_, "Event", nameProcess_ ), handleHltPrescaleTable );
00302       if ( handleHltPrescaleTable.isValid() ) {
00303         hltPrescaleTable = trigger::HLTPrescaleTable( handleHltPrescaleTable->set(), handleHltPrescaleTable->labels(), handleHltPrescaleTable->table() );
00304       }
00305     }
00306     // Try event setup, if no product
00307     if ( hltPrescaleTable.size() == 0 ) {
00308       if ( ! labelHltPrescaleTable_.empty() ) {
00309         LogWarning( "hltPrescaleInputTag" ) << "HLTPrescaleTable product with label '" << labelHltPrescaleTable_ << "' not found in process" << nameProcess_ << "\n"
00310                                             << "Using default from event setup";
00311       }
00312       if ( hltConfig_.prescaleSize() > 0 ) {
00313         if ( hltConfig_.prescaleSet( iEvent, iSetup ) != -1 ) {
00314           hltPrescaleTable = trigger::HLTPrescaleTable( hltConfig_.prescaleSet( iEvent, iSetup ), hltConfig_.prescaleLabels(), hltConfig_.prescaleTable() );
00315           LogDebug( "hltPrescaleTable" ) << "HLT prescale table found in event setup";
00316         } else {
00317           LogWarning( "hltPrescaleSet" ) << "HLTPrescaleTable from event setup has error";
00318         }
00319       }
00320     }
00321     unsigned set( hltPrescaleTable.set() );
00322     if ( hltPrescaleTable.size() > 0 ) {
00323       if ( hltPrescaleLabel_.size() > 0 ) {
00324         bool foundPrescaleLabel( false );
00325         for ( unsigned iLabel = 0; iLabel <  hltPrescaleTable.labels().size(); ++iLabel ) {
00326           if ( hltPrescaleTable.labels().at( iLabel ) == hltPrescaleLabel_ ) {
00327             set                = iLabel;
00328             foundPrescaleLabel = true;
00329             break;
00330           }
00331         }
00332         if ( ! foundPrescaleLabel ) {
00333           LogWarning( "hltPrescaleLabel" ) << "HLT prescale label '" << hltPrescaleLabel_ << "' not in prescale table\n"
00334                                            << "Using default";
00335         }
00336       }
00337     } else if ( iEvent.isRealData() ) {
00338       LogWarning( "hltPrescaleTable" ) << "No HLT prescale table found\n"
00339                                        << "Using default empty table with all prescales 1";
00340     }
00341 
00342     const unsigned sizePaths( hltConfig_.size() );
00343     const unsigned sizeFilters( handleTriggerEvent->sizeFilters() );
00344     const unsigned sizeObjects( handleTriggerEvent->sizeObjects() );
00345 
00346     std::auto_ptr< TriggerPathCollection > triggerPaths( new TriggerPathCollection() );
00347     triggerPaths->reserve( onlyStandAlone_ ? 0 : sizePaths );
00348     std::map< std::string, int > moduleStates;
00349     std::multimap< std::string, std::pair< std::string, bool > > filterPaths;
00350 
00351     for ( size_t iP = 0; iP < sizePaths; ++iP ) {
00352       const std::string namePath( hltConfig_.triggerName( iP ) );
00353       const unsigned indexPath( hltConfig_.triggerIndex( namePath ) );
00354       const unsigned sizeModulesPath( hltConfig_.size( namePath ) );
00355       const unsigned indexLastFilterPath( handleTriggerResults->index( indexPath ) );
00356       unsigned indexLastFilterPathModules( indexLastFilterPath + 1 );
00357       unsigned indexLastFilterFilters( sizeFilters );
00358       while ( indexLastFilterPathModules > 0 ) {
00359         --indexLastFilterPathModules;
00360         const std::string labelLastFilterModules( hltConfig_.moduleLabel( indexPath, indexLastFilterPathModules ) );
00361         indexLastFilterFilters = handleTriggerEvent->filterIndex( InputTag( labelLastFilterModules, "", nameProcess_ ) );
00362         if ( indexLastFilterFilters < sizeFilters ) break;
00363       }
00364       for ( size_t iM = 0; iM < sizeModulesPath; ++iM ) {
00365         const std::string nameFilter( hltConfig_.moduleLabel( indexPath, iM ) );
00366         const unsigned indexFilter( handleTriggerEvent->filterIndex( InputTag( nameFilter, "", nameProcess_ ) ) );
00367         if ( indexFilter < sizeFilters ) {
00368           std::pair< std::string, bool > pathAndStatus( namePath, handleTriggerResults->wasrun( indexPath ) && handleTriggerResults->accept( indexPath ) && indexFilter == indexLastFilterFilters );
00369           filterPaths.insert( std::pair< std::string, std::pair< std::string, bool > >( nameFilter, pathAndStatus ) );
00370         }
00371       }
00372       if ( ! onlyStandAlone_ ) {
00373         TriggerPath triggerPath( namePath, indexPath, hltConfig_.prescaleValue( set, namePath ), handleTriggerResults->wasrun( indexPath ), handleTriggerResults->accept( indexPath ), handleTriggerResults->error( indexPath ), indexLastFilterPath );
00374         // add module names to path and states' map
00375         assert( indexLastFilterPath < sizeModulesPath );
00376         std::map< unsigned, std::string > indicesModules;
00377         for ( size_t iM = 0; iM < sizeModulesPath; ++iM ) {
00378           const std::string nameModule( hltConfig_.moduleLabel( indexPath, iM ) );
00379           if ( addPathModuleLabels_ ) {
00380             triggerPath.addModule( nameModule );
00381           }
00382           const unsigned indexFilter( handleTriggerEvent->filterIndex( InputTag( nameModule, "", nameProcess_ ) ) );
00383           if ( indexFilter < sizeFilters ) {
00384             triggerPath.addFilterIndex( indexFilter );
00385           }
00386           const unsigned slotModule( hltConfig_.moduleIndex( indexPath, nameModule ) );
00387           indicesModules.insert( std::pair< unsigned, std::string >( slotModule, nameModule ) );
00388         }
00389         // add L1 seeds
00390         const L1SeedCollection l1Seeds( hltConfig_.hltL1GTSeeds( namePath ) );
00391         for ( L1SeedCollection::const_iterator iSeed = l1Seeds.begin(); iSeed != l1Seeds.end(); ++iSeed ) {
00392           triggerPath.addL1Seed( *iSeed );
00393         }
00394         // store path
00395         triggerPaths->push_back( triggerPath );
00396         // cache module states to be used for the filters
00397         for ( std::map< unsigned, std::string >::const_iterator iM = indicesModules.begin(); iM != indicesModules.end(); ++iM ) {
00398           if ( iM->first < indexLastFilterPath ) {
00399             moduleStates[ iM->second ] = 1;
00400           } else if ( iM->first == indexLastFilterPath ) {
00401             moduleStates[ iM->second ] = handleTriggerResults->accept( indexPath );
00402           } else if ( moduleStates.find( iM->second ) == moduleStates.end() ) {
00403             moduleStates[ iM->second ] = -1;
00404           }
00405         }
00406       }
00407     }
00408 
00409     // Put HLT paths to event
00410     if ( ! onlyStandAlone_ ) iEvent.put( triggerPaths );
00411 
00412     // Store used trigger objects and their types for HLT filters
00413     // (only last active filter(s) available from trigger::TriggerEvent)
00414 
00415     std::auto_ptr< TriggerFilterCollection > triggerFilters( new TriggerFilterCollection() );
00416     triggerFilters->reserve( onlyStandAlone_ ? 0 : sizeFilters );
00417     std::multimap< trigger::size_type, int >         objectTypes;
00418     std::multimap< trigger::size_type, std::string > filterLabels;
00419 
00420     for ( size_t iF = 0; iF < sizeFilters; ++iF ) {
00421       const std::string nameFilter( handleTriggerEvent->filterTag( iF ).label() );
00422       const trigger::Keys & keys  = handleTriggerEvent->filterKeys( iF );
00423       const trigger::Vids & types = handleTriggerEvent->filterIds( iF );
00424       assert( types.size() == keys.size() );
00425       for ( size_t iK = 0; iK < keys.size(); ++iK ) {
00426         filterLabels.insert( std::pair< trigger::size_type, std::string >( keys[ iK ], nameFilter ) ); // only for objects used in last active filter
00427         objectTypes.insert( std::pair< trigger::size_type, int >( keys[ iK ], types[ iK ] ) );             // only for objects used in last active filter
00428       }
00429     }
00430 
00431     // HLT objects
00432 
00433     const trigger::Keys & collectionKeys( handleTriggerEvent->collectionKeys() );
00434     std::map< trigger::size_type, trigger::size_type > newObjectKeys;
00435     for ( size_t iO = 0, iC = 0; iO < sizeObjects && iC < handleTriggerEvent->sizeCollections(); ++iO ) {
00436 
00437       TriggerObject triggerObject( handleTriggerEvent->getObjects().at( iO ) );
00438       // set collection
00439       while ( iO >= collectionKeys[ iC ] ) ++iC; // relies on well ordering of trigger objects with respect to the collections
00440       triggerObject.setCollection( handleTriggerEvent->collectionTag( iC ) );
00441       // set filter ID
00442       for ( std::multimap< trigger::size_type, int >::iterator iM = objectTypes.begin(); iM != objectTypes.end(); ++iM ) {
00443         if ( iM->first == iO ) {
00444           triggerObject.addTriggerObjectType( iM->second );
00445         }
00446       }
00447 
00448       // stand-alone trigger object
00449       TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00450       // check for excluded collections
00451       bool excluded( false );
00452       for ( size_t iE = 0; iE < exludeCollections_.size(); ++iE ) {
00453         if ( triggerObjectStandAlone.hasCollection( exludeCollections_.at( iE ) ) ) {
00454           newObjectKeys[ iO ] = trigger::size_type( sizeObjects );
00455           excluded = true;
00456           break;
00457         }
00458       }
00459       if ( excluded ) continue;
00460       for ( std::multimap< trigger::size_type, std::string >::iterator iM = filterLabels.begin(); iM != filterLabels.end(); ++iM ) {
00461         if ( iM->first == iO ) {
00462           triggerObjectStandAlone.addFilterLabel( iM->second );
00463           for ( std::multimap< std::string, std::pair< std::string, bool > >::iterator iP = filterPaths.begin(); iP != filterPaths.end(); ++iP ) {
00464             if ( iP->first == iM->second ) {
00465               triggerObjectStandAlone.addPathName( iP->second.first, iP->second.second );
00466             }
00467           }
00468         }
00469       }
00470 
00471       if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00472       triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00473       newObjectKeys[ iO ] = trigger::size_type( triggerObjectsStandAlone->size() - 1 );
00474     }
00475 
00476     // Re-iterate HLT filters and finally produce them
00477     // in ordert to account for optionally skipped objects
00478 
00479     if ( ! onlyStandAlone_ ) {
00480       for ( size_t iF = 0; iF < sizeFilters; ++iF ) {
00481         const std::string nameFilter( handleTriggerEvent->filterTag( iF ).label() );
00482         const trigger::Keys & keys  = handleTriggerEvent->filterKeys( iF ); // not cached
00483         const trigger::Vids & types = handleTriggerEvent->filterIds( iF );  // not cached
00484         TriggerFilter triggerFilter( nameFilter );
00485         // set filter type
00486         const std::string typeFilter( hltConfig_.moduleType( nameFilter ) );
00487         triggerFilter.setType( typeFilter );
00488         // set keys and trigger object types of used objects
00489         for ( size_t iK = 0; iK < keys.size(); ++iK ) { // identical to types.size()
00490           // check, if current object is excluded
00491           if ( newObjectKeys.find( keys.at( iK ) ) != newObjectKeys.end() ) {
00492             if ( newObjectKeys[ keys.at( iK ) ] == sizeObjects ) continue;
00493             triggerFilter.addObjectKey( keys.at( iK ) );
00494             triggerFilter.addTriggerObjectType( types.at( iK ) );
00495           } else {
00496             LogWarning( "triggerObjectKey" ) << "TriggerFilter '" << nameFilter << "' requests non-existing TriggerObject key " << keys.at( iK ) << "\n"
00497                                              << "Skipping object assignment";
00498           }
00499         }
00500         // set status from path info
00501         std::map< std::string, int >::iterator iS( moduleStates.find( nameFilter ) );
00502         if ( iS != moduleStates.end() ) {
00503           if ( ! triggerFilter.setStatus( iS->second ) ) {
00504             triggerFilter.setStatus( -1 ); // FIXME different code for "unvalid status determined" needed?
00505           }
00506         } else {
00507           triggerFilter.setStatus( -1 ); // FIXME different code for "unknown" needed?
00508         }
00509         // store filter
00510         triggerFilters->push_back( triggerFilter );
00511       }
00512       // put HLT filters to event
00513       iEvent.put( triggerFilters );
00514     }
00515 
00516   } // if ( goodHlt )
00517 
00518   // L1 objects
00519   // (needs to be done after HLT objects, since their x-links with filters rely on their collection keys)
00520 
00521   // map for assignments of objects to conditions
00522   std::map< L1GtObject, std::vector< unsigned > > l1ObjectTypeMap;
00523 
00524   if ( ! tagL1ExtraMu_.label().empty() ) {
00525     Handle< l1extra::L1MuonParticleCollection > handleL1ExtraMu;
00526     iEvent.getByLabel( tagL1ExtraMu_, handleL1ExtraMu );
00527     if ( handleL1ExtraMu.isValid() ) {
00528       std::vector< unsigned > muKeys;
00529       for ( size_t l1Mu = 0; l1Mu < handleL1ExtraMu->size(); ++l1Mu ) {
00530         if ( mainBxOnly_ && handleL1ExtraMu->at( l1Mu ).bx() != 0 ) continue;
00531         TriggerObject triggerObject;
00532         if ( saveL1Refs_ ) {
00533           const reco::CandidateBaseRef leafCandRef( l1extra::L1MuonParticleRef( handleL1ExtraMu, l1Mu ) );
00534           triggerObject = TriggerObject( leafCandRef );
00535         } else {
00536           const reco::LeafCandidate * leafCandidate( handleL1ExtraMu->at( l1Mu ).reco::LeafCandidate::clone() );
00537           triggerObject = TriggerObject( *leafCandidate );
00538         }
00539         triggerObject.setCollection( tagL1ExtraMu_ );
00540         triggerObject.addTriggerObjectType( trigger::TriggerL1Mu );
00541         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00542         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00543         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00544         if ( handleL1ExtraMu->at( l1Mu ).bx() == 0 ) muKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00545       }
00546       l1ObjectTypeMap.insert( std::make_pair( Mu, muKeys ) );
00547     } else LogError( "l1ExtraValid" ) << "l1extra::L1MuonParticleCollection product with InputTag '" << tagL1ExtraMu_.encode() << "' not in event";
00548   }
00549   if ( ! tagL1ExtraNoIsoEG_.label().empty() ) {
00550     Handle< l1extra::L1EmParticleCollection > handleL1ExtraNoIsoEG;
00551     iEvent.getByLabel( tagL1ExtraNoIsoEG_, handleL1ExtraNoIsoEG );
00552     if ( handleL1ExtraNoIsoEG.isValid() ) {
00553       std::vector< unsigned > noIsoEGKeys;
00554       for ( size_t l1NoIsoEG = 0; l1NoIsoEG < handleL1ExtraNoIsoEG->size(); ++l1NoIsoEG ) {
00555         if ( mainBxOnly_ && handleL1ExtraNoIsoEG->at( l1NoIsoEG ).bx() != 0 ) continue;
00556         TriggerObject triggerObject;
00557         if ( saveL1Refs_ ) {
00558           const reco::CandidateBaseRef leafCandRef( l1extra::L1EmParticleRef( handleL1ExtraNoIsoEG, l1NoIsoEG ) );
00559           triggerObject = TriggerObject( leafCandRef );
00560         } else {
00561           const reco::LeafCandidate * leafCandidate( handleL1ExtraNoIsoEG->at( l1NoIsoEG ).reco::LeafCandidate::clone() );
00562           triggerObject = TriggerObject( *leafCandidate );
00563         }
00564         triggerObject.setCollection( tagL1ExtraNoIsoEG_ );
00565         triggerObject.addTriggerObjectType( trigger::TriggerL1NoIsoEG );
00566         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00567         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00568         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00569         if ( handleL1ExtraNoIsoEG->at( l1NoIsoEG ).bx() == 0 ) noIsoEGKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00570       }
00571       l1ObjectTypeMap.insert( std::make_pair( NoIsoEG, noIsoEGKeys ) );
00572     } else LogError( "l1ExtraValid" ) << "l1extra::L1EmParticleCollection product with InputTag '" << tagL1ExtraNoIsoEG_.encode() << "' not in event";
00573   }
00574   if ( ! tagL1ExtraIsoEG_.label().empty() ) {
00575     Handle< l1extra::L1EmParticleCollection > handleL1ExtraIsoEG;
00576     iEvent.getByLabel( tagL1ExtraIsoEG_, handleL1ExtraIsoEG );
00577     if ( handleL1ExtraIsoEG.isValid() ) {
00578       std::vector< unsigned > isoEGKeys;
00579       for ( size_t l1IsoEG = 0; l1IsoEG < handleL1ExtraIsoEG->size(); ++l1IsoEG ) {
00580         if ( mainBxOnly_ && handleL1ExtraIsoEG->at( l1IsoEG ).bx() != 0 ) continue;
00581         TriggerObject triggerObject;
00582         if ( saveL1Refs_ ) {
00583           const reco::CandidateBaseRef leafCandRef( l1extra::L1EmParticleRef( handleL1ExtraIsoEG, l1IsoEG ) );
00584           triggerObject = TriggerObject( leafCandRef );
00585         } else {
00586           const reco::LeafCandidate * leafCandidate( handleL1ExtraIsoEG->at( l1IsoEG ).reco::LeafCandidate::clone() );
00587           triggerObject = TriggerObject( *leafCandidate );
00588         }
00589         triggerObject.setCollection( tagL1ExtraIsoEG_ );
00590         triggerObject.addTriggerObjectType( trigger::TriggerL1IsoEG );
00591         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00592         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00593         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00594         if ( handleL1ExtraIsoEG->at( l1IsoEG ).bx() == 0 ) isoEGKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00595       }
00596       l1ObjectTypeMap.insert( std::make_pair( IsoEG, isoEGKeys ) );
00597     } else LogError( "l1ExtraValid" ) << "l1extra::L1EmParticleCollection product with InputTag '" << tagL1ExtraIsoEG_.encode() << "' not in event";
00598   }
00599   if ( ! tagL1ExtraCenJet_.label().empty() ) {
00600     Handle< l1extra::L1JetParticleCollection > handleL1ExtraCenJet;
00601     iEvent.getByLabel( tagL1ExtraCenJet_, handleL1ExtraCenJet );
00602     if ( handleL1ExtraCenJet.isValid() ) {
00603       std::vector< unsigned > cenJetKeys;
00604       for ( size_t l1CenJet = 0; l1CenJet < handleL1ExtraCenJet->size(); ++l1CenJet ) {
00605         if ( mainBxOnly_ && handleL1ExtraCenJet->at( l1CenJet ).bx() != 0 ) continue;
00606         TriggerObject triggerObject;
00607         if ( saveL1Refs_ ) {
00608           const reco::CandidateBaseRef leafCandRef( l1extra::L1JetParticleRef( handleL1ExtraCenJet, l1CenJet ) );
00609           triggerObject = TriggerObject( leafCandRef );
00610         } else {
00611           const reco::LeafCandidate * leafCandidate( handleL1ExtraCenJet->at( l1CenJet ).reco::LeafCandidate::clone() );
00612           triggerObject = TriggerObject( *leafCandidate );
00613         }
00614         triggerObject.setCollection( tagL1ExtraCenJet_ );
00615         triggerObject.addTriggerObjectType( trigger::TriggerL1CenJet );
00616         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00617         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00618         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00619         if ( handleL1ExtraCenJet->at( l1CenJet ).bx() == 0 ) cenJetKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00620       }
00621       l1ObjectTypeMap.insert( std::make_pair( CenJet, cenJetKeys ) );
00622     } else LogError( "l1ExtraValid" ) << "l1extra::L1JetParticleCollection product with InputTag '" << tagL1ExtraCenJet_.encode() << "' not in event";
00623   }
00624   if ( ! tagL1ExtraForJet_.label().empty() ) {
00625     Handle< l1extra::L1JetParticleCollection > handleL1ExtraForJet;
00626     iEvent.getByLabel( tagL1ExtraForJet_, handleL1ExtraForJet );
00627     if ( handleL1ExtraForJet.isValid() ) {
00628       std::vector< unsigned > forJetKeys;
00629       for ( size_t l1ForJet = 0; l1ForJet < handleL1ExtraForJet->size(); ++l1ForJet ) {
00630         if ( mainBxOnly_ && handleL1ExtraForJet->at( l1ForJet ).bx() != 0 ) continue;
00631         TriggerObject triggerObject;
00632         if ( saveL1Refs_ ) {
00633           const reco::CandidateBaseRef leafCandRef( l1extra::L1JetParticleRef( handleL1ExtraForJet, l1ForJet ) );
00634           triggerObject = TriggerObject( leafCandRef );
00635         } else {
00636           const reco::LeafCandidate * leafCandidate( handleL1ExtraForJet->at( l1ForJet ).reco::LeafCandidate::clone() );
00637           triggerObject = TriggerObject( *leafCandidate );
00638         }
00639         triggerObject.setCollection( tagL1ExtraForJet_ );
00640         triggerObject.addTriggerObjectType( trigger::TriggerL1ForJet );
00641         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00642         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00643         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00644         if ( handleL1ExtraForJet->at( l1ForJet ).bx() == 0 ) forJetKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00645       }
00646       l1ObjectTypeMap.insert( std::make_pair( ForJet, forJetKeys ) );
00647     } else LogError( "l1ExtraValid" ) << "l1extra::L1JetParticleCollection product with InputTag '" << tagL1ExtraForJet_.encode() << "' not in event";
00648   }
00649   if ( ! tagL1ExtraTauJet_.label().empty() ) {
00650     Handle< l1extra::L1JetParticleCollection > handleL1ExtraTauJet;
00651     iEvent.getByLabel( tagL1ExtraTauJet_, handleL1ExtraTauJet );
00652     if ( handleL1ExtraTauJet.isValid() ) {
00653       std::vector< unsigned > tauJetKeys;
00654       for ( size_t l1TauJet = 0; l1TauJet < handleL1ExtraTauJet->size(); ++l1TauJet ) {
00655         if ( mainBxOnly_ && handleL1ExtraTauJet->at( l1TauJet ).bx() != 0 ) continue;
00656         TriggerObject triggerObject;
00657         if ( saveL1Refs_ ) {
00658           const reco::CandidateBaseRef leafCandRef( l1extra::L1JetParticleRef( handleL1ExtraTauJet, l1TauJet ) );
00659           triggerObject = TriggerObject( leafCandRef );
00660         } else {
00661           const reco::LeafCandidate * leafCandidate( handleL1ExtraTauJet->at( l1TauJet ).reco::LeafCandidate::clone() );
00662           triggerObject = TriggerObject( *leafCandidate );
00663         }
00664         triggerObject.setCollection( tagL1ExtraTauJet_ );
00665         triggerObject.addTriggerObjectType( trigger::TriggerL1TauJet );
00666         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00667         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00668         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00669         if ( handleL1ExtraTauJet->at( l1TauJet ).bx() == 0 ) tauJetKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00670       }
00671       l1ObjectTypeMap.insert( std::make_pair( TauJet, tauJetKeys ) );
00672     } else LogError( "l1ExtraValid" ) << "l1extra::L1JetParticleCollection product with InputTag '" << tagL1ExtraTauJet_.encode() << "' not in event";
00673   }
00674   if ( ! tagL1ExtraETM_ .label().empty()) {
00675     Handle< l1extra::L1EtMissParticleCollection > handleL1ExtraETM;
00676     iEvent.getByLabel( tagL1ExtraETM_, handleL1ExtraETM );
00677     if ( handleL1ExtraETM.isValid() ) {
00678       std::vector< unsigned > etmKeys;
00679       for ( size_t l1ETM = 0; l1ETM < handleL1ExtraETM->size(); ++l1ETM ) {
00680         if ( mainBxOnly_ && handleL1ExtraETM->at( l1ETM ).bx() != 0 ) continue;
00681         TriggerObject triggerObject;
00682         if ( saveL1Refs_ ) {
00683           const reco::CandidateBaseRef leafCandRef( l1extra::L1EtMissParticleRef( handleL1ExtraETM, l1ETM ) );
00684           triggerObject = TriggerObject( leafCandRef );
00685         } else {
00686           const reco::LeafCandidate * leafCandidate( handleL1ExtraETM->at( l1ETM ).reco::LeafCandidate::clone() );
00687           triggerObject = TriggerObject( *leafCandidate );
00688         }
00689         triggerObject.setCollection( tagL1ExtraETM_ );
00690         triggerObject.addTriggerObjectType( trigger::TriggerL1ETM );
00691         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00692         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00693         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00694         if ( handleL1ExtraETM->at( l1ETM ).bx() == 0 ) etmKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00695       }
00696       l1ObjectTypeMap.insert( std::make_pair( ETM, etmKeys ) );
00697     } else LogError( "l1ExtraValid" ) << "l1extra::L1EtMissParticleCollection product with InputTag '" << tagL1ExtraETM_.encode() << "' not in event";
00698   }
00699   if ( ! tagL1ExtraHTM_.label().empty() ) {
00700     Handle< l1extra::L1EtMissParticleCollection > handleL1ExtraHTM;
00701     iEvent.getByLabel( tagL1ExtraHTM_, handleL1ExtraHTM );
00702     if ( handleL1ExtraHTM.isValid() ) {
00703       std::vector< unsigned > htmKeys;
00704       for ( size_t l1HTM = 0; l1HTM < handleL1ExtraHTM->size(); ++l1HTM ) {
00705         if ( mainBxOnly_ && handleL1ExtraHTM->at( l1HTM ).bx() != 0 ) continue;
00706         TriggerObject triggerObject;
00707         if ( saveL1Refs_ ) {
00708           const reco::CandidateBaseRef leafCandRef( l1extra::L1EtMissParticleRef( handleL1ExtraHTM, l1HTM ) );
00709           triggerObject = TriggerObject( leafCandRef );
00710         } else {
00711           const reco::LeafCandidate * leafCandidate( handleL1ExtraHTM->at( l1HTM ).reco::LeafCandidate::clone() );
00712           triggerObject = TriggerObject( *leafCandidate );
00713         }
00714         triggerObject.setCollection( tagL1ExtraHTM_ );
00715         triggerObject.addTriggerObjectType( trigger::TriggerL1HTM );
00716         if ( ! onlyStandAlone_ ) triggerObjects->push_back( triggerObject );
00717         TriggerObjectStandAlone triggerObjectStandAlone( triggerObject );
00718         triggerObjectsStandAlone->push_back( triggerObjectStandAlone );
00719         if ( handleL1ExtraHTM->at( l1HTM ).bx() == 0 ) htmKeys.push_back( triggerObjectsStandAlone->size() - 1 );
00720       }
00721       l1ObjectTypeMap.insert( std::make_pair( HTM, htmKeys ) );
00722     } else LogError( "l1ExtraValid" ) << "l1extra::L1EtMissParticleCollection product with InputTag '" << tagL1ExtraHTM_.encode() << "' not in event";
00723   }
00724 
00725   // Put trigger objects to event
00726   if ( ! onlyStandAlone_ ) iEvent.put( triggerObjects );
00727 
00728   // L1 algorithms
00729   if ( ! onlyStandAlone_ ) {
00730     std::auto_ptr< TriggerAlgorithmCollection > triggerAlgos( new TriggerAlgorithmCollection() );
00731     std::auto_ptr< TriggerConditionCollection > triggerConditions( new TriggerConditionCollection() );
00732     if ( addL1Algos_ ) {
00733       // create trigger object types transalation map (yes, it's ugly!)
00734       std::map< L1GtObject, trigger::TriggerObjectType > mapObjectTypes;
00735       mapObjectTypes.insert( std::make_pair( Mu     , trigger::TriggerL1Mu ) );
00736       mapObjectTypes.insert( std::make_pair( NoIsoEG, trigger::TriggerL1NoIsoEG ) );
00737       mapObjectTypes.insert( std::make_pair( IsoEG  , trigger::TriggerL1IsoEG ) );
00738       mapObjectTypes.insert( std::make_pair( CenJet , trigger::TriggerL1CenJet ) );
00739       mapObjectTypes.insert( std::make_pair( ForJet , trigger::TriggerL1ForJet ) );
00740       mapObjectTypes.insert( std::make_pair( TauJet , trigger::TriggerL1TauJet ) );
00741       mapObjectTypes.insert( std::make_pair( ETM    , trigger::TriggerL1ETM ) );
00742       mapObjectTypes.insert( std::make_pair( HTM    , trigger::TriggerL1HTM ) );
00743       // get and cache L1 menu
00744       l1GtUtils_.retrieveL1EventSetup( iSetup );
00745       ESHandle< L1GtTriggerMenu > handleL1GtTriggerMenu;
00746       iSetup.get< L1GtTriggerMenuRcd >().get( handleL1GtTriggerMenu );
00747       L1GtTriggerMenu l1GtTriggerMenu( *handleL1GtTriggerMenu );
00748       const AlgorithmMap l1GtAlgorithms( l1GtTriggerMenu.gtAlgorithmMap() );
00749       const AlgorithmMap l1GtTechTriggers( l1GtTriggerMenu.gtTechnicalTriggerMap() );
00750       l1GtTriggerMenu.buildGtConditionMap();
00751       const std::vector< ConditionMap > l1GtConditionsVector( l1GtTriggerMenu.gtConditionMap() );
00752       // cache conditions in one single condition map
00753       ConditionMap l1GtConditions;
00754       for ( size_t iCv = 0; iCv < l1GtConditionsVector.size(); ++iCv ) {
00755         l1GtConditions.insert( l1GtConditionsVector.at( iCv ).begin(), l1GtConditionsVector.at( iCv ).end() );
00756       }
00757       triggerAlgos->reserve( l1GtAlgorithms.size() + l1GtTechTriggers.size() );
00758       Handle< L1GlobalTriggerObjectMapRecord > handleL1GlobalTriggerObjectMapRecord;
00759       iEvent.getByLabel( tagL1GlobalTriggerObjectMapRecord_, handleL1GlobalTriggerObjectMapRecord );
00760       if( ! handleL1GlobalTriggerObjectMapRecord.isValid() ) {
00761         LogWarning( "l1ObjectMap" ) << "L1GlobalTriggerObjectMapRecord product with InputTag '" << tagL1GlobalTriggerObjectMapRecord_.encode() << "' not in event\n"
00762                                     << "No L1 objects and GTL results available for physics algorithms";
00763       }
00764       // physics algorithms
00765       for ( CItAlgo iAlgo = l1GtAlgorithms.begin(); iAlgo != l1GtAlgorithms.end(); ++iAlgo ) {
00766         const std::string & algoName( iAlgo->second.algoName() );
00767         if ( ! ( iAlgo->second.algoBitNumber() < int( L1GlobalTriggerReadoutSetup::NumberPhysTriggers ) ) ) {
00768           LogError( "l1Algo" ) << "L1 physics algorithm '" << algoName << "' has bit number " << iAlgo->second.algoBitNumber() << " >= " << L1GlobalTriggerReadoutSetup::NumberPhysTriggers << "\n"
00769                                << "Skipping";
00770           continue;
00771         }
00772         L1GtUtils::TriggerCategory category;
00773         int bit;
00774         if ( ! l1GtUtils_.l1AlgoTechTrigBitNumber( algoName, category, bit ) ) {
00775           LogError( "l1Algo" ) << "L1 physics algorithm '" << algoName << "' not found in the L1 menu\n"
00776                                << "Skipping";
00777           continue;
00778         }
00779         if ( category != L1GtUtils::AlgorithmTrigger ) {
00780           LogError( "l1Algo" ) << "L1 physics algorithm '" << algoName << "' does not have category 'AlgorithmTrigger' from 'L1GtUtils'\n"
00781                                << "Skipping";
00782           continue;
00783         }
00784         bool decisionBeforeMask;
00785         bool decisionAfterMask;
00786         int  prescale;
00787         int  mask;
00788         int  error( l1GtUtils_.l1Results( iEvent, algoName, decisionBeforeMask, decisionAfterMask, prescale, mask ) );
00789         if ( error ) {
00790           LogError( "l1Algo" ) << "L1 physics algorithm '" << algoName << "' decision has error code " << error << " from 'L1GtUtils'\n"
00791                                << "Skipping";
00792           continue;
00793         }
00794         TriggerAlgorithm triggerAlgo( algoName, iAlgo->second.algoAlias(), category == L1GtUtils::TechnicalTrigger, (unsigned)bit, (unsigned)prescale, (bool)mask, decisionBeforeMask, decisionAfterMask );
00795         triggerAlgo.setLogicalExpression( iAlgo->second.algoLogicalExpression() );
00796         // GTL result and used conditions in physics algorithm
00797         if( ! handleL1GlobalTriggerObjectMapRecord.isValid() ) {
00798           triggerAlgos->push_back( triggerAlgo );
00799           continue; // LogWarning already earlier (before loop)
00800         }
00801         const L1GlobalTriggerObjectMap * l1ObjectMap( handleL1GlobalTriggerObjectMapRecord->getObjectMap( algoName ) );
00802         if ( ! l1ObjectMap ) {
00803           LogError( "l1ObjectMap" ) << "L1 physics algorithm '" << algoName << "' is missing in L1GlobalTriggerObjectMapRecord\n"
00804                                     << "Skipping conditions and GTL result";
00805           triggerAlgos->push_back( triggerAlgo );
00806           continue;
00807         }
00808 //         if ( ( l1ObjectMap->algoGtlResult() != decisionBeforeMask ) && ( decisionBeforeMask == true || prescale == 1 ) ) {
00809         if ( ( l1ObjectMap->algoGtlResult() != decisionBeforeMask ) && ( decisionBeforeMask == true ) ) { // FIXME: understand the difference for un-prescaled algos 118, 119, 123
00810           LogInfo( "l1ObjectMap" ) << "L1 physics algorithm '" << algoName << "' with different decisions in\n"
00811                                    << "L1GlobalTriggerObjectMapRecord (GTL result)        : " << l1ObjectMap->algoGtlResult() << "\n"
00812                                    << "L1GlobalTriggerReadoutRecord (decision before mask): " << decisionBeforeMask;
00813         }
00814         triggerAlgo.setGtlResult( l1ObjectMap->algoGtlResult() );
00815         // conditions in algorithm
00816         const std::vector< L1GtLogicParser::OperandToken > & tokens( l1ObjectMap->operandTokenVector() );
00817         for ( size_t iT = 0; iT < tokens.size(); ++iT ) {
00818           const L1GtLogicParser::OperandToken & token( tokens.at( iT ) );
00819           size_t key( triggerConditions->size() );
00820           for ( size_t iC = 0; iC < triggerConditions->size(); ++iC ) {
00821             if ( token.tokenName == triggerConditions->at( iC ).name() ) {
00822               key = iC;
00823               break;
00824             }
00825           }
00826           if ( key == triggerConditions->size() ) {
00827             TriggerCondition triggerCond( token.tokenName, token.tokenResult );
00828             if ( l1GtConditions.find( triggerCond.name() ) != l1GtConditions.end() ) {
00829               triggerCond.setCategory( l1GtConditions[ triggerCond.name() ]->condCategory() );
00830               triggerCond.setType( l1GtConditions[ triggerCond.name() ]->condType() );
00831               const std::vector< L1GtObject > l1ObjectTypes( l1GtConditions[ triggerCond.name() ]->objectType() );
00832               for ( size_t iT = 0 ; iT < l1ObjectTypes.size(); ++iT ) {
00833                 triggerCond.addTriggerObjectType( mapObjectTypes[ l1ObjectTypes.at( iT ) ] );
00834               }
00835               // objects in condition
00836               CombinationsInCond combis( l1ObjectMap->combinationVector().at( token.tokenNumber ) );
00837               for ( size_t iVV = 0; iVV < combis.size(); ++iVV ) {
00838                 SingleCombInCond combi( combis.at( iVV ) );
00839                 for ( size_t iV = 0; iV < combi.size(); ++iV ) {
00840                   if ( iV >= l1ObjectTypes.size() ) {
00841                     LogError( "l1CondMap" ) << "Index " << iV << " in combinations vector overshoots size " << l1ObjectTypes.size() << " of types vector in conditions map\n"
00842                                             << "Skipping object key in condition " << triggerCond.name();
00843                   } else if ( l1ObjectTypeMap.find( l1ObjectTypes.at( iV ) ) != l1ObjectTypeMap.end() ) {
00844                     if ( combi.at( iV ) >= int( l1ObjectTypeMap[ l1ObjectTypes.at( iV ) ].size() ) ) {
00845                       LogError( "l1CondMap" ) << "Index " << combi.at( iV ) << " in combination overshoots number " << l1ObjectTypeMap[ l1ObjectTypes.at( iV ) ].size() << "of according trigger objects\n"
00846                                               << "Skipping object key in condition " << triggerCond.name();
00847                     }
00848                     const unsigned objectKey( l1ObjectTypeMap[ l1ObjectTypes.at( iV ) ].at( combi.at( iV ) ) );
00849                     triggerCond.addObjectKey( objectKey );
00850                     // add current condition and algorithm also to the according stand-alone trigger object
00851                     triggerObjectsStandAlone->at( objectKey ).addAlgorithmName( triggerAlgo.name(), ( triggerAlgo.decision() && triggerCond.wasAccept() ) );
00852                     triggerObjectsStandAlone->at( objectKey ).addConditionName( triggerCond.name() );
00853                   }
00854                 }
00855               }
00856             } else {
00857               LogWarning( "l1CondMap" ) << "L1 conditions '" << triggerCond.name() << "' not found in the L1 menu\n"
00858                                         << "Remains incomplete";
00859             }
00860             triggerConditions->push_back( triggerCond );
00861           }
00862           triggerAlgo.addConditionKey( key );
00863         }
00864         triggerAlgos->push_back( triggerAlgo );
00865       }
00866       // technical triggers
00867       for ( CItAlgo iAlgo = l1GtTechTriggers.begin(); iAlgo != l1GtTechTriggers.end(); ++iAlgo ) {
00868         const std::string & algoName( iAlgo->second.algoName() );
00869         if ( ! ( iAlgo->second.algoBitNumber() < int( L1GlobalTriggerReadoutSetup::NumberTechnicalTriggers ) ) ) {
00870           LogError( "l1Algo" ) << "L1 technical trigger '" << algoName << "' has bit number " << iAlgo->second.algoBitNumber() << " >= " << L1GlobalTriggerReadoutSetup::NumberTechnicalTriggers << "\n"
00871                                << "Skipping";
00872           continue;
00873         }
00874         L1GtUtils::TriggerCategory category;
00875         int bit;
00876         if ( ! l1GtUtils_.l1AlgoTechTrigBitNumber( algoName, category, bit ) ) {
00877           LogError( "l1Algo" ) << "L1 technical trigger '" << algoName << "' not found in the L1 menu\n"
00878                                << "Skipping";
00879           continue;
00880         }
00881         if ( category != L1GtUtils::TechnicalTrigger ) {
00882           LogError( "l1Algo" ) << "L1 technical trigger '" << algoName << "' does not have category 'TechnicalTrigger' from 'L1GtUtils'\n"
00883                                << "Skipping";
00884           continue;
00885         }
00886         bool decisionBeforeMask;
00887         bool decisionAfterMask;
00888         int  prescale;
00889         int  mask;
00890         int  error( l1GtUtils_.l1Results( iEvent, algoName, decisionBeforeMask, decisionAfterMask, prescale, mask ) );
00891         if ( error ) {
00892           LogError( "l1Algo" ) << "L1 technical trigger '" << algoName << "' decision has error code " << error << " from 'L1GtUtils'\n"
00893                                << "Skipping";
00894           continue;
00895         }
00896         TriggerAlgorithm triggerAlgo( algoName, iAlgo->second.algoAlias(), category == L1GtUtils::TechnicalTrigger, (unsigned)bit, (unsigned)prescale, (bool)mask, decisionBeforeMask, decisionAfterMask );
00897         triggerAlgo.setLogicalExpression( iAlgo->second.algoLogicalExpression() );
00898         triggerAlgos->push_back( triggerAlgo );
00899       }
00900     }
00901 
00902     // Put L1 algorithms and conditions to event
00903     iEvent.put( triggerAlgos );
00904     iEvent.put( triggerConditions );
00905   }
00906 
00907   // Put (finally) stand-alone trigger objects to event
00908   iEvent.put( triggerObjectsStandAlone );
00909 
00910 }
00911 
00912 
00913 #include "FWCore/Framework/interface/MakerMacros.h"
00914 DEFINE_FWK_MODULE( PATTriggerProducer );