diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/python/TrigL2CaloRingerHypoTool.py b/Trigger/TrigHypothesis/TrigMultiVarHypo/python/TrigL2CaloRingerHypoTool.py index cb61d14a28a0a2c6365d165341e5d14eeb454d9b..dea77fc55d375af333dec65241b4cbfe3c8c88e6 100644 --- a/Trigger/TrigHypothesis/TrigMultiVarHypo/python/TrigL2CaloRingerHypoTool.py +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/python/TrigL2CaloRingerHypoTool.py @@ -10,12 +10,13 @@ _possibleSel = { 'tight':'Tight', 'medium':'Medium', 'loose':'Loose', 'vloose': 'lhtight':'Tight', 'lhmedium':'Medium', 'lhloose':'Loose', 'lhvloose':'VeryLoose'} from AthenaCommon.SystemOfUnits import GeV +from TriggerJobOpts.TriggerFlags import TriggerFlags +#from AthenaMonitoring.GenericMonitoringTool import GenericMonitoringTool,defineHistogram +# Just because the TriggerFlags Online and doValidation doen't work +from AthenaCommon.AthenaCommonFlags import athenaCommonFlags - - - -def _GetPath( cand, sel, basepath = 'RingerSelectorTools/TrigL2_20170221_v6' ): +def _GetPath( cand, sel, basepath = 'RingerSelectorTools/TrigL2_20180903_v9' ): from AthenaCommon.Logging import logging logger = logging.getLogger("TrigMultiVarHypo.GetPath") @@ -36,24 +37,20 @@ def _GetPath( cand, sel, basepath = 'RingerSelectorTools/TrigL2_20170221_v6' ): return constant, threshold - - - - - - - - -def _HypoTool(name, cand, threshold, sel): +def _IncTool(name, cand, threshold, sel): from TrigMultiVarHypo.TrigMultiVarHypoConf import TrigL2CaloRingerHypoToolMT + tool = TrigL2CaloRingerHypoToolMT( name ) tool.AcceptAll = False tool.MonTool = "" tool.EtCut = (float(threshold)-3.)*GeV - + + # monitoring part from TriggerJobOpts.TriggerFlags import TriggerFlags - if 'Validation' in TriggerFlags.enableMonitoring() or 'Online' in TriggerFlags.enableMonitoring(): + if (('Validation' in TriggerFlags.enableMonitoring()) or + ('Online' in TriggerFlags.enableMonitoring()) or + (athenaCommonFlags.isOnline)): from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool,defineHistogram monTool = GenericMonitoringTool('MonTool'+name) @@ -64,15 +61,12 @@ def _HypoTool(name, cand, threshold, sel): defineHistogram('Eta', type='TH1F', path='EXPERT',title="#eta of Clusters; #eta; number of RoIs", xbins=50,xmin=-2.5,xmax=2.5), defineHistogram('Phi',type='TH1F', path='EXPERT',title="#phi of Clusters; #phi; number of RoIs", xbins=64,xmin=-3.2,xmax=3.2), defineHistogram('Et',type='TH1F', path='EXPERT',title="E_{T} of Clusters; E_{T} [MeV]; number of RoIs", xbins=60,xmin=0,xmax=5e4), - defineHistogram('RnnOut',type='TH1F', path='EXPERT',title="E_{T} of Clusters; E_{T} [MeV]; number of RoIs", xbins=100,xmin=-10,xmax=10), + defineHistogram('RnnOut',type='TH1F', path='EXPERT',title="Neural Network output; NN output; number of RoIs", xbins=100,xmin=-10,xmax=10), ] monTool.HistPath='L2CaloHypo_Ringer/'+monTool.name() tool.MonTool=monTool - - - if sel == 'nocut': tool.AcceptAll = True elif sel == "etcut": @@ -85,60 +79,50 @@ def _HypoTool(name, cand, threshold, sel): return tool -def _AlgTool(name): - from TrigMultiVarHypo.TrigMultiVarHypoConf import TrigL2CaloRingerHypoAlgMT - return TrigL2CaloRingerHypoAlgMT( name ) -def decodeThreshold( threshold ): - """ decodes the thresholds of the form e10, 2e10, e10e15, ... """ - print ("TrigL2CaloHypoToolFromName: decoding threshold ", threshold) - if threshold[0].isdigit(): # is if the from NeX, return as list [X,X,X...N times...] - assert threshold[1] == 'e', "Two digit multiplicity not supported" - return [ threshold[2:] ] * int( threshold[0] ) - if threshold.count('e') > 1: # is of the form eXeYeZ, return as [X, Y, Z] - return threshold.strip('e').split('e') - if threshold.count('g') > 1: # us of the form gXgYgZ, return as [X, Y, Z] - return threshold.strip('g').split('g') - # inclusive, return as 1 element list - return [ threshold[1:] ] , threshold[0] +# Just need to modify the in order to construct the hypo +def _MultTool(name): + from TrigMultiVarHypo.TrigMultiVarHypoConf import TrigL2CaloRingerHypoToolMTMult + return TrigL2CaloRingerHypoToolMTMult( name ) -def createRingerDecisions( name, chains, ClustersKey="CaloClusters",RingerKey="CaloRings" ): - # set the name of the HypoTool (name=chain) and figure out the threshold and selection from conf """ - from AthenaCommon.Constants import INFO - tool = _AlgTool(name) - from AthenaCommon.AppMgr import ToolSvc +def TrigL2CaloRingerHypoToolFromDict( d ): + """ Use menu decoded chain dictionary to configure the tool """ + cparts = [i for i in d['chainParts'] if ((i['signature']=='Electron') or (i['signature']=='Photon'))] + from LumiBlockComps.LuminosityCondAlgDefault import LuminosityCondAlgOnlineDefault LuminosityCondAlgOnlineDefault() - if not type(chains) is list: - chains=[chains] - - hypotools = [] - for c in chains: - #print ("Configuring ", name) - bname = c.split('_') - threshold = bname[1] - sel = bname[2] - dt, cand = decodeThreshold( threshold ) - hypotools.append(_HypoTool( c, cand, dt[0], sel )) + def __mult(cpart): + return int( cpart['multiplicity'] ) + + def __th(cpart): + return cpart['threshold'] - for t in tool.HypoTools: - t.OutputLevel=INFO + def __sel(cpart): + return cpart['addInfo'][0] if cpart['addInfo'] else cpart['IDinfo'] - tool.HypoTools = hypotools - tool.ClustersKey = ClustersKey - tool.RingerKey = RingerKey - return tool - - + def __cand(cpart): + return cpart['trigType'] + name = d['chainName'] + + # do we need to configure high multiplicity selection, either NeX or ex_ey_ez etc...? + if len(cparts) > 1 or __mult(cparts[0]) > 1: + tool = _MultTool(name) + for cpart in cparts: + for cutNumber in range( __mult( cpart ) ): + tool.SubTools += [ _IncTool( cpart['chainPartName']+"_"+str(cutNumber), __cand(cpart), __th(cpart), __sel(cpart) ) ] + + return tool + else: + return _IncTool( name, __cand(cparts[0]), __th(cparts[0]), __sel(cparts[0]) ) diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/ITrigL2CaloRingerHypoToolMT.h b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/ITrigL2CaloRingerHypoToolMT.h new file mode 100644 index 0000000000000000000000000000000000000000..377ccb2a8f358f92dde44471f3311653446d2dc8 --- /dev/null +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/ITrigL2CaloRingerHypoToolMT.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef TRIGMULTIVARHYPO_ITRIGL2CALORINGERHYPOTOOLMT_H +#define TRIGMULTIVARHYPO_ITRIGL2CALORINGERHYPOTOOLMT_H 1 + +#include "GaudiKernel/IAlgTool.h" + + + +#include "AthenaBaseComps/AthAlgTool.h" +#include "DecisionHandling/HLTIdentifier.h" +#include "DecisionHandling/TrigCompositeUtils.h" +#include "xAODTrigRinger/TrigRingerRings.h" +#include "TrigSteeringEvent/TrigRoiDescriptorCollection.h" + + +/** + * @class Base for tools dooing L2 Calo Hypo selection + * @brief + **/ + +class ITrigL2CaloRingerHypoToolMT + : virtual public ::IAlgTool +{ + + public: + DeclareInterfaceID(ITrigL2CaloRingerHypoToolMT, 1, 0); + virtual ~ITrigL2CaloRingerHypoToolMT(){} + + + struct RingerInfo { + RingerInfo( TrigCompositeUtils::Decision* d, + const TrigRoiDescriptor* k, + const xAOD::TrigRingerRings* r, + const TrigCompositeUtils::Decision* previousDecision ) + : decision( d ), + roi( k ), + ringerShape( r ), + previousDecisionIDs( TrigCompositeUtils::decisionIDs( previousDecision ).begin(), + TrigCompositeUtils::decisionIDs( previousDecision ).end() ) + {} + TrigCompositeUtils::Decision* decision; + const TrigRoiDescriptor* roi; + const xAOD::TrigRingerRings* ringerShape; + const TrigCompositeUtils::DecisionIDContainer previousDecisionIDs; + }; + + /** + * @brief decides upon all clusters + * Note it is for a reason a non-virtual method, it is an interface in gaudi sense and implementation. + * There will be many tools called often to perform this quick operation and we do not want to pay for polymorphism which we do not need to use. + * Will actually see when N obj hypos will enter the scene + **/ + virtual StatusCode decide( std::vector<RingerInfo>& input ) const = 0; + + /** + * @brief Makes a decision for a single object + * The decision needs to be returned + **/ + virtual bool decide( const RingerInfo& i ) const = 0; + + protected: + + +}; + + +#endif //> !TRIGMULTIVARHYPO_ITRIGL2CALORINGERHYPOTOOLMT_H diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.cxx b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.cxx index 73d7a67a688108c6b395885135d6c88a98d58fbf..8051b4a7b3abb5731ac91fb3d387eb8708a15ce4 100644 --- a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.cxx +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.cxx @@ -1,25 +1,17 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include <map> #include "GaudiKernel/Property.h" #include "TrigL2CaloRingerHypoAlgMT.h" +#include "ITrigL2CaloRingerHypoToolMT.h" #include "AthViews/ViewHelper.h" #include "TrigCompositeUtils/HLTIdentifier.h" #include "TrigCompositeUtils/TrigCompositeUtils.h" #include "AthViews/ViewHelper.h" -using TrigCompositeUtils::DecisionContainer; -using TrigCompositeUtils::DecisionAuxContainer; -using TrigCompositeUtils::DecisionIDContainer; -using TrigCompositeUtils::decisionIDs; -using TrigCompositeUtils::newDecisionIn; -using TrigCompositeUtils::linkToPrevious; -using TrigCompositeUtils::createAndStore; -using TrigCompositeUtils::viewString; -using TrigCompositeUtils::featureString; -using TrigCompositeUtils::findLink; +using namespace TrigCompositeUtils; TrigL2CaloRingerHypoAlgMT::TrigL2CaloRingerHypoAlgMT( const std::string& name, ISvcLocator* pSvcLocator ) : @@ -52,29 +44,49 @@ StatusCode TrigL2CaloRingerHypoAlgMT::execute( const EventContext& context ) con SG::WriteHandle<DecisionContainer> outputHandle = createAndStore(decisionOutput(), context ); auto decisions = outputHandle.ptr(); // input for decision - std::vector<TrigL2CaloRingerHypoToolMT::RingerInfo> hypoToolInput; + std::vector<ITrigL2CaloRingerHypoToolMT::RingerInfo> hypoToolInput; // loop over previous decisions size_t counter=0; for ( auto previousDecision: *previousDecisionsHandle ) { - + //get RoI + + auto roiELInfo = findLink<TrigRoiDescriptorCollection>( previousDecision, initialRoIString() ); + ATH_CHECK( roiELInfo.isValid() ); + const TrigRoiDescriptor* roi = *(roiELInfo.link); + // get View const auto view = previousDecision->objectLink<ViewContainer>( viewString() ); ATH_CHECK( view.isValid() ); + auto ringerShapeHandle = ViewHelper::makeHandle( *(view), m_ringsKey, context); ATH_CHECK( ringerShapeHandle.isValid() ); + ATH_MSG_DEBUG ( "Ringer handle size: " << ringerShapeHandle->size() << "..." ); + + // add cluster + auto clusterHandle = ViewHelper::makeHandle( *view, m_clustersKey, context); + ATH_CHECK( clusterHandle.isValid() ); + // create new decision auto d = newDecisionIn( decisions, name() ); - hypoToolInput.emplace_back( TrigL2CaloRingerHypoToolMT::RingerInfo{ d, ringerShapeHandle.cptr()->at(0) } ); + hypoToolInput.emplace_back( d, roi, ringerShapeHandle.cptr()->at(0), previousDecision ); + // link the rings { auto el = ViewHelper::makeLink( *(view), ringerShapeHandle, 0 ); ATH_CHECK( el.isValid() ); d->setObjectLink( featureString(), el ); } - - TrigCompositeUtils::linkToPrevious( d, decisionInput().key(), counter ); + // link the cluster + { + auto clus = ViewHelper::makeLink( *(view), clusterHandle, 0 ); + ATH_CHECK( clus.isValid() ); + d->setObjectLink( featureString(), clus ); + } + d->setObjectLink( roiString(), roiELInfo.link ); + + TrigCompositeUtils::linkToPrevious( d, previousDecision, context ); counter++; } diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.h b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.h index 0ff083bc101f8677cd06cac401c23b415649f69d..3c8e0f1ad9e3e1518cc0aa5631ddfffa60e78a98 100644 --- a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.h +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoAlgMT.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef TRIGL2CALORINGERHYPOALGMT_H #define TRIGL2CALORINGERHYPOALGMT_H 1 @@ -12,31 +12,30 @@ #include "TrigCompositeUtils/TrigCompositeUtils.h" #include "DecisionHandling/HypoBase.h" #include "AthViews/View.h" +#include "TrigSteeringEvent/TrigRoiDescriptorCollection.h" -#include "TrigL2CaloRingerHypoToolMT.h" +#include "ITrigL2CaloRingerHypoToolMT.h" class TrigL2CaloRingerHypoAlgMT : public ::HypoBase -{ - public: +{ + public: TrigL2CaloRingerHypoAlgMT( const std::string& name, ISvcLocator* pSvcLocator ); virtual StatusCode initialize() override; virtual StatusCode execute(const EventContext& context) const override; - - private: - TrigL2CaloRingerHypoAlgMT(); - ToolHandleArray< TrigL2CaloRingerHypoToolMT > m_hypoTools {this, "HypoTools", {}, "Tools to perfrom selection"}; - SG::ReadHandleKey<xAOD::TrigRingerRingsContainer> m_ringsKey { this, "RingerKey","CaloRings",""}; - SG::ReadHandleKey<xAOD::TrigEMClusterContainer> m_clustersKey { this,"ClustersKey","CaloClusters",""}; + private: + ToolHandleArray< ITrigL2CaloRingerHypoToolMT > m_hypoTools {this, "HypoTools", {}, "Tools to perfrom selection"}; + SG::ReadHandleKey<xAOD::TrigRingerRingsContainer> m_ringsKey { this, "RingerKey","HLT_FastCaloRinger","Point to RingerKey"}; + SG::ReadHandleKey<xAOD::TrigEMClusterContainer> m_clustersKey { this,"ClustersKey","ClustersKey","ClustersKey in view"}; -}; +}; //DECLARE_ALGORITHM_FACTORY( TrigL2CaloRingerHypoAlgMT ) #endif //> !MULTIVARHYPO_TRIGL2CALORINGERHYPOALG_H diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.cxx b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.cxx index 7678bb8d7b48c8e930c2788e8c4c2e53e509d598..1a49bfda2e526dae293711d8aedd8001efa10be3 100644 --- a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.cxx +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ @@ -19,7 +19,7 @@ TrigL2CaloRingerHypoToolMT::TrigL2CaloRingerHypoToolMT( const std::string& type, const std::string& name, const IInterface* parent ) - : AthAlgTool( type, name, parent ), + : base_class( type, name, parent ), m_selectorTool(), m_lumiBlockMuTool("LumiBlockMuTool/LumiBlockMuTool"), m_decisionId( HLT::Identifier::fromToolName( name ) ) @@ -64,7 +64,7 @@ StatusCode TrigL2CaloRingerHypoToolMT::finalize() { TrigL2CaloRingerHypoToolMT::~TrigL2CaloRingerHypoToolMT() {} -bool TrigL2CaloRingerHypoToolMT::decideOnSingleObject( const xAOD::TrigRingerRings* ringerShape) const { +bool TrigL2CaloRingerHypoToolMT::decide( const RingerInfo & decision) const { auto etMon = Monitored::Scalar("Et",-100); @@ -81,14 +81,12 @@ bool TrigL2CaloRingerHypoToolMT::decideOnSingleObject( const xAOD::TrigRingerRin total_time.start(); - - if(m_acceptAll){ ATH_MSG_DEBUG("AcceptAll property is set: taking all events"); return true; } - + auto ringerShape = decision.ringerShape; const xAOD::TrigEMCluster *emCluster = 0; if(ringerShape){ emCluster = ringerShape->emCluster(); @@ -105,18 +103,19 @@ bool TrigL2CaloRingerHypoToolMT::decideOnSingleObject( const xAOD::TrigRingerRin float et = emCluster->et() / Gaudi::Units::GeV; float avgmu = m_lumiBlockMuTool->averageInteractionsPerCrossing(); - etaMon = emCluster->eta(); - etMon = emCluster->et(); - phiMon = emCluster->phi(); - if(eta>2.50) eta=2.50;///fix for events out of the ranger + // make sure that monitoring histogram will plotting only the events of chain. ///Et threshold if(et < m_emEtCut/Gaudi::Units::GeV){ ATH_MSG_DEBUG( "Event reproved by Et threshold. Et = " << et << ", EtCut = " << m_emEtCut/Gaudi::Units::GeV); return false; } + etaMon = emCluster->eta(); + etMon = emCluster->et(); + phiMon = emCluster->phi(); + const std::vector<float> rings = ringerShape->rings(); std::vector<float> refRings(rings.size()); refRings.assign(rings.begin(), rings.end()); @@ -137,13 +136,15 @@ bool TrigL2CaloRingerHypoToolMT::decideOnSingleObject( const xAOD::TrigRingerRin } -StatusCode TrigL2CaloRingerHypoToolMT::decide( std::vector<RingerInfo>& input ) const { +StatusCode TrigL2CaloRingerHypoToolMT::decide( std::vector<RingerInfo>& input ) const { for ( auto i: input ) { - auto objDecision = decideOnSingleObject( i.ringerShape ); + if ( passed ( m_decisionId.numeric(), i.previousDecisionIDs ) ) { + auto objDecision = decide( i ); if ( objDecision == true ) { addDecisionID( m_decisionId.numeric(), i.decision ); } + } } return StatusCode::SUCCESS; } diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.h b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.h index 0ded116a88468796a07c90640e9cd3255e12b9b0..4403fbdbd185c6508bc3a9840034fcf2bf8ea2ea 100644 --- a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.h +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMT.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef TRIGL2CALORINGERHYPOTOOLMT_H @@ -13,9 +13,11 @@ #include "TrigCompositeUtils/TrigCompositeUtils.h" #include "xAODTrigRinger/TrigRingerRings.h" #include "TrigMultiVarHypo/tools/RingerSelectorTool.h" +#include "ITrigL2CaloRingerHypoToolMT.h" #include "LumiBlockComps/ILumiBlockMuTool.h" -class TrigL2CaloRingerHypoToolMT : virtual public ::AthAlgTool + +class TrigL2CaloRingerHypoToolMT : virtual public extends<AthAlgTool, ITrigL2CaloRingerHypoToolMT> { public: TrigL2CaloRingerHypoToolMT( const std::string& type, @@ -27,17 +29,8 @@ class TrigL2CaloRingerHypoToolMT : virtual public ::AthAlgTool virtual StatusCode initialize() override; virtual StatusCode finalize() override; - - - bool decideOnSingleObject( const xAOD::TrigRingerRings* ringerShape ) const; - - - struct RingerInfo { - TrigCompositeUtils::Decision* decision; - const xAOD::TrigRingerRings* ringerShape; - }; - - StatusCode decide( std::vector<RingerInfo>& decisions ) const; + bool decide( const RingerInfo & decision ) const override; + StatusCode decide( std::vector<RingerInfo>& decisions ) const override; private: diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMTMult.cxx b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMTMult.cxx new file mode 100644 index 0000000000000000000000000000000000000000..98a357bb710fbb159b25756d721fa2ca5284af45 --- /dev/null +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMTMult.cxx @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ +#include "DecisionHandling/Combinators.h" +#include "DecisionHandling/TrigCompositeUtils.h" +#include "TrigL2CaloRingerHypoToolMTMult.h" + +using namespace TrigCompositeUtils; + +TrigL2CaloRingerHypoToolMTMult::TrigL2CaloRingerHypoToolMTMult( const std::string& type, + const std::string& name, + const IInterface* parent ) + : base_class( type, name, parent ), + m_decisionId( HLT::Identifier::fromToolName( name ) ) {} + +TrigL2CaloRingerHypoToolMTMult::~TrigL2CaloRingerHypoToolMTMult() {} + + +StatusCode TrigL2CaloRingerHypoToolMTMult::initialize() { + if( m_subTools.size() <= 1 ) { + ATH_MSG_ERROR( "Number of sub tools " << m_subTools.size() << ", while it has to be > 1, otherwise this is not a multiplicity selection" ); + return StatusCode::FAILURE; + } + CHECK( m_subTools.retrieve() ); + return StatusCode::SUCCESS; +} + +StatusCode TrigL2CaloRingerHypoToolMTMult::decide( std::vector<ITrigL2CaloRingerHypoToolMT::RingerInfo>& input ) const { + HLT::Index2DVec passingSelection( m_subTools.size() ); + ATH_MSG_DEBUG( "Applying Ringer selection of multiplicity " << m_subTools.size() ); + + size_t cutIndex{ 0 }; + for ( auto& tool: m_subTools ) { + size_t clusterIndex{ 0 }; + for ( auto iIter = input.begin(); iIter != input.end(); ++iIter, ++clusterIndex ) { + if ( passed( m_decisionId.numeric(), iIter->previousDecisionIDs ) ) { + if ( tool->decide( *iIter ) ) + passingSelection[ cutIndex ].push_back( clusterIndex ); + } + } + + if ( passingSelection[cutIndex].empty() ) { + ATH_MSG_DEBUG( "No object passed selection " << cutIndex << " rejecting" ); + return StatusCode::SUCCESS; + } + cutIndex++; + } + + std::set<size_t> passingIndices; + HLT::elementsInUniqueCombinations( passingSelection, passingIndices ); + + for ( auto idx: passingIndices ) + addDecisionID( m_decisionId.numeric(), input[idx].decision ); + + return StatusCode::SUCCESS; +} diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMTMult.h b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMTMult.h new file mode 100644 index 0000000000000000000000000000000000000000..9657db931cd82b0685c58b46b91c8e8d7395a6eb --- /dev/null +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/TrigL2CaloRingerHypoToolMTMult.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef TRIGMULTIVARHYPO_TRIGL2CALORINGERHYPOTOOLMULT_H +#define TRIGMULTIVARHYPO_TRIGL2CALORINGERHYPOTOOLMULT_H 1 + +//#include "GaudiKernel/IAlgTool.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "xAODTrigCalo/TrigEMCluster.h" +#include "TrigSteeringEvent/TrigRoiDescriptor.h" +#include "AthenaBaseComps/AthAlgTool.h" +#include "AthenaMonitoringKernel/GenericMonitoringTool.h" +#include "DecisionHandling/HLTIdentifier.h" +#include "DecisionHandling/TrigCompositeUtils.h" +#include "ITrigL2CaloRingerHypoToolMT.h" + + + +/** + * @class Implementation of the Egamma selection for CaloClusters with multiplicity + * @brief + **/ + +class TrigL2CaloRingerHypoToolMTMult : public extends<AthAlgTool, ITrigL2CaloRingerHypoToolMT> { + public: + TrigL2CaloRingerHypoToolMTMult( const std::string& type, + const std::string& name, + const IInterface* parent ); + + virtual ~TrigL2CaloRingerHypoToolMTMult(); + virtual StatusCode initialize() override; + + virtual StatusCode decide( std::vector<ITrigL2CaloRingerHypoToolMT::RingerInfo>& input ) const override; + + virtual bool decide( const ITrigL2CaloRingerHypoToolMT::RingerInfo& ) const override { + REPORT_MESSAGE(MSG::ERROR) << "this method should never be called"; + return false; + } + + private: + HLT::Identifier m_decisionId; + + ToolHandleArray<ITrigL2CaloRingerHypoToolMT> m_subTools { this, "SubTools", {}, "Sub tools performing cuts" }; + +}; + +#endif //> !TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOLMULT_H diff --git a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/components/TrigMultiVarHypo_entries.cxx b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/components/TrigMultiVarHypo_entries.cxx index 124b9c4d6e3175ed27e99c42c029deeb6bf2db03..2bbb9113a21017bcf8a8d0e9270bba15f5f57f4c 100755 --- a/Trigger/TrigHypothesis/TrigMultiVarHypo/src/components/TrigMultiVarHypo_entries.cxx +++ b/Trigger/TrigHypothesis/TrigMultiVarHypo/src/components/TrigMultiVarHypo_entries.cxx @@ -6,12 +6,14 @@ #include "TrigMultiVarHypo/TrigL2CaloRingerFex.h" #include "TrigMultiVarHypo/TrigL2CaloRingerHypo.h" #include "../TrigL2CaloRingerHypoToolMT.h" +#include "../TrigL2CaloRingerHypoToolMTMult.h" #include "../TrigL2CaloRingerHypoAlgMT.h" DECLARE_COMPONENT( TrigL2CaloRingerFex ) DECLARE_COMPONENT( TrigL2CaloRingerHypo ) DECLARE_COMPONENT( TrigL2CaloRingerHypoToolMT ) +DECLARE_COMPONENT( TrigL2CaloRingerHypoToolMTMult ) DECLARE_COMPONENT( TrigL2CaloRingerHypoAlgMT ) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/CaloSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/CaloSequenceSetup.py index ef0f50cc69fcacd42675bd731b991b647bb3fe6b..1c27db59896a9cdb6f09966a0d41827a34323a86 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/CaloSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/CaloSequenceSetup.py @@ -18,7 +18,7 @@ def fastCaloSequence(doRinger): from TrigT2CaloCommon.CaloDef import fastCaloEVCreator (fastCaloViewsMaker, InViewRoIs) = fastCaloEVCreator() - # reco sequence + # reco sequence always build the rings from TrigT2CaloCommon.CaloDef import fastCaloRecoSequence (fastCaloInViewSequence, sequenceOut) = fastCaloRecoSequence(InViewRoIs, doRinger=doRinger) @@ -27,21 +27,34 @@ def fastCaloSequence(doRinger): return (fastCaloSequence, fastCaloViewsMaker, sequenceOut) -def fastCaloMenuSequence(name, doRinger=True): +def fastCaloMenuSequence(name, doRinger): """ Creates L2 Fast Calo MENU sequence The Hypo name changes depending on name, so for different implementations (Electron, Gamma,....) + The doRinger flag is to use or not the Ringer hypo """ - (sequence, fastCaloViewsMaker, sequenceOut) = RecoFragmentsPool.retrieve(fastCaloSequence, doRinger) - - # hypo - from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2CaloHypoAlgMT - theFastCaloHypo = TrigL2CaloHypoAlgMT(name+"L2CaloHypo") - theFastCaloHypo.CaloClusters = sequenceOut - CaloMenuDefs.L2CaloClusters = sequenceOut - - - from TrigEgammaHypo.TrigL2CaloHypoTool import TrigL2CaloHypoToolFromDict - return MenuSequence( Sequence = sequence, - Maker = fastCaloViewsMaker, - Hypo = theFastCaloHypo, - HypoToolGen = TrigL2CaloHypoToolFromDict ) + (sequence, fastCaloViewsMaker, sequenceOut) = RecoFragmentsPool.retrieve(fastCaloSequence, {'doRinger' : doRinger}) + # check if use Ringer and are electron because there aren't ringer for photons yet + if doRinger: + # Ringer hypo + from TrigMultiVarHypo.TrigMultiVarHypoConf import TrigL2CaloRingerHypoAlgMT + theFastCaloHypo = TrigL2CaloRingerHypoAlgMT( name + "L2CaloRingerHypo") + theFastCaloHypo.ClustersKey = sequenceOut + CaloMenuDefs.L2CaloClusters = sequenceOut + + from TrigMultiVarHypo.TrigL2CaloRingerHypoTool import TrigL2CaloRingerHypoToolFromDict + return MenuSequence( Sequence = sequence, + Maker = fastCaloViewsMaker, + Hypo = theFastCaloHypo, + HypoToolGen = TrigL2CaloRingerHypoToolFromDict ) + else: + # hypo + from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2CaloHypoAlgMT + theFastCaloHypo = TrigL2CaloHypoAlgMT(name+"L2CaloHypo") + theFastCaloHypo.CaloClusters = sequenceOut + CaloMenuDefs.L2CaloClusters = sequenceOut + + from TrigEgammaHypo.TrigL2CaloHypoTool import TrigL2CaloHypoToolFromDict + return MenuSequence( Sequence = sequence, + Maker = fastCaloViewsMaker, + Hypo = theFastCaloHypo, + HypoToolGen = TrigL2CaloHypoToolFromDict ) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py index e2f4a6063aa2891da063885a73e6cde4705dc055..7cf22d9c06a1c04ca2dbe6f81740e53ed733faad 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py @@ -19,8 +19,12 @@ from TriggerMenuMT.HLTMenuConfig.Egamma.PrecisionElectronSequenceSetup import pr # so let's make them functions already now #---------------------------------------------------------------- -def electronFastCaloCfg( doRinger=True ): - return fastCaloMenuSequence("Electron", doRinger) + +def electronFastCaloCfg( flags ): + return fastCaloMenuSequence("Electron", doRinger=False) + +def electronFastCaloRingerCfg( flags ): + return fastCaloMenuSequence("Electron", doRinger=True) def fastElectronSequenceCfg( flags ): return fastElectronMenuSequence() @@ -38,18 +42,19 @@ class ElectronChainConfiguration(ChainConfigurationBase): def __init__(self, chainDict): ChainConfigurationBase.__init__(self,chainDict) - + # ---------------------- # Assemble the chain depending on information from chainName # ---------------------- def assembleChain(self): chainSteps = [] log.debug("Assembling chain for " + self.chainName) + # -------------------- # define here the names of the steps and obtain the chainStep configuration # -------------------- - etcut1step = [ self.getFastCalo() ] - etcut_sequence = [ self.getFastCalo(), self.getFastElectron(), self.getPrecisionCaloElectron()] + etcut1step = [ self.getFastCalo(doRinger=False) ] + etcut_sequence = [ self.getFastCalo(doRinger=False), self.getFastElectron(), self.getPrecisionCaloElectron()] electron_sequence = [ self.getFastCalo(), self.getFastElectron(), self.getPrecisionCaloElectron(), self.getPrecisionElectron()] etcut_noringer_sequence = [ self.getFastCalo(doRinger=False), self.getFastElectron(), self.getPrecisionCaloElectron()] electron_noringer_sequence = [ self.getFastCalo(doRinger=False), self.getFastElectron(), self.getPrecisionCaloElectron(), self.getPrecisionElectron()] @@ -68,25 +73,27 @@ class ElectronChainConfiguration(ChainConfigurationBase): 'lhtightnoringer' : electron_noringer_sequence, } - log.debug('electron chain part = ' + str(self.chainPart)) key = self.chainPart['extra'] + self.chainPart['IDinfo'] + self.chainPart['L2IDAlg'] + self.chainPart['isoInfo'] + for addInfo in self.chainPart['addInfo']: key+=addInfo - + log.debug('electron key = ' + key) if key in stepDictionary: steps=stepDictionary[key] else: raise RuntimeError("Chain configuration unknown for electron chain with key: " + key ) + chainSteps = [] for step in steps: log.debug('Adding electron trigger step ' + str(step)) chainSteps+=[step] - - myChain = self.buildChain(chainSteps) + + myChain = self.buildChain(chainSteps) + return myChain # -------------------- @@ -94,9 +101,14 @@ class ElectronChainConfiguration(ChainConfigurationBase): # -------------------- def getFastCalo(self, doRinger=True): - stepName = "Step1_FastCalo_electron" + if doRinger: + stepName = "Step1_FastCaloRinger_electron" + fastCaloCfg = electronFastCaloRingerCfg + else: + stepName = "Step1_FastCalo_electron" + fastCaloCfg = electronFastCaloCfg log.debug("Configuring step " + stepName) - fastCalo = RecoFragmentsPool.retrieve( electronFastCaloCfg, doRinger ) # the None will be used for flags in future + fastCalo = RecoFragmentsPool.retrieve(fastCaloCfg , None ) return ChainStep(stepName, [fastCalo], [self.mult], [self.dict]) def getFastElectron(self): @@ -110,7 +122,7 @@ class ElectronChainConfiguration(ChainConfigurationBase): stepName = "Step3_precisionCalo_electron" log.debug("Configuring step " + stepName) precisionReco = RecoFragmentsPool.retrieve( precisionCaloSequenceCfg, None ) - return ChainStep(stepName, [precisionReco], [self.mult], [self.dict]) + return ChainStep(stepName, [precisionReco], [self.mult], [self.dict]) def getPrecisionElectron(self): diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonDef.py index 00db5900216705cc825cef163257eaab96d1f8d8..328521d27d670e5141073babc0c9250932acb7a0 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonDef.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonDef.py @@ -20,7 +20,7 @@ from TriggerMenuMT.HLTMenuConfig.Egamma.PrecisionCaloSequenceSetup import precis # so let's make them functions already now #---------------------------------------------------------------- def fastPhotonCaloSequenceCfg( flags ): - return fastCaloMenuSequence('Photon') + return fastCaloMenuSequence('Photon', doRinger=False) def fastPhotonSequenceCfg( flags ): return fastPhotonMenuSequence()