diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx index c940256da44619e516dd65a9bb909dad7e12914f..47727546e9e0ddf7e0721df28592dcdb4dc9571f 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx @@ -213,6 +213,7 @@ StatusCode ComboHypo::execute(const EventContext& context ) const { uint16_t featureIndex = 0, roiIndex = 0; // NOTE: roiKey, roiIndex not currently used in this discrimination ATH_CHECK( extractFeatureAndRoI(dEL, featureKey, featureIndex, roiKey, roiIndex) ); + // TODO: move this to InitialRoI for serial merging const uint32_t featureHash = (featureKey + featureIndex); if (featureHash == 0) { ATH_MSG_WARNING("Disregarding feature hash of zero"); @@ -237,7 +238,6 @@ StatusCode ComboHypo::execute(const EventContext& context ) const { ATH_MSG_DEBUG( "Chain " << chainId << ( overallDecision ? " is accepted" : " is rejected") <<" after multiplicity requirements" ); if ( overallDecision == true ) { for (auto decID: allDecisionIds) { - // passing.insert( passing.end(), decID ); // saving the good combiantions goodMultCombMap.insert (thisChainCombMap.begin(), thisChainCombMap.end()); ATH_MSG_DEBUG(" Passing " << HLT::Identifier(decID)<<" after multiplicity test"); @@ -245,18 +245,18 @@ StatusCode ComboHypo::execute(const EventContext& context ) const { } } - // launching the tools: - /////////////////////// - LegDecisionsMap passingLegs; + LegDecisionsMap passingLegs; + if (goodMultCombMap.size()!=0){ + // launching the tools: + /////////////////////// if (m_hypoTools.size()>0){ for ( auto& tool: m_hypoTools ) { ATH_MSG_DEBUG( "Calling tool "<<tool->name()); ATH_CHECK( tool->decide( goodMultCombMap, passingLegs ) ); } } - else{ - passingLegs = goodMultCombMap; - } + else passingLegs=goodMultCombMap; + } // this is only for debug: if (msgLvl(MSG::DEBUG)){ @@ -281,6 +281,7 @@ StatusCode ComboHypo::extractFeatureAndRoI(const ElementLink<DecisionContainer>& uint32_t featureClid = 0; // Note: Unused. We don't care what the type of the feature is here const bool result = (*dEL)->typelessGetObjectLink(featureString(), featureKey, featureClid, featureIndex); if (!result) { + // WARNING? ATH_MSG_ERROR("Did not find the feature for " << dEL.dataID() << " index " << dEL.index()); } // Try and get seeding ROI data too. Don't need to be type-less here diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.h b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.h index dcf85ccb7f343f48da785dcc102d2fa9edb7496e..e633649aa59efdcdbb0b4d5ed8c388e5e61d03c0 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.h +++ b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.h @@ -11,7 +11,7 @@ // STL includes #include <string> #include <utility> -#include "IComboHypoTool.h" +#include "ComboHypoToolBase.h" /** * @class ComboHypo for combined hypotheses required only counting (multiplicity requirements) @@ -73,7 +73,7 @@ private: StatusCode fillDecisionsMap( LegDecisionsMap& dmap, const EventContext& context) const; - ToolHandleArray< IComboHypoTool > m_hypoTools {this, "ComboHypoTools", {}, "Tools to perform selection"}; + ToolHandleArray< ComboHypoToolBase > m_hypoTools {this, "ComboHypoTools", {}, "Tools to perform selection"}; }; diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.cxx b/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7f181f75667d5bbec43e8b9eda6eb33f13599d6b --- /dev/null +++ b/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.cxx @@ -0,0 +1,174 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "ComboHypoToolBase.h" +using namespace TrigCompositeUtils; + + +ComboHypoToolBase::ComboHypoToolBase(const std::string& type, const std::string& name, const IInterface* parent) : + base_class(type, name, parent), + m_decisionId( HLT::Identifier::fromToolName( name ) ) +{} + + +StatusCode ComboHypoToolBase::decide(const LegDecisionsMap & IDCombMap, LegDecisionsMap & passingCombinations ) const +{ + // if no combinations passed, then exit + size_t nLegs=IDCombMap.size(); + if (nLegs==0) return StatusCode::SUCCESS; + + // check that no other toold have efilled the map with this id + ATH_CHECK( passingCombinations[decisionId()].empty() ); + + ATH_MSG_DEBUG( "Looking for "<< decisionId() <<" in the map. Map contains "<<nLegs<<" legs"); + + // select the leg decisions from the map with this ID: + std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> leg_decisions; + ATH_CHECK( selectLegs(IDCombMap, leg_decisions) ); + + if (leg_decisions.size() == 0) { + ATH_MSG_INFO("Found 0 legs with this DecisionID: something failed?"); + return StatusCode::SUCCESS; + } + + // create the combinations between the legs + std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> combinations; + createCombinations( leg_decisions, combinations, nLegs, 2); + + + // do the actual algorithm and select the decisions that passed + for (ElementLinkVector<TrigCompositeUtils::DecisionContainer> thecomb: combinations){ + // to add: protection when the two decisions are the same object + bool pass = executeAlg(thecomb); + if (pass){ + setDecisionIds(thecomb, passingCombinations); + } + } + + printExecute(passingCombinations); + return StatusCode::SUCCESS; + +} + +StatusCode ComboHypoToolBase::selectLegs(const LegDecisionsMap & IDCombMap, std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>>& leg_decisions) const +{ + size_t nLegs=IDCombMap.size(); + if (nLegs==0) return StatusCode::SUCCESS; + + // collect combinations from all the legs, searching both chain name and leg name + for (auto id: IDCombMap){ + // get the Element links from the chainID (from all the legs) + HLT::Identifier chainId=0; + if (TrigCompositeUtils::isLegId(id.first)) + chainId= TrigCompositeUtils::getIDFromLeg(id.first); + else + chainId=id.first; + if ( chainId != decisionId() ) continue; + auto comb = id.second; + leg_decisions.push_back(comb); + } + + if (nLegs != leg_decisions.size()){ + ATH_MSG_ERROR("Expecting "<<nLegs<<" legs, but found "<< leg_decisions.size() <<" legs to combine"); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG("Getting "<<leg_decisions.size()<<" legs to combine, for ID: "<< decisionId()); + for (auto leg: leg_decisions){ + ATH_MSG_DEBUG("Leg --"); + for (auto dEL:leg) ATH_MSG_DEBUG(dEL.dataID() << " , " << dEL.index()); + } + + return StatusCode::SUCCESS; +} + + +// Include case of one leg and multiple legs with mult=1 on each leg. Need to be exended to cover cases with multiple legs qith different multiplicities (2mu_3e) +void ComboHypoToolBase::createCombinations(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & v_legs, + std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & combinations, int nLegs, int nToGroup) const +{ + if (nLegs ==1) { + auto elements = v_legs[0]; + std::vector<int> selector(elements.size()); + fill(selector.begin(), selector.begin() + nToGroup, 1); + ElementLinkVector<TrigCompositeUtils::DecisionContainer> thecomb; + do { + for (u_int i = 0; i < elements.size(); i++) { + if (selector[i]) { + thecomb.push_back(elements[i]); + } + } + combinations.push_back(thecomb); + thecomb.clear(); + } while (std::prev_permutation(selector.begin(), selector.end())); + } + + else { + ElementLinkVector<TrigCompositeUtils::DecisionContainer> local; + recursive_combine(v_legs, combinations, local, 0); + } + + for (auto comb: combinations){ + ATH_MSG_DEBUG("Combination"); + for (auto dEL :comb){ + ATH_MSG_DEBUG(dEL.dataID() << " , " << dEL.index()); + } + } + return; +} + + +void ComboHypoToolBase::setDecisionIds(const ElementLinkVector<TrigCompositeUtils::DecisionContainer>& thecomb, LegDecisionsMap & passingCombinations) const { + + for (ElementLink<TrigCompositeUtils::DecisionContainer> dEL: thecomb){ + const TrigCompositeUtils:: Decision* decision= (*dEL); + // get back the decID of this element + const std::vector<DecisionID>& allDecIDs = TrigCompositeUtils::decisionIDs( decision ); + ATH_MSG_DEBUG( dEL.dataID() << " , " << dEL.index() <<" with "<<allDecIDs.size() <<" decisionIDs"); + for (auto id: allDecIDs){ + if ((HLT::Identifier(id).name()).find(decisionId().name())!=std::string::npos){ + // we may have this element already stored, so there might be duplications + // add to both legID and chainID? + passingCombinations[id].push_back(dEL); + passingCombinations[ decisionId() ].push_back(dEL); + } + } + } + + // remove duplicates? + return; +} + + + +StatusCode ComboHypoToolBase::printExecute(const LegDecisionsMap & passingCombinations) const { + ATH_MSG_DEBUG("End of tool: Passing elments are: "); + for (auto id: passingCombinations){ + ATH_MSG_DEBUG("Id "<<HLT::Identifier(id.first)<<" with "<<id.second.size()<<" elements"); + for (auto dEL: id.second){ + ATH_MSG_DEBUG( dEL.dataID() << " , " << dEL.index()); + } + } + return StatusCode::SUCCESS; +} + + +void ComboHypoToolBase::recursive_combine(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> &all, + std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & tocombine, + ElementLinkVector<TrigCompositeUtils::DecisionContainer> & local, u_int lindex) const +{ + + for (size_t leg =lindex; leg<all.size(); leg++){ + for (size_t i=0; i<all[leg].size(); i++){ + local.push_back(all[leg][i]); + recursive_combine(all, tocombine,local, leg+1); + local.pop_back(); + } + } + if (local.size() == all.size()) + tocombine.push_back(local); + + return; + +} diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.h b/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.h new file mode 100644 index 0000000000000000000000000000000000000000..b00ff90e018c937c36e255e2cd1db5ff5e19c6dc --- /dev/null +++ b/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.h @@ -0,0 +1,102 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef DECISIONHANDLING_COMBOHYPOTOOLBASE_H +#define DECISIONHANDLING_COMBOHYPOTOOLBASE_H + +// Package includes +#include "IComboHypoTool.h" + +// Framework includes +#include "AthenaBaseComps/AthAlgTool.h" +#include "DecisionHandling/HLTIdentifier.h" +#include "DecisionHandling/TrigCompositeUtils.h" + +// STL includes +#include <string> + +/** + * @class ComboHypoToolBase + * @brief + **/ + + +class ComboHypoToolBase : public extends<AthAlgTool, IComboHypoTool> { + +public: + ComboHypoToolBase(const std::string& type, const std::string& name, const IInterface* parent); + + + /** + * @brief retreives the decisions associated to this decId, make their combinations and apply the algorithm + @param[in] InputDecisions + @param[in] Cobminaiton map that lists all the decisions passing the multiplicity map of the ComboHypo + @param[out] Combination map that lists all the decisions passing the HypoTool algorithm + **/ + virtual StatusCode decide(const LegDecisionsMap & IDCombMap,LegDecisionsMap & passingCombinations ) const override; + + + /** + * @brief retrieves this decision Id + **/ + virtual HLT::Identifier decisionId() const { return m_decisionId; } + + + protected: + + /** + * @brief creates the decision legs starting from the initial LegDecision map, storing only those concerning this decisionID + **/ + StatusCode selectLegs(const LegDecisionsMap & IDCombMap, std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>>& leg_decisions) const; + + /** + * @brief creates combinations of decisions starting from the legs vector of pairs, given the number of legs and the number of elements to combine + @param[in] v_legs: vector of legs (vector), each containing the corresponding decision pairs + @param[in] nLegs: number of legs to combine + @param[in] nToGroup: number of elements to group in a combination, in case one leg is used + @param[out] combinations: vector of combinations (vectors) of decision pairs + **/ + void createCombinations(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & v_legs, + std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & combinations, int nLegs, int nToGroup) const; + + /** + * @brief recursively creates combinations of elements from differnt vectors + @param[in] all: initial vector of decision legs + @parma[in] local: temporary vector of combinations + @param[in] lindex: leg index + @param[out] tocombine: vector of combinations + **/ + void recursive_combine(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> &all, + std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & tocombine, + ElementLinkVector<TrigCompositeUtils::DecisionContainer> & local, u_int lindex) const; + + + /** + * @brief contains the real algorithm to apply on the given combination of decisions + **/ + virtual bool executeAlg(ElementLinkVector<TrigCompositeUtils::DecisionContainer>& /* thecomb */) const {return true;} + + + /** + * @brief Retrieves the decisionIds from the passing combinations and produce a new LegDecisionMap + **/ + void setDecisionIds(const ElementLinkVector<TrigCompositeUtils::DecisionContainer>& thecomb, LegDecisionsMap & passingCombinations) const; + + + /** + * @brief Print the Tool results stored in the passing combinations + **/ + + StatusCode printExecute(const LegDecisionsMap & passingCombinations) const; + + +// add here WriteHandkles of combinations + +private: + + HLT::Identifier m_decisionId; + + +}; + +#endif // DECISIONHANDLING_COMBOHYPOTOOLBASE_H diff --git a/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.cxx b/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.cxx index dfdc36f308fbff23e01f8a554174a025c5aee6cd..6ae343487d76f723c1f89c424c4cc76b9e478028 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.cxx @@ -6,124 +6,47 @@ using namespace TrigCompositeUtils; DeltaRRoIComboHypoTool::DeltaRRoIComboHypoTool(const std::string& type, - const std::string& name, - const IInterface* parent) - : IComboHypoTool( name ), - AthAlgTool( type, name, parent ) + const std::string& name, + const IInterface* parent) + : ComboHypoToolBase(type, name, parent) { } -DeltaRRoIComboHypoTool::~DeltaRRoIComboHypoTool(){} - StatusCode DeltaRRoIComboHypoTool::initialize() { ATH_MSG_DEBUG("DR threshold set to " << m_DRcut ); return StatusCode::SUCCESS; } -StatusCode DeltaRRoIComboHypoTool::finalize() { - return StatusCode::SUCCESS; -} -StatusCode DeltaRRoIComboHypoTool::decide(const LegDecisionsMap & IDCombMap, LegDecisionsMap & passingCombinations ) const +bool DeltaRRoIComboHypoTool::executeAlg(ElementLinkVector<TrigCompositeUtils::DecisionContainer>& combination) const { - size_t nLegs=IDCombMap.size(); - ATH_MSG_DEBUG( "Looking for "<< m_decisionId <<" in the map. Map contains "<<nLegs<<" legs"); - if (passingCombinations[ m_decisionId].size() >0){ - ATH_MSG_ERROR("Passing combinations have "<< passingCombinations[ m_decisionId].size()<<" elements: what to do?"); - return StatusCode::FAILURE; - } - - std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> leg_decisions;// vector of decisions per leg, to combine - // collect combinations from all the legs, searching both chain name and leg name - for (auto id: IDCombMap){ - // get the Element links from the chainID (from all the legs) - HLT::Identifier chainId=0; - if (TrigCompositeUtils::isLegId(id.first)) - chainId= TrigCompositeUtils::getIDFromLeg(id.first); - else - chainId=id.first; - if ( chainId != m_decisionId ) continue; - auto comb = id.second; - leg_decisions.push_back(comb); - } - - if (nLegs != leg_decisions.size()){ - ATH_MSG_ERROR("Expecting "<<nLegs<<" legs, but found "<< leg_decisions.size() <<" legs to combine"); - return StatusCode::FAILURE; - } - - ATH_MSG_DEBUG("Getting "<<leg_decisions.size()<<" legs to combine, for ID: "<< m_decisionId); - for (auto leg: leg_decisions){ - ATH_MSG_DEBUG("Leg --"); - for (auto dEL:leg) ATH_MSG_DEBUG(dEL.dataID() << " , " << dEL.index()); + //retrieve the rois + std::vector<ElementLink<TrigRoiDescriptorCollection>> selected_rois; + for (auto el: combination){ + auto dec= (*el); + auto roiLink = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( dec, initialRoIString() ).link; + selected_rois.push_back(roiLink); } + ATH_MSG_DEBUG("Selected RoIs: "<<selected_rois.size()); + auto roiLink1=selected_rois[0]; + auto roiLink2=selected_rois[1]; - // create the combinatios: - // If we have one leg, the combination is between the elements in that leg; - // if we have more leges, use recursive combinator - std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> combinations; - createCombinations( leg_decisions, combinations, nLegs, 2); - for (auto comb: combinations){ - ATH_MSG_DEBUG("Combination"); - for (auto dEL :comb){ - ATH_MSG_DEBUG(dEL.dataID() << " , " << dEL.index()); - } - } - + // calucalte DeltaR + float Dr = deltaR((*roiLink1)->eta(), (*roiLink2)->eta(), (*roiLink1)->phi(), (*roiLink2)->phi()); + ATH_MSG_DEBUG("Found two RoIs with eta/phi " << (*roiLink1)->eta() <<"/"<<(*roiLink1)->phi() <<" and "<< (*roiLink2)->eta()<<"/"<<(*roiLink2)->phi() <<" with Dr="<<Dr); - // do the actual algorithm: - // to add: protection when the two decisions are the same object - for (auto paircomb: combinations){ - std::vector<ElementLink<TrigRoiDescriptorCollection>> selected_rois; - for (auto el: paircomb){ - auto dec= (*el); - auto roiLink = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( dec, initialRoIString() ).link; - selected_rois.push_back(roiLink); - } - ATH_MSG_DEBUG("Selected RoIs: "<<selected_rois.size()); - - //retrieve the rois and calcualte the Dr - auto roiLink1=selected_rois[0]; - auto roiLink2=selected_rois[1]; - float Dr = deltaR((*roiLink1)->eta(), (*roiLink2)->eta(), (*roiLink1)->phi(), (*roiLink2)->phi()); - ATH_MSG_DEBUG("Found two RoIs with eta/phi " << (*roiLink1)->eta() <<"/"<<(*roiLink1)->phi() <<" and "<< (*roiLink2)->eta()<<"/"<<(*roiLink2)->phi() <<" with Dr="<<Dr); - if (Dr <= m_DRcut){ - ATH_MSG_DEBUG( " RoIs within DR<"<<m_DRcut<<". Insert elements for this combination: "); + // apply the cut + bool pass=true; + if (Dr > m_DRcut) pass=false; - for (auto dEL: paircomb){ - auto decision= (*dEL); - // get back the decID of this element - auto allDec = decisionIDs( decision ); - ATH_MSG_DEBUG( dEL.dataID() << " , " << dEL.index() <<" size ="<<allDec.size()); - for (auto id: allDec){ - if ((HLT::Identifier(id).name()).find(m_decisionId.name())!=std::string::npos){ - // we may have this element already stored, so there might be duplications - // add to both legID and chainID? - passingCombinations[id].push_back(dEL); - passingCombinations[ m_decisionId ].push_back(dEL); - } - } - } - } - - } + if (pass) + ATH_MSG_DEBUG( " RoIs within DR<"<<m_DRcut<<". This seleciton passed! "); - // remove duplicates? - - ATH_MSG_DEBUG("End of tool: Passing elments are: "); - for (auto id: passingCombinations){ - ATH_MSG_DEBUG("Id "<<HLT::Identifier(id.first)<<" with "<<id.second.size()<<" elements"); - for (auto dEL: id.second){ - ATH_MSG_DEBUG( dEL.dataID() << " , " << dEL.index()); - } - } - - return StatusCode::SUCCESS; + return pass; } - double DeltaRRoIComboHypoTool::deltaR(double eta1, double eta2, double phi1, double phi2) const { double dPhi=std::remainder( phi1 - phi2, 2*M_PI ); double dEta=std::fabs(eta1-eta2); diff --git a/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h b/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h index ce0fb512b3dff938b497d4cfb0e0b56a3c746b07..27fed3a23453026bb66281d172083d44fcf4c1d0 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h +++ b/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h @@ -9,27 +9,26 @@ #include "DecisionHandling/HLTIdentifier.h" #include "AthenaBaseComps/AthAlgTool.h" #include "DecisionHandling/TrigCompositeUtils.h" -#include "IComboHypoTool.h" +#include "ComboHypoToolBase.h" -class DeltaRRoIComboHypoTool: virtual public IComboHypoTool, public AthAlgTool { +class DeltaRRoIComboHypoTool: public ComboHypoToolBase { public: DeltaRRoIComboHypoTool(const std::string& type, const std::string& name, const IInterface* parent); - virtual ~DeltaRRoIComboHypoTool(); + + virtual ~DeltaRRoIComboHypoTool() {}; virtual StatusCode initialize() override; - virtual StatusCode finalize() override; - virtual StatusCode decide( const LegDecisionsMap & IDCombMap, LegDecisionsMap & passingCombinations ) const override; private: - - Gaudi::Property<float> m_DRcut{this, "DRcut", 0.1, "DR threshold" }; + + bool executeAlg(ElementLinkVector<TrigCompositeUtils::DecisionContainer>& thecomb) const override; double deltaR(double eta1, double eta2, double phi1, double phi2) const; - + Gaudi::Property<float> m_DRcut{this, "DRcut", 0.1, "DR threshold" }; diff --git a/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.cxx b/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.cxx deleted file mode 100644 index f202a8eacf69d1d091584db3238d6d2dd65ce72c..0000000000000000000000000000000000000000 --- a/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.cxx +++ /dev/null @@ -1,51 +0,0 @@ -#include "IComboHypoTool.h" - - -void IComboHypoTool::recursive_combine(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> &all, - std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & tocombine, - ElementLinkVector<TrigCompositeUtils::DecisionContainer> & local, u_int lindex) const -{ - - for (size_t leg =lindex; leg<all.size(); leg++){ - for (size_t i=0; i<all[leg].size(); i++){ - local.push_back(all[leg][i]); - recursive_combine(all, tocombine,local, leg+1); - local.pop_back(); - } - } - if (local.size() == all.size()) - tocombine.push_back(local); - - return; - -} - -void IComboHypoTool::createCombinations(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & v_combinations, - std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & tocombine, int nLegs, int nToGroup) const -{ - - if (nLegs ==1) { - auto combinations = v_combinations[0]; - std::vector<int> selector(combinations.size()); - // int nRoIsToCombine = 2;// use two RoIs, get this from theconfiguration? - fill(selector.begin(), selector.begin() + nToGroup, 1); - ElementLinkVector<TrigCompositeUtils::DecisionContainer> thecomb; - do { - for (u_int i = 0; i < combinations.size(); i++) { - if (selector[i]) { - thecomb.push_back(combinations[i]); - } - } - tocombine.push_back(thecomb); - thecomb.clear(); - } while (std::prev_permutation(selector.begin(), selector.end())); - } - - else { - ElementLinkVector<TrigCompositeUtils::DecisionContainer> local; - recursive_combine(v_combinations, tocombine, local, 0); - } - - - return; -} diff --git a/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.h b/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.h index 9895f1c1ddcff5ae14eb676c2bd5e6daecf14380..5299d7d7e1aa700379e9d28fdb58e41c93a6d095 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.h +++ b/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.h @@ -4,8 +4,7 @@ #ifndef DECISIONHANDLING_ICOMBOHYPOTOOL_H #define DECISIONHANDLING_ICOMBOHYPOTOOL_H 1 -#include "DecisionHandling/HLTIdentifier.h" -#include "DecisionHandling/TrigCompositeUtils.h" +#include "DecisionHandling/TrigCompositeUtils.h" #include "GaudiKernel/IAlgTool.h" @@ -24,49 +23,10 @@ class IComboHypoTool: virtual public ::IAlgTool { public: DeclareInterfaceID(IComboHypoTool, 1, 0); - - virtual ~IComboHypoTool() {}; - IComboHypoTool(const std::string& name) : m_decisionId( HLT::Identifier::fromToolName( name ) ) {} - - /** - * @brief retreives the decisions associated to this decId, make their combinations and apply the algorithm - @param[in] InputDecisions - @param[in] Cobminaiton map that lists all the decisions passing the multiplicity map of the ComboHypo - @param[out] Combination map that lists all the decisions passing the HypoTool algorithm - **/ - virtual StatusCode decide(const LegDecisionsMap & IDCombMap, LegDecisionsMap & passingCombinations ) const = 0; - - /** - * @brief retrieves this decision Id - **/ - virtual HLT::Identifier decisionId() const { return m_decisionId; } - - - protected: - - HLT::Identifier m_decisionId; - /** - * @brief creates combinations of decisions starting from the legs vector of pairs, given the number of legs and the number of elements to combine - @param[in] v_combinations: vector of legs (vector), each containing the corresponding decision pairs - @param[in] nLegs: number of legs to combine - @param[in] nToGroup: number of elements to group in a combination, in case one leg is used - @param[out] tocombine: vector of combinations (vectors) of decision pairs - **/ - void createCombinations(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & v_combinations, - std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & tocombine, int nLegs, int nToGroup) const; - - /** - * @brief recursively creates combinations of elements from differnt vectors - @param[in] all: initial vector of decision legs - @parma[in] local: temporary vector of combinations - @param[in] lindex: leg index - @param[out] tocombine: vector of combinations - **/ - void recursive_combine(const std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> &all, - std::vector<ElementLinkVector<TrigCompositeUtils::DecisionContainer>> & tocombine, - ElementLinkVector<TrigCompositeUtils::DecisionContainer> & local, u_int lindex) const; + virtual StatusCode decide( const LegDecisionsMap & IDCombMap, LegDecisionsMap & passingCombinations ) const = 0 ; + }; diff --git a/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx b/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx index 8c49fa320d5c2fd447c63e63679f0ae9864bb6df..e55e57d985d6d54d53b9d19b229ec93a69b2abc0 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx @@ -4,12 +4,14 @@ #include "../ComboHypo.h" #include "../InputMakerForRoI.h" #include "../DeltaRRoIComboHypoTool.h" +#include "../ComboHypoToolBase.h" DECLARE_COMPONENT( DumpDecisions ) DECLARE_COMPONENT( RoRSeqFilter ) DECLARE_COMPONENT( TriggerSummaryAlg ) DECLARE_COMPONENT( ComboHypo ) DECLARE_COMPONENT( InputMakerForRoI ) +DECLARE_COMPONENT( ComboHypoToolBase ) DECLARE_COMPONENT( DeltaRRoIComboHypoTool ) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py index c55e0e1ac1b9e75f976140a0b87bd89239dc0665..97c90a6a1abf6d741490b8619841874e2e432135 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py @@ -39,13 +39,13 @@ class ChainConfigurationBase(object): mySequence = RecoFragmentsPool.retrieve(mySequenceCfg, None) # the None will be used for flags in future return mySequence - def getStep(self, stepID, stepPartName, sequenceCfgArray): + def getStep(self, stepID, stepPartName, sequenceCfgArray, comboTools=[]): stepName = 'Step%d'%stepID + '_%d'%self.mult + stepPartName log.debug("Configuring step " + stepName) seqArray = [] for sequenceCfg in sequenceCfgArray: seqArray.append( RecoFragmentsPool.retrieve( sequenceCfg, None)) - return ChainStep(stepName, seqArray, [self.mult]) + return ChainStep(stepName, seqArray, [self.mult], comboToolConfs=comboTools) def buildChain(self, chainSteps): myChain = Chain(name = self.chainName, diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py index 6aa90b3a97f878943a89e654a2ca5262faccb5f0..f6380dae0c1d346a30496ac9a83f29bf1d60000a 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py @@ -84,6 +84,7 @@ def makeChainSteps(steps): stepNumber = '' log.verbose(" steps %s ", steps) stepName = "merged" + comboHypoTools = [] for step in steps: if step is None: continue @@ -108,9 +109,11 @@ def makeChainSteps(steps): stepSeq.append(seq) # set the multiplicity of all the legs stepMult.append(sum(step.multiplicity)) + comboHypoTools.extend(step.comboToolConfs) - theChainStep = ChainStep(stepName, stepSeq, stepMult) + comboHypoTools = list(set(comboHypoTools)) + theChainStep = ChainStep(stepName, Sequences=stepSeq, multiplicity=stepMult, comboToolConfs=comboHypoTools) log.debug("Merged step: \n %s", theChainStep) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py index 8f3c82401a1c9bfa762c0e6dca289b08c4fca8e4..577b0256e59200dd4d9f1327df64b1ee8b050d03 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py @@ -50,6 +50,8 @@ def setupMenu(): ChainProp(name='HLT_2mu6_10invm70_L1MU6', groups=SingleMuonGroup), ChainProp(name='HLT_mu10_lateMu_L1MU10', l1SeedThresholds=['FSNOSEED'], groups=SingleMuonGroup), + # this is for test only + ChainProp(name='HLT_2mu6_Dr_L12MU4', groups=MultiMuonGroup), # ATR-20049 ChainProp(name='HLT_mu6_mu4_L12MU4', l1SeedThresholds=['MU4']*2, groups=MultiMuonGroup), diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py index a5c82d5eb2d0d99ed9ce3a3efeb08fb46eb2f79f..b3d78c066b6a96ac7182ed339fa8ce0d237cb1c7 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py @@ -758,18 +758,23 @@ class ChainStep(object): self.name = name self.sequences=Sequences self.multiplicity = multiplicity + self.comboToolConfs=comboToolConfs self.isCombo=sum(multiplicity)>1 self.combo=None if self.isCombo: - self.makeCombo(Sequences, comboToolConfs ) - self.decisions = [] + self.makeCombo() - def makeCombo(self, Sequences, comboToolConfs=[]): - if len(Sequences)==0: + + def addCombHypoTools(self, tools): + self.comboToolConfs=tools + self.combo.addComboHypoToolConfs(self.comboToolConfs) + + def makeCombo(self): + if len(self.sequences)==0: return hashableMult = tuple(self.multiplicity) self.combo = RecoFragmentsPool.retrieve(createComboAlg, None, name=CFNaming.comboHypoName(self.name), multiplicity=hashableMult) - self.combo.addComboHypoToolConfs(comboToolConfs) + self.combo.addComboHypoToolConfs(self.comboToolConfs) def createComboHypoTools(self, chainName): if self.isCombo: @@ -782,7 +787,7 @@ class ChainStep(object): def __repr__(self): - return "--- ChainStep %s ---\n + isCombo = %d, multiplicity = %d \n + MenuSequences = %s"%(self.name, self.isCombo,sum(self.multiplicity), ' '.join(map(str, [seq.name for seq in self.sequences]) )) + return "--- ChainStep %s ---\n + isCombo = %d, multiplicity = %d \n + MenuSequences = %s \n + ComboHypoTools = %s"%(self.name, self.isCombo,sum(self.multiplicity), ' '.join(map(str, [seq.name for seq in self.sequences]) ), ' '.join(map(str, [tool for tool in self.comboToolConfs]) )) def createComboAlg(dummyFlags, name, multiplicity): diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py index d6a32a443552f13051b45bd941a8def4517bc5d6..a23e5cef356799be889027b88bdb9689b17c905a 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py @@ -184,7 +184,7 @@ MuonChainParts = { 'trigType' : ['mu'], 'etaRange' : ['0eta2550','0eta105'], 'threshold' : '', - 'extra' : ['noL1', 'Comb', 'fast', 'msonly','lateMu'], + 'extra' : ['noL1', 'Comb', 'fast', 'msonly','lateMu', "Dr"], 'IDinfo' : [], 'isoInfo' : ['ivar','ivarmedium'], 'invMassInfo' : ['10invm70'], diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py index 5b7a6b77cb060921a02b1b3f021705a38878a359..c8df09a5c5cabf9641197aedc6edb60cafb40855 100755 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py @@ -15,6 +15,13 @@ from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigu from TriggerMenuMT.HLTMenuConfig.Muon.MuonSequenceSetup import muFastSequence, muFastOvlpRmSequence, muCombSequence, muCombOvlpRmSequence, muEFMSSequence, muEFSASequence, muIsoSequence, muEFCBSequence, muEFSAFSSequence, muEFCBFSSequence, muEFIsoSequence, muEFCBInvMassSequence, efLateMuRoISequence, efLateMuSequence +# this must be moved to the HypoTool file: +def dimuDrComboHypoToolFromDict(chainDict): + from DecisionHandling.DecisionHandlingConf import DeltaRRoIComboHypoTool + name = chainDict['chainName'] + tool= DeltaRRoIComboHypoTool(name) + tool.DRcut=3. + return tool #-------------------------------------------------------- @@ -121,7 +128,8 @@ class MuonChainConfiguration(ChainConfigurationBase): "msonly":[['getmuFast', 'getmuMSEmpty'], ['getmuEFMS']], "ivarmedium":[['getmuFast', 'getmuComb'], ['getmuEFSA', 'getmuEFCB', 'getmuEFIso']], "invM":[[],['getmuInvM']], - "lateMu":[[],['getLateMuRoI','getLateMu']] + "lateMu":[[],['getLateMuRoI','getLateMu']], + "Dr": [['getmuFastDr', 'getmuCombDr']] } return stepDictionary @@ -204,17 +212,18 @@ class MuonChainConfiguration(ChainConfigurationBase): def getmuMSEmptyAll(self, stepID): return self.getStep(stepID,'muMS_empty',[]) - #-------------------- + #-------------------- def getmuMSEmpty(self): return self.getmuMSEmptyAll(2) - #-------------------- + #-------------------- def getmuFastEmpty(self): return self.getStep(1,'muFast_empty',[]) - + #-------------------- def getEFCBEmpty(self): return self.getStep(6,'EFCBEmpty',[]) + #-------------------- def getmuInvM(self): return self.getStep(5,'muInvM',[muEFCBInvMSequenceCfg]) @@ -226,3 +235,18 @@ class MuonChainConfiguration(ChainConfigurationBase): #-------------------- def getLateMu(self): return self.getStep(2,'muEFLate',[muEFLateSequenceCfg]) + + #-------------------- + # FP: + # Here example of how to create steps with ComboHypoTools + # tmp: the problem is that we create a differnt Alg, insetad of reusing the same ComboAlg + # need to be fixed! + def getmuCombDr(self): + step=self.getStep(2, 'muCombDr', sequenceCfgArray=[muCombSequenceCfg]) + step.addCombHypoTools([dimuDrComboHypoToolFromDict] ) + return step + + def getmuFastDr(self): + step=self.getStep(1,"mufastDr", [muFastSequenceCfg] ) + step.addCombHypoTools([dimuDrComboHypoToolFromDict] ) + return step