Skip to content
Snippets Groups Projects
Commit c7b68758 authored by Edward Moyse's avatar Edward Moyse
Browse files

Merge branch 'master-HLTJet-copymods' into 'master'

Reduce need for jet modifiers on HLT jet copy collections

See merge request atlas/athena!38842
parents 2b5bebe3 a0e79004
No related branches found
No related tags found
No related merge requests found
...@@ -53,6 +53,17 @@ public: ...@@ -53,6 +53,17 @@ public:
/// from the templated JetProvider class provided below. /// from the templated JetProvider class provided below.
virtual StatusCode getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const = 0; virtual StatusCode getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const = 0;
/// Method to allow the client to pass in a WriteHandle during
/// initialisation, in case this is needed for anything...
///
/// The main (only?) use case is for copying jets, and propagating
/// any decorations already on the original to the copy in StoreGate
///
/// Quietly return success in the general case -- the JetRecAlg
/// will always call this, so as to remain agnostic as to the
/// concrete type.
virtual StatusCode initWithOutput(const SG::WriteHandleKey<xAOD::JetContainer>&) {return StatusCode::SUCCESS;};
}; };
...@@ -65,8 +76,8 @@ template <typename CONCRETEAUX> class JetProvider ...@@ -65,8 +76,8 @@ template <typename CONCRETEAUX> class JetProvider
: virtual public IJetProvider : virtual public IJetProvider
{ {
public: public:
StatusCode getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const { StatusCode getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const {
std::unique_ptr<xAOD::JetContainer> jets(nullptr); std::unique_ptr<xAOD::JetContainer> jets(nullptr);
std::unique_ptr<SG::IAuxStore> auxCont(nullptr); std::unique_ptr<SG::IAuxStore> auxCont(nullptr);
......
...@@ -8,7 +8,7 @@ set( extra_libs ) ...@@ -8,7 +8,7 @@ set( extra_libs )
if( NOT GENERATIONBASE ) if( NOT GENERATIONBASE )
list( APPEND extra_libs xAODPFlow ) list( APPEND extra_libs xAODPFlow )
if( NOT XAOD_STANDALONE ) if( NOT XAOD_STANDALONE )
list( APPEND extra_libs AthenaMonitoringKernelLib ) list( APPEND extra_libs AthenaMonitoringKernelLib StoreGateLib )
endif() endif()
endif() endif()
......
...@@ -19,10 +19,17 @@ ...@@ -19,10 +19,17 @@
#include "AsgTools/PropertyWrapper.h" #include "AsgTools/PropertyWrapper.h"
#include "AsgTools/AsgTool.h" #include "AsgTools/AsgTool.h"
#include "AsgDataHandles/ReadHandleKey.h" #include "AsgDataHandles/ReadHandleKey.h"
#include "AsgDataHandles/WriteHandleKey.h"
#include "JetInterface/IJetProvider.h" #include "JetInterface/IJetProvider.h"
#include "xAODJet/JetContainer.h" #include "xAODJet/JetContainer.h"
#include "xAODCore/ShallowAuxContainer.h" #include "xAODCore/ShallowAuxContainer.h"
// This class doesn't (yet) exist for AnalysisBase, so in that release
// we will simply have to rerun modifiers if we need them.
#ifndef XAOD_ANALYSIS
#include "StoreGate/ShallowCopyDecorDeps.h"
#endif
class JetCopier class JetCopier
: public asg::AsgTool, : public asg::AsgTool,
virtual public IJetProvider virtual public IJetProvider
...@@ -32,20 +39,35 @@ class JetCopier ...@@ -32,20 +39,35 @@ class JetCopier
public: public:
using asg::AsgTool::AsgTool; using asg::AsgTool::AsgTool;
// Called in parent initialize()
virtual StatusCode initialize() override; virtual StatusCode initialize() override;
virtual StatusCode getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const override; #ifndef XAOD_ANALYSIS
// Needed to initialise the ShallowCopyDecorDeps object, which propagates
// decorations on the original into the copy in StoreGate.
// Override interface implementation in Athena only
virtual StatusCode initWithOutput(const SG::WriteHandleKey<xAOD::JetContainer>& outputJets) override;
#endif
// Called during execution
virtual StatusCode getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const override;
virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > getJets() const override; virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > getJets() const override;
private:
virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > ShallowCopyJets() const; virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > ShallowCopyJets() const;
virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > DeepCopyJets() const; virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > DeepCopyJets() const;
private:
// Handle Input JetContainer // Handle Input JetContainer
SG::ReadHandleKey<xAOD::JetContainer> m_inputJets {this, "InputJets", "", "Jet collection to be copied"}; SG::ReadHandleKey<xAOD::JetContainer> m_inputJets {this, "InputJets", "", "Jet collection to be copied"};
Gaudi::Property<bool> m_shallowCopy {this, "ShallowCopy", true, "True for shallow copy, false for deep copy"}; Gaudi::Property<bool> m_shallowCopy {this, "ShallowCopy", true, "True for shallow copy, false for deep copy"};
Gaudi::Property<bool> m_shallowIO {this, "ShallowIO", false, "True for storing only modified data"}; Gaudi::Property<bool> m_shallowIO {this, "ShallowIO", false, "True for storing only modified data"};
#ifndef XAOD_ANALYSIS
SG::ShallowCopyDecorDeps<xAOD::JetContainer> m_decorDeps { this, "DecorDeps", {},
"List of decorations to propagate through the shallow copy." };
#endif
}; };
#endif #endif
...@@ -35,6 +35,15 @@ StatusCode JetCopier::initialize() { ...@@ -35,6 +35,15 @@ StatusCode JetCopier::initialize() {
return StatusCode::SUCCESS; return StatusCode::SUCCESS;
} }
#ifndef XAOD_ANALYSIS
// Setup helper to propagate decorations from original to copy
StatusCode JetCopier::initWithOutput(const SG::WriteHandleKey<xAOD::JetContainer>& outputJets) {
return m_decorDeps.initialize(m_inputJets, outputJets) ;
}
#endif
StatusCode JetCopier::getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const { StatusCode JetCopier::getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetHandle) const {
std::unique_ptr<xAOD::JetContainer> jets(nullptr); std::unique_ptr<xAOD::JetContainer> jets(nullptr);
std::unique_ptr<SG::IAuxStore> auxCont(nullptr); std::unique_ptr<SG::IAuxStore> auxCont(nullptr);
...@@ -44,12 +53,19 @@ StatusCode JetCopier::getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetH ...@@ -44,12 +53,19 @@ StatusCode JetCopier::getAndRecordJets(SG::WriteHandle<xAOD::JetContainer>& jetH
if(m_shallowCopy){ if(m_shallowCopy){
std::unique_ptr<xAOD::ShallowAuxContainer> auxCont_derived(static_cast<xAOD::ShallowAuxContainer*>(auxCont.release())); std::unique_ptr<xAOD::ShallowAuxContainer> auxCont_derived(static_cast<xAOD::ShallowAuxContainer*>(auxCont.release()));
return jetHandle.record(std::move(jets), std::move(auxCont_derived)); ATH_CHECK( jetHandle.record(std::move(jets), std::move(auxCont_derived)) );
#ifndef XAOD_ANALYSIS
ATH_CHECK( m_decorDeps.linkDecors (m_inputJets) );
#endif
} }
else{ else{
std::unique_ptr<xAOD::JetAuxContainer> auxCont_derived(static_cast<xAOD::JetAuxContainer*>(auxCont.release())); std::unique_ptr<xAOD::JetAuxContainer> auxCont_derived(static_cast<xAOD::JetAuxContainer*>(auxCont.release()));
return jetHandle.record(std::move(jets), std::move(auxCont_derived)); ATH_CHECK( jetHandle.record(std::move(jets), std::move(auxCont_derived)) );
#ifndef XAOD_ANALYSIS
ATH_CHECK( m_decorDeps.linkDecors (m_inputJets) );
#endif
} }
return StatusCode::SUCCESS;
} }
std::pair<std::unique_ptr<xAOD::JetContainer>,std::unique_ptr<SG::IAuxStore> > JetCopier::getJets() const { std::pair<std::unique_ptr<xAOD::JetContainer>,std::unique_ptr<SG::IAuxStore> > JetCopier::getJets() const {
......
...@@ -17,7 +17,13 @@ using std::string; ...@@ -17,7 +17,13 @@ using std::string;
StatusCode JetRecAlg::initialize() { StatusCode JetRecAlg::initialize() {
ATH_CHECK(m_output.initialize());
ATH_CHECK(m_jetprovider.retrieve()); ATH_CHECK(m_jetprovider.retrieve());
// Some providers (e.g. copy) need the output WriteHandle
// to be provided during initialisation
ATH_CHECK(m_jetprovider->initWithOutput(m_output));
ATH_MSG_INFO(" Initialized IJetProvider : "<< m_jetprovider->name()); ATH_MSG_INFO(" Initialized IJetProvider : "<< m_jetprovider->name());
ATH_MSG_INFO(" Initialize .... List of modifiers: "); ATH_MSG_INFO(" Initialize .... List of modifiers: ");
...@@ -26,7 +32,6 @@ StatusCode JetRecAlg::initialize() { ...@@ -26,7 +32,6 @@ StatusCode JetRecAlg::initialize() {
ATH_MSG_INFO(" --> : "<< t->name()); ATH_MSG_INFO(" --> : "<< t->name());
} }
ATH_CHECK(m_output.initialize());
return StatusCode::SUCCESS; return StatusCode::SUCCESS;
} }
......
...@@ -325,11 +325,15 @@ def getJetRecAlg( jetdef): ...@@ -325,11 +325,15 @@ def getJetRecAlg( jetdef):
# these may be set up already in the original jet collection # these may be set up already in the original jet collection
# In future we may wish to add a toggle. # In future we may wish to add a toggle.
# #
def getJetCopyAlg(jetsin, jetsoutdef, shallowcopy=True, shallowIO=True): # The decoration list can be set in order for the decorations
# (jet moments) on the original jets to be propagated to the
# copy collection. Beware of circular dependencies!
def getJetCopyAlg(jetsin, jetsoutdef, decorations=[], shallowcopy=True, shallowIO=True):
jcopy = CompFactory.JetCopier( jcopy = CompFactory.JetCopier(
"copier", "copier",
InputJets = jetsin, InputJets = jetsin,
DecorDeps=decorations,
ShallowCopy=shallowcopy, ShallowCopy=shallowcopy,
ShallowIO=shallowIO) ShallowIO=shallowIO)
......
...@@ -263,3 +263,19 @@ def defineCalibMods(jetRecoDict,dataSource,rhoKey="auto"): ...@@ -263,3 +263,19 @@ def defineCalibMods(jetRecoDict,dataSource,rhoKey="auto"):
"Calib:"+calibSpec] "Calib:"+calibSpec]
return calibMods return calibMods
def getDecorList(doTracks,isPFlow):
# Basic jet info provided by the jet builder
decorlist = [ 'AlgorithmType', 'InputType'
'ActiveArea', 'ActiveArea4vec_eta', 'ActiveArea4vec_m',
'ActiveArea4vec_phi', 'ActiveArea4vec_pt']
if doTracks:
decorlist += ["GhostTrack",
"NumTrkPt500","NumTrkPt1000",
"SumPtTrkPt500","SumPtTrkPt1000",
"TrackWidthPt1000",
"JVFCorr"]
if isPFlow:
decorlist += ["SumPtChargedPFOPt500"]
return decorlist
...@@ -77,11 +77,16 @@ def jetRecoSequence( configFlags, clustersKey, **jetRecoDict ): ...@@ -77,11 +77,16 @@ def jetRecoSequence( configFlags, clustersKey, **jetRecoDict ):
def standardJetBuildSequence( configFlags, dataSource, clustersKey, **jetRecoDict ): def standardJetBuildSequence( configFlags, dataSource, clustersKey, **jetRecoDict ):
jetDefString = jetRecoDictToString(jetRecoDict) jetDefString = jetRecoDictToString(jetRecoDict)
buildSeq = parOR( "JetBuildSeq_"+jetDefString, []) buildSeq = parOR( "JetBuildSeq_"+jetDefString, [])
trkcolls = getTrkColls(jetRecoDict) if jetRecoDict["trkopt"]!="notrk" else {} doesTracking = jetRecoDict["trkopt"]!="notrk"
trkcolls = getTrkColls(jetRecoDict) if doesTracking else {}
if doesTracking and not trkcolls:
raise RuntimeError("Failed to retrieve track collections for trkopt '{}'".format(jetRecoDict["trkopt"]))
isPFlow = "pf" in jetRecoDict["dataType"]
# Add particle flow reconstruction if needed # Add particle flow reconstruction if needed
if "pf" in jetRecoDict["dataType"]: if isPFlow:
if not trkcolls: if not doesTracking:
raise RuntimeError("PFlow jet chain requested with no tracking option!") raise RuntimeError("PFlow jet chain requested with no tracking option!")
from eflowRec.PFHLTSequence import PFHLTSequence from eflowRec.PFHLTSequence import PFHLTSequence
(pfseq, pfoPrefix) = RecoFragmentsPool.retrieve( (pfseq, pfoPrefix) = RecoFragmentsPool.retrieve(
...@@ -114,11 +119,10 @@ def standardJetBuildSequence( configFlags, dataSource, clustersKey, **jetRecoDic ...@@ -114,11 +119,10 @@ def standardJetBuildSequence( configFlags, dataSource, clustersKey, **jetRecoDic
# Basic list of PseudoJets is just the constituents # Basic list of PseudoJets is just the constituents
# Append ghosts (tracks) if desired # Append ghosts (tracks) if desired
pjs = [constitPJKey] pjs = [constitPJKey]
if trkcolls: # Also compile modifier list
pjs.append(trkcolls["GhostTracks"])
jetModList = [] jetModList = []
if trkcolls: if doesTracking:
pjs.append(trkcolls["GhostTracks"])
trkMods = JetRecoConfiguration.defineTrackMods(jetRecoDict["trkopt"]) trkMods = JetRecoConfiguration.defineTrackMods(jetRecoDict["trkopt"])
jetModList += trkMods jetModList += trkMods
...@@ -177,8 +181,13 @@ def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict ...@@ -177,8 +181,13 @@ def standardJetRecoSequence( configFlags, dataSource, clustersKey, **jetRecoDict
rhoKey = str(eventShapeAlg.EventDensityTool.OutputContainer) rhoKey = str(eventShapeAlg.EventDensityTool.OutputContainer)
jetDef.modifiers = JetRecoConfiguration.defineCalibMods(jetRecoDict,dataSource,rhoKey) jetDef.modifiers = JetRecoConfiguration.defineCalibMods(jetRecoDict,dataSource,rhoKey)
jetDef.modifiers += jetDefNoCalib.modifiers[:-2] # Leave off sort + filter # If we need JVT, just rerun the JVT modifier
copyCalibAlg = JetRecConfig.getJetCopyAlg(jetsin=jetsNoCalib,jetsoutdef=jetDef) doesTracking = jetRecoDict["trkopt"] != "notrk"
isPFlow = "pf" in jetRecoDict["dataType"]
if doesTracking:
jetDef.modifiers.append("JVT:"+jetRecoDict["trkopt"])
decorList = JetRecoConfiguration.getDecorList(doesTracking,isPFlow)
copyCalibAlg = JetRecConfig.getJetCopyAlg(jetsin=jetsNoCalib,jetsoutdef=jetDef,decorations=decorList)
recoSeq += copyCalibAlg recoSeq += copyCalibAlg
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment