CMS 3D CMS Logo

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

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