CMS 3D CMS Logo

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

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