diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/CMakeLists.txt b/Tracker/TrackerDigitization/FaserSCT_Digitization/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e836c3e3cca2471e61dfe071ad8df8372dee261d --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/CMakeLists.txt @@ -0,0 +1,55 @@ +################################################################################ +# Package: FaserSCT_Digitization +################################################################################ + +# Declare the package name: +atlas_subdir( FaserSCT_Digitization ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + #Commission/CommissionEvent + Control/AthenaBaseComps + Control/AthenaKernel + Control/PileUpTools + DetectorDescription/Identifier + Event/xAOD/xAODEventInfo + GaudiKernel + InnerDetector/InDetConditions/InDetCondTools + Tracker/TrackerDigitization/FaserSiDigitization + InnerDetector/InDetRawEvent/InDetRawData + Tracker/TrackerSimEvent + Simulation/HitManagement + PRIVATE + Control/StoreGate + Generators/GeneratorObjects + #InnerDetector/InDetConditions/InDetConditionsSummaryService + #InnerDetector/InDetConditions/SCT_ConditionsTools + #InnerDetector/InDetConditions/SiPropertiesTool + Tracker/TrackerDetDescr/TrackerIdentifier + Tracker/TrackerDetDescr/TrackerReadoutGeometry + #InnerDetector/InDetDetDescr/SCT_ModuleDistortions + InnerDetector/InDetRawEvent/InDetSimData ) + +# External dependencies: +find_package( Boost COMPONENTS filesystem thread system ) +find_package( CLHEP ) +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_component( FaserSCT_Digitization + src/*.cxx + src/components/*.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ${CLHEP_LIBRARIES} AthenaBaseComps AthenaKernel PileUpToolsLib Identifier xAODEventInfo GaudiKernel FaserSiDigitization InDetRawData TrackerSimEvent HitManagement GeneratorObjects TrackerIdentifier TrackerReadoutGeometry InDetSimData ) +# LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ${CLHEP_LIBRARIES} CommissionEvent AthenaBaseComps AthenaKernel PileUpToolsLib Identifier xAODEventInfo GaudiKernel SiDigitization InDetRawData InDetSimEvent HitManagement GeneratorObjects SiPropertiesToolLib InDetIdentifier InDetReadoutGeometry InDetSimData ) + +#atlas_add_test( SCT_DigitizationMT_test +# SCRIPT Digi_tf.py --inputHITSFile /cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/DigitizationTests/HITS.04919495._001041.pool.root.1 --conditionsTag default:OFLCOND-RUN12-SDR-25 --digiSeedOffset1 170 --digiSeedOffset2 170 --geometryVersion ATLAS-R2-2015-03-01-00 --DataRunNumber 222525 --outputRDOFile mc15_2015_ttbar.RDO.pool.root --preInclude HITtoRDO:SimulationJobOptions/preInclude.SCTOnlyConfig.py,Digitization/ForceUseOfAlgorithms.py --postInclude Digitization/FixDataDependenciesForMT.py --skipEvents 0 --maxEvents 100 --athenaopts=--threads=10 +# PROPERTIES TIMEOUT 1200 +# ENVIRONMENT THREADS=10 ) + +# Install files from the package: +atlas_install_headers( FaserSCT_Digitization ) +atlas_install_python_modules( python/*.py ) +atlas_install_joboptions( share/*.py ) + diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ATLAS_CHECK_THREAD_SAFETY b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ATLAS_CHECK_THREAD_SAFETY new file mode 100644 index 0000000000000000000000000000000000000000..c5030c6d4ab80ea56f53ce2ea52e49acec23ed91 --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ATLAS_CHECK_THREAD_SAFETY @@ -0,0 +1 @@ +Tracker/TrackerDigitization/FaserSCT_Digitization \ No newline at end of file diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_Amp.h b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_Amp.h new file mode 100644 index 0000000000000000000000000000000000000000..267840df70550cf4cc63de8a9f5d3de8a9c86fa2 --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_Amp.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * ISCT_Amp.h + * Header file for abstract base class ISCT_Amp + * (c) ATLAS Detector software + * Interface for the SiChargedDiode processor classes + * 23/08/2007 Kondo.Gnanvo@cern.ch, and others + */ + +#ifndef FASERSIDIGITIZATION_ISCT_AMP_H +#define FASERSIDIGITIZATION_ISCT_AMP_H + +#include "GaudiKernel/IAlgTool.h" +#include "TrackerSimEvent/SiTotalCharge.h" + +#include <vector> + +static const InterfaceID IID_ISCT_Amp("ISCT_Amp", 1, 0); + +class ISCT_Amp : virtual public IAlgTool { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + typedef SiTotalCharge::list_t list_t; + + //Retrieve interface ID + static const InterfaceID& interfaceID() { return IID_ISCT_Amp; } + + // Destructor: + virtual ~ISCT_Amp() {} + + /////////////////////////////////////////////////////////////////// + // Pure virtual methods: + /////////////////////////////////////////////////////////////////// + + // process the collection of charged diodes + /** main purpose: CR-RC^3 response to a list of charges with times */ + virtual float response(const list_t& Charges, const float timeOverThreshold) const =0; + virtual void response(const list_t& Charges, const float timeOverThreshold, std::vector<float>& resp) const =0; + + /** Neighbour strip cross talk response strip to a list of charges with times */ + virtual float crosstalk(const list_t& Charges, const float timeOverThreshold) const =0; + virtual void crosstalk(const list_t& Charges, const float timeOverThreshold, std::vector<float> &resp) const =0; +}; + +#endif // FASERSIDIGITIZATION_ISCT_AMP_H diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_FrontEnd.h b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_FrontEnd.h new file mode 100644 index 0000000000000000000000000000000000000000..35a40ddbfa4f78825dae788954202f868c527732 --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_FrontEnd.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * ISCT_FrontEnd.h + * Header file for interface class for SCT_FrontEnd + * (c) ATLAS Detector software + */ + +#ifndef FASERSCT_DIGITIZATION_ISCT_FRONTEND_H +#define FASERSCT_DIGITIZATION_ISCT_FRONTEND_H + +//Inheritance +#include "FaserSiDigitization/ISiChargedDiodesProcessorTool.h" +#include "FaserSiDigitization/SiChargedDiode.h" + +//methods +#include "Identifier/Identifier.h" +class SiChargedDiodeCollection; +namespace CLHEP { + class HepRandomEngine; +} + +static const InterfaceID IID_ISCT_FrontEnd("ISCT_FrontEnd", 1, 0); + +class ISCT_FrontEnd : virtual public ISiChargedDiodesProcessorTool { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + //** Retrieve interface ID */ + static const InterfaceID& interfaceID() { return IID_ISCT_FrontEnd; } + + //** Destructor: */ + virtual ~ISCT_FrontEnd() {} + +}; + +#endif // FASERSCT_DIGITIZATION_ISCT_FRONTEND_H diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_RandomDisabledCellGenerator.h b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_RandomDisabledCellGenerator.h new file mode 100644 index 0000000000000000000000000000000000000000..d3c69bc251a9402ca1bb6e3a02cbd2c65c45a250 --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_RandomDisabledCellGenerator.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * ISCT_RandomDisabledCellGenerator.h + * Header file for interface class for SCT_RandomDisabledCellGenerator + * (c) ATLAS Detector software + */ + +#ifndef FASERSCT_DIGITIZATION_ISCT_RANDOMDISABLEDCELLGENERATOR_H +#define FASERSCT_DIGITIZATION_ISCT_RANDOMDISABLEDCELLGENERATOR_H + +//Inheritance +#include "FaserSiDigitization/ISiChargedDiodesProcessorTool.h" + +//methods +class SiChargedDiodeCollection; +namespace CLHEP { + class HepRandomEngine; +} + +static const InterfaceID IID_ISCT_RandomDisabledCellGenerator("ISCT_RandomDisabledCellGenerator",1,0); + +class ISCT_RandomDisabledCellGenerator : virtual public ISiChargedDiodesProcessorTool { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + //Retrieve interface ID + static const InterfaceID& interfaceID() { return IID_ISCT_RandomDisabledCellGenerator; } + + // Destructor: + virtual ~ISCT_RandomDisabledCellGenerator() {} + +}; + +#endif // FASERSCT_DIGITIZATION_ISCT_RANDOMDISABLEDCELLGENERATOR_H diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_SurfaceChargesGenerator.h b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_SurfaceChargesGenerator.h new file mode 100644 index 0000000000000000000000000000000000000000..9188844d716ab40eab7ff8fe924a240a0dee6a64 --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/FaserSCT_Digitization/ISCT_SurfaceChargesGenerator.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * ISCT_SurfaceChargesGenerator.h + * Header file for abstract base class ISCT_SurfaceChargesGenerator + * (c) ATLAS Detector software + * Interface for the Sct_SurfaceCharge generator classes + * Version 23/08/2007 Kondo Gnanvo + */ + +#ifndef FASERSCT_DIGITIZATION_ISCT_SURFACECHARGESGENERATOR_H +#define FASERSCT_DIGITIZATION_ISCT_SURFACECHARGESGENERATOR_H + +// Input/output classes +#include <list> +#include "FaserSiDigitization/SiSurfaceCharge.h" +#include "HitManagement/TimedHitPtr.h" + +#include "GaudiKernel/IAlgTool.h" + +class FaserSiHit; + +namespace TrackerDD { + class SiDetectorElement; +} +namespace CLHEP { + class HepRandomEngine; +} + +class ISiSurfaceChargesInserter +{ + public: + virtual ~ISiSurfaceChargesInserter() {} + virtual void operator() (const SiSurfaceCharge& scharge) const = 0; +}; + +static const InterfaceID IID_ISCT_SurfaceChargesGenerator("ISCT_SurfaceChargesGenerator",1,0); + +class ISCT_SurfaceChargesGenerator : virtual public IAlgTool { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + //Retrieve interface ID + static const InterfaceID& interfaceID() { return IID_ISCT_SurfaceChargesGenerator; } + + // Destructor: + virtual ~ISCT_SurfaceChargesGenerator() {} + + virtual void process(const TrackerDD::SiDetectorElement* ele, + const TimedHitPtr<FaserSiHit>& phit, + const ISiSurfaceChargesInserter& inserter, CLHEP::HepRandomEngine * rndmEngine) const =0; + virtual void setFixedTime(float fixedTime) =0; +}; + +#endif // FASERSCT_DIGITIZATION_ISCT_SURFACECHARGESGENERATOR_H diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/src/SCT_DigitizationTool.cxx b/Tracker/TrackerDigitization/FaserSCT_Digitization/src/SCT_DigitizationTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..981e3e97d98de8da7c12d9c5f15c91406255d8ee --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/src/SCT_DigitizationTool.cxx @@ -0,0 +1,795 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "SCT_DigitizationTool.h" + +// Mother Package includes +#include "FaserSiDigitization/SiHelper.h" +#include "FaserSiDigitization/SiChargedDiodeCollection.h" + +// EDM includes +#include "InDetRawData/SCT1_RawData.h" +#include "InDetRawData/SCT3_RawData.h" + +// Hit class includes +#include "TrackerSimEvent/FaserSiHit.h" +#include "Identifier/Identifier.h" + +// Det Descr includes +#include "TrackerReadoutGeometry/SiDetectorElement.h" +#include "TrackerReadoutGeometry/SCT_ModuleSideDesign.h" + +// Data Handle +#include "StoreGate/ReadCondHandle.h" +#include "StoreGate/ReadHandle.h" + +// Random Number Generation +#include "AthenaKernel/RNGWrapper.h" +#include "CLHEP/Random/RandomEngine.h" + +// C++ Standard Library +#include <memory> +#include <sstream> + +// Barcodes at the HepMC level are int + +using TrackerDD::SiCellId; + +SCT_DigitizationTool::SCT_DigitizationTool(const std::string& type, + const std::string& name, + const IInterface* parent) : + base_class(type, name, parent) { + m_WriteSCT1_RawData.declareUpdateHandler(&SCT_DigitizationTool::SetupRdoOutputType, this); +} + +SCT_DigitizationTool::~SCT_DigitizationTool() { + delete m_thpcsi; + for (FaserSiHitCollection* hit: m_hitCollPtrs) { + hit->Clear(); + delete hit; + } + m_hitCollPtrs.clear(); +} + +// ---------------------------------------------------------------------- +// Initialize method: +// ---------------------------------------------------------------------- +StatusCode SCT_DigitizationTool::initialize() { + ATH_MSG_DEBUG("SCT_DigitizationTool::initialize()"); + + // +++ Init the services + ATH_CHECK(initServices()); + + // +++ Get the Surface Charges Generator tool + ATH_CHECK(initSurfaceChargesGeneratorTool()); + + // +++ Get the Front End tool + ATH_CHECK(initFrontEndTool()); + + // +++ Initialise for disabled cells from the random disabled cells tool + // +++ Default off, since disabled cells taken form configuration in + // reconstruction stage + if (m_randomDisabledCells) { + ATH_CHECK(initDisabledCells()); + ATH_MSG_INFO("Use of Random disabled cells"); + } else { + m_sct_RandomDisabledCellGenerator.disable(); + } + + // check the input object name + if (m_hitsContainerKey.key().empty()) { + ATH_MSG_FATAL("Property InputObjectName not set !"); + return StatusCode::FAILURE; + } + if(m_onlyUseContainerName) m_inputObjectName = m_hitsContainerKey.key(); + ATH_MSG_DEBUG("Input objects in container : '" << m_inputObjectName << "'"); + + // Initialize ReadHandleKey + ATH_CHECK(m_hitsContainerKey.initialize(!m_onlyUseContainerName)); + + // +++ Initialize WriteHandleKey + ATH_CHECK(m_rdoContainerKey.initialize()); + ATH_CHECK(m_simDataCollMapKey.initialize()); + + // Initialize ReadCondHandleKey + ATH_CHECK(m_SCTDetEleCollKey.initialize()); + + ATH_MSG_DEBUG("SiDigitizationTool::initialize() complete"); + + return StatusCode::SUCCESS; +} + +namespace { + class SiDigitizationSurfaceChargeInserter + : public ISiSurfaceChargesInserter + { + public: + SiDigitizationSurfaceChargeInserter(const TrackerDD::SiDetectorElement* sielement, + SiChargedDiodeCollection* chargedDiodes) + : m_sielement(sielement), + m_chargedDiodes(chargedDiodes) { + } + + void operator () (const SiSurfaceCharge& scharge) const; + private: + const TrackerDD::SiDetectorElement* m_sielement; + SiChargedDiodeCollection* m_chargedDiodes; + }; + + + void SiDigitizationSurfaceChargeInserter::operator () + (const SiSurfaceCharge& scharge) const { + // get the diode in which this charge is + SiCellId diode{m_sielement->cellIdOfPosition(scharge.position())}; + + if (diode.isValid()) { + // add this charge to the collection (or merge in existing charged diode) + m_chargedDiodes->add(diode, scharge.charge()); + } + } +} // anonymous namespace + +// ---------------------------------------------------------------------- +// Initialise the surface charge generator Tool +// ---------------------------------------------------------------------- +StatusCode SCT_DigitizationTool::initSurfaceChargesGeneratorTool() { + ATH_CHECK(m_sct_SurfaceChargesGenerator.retrieve()); + + if (m_cosmicsRun and m_tfix > -998) { + m_sct_SurfaceChargesGenerator->setFixedTime(m_tfix); + ATH_MSG_INFO("Use of FixedTime = " << m_tfix << " in cosmics"); + } + + ATH_MSG_DEBUG("Retrieved and initialised tool " << m_sct_SurfaceChargesGenerator); + + return StatusCode::SUCCESS; +} + +// ---------------------------------------------------------------------- +// Initialise the Front End electronics Tool +// ---------------------------------------------------------------------- +StatusCode SCT_DigitizationTool::initFrontEndTool() { + ATH_CHECK(m_sct_FrontEnd.retrieve()); + + storeTool(&(*m_sct_FrontEnd)); + + ATH_MSG_DEBUG("Retrieved and initialised tool " << m_sct_FrontEnd); + return StatusCode::SUCCESS; +} + +// ---------------------------------------------------------------------- +// Initialize the different services +// ---------------------------------------------------------------------- +StatusCode SCT_DigitizationTool::initServices() { + // Get SCT ID helper for hash function and Store them using methods from the + // SiDigitization. + ATH_CHECK(detStore()->retrieve(m_detID, "FaserSCT_ID")); + + ATH_CHECK(m_mergeSvc.retrieve()); + ATH_CHECK(m_rndmSvc.retrieve()); + + return StatusCode::SUCCESS; +} + +// ---------------------------------------------------------------------- +// Initialize the disabled cells for cosmics or CTB cases +// ---------------------------------------------------------------------- +StatusCode SCT_DigitizationTool::initDisabledCells() { + // +++ Retrieve the SCT_RandomDisabledCellGenerator + ATH_CHECK(m_sct_RandomDisabledCellGenerator.retrieve()); + + storeTool(&(*m_sct_RandomDisabledCellGenerator)); + + ATH_MSG_INFO("Retrieved the SCT_RandomDisabledCellGenerator tool:" << m_sct_RandomDisabledCellGenerator); + return StatusCode::SUCCESS; +} + +StatusCode SCT_DigitizationTool::processAllSubEvents() { + if (prepareEvent(0).isFailure()) { + return StatusCode::FAILURE; + } + // Set the RNG to use for this event. + ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this); + rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() ); + CLHEP::HepRandomEngine *rndmEngine = *rngWrapper; + + ATH_MSG_VERBOSE("Begin digitizeAllHits"); + if (m_enableHits and (not getNextEvent().isFailure())) { + digitizeAllHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, m_thpcsi, rndmEngine); + } else { + ATH_MSG_DEBUG("no hits found in event!"); + } + ATH_MSG_DEBUG("Digitized Elements with Hits"); + + // loop over elements without hits + if (not m_onlyHitElements) { + digitizeNonHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, rndmEngine); + ATH_MSG_DEBUG("Digitized Elements without Hits"); + } + + delete m_thpcsi; + m_thpcsi = nullptr; + + ATH_MSG_VERBOSE("Digitize success!"); + return StatusCode::SUCCESS; +} + +// ====================================================================== +// prepareEvent +// ====================================================================== +StatusCode SCT_DigitizationTool::prepareEvent(unsigned int /*index*/) { + ATH_MSG_VERBOSE("SCT_DigitizationTool::prepareEvent()"); + // Create the IdentifiableContainer to contain the digit collections Create + // a new RDO container + m_rdoContainer = SG::makeHandle(m_rdoContainerKey); + ATH_CHECK(m_rdoContainer.record(std::make_unique<SCT_RDO_Container>(m_detID->wafer_hash_max()))); + + // Create a map for the SDO and register it into StoreGate + m_simDataCollMap = SG::makeHandle(m_simDataCollMapKey); + ATH_CHECK(m_simDataCollMap.record(std::make_unique<InDetSimDataCollection>())); + + m_processedElements.clear(); + m_processedElements.resize(m_detID->wafer_hash_max(), false); + + m_thpcsi = new TimedHitCollection<FaserSiHit>(); +// m_HardScatterSplittingSkipper = false; + return StatusCode::SUCCESS; +} + +// ========================================================================= +// mergeEvent +// ========================================================================= +StatusCode SCT_DigitizationTool::mergeEvent() { + ATH_MSG_VERBOSE("SCT_DigitizationTool::mergeEvent()"); + + // Set the RNG to use for this event. + ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this); + rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() ); + CLHEP::HepRandomEngine *rndmEngine = *rngWrapper; + + if (m_enableHits) { + digitizeAllHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, m_thpcsi, rndmEngine); + } + + if (not m_onlyHitElements) { + digitizeNonHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, rndmEngine); + } + + for (FaserSiHitCollection* hit: m_hitCollPtrs) { + hit->Clear(); + delete hit; + } + m_hitCollPtrs.clear(); + + delete m_thpcsi; + m_thpcsi = nullptr; + + ATH_MSG_DEBUG("Digitize success!"); + return StatusCode::SUCCESS; +} + +void SCT_DigitizationTool::digitizeAllHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, std::vector<bool>* processedElements, TimedHitCollection<FaserSiHit>* thpcsi, CLHEP::HepRandomEngine * rndmEngine) const { + ///////////////////////////////////////////////// + // + // In order to process all element rather than just those with hits we + // create a vector to keep track of which elements have been processed. + // NB. an element is an sct module + // + ///////////////////////////////////////////////// + ATH_MSG_DEBUG("Digitizing hits"); + int hitcount{0}; // First, elements with hits. + + SiChargedDiodeCollection chargedDiodes; + + while (digitizeElement(&chargedDiodes, thpcsi, rndmEngine)) { + ATH_MSG_DEBUG("Hit collection ID=" << m_detID->show_to_string(chargedDiodes.identify())); + + hitcount++; // Hitcount will be a number in the hit collection minus + // number of hits in missing mods + + ATH_MSG_DEBUG("in digitize elements with hits: station - layer - eta - phi " + << m_detID->station(chargedDiodes.identify()) << " - " + << m_detID->layer(chargedDiodes.identify()) << " - " + << m_detID->eta_module(chargedDiodes.identify()) << " - " + << m_detID->phi_module(chargedDiodes.identify()) << " - " + << " processing hit number " << hitcount); + + // Have a flag to check if the module is present or not + // Generally assume it is: + + IdentifierHash idHash{chargedDiodes.identifyHash()}; + + assert(idHash < processedElements->size()); + (*processedElements)[idHash] = true; + + // create and store RDO and SDO + + if (not chargedDiodes.empty()) { + StatusCode sc{createAndStoreRDO(&chargedDiodes, rdoContainer)}; + if (sc.isSuccess()) { // error msg is given inside + // createAndStoreRDO() + addSDO(&chargedDiodes, simDataCollMap); + } + } + + chargedDiodes.clear(); + } + ATH_MSG_DEBUG("hits processed"); + return; +} + +// digitize elements without hits +void SCT_DigitizationTool::digitizeNonHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, const std::vector<bool>* processedElements, CLHEP::HepRandomEngine * rndmEngine) const { + // Get SCT_DetectorElementCollection + SG::ReadCondHandle<TrackerDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey); + const TrackerDD::SiDetectorElementCollection* elements{sctDetEle.retrieve()}; + if (elements==nullptr) { + ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved"); + return; + } + + ATH_MSG_DEBUG("processing elements without hits"); + SiChargedDiodeCollection chargedDiodes; + + for (unsigned int i{0}; i < processedElements->size(); i++) { + if (not (*processedElements)[i]) { + IdentifierHash idHash{i}; + if (not idHash.is_valid()) { + ATH_MSG_ERROR("SCT Detector element id hash is invalid = " << i); + } + + const TrackerDD::SiDetectorElement* element{elements->getDetectorElement(idHash)}; + if (element) { + ATH_MSG_DEBUG("In digitize of untouched elements: layer - phi - eta " + << m_detID->layer(element->identify()) << " - " + << m_detID->phi_module(element->identify()) << " - " + << m_detID->eta_module(element->identify()) << " - " + << "size: " << processedElements->size()); + + chargedDiodes.setDetectorElement(element); + ATH_MSG_DEBUG("calling applyProcessorTools() for NON hits"); + applyProcessorTools(&chargedDiodes, rndmEngine); + + // Create and store RDO and SDO + // Don't create empty ones. + if (not chargedDiodes.empty()) { + StatusCode sc{createAndStoreRDO(&chargedDiodes, rdoContainer)}; + if (sc.isSuccess()) {// error msg is given inside + // createAndStoreRDO() + addSDO(&chargedDiodes, simDataCollMap); + } + } + + chargedDiodes.clear(); + } + } + } + + return; +} + +bool SCT_DigitizationTool::digitizeElement(SiChargedDiodeCollection* chargedDiodes, TimedHitCollection<FaserSiHit>*& thpcsi, CLHEP::HepRandomEngine * rndmEngine) const { + if (nullptr == thpcsi) { + ATH_MSG_ERROR("thpcsi should not be nullptr!"); + + return false; + } + + // get the iterator pairs for this DetEl + + TimedHitCollection<FaserSiHit>::const_iterator i, e; + if (thpcsi->nextDetectorElement(i, e) == false) { // no more hits + return false; + } + + // create the identifier for the collection: + ATH_MSG_DEBUG("create ID for the hit collection"); + const TimedHitPtr<FaserSiHit>& firstHit{*i}; + int barrel{firstHit->getStation()}; + Identifier id{m_detID->wafer_id(barrel, + firstHit->getPlane(), + firstHit->getRow(), + firstHit->getModule(), + firstHit->getSensor())}; + IdentifierHash waferHash{m_detID->wafer_hash(id)}; + + // Get SCT_DetectorElementCollection + SG::ReadCondHandle<TrackerDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey); + const TrackerDD::SiDetectorElementCollection* elements(sctDetEle.retrieve()); + if (elements==nullptr) { + ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved"); + return false; + } + + // get the det element from the manager + const TrackerDD::SiDetectorElement* sielement{elements->getDetectorElement(waferHash)}; + + if (sielement == nullptr) { + ATH_MSG_DEBUG("Station=" << barrel << " layer=" << firstHit->getPlane() << " Row=" << firstHit->getRow() << " Module=" << firstHit->getModule() << " Side=" << firstHit->getSensor()); + ATH_MSG_ERROR("detector manager could not find element with id = " << id); + return false; + } + // create the charged diodes collection + chargedDiodes->setDetectorElement(sielement); + + // Loop over the hits and created charged diodes: + while (i != e) { + TimedHitPtr<FaserSiHit> phit{*i++}; + + // skip hits which are more than 10us away + if (fabs(phit->meanTime()) < 10000. * CLHEP::ns) { + ATH_MSG_DEBUG("HASH = " << m_detID->wafer_hash(m_detID->wafer_id(phit->getStation(), + phit->getPlane(), + phit->getRow(), + phit->getModule(), + phit->getSensor()))); + ATH_MSG_DEBUG("calling process() for all methods"); + m_sct_SurfaceChargesGenerator->process(sielement, phit, SiDigitizationSurfaceChargeInserter(sielement, chargedDiodes), rndmEngine); + ATH_MSG_DEBUG("charges filled!"); + } + } + applyProcessorTools(chargedDiodes, rndmEngine); // !< Use of the new AlgTool surface + // charges generator class + return true; +} + +// ----------------------------------------------------------------------------- +// Applies processors to the current detector element for the current element: +// ----------------------------------------------------------------------------- +void SCT_DigitizationTool::applyProcessorTools(SiChargedDiodeCollection* chargedDiodes, CLHEP::HepRandomEngine * rndmEngine) const { + ATH_MSG_DEBUG("applyProcessorTools()"); + int processorNumber{0}; + + for (ISiChargedDiodesProcessorTool* proc: m_diodeCollectionTools) { + proc->process(*chargedDiodes, rndmEngine); + + processorNumber++; + ATH_MSG_DEBUG("Applied processor # " << processorNumber); + } +} + +StatusCode SCT_DigitizationTool::processBunchXing(int bunchXing, + SubEventIterator bSubEvents, + SubEventIterator eSubEvents) { + ATH_MSG_VERBOSE("SCT_DigitizationTool::processBunchXing() " << bunchXing); + + typedef PileUpMergeSvc::TimedList<FaserSiHitCollection>::type TimedHitCollList; + TimedHitCollList hitCollList; + + if ((not (m_mergeSvc->retrieveSubSetEvtData(m_inputObjectName, hitCollList, bunchXing, + bSubEvents, eSubEvents).isSuccess())) and + hitCollList.size() == 0) { + ATH_MSG_ERROR("Could not fill TimedHitCollList"); + return StatusCode::FAILURE; + } else { + ATH_MSG_VERBOSE(hitCollList.size() << " SiHitCollections with key " << + m_inputObjectName << " found"); + } + + TimedHitCollList::iterator endColl{hitCollList.end()}; + for (TimedHitCollList::iterator iColl{hitCollList.begin()}; iColl != endColl; iColl++) { + FaserSiHitCollection *hitCollPtr{new FaserSiHitCollection(*iColl->second)}; + PileUpTimeEventIndex timeIndex{iColl->first}; + ATH_MSG_DEBUG("SiHitCollection found with " << hitCollPtr->size() << + " hits"); + ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time() + << " index: " << timeIndex.index() + << " type: " << timeIndex.type()); + m_thpcsi->insert(timeIndex, hitCollPtr); + m_hitCollPtrs.push_back(hitCollPtr); + } + + return StatusCode::SUCCESS; + +} + +// ========================================================================= +// property handlers +// ========================================================================= +void SCT_DigitizationTool::SetupRdoOutputType(Property &) { +} + +// Does nothing, but required by Gaudi + +// ---------------------------------------------------------------------- +// Digitisation of non hit elements +// ---------------------------------------------------------------------- + +class DigitizeNonHitElementsDebugPrinter +{ +public: + DigitizeNonHitElementsDebugPrinter(const FaserSCT_ID* detID) : + m_detID{detID}, m_msgNo{-1} { + } + + std::string msg(const TrackerDD::SiDetectorElement* element) { + std::ostringstream ost; + + ost << "Digitized unprocessed elements: layer - phi - eta - side " + << m_detID->layer(element->identify()) << " - " + << m_detID->phi_module(element->identify()) << " - " + << m_detID->eta_module(element->identify()) << " - " + << m_detID->side(element->identify()) << " - " + << " unprocessed hit number: " << ++m_msgNo << '\n'; + + return ost.str(); + } + +private: + const FaserSCT_ID* m_detID; + int m_msgNo; +}; + +// ----------------------------------------------------------------------// +// createAndStoreRDO // +// ----------------------------------------------------------------------// +StatusCode SCT_DigitizationTool::createAndStoreRDO(SiChargedDiodeCollection* chDiodeCollection, SG::WriteHandle<SCT_RDO_Container>* rdoContainer) const { + + // Create the RDO collection + SCT_RDO_Collection* RDOColl{createRDO(chDiodeCollection)}; + + // Add it to storegate + if ((*rdoContainer)->addCollection(RDOColl, RDOColl->identifyHash()).isFailure()) { + ATH_MSG_FATAL("SCT RDO collection could not be added to container!"); + delete RDOColl; + RDOColl = nullptr; + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} // SCT_Digitization::createAndStoreRDO() + +// ---------------------------------------------------------------------- +// createRDO +// ---------------------------------------------------------------------- +SCT_RDO_Collection* SCT_DigitizationTool::createRDO(SiChargedDiodeCollection* collection) const { + + // create a new SCT RDO collection + SCT_RDO_Collection* p_rdocoll{nullptr}; + + // need the DE identifier + const Identifier id_de{collection->identify()}; + IdentifierHash idHash_de{collection->identifyHash()}; + try { + p_rdocoll = new SCT_RDO_Collection(idHash_de); + } catch (const std::bad_alloc&) { + ATH_MSG_FATAL("Could not create a new SCT_RDORawDataCollection !"); + } + p_rdocoll->setIdentifier(id_de); + + SiChargedDiodeIterator i_chargedDiode{collection->begin()}; + SiChargedDiodeIterator i_chargedDiode_end{collection->end()}; + // Choice of producing SCT1_RawData or SCT3_RawData + if (m_WriteSCT1_RawData.value()) { + for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) { + unsigned int flagmask{static_cast<unsigned int>((*i_chargedDiode).second.flag() & 0xFE)}; + + if (!flagmask) { // now check it wasn't masked: + // create new SCT RDO, using method 1 for mask: + // GroupSize=1: need readout id, make use of + // SiTrackerDetDescr + TrackerDD::SiReadoutCellId roCell{(*i_chargedDiode).second.getReadoutCell()}; + int strip{roCell.strip()}; + if (strip > 0xffff) { // In upgrade layouts strip can be bigger + // than 4000 + ATH_MSG_FATAL("Strip number too big for SCT1 raw data format."); + } + const Identifier id_readout{m_detID->strip_id(collection->identify(), strip)}; + + // build word, masks taken from SiTrackerEvent/SCTRawData.cxx + const unsigned int strip_rdo{static_cast<unsigned int>((strip & 0xFFFF) << 16)}; + + // user can define what GroupSize is, here 1: TC. Incorrect, + // GroupSize >= 1 + int size{SiHelper::GetStripNum((*i_chargedDiode).second)}; + unsigned int size_rdo{static_cast<unsigned int>(size & 0xFFFF)}; + + // TC. Need to check if there are disabled strips in the cluster + int cluscounter{0}; + if (size > 1) { + SiChargedDiodeIterator it2{i_chargedDiode}; + ++it2; + for (; it2 != i_chargedDiode_end; ++it2) { + ++cluscounter; + if (cluscounter >= size) { + break; + } + if (it2->second.flag() & 0xDE) { + int tmp{cluscounter}; + while ((it2 != i_chargedDiode_end) and (cluscounter < size - 1) and (it2->second.flag() & 0xDE)) { + it2++; + cluscounter++; + } + if ((it2 != collection->end()) and !(it2->second.flag() & 0xDE)) { + SiHelper::ClusterUsed(it2->second, false); + SiHelper::SetStripNum(it2->second, size - cluscounter, &msg()); + } + // groupSize=tmp; + size_rdo = tmp & 0xFFFF; + break; + } + } + } + unsigned int SCT_Word{strip_rdo | size_rdo}; + SCT1_RawData* p_rdo{new SCT1_RawData(id_readout, SCT_Word)}; + if (p_rdo) { + p_rdocoll->push_back(p_rdo); + } + } + } + } else { + // Under the current scheme time bin and ERRORS are hard-coded to + // default values. + int ERRORS{0}; + static std::vector<int> dummyvector; + for (; i_chargedDiode != i_chargedDiode_end; ++i_chargedDiode) { + unsigned int flagmask{static_cast<unsigned int>((*i_chargedDiode).second.flag() & 0xFE)}; + + if (!flagmask) { // Check it wasn't masked + int tbin{SiHelper::GetTimeBin((*i_chargedDiode).second)}; + // create new SCT RDO + TrackerDD::SiReadoutCellId roCell{(*i_chargedDiode).second.getReadoutCell()}; + int strip{roCell.strip()}; + Identifier id_readout; + id_readout = m_detID->strip_id(collection->identify(), strip); + + // build word (compatible with + // SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx) + int size{SiHelper::GetStripNum((*i_chargedDiode).second)}; + int groupSize{size}; + + // TC. Need to check if there are disabled strips in the cluster + int cluscounter{0}; + if (size > 1) { + SiChargedDiode* diode{i_chargedDiode->second.nextInCluster()}; + while (diode) {//check if there is a further strip in the cluster + ++cluscounter; + if (cluscounter >= size) { + ATH_MSG_WARNING("Cluster size reached while neighbouring strips still defined."); + break; + } + if (diode->flag() & 0xDE) {//see if it is disabled/below threshold/disconnected/etc (0xDE corresponds to BT_SET | DISABLED_SET | BADTOT_SET | DISCONNECTED_SET | MASKOFF_SET) + int tmp{cluscounter}; + while ((cluscounter < size - 1) and (diode->flag() & 0xDE)) { //check its not the end and still disabled + diode = diode->nextInCluster(); + cluscounter++; + } + if (diode and !(diode->flag() & 0xDE)) { + SiHelper::ClusterUsed(*diode, false); + SiHelper::SetStripNum(*diode, size - cluscounter, &msg()); + } + groupSize = tmp; + break; + } + diode = diode->nextInCluster(); + } + } + + int stripIn11bits{strip & 0x7ff}; + if (stripIn11bits != strip) { + ATH_MSG_DEBUG("Strip number " << strip << " doesn't fit into 11 bits - will be truncated"); + } + + unsigned int SCT_Word{static_cast<unsigned int>(groupSize | (stripIn11bits << 11) | (tbin << 22) | (ERRORS << 25))}; + SCT3_RawData *p_rdo{new SCT3_RawData(id_readout, SCT_Word, &dummyvector)}; + if (p_rdo) { + p_rdocoll->push_back(p_rdo); + } + } + } + } + return p_rdocoll; +} // SCT_Digitization::createRDO() + +// ------------------------------------------------------------ +// Get next event and extract collection of hit collections: +// ------------------------------------------------------------ +StatusCode SCT_DigitizationTool::getNextEvent() { + ATH_MSG_DEBUG("SCT_DigitizationTool::getNextEvent()"); + // get the container(s) + typedef PileUpMergeSvc::TimedList<FaserSiHitCollection>::type TimedHitCollList; + // this is a list<pair<time_t, DataLink<SiHitCollection> > + + // In case of single hits container just load the collection using read handles + if (!m_onlyUseContainerName) { + SG::ReadHandle<FaserSiHitCollection> hitCollection(m_hitsContainerKey); + if (!hitCollection.isValid()) { + ATH_MSG_ERROR("Could not get SCT SiHitCollection container " << hitCollection.name() << " from store " << hitCollection.store()); + return StatusCode::FAILURE; + } + + // create a new hits collection + m_thpcsi = new TimedHitCollection<FaserSiHit>{1}; + m_thpcsi->insert(0, hitCollection.cptr()); + ATH_MSG_DEBUG("SiHitCollection found with " << hitCollection->size() << " hits"); + + return StatusCode::SUCCESS; + } + + TimedHitCollList hitCollList; + unsigned int numberOfSiHits{0}; + if (not (m_mergeSvc->retrieveSubEvtsData(m_inputObjectName, hitCollList, numberOfSiHits).isSuccess()) and hitCollList.size() == 0) { + ATH_MSG_ERROR("Could not fill TimedHitCollList"); + return StatusCode::FAILURE; + } else { + ATH_MSG_DEBUG(hitCollList.size() << " SiHitCollections with key " << m_inputObjectName << " found"); + } + // create a new hits collection + m_thpcsi = new TimedHitCollection<FaserSiHit>{numberOfSiHits}; + // now merge all collections into one + TimedHitCollList::iterator endColl{hitCollList.end()}; + for (TimedHitCollList::iterator iColl{hitCollList.begin()}; iColl != endColl; ++iColl) { + const FaserSiHitCollection* p_collection{iColl->second}; + m_thpcsi->insert(iColl->first, p_collection); + ATH_MSG_DEBUG("SiTrackerHitCollection found with " << p_collection->size() << " hits"); // loop on the hit collections + } + return StatusCode::SUCCESS; +} + +// ----------------------------------------------------------------------------------------------- +// Convert a SiTotalCharge to a InDetSimData, and store it. +// ----------------------------------------------------------------------------------------------- +void SCT_DigitizationTool::addSDO(SiChargedDiodeCollection* collection, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap) const { + typedef SiTotalCharge::list_t list_t; + std::vector<InDetSimData::Deposit> deposits; + deposits.reserve(5); // no idea what a reasonable number for this would be + // with pileup + // loop over the charged diodes + SiChargedDiodeIterator EndOfDiodeCollection{collection->end()}; + for (SiChargedDiodeIterator i_chargedDiode{collection->begin()}; i_chargedDiode != EndOfDiodeCollection; ++i_chargedDiode) { + deposits.clear(); + const list_t& charges{(*i_chargedDiode).second.totalCharge().chargeComposition()}; + + bool real_particle_hit{false}; + // loop over the list + list_t::const_iterator EndOfChargeList{charges.end()}; + for (list_t::const_iterator i_ListOfCharges{charges.begin()}; i_ListOfCharges != EndOfChargeList; ++i_ListOfCharges) { + const HepMcParticleLink& trkLink{i_ListOfCharges->particleLink()}; + const int barcode{trkLink.barcode()}; + if ((barcode == 0) or (barcode == m_vetoThisBarcode)) { + continue; + } + if (not real_particle_hit) { + // Types of SiCharges expected from SCT + // Noise: barcode==0 and + // processType()==SiCharge::noise + // Delta Rays: barcode==0 and + // processType()==SiCharge::track + // Pile Up Tracks With No Truth: barcode!=0 and + // processType()==SiCharge::cut_track + // Tracks With Truth: barcode!=0 and + // processType()==SiCharge::track + if (barcode != 0 and i_ListOfCharges->processType() == SiCharge::track) { + real_particle_hit = true; + } + } + // check if this track number has been already used. + std::vector<InDetSimData::Deposit>::reverse_iterator theDeposit{deposits.rend()}; // dummy value + std::vector<InDetSimData::Deposit>::reverse_iterator depositsR_end{deposits.rend()}; + std::vector<InDetSimData::Deposit>::reverse_iterator i_Deposit{deposits.rbegin()}; + for (; i_Deposit != depositsR_end; ++i_Deposit) { + if ((*i_Deposit).first == trkLink) { + theDeposit = i_Deposit; + break; + } + } + + // if the charge has already hit the Diode add it to the deposit + if (theDeposit != depositsR_end) { + (*theDeposit).second += i_ListOfCharges->charge(); + } else { // create a new deposit + InDetSimData::Deposit deposit(trkLink, i_ListOfCharges->charge()); + deposits.push_back(deposit); + } + } + + // add the simdata object to the map: + if (real_particle_hit or m_createNoiseSDO) { + TrackerDD::SiReadoutCellId roCell{(*i_chargedDiode).second.getReadoutCell()}; + int strip{roCell.strip()}; + Identifier id_readout; + id_readout = m_detID->strip_id(collection->identify(),strip); + (*simDataCollMap)->insert(std::make_pair(id_readout, InDetSimData(deposits, (*i_chargedDiode).second.flag()))); + } + } +} diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/src/SCT_DigitizationTool.h b/Tracker/TrackerDigitization/FaserSCT_Digitization/src/SCT_DigitizationTool.h new file mode 100644 index 0000000000000000000000000000000000000000..f34d0619d4bb0538d63e4ded88df576d5b175f44 --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/src/SCT_DigitizationTool.h @@ -0,0 +1,156 @@ +/* -*- C++ -*- */ + +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERSCT_DIGITZATION_SCT_DIGITZATIONTOOL_H +#define FASERSCT_DIGITZATION_SCT_DIGITZATIONTOOL_H +/** @file SCT_DigitizationTool.h + * @brief Digitize the SCT using an implementation of IPileUpTool + * $Id: SCT_DigitizationTool.h,v 1.0 2009-09-22 18:34:42 jchapman Exp $ + * @author John Chapman - ATLAS Collaboration + */ + +//Base class header +#include "PileUpTools/PileUpToolBase.h" + +// Athena headers +#include "AthenaKernel/IAthRNGSvc.h" +#include "HitManagement/TimedHitCollection.h" +#include "InDetRawData/SCT_RDO_Container.h" +#include "TrackerReadoutGeometry/SiDetectorElementCollection.h" +#include "InDetSimData/InDetSimDataCollection.h" +#include "TrackerSimEvent/FaserSiHitCollection.h" +#include "PileUpTools/PileUpMergeSvc.h" +#include "FaserSCT_Digitization/ISCT_FrontEnd.h" +#include "FaserSCT_Digitization/ISCT_RandomDisabledCellGenerator.h" +#include "FaserSCT_Digitization/ISCT_SurfaceChargesGenerator.h" +#include "StoreGate/ReadCondHandleKey.h" +#include "StoreGate/ReadHandleKey.h" +#include "StoreGate/WriteHandle.h" +#include "StoreGate/WriteHandleKey.h" + +// Gaudi headers +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/ToolHandle.h" + +// STL headers +#include <limits> +#include <string> + +// Forward declarations +class ISiChargedDiodesProcessorTool; +class FaserSCT_ID; +class SiChargedDiodeCollection; + +namespace CLHEP +{ + class HepRandomEngine; +} + +class SCT_DigitizationTool : public extends<PileUpToolBase, IPileUpTool> +{ +public: + static const InterfaceID& interfaceID(); + SCT_DigitizationTool(const std::string& type, + const std::string& name, + const IInterface* parent); + virtual ~SCT_DigitizationTool(); + /** + @brief Called before processing physics events + */ + virtual StatusCode prepareEvent(unsigned int) override final; + virtual StatusCode processBunchXing(int bunchXing, + SubEventIterator bSubEvents, + SubEventIterator eSubEvents) override final; + virtual StatusCode mergeEvent() override final; + + virtual StatusCode initialize() override final; + virtual StatusCode processAllSubEvents() override final; + +protected: + + bool digitizeElement(SiChargedDiodeCollection* chargedDiodes, TimedHitCollection<FaserSiHit>*& thpcsi, CLHEP::HepRandomEngine * rndmEngine) const ; //! + void applyProcessorTools(SiChargedDiodeCollection* chargedDiodes, CLHEP::HepRandomEngine * rndmEngine) const; //! + void addSDO(SiChargedDiodeCollection* collection, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap) const; + + void storeTool(ISiChargedDiodesProcessorTool* p_processor) {m_diodeCollectionTools.push_back(p_processor);} + +private: + + /** + @brief initialize the required services + */ + StatusCode initServices(); + /** + @brief Initialize the SCT_FrontEnd AlgTool + */ + StatusCode initFrontEndTool(); + /** + @brief Initialize the SCT_RandomDisabledCellGenerator AlgTool + */ + StatusCode initDisabledCells(); + /** + @brief Initialize the SCT_SurfaceChargesGenerator AlgTool + */ + StatusCode initSurfaceChargesGeneratorTool(); + + /** RDO and SDO methods*/ + /** + @brief Create RDOs from the SiChargedDiodeCollection for the current wafer and save to StoreGate + @param chDiodeCollection list of the SiChargedDiodes on the current wafer + */ + StatusCode createAndStoreRDO(SiChargedDiodeCollection* chDiodeCollection, SG::WriteHandle<SCT_RDO_Container>* rdoContainer) const; + /** + @brief Create RDOs from the SiChargedDiodeCollection for the current wafer + @param chDiodeCollection list of the SiChargedDiodes on the current wafer + */ + SCT_RDO_Collection* createRDO(SiChargedDiodeCollection* collection) const; + + StatusCode getNextEvent(); + void digitizeAllHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, std::vector<bool>* processedElements, TimedHitCollection<FaserSiHit>* thpcsi, CLHEP::HepRandomEngine * rndmEngine) const; //!< digitize all hits + void digitizeNonHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, const std::vector<bool>* processedElements, CLHEP::HepRandomEngine * rndmEngine) const; //!< digitize SCT without hits + + /** + @brief Called when m_WriteSCT1_RawData is altered. Does nothing, but required by Gaudi. + */ + void SetupRdoOutputType(Property&); + + FloatProperty m_tfix{this, "FixedTime", -999., "Fixed time for Cosmics run selection"}; + BooleanProperty m_enableHits{this, "EnableHits", true, "Enable hits"}; + BooleanProperty m_onlyHitElements{this, "OnlyHitElements", false, "Process only elements with hits"}; + BooleanProperty m_cosmicsRun{this, "CosmicsRun", false, "Cosmics run selection"}; + BooleanProperty m_randomDisabledCells{this, "RandomDisabledCells", false, "Use Random disabled cells, default no"}; + BooleanProperty m_createNoiseSDO{this, "CreateNoiseSDO", false, "Create SDOs for strips with only noise hits (huge increase in SDO collection size"}; + BooleanProperty m_WriteSCT1_RawData{this, "WriteSCT1_RawData", false, "Write out SCT1_RawData rather than SCT3_RawData"}; + + BooleanProperty m_onlyUseContainerName{this, "OnlyUseContainerName", true, "Don't use the ReadHandleKey directly. Just extract the container name from it."}; + SG::ReadHandleKey<FaserSiHitCollection> m_hitsContainerKey{this, "InputObjectName", "SCT_Hits", "Input HITS collection name"}; + std::string m_inputObjectName{""}; + + SG::WriteHandleKey<SCT_RDO_Container> m_rdoContainerKey{this, "OutputObjectName", "SCT_RDOs", "Output Object name"}; + SG::WriteHandle<SCT_RDO_Container> m_rdoContainer; //!< RDO container handle + SG::WriteHandleKey<InDetSimDataCollection> m_simDataCollMapKey{this, "OutputSDOName", "SCT_SDO_Map", "Output SDO container name"}; + SG::WriteHandle<InDetSimDataCollection> m_simDataCollMap; //!< SDO Map handle + SG::ReadCondHandleKey<TrackerDD::SiDetectorElementCollection> m_SCTDetEleCollKey{this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"}; + + ToolHandle<ISCT_FrontEnd> m_sct_FrontEnd{this, "FrontEnd", "SCT_FrontEnd", "Handle the Front End Electronic tool"}; + ToolHandle<ISCT_SurfaceChargesGenerator> m_sct_SurfaceChargesGenerator{this, "SurfaceChargesGenerator", "SCT_SurfaceChargesGenerator", "Choice of using a more detailed charge drift model"}; + ToolHandle<ISCT_RandomDisabledCellGenerator> m_sct_RandomDisabledCellGenerator{this, "RandomDisabledCellGenerator", "SCT_RandomDisabledCellGenerator", ""}; + ServiceHandle<IAthRNGSvc> m_rndmSvc{this, "RndmSvc", "AthRNGSvc", ""}; //!< Random number service + ServiceHandle <PileUpMergeSvc> m_mergeSvc{this, "MergeSvc", "PileUpMergeSvc", "Merge service used in Pixel & SCT digitization"}; //! + + const FaserSCT_ID* m_detID{nullptr}; //!< Handle to the ID helper + TimedHitCollection<FaserSiHit>* m_thpcsi{nullptr}; + std::list<ISiChargedDiodesProcessorTool*> m_diodeCollectionTools; + std::vector<bool> m_processedElements; //!< vector of processed elements - set by digitizeHits() */ + std::vector<FaserSiHitCollection*> m_hitCollPtrs; +}; + +static const InterfaceID IID_ISCT_DigitizationTool("SCT_DigitizationTool", 1, 0); +inline const InterfaceID& SCT_DigitizationTool::interfaceID() { + return IID_ISCT_DigitizationTool; +} + +#endif // FASERSCT_DIGITZATION_SCT_DIGITZATIONTOOL_H diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/src/components/FaserSCT_Digitization_entries.cxx b/Tracker/TrackerDigitization/FaserSCT_Digitization/src/components/FaserSCT_Digitization_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..dc705d93a4a8e156f3824cd286a678c8d9b08010 --- /dev/null +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/src/components/FaserSCT_Digitization_entries.cxx @@ -0,0 +1,16 @@ +// #include "../SCT_Amp.h" +// #include "../SCT_FrontEnd.h" +// #include "../SCT_Digitization.h" +#include "../SCT_DigitizationTool.h" +// #include "../SCT_SurfaceChargesGenerator.h" +// #include "../SCT_DetailedSurfaceChargesGenerator.h" +// #include "../SCT_RandomDisabledCellGenerator.h" + +// DECLARE_COMPONENT( SCT_Digitization ) +// DECLARE_COMPONENT( SCT_Amp ) +// DECLARE_COMPONENT( SCT_FrontEnd ) +DECLARE_COMPONENT( SCT_DigitizationTool ) +// DECLARE_COMPONENT( SCT_SurfaceChargesGenerator ) +// DECLARE_COMPONENT( SCT_DetailedSurfaceChargesGenerator ) +// DECLARE_COMPONENT( SCT_RandomDisabledCellGenerator ) +