From 6658b1f2b8f48ffc1a8d535d7623b36a5a4bfec1 Mon Sep 17 00:00:00 2001 From: kochebina Date: Tue, 5 Dec 2023 17:20:06 +0100 Subject: [PATCH] Xtalk in GND --- CMakeLists.txt | 1 - source/digits_hits/include/GateCrosstalk.hh | 197 ++++---- .../include/GateCrosstalkMessenger.hh | 57 ++- .../include/GateIntrinsicResolution.hh | 6 + .../GateIntrinsicResolutionMessenger.hh | 2 + source/digits_hits/src/GateCrosstalk.cc | 453 +++++++++++------- .../digits_hits/src/GateCrosstalkMessenger.cc | 89 ++-- .../src/GateIntrinsicResolution.cc | 24 +- .../src/GateIntrinsicResolutionMessenger.cc | 19 + .../src/GateSinglesDigitizerMessenger.cc | 10 +- 10 files changed, 527 insertions(+), 331 deletions(-) mode change 100644 => 100755 source/digits_hits/include/GateCrosstalk.hh mode change 100644 => 100755 source/digits_hits/include/GateCrosstalkMessenger.hh mode change 100644 => 100755 source/digits_hits/src/GateCrosstalk.cc mode change 100644 => 100755 source/digits_hits/src/GateCrosstalkMessenger.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d1919b76b..777d05a1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,7 +318,6 @@ MESSAGE("- Coincidence digitizer modules (combining of several Coincidence Sorte MESSAGE("- Compton Camera digitizer modules and output") MESSAGE("- Output: Sinogram, Ecat7, LMF") MESSAGE("- ARF may work not properly yet") -MESSAGE("- Digitizer Modules to be added soon: Buffer, intrinsicResolutionBlurring, lightYield, transferEfficiency, quantumEfficiency, crosstalk, calibration") MESSAGE("We apologize for this inconvenience and kindly ask for your patience.") MESSAGE("This functionalities will be added during 2023.") MESSAGE("Meanwhile, please, use Gate 9.2") diff --git a/source/digits_hits/include/GateCrosstalk.hh b/source/digits_hits/include/GateCrosstalk.hh old mode 100644 new mode 100755 index c9dab5ddb..ad09a5de6 --- a/source/digits_hits/include/GateCrosstalk.hh +++ b/source/digits_hits/include/GateCrosstalk.hh @@ -6,91 +6,80 @@ of the GNU Lesser General Public Licence (LGPL) See LICENSE.md for further details ----------------------*/ +// OK GND 2022 +/*! \class GateCrosstalk + \brief Digitizer Module for simulating an optical and/or an electronic Crosstalk + - GateCrosstalk - by Martin.Rey@epfl.ch (dec 2002) + + - Digitizer Module for simulating an optical and/or an electronic Crosstalk + of the scintillation light between the neighbor crystals: + if the input Digi arrives in a crystal array, Digis around + it are created (in the edge and corner neighbor crystals). + ATTENTION: this module functions only for a chosen volume which is an array repeater !!! + + 5/12/23 - added to GND by kochebina@cea.fr but MAYBE NOT PROPERLY TESTED !!!! + + \sa GateVDigitizerModule +*/ #ifndef GateCrosstalk_h #define GateCrosstalk_h 1 +#include "GateVDigitizerModule.hh" +#include "GateDigi.hh" +#include "GateClockDependent.hh" +#include "GateCrystalSD.hh" + #include "globals.hh" -#include -#include -#include "GateVPulseProcessor.hh" +#include "GateCrosstalkMessenger.hh" +#include "GateSinglesDigitizer.hh" -class GateCrosstalkMessenger; class GateArrayParamsFinder; -class GateOutputVolumeID; -/*! \class GateCrosstalk - \brief Pulse-processor for simulating an optical and/or an electronic crosstalk - - GateCrosstalk - by Martin.Rey@epfl.ch (dec 2002) +class GateCrosstalk : public GateVDigitizerModule +{ +public: + //! This function allows to retrieve the current instance of the GateCrosstalk singleton + /*! + If the GateCrosstalk already exists, GetInstance only returns a pointer to this singleton. + If this singleton does not exist yet, GetInstance creates it by calling the private + GateCrosstalk constructor + */ + static GateCrosstalk* GetInstance(GateSinglesDigitizer* itsChain, + const G4String& itsName, + G4double itsEdgesFraction, G4double itsCornersFraction); - - Pulse-processor for simulating an optical and/or an electronic crosstalk - of the scintillation light between the neighbor crystals: - if the input pulse arrives in a crystal array, pulses around - it are created (in the edge and corner neighbor crystals). - ATTENTION: this module functions only for a chosen volume which is an array repeater !!! + GateCrosstalk(GateSinglesDigitizer *digitizer, G4String name, G4double itsEdgesFraction, G4double itsCornersFraction); + ~GateCrosstalk(); + + void Digitize() override; - \sa GateVPulseProcessor -*/ -class GateCrosstalk : public GateVPulseProcessor -{ - public: - //! This function allows to retrieve the current instance of the GateCrosstalk singleton - /*! - If the GateCrosstalk already exists, GetInstance only returns a pointer to this singleton. - If this singleton does not exist yet, GetInstance creates it by calling the private - GateCrosstalk constructor - */ - static GateCrosstalk* GetInstance(GatePulseProcessorChain* itsChain, - const G4String& itsName, - G4double itsEdgesFraction, G4double itsCornersFraction); - - //! Public Destructor - virtual ~GateCrosstalk() ; - - private: - //!< Private constructor which Constructs a new crosstalk module attached to a GateDigitizer: - //! this function should only be called from GetInstance() - GateCrosstalk(GatePulseProcessorChain* itsChain, - const G4String& itsName, - G4double itsEdgesFraction, G4double itsCornersFraction) ; - - public: - - - void CheckVolumeName(G4String val); - - //! \name getters and setters - //@{ - //! This function returns the fraction of the part of energy which goes in the edge crystals. - G4double GetEdgesFraction() { return m_edgesCrosstalkFraction; } - - //! This function sets the fraction of the part of energy which goes in the edge crystals. - void SetEdgesFraction (G4double val) { m_edgesCrosstalkFraction = val; } - - //! This function returns the fraction of the part of energy which goes in the corner crystals. - G4double GetCornersFraction() { return m_cornersCrosstalkFraction; } - - //! This function sets the fraction of the part of energy which goes in the corner crystals. - void SetCornersFraction (G4double val) { m_cornersCrosstalkFraction = val; } - - //! Return the rest crosstalk per cent - G4double GetXTPerCent() { return m_XtalkpCent; }; - //@} - - //! Implementation of the pure virtual method declared by the base class GateDigitizerComponent - //! print-out the attributes specific of the crosstalk - virtual void DescribeMyself(size_t indent); - - protected: - //! Implementation of the pure virtual method declared by the base class GateVPulseProcessor - //! This methods processes one input-pulse - //! It is is called by ProcessPulseList() for each of the input pulses - //! The result of the pulse-processing is incorporated into the output pulse-list - void ProcessOnePulse(const GatePulse* inputPulse,GatePulseList& outputPulseList); - - private: + + void CheckVolumeName(G4String val); + + //! \name getters and setters + //@{ + //! This function returns the fraction of the part of energy which goes in the edge crystals. + G4double GetEdgesFraction() { return m_edgesCrosstalkFraction; } + + //! This function sets the fraction of the part of energy which goes in the edge crystals. + void SetEdgesFraction (G4double val) { m_edgesCrosstalkFraction = val; } + + //! This function returns the fraction of the part of energy which goes in the corner crystals. + G4double GetCornersFraction() { return m_cornersCrosstalkFraction; } + + //! This function sets the fraction of the part of energy which goes in the corner crystals. + void SetCornersFraction (G4double val) { m_cornersCrosstalkFraction = val; } + + //! Return the rest Crosstalk per cent + G4double GetXTPerCent() { return m_XtalkpCent; }; + //@} + + void DescribeMyself(size_t ); + +private: // //! Find the different parameters of the array of detection : // //! The numbers of rows in x, y and z // //! The position in this matrix of the hit @@ -102,34 +91,54 @@ class GateCrosstalk : public GateVPulseProcessor // //! Get the ArrayRepeater from an VObjectReapeater (if it isn't an ArrayRepeater return 0) // GateArrayRepeater* GetArrayRepeater(GateVGlobalPlacement* aRepeater); -// //! Find the different parameters of the input Pulse : +// //! Find the different parameters of the input Digi : // //! e.g. the position in this array of the hit -// void FindInputPulseParams(const GateVolumeID* m_volumeID); +// void FindInputDigiParams(const GateVolumeID* m_volumeID); - //! Create a new VolumeID for the volume of in the matrix with position \i,\j,\k - GateVolumeID CreateVolumeID(const GateVolumeID* m_volumeID, G4int i, G4int j, G4int k); + //! Create a new VolumeID for the volume of in the matrix with position \i,\j,\k + GateVolumeID CreateVolumeID(const GateVolumeID* m_volumeID, G4int i, G4int j, G4int k); - //! Create a new OutputVolumeID for the volume of in the matrix with position \i,\j,\k - GateOutputVolumeID CreateOutputVolumeID(const GateVolumeID m_volumeID); + //! Create a new OutputVolumeID for the volume of in the matrix with position \i,\j,\k + GateOutputVolumeID CreateOutputVolumeID(const GateVolumeID m_volumeID); - //! Create a new Pulse of an energy of \val * ENERGY of \pulse in the volume in position \i,\j,\k - GatePulse* CreatePulse(G4double val, const GatePulse* pulse, G4int i, G4int j, G4int k); + //! Create a new Digi of an energy of \val * ENERGY of \Digi in the volume in position \i,\j,\k + GateDigi* CreateDigi(G4double val, const GateDigi* Digi, G4int i, G4int j, G4int k); - private: - //! Static pointer to the GateCrosstalk singleton - static GateCrosstalk* theGateCrosstalk; - G4double m_XtalkpCent; //!< Actual crosstalk per cent of energy - G4double m_edgesCrosstalkFraction, m_cornersCrosstalkFraction; //!< Coefficient which connects energy to the resolution - GateCrosstalkMessenger *m_messenger; //!< Messenger - G4String m_volume; //!< Name of the crosstalk volume - G4int m_testVolume; //!< Equal to 1 if m_volume is a valid volume name, else 0 +protected: + G4double m_XtalkpCent; //!< Actual Crosstalk per cent of energy + G4double m_edgesCrosstalkFraction, m_cornersCrosstalkFraction; //!< Coefficient which connects energy to the resolution + GateCrosstalkMessenger *m_messenger; //!< Messenger + G4String m_volume; //!< Name of the Crosstalk volume + G4int m_testVolume; //!< Equal to 1 if m_volume is a valid volume name, else 0 - GateArrayParamsFinder* ArrayFinder; - size_t m_nbX, m_nbY, m_nbZ; //!< Parameters of the matrix of detection - size_t m_i, m_j, m_k; //!< position \i,\j,\k in the matrix - size_t m_depth; //!< Depth of the selected volume in the Inserter -}; + GateArrayParamsFinder* ArrayFinder; + size_t m_nbX, m_nbY, m_nbZ; //!< Parameters of the matrix of detection + size_t m_i, m_j, m_k; //!< position \i,\j,\k in the matrix + size_t m_depth; + +private: + + //! Static pointer to the GateCrosstalk singleton + static GateCrosstalk* theGateCrosstalk; + + GateDigi* m_outputDigi; + + GateCrosstalkMessenger *m_Messenger; + + GateDigiCollection* m_OutputDigiCollection; + + GateSinglesDigitizer *m_digitizer; +}; + #endif + + + + + + + + diff --git a/source/digits_hits/include/GateCrosstalkMessenger.hh b/source/digits_hits/include/GateCrosstalkMessenger.hh old mode 100644 new mode 100755 index a1c2483a2..3b51d95de --- a/source/digits_hits/include/GateCrosstalkMessenger.hh +++ b/source/digits_hits/include/GateCrosstalkMessenger.hh @@ -6,34 +6,59 @@ of the GNU Lesser General Public Licence (LGPL) See LICENSE.md for further details ----------------------*/ +// OK GND 2022 +/*This class is not used by GATE ! + The purpose of this class is to help to create new users digitizer module(DM). + Please, check GateCrosstalk.cc for more detals + */ + + +/*! \class GateCrosstalkMessenger + \brief Messenger for the GateCrosstalk + + - GateCrosstalk - by name.surname@email.com + + \sa GateCrosstalk, GateCrosstalkMessenger +*/ + #ifndef GateCrosstalkMessenger_h #define GateCrosstalkMessenger_h 1 -#include "GatePulseProcessorMessenger.hh" -#include -#include "G4UIdirectory.hh" +#include "G4UImessenger.hh" +#include "globals.hh" + +#include "GateClockDependentMessenger.hh" +class GateCrosstalk; class G4UIcmdWithAString; class G4UIcmdWithADouble; -class GateCrosstalk; - -class GateCrosstalkMessenger: public GatePulseProcessorMessenger +class GateCrosstalkMessenger : public GateClockDependentMessenger { - public: - GateCrosstalkMessenger(GateCrosstalk* itsCrosstalk); - virtual ~GateCrosstalkMessenger(); +public: + + GateCrosstalkMessenger(GateCrosstalk*); + ~GateCrosstalkMessenger(); + + void SetNewValue(G4UIcommand*, G4String); - inline void SetNewValue(G4UIcommand* aCommand, G4String aString); + +private: + GateCrosstalk* m_Crosstalk; + + G4UIcmdWithADouble *edgesFractionCmd; + G4UIcmdWithADouble *cornersFractionCmd; - inline GateCrosstalk* GetCrosstalk() - { return (GateCrosstalk*) GetPulseProcessor(); } - private: - G4UIcmdWithAString *newVolCmd; - G4UIcmdWithADouble *edgesFractionCmd; - G4UIcmdWithADouble *cornersFractionCmd; }; #endif + + + + + + + + diff --git a/source/digits_hits/include/GateIntrinsicResolution.hh b/source/digits_hits/include/GateIntrinsicResolution.hh index 3781cbb7c..08ad9f16f 100755 --- a/source/digits_hits/include/GateIntrinsicResolution.hh +++ b/source/digits_hits/include/GateIntrinsicResolution.hh @@ -51,6 +51,9 @@ public: void SetEref(const G4double& value ){ m_Eref=value;} ; void SetLightOutput(const G4double& value ){ m_LY=value;} ; void SetTransferEff(const G4double& value ){ m_TE=value;} ; + void SetEdgesFraction (G4double val) { m_edgesCrosstalkFraction = val; } + void SetCornersFraction (G4double val) { m_cornersCrosstalkFraction = val; } + //! Allow to use file(s) as lookout table for quantum efficiency void UseFile(G4String aFile); @@ -70,6 +73,7 @@ protected: G4double m_LY; //Light Yield G4double m_TE; //Transfer efficiency G4double m_QE; //Quantum efficiency + G4double m_XtalkpCent; G4bool isFirstEvent; G4double m_uniqueQE; //!< Value of the quantum efficiency if it's unique @@ -93,6 +97,8 @@ protected: G4double** m_table; //!< Lookout table for the quantum efficiency of all channels G4String m_volumeName; //!< Name of the module G4int m_testVolume; //!< equal to 1 if the volume name is valid, 0 else + G4double m_edgesCrosstalkFraction, m_cornersCrosstalkFraction; //!< Coefficient which connects energy to the resolution + private: GateDigi* m_outputDigi; diff --git a/source/digits_hits/include/GateIntrinsicResolutionMessenger.hh b/source/digits_hits/include/GateIntrinsicResolutionMessenger.hh index eabde5295..42f77b860 100755 --- a/source/digits_hits/include/GateIntrinsicResolutionMessenger.hh +++ b/source/digits_hits/include/GateIntrinsicResolutionMessenger.hh @@ -53,6 +53,8 @@ private: G4UIcmdWithADouble *coeffTECmd; G4UIcmdWithAString *newFileQECmd; G4UIcmdWithADouble *uniqueQECmd; + G4UIcmdWithADouble *edgesFractionCmd; + G4UIcmdWithADouble *cornersFractionCmd; diff --git a/source/digits_hits/src/GateCrosstalk.cc b/source/digits_hits/src/GateCrosstalk.cc old mode 100644 new mode 100755 index 79a3dc795..8f86b362a --- a/source/digits_hits/src/GateCrosstalk.cc +++ b/source/digits_hits/src/GateCrosstalk.cc @@ -1,29 +1,85 @@ -/*---------------------- - Copyright (C): OpenGATE Collaboration - -This software is distributed under the terms -of the GNU Lesser General Public Licence (LGPL) -See LICENSE.md for further details -----------------------*/ +/*---------------------- + Copyright (C): OpenGATE Collaboration + + This software is distributed under the terms + of the GNU Lesser General Public Licence (LGPL) + See LICENSE.md for further details + ----------------------*/ + +/*! + \class GateCrosstalk + + This class is not used by GATE ! + The purpose of this class is to help to create new users digitizer module(DM). + + - Create your DM by coping this class and GateDummyDigitizerMessenger class for your DM messenger + - Places to change are marked with // ****** comment and called with "dummy" names + - Include your module to GateSinglesDigitizerMessenger in the method DoInsertion(..) + + If you adapting some already exiting class from Old Gate Digitizer here is some of the tips + - Digitize () is a fusion of GateVdigiProcessor::ProcessdigiList and GateXXX::Digitize + - digi --> Digi + - outputdigiList --> OutputDigiCollectionVector + - inputDigi-->inputDigi + - outputdigi --> m_outputDigi + - how to adapt iterators check GateAdder class + + To create new Digitizer Module (DM), please, follow the steps: + 1) Copy .cc and .hh of GateCrosstalk, GateCrosstalkMessenger to GateYourNewDigitizerModule and GateYourNewDigitizerModuleMessenger + 2) Replace in these new files : Crosstalk -> YourNewDigitizerModule + 3) Compile 1st time (so not forget to redo ccmake to) + 4) Adapt GateYourNewDigitizerModuleMessenger.cc + 5) Adapt GateYourNewDigitizerModuleMessenger.hh (!!!! DO NOT FORGET TO WRITE A SHORT EXPLANATION ON WHAT DOES YOUR DM !!!!) + 6) Adapt GateYourNewDigitizerModule.hh + 7) Adapt GateYourNewDigitizerModule.cc + - Change the names (x2) of YourDigitizerModule in the constructor of GateYourNewDigitizerModule.cc: + line: + :GateVDigitizerModule("Dummy","digitizerMgr/"+digitizer->GetSD()->GetName()+"/SinglesDigitizer/"+digitizer->m_digitizerName+"/dummy",digitizer,digitizer->GetSD()), + + - !!!! DO NOT FORGET TO WRITE A SHORT EXPLANATION ON WHAT DOES YOUR DM !!!! + - Comment everything inside Digitize() method + 8) Compile 2ed time + 9) In case of adaptation of old existing class: + - Copy everything inside Digitize() and ProcessdigiList() from old module to Digitize() (places where to copy are indicated in this class) + - Replace: + inputDigi -> inputDigi + outputdigi -> m_outputDigi + correct the first declaration (as in this Dummy module) + m_OutputDigiCollection->insert(outputdigi) -> m_OutputDigiCollection->insert(m_outputDigi); + 10) Add YourDigitizerModule to GateSinglesDigitizer.cc + - #include "YourDigitizerModule.hh" + - in DumpMap() method in + static G4String theList = " ...." + - in DoInsertion() : + else if (childTypeName=="yourDM") + { + newDM = new GateYourDigitizerModule(m_digitizer); + m_digitizer->AddNewModule(newDM); + } + 11) Compile 3ed time and execute + + */ #include "GateCrosstalk.hh" - #include "GateCrosstalkMessenger.hh" -#include "GateTools.hh" -#include -#include "G4ThreeVector.hh" +#include "GateDigi.hh" -#include "GateVolumeID.hh" -#include "GateOutputVolumeID.hh" +#include "GateDigitizerMgr.hh" +#include "GateObjectStore.hh" #include "GateDetectorConstruction.hh" -#include "GateCrystalSD.hh" -#include "GateVSystem.hh" #include "GateArrayParamsFinder.hh" + +#include "G4SystemOfUnits.hh" +#include "G4EventManager.hh" +#include "G4Event.hh" +#include "G4SDManager.hh" +#include "G4DigiManager.hh" +#include "G4ios.hh" #include "G4UnitsTable.hh" -#include "GateObjectStore.hh" + + // Static pointer to the GateCrosstalk singleton GateCrosstalk* GateCrosstalk::theGateCrosstalk=0; @@ -33,7 +89,7 @@ GateCrosstalk* GateCrosstalk::theGateCrosstalk=0; If this singleton does not exist yet, GetInstance creates it by calling the private GateCrosstalk constructor */ -GateCrosstalk* GateCrosstalk::GetInstance(GatePulseProcessorChain* itsChain, +GateCrosstalk* GateCrosstalk::GetInstance(GateSinglesDigitizer* itsChain, const G4String& itsName, G4double itsEdgesFraction, G4double itsCornersFraction) { @@ -44,26 +100,32 @@ GateCrosstalk* GateCrosstalk::GetInstance(GatePulseProcessorChain* itsChain, } -// Private constructor -GateCrosstalk::GateCrosstalk(GatePulseProcessorChain* itsChain, - const G4String& itsName, G4double itsEdgesFraction, - G4double itsCornersFraction) - : GateVPulseProcessor(itsChain, itsName), - m_edgesCrosstalkFraction(itsEdgesFraction),m_cornersCrosstalkFraction(itsCornersFraction) -{ - m_messenger = new GateCrosstalkMessenger(this); - m_testVolume = 0; -} +GateCrosstalk::GateCrosstalk(GateSinglesDigitizer *digitizer, G4String name, G4double itsEdgesFraction, G4double itsCornersFraction) + :GateVDigitizerModule(name,"digitizerMgr/"+digitizer->GetSD()->GetName()+"/SinglesDigitizer/"+digitizer->m_digitizerName+"/"+name,digitizer,digitizer->GetSD()), + m_edgesCrosstalkFraction(itsEdgesFraction), + m_cornersCrosstalkFraction(itsCornersFraction), + m_outputDigi(0), + m_OutputDigiCollection(0), + m_digitizer(digitizer) + { + G4String colName = digitizer->GetOutputName() ; + collectionName.push_back(colName); + m_Messenger = new GateCrosstalkMessenger(this); + m_testVolume = 0; + CheckVolumeName(m_digitizer->GetSD()->GetName()); +} GateCrosstalk::~GateCrosstalk() { - delete m_messenger; - delete ArrayFinder; + delete m_messenger; + delete ArrayFinder; + } + void GateCrosstalk::CheckVolumeName(G4String val) { //Retrieve the inserter store to check if the volume name is valid @@ -80,132 +142,187 @@ void GateCrosstalk::CheckVolumeName(G4String val) } } -void GateCrosstalk::ProcessOnePulse(const GatePulse* inputPulse,GatePulseList& outputPulseList) -{ - - if(!m_testVolume) - { - G4cerr << Gateendl << "[GateCrosstalk::ProcessOnePulse]:\n" - << "Sorry, but you don't have choosen any volume !\n"; - - G4String msg = "You must choose a volume for crosstalk, e.g. crystal:\n" - "\t/gate/digitizer/Singles/crosstalk/chooseCrosstalkVolume VOLUME NAME\n" - "or disable the crosstalk using:\n" - "\t/gate/digitizer/Singles/crosstalk/disable\n"; - - G4Exception( "GateCrosstalk::ProcessOnePulse", "ProcessOnePulse", FatalException, msg ); - } - //Find the pulse position in the array - m_depth = (size_t)(inputPulse->GetVolumeID().GetCreatorDepth(m_volume)); - ArrayFinder->FindInputPulseParams(inputPulse->GetVolumeID().GetCopyNo(m_depth), m_i, m_j, m_k); - //Numbers of edge and corner neighbors for the pulses - G4int countE = 0; - G4int countC = 0; - - // Find the possible neighbors - if (m_edgesCrosstalkFraction != 0) { - if (m_i != 0) { - outputPulseList.push_back(CreatePulse(m_edgesCrosstalkFraction, inputPulse, m_i - 1, m_j, m_k)); - countE++; - } - if (m_i != m_nbX - 1) { - outputPulseList.push_back(CreatePulse(m_edgesCrosstalkFraction, inputPulse, m_i + 1, m_j, m_k)); - countE++; - } - if (m_j != 0) { - outputPulseList.push_back(CreatePulse(m_edgesCrosstalkFraction, inputPulse, m_i, m_j - 1, m_k)); - countE++; - } - if (m_j != m_nbY - 1) { - outputPulseList.push_back(CreatePulse(m_edgesCrosstalkFraction, inputPulse, m_i, m_j + 1, m_k)); - countE++; - } - if (m_k != 0) { - outputPulseList.push_back(CreatePulse(m_edgesCrosstalkFraction, inputPulse, m_i, m_j, m_k - 1)); - countE++; - } - if (m_k != m_nbZ - 1) { - outputPulseList.push_back(CreatePulse(m_edgesCrosstalkFraction, inputPulse, m_i, m_j, m_k + 1)); - countE++; - } - } - - if (m_cornersCrosstalkFraction != 0) { - if ((m_i != 0) & (m_j != 0)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i - 1, m_j - 1, m_k)); - countC++; - } - if ((m_i != 0) & (m_j != m_nbY - 1)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i - 1, m_j + 1, m_k)); - countC++; - } - if ((m_i != 0) & (m_k != 0)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i - 1, m_j, m_k - 1)); - countC++; - } - if ((m_i != 0) & (m_k != m_nbZ - 1)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i - 1, m_j, m_k + 1)); - countC++; - } - if ((m_i != m_nbX - 1) & (m_j != 0)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i + 1, m_j - 1, m_k)); - countC++; - } - if ((m_i != m_nbX - 1) & (m_j != m_nbY - 1)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i + 1, m_j + 1, m_k)); - countC++; - } - if ((m_i != m_nbX - 1) & (m_k != 0)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i + 1, m_j, m_k - 1)); - countC++; - } - if ((m_i != m_nbX - 1) & (m_k != m_nbZ - 1)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i + 1, m_j, m_k + 1)); - countC++; - } - if ((m_j != 0) & (m_k != 0)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i, m_j - 1, m_k - 1)); - countC++; - } - if ((m_j != 0) & (m_k != m_nbZ - 1)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i, m_j - 1, m_k + 1)); - countC++; - } - - if ((m_j != m_nbY - 1) & (m_k != 0)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i, m_j + 1, m_k - 1)); - countC++; - } - if ((m_j != m_nbY - 1) & (m_k != m_nbZ - 1)) { - outputPulseList.push_back(CreatePulse(m_cornersCrosstalkFraction, inputPulse, m_i, m_j + 1, m_k + 1)); - countC++; - } - } - - // Check if the energy of neighbors is not higher than the energy of the incident pulse - G4double energytot = inputPulse->GetEnergy()*((countE*m_edgesCrosstalkFraction)+(countC*m_cornersCrosstalkFraction)); - if(energytot>=inputPulse->GetEnergy()) +void GateCrosstalk::Digitize() +{ + if(!m_testVolume) + { + G4cerr << Gateendl << "[GateCrosstalk::Digitize]:\n" + << "Sorry, but you don't have choosen any volume !\n"; + + G4String msg = "You must choose a volume for Crosstalk, e.g. crystal:\n" + "\t/gate/digitizer/Singles/Crosstalk/chooseCrosstalkVolume VOLUME NAME\n" + "or disable the Crosstalk using:\n" + "\t/gate/digitizer/Singles/Crosstalk/disable\n"; + + G4Exception( "GateCrosstalk::Digitize", "Digitize", FatalException, msg ); + } + + + + G4String digitizerName = m_digitizer->m_digitizerName; + G4String outputCollName = m_digitizer-> GetOutputName(); + + m_OutputDigiCollection = new GateDigiCollection(GetName(),outputCollName); // to create the Digi Collection + + G4DigiManager* DigiMan = G4DigiManager::GetDMpointer(); + + + + GateDigiCollection* IDC = 0; + IDC = (GateDigiCollection*) (DigiMan->GetDigiCollection(m_DCID)); + + GateDigi* inputDigi; + + std::vector< GateDigi* >* OutputDigiCollectionVector = m_OutputDigiCollection->GetVector (); + std::vector::iterator iter; + + + /* if (nVerboseLevel==1) + { + G4cout << "[ GateCrosstalk::Digitize]: returning output digi-list with " << m_OutputDigiCollection->entries() << " entries\n"; + for (size_t k=0; kentries();k++) + G4cout << *(*IDC)[k] << Gateendl; + G4cout << Gateendl; + } + */ + + if (IDC) + { + G4int n_digi = IDC->entries(); + + //loop over input digits + for (G4int i=0;iGetVolumeID().GetCreatorDepth(m_volume)); + ArrayFinder->FindInputPulseParams(inputDigi->GetVolumeID().GetCopyNo(m_depth), m_i, m_j, m_k); + + //Numbers of edge and corner neighbors for the digis + G4int countE = 0; + G4int countC = 0; + + // Find the possible neighbors + if (m_edgesCrosstalkFraction != 0) { + if (m_i != 0) { + m_OutputDigiCollection->insert(CreateDigi(m_edgesCrosstalkFraction, inputDigi, m_i - 1, m_j, m_k)); + countE++; + } + if (m_i != m_nbX - 1) { + m_OutputDigiCollection->insert(CreateDigi(m_edgesCrosstalkFraction, inputDigi, m_i + 1, m_j, m_k)); + countE++; + } + if (m_j != 0) { + m_OutputDigiCollection->insert(CreateDigi(m_edgesCrosstalkFraction, inputDigi, m_i, m_j - 1, m_k)); + countE++; + } + if (m_j != m_nbY - 1) { + m_OutputDigiCollection->insert(CreateDigi(m_edgesCrosstalkFraction, inputDigi, m_i, m_j + 1, m_k)); + countE++; + } + if (m_k != 0) { + m_OutputDigiCollection->insert(CreateDigi(m_edgesCrosstalkFraction, inputDigi, m_i, m_j, m_k - 1)); + countE++; + } + if (m_k != m_nbZ - 1) { + m_OutputDigiCollection->insert(CreateDigi(m_edgesCrosstalkFraction, inputDigi, m_i, m_j, m_k + 1)); + countE++; + } + } + + if (m_cornersCrosstalkFraction != 0) { + if ((m_i != 0) & (m_j != 0)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i - 1, m_j - 1, m_k)); + countC++; + } + if ((m_i != 0) & (m_j != m_nbY - 1)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i - 1, m_j + 1, m_k)); + countC++; + } + if ((m_i != 0) & (m_k != 0)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i - 1, m_j, m_k - 1)); + countC++; + } + if ((m_i != 0) & (m_k != m_nbZ - 1)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i - 1, m_j, m_k + 1)); + countC++; + } + if ((m_i != m_nbX - 1) & (m_j != 0)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i + 1, m_j - 1, m_k)); + countC++; + } + if ((m_i != m_nbX - 1) & (m_j != m_nbY - 1)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i + 1, m_j + 1, m_k)); + countC++; + } + if ((m_i != m_nbX - 1) & (m_k != 0)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i + 1, m_j, m_k - 1)); + countC++; + } + if ((m_i != m_nbX - 1) & (m_k != m_nbZ - 1)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i + 1, m_j, m_k + 1)); + countC++; + } + if ((m_j != 0) & (m_k != 0)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i, m_j - 1, m_k - 1)); + countC++; + } + if ((m_j != 0) & (m_k != m_nbZ - 1)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i, m_j - 1, m_k + 1)); + countC++; + } + + if ((m_j != m_nbY - 1) & (m_k != 0)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i, m_j + 1, m_k - 1)); + countC++; + } + if ((m_j != m_nbY - 1) & (m_k != m_nbZ - 1)) { + m_OutputDigiCollection->insert(CreateDigi(m_cornersCrosstalkFraction, inputDigi, m_i, m_j + 1, m_k + 1)); + countC++; + } + } + + // Check if the energy of neighbors is not higher than the energy of the incident digi + G4double energytot = inputDigi->GetEnergy()*((countE*m_edgesCrosstalkFraction)+(countC*m_cornersCrosstalkFraction)); + + if(energytot>=inputDigi->GetEnergy()) + { + G4cerr << Gateendl << "[GateCrosstalk::Digitize]:\n" + << "Sorry, but you have too much energy !\n"; + + G4String msg = "You must change your fractions of energy for the close crystals :\n" + "\t/gate/digitizer/Singles/Crosstalk/setSidesFraction NUMBER\n" + "\t/gate/digitizer/Singles/Crosstalk/setCornersFraction NUMBER\n" + "or disable the Crosstalk using:\n" + "\t/gate/digitizer/Singles/Crosstalk/disable\n"; + G4Exception( "GateCrosstalk::Digitize", "Digitize", FatalException,msg); + } + + + // Add the incident digi in the digi list with less energy + m_outputDigi = new GateDigi(*inputDigi); + + m_XtalkpCent = (1-(4*m_edgesCrosstalkFraction+4*m_cornersCrosstalkFraction)); + m_outputDigi->SetEnergy((inputDigi->GetEnergy())*m_XtalkpCent); + m_OutputDigiCollection->insert(m_outputDigi); + + if (nVerboseLevel>1) + G4cout << "the input digi created " << countE+countC << " digis around it" + << Gateendl; + + } //loop over input digits + } //IDC + else { - G4cerr << Gateendl << "[GateCrosstalk::ProcessOnePulse]:\n" - << "Sorry, but you have too much energy !\n"; - - G4String msg = "You must change your fractions of energy for the close crystals :\n" - "\t/gate/digitizer/Singles/crosstalk/setSidesFraction NUMBER\n" - "\t/gate/digitizer/Singles/crosstalk/setCornersFraction NUMBER\n" - "or disable the crosstalk using:\n" - "\t/gate/digitizer/Singles/crosstalk/disable\n"; - G4Exception( "GateCrosstalk::ProcessOnePulse", "ProcessOnePulse", FatalException,msg); + if (nVerboseLevel>1) + G4cout << "[GateCrosstalk::Digitize]: input digi collection is null -> nothing to do\n\n"; + return; } - // Add the incident pulse in the pulse list with less energy - GatePulse* outputPulse = new GatePulse(*inputPulse); - m_XtalkpCent = (1-(4*m_edgesCrosstalkFraction+4*m_cornersCrosstalkFraction)); - outputPulse->SetEnergy((inputPulse->GetEnergy())*m_XtalkpCent); - outputPulseList.push_back(outputPulse); - if (nVerboseLevel>1) - G4cout << "the input pulse created " << countE+countC << " pulses around it" - << Gateendl; + StoreDigiCollection(m_OutputDigiCollection); + } @@ -225,25 +342,31 @@ GateVolumeID GateCrosstalk::CreateVolumeID(const GateVolumeID* aVolumeID, G4int GateOutputVolumeID GateCrosstalk::CreateOutputVolumeID(const GateVolumeID aVolumeID) { - GateDetectorConstruction* aDetectorConstruction = GateDetectorConstruction::GetGateDetectorConstruction(); - GateOutputVolumeID anOutputVolumeID = aDetectorConstruction->GetCrystalSD()->GetSystem()->ComputeOutputVolumeID(aVolumeID); + //GateDetectorConstruction* aDetectorConstruction = GateDetectorConstruction::GetGateDetectorConstruction(); + //GateOutputVolumeID anOutputVolumeID = aDetectorConstruction->GetCrystalSD()->GetSystem()->ComputeOutputVolumeID(aVolumeID); + + GateOutputVolumeID anOutputVolumeID = m_digitizer->GetSystem()->ComputeOutputVolumeID(aVolumeID); + return anOutputVolumeID; } -GatePulse* GateCrosstalk::CreatePulse(G4double val, const GatePulse* pulse, G4int i, G4int j, G4int k) +GateDigi* GateCrosstalk::CreateDigi(G4double val, const GateDigi* digi, G4int i, G4int j, G4int k) { - GatePulse* apulse = new GatePulse(pulse); - apulse->SetLocalPos(G4ThreeVector(0,0,0)); - apulse->SetVolumeID(CreateVolumeID(&pulse->GetVolumeID(), i, j, k)); - apulse->SetGlobalPos(apulse->GetVolumeID().MoveToAncestorVolumeFrame(apulse->GetLocalPos())); - apulse->SetOutputVolumeID(CreateOutputVolumeID(apulse->GetVolumeID())); - apulse->SetEnergy(pulse->GetEnergy()*val); - return apulse; + GateDigi* adigi = new GateDigi(digi); + + adigi->SetLocalPos(G4ThreeVector(0,0,0)); + adigi->SetVolumeID(CreateVolumeID(&digi->GetVolumeID(), i, j, k)); + adigi->SetGlobalPos(adigi->GetVolumeID().MoveToAncestorVolumeFrame(adigi->GetLocalPos())); + adigi->SetOutputVolumeID(CreateOutputVolumeID(adigi->GetVolumeID())); + adigi->SetEnergy(digi->GetEnergy()*val); + + return adigi; } -void GateCrosstalk::DescribeMyself(size_t indent) + +void GateCrosstalk::DescribeMyself(size_t indent ) { - G4cout << GateTools::Indent(indent) << "Optical crosstalk for " << m_volume << ":\n" - << GateTools::Indent(indent+1) << "fraction of energy for side crystals: " << m_edgesCrosstalkFraction << "\n" - << GateTools::Indent(indent+1) << "fraction of energy for corner crystals: " << m_cornersCrosstalkFraction << Gateendl; + G4cout << GateTools::Indent(indent) << "Optical Crosstalk for " << m_volume << ":\n" + << GateTools::Indent(indent+1) << "fraction of energy for side crystals: " << m_edgesCrosstalkFraction << "\n" + << GateTools::Indent(indent+1) << "fraction of energy for corner crystals: " << m_cornersCrosstalkFraction << Gateendl; } diff --git a/source/digits_hits/src/GateCrosstalkMessenger.cc b/source/digits_hits/src/GateCrosstalkMessenger.cc old mode 100644 new mode 100755 index ac02515cb..683a9c780 --- a/source/digits_hits/src/GateCrosstalkMessenger.cc +++ b/source/digits_hits/src/GateCrosstalkMessenger.cc @@ -6,57 +6,74 @@ of the GNU Lesser General Public Licence (LGPL) See LICENSE.md for further details ----------------------*/ +// OK GND 2022 #include "GateCrosstalkMessenger.hh" - #include "GateCrosstalk.hh" +#include "GateDigitizerMgr.hh" + +#include "G4SystemOfUnits.hh" +#include "G4UIcmdWithAString.hh" +#include "G4UIdirectory.hh" #include "G4UIcmdWithAString.hh" -#include "G4UIcmdWithADoubleAndUnit.hh" #include "G4UIcmdWithADouble.hh" -GateCrosstalkMessenger::GateCrosstalkMessenger(GateCrosstalk* itsCrosstalk) - : GatePulseProcessorMessenger(itsCrosstalk) + +class G4UIcmdWithAString; +class G4UIcmdWithADouble; + + +GateCrosstalkMessenger::GateCrosstalkMessenger (GateCrosstalk* Crosstalk) +:GateClockDependentMessenger(Crosstalk), + m_Crosstalk(Crosstalk) { - G4String guidance; - G4String cmdName; - G4String cmdName2; - G4String cmdName3; - - cmdName = GetDirectoryName() + "chooseCrosstalkVolume"; - newVolCmd = new G4UIcmdWithAString(cmdName,this); - newVolCmd->SetGuidance("Choose a volume for crosstalk (e.g. crystal)"); - - cmdName2 = GetDirectoryName() + "setEdgesFraction"; - edgesFractionCmd = new G4UIcmdWithADouble(cmdName2,this); - edgesFractionCmd->SetGuidance("Set the fraction of energy which leaves on each edge crystal"); - - cmdName3 = GetDirectoryName() + "setCornersFraction"; - cornersFractionCmd = new G4UIcmdWithADouble(cmdName3,this); - cornersFractionCmd->SetGuidance("Set the fraction of the energy which leaves on each corner crystal"); -} + G4String guidance; + G4String cmdName; + + cmdName = GetDirectoryName() + "setEdgesFraction"; + edgesFractionCmd = new G4UIcmdWithADouble(cmdName,this); + edgesFractionCmd->SetGuidance("Set the fraction of energy which leaves on each edge crystal"); + + cmdName = GetDirectoryName() + "setCornersFraction"; + cornersFractionCmd = new G4UIcmdWithADouble(cmdName,this); + cornersFractionCmd->SetGuidance("Set the fraction of the energy which leaves on each corner crystal"); +} GateCrosstalkMessenger::~GateCrosstalkMessenger() { - delete newVolCmd; - delete edgesFractionCmd; - delete cornersFractionCmd; + delete edgesFractionCmd; + delete cornersFractionCmd; } -void GateCrosstalkMessenger::SetNewValue(G4UIcommand* command, G4String newValue) +void GateCrosstalkMessenger::SetNewValue(G4UIcommand * aCommand,G4String newValue) { - if ( command==newVolCmd ) { - GetCrosstalk()->CheckVolumeName(newValue); - } - else if ( command==edgesFractionCmd ) { - GetCrosstalk()->SetEdgesFraction (edgesFractionCmd->GetNewDoubleValue(newValue)); - } - else if ( command==cornersFractionCmd ) { - GetCrosstalk()->SetCornersFraction (cornersFractionCmd->GetNewDoubleValue(newValue)); - } - else - GatePulseProcessorMessenger::SetNewValue(command,newValue); + if (aCommand ==edgesFractionCmd) + { + m_Crosstalk->SetEdgesFraction (edgesFractionCmd->GetNewDoubleValue(newValue)); + } + else if (aCommand ==cornersFractionCmd) + { + m_Crosstalk->SetCornersFraction (cornersFractionCmd->GetNewDoubleValue(newValue)); + } + else + { + GateClockDependentMessenger::SetNewValue(aCommand,newValue); + } } + + + + + + + + + + + + + diff --git a/source/digits_hits/src/GateIntrinsicResolution.cc b/source/digits_hits/src/GateIntrinsicResolution.cc index 9d9b0747f..5655b62bf 100755 --- a/source/digits_hits/src/GateIntrinsicResolution.cc +++ b/source/digits_hits/src/GateIntrinsicResolution.cc @@ -39,6 +39,8 @@ #include "GateDigi.hh" #include "GateDigitizerMgr.hh" +#include "GateCrosstalk.hh" + #include "G4SystemOfUnits.hh" #include "G4EventManager.hh" @@ -58,6 +60,8 @@ GateIntrinsicResolution::GateIntrinsicResolution(GateSinglesDigitizer *digitizer m_LY(1), m_TE(1), m_QE(1), + m_edgesCrosstalkFraction(0), + m_cornersCrosstalkFraction(0), isFirstEvent(true), m_outputDigi(0), m_OutputDigiCollection(0), @@ -83,7 +87,6 @@ GateIntrinsicResolution::~GateIntrinsicResolution() void GateIntrinsicResolution::Digitize() { - G4double XtalkpCent; if(isFirstEvent) { @@ -104,22 +107,7 @@ void GateIntrinsicResolution::Digitize() // For QE (from QE class) CheckVolumeName(m_digitizer->GetSD()->GetName()); CreateTable(); - - /* XtalkpCent = (GateCrosstalk::GetInstance(NULL,"name",0.,0.)) ? - GateCrosstalk::GetInstance(NULL,"name",0.,0.)->GetXTPerCent() : 1.; - - if (GateQuantumEfficiency::GetInstance(NULL,"name")) - { - m_volumeName = GateQuantumEfficiency::GetInstance(NULL,"name")->GetVolumeName(); - FindInputPulseParams(&inputPulse->GetVolumeID()); - G4int level2No = GateQuantumEfficiency::GetInstance(NULL,"name")->Getlevel2No(); - G4int level3No = GateQuantumEfficiency::GetInstance(NULL,"name")->Getlevel3No(); - G4int tableNB = m_k + m_j*level3No + m_i*level3No*level2No; - QECoef = GateQuantumEfficiency::GetInstance(NULL,"name")->GetQECoeff(tableNB, m_volumeIDNo); - } - else - QECoef = 1.; - */ + m_XtalkpCent = (1-(4*m_edgesCrosstalkFraction+4*m_cornersCrosstalkFraction)); isFirstEvent=false; } @@ -176,7 +164,7 @@ void GateIntrinsicResolution::Digitize() m_outputDigi = new GateDigi(*inputDigi); G4double energy = inputDigi->GetEnergy(); - G4double Nph = energy*m_LY*m_TE*m_QE;//*XtalkpCent GND TODO; + G4double Nph = energy*m_LY*m_TE*m_QE*m_XtalkpCent; G4double Ri = m_resolution * sqrt((m_Eref / energy)); G4double resol = sqrt((1.1/Nph)*(GateConstants::fwhm_to_sigma*GateConstants::fwhm_to_sigma) + Ri*Ri); diff --git a/source/digits_hits/src/GateIntrinsicResolutionMessenger.cc b/source/digits_hits/src/GateIntrinsicResolutionMessenger.cc index 7cc75d066..706540cca 100755 --- a/source/digits_hits/src/GateIntrinsicResolutionMessenger.cc +++ b/source/digits_hits/src/GateIntrinsicResolutionMessenger.cc @@ -58,6 +58,15 @@ GateIntrinsicResolutionMessenger::GateIntrinsicResolutionMessenger (GateIntrinsi cmdName = GetDirectoryName() + "setUniqueQE"; uniqueQECmd = new G4UIcmdWithADouble(cmdName,this); uniqueQECmd->SetGuidance("Set an unique quantum efficiency"); + + cmdName = GetDirectoryName() + "setEdgesFraction"; + edgesFractionCmd = new G4UIcmdWithADouble(cmdName,this); + edgesFractionCmd->SetGuidance("Set the fraction of energy which leaves on each edge crystal"); + + cmdName = GetDirectoryName() + "setCornersFraction"; + cornersFractionCmd = new G4UIcmdWithADouble(cmdName,this); + cornersFractionCmd->SetGuidance("Set the fraction of the energy which leaves on each corner crystal"); + } @@ -69,6 +78,8 @@ GateIntrinsicResolutionMessenger::~GateIntrinsicResolutionMessenger() delete coeffTECmd; delete newFileQECmd; delete uniqueQECmd; + delete edgesFractionCmd; + delete cornersFractionCmd; } @@ -98,6 +109,14 @@ void GateIntrinsicResolutionMessenger::SetNewValue(G4UIcommand * aCommand,G4Stri { m_IntrinsicResolution->SetUniqueQE(uniqueQECmd->GetNewDoubleValue(newValue)); } + else if (aCommand ==edgesFractionCmd) + { + m_IntrinsicResolution->SetEdgesFraction (edgesFractionCmd->GetNewDoubleValue(newValue)); + } + else if (aCommand ==cornersFractionCmd) + { + m_IntrinsicResolution->SetCornersFraction (cornersFractionCmd->GetNewDoubleValue(newValue)); + } else { diff --git a/source/digits_hits/src/GateSinglesDigitizerMessenger.cc b/source/digits_hits/src/GateSinglesDigitizerMessenger.cc index 54318c57b..95f2be98b 100755 --- a/source/digits_hits/src/GateSinglesDigitizerMessenger.cc +++ b/source/digits_hits/src/GateSinglesDigitizerMessenger.cc @@ -44,6 +44,7 @@ See LICENSE.md for further details #include "GateDigitizerMerger.hh" #include "GateBuffer.hh" #include "GateIntrinsicResolution.hh" +#include "GateCrosstalk.hh" #include "GateDoIModels.hh" /* @@ -114,7 +115,7 @@ void GateSinglesDigitizerMessenger::SetNewValue(G4UIcommand* command,G4String ne const G4String& GateSinglesDigitizerMessenger::DumpMap() { - static G4String theList = "readout adder energyFraming timeResolution energyResolution spatialResolution efficiency deadtime pileup adderCompton opticaladder noise merger intrinsicResolution buffer doIModels"; + static G4String theList = "readout adder energyFraming timeResolution energyResolution spatialResolution efficiency deadtime pileup adderCompton opticaladder noise merger intrinsicResolution buffer crosstalk doIModels"; return theList; @@ -215,6 +216,13 @@ void GateSinglesDigitizerMessenger::DoInsertion(const G4String& childTypeName) newDM = new GateIntrinsicResolution(m_digitizer, DMname); m_digitizer->AddNewModule(newDM); } + + else if (childTypeName=="crosstalk") + { + newDM = new GateCrosstalk(m_digitizer, DMname, 0, 0); + m_digitizer->AddNewModule(newDM); + } + else if (childTypeName=="doIModels") { newDM = new GateDoIModels(m_digitizer, DMname);