Skip to content
Snippets Groups Projects
Commit 0772090a authored by Frank Winklmeier's avatar Frank Winklmeier
Browse files

Merge branch 'StartOverlay' into 'main'

MuonR4 - Introduce barebone digitization tool serving as template for all sub detector digitizations

See merge request !71780
parents da0e88e5 06cc6e53
No related branches found
No related tags found
27 merge requests!78241Draft: FPGATrackSim: GenScan code refactor,!78236Draft: Switching Streams https://its.cern.ch/jira/browse/ATR-27417,!78056AFP monitoring: new synchronization and cleaning,!78041AFP monitoring: new synchronization and cleaning,!77990Updating TRT chip masks for L1TRT trigger simulation - ATR-28372,!77733Draft: add new HLT NN JVT, augmented with additional tracking information,!77731Draft: Updates to ZDC reconstruction,!77728Draft: updates to ZDC reconstruction,!77522Draft: sTGC Pad Trigger Emulator,!76725ZdcNtuple: Fix cppcheck warning.,!76611L1CaloFEXByteStream: Fix out-of-bounds array accesses.,!76475Punchthrough AF3 implementation in FastG4,!76474Punchthrough AF3 implementation in FastG4,!75729New implementation of ZDC nonlinear FADC correction.,!75703Draft: Update to HI han config for HLT jets,!75184Draft: Update file heavyions_run.config,!74430Draft: Fixing upper bound for Delayed Jet Triggers,!73963Changing the path of the histograms to "Expert" area,!73875updating ID ART reference plots,!73874AtlasCLHEP_RandomGenerators: Fix cppcheck warnings.,!73449Add muon detectors to DarkJetPEBTLA partial event building,!73343Draft: [TrigEgamma] Add photon ringer chains on bootstrap mechanism,!72336Fixed TRT calibration crash,!72176Draft: Improving L1TopoOnline chain that now gets no-empty plots. Activating it by default,!72012Draft: Separate JiveXMLConfig.py into Config files,!71876Fix MET trigger name in MissingETMonitoring,!71780MuonR4 - Introduce barebone digitization tool serving as template for all sub detector digitizations
Showing
with 558 additions and 16 deletions
......@@ -392,9 +392,11 @@ namespace Muon {
const MdtIdHelper& id_helper{m_idHelperSvc->mdtIdHelper()};
const Identifier prdId{calibInput.identify()};
xprd->setIdentifier(calibInput.identify().get_identifier32().get_compact());
xprd->setIdentifier(calibInput.identify().get_compact());
xprd->setMeasurement(calibInput.legacyDescriptor()->identifyHash(), driftRadius, cov);
xprd->setMeasurement(calibInput.decriptor()
? calibInput.decriptor()->identHash()
: calibInput.legacyDescriptor()->identifyHash(), driftRadius, cov);
xprd->setTdc(calibInput.tdc());
xprd->setAdc(calibInput.adc());
......
......@@ -44,8 +44,7 @@ def RT_Relation_DB_DigiToolCfg(flags, name="RT_Relation_DB_DigiTool", **kwargs):
def MDT_Response_DigiToolCfg(flags, name="MDT_Response_DigiTool",**kwargs):
"""Return a configured MDT_Response_DigiTool"""
acc = ComponentAccumulator()
QballConfig = (flags.Input.SpecialConfiguration.get("MDT_QballConfig", "False") == "True")
kwargs.setdefault("DoQballGamma", QballConfig)
kwargs.setdefault("DoQballGamma", (flags.Input.SpecialConfiguration.get("MDT_QballConfig", "False") == "True"))
MDT_Response_DigiTool = CompFactory.MDT_Response_DigiTool
acc.setPrivateTools(MDT_Response_DigiTool(name, **kwargs))
return acc
......@@ -60,19 +59,27 @@ def MDT_DigitizationToolCommonCfg(flags, name="MdtDigitizationTool", **kwargs):
acc.merge(MdtCondDbAlgCfg(flags))
acc.merge(MdtCalibDbAlgCfg(flags))
kwargs.setdefault("DiscardEarlyHits", True)
kwargs.setdefault("UseTof", flags.Beam.Type is not BeamType.Cosmics)
# "RT_Relation_DB_DigiTool" in jobproperties.Digitization.experimentalDigi() not migrated
kwargs.setdefault("DigitizationTool", acc.popToolsAndMerge(MDT_Response_DigiToolCfg(flags)))
QballConfig = (flags.Input.SpecialConfiguration.get("MDT_QballConfig", "False") == "True")
kwargs.setdefault("DoQballCharge", QballConfig)
### configuration arguments not yet migrated to the PhaseII geometry
if not flags.Muon.usePhaseIIGeoSetup:
kwargs.setdefault("DiscardEarlyHits", True)
kwargs.setdefault("UseTof", flags.Beam.Type is not BeamType.Cosmics)
kwargs.setdefault("DoQballCharge", (flags.Input.SpecialConfiguration.get("MDT_QballConfig", "False") == "True"))
kwargs.setdefault("DigitizationTool", acc.popToolsAndMerge(MDT_Response_DigiToolCfg(flags)))
else:
### Use the simple digitization tool as a first start
kwargs.setdefault("DigitizationTool", acc.popToolsAndMerge(RT_Relation_DB_DigiToolCfg(flags)))
kwargs.setdefault("SimHitKey", "xMdtSimHits")
kwargs.setdefault("StreamName", "MdtDigitForklifting")
if flags.Digitization.DoXingByXingPileUp:
kwargs.setdefault("FirstXing", MDT_FirstXing())
kwargs.setdefault("LastXing", MDT_LastXing())
from RngComps.RngCompsConfig import AthRNGSvcCfg
kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name)
MdtDigitizationTool = CompFactory.MdtDigitizationTool
acc.setPrivateTools(MdtDigitizationTool(name, **kwargs))
kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)))
if not flags.Muon.usePhaseIIGeoSetup:
acc.setPrivateTools(CompFactory.MdtDigitizationTool(name, **kwargs))
else:
acc.setPrivateTools(CompFactory.MuonR4.MdtDigitizationTool(name, **kwargs))
return acc
......@@ -148,8 +155,7 @@ def MDT_OverlayDigitizationBasicCfg(flags, **kwargs):
# Set common overlay extra inputs
kwargs.setdefault("ExtraInputs", flags.Overlay.ExtraInputs)
MDT_Digitizer = CompFactory.MDT_Digitizer
acc.addEventAlgo(MDT_Digitizer(name="MDT_OverlayDigitizer", **kwargs))
acc.addEventAlgo(CompFactory.MDT_Digitizer(name="MDT_OverlayDigitizer", **kwargs))
return acc
......
......@@ -75,7 +75,11 @@ def xAODSimHitToMmMeasCnvAlgCfg(flags, name = "SimHitToMmMeasurementCnvAlg",**kw
def MuonSimHitToMeasurementCfg(flags):
result = ComponentAccumulator()
if flags.Detector.GeometryMDT:
result.merge(xAODSimHitToMdtMeasCnvAlgCfg(flags))
from MuonConfig.MDT_DigitizationConfig import MDT_DigitizationDigitToRDOCfg
#result.merge(xAODSimHitToMdtMeasCnvAlgCfg(flags))
from MuonConfig.MuonRdoDecodeConfig import MdtRDODecodeCfg
result.merge(MDT_DigitizationDigitToRDOCfg(flags))
result.merge(MdtRDODecodeCfg(flags))
if flags.Detector.GeometryRPC:
result.merge(xAODSimHitToRpcMeasCnvAlgCfg(flags))
if flags.Detector.GeometryTGC:
......
################################################################################
# Package: MuonOverlayR4
################################################################################
# Declare the package name:
atlas_subdir( MdtDigitizationR4 )
atlas_add_component( MdtDigitizationR4
src/components/*.cxx src/*.cxx
LINK_LIBRARIES AthenaKernel StoreGateLib xAODMuonSimHit MuonReadoutGeometryR4 MdtCalibSvcLib
MuonDigitizationR4 MuonCondData MuonDigitContainer MuonIdHelpersLib MDT_DigitizationLib)
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "MdtDigitizationTool.h"
#include "StoreGate/WriteHandle.h"
#include "MDT_Digitization/MdtDigiToolInput.h"
#include "MdtCalibInterfaces/IMdtCalibrationTool.h"
#include "CLHEP/Random/RandGaussZiggurat.h"
namespace{
constexpr double timeToTdcCnv = 1. / IMdtCalibrationTool::tdcBinSize;
}
namespace MuonR4 {
MdtDigitizationTool::MdtDigitizationTool(const std::string& type, const std::string& name, const IInterface* pIID):
MuonDigitizationTool{type,name, pIID} {}
StatusCode MdtDigitizationTool::initialize() {
ATH_CHECK(MuonDigitizationTool::initialize());
ATH_CHECK(m_writeKey.initialize());
ATH_CHECK(m_calibDbKey.initialize());
ATH_CHECK(m_badTubeKey.initialize());
return StatusCode::SUCCESS;
}
StatusCode MdtDigitizationTool::digitize(const EventContext& ctx,
const TimedHits& hitsToDigit,
xAOD::MuonSimHitContainer* sdoContainer) const {
const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
// Prepare the temporary cache
DigiCache digitCache{};
/// Fetch the needed conditions
const MuonCalib::MdtCalibDataContainer* calibData{nullptr};
ATH_CHECK(retrieveConditions(ctx, m_calibDbKey, calibData));
const MdtCondDbData* badTubes{nullptr};
ATH_CHECK(retrieveConditions(ctx, m_badTubeKey, badTubes));
CLHEP::HepRandomEngine* rndEngine = getRandomEngine(ctx);
double deadTime{0.};
for (const TimedHitPtr<xAOD::MuonSimHit>& simHit : hitsToDigit) {
const Identifier hitId{simHit->identify()};
/// Hit is masked in the database for whatever reason
if (!badTubes->isGood(hitId)) {
ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hitId)<<" is rejected due to masking in DB.");
continue;
}
const MuonGMR4::MdtReadoutElement* readOutEle = m_detMgr->getMdtReadoutElement(hitId);
const IdentifierHash measHash{readOutEle->measurementHash(hitId)};
const Amg::Vector3D locPos{xAOD::toEigen(simHit->localPosition())};
const double distRO = std::abs(0.5*readOutEle->getParameters().readoutSide*readOutEle->activeTubeLength(measHash) - locPos.z());
const MdtDigiToolInput digiInput(std::abs(locPos.perp()), distRO, 0., 0., 0., 0., hitId);
const MdtDigiToolOutput digiOutput(m_digiTool->digitize(ctx, digiInput, rndEngine));
if (!digiOutput.wasEfficient()) {
ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hitId)<<" is rejected due to inefficiency modelling.");
continue;
}
const MuonCalib::MdtFullCalibData* tubeConstants = calibData->getCalibData(hitId, msgStream());
const MuonCalib::MdtTubeCalibContainer::SingleTubeCalib& tubeCalib{*tubeConstants->tubeCalib->getCalib(hitId)};
const double sigPropTime = tubeCalib.inversePropSpeed*distRO;
/// Total tdc time is the sum of the drift time, the time of flight of the muon, the propgation along the wire
/// and finally the constant t0 tube offset
const double totalTdcTime = digiOutput.driftTime() + simHit->globalTime() + sigPropTime + tubeCalib.t0;
MdtDigitCollection* outColl = fetchCollection(hitId, digitCache);
if (outColl->empty() || outColl->back()->identify() != hitId || totalTdcTime > deadTime) {
deadTime = totalTdcTime + m_deadTime;
} else if (totalTdcTime <= deadTime) {
ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hitId)<<" is within dead time "<<deadTime<<" totalTdcTime: "<<totalTdcTime);
continue;
}
const bool hasHPTdc = m_idHelperSvc->hasHPTDC(hitId);
/// The HPTdc has 4 times higher clock frequency. Smear both
const uint16_t tdcCounts = timeToTdcCnv*(hasHPTdc ? 4 : 1)*CLHEP::RandGaussZiggurat::shoot(rndEngine, totalTdcTime, m_timeResTDC);
const uint16_t adcCounts = (hasHPTdc ? 4 : 1) *CLHEP::RandGaussZiggurat::shoot(rndEngine, digiOutput.adc(), m_timeResADC);
auto digit = std::make_unique<MdtDigit>(hitId, tdcCounts, adcCounts);
outColl->push_back(std::move(digit));
addSDO(simHit, sdoContainer);
}
/// Write everything at the end into the final digit container
ATH_CHECK(writeDigitContainer(ctx, m_writeKey, std::move(digitCache), idHelper.module_hash_max()));
return StatusCode::SUCCESS;
}
}
\ No newline at end of file
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MDT_DIGITIZATIONR4_MDTDIGITIZATIONTOOL_H
#define MDT_DIGITIZATIONR4_MDTDIGITIZATIONTOOL_H
#include "MuonDigitizationR4/MuonDigitizationTool.h"
#include "MDT_Digitization/IMDT_DigitizationTool.h"
#include "MuonDigitContainer/MdtDigitContainer.h"
#include "MdtCalibData/MdtCalibDataContainer.h"
#include "MuonCondData/MdtCondDbData.h"
namespace MuonR4{
class MdtDigitizationTool final: public MuonDigitizationTool {
public:
MdtDigitizationTool(const std::string& type, const std::string& name, const IInterface* pIID);
StatusCode initialize() override final;
protected:
StatusCode digitize(const EventContext& ctx,
const TimedHits& hitsToDigit,
xAOD::MuonSimHitContainer* sdoContainer) const override final;
private:
SG::WriteHandleKey<MdtDigitContainer> m_writeKey{this, "OutputObjectName", "MDT_Digits"};
SG::ReadCondHandleKey<MuonCalib::MdtCalibDataContainer> m_calibDbKey{this, "CalibDataKey", "MdtCalibConstants",
"Conditions object containing the calibrations"};
SG::ReadCondHandleKey<MdtCondDbData> m_badTubeKey{this, "BadTubeKey", "MdtCondDbData", "Key of MdtCondDbData"};
ToolHandle<IMDT_DigitizationTool> m_digiTool{this, "DigitizationTool", ""};
Gaudi::Property<double> m_timeResTDC{this, "ResolutionTDC", 0.5, "TDC time resolution"};
Gaudi::Property<double> m_timeResADC{this, "ResolutionADC", 0.5 * Gaudi::Units::ns, "ADC time resolution"};
Gaudi::Property<double> m_deadTime{this, "DeadTime", 700., "MDT drift tube dead time"};
using DigiCache = OutDigitCache_t<MdtDigitCollection>;
};
}
#endif
\ No newline at end of file
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "../MdtDigitizationTool.h"
DECLARE_COMPONENT(MuonR4::MdtDigitizationTool)
\ No newline at end of file
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
################################################################################
# Package: MuonDigitizationR4
################################################################################
# Declare the package name:
atlas_subdir( MuonDigitizationR4 )
atlas_add_library( MuonDigitizationR4
src/*.cxx
PUBLIC_HEADERS MuonDigitizationR4
LINK_LIBRARIES MuonReadoutGeometryR4 PileUpToolsLib xAODMuonSimHit
ActsGeometryInterfacesLib MuonIdHelpersLib HitManagement
AthenaBaseComps StoreGateLib)
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MUONDIGITIZATIONR4_MUONDIGITIZATIONTOOL_H
#define MUONDIGITIZATIONR4_MUONDIGITIZATIONTOOL_H
#include "PileUpTools/PileUpMergeSvc.h"
#include "PileUpTools/PileUpToolBase.h"
#include "CLHEP/Random/RandomEngine.h"
#include "AthenaKernel/IAthRNGSvc.h"
#include "AthenaBaseComps/AthAlgTool.h"
#include "StoreGate/ReadHandleKey.h"
#include "StoreGate/ReadCondHandleKey.h"
#include "xAODMuonSimHit/MuonSimHitContainer.h"
#include "MuonReadoutGeometryR4/MuonDetectorManager.h"
#include "MuonIdHelpers/IMuonIdHelperSvc.h"
#include "ActsGeometryInterfaces/ActsGeometryContext.h"
#include "HitManagement/TimedHitPtr.h"
namespace MuonR4 {
/** @brief Barebone implementation of the I/O infrastructure for all MuonDigitizationTools.
*
*/
class MuonDigitizationTool: public PileUpToolBase {
public:
MuonDigitizationTool(const std::string& type,
const std::string& name,
const IInterface* pIID);
StatusCode initialize() override;
StatusCode processBunchXing(int bunchXing,
SubEventIterator bSubEvents,
SubEventIterator eSubEvents) override final;
StatusCode mergeEvent(const EventContext& ctx) override final;
/** When being run from PileUpToolsAlgs, this method is called at the start of the subevts loop. Not able to access SubEvents */
StatusCode prepareEvent(const EventContext& ctx,
const unsigned int /*nInputEvents*/) override final;
/** alternative interface which uses the PileUpMergeSvc to obtain
all the required SubEvents. */
StatusCode processAllSubEvents(const EventContext& ctx) override final;
protected:
CLHEP::HepRandomEngine* getRandomEngine(const EventContext&ctx) const;
using TimedHit = TimedHitPtr<xAOD::MuonSimHit>;
using TimedHits = std::vector<TimedHitPtr<xAOD::MuonSimHit>>;
/** @brief Digitize the time ordered hits and write them to the digit format specific for the
* detector technology. A new MuonSimHitContainer pointer is parsed to also create the MuonSDO.
* If a new SDO should be added to the container plese use the addSDO() method as defined below.
*/
virtual StatusCode digitize(const EventContext& ctx,
const TimedHits& hitsToDigit,
xAOD::MuonSimHitContainer* sdoContainer) const = 0;
/** @brief Adds the timed simHit to the output SDO container. The hit may be rejected if it's originating from
* pile-up and the pile-up truth skimming strategy is applied
*/
void addSDO(const TimedHit& hit, xAOD::MuonSimHitContainer* sdoContainer) const;
/** @brief Returns the reference to the ActsGeometryContext needed to fetch global positions from the Readout geometry*/
const ActsGeometryContext& getGeoCtx(const EventContext& ctx) const;
/** @brief Helper function to retrieve a container from StoreGate. If the readHandleKey is empty, the container is assigned
* to be a nullptr and the operation is marked as success. Otherwise, a failure is returned if the Container cannot be fetched
* from StoreGate
*/
template <class Container> StatusCode retrieveContainer(const EventContext& ctx,
const SG::ReadHandleKey<Container>& key,
const Container* & contPtr) const;
/** @brief Helper function to access the conditions data. If the key is empty, the conditions object is assigned to be a nullptr
* Otherwise, a failure is returned if the Conditions data are not available in the event.
*/
template <class Container> StatusCode retrieveConditions(const EventContext&ctx,
const SG::ReadCondHandleKey<Container>& key,
const Container* & contPtr) const;
/** @brief DigitContainers are sorted by DigitCollections which are the ensemble of all hits in a given
* MuonChamber. To fill the final DigitContainer thread-safely, the DigitCollections shall be cached
* pre cached in a OutDigitCache_t vector which is later moved to the final DigitContainer
*/
template <class DetType> using OutDigitCache_t = std::vector<std::unique_ptr<DetType>>;
/** @brief Helper function that provides fetches the proper DigitCollection from the DigitCache for a given hit identifier
* If the Collection is fetched for the first time, it's inserted into the cache first.
*/
template <class DigitColl>
DigitColl* fetchCollection(const Identifier& hitId,
OutDigitCache_t<DigitColl>& digitCache) const;
/** @brief Helper function to move the collected digits into the final DigitContainer. The function needs the maximal
* size of the container in advance which is provided by calling the module_hash_max() function of the corresponding
* MuonIdHelper.
*/
template <class DigitCont, class DigitColl>
StatusCode writeDigitContainer(const EventContext& ctx,
const SG::WriteHandleKey<DigitCont>& key,
OutDigitCache_t<DigitColl>&& digitCache,
unsigned int hashMax) const;
const MuonGMR4::MuonDetectorManager* m_detMgr{nullptr};
ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc{this, "MuonIdHelperSvc",
"Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
private:
using PileUpHits = PileUpMergeSvc::TimedList<xAOD::MuonSimHitContainer>::type;
StatusCode fillTimedHits(const PileUpHits& hitColl);
SG::ReadHandleKey<xAOD::MuonSimHitContainer> m_simHitKey{this, "SimHitKey", ""};
SG::ReadHandleKey<ActsGeometryContext> m_geoCtxKey{this, "AlignmentKey", "ActsAlignment",
"Geometry context"};
ServiceHandle<PileUpMergeSvc> m_mergeSvc{this, "PileUpMergeSvc", "PileUpMergeSvc", ""};
Gaudi::Property<std::string> m_streamName{this, "StreamName", ""};
ServiceHandle<IAthRNGSvc> m_rndmSvc{this, "RndmSvc", "AthRNGSvc", ""}; // Random number service
SG::WriteHandleKey<xAOD::MuonSimHitContainer> m_sdoKey{this, "OutputSDOName", ""};
Gaudi::Property<bool> m_onlyUseContainerName{this, "OnlyUseContainerName", true,
"Don't use the ReadHandleKey directly. Just extract the container name from it."};
Gaudi::Property<bool> m_includePileUpTruth{this, "IncludePileUpTruth", true, "Include pile-up truth info"};
std::string m_inputObjectName{""};
TimedHits m_timedHits{};
};
}
#include "MuonDigitizationR4/MuonDigitizationTool.icc"
#endif
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MUONDIGITIZATION_MUONDIGITIZATIONTOOL_ICC
#define MUONDIGITIZATION_MUONDIGITIZATIONTOOL_ICC
#include <StoreGate/ReadHandle.h>
#include <StoreGate/WriteHandle.h>
#include <StoreGate/ReadCondHandle.h>
namespace MuonR4{
template <class Container>
StatusCode MuonDigitizationTool::retrieveContainer(const EventContext& ctx,
const SG::ReadHandleKey<Container>& key,
const Container* & contPtr) const {
if (key.empty()) {
ATH_MSG_VERBOSE("No container key has been set for "<<typeid(Container).name());
contPtr = nullptr;
return StatusCode::SUCCESS;
}
SG::ReadHandle<Container> readHandle{key, ctx};
ATH_CHECK(readHandle.isPresent());
contPtr = readHandle.cptr();
return StatusCode::SUCCESS;
}
template <class Container> StatusCode MuonDigitizationTool::retrieveConditions(const EventContext&ctx,
const SG::ReadCondHandleKey<Container>& key,
const Container* & contPtr) const {
if (key.empty()) {
ATH_MSG_VERBOSE("No conditions key has been set for "<<typeid(Container).name());
contPtr = nullptr;
return StatusCode::SUCCESS;
}
SG::ReadCondHandle<Container> readCondHandle{key, ctx};
ATH_CHECK(readCondHandle.isValid());
contPtr = readCondHandle.cptr();
return StatusCode::SUCCESS;
}
template <class DigitColl>
DigitColl* MuonDigitizationTool::fetchCollection(const Identifier& hitId,
OutDigitCache_t<DigitColl>& digitCache) const {
const IdentifierHash hash{m_idHelperSvc->moduleHash(hitId)};
if (static_cast<unsigned>(hash) >= digitCache.size()) {
digitCache.resize(static_cast<unsigned>(hash) + 1);
}
std::unique_ptr<DigitColl>& coll = digitCache[static_cast<unsigned>(hash)];
if (!coll) {
coll = std::make_unique<DigitColl>(m_idHelperSvc->chamberId(hitId), hash);
}
return coll.get();
}
template <class DigitCont, class DigitColl>
StatusCode MuonDigitizationTool:: writeDigitContainer(const EventContext& ctx,
const SG::WriteHandleKey<DigitCont>& key,
OutDigitCache_t<DigitColl>&& digitCache,
unsigned int hashMax) const {
SG::WriteHandle<DigitCont> writeHandle{key, ctx};
ATH_CHECK(writeHandle.record(std::make_unique<DigitCont>(hashMax)));
for (size_t coll_hash = 0; coll_hash < digitCache.size(); ++coll_hash) {
if (digitCache[coll_hash] && digitCache[coll_hash]->size()) {
ATH_CHECK(writeHandle->addCollection(digitCache[coll_hash].release(), coll_hash));
}
}
return StatusCode::SUCCESS;
}
}
#endif
\ No newline at end of file
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "MuonDigitizationR4/MuonDigitizationTool.h"
#include <xAODMuonSimHit/MuonSimHitAuxContainer.h>
#include <AthenaKernel/RNGWrapper.h>
#include <GeoModelHelpers/throwExcept.h>
namespace MuonR4{
MuonDigitizationTool::MuonDigitizationTool(const std::string& type,
const std::string& name,
const IInterface* pIID):
PileUpToolBase{type,name, pIID} {}
StatusCode MuonDigitizationTool::initialize(){
if (m_simHitKey.empty()) {
ATH_MSG_FATAL("Property <SimHitKey> not set !");
return StatusCode::FAILURE;
}
if (m_streamName.empty()) {
ATH_MSG_FATAL("Property "<<m_streamName<<" not set !");
return StatusCode::FAILURE;
}
if (m_onlyUseContainerName) {
m_inputObjectName = m_simHitKey.key();
ATH_CHECK(m_mergeSvc.retrieve());
}
/// Initialize ReadHandleKey
ATH_CHECK(m_simHitKey.initialize(!m_onlyUseContainerName));
ATH_CHECK(m_geoCtxKey.initialize());
ATH_CHECK(m_sdoKey.initialize(!m_sdoKey.empty()));
ATH_CHECK(m_rndmSvc.retrieve());
ATH_CHECK(detStore()->retrieve(m_detMgr));
ATH_CHECK(m_idHelperSvc.retrieve());
return StatusCode::SUCCESS;
}
StatusCode MuonDigitizationTool::prepareEvent(const EventContext& /*ctx*/,
unsigned int nInputEvents) {
ATH_MSG_DEBUG("prepareEvent() called for " << nInputEvents << " input events");
m_timedHits.clear();
return StatusCode::SUCCESS;
}
StatusCode MuonDigitizationTool::fillTimedHits(const PileUpHits& hitColl) {
for (const auto& [timeIndex, simHitColl] : hitColl) {
m_timedHits.reserve(m_timedHits.capacity() + simHitColl->size());
for (const xAOD::MuonSimHit* simHit : *simHitColl) {
m_timedHits.emplace_back(timeIndex.time(), timeIndex.index(), simHit, timeIndex.type());
}
}
std::sort(m_timedHits.begin(), m_timedHits.end(),
[](const TimedHitPtr<xAOD::MuonSimHit>& a, const TimedHitPtr<xAOD::MuonSimHit>& b){
if (a->identify() != b->identify()){
return a->identify() < b->identify();
}
if (a.eventId() != b.eventId()) {
return a.eventId() < b.eventId();
}
return a.eventTime() < b.eventTime();
});
return StatusCode::SUCCESS;
}
StatusCode MuonDigitizationTool::processAllSubEvents(const EventContext& ctx) {
PileUpHits hitCollList{};
/// In case of single hits container just load the collection using read handles
if (!m_onlyUseContainerName) {
const xAOD::MuonSimHitContainer* hitCollection{nullptr};
ATH_CHECK(retrieveContainer(ctx, m_simHitKey, hitCollection));
hitCollList.emplace_back(PileUpTimeEventIndex(0), hitCollection);
} else {
ATH_CHECK(m_mergeSvc->retrieveSubEvtsData(m_inputObjectName, hitCollList));
}
ATH_CHECK(fillTimedHits(hitCollList));
ATH_CHECK(mergeEvent(ctx));
return StatusCode::SUCCESS;
}
StatusCode MuonDigitizationTool::mergeEvent(const EventContext& ctx) {
ATH_MSG_DEBUG("mergeEvent()");
SG::WriteHandle<xAOD::MuonSimHitContainer> sdoContainer{};
if (!m_sdoKey.empty()) {
sdoContainer = SG::WriteHandle<xAOD::MuonSimHitContainer>{m_sdoKey, ctx};
ATH_CHECK(sdoContainer.record(std::make_unique<xAOD::MuonSimHitContainer>(),
std::make_unique<xAOD::MuonSimHitAuxContainer>()));
}
ATH_CHECK(digitize(ctx, m_timedHits, !m_sdoKey.empty() ? sdoContainer.ptr() : nullptr));
m_timedHits.clear();
return StatusCode::SUCCESS;
}
StatusCode MuonDigitizationTool::processBunchXing(int bunchXing,
SubEventIterator bSubEvents,
SubEventIterator eSubEvents) {
ATH_MSG_DEBUG("processBunchXing()" << bunchXing);
PileUpHits hitList{};
ATH_CHECK(m_mergeSvc->retrieveSubSetEvtData(m_inputObjectName, hitList, bunchXing, bSubEvents, eSubEvents));
ATH_MSG_VERBOSE(hitList.size() << " hits in xAODMuonSimHitContainer " << m_inputObjectName << " found");
ATH_CHECK(fillTimedHits(hitList));
return StatusCode::SUCCESS;
}
CLHEP::HepRandomEngine* MuonDigitizationTool::getRandomEngine(const EventContext&ctx) const {
ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_streamName);
std::string rngName = m_streamName;
rngWrapper->setSeed(rngName, ctx);
return rngWrapper->getEngine(ctx);
}
const ActsGeometryContext& MuonDigitizationTool::getGeoCtx(const EventContext& ctx) const {
const ActsGeometryContext* gctx{};
if (!retrieveContainer(ctx, m_geoCtxKey, gctx).isSuccess()) {
THROW_EXCEPTION("Failed to retrieve the geometry context "<<m_geoCtxKey.fullKey());
}
return *gctx;
}
void MuonDigitizationTool::addSDO(const TimedHit& hit, xAOD::MuonSimHitContainer* sdoContainer) const{
if(!sdoContainer) {
ATH_MSG_VERBOSE("No SDO container setup of writing");
return;
}
if (!m_includePileUpTruth && HepMC::ignoreTruthLink(hit->genParticleLink(), m_vetoPileUpTruthLinks)) {
ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hit->identify())<<" is a pile-up truth link");
return;
}
xAOD::MuonSimHit* sdoHit = sdoContainer->push_back(std::make_unique<xAOD::MuonSimHit>());
(*sdoHit) = (*hit);
static const SG::Accessor<float> acc_eventTime{"SDO_evtTime"};
static const SG::Accessor<unsigned short> acc_eventID{"SDO_evtID"};
static const SG::Accessor<unsigned short> acc_puType{"SDO_puType"};
acc_eventTime(*sdoHit) = hit.eventTime();
acc_eventID(*sdoHit) = hit.eventId();
acc_puType(*sdoHit) = hit.pileupType();
}
}
\ No newline at end of file
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