Skip to content
Snippets Groups Projects
Commit 5afac519 authored by Tomasz Bold's avatar Tomasz Bold Committed by Frank Winklmeier
Browse files

Bootstrap of refactored Run2ToRun3 conversion alg

parent 115a3042
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python
#
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
#
# Output file can be checked (and navigation graphs converted using):
#
# athena TrigNavTools/navGraphDump.py
# see there for more info
if __name__=='__main__':
import sys
# Setup the Run III behavior
from AthenaCommon.Configurable import Configurable
Configurable.configurableRun3Behavior = 1
# Set the Athena configuration flags
from AthenaCommon.Constants import WARNING
from AthenaConfiguration.AllConfigFlags import ConfigFlags
###test input file: --filesInput='/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Tier0ChainTests/q221/21.0/myAOD.pool.root'
# Set the Athena configuration flags
ConfigFlags.Input.Files=["/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Tier0ChainTests/q221/21.0/myAOD.pool.root"]
ConfigFlags.Output.AODFileName = "outAOD.pool.root"
ConfigFlags.Detector.GeometryLAr=True
ConfigFlags.Detector.GeometryTile=True
# useful examples: test units based on them
#ConfigFlags.addFlag("TestNavConversion.Chains",["HLT_mu4"])
#ConfigFlags.addFlag("TestNavConversion.Chains",["HLT_mu4","HLT_mu6","HLT_mu10","HLT_mu6_2mu4","HLT_mu22"])
# ConfigFlags.addFlag("TestNavConversion.Chains",["HLT_e5_lhvloose_nod0","HLT_e9_etcut","HLT_e26_lhtight_nod0","HLT_e28_lhtight_nod0"])
#ConfigFlags.addFlag("TestNavConversion.Collections",["xAOD::MuonContainer","xAOD::L2StandAloneMuonContainer","xAOD::TrigMissingET","xAOD::JetContainer"])
# ConfigFlags.addFlag("TestNavConversion.Collections",["xAOD::ElectronContainer","xAOD::TrigEMClusterContainer","xAOD::TrigEMCluster","xAOD::TrigElectron","xAOD::TrigElectronContainer","xAOD::CaloCluster","xAOD::CaloClusterContainer"])
# ConfigFlags.fillFromArgs()
ConfigFlags.lock()
# Initialize configuration object, add accumulator, merge, and run.
from AthenaConfiguration.MainServicesConfig import MainServicesCfg
from AthenaConfiguration.ComponentFactory import CompFactory
from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
cfg = MainServicesCfg(ConfigFlags)
cfg.merge(PoolReadCfg(ConfigFlags))
from AthenaServices.MetaDataSvcConfig import MetaDataSvcCfg
cfg.merge(MetaDataSvcCfg(ConfigFlags))
confSvc = CompFactory.TrigConf.xAODConfigSvc("xAODConfigSvc")
cfg.addService(confSvc)
from AthenaCommon.Constants import DEBUG
alg = CompFactory.Run2ToRun3TrigNavConverterV2("TrigNavCnv", OutputLevel=DEBUG, TrigConfigSvc=confSvc)
alg.doSelfValidation = False
cfg.addEventAlgo(alg, sequenceName="AthAlgSeq")
from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
outputType="AOD"
toRecord = ["xAOD::TrigCompositeContainer#HLTNav_All", "xAOD::TrigCompositeAuxContainer#HLTNav_AllAux.",
"xAOD::TrigCompositeContainer#HLTNav_Summary", "xAOD::TrigCompositeAuxContainer#HLTNav_SummaryAux."]
outputCfg = OutputStreamCfg(ConfigFlags, outputType, ItemList=toRecord, disableEventTag=True)
streamAlg = outputCfg.getEventAlgo("OutputStream"+outputType)
# need to expand possible options for the OutputStreamCfg to be able to pass also the metadata containers
streamAlg.MetadataItemList += ["xAOD::TriggerMenuContainer#TriggerMenu", "xAOD::TriggerMenuAuxContainer#TriggerMenuAux."]
streamAlg.TakeItemsFromInput = True
cfg.addPublicTool(CompFactory.xAODMaker.TriggerMenuMetaDataTool("TriggerMenuMetaDataTool"))
cfg.addService( CompFactory.MetaDataSvc("MetaDataSvc", MetaDataTools = [cfg.getPublicTool("TriggerMenuMetaDataTool")]))
cfg.merge(outputCfg)
# input EDM needs calo det descrition for conversion (uff)
from LArGeoAlgsNV.LArGMConfig import LArGMCfg
from TileGeoModel.TileGMConfig import TileGMCfg
cfg.merge(LArGMCfg(ConfigFlags))
cfg.merge(TileGMCfg(ConfigFlags))
cfg.printConfig(withDetails=True, summariseProps=False) # set True for exhaustive info
sc = cfg.run(ConfigFlags.Exec.MaxEvents, ConfigFlags.Exec.OutputLevel)
sys.exit(0 if sc.isSuccess() else 1)
/*
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#include "Run2ToRun3TrigNavConverterV2.h"
namespace TCU = TrigCompositeUtils;
// helper class
ConvProxy::ConvProxy(const HLT::TriggerElement* t) : te{ t } {}
void ConvProxy::merge(ConvProxy* /*other*/) {
// copy over chains & links
// prune the other
}
// the algorithm
Run2ToRun3TrigNavConverterV2::Run2ToRun3TrigNavConverterV2(const std::string& name, ISvcLocator* pSvcLocator) :
AthReentrantAlgorithm(name, pSvcLocator)
{
}
Run2ToRun3TrigNavConverterV2::~Run2ToRun3TrigNavConverterV2()
{
}
StatusCode Run2ToRun3TrigNavConverterV2::initialize()
{
ATH_CHECK(m_trigOutputNavKey.initialize());
ATH_CHECK(m_tdt.empty() != m_trigNavKey.key().empty()); //either of the two has to be enabled but not both
if (!m_tdt.empty()) {
ATH_CHECK(m_tdt.retrieve());
ATH_MSG_INFO("Will use Trigger Navigation from TrigDecisionTool");
}
else {
ATH_CHECK(m_trigNavKey.initialize(SG::AllowEmpty));
ATH_MSG_INFO("Will use Trigger Navigation decoded from TrigNavigation object");
}
ATH_CHECK(m_configSvc.retrieve());
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::finalize()
{
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::execute(const EventContext& context) const
{
// need to check if this step works in start() or initialize, if so we need to it once
// and remember this mapping
TEIdToChainsMap_t allTEIdsToChains, finalTEIdsToChains;
ATH_CHECK(extractTECtoChainMapping(allTEIdsToChains, finalTEIdsToChains));
ConvProxySet_t convProxies;
ATH_CHECK(mirrorTEsStructure(convProxies, context));
if (m_doSelfValidation)
ATH_CHECK(allProxiesConnected(convProxies));
ATH_CHECK(associateChainsToProxies(convProxies, allTEIdsToChains));
ATH_CHECK(cureUnassociatedProxies(convProxies));
ATH_MSG_DEBUG("Proxies to chains mapping done");
if (not m_chainsToSave.empty()) {
ATH_CHECK(removeUnassociatedProxies(convProxies));
ATH_MSG_DEBUG("Removed proxies to chains that are not converted, remaining number of elements " << convProxies.size());
}
if (m_doSelfValidation) {
ATH_CHECK(allProxiesHaveChain(convProxies));
}
if (m_doCompression) {
ATH_CHECK(doCompression(convProxies));
}
if (m_doLinkFeatures) {
ATH_CHECK(fillRelevantFeatures(convProxies));
ATH_MSG_DEBUG("Features to link found");
}
SG::WriteHandle<TrigCompositeUtils::DecisionContainer> outputNavigation = TrigCompositeUtils::createAndStore(m_trigOutputNavKey, context);
auto decisionOutput = outputNavigation.ptr();
TrigCompositeUtils::newDecisionIn(decisionOutput, "HLTPassRaw"); // we rely on the fact that the 1st element is the top
ATH_CHECK(createIMHNodes(convProxies, *decisionOutput));
if (m_doSelfValidation) {
ATH_CHECK(numberOfHNodesPerProxyNotExcessive(convProxies));
}
ATH_CHECK(createFSNodes(convProxies, *decisionOutput, finalTEIdsToChains));
ATH_CHECK(linkTopNode(*decisionOutput));
ATH_MSG_DEBUG("Conversion done, from " << convProxies.size() << " elements to " << decisionOutput->size() << " elements");
// dispose temporaries
for (auto proxy : convProxies) {
delete proxy;
}
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::extractTECtoChainMapping(TEIdToChainsMap_t& allTEs, TEIdToChainsMap_t& finalTEs) const {
// port chains iteration code from previous version
ATH_MSG_DEBUG("Recognised " << allTEs.size() << " kinds of TEs and among them " << finalTEs.size() << " final types");
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::mirrorTEsStructure(ConvProxySet_t& convProxies, const EventContext& context) const {
const HLT::TrigNavStructure* run2NavigationPtr = nullptr;
HLT::StandaloneNavigation standaloneNav;
if (!m_trigNavKey.key().empty()) {
SG::ReadHandle navReadHandle(m_trigNavKey, context);
ATH_CHECK(navReadHandle.isValid());
standaloneNav.deserialize(navReadHandle->serialized());
run2NavigationPtr = &standaloneNav;
}
else {
run2NavigationPtr = m_tdt->ExperimentalAndExpertMethods().getNavigation();
}
const HLT::TrigNavStructure& run2Navigation = *run2NavigationPtr;
// iterate over the TEs, for each make the ConvProxy and build connections
std::map<const HLT::TriggerElement*, ConvProxy*> teToProxy;
ATH_MSG_DEBUG("TrigNavStructure with " << run2Navigation.getAllTEs().size() << " TEs acquired");
for (auto te : run2Navigation.getAllTEs()) {
// skip event seed node
if (HLT::TrigNavStructure::isInitialNode(te)) continue;
auto proxy = new ConvProxy(te);
convProxies.insert(proxy);
// add linking
for (auto predecessor : HLT::TrigNavStructure::getDirectPredecessors(te)) {
ConvProxy* predecessorProxy = teToProxy[predecessor];
if (predecessorProxy != nullptr) { // because we skip some
proxy->parents.push_back(predecessorProxy);
predecessorProxy->children.push_back(proxy);
}
}
}
ATH_MSG_DEBUG("Created " << convProxies.size() << " proxy objects");
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::associateChainsToProxies(ConvProxySet_t&, const TEIdToChainsMap_t&) const {
// using map chain IDs mapping
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::cureUnassociatedProxies(ConvProxySet_t& convProxies) const {
// propagate up (towards L1) chain IDs if they are not in proxies
// technically each proxy looks at the children proxies and inserts from it all unseen chains
// procedure is repeated until, no single proxy needs an update (tedious - we may be smarter in future)
while (true) {
size_t numberOfUpdates = 0;
for (auto p : convProxies) {
for (auto child : p->children) {
size_t startSize = p->runChains.size();
p->runChains.insert(std::begin(child->runChains), std::end(child->runChains));
if (startSize != p->runChains.size()) { // some chain needed to be inserted
numberOfUpdates++;
// if update was need, it means set of chains that passed need update as well
p->passChains.insert(std::begin(child->runChains), std::end(child->runChains));
}
}
}
ATH_MSG_DEBUG("Needed to propagate chains from " << numberOfUpdates << " child(ren)");
if (numberOfUpdates == 0) {
break;
}
}
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::removeUnassociatedProxies(ConvProxySet_t& convProxies) const {
// remove proxies that have no chains
for (auto i = std::begin(convProxies); i != std::end(convProxies);) {
if ((*i)->runChains.empty()) {
// TODO we may need to deregister it from it's children & parents
delete* i;
i = convProxies.erase(i);
}
else {
++i;
}
}
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::doCompression(ConvProxySet_t& convProxies) const {
ATH_CHECK(fillFEAHashes(convProxies));
FEAToConvProxySet_t sharedFeaturesMap;
ATH_CHECK(findSharedFEAHashes(convProxies, sharedFeaturesMap));
if (m_doSelfValidation) {
ATH_CHECK(allFEAHashesAreUnique(sharedFeaturesMap));
}
ATH_CHECK(collapseConvProxies(convProxies, sharedFeaturesMap));
ATH_CHECK(cureFeaturelessProxies(convProxies));
if (m_doSelfValidation) {
ATH_CHECK(allProxiesHaveChain(convProxies));
ATH_CHECK(allProxiesConnected(convProxies));
}
ATH_MSG_DEBUG("Compression done");
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::fillFEAHashes(ConvProxySet_t&) const {
// calculate fea hash for each vector<FEA> from te associated to proxy
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::findSharedFEAHashes(const ConvProxySet_t&, FEAToConvProxySet_t&) const {
// ceate feahash -> [te1, te2...] mapping, these tes are candidates for merging/compression
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::collapseConvProxies(ConvProxySet_t&, const FEAToConvProxySet_t&) const {
// this for all entries in the FEA to TES map, use the first TE as a "primary" and merge all others to it
// remove from proxies set all elements that are now unassociated (remember to delete after)
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::cureFeaturelessProxies(ConvProxySet_t&) const {
// heuristically compres proxies that mirror TEs w/o any feature
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::fillRelevantFeatures(ConvProxySet_t&) const {
// from all FEAs of the associated TE pick those objects that are to be linked
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::createIMHNodes(ConvProxySet_t&, xAOD::TrigCompositeContainer& decisions) const {
// create nodes of ne navigation for relevant features
ATH_MSG_DEBUG("IM & H nodes made, output nav elements " << decisions.size());
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::createFSNodes(const ConvProxySet_t&, xAOD::TrigCompositeContainer& decisions, const TEIdToChainsMap_t&) const {
// associate terminal nodes to filter nodes,
// associate all nodes designated as final one with the filter nodes
ATH_MSG_DEBUG("FS nodes made, output nav elements " << decisions.size());
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::linkTopNode(xAOD::TrigCompositeContainer& decisions) const {
// simply link all filter nodes to the HLTPassRaw (the 1st element)
ATH_CHECK((*decisions.begin())->name() == "HLTPassRaw");
return StatusCode::SUCCESS;
}
uint64_t Run2ToRun3TrigNavConverterV2::feaToHash(const std::vector<HLT::TriggerElement::FeatureAccessHelper>&) const {
// clever FEA vectors hashing
return 0;
}
StatusCode Run2ToRun3TrigNavConverterV2::allProxiesHaveChain(const ConvProxySet_t& proxies) const {
for (auto p : proxies) {
if (p->runChains.empty()) {
ATH_MSG_ERROR("Proxy with no chains");
return StatusCode::FAILURE;
}
}
ATH_MSG_DEBUG("CHECK OK, no proxies w/o a chain");
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::allProxiesConnected(const ConvProxySet_t& proxies) const {
for (auto p : proxies) {
if (p->children.empty() and p->parents.empty()) {
ATH_MSG_ERROR("Orphanted proxy");
return StatusCode::FAILURE;
}
}
ATH_MSG_DEBUG("CHECK OK, no orphanted proxies");
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::allFEAHashesAreUnique(const FEAToConvProxySet_t& feaToProxies) const {
for (auto [feaHash, proxies] : feaToProxies) {
auto first = *proxies.begin();
for (auto p : proxies) {
if (p->te->getFeatureAccessHelpers() != first->te->getFeatureAccessHelpers()) {
ATH_MSG_ERROR("Proxies grouped in FEA to Proxies map entries have distinct features");
return StatusCode::FAILURE;
}
}
}
ATH_MSG_DEBUG("CHECK OK, FE hashes unique");
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::numberOfHNodesPerProxyNotExcessive(const ConvProxySet_t& proxies) const {
for (auto p : proxies) {
if (p->hNodes.size() > m_hNodesPerProxyThreshold) {
ATH_MSG_ERROR("Too many H nodes per proxy");
return StatusCode::FAILURE;
}
}
ATH_MSG_DEBUG("CHECK OK, no excessive number of H nodes per proxy");
return StatusCode::SUCCESS;
}
StatusCode Run2ToRun3TrigNavConverterV2::noUnconnectedHNodes(const xAOD::TrigCompositeContainer& decisions)const {
// build map of all links to H nodes from IMs and FS
std::set<const TrigCompositeUtils::Decision*> linkedHNodes;
for (auto d : decisions) {
if (d->name() == "IM" or d->name() == "FS") {
/* FIXME links are not iterable
for (auto links : TCU::getLinkToPrevious(d)) {
for (auto l : links) {
linkedHNodes.insert(*l);
}
}
*/
}
}
for (auto d : decisions) {
if (d->name() == "H") {
if (linkedHNodes.count(d) == 0) {
ATH_MSG_ERROR("Orphanted H node");
return StatusCode::FAILURE;
}
}
}
ATH_MSG_DEBUG("CHECK OK, all H modes are connected");
return StatusCode::SUCCESS;
}
\ No newline at end of file
/*
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#ifndef TRIGNAVTOOLS_RUN2TORUN3TRIGNAVCONVERTERV2_H
#define TRIGNAVTOOLS_RUN2TORUN3TRIGNAVCONVERTERV2_H
// Framework includes
#include "AthenaBaseComps/AthReentrantAlgorithm.h"
#include "StoreGate/ReadHandleKey.h"
#include "StoreGate/WriteHandleKey.h"
#include "xAODTrigger/TrigNavigation.h"
#include "TrigConfInterfaces/IHLTConfigSvc.h"
#include "GaudiKernel/IClassIDSvc.h"
#include "xAODTrigger/TrigComposite.h"
#include "xAODTrigger/TrigCompositeContainer.h"
#include "TrigCompositeUtils/TrigCompositeUtils.h"
#include "TrigNavStructure/Types.h"
#include "TrigNavStructure/TypedHolder.h"
#include "TrigNavStructure/TrigNavStructure.h"
#include "TrigSteeringEvent/TrigRoiDescriptorCollection.h"
#include "TrigDecisionTool/TrigDecisionTool.h"
// STL includes
#include <string>
#include <set>
#include <map>
// class of temporary objects used to integrate informations needed in conversion process
struct ConvProxy {
ConvProxy(const HLT::TriggerElement* te);
void merge(ConvProxy* other); // this will change the also the "other" so it knows it has been merged
const HLT::TriggerElement* te = nullptr;
std::vector<ConvProxy*> children;
std::vector<ConvProxy*> parents;
std::set<HLT::Identifier> runChains;
std::set<HLT::Identifier> passChains;
uint64_t feaHash;
std::vector<TrigCompositeUtils::Decision*> imNodes; // for checks only
std::vector<TrigCompositeUtils::Decision*> hNodes;
};
using ConvProxySet_t = std::set<ConvProxy*>;
using TEIdToChainsMap_t = std::map<HLT::te_id_type, std::set<HLT::Identifier>>;
using FEAToConvProxySet_t = std::map<uint64_t, ConvProxySet_t>;
/**
* @class Run2ToRun3TrigNavConverterV2
* @brief
**/
class Run2ToRun3TrigNavConverterV2 : public AthReentrantAlgorithm {
public:
Run2ToRun3TrigNavConverterV2(const std::string& name, ISvcLocator* pSvcLocator);
virtual ~Run2ToRun3TrigNavConverterV2() override;
virtual StatusCode initialize() override;
virtual StatusCode execute(const EventContext& context) const override;
virtual StatusCode finalize() override;
private:
// configurable properties & services
SG::ReadHandleKey<xAOD::TrigNavigation> m_trigNavKey{ this, "TrigNavReadKey", "TrigNavigation" };
PublicToolHandle<Trig::TrigDecisionTool> m_tdt{ this, "TrigDecisionTool","", "When enabled read navigation from TDT/off by default" };
ServiceHandle< TrigConf::IHLTConfigSvc > m_configSvc{ this, "TrigConfigSvc", "TrigConf::xAODConfigSvc/xAODConfigSvc", "Trigger configuration service" };
Gaudi::Property<bool> m_doSelfValidation{ this, "doSelfValidation", false, "Run consistency checks after stages of conversion (slows down the alg)" };
Gaudi::Property<bool> m_doCompression{ this, "doCompression", true, "Collapse navigation elements to save ouput space" };
Gaudi::Property<bool> m_doLinkFeatures{ this, "doLinkFeatures", true, "Add links to objects, setting it false makes sense when running tests" };
Gaudi::Property<size_t> m_hNodesPerProxyThreshold{ this, "hNodesPerProxyThreshhold", 15, "Limit number of H nodes per TE (if exceeded conversion results in an error)" };
Gaudi::Property<std::vector<std::string>> m_chainsToSave{ this, "Chains", {}, "If not specified, all chains are handled" };
SG::WriteHandleKey<xAOD::TrigCompositeContainer> m_trigOutputNavKey{ this, "OutputNavKey", "HLTNav_Summary" };
StatusCode extractTECtoChainMapping(TEIdToChainsMap_t& allTES, TEIdToChainsMap_t& finalTEs) const;
StatusCode mirrorTEsStructure(ConvProxySet_t&, const EventContext& context) const;
StatusCode associateChainsToProxies(ConvProxySet_t&, const TEIdToChainsMap_t&) const;
StatusCode cureUnassociatedProxies(ConvProxySet_t&) const;
StatusCode removeUnassociatedProxies(ConvProxySet_t&) const;
StatusCode doCompression(ConvProxySet_t&) const;
StatusCode fillFEAHashes(ConvProxySet_t&) const;
StatusCode findSharedFEAHashes(const ConvProxySet_t&, FEAToConvProxySet_t&) const;
StatusCode collapseConvProxies(ConvProxySet_t&, const FEAToConvProxySet_t&) const;
StatusCode cureFeaturelessProxies(ConvProxySet_t&) const;
StatusCode fillRelevantFeatures(ConvProxySet_t&) const;
StatusCode createIMHNodes(ConvProxySet_t&, xAOD::TrigCompositeContainer&) const;
StatusCode createFSNodes(const ConvProxySet_t&, xAOD::TrigCompositeContainer&, const TEIdToChainsMap_t& finalTEs) const;
StatusCode linkTopNode(xAOD::TrigCompositeContainer&) const;
// helpers
uint64_t feaToHash(const std::vector<HLT::TriggerElement::FeatureAccessHelper>&) const;
// self validators
// they return failure if something is not ok
StatusCode allProxiesHaveChain(const ConvProxySet_t&) const;
StatusCode allProxiesConnected(const ConvProxySet_t&) const;
StatusCode allFEAHashesAreUnique(const FEAToConvProxySet_t&) const;
StatusCode numberOfHNodesPerProxyNotExcessive(const ConvProxySet_t&) const;
StatusCode noUnconnectedHNodes(const xAOD::TrigCompositeContainer&) const;
//Gaudi::Property<int> m_myInt{this, "MyInt", 0, "An Integer"};
};
#endif // TRIGNAVTOOLS_RUN2TORUN3TRIGNAVCONVERTERV2_H
\ No newline at end of file
#include "../TrigNavigationThinningSvc.h"
#include "../Run2ToRun3TrigNavConverter.h"
#include "../Run2ToRun3TrigNavConverterV2.h"
DECLARE_COMPONENT( TrigNavigationThinningSvc )
DECLARE_COMPONENT( Run2ToRun3TrigNavConverter )
DECLARE_COMPONENT( Run2ToRun3TrigNavConverterV2 )
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