diff --git a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMufastHypoAlg.cxx b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMufastHypoAlg.cxx index b76a04d1788087882d799b0391eac5df3c957d97..3be67843f23e973cc7a8d573cbd055fb88ee9edb 100755 --- a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMufastHypoAlg.cxx +++ b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMufastHypoAlg.cxx @@ -76,7 +76,9 @@ StatusCode TrigMufastHypoAlg::execute( const EventContext& context ) const size_t counter=0; for ( auto previousDecision: *previousDecisionsHandle ) { //get RoI - auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto roiInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( previousDecision, "initialRoI" ); + auto roiEL = roiInfo.link; + // auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); ATH_CHECK( roiEL.isValid() ); const TrigRoiDescriptor* roi = *roiEL; diff --git a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFCombinerHypoAlg.cxx b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFCombinerHypoAlg.cxx index 6deee0ce7584e916bfe5dce1896bae4c39b9e1ad..d05c606b61d62826d7f189d13002ecbb92b6abb7 100755 --- a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFCombinerHypoAlg.cxx +++ b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFCombinerHypoAlg.cxx @@ -77,7 +77,9 @@ StatusCode TrigMuonEFCombinerHypoAlg::execute( const EventContext& context ) con // loop over previous decisions for ( auto previousDecision: *previousDecisionsHandle ) { // get RoIs - auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto roiInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( previousDecision, "initialRoI" ); + auto roiEL = roiInfo.link; + // auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); ATH_CHECK( roiEL.isValid() ); const TrigRoiDescriptor* roi = *roiEL; diff --git a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFMSonlyHypoAlg.cxx b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFMSonlyHypoAlg.cxx index c301fbfa3f472c3d63d8eb17ddd917bf0f36dcb4..1c9ddf33e41a1cb11d6de4d081ecb50774036f72 100755 --- a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFMSonlyHypoAlg.cxx +++ b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFMSonlyHypoAlg.cxx @@ -77,7 +77,9 @@ StatusCode TrigMuonEFMSonlyHypoAlg::execute( const EventContext& context ) const // loop over previous decisions for ( auto previousDecision: *previousDecisionsHandle ) { // get RoIs - auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto roiInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( previousDecision, "initialRoI" ); + auto roiEL = roiInfo.link; + //auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); ATH_CHECK( roiEL.isValid() ); const TrigRoiDescriptor* roi = *roiEL; diff --git a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFTrackIsolationHypoAlg.cxx b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFTrackIsolationHypoAlg.cxx index f3826e60d652084cbd3da065d67563566e1bdb14..d4c867e04959f83367392632a45a6c11de61217a 100755 --- a/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFTrackIsolationHypoAlg.cxx +++ b/Trigger/TrigHypothesis/TrigMuonHypo/src/TrigMuonEFTrackIsolationHypoAlg.cxx @@ -73,7 +73,9 @@ StatusCode TrigMuonEFTrackIsolationHypoAlg::execute( const EventContext& context size_t counter = 0; for ( auto previousDecision: *previousDecisionsHandle ) { // get RoIs - auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>("roi"); + auto roiInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( previousDecision, "initialRoI" ); + auto roiEL = roiInfo.link; + // auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>("roi"); ATH_CHECK( roiEL.isValid() ); const TrigRoiDescriptor *roi = *roiEL; diff --git a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h index 7c5ce693f4f061d0005e5f68cc32201194d7d26a..10d56a39c905e6f62cdd9cf5dd687950d68b8466 100644 --- a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h +++ b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h @@ -10,6 +10,7 @@ #include "AthenaBaseComps/AthReentrantAlgorithm.h" #include "StoreGate/ReadHandleKeyArray.h" + class InputMakerBase : public ::AthReentrantAlgorithm { /** * @class InputMakerBase @@ -26,22 +27,45 @@ This is a base class for HLT InputMakers to reduce boilerplate and enforce the c /// execute to be implemented in derived clas virtual StatusCode execute(const EventContext&) const override = 0; virtual StatusCode finalize() override = 0; - virtual StatusCode initialize() override = 0; + virtual StatusCode initialize() override = 0; + protected: /// methods for derived classes to access handles of the base class input and output decisions; other read/write handles may be implemented by derived classes const SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionInputs() const; + /// methods for derived classes to access handles of the base class input and output decisions; other read/write handles may be implemented by derived classes const SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionOutputs() const; - // helper methods for derived classes to reduce boiler plate code + + // name of link to the RoI + StringProperty m_roisLink { this, "RoIsLink", "initialRoI", "Name of EL to RoI object linked to the decision" }; + + // helper methods for derived classes to reduce boiler plate code // + ///////////////////////////////////////////////////////////////////// + /// provides debug printout of the output of the algorithm StatusCode debugPrintOut(const EventContext& context, const std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> >& outputHandles) const; - /// does the standard handling of input decisions: read from handles with all the checks, create corresponding output handles and link them, return outputHandles + + /// does the standard handling of input decisions: read from handles with all the checks, create corresponding output handles and link them, copies links and return outputHandles StatusCode decisionInputToOutput(const EventContext& context, std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > & outputHandles) const; + + /// does the standard handling of input decisions: read from handles with all the checks, create merged output handles and link them, copies links and return outputHandles + StatusCode decisionInputToMergedOutput(const EventContext& context, std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > & outputHandles) const; + + /// counts valid input decisions + size_t countInputHandles( const EventContext& context ) const; + private: + /// input decisions, will be implicit (renounced). SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_inputs { this, "InputMakerInputDecisions", {}, "Input Decisions (implicit)" }; + /// output decisions SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_outputs { this, "InputMakerOutputDecisions", {}, "Ouput Decisions" }; + + // setting strategy for output creation: merged means one decision per ROI + Gaudi::Property<bool> m_mergeOutputs { this, "mergeOutputs", true, "true=outputs are merged, false=one output per input" }; + + }; diff --git a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h index c78f3be5a1193b14b2f8f79edd2ea02f7d56ee58..f72f8f21b16729e9981b021606b7afc0a7101ac9 100644 --- a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h +++ b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h @@ -87,6 +87,20 @@ Decision* newDecisionIn( DecisionContainer* dc, const Decision* dOld, const std: **/ void addDecisionID( DecisionID id, Decision* d); + /** + * @brief Appends the decision IDs of src to the dest decision object + * @warning Performing merging of IDs and solving the duples (via set) + * This helps when making copies of Decision obejcts + **/ + void insertDecisionIDs( const Decision* src, Decision* dest ); + + /** + * @brief Make unique list of decision IDs of dest Decision object + * @warning Use vector->set->vector + * This helps solving multiple inserts of the Decision obejcts + **/ + void uniqueDecisionIDs( Decision* dest); + /** * @brief Extracts DecisionIDs stored in the Decision object @@ -133,7 +147,7 @@ Decision* newDecisionIn( DecisionContainer* dc, const Decision* dOld, const std: /** * @brief returns link to previous decision object **/ - ElementLink<DecisionContainer> linkToPrevious(const Decision*); + ElementLinkVector<DecisionContainer> getLinkToPrevious(const Decision*); /** * @brief copy all links from src to dest TC objects @@ -141,8 +155,8 @@ Decision* newDecisionIn( DecisionContainer* dc, const Decision* dOld, const std: * @ret true if success **/ bool copyLinks(const Decision* src, Decision* dest); - - /** + + /** * @brief traverses TC links for another TC fufilling the prerequisite specified by the filter * @return matching TC or nullptr **/ @@ -196,8 +210,8 @@ Decision* newDecisionIn( DecisionContainer* dc, const Decision* dOld, const std: }; /** - * @brief search back the TC links for the object of type T linked to the one of TC - * @arg start the TC where from where the link back is to be looked for + * @brief search back the TC links for the object of type T linked to the one of TC (recursively) + * @arg start the TC from where the link back is to be looked for * @arg linkName the name with which the Link was added to the source TC * @return pair of link and TC with which it was associated, */ @@ -205,8 +219,21 @@ Decision* newDecisionIn( DecisionContainer* dc, const Decision* dOld, const std: LinkInfo<T> findLink(const xAOD::TrigComposite* start, const std::string& linkName) { auto source = find(start, HasObject(linkName) ); - if ( not source ) + // + if ( not source ){ + auto seeds = getLinkToPrevious(start); + // std::cout<<"Looking for seeds: found " <<seeds.size()<<std::endl; + for (auto seed: seeds){ + const xAOD::TrigComposite* dec = *seed;//deference + LinkInfo<T> link= findLink<T>( dec, linkName ); + // return the first found + if (link.isValid()) return link; + } return LinkInfo<T>(); // invalid link + } + + //std::cout<<"Found source for "<<linkName<<std::endl; + return LinkInfo<T>( source, source->objectLink<T>( linkName ) ); } diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx index 3627d105deada3a356aaa43b695f2e4b4adf65a8..02488db94d84359d669f5d1ac3bc075fe5ea2606 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx @@ -87,28 +87,17 @@ StatusCode ComboHypo::copyDecisions( const DecisionIDContainer& passing, const E std::set_intersection( inputDecisionIDs.begin(), inputDecisionIDs.end(), passing.begin(), passing.end(), std::inserter( common, common.end() ) ); + Decision* newDec = newDecisionIn( outDecisions ); - linkToPrevious( newDec, inputHandle.key(), i ); + linkToPrevious( newDec, inputHandle.key(), i ); + ATH_MSG_DEBUG("New decision has "<< (TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( newDec, "initialRoI")).isValid() + <<" valid initialRoI and "<< TrigCompositeUtils::getLinkToPrevious(newDec).size() <<" previous decisions"); + for ( auto id: common ) { addDecisionID( id, newDec ); } - // add RoI: at least one RoI link must exist - if ( inputDecision->hasObjectLink("roi" ) ){ - auto roiEL = inputDecision->objectLink<TrigRoiDescriptorCollection>( "roi" ); - CHECK( roiEL.isValid() ); - newDec->setObjectLink( "roi", roiEL ); - } - else if ( inputDecision->hasObjectLink("initialRoI" ) ){ - auto roiEL = inputDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); - CHECK( roiEL.isValid() ); - newDec->setObjectLink( "initialRoI", roiEL ); - } - else { - ATH_MSG_ERROR( "Input decision " << i <<" from "<<inputHandle.key() <<" does not link any RoI"); - return StatusCode::FAILURE; - } - // add View + // add View? if ( inputDecision->hasObjectLink( "view" ) ) { auto viewEL = inputDecision->objectLink< ViewContainer >( "view" ); CHECK( viewEL.isValid() ); diff --git a/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx b/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx index c36fc5a9658909c4cb83558d9ba34a81720a913d..34e8daff94ef8b8512f7772a1db49870f88b440e 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx @@ -6,6 +6,9 @@ #include "DecisionHandling/HLTIdentifier.h" #include "TrigSteeringEvent/TrigRoiDescriptorCollection.h" +using namespace TrigCompositeUtils; + + InputMakerBase::InputMakerBase( const std::string& name, ISvcLocator* pSvcLocator ) : ::AthReentrantAlgorithm( name, pSvcLocator ) {} @@ -21,6 +24,7 @@ const SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer>& InputMaker StatusCode InputMakerBase::sysInitialize() { CHECK( AthReentrantAlgorithm::sysInitialize() ); // initialise base class + ATH_MSG_DEBUG("mergeOutputs is "<<m_mergeOutputs); CHECK( m_inputs.initialize() ); renounceArray(m_inputs); // make inputs implicit, i.e. not required by scheduler ATH_MSG_DEBUG("Will consume implicit decisions:" ); @@ -36,22 +40,14 @@ StatusCode InputMakerBase::sysInitialize() { } +// For each input Decision in the input container, create an output Decision in the corresponding output container and link them. StatusCode InputMakerBase::decisionInputToOutput(const EventContext& context, std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > & outputHandles) const{ - outputHandles = decisionOutputs().makeHandles(context); + if (!m_mergeOutputs) ATH_MSG_DEBUG("Creating one output per input"); + else ATH_MSG_DEBUG("Creating one merged output per RoI"); - // check inputs - size_t validInput=0; - for ( auto inputKey: decisionInputs() ) { - auto inputHandle = SG::makeHandle( inputKey, context ); - ATH_MSG_DEBUG(" "<<inputKey.key()<<(inputHandle.isValid()? " is valid": " is not valid" ) ); - if (inputHandle.isValid()) validInput++; - } - ATH_MSG_DEBUG( "number of implicit ReadHandles is " << decisionInputs().size() <<", "<< validInput<<" are valid" ); - - // Input is array of input decision containers - // Loop over them. For each input decision container, create an output decision container - // For each input Decision in the input container, create and output Decision in the corresponding output container and link them. + outputHandles = decisionOutputs().makeHandles(context); + //size_t tot_inputs = countInputHandles( context ); size_t outputIndex = 0; for ( auto inputKey: decisionInputs() ) { auto inputHandle = SG::makeHandle( inputKey, context ); @@ -65,34 +61,62 @@ StatusCode InputMakerBase::decisionInputToOutput(const EventContext& context, st outputIndex++; continue; } - ATH_MSG_DEBUG( "Got input "<< inputKey.key()<<" with " << inputHandle->size() << " elements" ); + ATH_MSG_DEBUG( "Running on input "<< inputKey.key()<<" with " << inputHandle->size() << " elements" ); + // create the output container TrigCompositeUtils::createAndStore(outputHandles[outputIndex]); auto outDecisions = outputHandles[outputIndex].ptr(); - // loop over input decisions retrieved from this input handle + //map all RoIs that are stored in this input container + std::vector <ElementLink<TrigRoiDescriptorCollection> > RoIsFromDecision; + + // loop over decisions retrieved from this input size_t input_counter =0; - for ( auto inpDecision : *inputHandle){ - // create new decision for each input - TrigCompositeUtils::Decision* newDec = TrigCompositeUtils::newDecisionIn( outDecisions, inpDecision, "", context ); - { - //copy decisions ID - TrigCompositeUtils::DecisionIDContainer objDecisions; - TrigCompositeUtils::decisionIDs( inpDecision, objDecisions ); - for ( const HLT::Identifier& id: objDecisions ){ - TrigCompositeUtils::addDecisionID( id, newDec ); - } + size_t output_counter =0; + + for ( auto decision : *inputHandle){ + ATH_MSG_DEBUG( "Input Decision "<<input_counter <<" has " <<TrigCompositeUtils::getLinkToPrevious(decision).size()<<" previous links"); + TrigCompositeUtils::Decision* newDec; + bool addDecision=false; + int roi_counter=0; + if (m_mergeOutputs){ + auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( decision, m_roisLink.value()); + CHECK( roiELInfo.isValid() ); + auto roiEL = roiELInfo.link; + auto roiIt=find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); + addDecision = (roiIt == RoIsFromDecision.end()); + if (addDecision) { + RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used + const TrigRoiDescriptor* roi = *roiEL; + ATH_MSG_DEBUG( "Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); + roi_counter = roiIt-RoIsFromDecision.begin(); + } + } else + addDecision=true; + + if ( addDecision ){ + newDec = TrigCompositeUtils::newDecisionIn( outDecisions ); + output_counter++; + } + else{ + newDec = outDecisions[outputIndex][roi_counter]; } + + TrigCompositeUtils::linkToPrevious( newDec, inputKey.key(), input_counter ); + TrigCompositeUtils::insertDecisionIDs( decision, newDec ); + ATH_MSG_DEBUG("New decision has "<< (TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( newDec, m_roisLink.value())).isValid() <<" valid "<<m_roisLink.value() <<" and "<< TrigCompositeUtils::getLinkToPrevious(newDec).size() <<" previous decisions"); input_counter++; } // loop over input decisions - ATH_MSG_DEBUG( "Recorded output key " << decisionOutputs()[ outputIndex ].key() <<" of size "<<outDecisions->size() <<" at index "<< outputIndex); + ATH_MSG_DEBUG( "Filled output key " << decisionOutputs()[ outputIndex ].key() <<" of size "<<outDecisions->size() <<" at index "<< outputIndex); outputIndex++; } // end of first loop over input keys return StatusCode::SUCCESS; } + + StatusCode InputMakerBase::debugPrintOut(const EventContext& context, const std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> >& outputHandles) const{ size_t validInput=0; for ( auto inputKey: decisionInputs() ) { @@ -125,3 +149,20 @@ StatusCode InputMakerBase::debugPrintOut(const EventContext& context, const std: } return StatusCode::SUCCESS; } + + + +size_t InputMakerBase::countInputHandles( const EventContext& context ) const { + size_t validInputCount=0; + for ( auto &inputKey: decisionInputs() ) { + auto inputHandle = SG::makeHandle( inputKey, context ); + ATH_MSG_DEBUG(" "<<inputKey.key()<<(inputHandle.isValid()? " is valid": " is not valid" ) ); + if (inputHandle.isValid()) validInputCount++; + } + ATH_MSG_DEBUG( "number of implicit ReadHandles is " << decisionInputs().size() <<", "<< validInputCount<<" are valid" ); + return validInputCount; +} + + + + diff --git a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx index b116703641bbbc165852500111ca7c3dbae898b0..2b4e32176d6405021bef99ebc593558704812158 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx @@ -57,24 +57,27 @@ StatusCode InputMakerForRoI::execute( const EventContext& context ) const { ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); // loop over output decisions in container of outputHandle, follow link to inputDecision for ( auto outputDecision : *outputHandle){ - ElementLink<DecisionContainer> inputLink = linkToPrevious(outputDecision); - const Decision* inputDecision = *inputLink; - auto roiEL = inputDecision->objectLink<TrigRoiDescriptorCollection>(m_linkName.value() ); //"initialRoI" - ATH_CHECK( roiEL.isValid() ); + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + for (auto input: inputLinks){ + const Decision* inputDecision = *input; + auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); + auto roiEL = roiELInfo.link; + ATH_CHECK( roiEL.isValid() ); - // avoid adding the same feature multiple times: check if not in container, if not add it - if ( find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL) - == RoIsFromDecision.end() ){ - RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used - const TrigRoiDescriptor* roi = *roiEL; - ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); - //make a new one: - TrigRoiDescriptor* newroi= new TrigRoiDescriptor(*roi); //use copy constructor - oneRoIColl->push_back(newroi); - ATH_MSG_DEBUG("Added RoI:" <<*newroi<<" FS="<<newroi->isFullscan()); - } + // avoid adding the same feature multiple times: check if not in container, if not add it + if ( find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL) + == RoIsFromDecision.end() ){ + RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used + const TrigRoiDescriptor* roi = *roiEL; + ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); + //make a new one: + TrigRoiDescriptor* newroi= new TrigRoiDescriptor(*roi); //use copy constructor + oneRoIColl->push_back(newroi); + ATH_MSG_DEBUG("Added RoI:" <<*newroi<<" FS="<<newroi->isFullscan()); + } + } // loop over previous input links } // loop over decisions - } // loop over input keys + } // loop over output keys // Finally, record output @@ -83,7 +86,7 @@ StatusCode InputMakerForRoI::execute( const EventContext& context ) const { ATH_CHECK( roi_outputHandle.record(std::move(oneRoIColl)) ); // call base class helper method to print some debug messages summarising the content of the outputHandles. - CHECK( debugPrintOut(context, outputHandles) ); + ATH_CHECK( debugPrintOut(context, outputHandles) ); return StatusCode::SUCCESS; } diff --git a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h index 0f015a07614229406e243ff30bbbfbd95ad724fd..a18bd505d6e84892d40e28b51cbc85a511252cd2 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h +++ b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h @@ -30,14 +30,9 @@ private: InputMakerForRoI(); - // Use this to customise the example for a different input feature - typedef TrigRoiDescriptor FeatureOBJ; - typedef TrigRoiDescriptorCollection FeatureContainer; - SG::WriteHandleKey<TrigRoiDescriptorCollection> m_RoIs {this,"RoIs", "Unspecified", "Nam eof the RoIs extracted from the decisions"}; - - StringProperty m_linkName {this, "LinkName", "initialRoI", "name of the link to the features in the decision, e.g. 'feature', 'initialRoI'"}; - + // want to try also const? + //SG::WriteHandleKey< ConstDataVector<TrigRoiDescriptorCollection> > m_RoIs{ this, "RoIs", "Unspecified", "Name of the RoIs extracted from the decisions" }; }; diff --git a/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx b/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx index 2fd9a93e8dac98bc85cb80fc0a60e0289e5ac5ad..cfffdd294b14595d45e7f00c80736dc1f0d70dea 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx @@ -89,6 +89,21 @@ namespace TrigCompositeUtils { return readWriteAccessor( *d ); } + void insertDecisionIDs( const Decision* src, Decision* dest ){ + DecisionIDContainer ids; + decisionIDs( src, ids ); + decisionIDs( dest, ids ); + decisionIDs( dest ).clear(); + decisionIDs( dest ).insert( decisionIDs(dest).end(), ids.begin(), ids.end() ); + } + + void uniqueDecisionIDs( Decision* dest){ + DecisionIDContainer ids; + decisionIDs( dest, ids ); + decisionIDs( dest ).clear(); + decisionIDs( dest ).insert( decisionIDs(dest).end(), ids.begin(), ids.end() ); + } + bool allFailed( const Decision* d ) { const std::vector<int>& decisions = readOnlyAccessor( *d ); return decisions.empty(); @@ -107,15 +122,30 @@ namespace TrigCompositeUtils { } void linkToPrevious( Decision* d, const std::string& previousCollectionKey, size_t previousIndex ) { - d->setObjectLink( "seed", ElementLink<DecisionContainer>( previousCollectionKey, previousIndex ) ); + ElementLinkVector<DecisionContainer> seeds; + ElementLink<DecisionContainer> new_seed= ElementLink<DecisionContainer>( previousCollectionKey, previousIndex ); + // do we need this link to self link? + if ( (*new_seed)->hasObjectLink("self" ) ) + seeds.push_back( (*new_seed)->objectLink<DecisionContainer>("self")); // make use of self-link + else + seeds.push_back(ElementLink<DecisionContainer>( previousCollectionKey, previousIndex )); + + if (hasLinkToPrevious(d) ){ + ElementLinkVector<DecisionContainer> oldseeds = d->objectCollectionLinks<DecisionContainer>( "seed" ); + seeds.reserve( seeds.size() + oldseeds.size() ); + std::move( oldseeds.begin(), oldseeds.end(), std::back_inserter( seeds ) ); + } + + d->addObjectCollectionLinks("seed", seeds); + } bool hasLinkToPrevious( const Decision* d ) { return d->hasObjectLink( "seed" ); } - ElementLink<DecisionContainer> linkToPrevious( const Decision* d ) { - return d->objectLink<DecisionContainer>( "seed" ); + ElementLinkVector <DecisionContainer> getLinkToPrevious( const Decision* d ) { + return d->objectCollectionLinks<DecisionContainer>( "seed" ); } @@ -123,7 +153,8 @@ namespace TrigCompositeUtils { return dest->copyAllLinksFrom(src); } - + + const xAOD::TrigComposite* find( const xAOD::TrigComposite* start, const std::function<bool( const xAOD::TrigComposite* )>& filter ) { if ( filter( start ) ) return start; diff --git a/Trigger/TrigSteer/L1Decoder/src/JRoIsUnpackingTool.cxx b/Trigger/TrigSteer/L1Decoder/src/JRoIsUnpackingTool.cxx index 9ea3c5c422ca01dd2cc39d00d4720b2c8bab976f..0fc1f102fedf8da4bbbc872bdc5d19084272e3b6 100644 --- a/Trigger/TrigSteer/L1Decoder/src/JRoIsUnpackingTool.cxx +++ b/Trigger/TrigSteer/L1Decoder/src/JRoIsUnpackingTool.cxx @@ -105,14 +105,9 @@ StatusCode JRoIsUnpackingTool::unpack( const EventContext& ctx, } } - TrigCompositeUtils::DecisionIDContainer uniqueDecisions; // this is set - std::vector<int>& storedIDs = TrigCompositeUtils::decisionIDs( decision ); - TrigCompositeUtils::decisionIDs( decision, uniqueDecisions ); // copy to set -> unique - storedIDs.clear(); - storedIDs.insert( storedIDs.end(), uniqueDecisions.begin(), uniqueDecisions.end() ); - //copy back - + TrigCompositeUtils::uniqueDecisionIDs( decision); + if ( msgLvl(MSG::DEBUG) ) { for ( auto roi: *trigRoIs ) { diff --git a/Trigger/TrigSteer/L1Decoder/test/test_l1decoder.sh b/Trigger/TrigSteer/L1Decoder/test/test_l1decoder.sh index bad6514e2009c2c7e2b28a8a3dd511316b84bc48..0baa8ad104982b6409cbfc9f2cf58c69a94d3124 100755 --- a/Trigger/TrigSteer/L1Decoder/test/test_l1decoder.sh +++ b/Trigger/TrigSteer/L1Decoder/test/test_l1decoder.sh @@ -1,5 +1,6 @@ #!/bin/sh # art-type: build # art-ci: master +# art-include: master/Athena athena --threads=1 --skipEvents=5 --evtMax=20 --filesInput="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/TrigP1Test/data17_13TeV.00327265.physics_EnhancedBias.merge.RAW._lb0100._SFO-1._0001.1" L1Decoder/testL1Decoder.py diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx index 6b9f57f656147e8895f6f02394f7c8299b4b715a..e4c97ab6141cfc20d83d6abfd31af51f17683308 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx @@ -9,8 +9,8 @@ #include "AthViews/ViewHelper.h" #include "AthViews/View.h" #include "DecisionHandling/TrigCompositeUtils.h" -#include "DecisionHandling/HLTIdentifier.h" +using namespace TrigCompositeUtils; EventViewCreatorAlgorithm::EventViewCreatorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ) : InputMakerBase( name, pSvcLocator ) {} @@ -25,99 +25,83 @@ StatusCode EventViewCreatorAlgorithm::initialize() { return StatusCode::SUCCESS; } -StatusCode EventViewCreatorAlgorithm::execute( const EventContext& context ) const { - auto outputHandles = decisionOutputs().makeHandles( context ); - // make and store the views + +StatusCode EventViewCreatorAlgorithm::execute( const EventContext& context ) const { + + // create the output decisions, similar to inputs (copy basic links) + std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > outputHandles; + ATH_CHECK (decisionInputToOutput(context, outputHandles)); + + // make the views auto viewsHandle = SG::makeHandle( m_viewsKey ); auto viewVector1 = std::make_unique< ViewContainer >(); ATH_CHECK( viewsHandle.record( std::move( viewVector1 ) ) ); auto viewVector = viewsHandle.ptr(); - + + + + // auto viewVector = std::make_unique< ViewContainer >(); auto contexts = std::vector<EventContext>( ); unsigned int viewCounter = 0; unsigned int conditionsRun = context.getExtension<Atlas::ExtendedEventContext>().conditionsRun(); - // const TrigRoiDescriptor* previousRoI = 0; - // mapping RoI with index of the View in the vector - // This is used to link the same view to differnt decisions that come from the same RoI - std::map <const TrigRoiDescriptor*, int> viewMap; - std::map <const TrigRoiDescriptor*, int>::iterator itViewMap; - int outputIndex = -1; - // Loop over all input containers, which are of course TrigComposites, and request their features - // this is the same as InputMaker, apart from the view creation. The loop can be splitted in two loops, to have one common part - for ( auto inputKey: decisionInputs() ) { - outputIndex++; - auto inputHandle = SG::makeHandle( inputKey, context ); - if( not inputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from input " << inputKey.key() ); - continue; - } - if( inputHandle->size() == 0 ) { // input filtered out - ATH_MSG_DEBUG( "Got no decisions from input " << inputKey.key() ); + //map all RoIs that are stored + std::vector <ElementLink<TrigRoiDescriptorCollection> > RoIsFromDecision; + + // loop over decisions + for (auto outputHandle: outputHandles) { + if( not outputHandle.isValid() ) { + ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); continue; } - ATH_MSG_DEBUG( "Got input " << inputKey.key() << " with " << inputHandle->size() << " elements" ); - - // prepare output decisions - TrigCompositeUtils::createAndStore(outputHandles[outputIndex]); - TrigCompositeUtils::DecisionContainer* outputDecisions = outputHandles[outputIndex].ptr(); - - const TrigRoiDescriptor* prevRoIDescriptor = nullptr; - int inputCounter = -1; - for ( auto inputDecision: *inputHandle ) { - inputCounter++; - // pull RoI descriptor - TrigCompositeUtils::LinkInfo<TrigRoiDescriptorCollection> roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>(inputDecision, m_roisLink ); - ATH_CHECK( roiELInfo.isValid() ); - // associate this RoI to output decisions - auto roiDescriptor = *roiELInfo.link; - ATH_MSG_DEBUG( "Placing TrigRoiDescriptor " << *roiDescriptor ); - - TrigCompositeUtils::Decision* newDecision = nullptr; - if ( prevRoIDescriptor != roiDescriptor ) { - //make one TC decision output per input and connect to previous - newDecision = TrigCompositeUtils::newDecisionIn( outputDecisions, name() ); - TrigCompositeUtils::linkToPrevious( newDecision, inputKey.key(), inputCounter ); - insertDecisions( inputDecision, newDecision ); - newDecision->setObjectLink( "initialRoI", roiELInfo.link ); - prevRoIDescriptor = roiDescriptor; - } else { - newDecision = outputDecisions->back(); - newDecision->setObjectLink( "seedEnd", ElementLink<TrigCompositeUtils::DecisionContainer>( inputHandle.key(), inputCounter ) ); - insertDecisions( inputDecision, newDecision ); - ATH_MSG_DEBUG("No need to create another output decision object, just adding decision IDs"); - } - - // search for existing view - itViewMap = viewMap.find(roiDescriptor); - if ( itViewMap != viewMap.end() ) { - int iview = itViewMap->second; - newDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), iview ) ); //adding view to TC - ATH_MSG_DEBUG( "Adding already mapped view " << iview << " in ViewVector , to new decision"); - // need to check if this View has parent views? can we have more than one parent views? - } else { - - ATH_MSG_DEBUG( "Positive decisions on RoI, preparing view" ); - - // make the view - ATH_MSG_DEBUG( "Making the View" ); - auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view - viewVector->push_back( newView ); - contexts.emplace_back( context ); - contexts.back().setExtension( Atlas::ExtendedEventContext( viewVector->back(), conditionsRun ) ); - - // link decision to this view - newDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC - viewMap[roiDescriptor]=viewVector->size()-1; - ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); - - ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); - ATH_CHECK( placeRoIInView( roiDescriptor, viewVector->back(), contexts.back() ) ); - } + + if( outputHandle->size() == 0){ // input filtered out + ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty. Is this expected?"); + return StatusCode::FAILURE; } - - ATH_MSG_DEBUG( "Recorded output key " << decisionOutputs()[ outputIndex ].key() <<" of size "<< outputDecisions->size() <<" at index "<< outputIndex); - } + ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); + // loop over output decisions in container of outputHandle, follow link to inputDecision + for ( auto outputDecision : *outputHandle){ + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + // loop over input links as predecessors + for (auto input: inputLinks){ + const Decision* inputDecision = *input; + // find the RoI + auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); + auto roiEL = roiELInfo.link; + ATH_CHECK( roiEL.isValid() ); + // check if already found + auto roiIt=find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); + if ( roiIt == RoIsFromDecision.end() ){ + RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used + const TrigRoiDescriptor* roi = *roiEL; + ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); + ATH_MSG_DEBUG( "Positive decisions on RoI, preparing view" ); + + // make the view + ATH_MSG_DEBUG( "Making the View" ); + auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view + viewVector->push_back( newView ); + contexts.emplace_back( context ); + contexts.back().setExtension( Atlas::ExtendedEventContext( viewVector->back(), conditionsRun ) ); + + // link decision to this view + outputDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC + ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); + ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); + ATH_CHECK( placeRoIInView( roi, viewVector->back(), contexts.back() ) ); + } + else { + int iview = roiIt-RoIsFromDecision.begin(); + outputDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), iview ) ); //adding view to TC + ATH_MSG_DEBUG( "Adding already mapped view " << iview << " in ViewVector , to new decision"); + } + }// loop over previous inputs + } // loop over decisions + }// loop over output keys + + + // launch view execution ATH_MSG_DEBUG( "Launching execution in " << viewVector->size() << " views" ); ATH_CHECK( ViewHelper::ScheduleViews( viewVector, // Vector containing views @@ -126,65 +110,15 @@ StatusCode EventViewCreatorAlgorithm::execute( const EventContext& context ) con m_scheduler.get() ) ); // report number of views, stored already when container was created + // auto viewsHandle = SG::makeHandle( m_viewsKey ); + // ATH_CHECK( viewsHandle.record( std::move( viewVector ) ) ); ATH_MSG_DEBUG( "Store "<< viewsHandle->size() <<" Views"); - - size_t validInputCount = countInputHandles( context ); - size_t validOutputCount = 0; - for ( auto outHandle: outputHandles ) { - if( not outHandle.isValid() ) continue; - validOutputCount++; - } - ATH_MSG_DEBUG("Produced " << validOutputCount << " decisions containers"); - if(validInputCount != validOutputCount ) { - ATH_MSG_ERROR("Found " << validInputCount << " inputs and " << validOutputCount << " outputs"); - return StatusCode::FAILURE; - } - printDecisions( outputHandles ); + ATH_CHECK( debugPrintOut(context, outputHandles) ); return StatusCode::SUCCESS; } -size_t EventViewCreatorAlgorithm::countInputHandles( const EventContext& context ) const { - size_t validInputCount=0; - for ( auto inputKey: decisionInputs() ) { - auto inputHandle = SG::makeHandle( inputKey, context ); - ATH_MSG_DEBUG(" " << inputKey.key() << (inputHandle.isValid()? "valid": "not valid" ) ); - if (inputHandle.isValid() and inputHandle->size() > 0 ) validInputCount++; - } - ATH_MSG_DEBUG( "number of implicit ReadHandles is " << decisionInputs().size() << ", " << validInputCount << " are valid" ); - - return validInputCount; -} - - -void EventViewCreatorAlgorithm::printDecisions( const std::vector<SG::WriteHandle<TrigCompositeUtils::DecisionContainer>>& outputHandles ) const { - if ( not msgLvl( MSG::DEBUG ) ) - return; - - for ( auto outHandle: outputHandles ) { - if( not outHandle.isValid() ) continue; - ATH_MSG_DEBUG(outHandle.key() << " with " << outHandle->size() << " decisions:"); - for ( auto outDecision: *outHandle ) { - TrigCompositeUtils::DecisionIDContainer objDecisions; - TrigCompositeUtils::decisionIDs( outDecision, objDecisions ); - - ATH_MSG_DEBUG("Number of positive decisions for this output: " << objDecisions.size() ); - - for ( TrigCompositeUtils::DecisionID id : TrigCompositeUtils::decisionIDs(outDecision) ) { - ATH_MSG_DEBUG( " --- decision " << HLT::Identifier( id ) ); - } - } - } -} -void EventViewCreatorAlgorithm::insertDecisions( const TrigCompositeUtils::Decision* src, TrigCompositeUtils::Decision* dest ) const { - using namespace TrigCompositeUtils; - DecisionIDContainer ids; - decisionIDs( dest, ids ); - decisionIDs( src, ids ); - decisionIDs( dest ).clear(); - decisionIDs(dest).insert( decisionIDs(dest).end(), ids.begin(), ids.end() ); -} StatusCode EventViewCreatorAlgorithm::linkViewToParent( const TrigCompositeUtils::Decision* inputDecision, SG::View* newView ) const { // see if there is a view linked to the decision object, if so link it to the view that is just made diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h index 4e2b4974950b65f7857545ddf1bac53225ed9b5c..0950e60efffb9aa30fd06aed9d0b509fd09eb82f 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h @@ -26,6 +26,8 @@ * @brief Used at the start of a sequence to create the EventViews: retrieves filtered collection via menu decision from previous step and writes it out directly so it can be used as input by the reco alg that follows in sequence. **/ + + class EventViewCreatorAlgorithm : public ::InputMakerBase { public: @@ -41,21 +43,20 @@ class EventViewCreatorAlgorithm : public ::InputMakerBase //Output views for merging SG::WriteHandleKey< ViewContainer > m_viewsKey{ this, "Views", "Unspecified", "The key of views collection produced" }; - // auxiliary handles + // same handles as inputMakerForRoI SG::WriteHandleKey< ConstDataVector<TrigRoiDescriptorCollection> > m_inViewRoIs{ this, "InViewRoIs", "Unspecified", "Name with which the RoIs shoudl be inserted into the views" }; - + // needs for views ServiceHandle< IScheduler > m_scheduler{ this, "Scheduler", "AvalancheSchedulerSvc", "The Athena scheduler" }; Gaudi::Property<bool> m_viewPerRoI{ this, "ViewPerRoI", false, "Create one View per RoI as opposed to one View per Decision object, needs to be true when multiple decisions per RoI exists" }; Gaudi::Property< std::string > m_viewNodeName{ this, "ViewNodeName", "", "Name of the CF node to attach a view to" }; - Gaudi::Property< std::string > m_roisLink{ this, "RoIsLink", "initialRoI", "Name of EL to RoI object lined to the decision" }; + Gaudi::Property< bool > m_viewFallThrough { this, "ViewFallThrough", false, "Set whether views may accesas StoreGate directly to retrieve data" }; Gaudi::Property< bool > m_requireParentView { this, "RequireParentView", false, "Fail if the parent view can not be found" }; - size_t countInputHandles( const EventContext& context ) const; - void printDecisions( const std::vector<SG::WriteHandle<TrigCompositeUtils::DecisionContainer>>& outputHandles ) const; - void insertDecisions( const TrigCompositeUtils::Decision* src, TrigCompositeUtils::Decision* dest ) const; + + // methods /** * @brief makes sure the views are linked, if configuration requireParentView is set, failure to set the parent is an error **/ diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx index 0dc87e50cfa84d057e8e147022fc41185d2d14e0..c9ec14c5bb42cba252d63cb93a2c603cb027bc5e 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx @@ -11,6 +11,7 @@ #include "DecisionHandling/TrigCompositeUtils.h" #include "DecisionHandling/HLTIdentifier.h" +using namespace TrigCompositeUtils; EventViewCreatorAlgorithmWithJets::EventViewCreatorAlgorithmWithJets( const std::string& name, ISvcLocator* pSvcLocator ) : EventViewCreatorAlgorithm( name, pSvcLocator ) {} @@ -25,111 +26,90 @@ StatusCode EventViewCreatorAlgorithmWithJets::initialize() { return StatusCode::SUCCESS; } -StatusCode EventViewCreatorAlgorithmWithJets::execute( const EventContext& context ) const { - auto outputHandles = decisionOutputs().makeHandles( context ); - // make and store the views +StatusCode EventViewCreatorAlgorithmWithJets::execute( const EventContext& context ) const { + // create the output decisions, similar to inputs (copy basic links) + std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > outputHandles; + ATH_CHECK (decisionInputToOutput(context, outputHandles)); + + // make the views auto viewsHandle = SG::makeHandle( m_viewsKey ); auto viewVector1 = std::make_unique< ViewContainer >(); ATH_CHECK( viewsHandle.record( std::move( viewVector1 ) ) ); auto viewVector = viewsHandle.ptr(); + // auto viewVector = std::make_unique< ViewContainer >(); auto contexts = std::vector<EventContext>( ); unsigned int viewCounter = 0; unsigned int conditionsRun = context.getExtension<Atlas::ExtendedEventContext>().conditionsRun(); - // const TrigRoiDescriptor* previousRoI = 0; - // mapping RoI with index of the View in the vector - // This is used to link the same view to differnt decisions that come from the same RoI - std::map <const TrigRoiDescriptor*, int> viewMap; - std::map <const TrigRoiDescriptor*, int>::iterator itViewMap; - int outputIndex = -1; - // Loop over all input containers, which are of course TrigComposites, and request their features - // this is the same as InputMaker, apart from the view creation. The loop can be splitted in two loops, to have one common part - for ( auto inputKey: decisionInputs() ) { - outputIndex++; - auto inputHandle = SG::makeHandle( inputKey, context ); - if( not inputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from input " << inputKey.key() ); + //map all RoIs that are stored + std::vector <ElementLink<TrigRoiDescriptorCollection> > RoIsFromDecision; + + + for (auto outputHandle: outputHandles) { + if( not outputHandle.isValid() ) { + ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); continue; } - - if( inputHandle->size() == 0 ) { // input filtered out - ATH_MSG_ERROR( "Got 0 decisions from valid input "<< inputKey.key()<<". Is it expected?"); + if( outputHandle->size() == 0){ // input filtered out + ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty. Is this expected?"); return StatusCode::FAILURE; } - ATH_MSG_DEBUG( "Got input " << inputKey.key() << " with " << inputHandle->size() << " elements" ); - - // prepare output decisions - TrigCompositeUtils::createAndStore(outputHandles[outputIndex]); - TrigCompositeUtils::DecisionContainer* outputDecisions = outputHandles[outputIndex].ptr(); - - const TrigRoiDescriptor* prevRoIDescriptor = nullptr; - int inputCounter = -1; - for ( auto inputDecision: *inputHandle ) { - inputCounter++; - // Retrieve jets ... - ATH_MSG_DEBUG( "Checking there are jets linked to decision object" ); - TrigCompositeUtils::LinkInfo< xAOD::JetContainer > jetELInfo = TrigCompositeUtils::findLink< xAOD::JetContainer >( inputDecision,m_jetsLink ); - ATH_CHECK( jetELInfo.isValid() ); - const xAOD::Jet *jet = *jetELInfo.link; - ATH_MSG_DEBUG( "Placing xAOD::JetContainer " ); - ATH_MSG_DEBUG( " -- pt="<< jet->p4().Et() <<" eta="<< jet->eta() << " phi="<< jet->phi() ); - - // pull RoI descriptor - TrigCompositeUtils::LinkInfo<TrigRoiDescriptorCollection> roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>(inputDecision, m_roisLink ); - ATH_CHECK( roiELInfo.isValid() ); - // associate this RoI to output decisions - auto roiDescriptor = *roiELInfo.link; - ATH_MSG_DEBUG( "Placing TrigRoiDescriptor " ); - ATH_MSG_DEBUG( " " << *roiDescriptor ); - - TrigCompositeUtils::Decision* newDecision = nullptr; - if ( prevRoIDescriptor != roiDescriptor ) { - //make one TC decision output per input and connect to previous - newDecision = TrigCompositeUtils::newDecisionIn( outputDecisions, name() ); - TrigCompositeUtils::linkToPrevious( newDecision, inputKey.key(), inputCounter ); - insertDecisions( inputDecision, newDecision ); - newDecision->setObjectLink( "initialRoI", roiELInfo.link ); - newDecision->setObjectLink( "jets", jetELInfo.link ); - prevRoIDescriptor = roiDescriptor; - } else { - newDecision = outputDecisions->back(); - newDecision->setObjectLink( "seedEnd", ElementLink<TrigCompositeUtils::DecisionContainer>( inputHandle.key(), inputCounter ) ); - insertDecisions( inputDecision, newDecision ); - ATH_MSG_DEBUG("No need to create another output decision object, just adding decision IDs"); - } - - // search for existing view - itViewMap = viewMap.find(roiDescriptor); - if ( itViewMap != viewMap.end() ) { - int iview = itViewMap->second; - newDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), iview ) ); //adding view to TC - ATH_MSG_DEBUG( "Adding already mapped view " << iview << " in ViewVector , to new decision"); - // need to check if this View has parent views? can we have more than one parent views? - } else { - - ATH_MSG_DEBUG( "Positive decisions on RoI, preparing view" ); - - // make the view - ATH_MSG_DEBUG( "Making the View" ); - auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view - viewVector->push_back( newView ); - contexts.emplace_back( context ); - contexts.back().setExtension( Atlas::ExtendedEventContext( viewVector->back(), conditionsRun ) ); + + ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); + // loop over output decisions in container of outputHandle, follow link to inputDecision + for ( auto outputDecision : *outputHandle){ + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + // loop over input links as predecessors + for (auto input: inputLinks){ + const Decision* inputDecision = *input; + // Retrieve jets ... + ATH_MSG_DEBUG( "Checking there are jets linked to decision object" ); + TrigCompositeUtils::LinkInfo< xAOD::JetContainer > jetELInfo = TrigCompositeUtils::findLink< xAOD::JetContainer >( inputDecision,m_jetsLink ); + ATH_CHECK( jetELInfo.isValid() ); + const xAOD::Jet *jet = *jetELInfo.link; + ATH_MSG_DEBUG( "Placing xAOD::JetContainer " ); + ATH_MSG_DEBUG( " -- pt="<< jet->p4().Et() <<" eta="<< jet->eta() << " phi="<< jet->phi() ); + - // link decision to this view - newDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC - viewMap[roiDescriptor]=viewVector->size()-1; - ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); - - ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); - ATH_CHECK( placeRoIInView( roiDescriptor, viewVector->back(), contexts.back() ) ); - ATH_CHECK( placeJetInView( jet, viewVector->back(), contexts.back() ) ); - } - } - - ATH_MSG_DEBUG( "Recording output key " << decisionOutputs()[ outputIndex ].key() <<" of size "<< outputDecisions->size() <<" at index "<< outputIndex); - } + // find the RoI + auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); + auto roiEL = roiELInfo.link; + ATH_CHECK( roiEL.isValid() ); + // check if already found + auto roiIt=find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); + if ( roiIt == RoIsFromDecision.end() ){ + RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used + const TrigRoiDescriptor* roi = *roiEL; + ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); + ATH_MSG_DEBUG( "Positive decisions on RoI, preparing view" ); + + // make the view + ATH_MSG_DEBUG( "Making the View" ); + auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view + viewVector->push_back( newView ); + contexts.emplace_back( context ); + contexts.back().setExtension( Atlas::ExtendedEventContext( viewVector->back(), conditionsRun ) ); + + // link decision to this view + outputDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC + outputDecision->setObjectLink( "jets", jetELInfo.link ); + ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); + ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); + ATH_CHECK( placeRoIInView( roi, viewVector->back(), contexts.back() ) ); + ATH_CHECK( placeJetInView( jet, viewVector->back(), contexts.back() ) ); + } + else { + int iview = roiIt-RoIsFromDecision.begin(); + outputDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), iview ) ); //adding view to TC + outputDecision->setObjectLink( "jets", jetELInfo.link ); + ATH_MSG_DEBUG( "Adding already mapped view " << iview << " in ViewVector , to new decision"); + } + }// loop over previous inputs + } // loop over decisions + }// loop over output keys + + ATH_MSG_DEBUG( "Launching execution in " << viewVector->size() << " views" ); ATH_CHECK( ViewHelper::ScheduleViews( viewVector, // Vector containing views @@ -137,22 +117,12 @@ StatusCode EventViewCreatorAlgorithmWithJets::execute( const EventContext& conte context, // Source context m_scheduler.get() ) ); - // report number of views, stored already when container was created + // store views + // auto viewsHandle = SG::makeHandle( m_viewsKey ); + // ATH_CHECK( viewsHandle.record( std::move( viewVector ) ) ); ATH_MSG_DEBUG( "Store "<< viewsHandle->size() <<" Views"); - size_t validInputCount = countInputHandles( context ); - size_t validOutputCount = 0; - for ( auto outHandle: outputHandles ) { - if( not outHandle.isValid() ) continue; - validOutputCount++; - } - - ATH_MSG_DEBUG("Produced " << validOutputCount << " decisions containers"); - if(validInputCount != validOutputCount ) { - ATH_MSG_ERROR("Found " << validInputCount << " inputs and " << validOutputCount << " outputs"); - return StatusCode::FAILURE; - } - printDecisions( outputHandles ); + ATH_CHECK( debugPrintOut(context, outputHandles) ); return StatusCode::SUCCESS; } diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureConfig.py b/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureConfig.py index 4504157e24ff17e72abbc20b484f2fe4052eda0c..d291d5c2cde2c7a250eab123222df175ac8a22f6 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureConfig.py +++ b/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureConfig.py @@ -5,10 +5,19 @@ from TrigUpgradeTest.TrigUpgradeTestConf import HLTTest__TestComboHypoAlg from AthenaCommon.Constants import VERBOSE,DEBUG from TrigUpgradeTest.HLTSignatureHypoTools import * + + + +UseThisLinkName="initialRoI" +#UseThisLinkName="feature" + + from TrigUpgradeTest.TrigUpgradeTestConf import HLTTest__TestInputMaker -def InputMakerAlg(name): - return HLTTest__TestInputMaker(name, OutputLevel = DEBUG, LinkName="initialRoI") +def InputMakerForInitialRoIAlg(name): + return HLTTest__TestInputMaker(name, OutputLevel = DEBUG, RoIsLink="initialRoI", LinkName="initialRoI") +def InputMakerForFeatureAlg(name): + return HLTTest__TestInputMaker(name, OutputLevel = DEBUG, RoIsLink="initialRoI", LinkName=UseThisLinkName) # here define the sequences from the signatures # signatures do this: @@ -19,9 +28,6 @@ from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence from AthenaCommon.CFElements import parOR, seqAND, stepSeq -UseThisLinkName="initialRoI" -#UseThisLinkName="feature" - #### muon signatures ##################### @@ -36,7 +42,7 @@ def MuHypo(name): -muIM= InputMakerAlg(name="Step1MuInputMaker") +muIM= InputMakerForInitialRoIAlg(name="Step1MuInputMaker") muIM.Output='muIM_out' #print muIM @@ -56,7 +62,7 @@ def muStep1Sequence(): return MenuSequence(Sequence=mustep1_sequence, Maker=muIM, Hypo=muHypo, HypoToolGen=MuTestHypoTool) # mu step2 -muIM2= InputMakerAlg(name="Step2MuInputMaker") +muIM2= InputMakerForFeatureAlg(name="Step2MuInputMaker") muIM2.Output='muIM2_out' muAlg2 = muMSRecAlg(name="muMSRecAlg2", FileName="msmu.dat") @@ -87,7 +93,7 @@ def ElGamHypo(name): -elIM= InputMakerAlg(name="Step1ElInputMaker") +elIM= InputMakerForInitialRoIAlg(name="Step1ElInputMaker") elIM.Output='elIM_out' elAlg = CaloClustering(name="CaloClustering", FileName="emclusters.dat") @@ -112,7 +118,7 @@ def gammStep1Sequence(): #step2 -elIM2= InputMakerAlg(name="Step2ElInputMaker") +elIM2= InputMakerForFeatureAlg(name="Step2ElInputMaker") elIM2.Output='elIM2_out' elAlg2 = CaloClustering(name="CaloClustering2", FileName="emclusters.dat") diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/PhotonMenuConfig.py b/Trigger/TrigValidation/TrigUpgradeTest/python/PhotonMenuConfig.py index 535a6cf7a17294f47c6a461abbcdcd9f64dc303c..2007bddf05faf7e99d3b3209fa19ad7002b06e3b 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/python/PhotonMenuConfig.py +++ b/Trigger/TrigValidation/TrigUpgradeTest/python/PhotonMenuConfig.py @@ -23,6 +23,7 @@ def l2PhotonRecoCfg( flags ): reco = InViewReco("L2PhotonReco") reco.inputMaker().RequireParentView = True + reco.inputMaker().RoIsLink="roi" import AthenaCommon.CfgMgr as CfgMgr moveClusters = CfgMgr.AthViews__ViewDataVerifier("photonViewDataVerifier") diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/bjetMenuDefs.py b/Trigger/TrigValidation/TrigUpgradeTest/python/bjetMenuDefs.py index e6201785dd50f52116a92e2a825e555c06a10706..9d97e72155d69af5b56596d259bdcb80a862c629 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/python/bjetMenuDefs.py +++ b/Trigger/TrigValidation/TrigUpgradeTest/python/bjetMenuDefs.py @@ -48,9 +48,10 @@ def bJetStep1Sequence(): # input maker from DecisionHandling.DecisionHandlingConf import InputMakerForRoI - InputMakerAlg = InputMakerForRoI("JetInputMaker",OutputLevel=INFO) - InputMakerAlg.LinkName = "initialRoI" + InputMakerAlg = InputMakerForRoI("JetInputMaker", OutputLevel = DEBUG, RoIsLink="initialRoI") InputMakerAlg.RoIs='FSJETRoI' + InputMakerAlg.OutputLevel = DEBUG + # Construct jets from TrigUpgradeTest.jetDefs import jetRecoSequence @@ -122,8 +123,7 @@ def bJetStep1SequenceALLTE(): # input maker from DecisionHandling.DecisionHandlingConf import InputMakerForRoI - InputMakerAlg = InputMakerForRoI("JetInputMaker",OutputLevel=INFO) - InputMakerAlg.LinkName="initialRoI" + InputMakerAlg = InputMakerForRoI("JetInputMaker",OutputLevel=INFO, RoIsLink="initialRoI") InputMakerAlg.RoIs='FSJETRoI' # Construct jets @@ -198,7 +198,7 @@ def bJetStep2Sequence(): # Event View Creator Algorithm from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithmWithJets - InputMakerAlg = EventViewCreatorAlgorithmWithJets("BJetInputMaker_step2") + InputMakerAlg = EventViewCreatorAlgorithmWithJets("BJetInputMaker_step2", RoIsLink="initialRoI") InputMakerAlg.OutputLevel = DEBUG InputMakerAlg.ViewFallThrough = True # Access Store Gate for retrieving data InputMakerAlg.ViewPerRoI = True # If True it creates one view per RoI @@ -251,9 +251,8 @@ def bJetStep2SequenceALLTE(): # input maker from DecisionHandling.DecisionHandlingConf import InputMakerForRoI - InputMakerAlg = InputMakerForRoI("BJetInputMaker_step2_ALLTE") + InputMakerAlg = InputMakerForRoI("BJetInputMaker_step2_ALLTE", RoIsLink="initialRoI") InputMakerAlg.OutputLevel = DEBUG - InputMakerAlg.LinkName="initialRoI" # InputMakerAlg.RoIs="SplitJets" # TMP commenting # gsc correction diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py b/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py index 64c49d0301353eb1d167add3e4a1ca12fbc3c731..57d2592e6890581b9b8b8006dde1a2c7aba8e093 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py +++ b/Trigger/TrigValidation/TrigUpgradeTest/python/jetMenuDefs.py @@ -11,13 +11,14 @@ def jetSequence(): #input maker from DecisionHandling.DecisionHandlingConf import InputMakerForRoI - InputMakerAlg = InputMakerForRoI("JetInputMaker", OutputLevel = DEBUG, LinkName="initialRoI") + InputMakerAlg = InputMakerForRoI("JetInputMaker", OutputLevel = DEBUG, RoIsLink="initialRoI") InputMakerAlg.RoIs='FSJETRoI' #reco sequence from TrigUpgradeTest.jetDefs import jetRecoSequence (recoSequence, sequenceOut) = jetRecoSequence(InputMakerAlg.RoIs) + #hypo from TrigHLTJetHypo.TrigHLTJetHypoConf import TrigJetHypoAlgMT from TrigHLTJetHypo.TrigJetHypoToolConfig import trigJetHypoToolFromName diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/simpleJetJob.py b/Trigger/TrigValidation/TrigUpgradeTest/share/simpleJetJob.py index 856b55d284317a82b5f0a85a51810d53f7fbf7e6..4775d3ff7c97ef5a3e5f4c7dea6532a2529df2fa 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/share/simpleJetJob.py +++ b/Trigger/TrigValidation/TrigUpgradeTest/share/simpleJetJob.py @@ -55,7 +55,7 @@ if TriggerFlags.doCalo: #inputmaker from DecisionHandling.DecisionHandlingConf import InputMakerForRoI - InputMakerAlg = InputMakerForRoI("JetInputMaker", OutputLevel = DEBUG, LinkName="initialRoI") + InputMakerAlg = InputMakerForRoI("JetInputMaker", OutputLevel = DEBUG, RoIsLink="initialRoI") InputMakerAlg.RoIs='FSJETRoI' InputMakerAlg.InputMakerInputDecisions = filterL1RoIsAlg.Output InputMakerAlg.InputMakerOutputDecisions = ["JETRoIDecisionsOutput"] diff --git a/Trigger/TrigValidation/TrigUpgradeTest/src/TestComboHypoAlg.cxx b/Trigger/TrigValidation/TrigUpgradeTest/src/TestComboHypoAlg.cxx index 0bba744bd22dc28934c2946c9ca5aaf5a30d8e7a..73fae66a2c04cb923d8b435c48888e110cbfb85c 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/src/TestComboHypoAlg.cxx +++ b/Trigger/TrigValidation/TrigUpgradeTest/src/TestComboHypoAlg.cxx @@ -13,15 +13,10 @@ namespace HLTTest { TestComboHypoAlg::TestComboHypoAlg( const std::string& name, ISvcLocator* pSvcLocator ) : ::AthReentrantAlgorithm( name, pSvcLocator ) { - //declareProperty( "Property", m_nProperty ); - // declareProperty( "Input1", m_recoInput1 ); - // declareProperty( "Input2", m_recoInput2 ); declareProperty( "Property1", m_property1 ); declareProperty( "Property2", m_property2 ); declareProperty( "Threshold1", m_threshold1 = 0); declareProperty( "Threshold2", m_threshold2 = 0); - // declareProperty( "Output1", m_output1 ); - // declareProperty( "Output2", m_output2 ); declareProperty( "DecisionLabel", m_decisionLabel ); } @@ -57,10 +52,12 @@ namespace HLTTest { bool TestComboHypoAlg::passed( const Decision* d1, const Decision* d2 ) const { { - auto feature1 = d1->objectLink<xAOD::TrigCompositeContainer>( "feature" ); + auto featureInfo = TrigCompositeUtils::findLink<xAOD::TrigCompositeContainer>( d1, "feature" ); + auto feature1 = featureInfo.link; + if ( not feature1.isValid() ) { ATH_MSG_ERROR( "Can not find reference to the object from the decision1" ); - return false; //StatusCode::FAILURE; + return false; } if ( (*feature1)->hasDetail<float>(m_property1 ) ){ float v = (*feature1)->getDetail<float>( m_property1 ); @@ -71,8 +68,10 @@ namespace HLTTest { else ATH_MSG_ERROR( "Cannot find detail "<<m_property1<<" in feature1"); } - { - auto feature2 = d2->objectLink<xAOD::TrigCompositeContainer>( "feature" ); + { + auto featureInfo = TrigCompositeUtils::findLink<xAOD::TrigCompositeContainer>( d2, "feature" ); + auto feature2 = featureInfo.link; + if ( not feature2.isValid() ) { ATH_MSG_ERROR( "Can not find reference to the object from the decision2" ); return false;//StatusCode::FAILURE; @@ -89,79 +88,6 @@ namespace HLTTest { } - // StatusCode TestComboHypoAlg::execute_oninput( int inputCounter, const EventContext& context ) const { - // ReadHandle<DecisionContainer> previousDecisionsHandle; - // if (inputCounter==0) previousDecisionsHandle = SG::makeHandle( m_previousDecisions1, context ); - // else if (inputCounter==1) previousDecisionsHandle = SG::makeHandle( m_previousDecisions2, context ); - - // if( not previousDecisionsHandle.isValid() ) {//implicit - // ATH_MSG_ERROR( "No implicit RH for previous decisions on input "<<inputCounter<<": is this expected?" ); - // return StatusCode::SUCCESS; - // } - - // ATH_MSG_DEBUG( "Running on input "<<inputCounter<<" with "<< previousDecisionsHandle->size() <<" implicit ReadHandles for previous decisions"); - - // ReadHandle<DecisionContainer> recoInput; - // if (inputCounter==0) recoInput = SG::makeHandle(m_recoInput1, context); - // else if (inputCounter==1) recoInput = SG::makeHandle(m_recoInput2, context); - // ATH_MSG_DEBUG( "and with "<< recoInput->size() <<" reco inputs"); - - // // new output decisions - // auto decisions = std::make_unique<DecisionContainer>(); - // auto aux = std::make_unique<DecisionAuxContainer>(); - // decisions->setStore( aux.get() ); - - - // std::vector<const FeatureOBJ*> featureFromDecision; - // for ( auto previousDecision: *previousDecisionsHandle ) { - // auto featurelink = (previousDecision)->objectLink<FeatureContainer>( m_linkName.value() ); - // CHECK( featurelink.isValid() ); - // const FeatureOBJ* feature = *featurelink; - // featureFromDecision.push_back( feature); - // } - - // // reduce if same feature is found - // // - - // ATH_MSG_DEBUG("Found "<<featureFromDecision.size()<<" features "<<m_linkName.value() <<" mapped from previous decisions"); - - // size_t counter = 0; - // //map reco object and decision: find in reco obejct the initial RoI and map it to the correct decision - // for (auto recoobj: *recoInput){ - // auto roiEL = recoobj->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); - // CHECK( roiEL.isValid() ); - // auto featurelink = (recoobj)->objectLink<FeatureContainer>( m_linkName.value() ); - // CHECK( featurelink.isValid() ); - // if ( not featurelink.isValid() ) { - // ATH_MSG_ERROR( " Can not find reference to " + m_linkName.value() + " from the decision" ); - // return StatusCode::FAILURE; - // } - - // ATH_MSG_DEBUG("Found link from the reco object to feature "<<m_linkName.value() ); - // const FeatureOBJ* feature = *featurelink; - // // find the same roi in the previous decisions - // bool foundRoIInDecision=false; - // size_t pos=distance(featureFromDecision.begin(), find(featureFromDecision.begin(), featureFromDecision.end(), feature)); - // if (pos < featureFromDecision.size()){ - // foundRoIInDecision=true; - // } - - // if (foundRoIInDecision){ - // ATH_MSG_DEBUG("Found link from the reco object to the previous decision at position "<<pos); - // auto d = newDecisionIn(decisions.get()); - // d->setObjectLink( "feature", ElementLink<xAOD::TrigCompositeContainer>(m_recoInput.key(), counter) );// feature used by the Tool - // d->setObjectLink( "initialRoI", featurelink );// this is used by the InputMaker - // d->setObjectLink( "previousDecisions", ElementLink<DecisionContainer>(m_previousDecisions.key(), pos) );// link to previous decision object - // } - // else{ - // ATH_MSG_ERROR( " Can not find reference to previous decision from feature " + m_linkName.value() + " from reco object " << counter ); - // return StatusCode::FAILURE; - // } - // counter++; - // } - - - // } StatusCode TestComboHypoAlg::execute( const EventContext& context ) const { @@ -194,7 +120,9 @@ namespace HLTTest { // find RoIs from previous decisions std::vector<const FeatureOBJ*> featureFromDecision1; for ( auto previousDecision: *previousDecisionsHandle1 ) { - auto featurelink = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto featureInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( previousDecision, "initialRoI" ); + auto featurelink = featureInfo.link; + CHECK( featurelink.isValid() ); const FeatureOBJ* feature = *featurelink; featureFromDecision1.push_back( feature); @@ -203,7 +131,9 @@ namespace HLTTest { std::vector<const FeatureOBJ*> featureFromDecision2; for ( auto previousDecision: *previousDecisionsHandle2 ) { - auto featurelink = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto featureInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( previousDecision, "initialRoI" ); + auto featurelink = featureInfo.link; + CHECK( featurelink.isValid() ); const FeatureOBJ* feature = *featurelink; featureFromDecision2.push_back( feature); @@ -213,7 +143,8 @@ namespace HLTTest { //map reco object and decision: find in reco obejct the initial RoI and map it to the correct decision size_t counter1 = 0; for (auto recoobj: *recoInput1){ - auto featurelink = recoobj->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto featureInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( recoobj, "initialRoI" ); + auto featurelink = featureInfo.link; CHECK( featurelink.isValid() ); ATH_MSG_DEBUG("Found link from the reco object1 to RoI" ); const FeatureOBJ* feature = *featurelink; @@ -241,7 +172,9 @@ namespace HLTTest { size_t counter2 = 0; for (auto recoobj: *recoInput2){ - auto featurelink = recoobj->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto featureInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( recoobj, "initialRoI" ); + auto featurelink = featureInfo.link; + CHECK( featurelink.isValid() ); ATH_MSG_DEBUG("Found link from the reco object2 to RoI" ); const FeatureOBJ* feature = *featurelink; @@ -266,36 +199,8 @@ namespace HLTTest { counter2++; } - // // pre-recate decision objects for each container - // size_t counter1 = 0; - // for ( auto previousDecision: *previousDecisionsHandle1 ) { - // auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); - // CHECK( roiEL.isValid() ); - // auto d = newDecisionIn( decisions1 ); - // if (counter1<input1->size()) - // d->setObjectLink( "feature", ElementLink<xAOD::TrigCompositeContainer>( m_recoInput1.key(), counter1) ); - // else - // ATH_MSG_DEBUG( "Feature not added to the new decision of type 1: counter =" << counter1<<" list size = "<<input1->size()); - // d->setObjectLink( "initialRoI", roiEL ); - // d->setObjectLink( "previousDecisions", ElementLink<DecisionContainer>(m_previousDecisions1.key(), counter1) ); - // counter1++; - // } - ATH_MSG_DEBUG( "Found "<<counter1<<" rois from input 1 " ); - - // size_t counter2 = 0; - // for ( auto previousDecision: *previousDecisionsHandle2 ) { - // auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); - // CHECK( roiEL.isValid() ); - // auto d = newDecisionIn( decisions2 ); - // //get the feature - // if (counter2<input2->size()) - // d->setObjectLink( "feature", ElementLink<xAOD::TrigCompositeContainer>( m_recoInput2.key(), counter2) ); - // else - // ATH_MSG_DEBUG( "Feature not added to the new decision of type 2"); - // d->setObjectLink( "initialRoI", roiEL );// this is used by the InputMaker - // d->setObjectLink( "previousDecisions", ElementLink<DecisionContainer>(m_previousDecisions2.key(), counter2) ); - // counter2++; - // } + + ATH_MSG_DEBUG( "Found "<<counter1<<" rois from input 1 " ); ATH_MSG_DEBUG( "Found "<<counter2<<" rois from input 2 " ); // this is the tool @@ -365,7 +270,6 @@ namespace HLTTest { } } - // ATH_MSG_DEBUG ( "Exit with "<<decisions1->size() <<" decision from input 1 and " <<decisions2->size()<<" form input 2"); return StatusCode::SUCCESS; } diff --git a/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoAlg.cxx b/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoAlg.cxx index 3df9f4318bd666bd15b82d1ae6274ae3a598a033..94b86c7dfa59afef4fd0b43da787a54b6971f267 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoAlg.cxx +++ b/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoAlg.cxx @@ -52,9 +52,8 @@ namespace HLTTest { // find features: std::vector<const FeatureOBJ*> featureFromDecision; for ( auto previousDecision: *previousDecisionsHandle ) { - TrigCompositeUtils::LinkInfo<FeatureContainer> linkInfo = TrigCompositeUtils::findLink<FeatureContainer>(previousDecision, m_linkName.value()); - ElementLink<FeatureContainer> featureLink = linkInfo.link; - //auto featureLink = (previousDecision)->objectLink<FeatureContainer>( m_linkName.value() ); + auto linkInfo = TrigCompositeUtils::findLink<FeatureContainer>(previousDecision, m_linkName.value()); + auto featureLink = linkInfo.link; CHECK( featureLink.isValid() ); const FeatureOBJ* feature = *featureLink; featureFromDecision.push_back( feature); @@ -64,9 +63,12 @@ namespace HLTTest { //map reco object and decision: find in reco obejct the initial RoI and map it to the correct decision size_t reco_counter = 0; for (auto recoobj: *recoInput){ - auto roiEL = recoobj->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + auto roiInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( recoobj, "initialRoI" ); + auto roiEL = roiInfo.link; CHECK( roiEL.isValid() ); - auto featurelink = (recoobj)->objectLink<FeatureContainer>( m_linkName.value() ); + + auto featureInfo = TrigCompositeUtils::findLink<FeatureContainer>( recoobj, m_linkName.value() ); + auto featurelink = featureInfo.link; CHECK( featurelink.isValid() ); if ( not featurelink.isValid() ) { ATH_MSG_ERROR( " Can not find reference to " + m_linkName.value() + " from the decision" ); @@ -87,7 +89,6 @@ namespace HLTTest { auto d = newDecisionIn(decisions); d->setObjectLink( "feature", ElementLink<xAOD::TrigCompositeContainer>(m_recoInput.key(), reco_counter) );// feature used by the Tool d->setObjectLink( m_linkName.value(), featurelink ); - d->setObjectLink( "initialRoI", roiEL ); linkToPrevious( d, decisionInput().key(), pos ); } else{ diff --git a/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoTool.cxx b/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoTool.cxx index b5344725153ef79dc807dafba7ea86d93db97259..cac352bfc086e1737d36e2117255d525f33b91bd 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoTool.cxx +++ b/Trigger/TrigValidation/TrigUpgradeTest/src/TestHypoTool.cxx @@ -38,36 +38,40 @@ namespace HLTTest { size_t counter = 0; for ( auto d: *decisions ) { //get previous decisions - auto previousDecisions = linkToPrevious( d); - TrigCompositeUtils::DecisionIDContainer objDecisions; - TrigCompositeUtils::decisionIDs( *previousDecisions, objDecisions ); + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(d); + ATH_MSG_DEBUG("Got "<<inputLinks.size()<<" previous decisions"); + for (auto previousDecisions: inputLinks){ + + //auto previousDecisions = linkToPrevious( d); + TrigCompositeUtils::DecisionIDContainer objDecisions; + TrigCompositeUtils::decisionIDs( *previousDecisions, objDecisions ); - ATH_MSG_DEBUG("Number of previous decisions for input "<< counter <<"= " << objDecisions.size() ); + ATH_MSG_DEBUG("Number of previous decisions ID for input "<< counter <<"= " << objDecisions.size() ); - for ( TrigCompositeUtils::DecisionID id : objDecisions ) { - ATH_MSG_DEBUG( " -- found decision " << HLT::Identifier( id ) ); - } - - auto it= find(objDecisions.begin(), objDecisions.end(), m_decisionId); - if (it != objDecisions.end()){ - - auto feature = d->objectLink<xAOD::TrigCompositeContainer>( "feature" ); - //auto feature = d->objectLink<xAOD::TrigCompositeContainer>( m_linkName.value() ); - if ( not feature.isValid() ) { - ATH_MSG_ERROR( " Can not find reference to the object from the decision" ); - return StatusCode::FAILURE; + for ( TrigCompositeUtils::DecisionID id : objDecisions ) { + ATH_MSG_DEBUG( " -- found decision " << HLT::Identifier( id ) ); } - float v = (*feature)->getDetail<float>( m_property ); - if ( v > m_threshold ) { // actual cut will be more complex of course - ATH_MSG_DEBUG( " threshold " << m_threshold << " passed by value: " << v ); - addDecisionID( m_decisionId, d ); + + auto it= find(objDecisions.begin(), objDecisions.end(), m_decisionId); + if (it != objDecisions.end()){ + auto feature = d->objectLink<xAOD::TrigCompositeContainer>( "feature" ); + //auto feature = d->objectLink<xAOD::TrigCompositeContainer>( m_linkName.value() ); + if ( not feature.isValid() ) { + ATH_MSG_ERROR( " Can not find reference to the object from the decision" ); + return StatusCode::FAILURE; + } + float v = (*feature)->getDetail<float>( m_property ); + if ( v > m_threshold ) { // actual cut will be more complex of course + ATH_MSG_DEBUG( " threshold " << m_threshold << " passed by value: " << v ); + addDecisionID( m_decisionId, d ); + } + else ATH_MSG_DEBUG( " threshold " << m_threshold << " not passed by value " << v ); } - else ATH_MSG_DEBUG( " threshold " << m_threshold << " not passed by value " << v ); - } - else { - ATH_MSG_DEBUG("No Input decisions requested by active chain "<< m_decisionId); + else { + ATH_MSG_DEBUG("No Input decisions requested by active chain "<< m_decisionId); + } + counter++; } - counter++; } return StatusCode::SUCCESS; diff --git a/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx b/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx index 4a4a72d69bbf0f460a4fc2abca8e31476e2f760f..3d7b76d870f9b2df38d784cfebf4933b5fe119ef 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx +++ b/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx @@ -60,39 +60,35 @@ namespace HLTTest { ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); // loop over output decisions in container of outputHandle, follow link to inputDecision for ( auto outputDecision : *outputHandle){ - ElementLink<DecisionContainer> inputLink = linkToPrevious(outputDecision); - ATH_MSG_DEBUG( "followed seed link to input "<< inputLink.key() ); - const Decision* inputDecision = *inputLink; - auto roiEL = inputDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); - CHECK( roiEL.isValid() ); + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + for (auto input: inputLinks){ + ATH_MSG_DEBUG( "followed seed link to input "<< input.key() ); + const Decision* inputDecision = *input; + auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value()); + CHECK( roiELInfo.isValid() ); - // retrieve input feature from input decision (TrigComposite), will in this case be a TrigRoiDescriptor - auto featureLink = inputDecision->objectLink<FeatureContainer>( m_linkName.value() ); - if ( not featureLink.isValid() ) { - ATH_MSG_ERROR( " Can not find reference to " + m_linkName.value() + " from the decision" ); - return StatusCode::FAILURE; - } - - // link input reco object to outputDecision - outputDecision->setObjectLink(m_linkName.value(), featureLink); - - const FeatureOBJ* feature = *featureLink; - ATH_MSG_DEBUG(" Found feature " <<m_linkName.value() ); - - // merge reco outputs that are linked to the same feature (RoI): this avoids processing the same RoI from TC decisions from different chains - - // avoid adding the same feature multiple times: check if not in container, if not add it - if ( find(featuresFromDecision.begin(), featuresFromDecision.end(), feature) - == featuresFromDecision.end() ){ - featuresFromDecision.push_back(feature); // just to keep track of which we have used - // create the "reco" output: this would normally be a copy of the reco input or something derived from it, e.g. detector data inside a RoI. A TrigComposite is used here just for a trivial example. - auto newFeature = new xAOD::TrigComposite; - reco_output->push_back(newFeature); - // - newFeature->setObjectLink("initialRoI", roiEL); - newFeature->setObjectLink(m_linkName.value(), featureLink); - ATH_MSG_DEBUG(" Added " <<m_linkName.value() << " and initialRoI " << " to reco object"); - } + // retrieve input feature from input decision (TrigComposite), will in this case be a TrigRoiDescriptor + auto featureLinkInfo = TrigCompositeUtils::findLink<FeatureContainer>( inputDecision, m_linkName.value()); + CHECK( featureLinkInfo.isValid() ); + + // link input reco object to outputDecision + auto featureLink = featureLinkInfo.link; + const FeatureOBJ* feature = *featureLink; + ATH_MSG_DEBUG(" Found feature " <<m_linkName.value() ); + + // merge reco outputs that are linked to the same feature (RoI): this avoids processing the same RoI from TC decisions from different chains + + // avoid adding the same feature multiple times: check if not in container, if not add it + if ( find(featuresFromDecision.begin(), featuresFromDecision.end(), feature) + == featuresFromDecision.end() ){ + featuresFromDecision.push_back(feature); // just to keep track of which we have used + // create the "reco" output: this would normally be a copy of the reco input or something derived from it, e.g. detector data inside a RoI. A TrigComposite is used here just for a trivial example. + auto newFeature = new xAOD::TrigComposite; + reco_output->push_back(newFeature); + newFeature->setObjectLink(m_linkName.value(), featureLink); + ATH_MSG_DEBUG(" Added " <<m_linkName.value() << " and " << m_roisLink.value() << " to reco object"); + } + }//loop over previous inputs // For early tests, create TC, link to RoiD, push back onto TCC. // Later will output RoID collection directly via tool. } // loop over decisions diff --git a/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.h b/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.h index 8039db3e582bd1bf61614fff7fac982395c05d42..04c586d370e5c2ee038ad16d1d87c9318252cd2c 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.h +++ b/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.h @@ -43,7 +43,7 @@ namespace HLTTest { SG::WriteHandleKey<xAOD::TrigCompositeContainer> m_recoOutput { this, "Output", "undefined", "name of the output collection for input to next reco alg in sequence" }; StringProperty m_linkName {this, "LinkName", "initialRoI", "name of the link to the features in the decision, e.g. 'feature', 'initialRoI'"}; - StringProperty m_outputType {this, "OutputType","outputType", "reserved for future use"}; + //StringProperty m_outputType {this, "OutputType","outputType", "reserved for future use"}; }; diff --git a/Trigger/TrigValidation/TrigUpgradeTest/src/TestRecoAlg.cxx b/Trigger/TrigValidation/TrigUpgradeTest/src/TestRecoAlg.cxx index 79b595587596a175d0e5ab50802b7865bc7a6eb5..b9cd0a9016896a41ad2f3eb116e628eb4fb9bc2f 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/src/TestRecoAlg.cxx +++ b/Trigger/TrigValidation/TrigUpgradeTest/src/TestRecoAlg.cxx @@ -96,14 +96,11 @@ namespace HLTTest { auto inputHandle = SG::makeHandle(m_input); ATH_MSG_DEBUG("Input " << m_input.key() << " has "<<inputHandle->size() <<" elements, scanning it"); - for ( auto i: *inputHandle.cptr() ) { - // auto roiLink = findLink<TrigRoiDescriptorCollection>(i, "initialRoI"); - auto roiLink = i->objectLink<TrigRoiDescriptorCollection>( "initialRoI" ); + for ( auto i: *inputHandle.cptr() ) { + auto featureInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( i, "initialRoI" ); + auto roiLink = featureInfo.link; CHECK( roiLink.isValid() ); - if ( roiLink.isValid() ) { - // const FeatureOBJ* feature = *featurelink; - // auto roiPtr(roiLink.link.cptr()); auto roiPtr(roiLink.cptr()); ATH_MSG_DEBUG("RoI" << **roiPtr ); // create new outpu objects and add the properties @@ -114,13 +111,6 @@ namespace HLTTest { // maintain link to previous collections xobj->setObjectLink( "initialRoI", roiLink );// this is used by the HypoAlg - - // auto tc = new xAOD::TrigComposite; - // reco_output->push_back(tc); - // // copy all features to a single output collection - // tc->setObjectLink(m_linkName.value(), featurelink); - - ATH_MSG_DEBUG( "Reconstructed object" ); for ( auto prop : object ) { xobj->setDetail( prop.first, prop.second ); @@ -134,9 +124,6 @@ namespace HLTTest { ATH_MSG_DEBUG("RoI information missing"); } } - - - ATH_MSG_DEBUG("Reconstructed "<<output->size() <<" objects"); diff --git a/Trigger/TrigValidation/TrigUpgradeTest/test/test_calo_only_data.sh b/Trigger/TrigValidation/TrigUpgradeTest/test/test_calo_only_data.sh index a95fa6097d5f49dad21ec00de4cd76249587503e..9d4f63da1c55a343ab85d0bd3765e8624a07bdd4 100755 --- a/Trigger/TrigValidation/TrigUpgradeTest/test/test_calo_only_data.sh +++ b/Trigger/TrigValidation/TrigUpgradeTest/test/test_calo_only_data.sh @@ -1,5 +1,6 @@ #!/bin/sh # art-type: build # art-ci: master +# art-include: master/Athena athena.py --threads=1 --evtMax=10 --filesInput="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/TrigP1Test/data17_13TeV.00327265.physics_EnhancedBias.merge.RAW._lb0100._SFO-1._0001.1" -c 'doID=False' TrigUpgradeTest/Calo.py diff --git a/Trigger/TrigValidation/TrigUpgradeTest/test/test_jet.sh b/Trigger/TrigValidation/TrigUpgradeTest/test/test_jet.sh index b106306eabe4f9ebc2e084e0f5ae0078524992da..14a88ef8e08aa8c7c962e8670e581d271dd6fc25 100755 --- a/Trigger/TrigValidation/TrigUpgradeTest/test/test_jet.sh +++ b/Trigger/TrigValidation/TrigUpgradeTest/test/test_jet.sh @@ -1,7 +1,9 @@ #!/bin/sh # art-type: build # art-ci: master +# art-include: master/Athena + # 10 events athena.py --threads=1 --evtMax=10 --skipEvents=5 --filesInput="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/TrigP1Test/data17_13TeV.00327265.physics_EnhancedBias.merge.RAW._lb0100._SFO-1._0001.1" -c 'doID=False' TrigUpgradeTest/simpleJetJob.py -#athena --threads=1 --evtMax=15 --filesInput="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/TrigP1Test/data17_13TeV.00327265.physics_EnhancedBias.merge.RAW._lb0100._SFO-1._0001.1" TrigUpgradeTest/simpleJetJob.py +