From 5fe289e679260a54892899deb8dc555f7d6296ff Mon Sep 17 00:00:00 2001 From: kochebina Date: Mon, 4 Dec 2023 16:16:59 +0100 Subject: [PATCH 1/2] IntrinsicResolution added to New Digitizer --- .../GateBlurringWithIntrinsicResolution.hh | 109 ------- ...lurringWithIntrinsicResolutionMessenger.hh | 45 --- source/digits_hits/include/GateCalibration.hh | 76 ----- .../include/GateCalibrationMessenger.hh | 37 --- .../include/GateIntrinsicResolution.hh | 116 +++++++ .../GateIntrinsicResolutionMessenger.hh | 69 ++++ source/digits_hits/include/GateLightYield.hh | 112 ------- .../include/GateLightYieldMessenger.hh | 43 --- .../include/GateQuantumEfficiency.hh | 134 -------- .../include/GateQuantumEfficiencyMessenger.hh | 39 --- .../include/GateTransferEfficiency.hh | 100 ------ .../GateTransferEfficiencyMessenger.hh | 50 --- .../GateBlurringWithIntrinsicResolution.cc | 143 -------- ...lurringWithIntrinsicResolutionMessenger.cc | 86 ----- source/digits_hits/src/GateCalibration.cc | 98 ------ .../src/GateCalibrationMessenger.cc | 33 -- .../src/GateIntrinsicResolution.cc | 307 ++++++++++++++++++ .../src/GateIntrinsicResolutionMessenger.cc | 119 +++++++ source/digits_hits/src/GateLightYield.cc | 108 ------ .../src/GateLightYieldMessenger.cc | 73 ----- .../digits_hits/src/GateQuantumEfficiency.cc | 206 ------------ .../src/GateQuantumEfficiencyMessenger.cc | 58 ---- .../src/GateSinglesDigitizerMessenger.cc | 9 +- .../digits_hits/src/GateTransferEfficiency.cc | 113 ------- .../src/GateTransferEfficiencyMessenger.cc | 72 ---- 25 files changed, 619 insertions(+), 1736 deletions(-) delete mode 100644 source/digits_hits/include/GateBlurringWithIntrinsicResolution.hh delete mode 100644 source/digits_hits/include/GateBlurringWithIntrinsicResolutionMessenger.hh delete mode 100644 source/digits_hits/include/GateCalibration.hh delete mode 100644 source/digits_hits/include/GateCalibrationMessenger.hh create mode 100755 source/digits_hits/include/GateIntrinsicResolution.hh create mode 100755 source/digits_hits/include/GateIntrinsicResolutionMessenger.hh delete mode 100644 source/digits_hits/include/GateLightYield.hh delete mode 100644 source/digits_hits/include/GateLightYieldMessenger.hh delete mode 100644 source/digits_hits/include/GateQuantumEfficiency.hh delete mode 100644 source/digits_hits/include/GateQuantumEfficiencyMessenger.hh delete mode 100644 source/digits_hits/include/GateTransferEfficiency.hh delete mode 100644 source/digits_hits/include/GateTransferEfficiencyMessenger.hh delete mode 100644 source/digits_hits/src/GateBlurringWithIntrinsicResolution.cc delete mode 100644 source/digits_hits/src/GateBlurringWithIntrinsicResolutionMessenger.cc delete mode 100644 source/digits_hits/src/GateCalibration.cc delete mode 100644 source/digits_hits/src/GateCalibrationMessenger.cc create mode 100755 source/digits_hits/src/GateIntrinsicResolution.cc create mode 100755 source/digits_hits/src/GateIntrinsicResolutionMessenger.cc delete mode 100644 source/digits_hits/src/GateLightYield.cc delete mode 100644 source/digits_hits/src/GateLightYieldMessenger.cc delete mode 100644 source/digits_hits/src/GateQuantumEfficiency.cc delete mode 100644 source/digits_hits/src/GateQuantumEfficiencyMessenger.cc delete mode 100644 source/digits_hits/src/GateTransferEfficiency.cc delete mode 100644 source/digits_hits/src/GateTransferEfficiencyMessenger.cc diff --git a/source/digits_hits/include/GateBlurringWithIntrinsicResolution.hh b/source/digits_hits/include/GateBlurringWithIntrinsicResolution.hh deleted file mode 100644 index 9ff533a56..000000000 --- a/source/digits_hits/include/GateBlurringWithIntrinsicResolution.hh +++ /dev/null @@ -1,109 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateBlurringWithIntrinsicResolution_h -#define GateBlurringWithIntrinsicResolution_h 1 - -#include "globals.hh" -#include -#include - -#include "GateVPulseProcessor.hh" - -#include "GateMaps.hh" - - -class GateBlurringWithIntrinsicResolutionMessenger; - -/*! \class GateBlurringWithIntrinsicResolution - \brief Pulse-processor for simulating a special and local Gaussian blurring - - - GateBlurringWithIntrinsicResolution - by Martin.Rey@epfl.ch (mai 2003) - - - Pulse-processor for simulating a Gaussian local blurring on the energy spectrum - (different for several cystals) based on model : - \f[R=\sqrt{\frac{1.1}{N_{ph}\cdot QE\cdot TE}\cdot 2.35^2+R_i^2}\f] - where \f$N_{ph}=LY\cdot E_{inputPulse}\f$. - You have to give the intrinsic resolution (Ri) of each crystal. - If you use also the modules for Light Yield, Transfert et Quantum Efficiencies (LY, TE and QE), - this module takes these differents values, in other case they are equal to 1. - - \sa GateVPulseProcessor -*/ -class GateBlurringWithIntrinsicResolution : public GateVPulseProcessor -{ - - public: - //! Public Constructor - GateBlurringWithIntrinsicResolution(GatePulseProcessorChain* itsChain, - const G4String& itsName) ; - - //! Public Destructor - virtual ~GateBlurringWithIntrinsicResolution() ; - - public: - - //! Adds volume to the hashmap and returns 1 if it exists. If it does not exist, returns 0. - - G4int ChooseVolume(G4String val); - - - //! \name setters and getters - //@{ - - //! Allows to set the intrinsic resolution @ an energy of reference for crystal called 'name' - void SetIntrinsicResolution(G4String name, G4double val) { m_table[name].resolution = val; }; - void SetRefEnergy(G4String name, G4double val) {m_table[name].eref = val; }; - - //! Allows to get the intrinsic resolution @ an energy of reference for crystal called 'name' - //@{ - G4double GetIntrinsicResolution(G4String name) { return m_table[name].resolution; }; - G4double GetRefEnergy(G4String name) {return m_table[name].eref; }; - //@} - - //@} - - //! Implementation of the pure virtual method declared by the base class GateDigitizerComponent - //! print-out the attributes specific of the blurring - 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: - //! Find the different parameters of the input Pulse : - //! The depth 'm_depth in the VolumeID 'aVolumeID corresponding @ the volume named 'm_volumeName - //! The copy number 'm_volumeIDNo of the Inserter of the VolumeID 'aVolumeID for depth 'm_depth - //! The copy number of the Inserters above: m_k corresponding @ level 'm_depth-1, m_j @ level 'm_depth-2 and m_i @ level 'm_depth-3 - void FindInputPulseParams(const GateVolumeID* aVolumeID); - - struct param { - G4double resolution; - G4double eref; - }; - - private: - param m_param; //!< Simulated energy resolution and energy of reference - G4String m_name; //!< Name of the volume - GateMap m_table ; //!< Table which contains the names of volume with their characteristics - GateMap ::iterator im; //!< Table iterator - G4String m_volumeName; //!< Name of the module for quantum efficiency - G4int m_volumeIDNo; //!< numero of the volumeID - G4int m_i, m_j, m_k; //!< numero of the volumeID - size_t m_depth; //!< Depth of the selected volume in the Inserter - - GateBlurringWithIntrinsicResolutionMessenger *m_messenger; //!< Messenger -}; - - -#endif diff --git a/source/digits_hits/include/GateBlurringWithIntrinsicResolutionMessenger.hh b/source/digits_hits/include/GateBlurringWithIntrinsicResolutionMessenger.hh deleted file mode 100644 index 15ff287f3..000000000 --- a/source/digits_hits/include/GateBlurringWithIntrinsicResolutionMessenger.hh +++ /dev/null @@ -1,45 +0,0 @@ -/*---------------------- - 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 - ----------------------*/ - - -#ifndef GateBlurringWithIntrinsicResolutionMessenger_h -#define GateBlurringWithIntrinsicResolutionMessenger_h 1 - -#include "GatePulseProcessorMessenger.hh" -#include -#include "G4UIdirectory.hh" - -class G4UIdirectory; -class G4UIcmdWithAString; -class G4UIcmdWithADouble; -class G4UIcmdWithADoubleAndUnit; - -class GateBlurringWithIntrinsicResolution; - -class GateBlurringWithIntrinsicResolutionMessenger: public GatePulseProcessorMessenger -{ -public: - GateBlurringWithIntrinsicResolutionMessenger(GateBlurringWithIntrinsicResolution* itsIntrinsic); - virtual ~GateBlurringWithIntrinsicResolutionMessenger(); - - inline void SetNewValue(G4UIcommand* aCommand, G4String aString); - inline void SetNewValue2(G4UIcommand* aCommand, G4String aString); - - inline GateBlurringWithIntrinsicResolution* GetBlurringWithIntrinsicResolution() - { return (GateBlurringWithIntrinsicResolution*) GetPulseProcessor(); } - -private: - G4UIcmdWithAString *newVolCmd; - std::vector m_volDirectory; - std::vector resolutionCmd; - std::vector erefCmd; - std::vector m_name; - G4int m_count; -}; - -#endif diff --git a/source/digits_hits/include/GateCalibration.hh b/source/digits_hits/include/GateCalibration.hh deleted file mode 100644 index 9b80200b2..000000000 --- a/source/digits_hits/include/GateCalibration.hh +++ /dev/null @@ -1,76 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateCalibration_h -#define GateCalibration_h 1 - -#include "globals.hh" -#include -//#include -#include -#include "G4ThreeVector.hh" - -#include "GateVPulseProcessor.hh" - -class GateCalibrationMessenger; - - -/*! \class GateCalibration - \brief Pulse-processor modelling a calibration Nphotons->Energy. - - - GateCalibration - by Martin.Rey@epfl.ch (feb 2003) - - - Can be usefull if you use the class(es) GateLightYield, GateTransferEfficiency or GateQuantumEfficiency. - You can also set your own calibration factor. Allows the "recalibration" in energy. - - \sa GateVPulseProcessor -*/ -class GateCalibration : public GateVPulseProcessor -{ - public: - - //! Constructs a new calibration attached to a GateDigitizer - GateCalibration(GatePulseProcessorChain* itsChain, - const G4String& itsName) ; - //! Destructor - virtual ~GateCalibration() ; - - G4double GetCalibrationFactor() { return m_calib; }; - - void SetCalibrationFactor(G4double itsCalib) { m_calib = itsCalib; }; - - //! Implementation of the pure virtual method declared by the base class GateDigitizerComponent - //! print-out the attributes specific of the calibration - 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: - //! Find the different parameters of the input Pulse : - //! The depth 'm_depth in the VolumeID 'aVolumeID corresponding @ the volume named 'm_volumeName - //! The copy number 'm_volumeIDNo of the Inserter of the VolumeID 'aVolumeID for depth 'm_depth - //! The copy number of the Inserters above: m_k corresponding @ level 'm_depth-1, m_j @ level 'm_depth-2 and m_i @ level 'm_depth-3 - void FindInputPulseParams(const GateVolumeID* aVolumeID); - - private: - G4String m_volumeName; //!< Name of the module for quantum efficiency - G4int m_volumeIDNo; //!< numero of the volumeID - G4int m_i, m_j, m_k; //!< numero of the volumeID - size_t m_depth; //!< Depth of the selected volume in the Inserter - GateCalibrationMessenger *m_messenger; //!< Messenger - G4double m_calib; -}; - - -#endif diff --git a/source/digits_hits/include/GateCalibrationMessenger.hh b/source/digits_hits/include/GateCalibrationMessenger.hh deleted file mode 100644 index f78a1c32d..000000000 --- a/source/digits_hits/include/GateCalibrationMessenger.hh +++ /dev/null @@ -1,37 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateCalibrationMessenger_h -#define GateCalibrationMessenger_h 1 - -#include "GatePulseProcessorMessenger.hh" - -class G4UIdirectory; -class G4UIcmdWithoutParameter; -class G4UIcmdWithADouble; - -class GateCalibration; - -class GateCalibrationMessenger: public GatePulseProcessorMessenger -{ - public: - GateCalibrationMessenger(GateCalibration* itsCalibration); - virtual ~GateCalibrationMessenger() {}; - - void SetNewValue(G4UIcommand* aCommand, G4String aString); - - inline GateCalibration* GetCalibration() - { return (GateCalibration*) GetPulseProcessor(); } - -private: - G4UIcmdWithADouble *calibCmd; - -}; - -#endif diff --git a/source/digits_hits/include/GateIntrinsicResolution.hh b/source/digits_hits/include/GateIntrinsicResolution.hh new file mode 100755 index 000000000..3781cbb7c --- /dev/null +++ b/source/digits_hits/include/GateIntrinsicResolution.hh @@ -0,0 +1,116 @@ +/*---------------------- + 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 +----------------------*/ + +// 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 GateIntrinsicResolution.cc for more detals + */ + + +/*! \class GateIntrinsicResolution + \brief GateIntrinsicResolution does some dummy things with input digi + to create output digi + + - GateIntrinsicResolution - by name.surname@email.com + + \sa GateIntrinsicResolution, GateIntrinsicResolutionMessenger +*/ + +#ifndef GateIntrinsicResolution_h +#define GateIntrinsicResolution_h 1 + +#include "GateVDigitizerModule.hh" +#include "GateDigi.hh" +#include "GateClockDependent.hh" +#include "GateCrystalSD.hh" + +#include "globals.hh" + +#include "GateIntrinsicResolutionMessenger.hh" +#include "GateSinglesDigitizer.hh" +#include "GateLevelsFinder.hh" + + +class GateIntrinsicResolution : public GateVDigitizerModule +{ +public: + + GateIntrinsicResolution(GateSinglesDigitizer *digitizer, G4String name); + ~GateIntrinsicResolution(); + + void Digitize() override; + + // *******implement your methods here + void SetResolution(const G4double& value ){ m_resolution=value;} ; + void SetEref(const G4double& value ){ m_Eref=value;} ; + void SetLightOutput(const G4double& value ){ m_LY=value;} ; + void SetTransferEff(const G4double& value ){ m_TE=value;} ; + + //! Allow to use file(s) as lookout table for quantum efficiency + void UseFile(G4String aFile); + + //! Apply an unique quantum efficiency for all the channels + void SetUniqueQE(G4double val) { m_uniqueQE = val; }; + + void CreateTable(); + + void CheckVolumeName(G4String val); + + void DescribeMyself(size_t ); + +protected: + G4double m_resolution; + G4double m_Eref; + G4double m_LY; //Light Yield + G4double m_TE; //Transfer efficiency + G4double m_QE; //Quantum efficiency + G4bool isFirstEvent; + + G4double m_uniqueQE; //!< Value of the quantum efficiency if it's unique + G4int m_nbFiles; //!< Number of file(s) used for creating the lookout table + std::vector m_file; //!< Vector which contains the name(s) of the file(s) for the lookout table + + G4int m_nbCrystals; + //!< Number of PhysicalVolume copies of the Inserter corresponding @ level 'm_depth-1 + //!< Number of PhysicalVolume copies of the Inserter corresponding @ level 'm_depth-1 + G4int m_level3No; + //!< Number of PhysicalVolume copies of the Inserter corresponding @ level 'm_depth-2 + G4int m_level2No; + //!< Number of PhysicalVolume copies of the Inserter corresponding @ volume name 'm_volumeName + G4int m_level1No; + G4int m_nbTables; + GateLevelsFinder* m_levelFinder; + //!< Number of PhysicalVolume copies of the Inserter corresponding @ volume name 'm_volumeName + G4int m_i, m_j, m_k; //!< numero of the volumeID + G4int m_volumeIDNo; //!< numero of the volumeID + size_t m_depth; //!< Depth of the selected volume in the Inserter + 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 + +private: + GateDigi* m_outputDigi; + + GateIntrinsicResolutionMessenger *m_Messenger; + + GateDigiCollection* m_OutputDigiCollection; + + GateSinglesDigitizer *m_digitizer; + + +}; + +#endif + + + + + + + diff --git a/source/digits_hits/include/GateIntrinsicResolutionMessenger.hh b/source/digits_hits/include/GateIntrinsicResolutionMessenger.hh new file mode 100755 index 000000000..eabde5295 --- /dev/null +++ b/source/digits_hits/include/GateIntrinsicResolutionMessenger.hh @@ -0,0 +1,69 @@ +/*---------------------- + 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 +----------------------*/ + +// 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 GateIntrinsicResolution.cc for more detals + */ + + +/*! \class GateIntrinsicResolutionMessenger + \brief Messenger for the GateIntrinsicResolution + + - GateIntrinsicResolution - by name.surname@email.com + + \sa GateIntrinsicResolution, GateIntrinsicResolutionMessenger +*/ + + +#ifndef GateIntrinsicResolutionMessenger_h +#define GateIntrinsicResolutionMessenger_h 1 + +#include "G4UImessenger.hh" +#include "globals.hh" + +#include "GateClockDependentMessenger.hh" +class GateIntrinsicResolution; +class G4UIcmdWithADouble; +class G4UIcmdWithADoubleAndUnit; +class G4UIcmdWithAString; + +class GateIntrinsicResolutionMessenger : public GateClockDependentMessenger +{ +public: + + GateIntrinsicResolutionMessenger(GateIntrinsicResolution*); + ~GateIntrinsicResolutionMessenger(); + + void SetNewValue(G4UIcommand*, G4String); + + +private: + GateIntrinsicResolution* m_IntrinsicResolution; + + G4UIcmdWithADouble *resolutionCmd; + G4UIcmdWithADoubleAndUnit *erefCmd; + G4UIcmdWithADouble *lightOutputCmd; + G4UIcmdWithADouble *coeffTECmd; + G4UIcmdWithAString *newFileQECmd; + G4UIcmdWithADouble *uniqueQECmd; + + + +}; + +#endif + + + + + + + + diff --git a/source/digits_hits/include/GateLightYield.hh b/source/digits_hits/include/GateLightYield.hh deleted file mode 100644 index 6346a0240..000000000 --- a/source/digits_hits/include/GateLightYield.hh +++ /dev/null @@ -1,112 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateLightYield_h -#define GateLightYield_h 1 - -#include "globals.hh" -#include -#include -#include "G4ThreeVector.hh" - -#include "GateVPulseProcessor.hh" - -#include "GateMaps.hh" - -class GateLightYieldMessenger; - -/*! \class GateLightYield - \brief Pulse-processor for simulating the effect of the light yield of crystal(s). - You have to give the light yield (LY) of each crystal. - - - GateLightYield - by Martin.Rey@epfl.ch (mai 2003) - - - Pulse-processor for simulating the effect of the light yield of several crystals. - You have to give the light yield (LY) of each crystal. - - \sa GateVPulseProcessor -*/ -class GateLightYield : public GateVPulseProcessor -{ - - public: - //! This function allows to retrieve the current instance of the GateLightYield singleton - /*! - If the GateLightYield already exists, GetInstance only returns a pointer to this singleton. - If this singleton does not exist yet, GetInstance creates it by calling the private - GateLightYield constructor - */ - static GateLightYield* GetInstance(GatePulseProcessorChain* itsChain, - const G4String& itsName); - - //! Public Destructor - virtual ~GateLightYield() ; - - private: - //!< Private constructor which Constructs a new blurring module attached to a GateDigitizer: - //! this function should only be called from GetInstance() - GateLightYield(GatePulseProcessorChain* itsChain, - const G4String& itsName); - - public: - - //! Adds volume to the hashmap and returns 1 if it exists. If it does not exist, returns 0. - - G4int ChooseVolume(G4String val); - - - //! \name setters and getters - //@{ - - //! Allows to set the light output for crystal called 'name' (Nph/MeV) - void SetLightOutput(G4String name, G4double val) { m_table[name] = val; }; - - //! Allows to get the light output for crystal called 'name' (Nph/MeV) - G4double GetLightOutput(G4String name) { return m_table[name]; }; - - //! Return the actual light output - G4double GetActLightOutput() { return m_lightOutput; }; - - //! Return the minimum light output - G4double GetMinLightOutput(); - - //! Return the crystal name which have the minimum light output - G4String GetMinLightOutputName() { return m_minLightOutputName; }; - //@} - - - //! Implementation of the pure virtual method declared by the base class GateDigitizerComponent - //! print-out the attributes specific of the blurring - 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: - //! Static pointer to the GateLightYield singleton - static GateLightYield* theGateLightYield; - - private: - G4String m_name; //!< Name of the volume - GateMap m_table ; //!< Table which contains the names of volume with their characteristics - GateMap ::iterator im; //!< Table iterator - GateLightYieldMessenger *m_messenger; //!< Messenger - - G4double m_lightOutput; //!< Actual light output - - G4double m_minLightOutput; //!< Minimum light output - G4String m_minLightOutputName; //! Crystal name which have the minimum light output -}; - - -#endif diff --git a/source/digits_hits/include/GateLightYieldMessenger.hh b/source/digits_hits/include/GateLightYieldMessenger.hh deleted file mode 100644 index f815a5d16..000000000 --- a/source/digits_hits/include/GateLightYieldMessenger.hh +++ /dev/null @@ -1,43 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateLightYieldMessenger_h -#define GateLightYieldMessenger_h 1 - -#include "GatePulseProcessorMessenger.hh" -#include -#include "GateLightYield.hh" - -class G4UIdirectory; -class G4UIcmdWithAString; -class G4UIcmdWithADouble; - -class GateLightYield; - -class GateLightYieldMessenger: public GatePulseProcessorMessenger -{ - public: - GateLightYieldMessenger(GateLightYield* itsLightYield); - virtual ~GateLightYieldMessenger(); - - inline void SetNewValue(G4UIcommand* aCommand, G4String aString); - inline void SetNewValue2(G4UIcommand* aCommand, G4String aString); - - inline GateLightYield* GetLightYield() - { return (GateLightYield*) GetPulseProcessor(); } - - private: - G4UIcmdWithAString *newVolCmd; - std::vector m_volDirectory; - std::vector lightOutputCmd; - std::vector m_name; - G4int m_count; -}; - -#endif diff --git a/source/digits_hits/include/GateQuantumEfficiency.hh b/source/digits_hits/include/GateQuantumEfficiency.hh deleted file mode 100644 index 8f155f430..000000000 --- a/source/digits_hits/include/GateQuantumEfficiency.hh +++ /dev/null @@ -1,134 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateQuantumEfficiency_h -#define GateQuantumEfficiency_h 1 - -#include "globals.hh" -#include -#include -#include - -#include "GateVPulseProcessor.hh" -#include "GateLevelsFinder.hh" - -class GateQuantumEfficiencyMessenger; - -/*! \class GateQuantumEfficiency - \brief Pulse-processor for simulating a quantum efficiency. - - - GateQuantumEfficiency - by Martin.Rey@epfl.ch (dec 2002) - - - Pulse-processor for simulating the quantum efficiency on each channel of a PM or an APD. - There are two options: one, is to give an unique quantum efficiency for all the channels, - and, the other, is to give some lookout tables which contains data and this class takes these data - with small variations (minus than 2%) for creating the tables before the simulation. - - \sa GateVPulseProcessor -*/ -class GateQuantumEfficiency : public GateVPulseProcessor -{ - public: - //! This function allows to retrieve the current instance of the GateQuantumEfficiency singleton - /*! - If the GateQuantumEfficiency already exists, GetInstance only returns a pointer to this singleton. - If this singleton does not exist yet, GetInstance creates it by calling the private - GateQuantumEfficiency constructor - */ - static GateQuantumEfficiency* GetInstance(GatePulseProcessorChain* itsChain, - const G4String& itsName); - - //! Public Destructor - virtual ~GateQuantumEfficiency() ; - - private: - //!< Private constructor which Constructs a new quantum efficiency module attached to a GateDigitizer: - //! this function should only be called from GetInstance() - GateQuantumEfficiency(GatePulseProcessorChain* itsChain, - const G4String& itsName); - - public: - - //! Check the validity of the volume name where the quantum efficiency will be applied - void CheckVolumeName(G4String val); - - //! Allow to use file(s) as lookout table for quantum efficiency - void UseFile(G4String aFile); - - //! Apply an unique quantum efficiency for all the channels - void SetUniqueQE(G4double val) { m_uniqueQE = val; }; - - //! Create the table for the quantum efficiency inhomogeneity - void CreateTable(); - - //! Return the volume name where the quantum efficiency is applied - G4String GetVolumeName() { return m_volumeName; }; - - //! Return the actual QE coef - G4double GetActQECoeff() { return m_QECoef; }; - - //! Return the QE coef - G4double GetQECoeff(G4int tableNB, G4int crystalNb) { return m_table[tableNB][crystalNb]; }; - - //! Return the minimum QE coef - G4double GetMinQECoeff(); - - //! Return the number of element at level 1 - G4int Getlevel1No() { return m_level1No; }; - - //! Return the number of element at level 2 - G4int Getlevel2No() { return m_level2No; }; - - //! Return the number of element at level 3 - G4int Getlevel3No() { return m_level3No; }; - - //! Implementation of the pure virtual method declared by the base class GateDigitizerComponent - //! print-out the attributes specific of the gain module - 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: - //! Static pointer to the GateQuantumEfficiency singleton - static GateQuantumEfficiency* theGateQuantumEfficiency; - - GateQuantumEfficiencyMessenger* m_messenger; //!< Messenger - - G4String m_volumeName; //!< Name of the module - G4int m_testVolume; //!< equal to 1 if the volume name is valid, 0 else - size_t m_count; //!< equal to 0 before first ProcessOnPulse use, then 1 - GateLevelsFinder* m_levelFinder; - //!< Number of PhysicalVolume copies of the Inserter corresponding @ volume name 'm_volumeName - G4int m_nbCrystals; - //!< Number of PhysicalVolume copies of the Inserter corresponding @ level 'm_depth-1 - G4int m_level3No; - //!< Number of PhysicalVolume copies of the Inserter corresponding @ level 'm_depth-2 - G4int m_level2No; - //!< Number of PhysicalVolume copies of the Inserter corresponding @ volume name 'm_volumeName - G4int m_level1No; - G4int m_nbTables; - G4int m_volumeIDNo; //!< numero of the volumeID - G4int m_i, m_j, m_k; //!< numero of the volumeID - size_t m_depth; //!< Depth of the selected volume in the Inserter - G4int m_nbFiles; //!< Number of file(s) used for creating the lookout table - std::vector m_file; //!< Vector which contains the name(s) of the file(s) for the lookout table - G4double m_uniqueQE; //!< Value of the quantum efficiency if it's unique - G4double** m_table; //!< Lookout table for the quantum efficiency of all channels - G4double m_QECoef; //!< Actual value of the quantum efficiency - G4double m_minQECoef; //!< Minimum quantum efficiency -}; - - -#endif diff --git a/source/digits_hits/include/GateQuantumEfficiencyMessenger.hh b/source/digits_hits/include/GateQuantumEfficiencyMessenger.hh deleted file mode 100644 index 1cb41ba16..000000000 --- a/source/digits_hits/include/GateQuantumEfficiencyMessenger.hh +++ /dev/null @@ -1,39 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateQuantumEfficiencyMessenger_h -#define GateQuantumEfficiencyMessenger_h 1 - -#include "GatePulseProcessorMessenger.hh" -#include -#include "G4UIdirectory.hh" - -class G4UIcmdWithAString; -class G4UIcmdWithADouble; - -class GateQuantumEfficiency; - -class GateQuantumEfficiencyMessenger: public GatePulseProcessorMessenger -{ - public: - GateQuantumEfficiencyMessenger(GateQuantumEfficiency* itsQE); - virtual ~GateQuantumEfficiencyMessenger(); - - inline void SetNewValue(G4UIcommand* aCommand, G4String aString); - - inline GateQuantumEfficiency* GetQE() - { return (GateQuantumEfficiency*) GetPulseProcessor(); } - - private: - G4UIcmdWithAString *newVolCmd; - G4UIcmdWithADouble *uniqueQECmd; - G4UIcmdWithAString *newFileCmd; -}; - -#endif diff --git a/source/digits_hits/include/GateTransferEfficiency.hh b/source/digits_hits/include/GateTransferEfficiency.hh deleted file mode 100644 index dc92e48e1..000000000 --- a/source/digits_hits/include/GateTransferEfficiency.hh +++ /dev/null @@ -1,100 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#ifndef GateTransferEfficiency_h -#define GateTransferEfficiency_h 1 - -#include "globals.hh" -#include -#include - -#include "GateVPulseProcessor.hh" - -#include "GateMaps.hh" - -class GateTransferEfficiencyMessenger; - - -/*! \class GateTransferEfficiency - \brief Pulse-processor for simulating the transfer efficiency on each crystal. - - - GateTransferEfficiency - by Martin.Rey@epfl.ch (jan 2003) - - - Allows to specify a transfer coefficient for each type of crystals. - - \sa GateVPulseProcessor -*/ -class GateTransferEfficiency : public GateVPulseProcessor -{ - public: - //! This function allows to retrieve the current instance of the GateTransferEfficiency singleton - /*! - If the GateTransferEfficiency already exists, GetInstance only returns a pointer to this singleton. - If this singleton does not exist yet, GetInstance creates it by calling the private - GateTransferEfficiency constructor - */ - static GateTransferEfficiency* GetInstance(GatePulseProcessorChain* itsChain, - const G4String& itsName); - - //! Public Destructor - virtual ~GateTransferEfficiency() ; - - private: - //!< Private constructor: this function should only be called from GetInstance() - GateTransferEfficiency(GatePulseProcessorChain* itsChain, - const G4String& itsName); - public: - - //! Adds volume to the hashmap and returns 1 if it exists. If it does not exist, returns 0. - G4int ChooseVolume(G4String val); - - - //! \name setters and getters - //@{ - //! Set the transfer efficiency for the crystal called 'name - void SetTECoeff(G4String name, G4double val) { m_table[name] = val; }; - - //! Get the light output for crystal called 'name (Nph/MeV) - G4double GetTECrystCoeff(G4String name) { return m_table[name]; }; - - //! Get the actual transfer efficiency - G4double GetTECoeff() { return m_TECoef; }; - //! Get the minimum transfer efficiency - G4double GetTEMin(); - //@} - - //! Implementation of the pure virtual method declared by the base class GateDigitizerComponent - //! print-out the attributes specific of the blurring - 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: - //! Static pointer to the GateTransferEfficiency singleton - static GateTransferEfficiency* theGateTransferEfficiency; - - private: - G4String m_name; //! Name of the volume - //! Table which contains the names of volume with their transfert efficiencies - GateMap m_table ; - GateMap ::iterator im; - G4double m_TECoef; //! Actual transfer efficiency coefficient - G4double m_TEMin; //! Minimum transfer efficiency coefficient - - GateTransferEfficiencyMessenger *m_messenger; //!< Messenger -}; - - -#endif diff --git a/source/digits_hits/include/GateTransferEfficiencyMessenger.hh b/source/digits_hits/include/GateTransferEfficiencyMessenger.hh deleted file mode 100644 index 2c1ae1443..000000000 --- a/source/digits_hits/include/GateTransferEfficiencyMessenger.hh +++ /dev/null @@ -1,50 +0,0 @@ -/*---------------------- - 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 - ----------------------*/ - - -#ifndef GateTransferEfficiencyMessenger_h -#define GateTransferEfficiencyMessenger_h 1 - -#include "GatePulseProcessorMessenger.hh" -#include -#include "G4UIdirectory.hh" -#include "GateTransferEfficiency.hh" - -class G4UIdirectory; -class G4UIcmdWithoutParameter; -class G4UIcmdWithAString; -class G4UIcmdWithABool; -class G4UIcmdWithAnInteger; -class G4UIcmdWithADouble; -class G4UIcmdWithADoubleAndUnit; -class G4UIcmdWith3Vector; -class G4UIcmdWith3VectorAndUnit; - -class GateTransferEfficiency; - -class GateTransferEfficiencyMessenger: public GatePulseProcessorMessenger -{ -public: - GateTransferEfficiencyMessenger(GateTransferEfficiency* itsTE); - virtual ~GateTransferEfficiencyMessenger(); - - inline void SetNewValue(G4UIcommand* aCommand, G4String aString); - inline void SetNewValue2(G4UIcommand* aCommand, G4String aString); - - inline GateTransferEfficiency* GetTransferEfficiency() - { return (GateTransferEfficiency*) GetPulseProcessor(); } - -private: - G4UIcmdWithAString *newVolCmd; - std::vector m_volDirectory; - std::vector coeffTECmd; - std::vector m_name; - G4int m_count; -}; - -#endif diff --git a/source/digits_hits/src/GateBlurringWithIntrinsicResolution.cc b/source/digits_hits/src/GateBlurringWithIntrinsicResolution.cc deleted file mode 100644 index 0811214c2..000000000 --- a/source/digits_hits/src/GateBlurringWithIntrinsicResolution.cc +++ /dev/null @@ -1,143 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#include "GateBlurringWithIntrinsicResolution.hh" -#include "GateBlurringWithIntrinsicResolutionMessenger.hh" -#include "GateObjectStore.hh" - -#include "GateTools.hh" -#include "GateVolumeID.hh" -#include "GateCrosstalk.hh" -#include "GateTransferEfficiency.hh" -#include "GateQuantumEfficiency.hh" -#include "GateLightYield.hh" -#include "Randomize.hh" - -#include "G4UnitsTable.hh" -#include "GateConstants.hh" - - -// Constructor -GateBlurringWithIntrinsicResolution::GateBlurringWithIntrinsicResolution(GatePulseProcessorChain* itsChain, - const G4String& itsName) - : GateVPulseProcessor(itsChain, itsName) -{ - m_messenger = new GateBlurringWithIntrinsicResolutionMessenger(this); -} - -GateBlurringWithIntrinsicResolution::~GateBlurringWithIntrinsicResolution() -{ - delete m_messenger; -} - -G4int GateBlurringWithIntrinsicResolution::ChooseVolume(G4String val) -{ - GateObjectStore* m_store = GateObjectStore::GetInstance(); - - if (m_store->FindCreator(val)!=0) { - m_param.resolution = -1; - m_param.eref = -1; - m_table[val] = m_param; - return 1; - } - else { - G4cout << "Wrong Volume Name\n"; - return 0; - } -} - -void GateBlurringWithIntrinsicResolution::ProcessOnePulse(const GatePulse* inputPulse,GatePulseList& outputPulseList) -{ - im=m_table.find(((inputPulse->GetVolumeID()).GetBottomCreator())->GetObjectName()); - GatePulse* outputPulse = new GatePulse(*inputPulse); - if(im != m_table.end()) - { - if((*im).second.resolution < 0 ) { - G4cerr << Gateendl << "[GateBlurringWithIntrinsicResolution::ProcessOnePulse]:\n" - << "Sorry, but the resolution (" << (*im).second.resolution << ") for " << (*im).first << " is invalid\n"; - G4String msg = "You must set the energy of reference AND the resolution:\n\t/gate/digitizer/Singles/intrinsicResolutionBlurring/" + (*im).first + "/setEnergyOfReference ENERGY\n or disable the intrinsic resolution blurring using:\n\t/gate/digitizer/Singles/intrinsicResolutionBlurring/disable"; - G4Exception( "GateBlurringWithIntrinsicResolution::ProcessOnePulse", "ProcessOnePulse", FatalException, msg ); - } - else if((*im).second.eref < 0) { - G4cerr << Gateendl << "[GateBlurringWithIntrinsicResolution::ProcessOnePulse]:\n" - << "Sorry, but the energy of reference (" << G4BestUnit((*im).second.eref,"Energy") << ") for " - << (*im).first <<" is invalid\n"; - G4String msg = "You must set the resolution AND the energy of reference:\n\t/gate/digitizer/Singles/intrinsicResolutionBlurring/" + (*im).first + "/setEnergyOfReference ENERGY\n or disable the intrinsic resolution blurring using:\n\t/gate/digitizer/Singles/intrinsicResolutionBlurring/disable"; - G4Exception( "GateBlurringWithIntrinsicResolution::ProcessOnePulse", "ProcessOnePulse", FatalException, msg ); - } - else { - G4String LayerName = ((inputPulse->GetVolumeID()).GetBottomCreator())->GetObjectName(); - - G4double XtalkpCent = (GateCrosstalk::GetInstance(NULL,"name",0.,0.)) ? - GateCrosstalk::GetInstance(NULL,"name",0.,0.)->GetXTPerCent() : 1.; - - G4double TECoef = (GateTransferEfficiency::GetInstance(NULL,"name")) ? - GateTransferEfficiency::GetInstance(NULL,"name")->GetTECrystCoeff(LayerName) : 1.; - - G4double QECoef; - 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.; - - G4double LightOutput = (GateLightYield::GetInstance(NULL,"name")) ? - GateLightYield::GetInstance(NULL,"name")->GetLightOutput(LayerName) : 1.; - - G4double mu = inputPulse->GetEnergy(); - G4double intrinsicResol = (*im).second.resolution - * sqrt(((*im).second.eref * XtalkpCent * QECoef * TECoef * LightOutput) - / inputPulse->GetEnergy()); - - G4double resol = sqrt((1.1/mu)*(GateConstants::fwhm_to_sigma*GateConstants::fwhm_to_sigma) + intrinsicResol*intrinsicResol); - - outputPulse->SetEnergy(G4RandGauss::shoot(mu,(resol * mu)/GateConstants::fwhm_to_sigma)); - } - } - outputPulseList.push_back(outputPulse); -} - -void GateBlurringWithIntrinsicResolution::FindInputPulseParams(const GateVolumeID* aVolumeID) -{ - m_depth = (size_t)(aVolumeID->GetCreatorDepth(m_volumeName)); - m_volumeIDNo = aVolumeID->GetCopyNo(m_depth); - if (aVolumeID->GetCopyNo(m_depth-1)==-1) { - m_k=0; - m_j=0; - m_i=0; - } - else { - m_k = aVolumeID->GetCopyNo(m_depth-1); - if (aVolumeID->GetCopyNo(m_depth-2)==-1) { - m_j=0; - m_i=0; - } - else { - m_j = aVolumeID->GetCopyNo(m_depth-2); - if(aVolumeID->GetCopyNo(m_depth-3)==-1) - m_i=0; - else - m_i = aVolumeID->GetCopyNo(m_depth-3); - } - } -} - -void GateBlurringWithIntrinsicResolution::DescribeMyself(size_t indent) -{ - for (im=m_table.begin(); im!=m_table.end(); im++) - G4cout << GateTools::Indent(indent) << (*im).first << " :\n" - << GateTools::Indent(indent+1) << "Intrinsic resolution : " << (*im).second.resolution << " @ " - << G4BestUnit((*im).second.eref,"Energy") << Gateendl; -} diff --git a/source/digits_hits/src/GateBlurringWithIntrinsicResolutionMessenger.cc b/source/digits_hits/src/GateBlurringWithIntrinsicResolutionMessenger.cc deleted file mode 100644 index 488499b70..000000000 --- a/source/digits_hits/src/GateBlurringWithIntrinsicResolutionMessenger.cc +++ /dev/null @@ -1,86 +0,0 @@ -/*---------------------- - 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 - ----------------------*/ - - -#include "GateBlurringWithIntrinsicResolutionMessenger.hh" -#include "GateBlurringWithIntrinsicResolution.hh" - -#include "G4UIcmdWithAString.hh" -#include "G4UIcmdWithADoubleAndUnit.hh" -#include "G4UIcmdWithADouble.hh" - -GateBlurringWithIntrinsicResolutionMessenger::GateBlurringWithIntrinsicResolutionMessenger(GateBlurringWithIntrinsicResolution* itsIntrinsic) - : GatePulseProcessorMessenger(itsIntrinsic) -{ - G4String guidance; - G4String cmdName; - m_count=0; - - cmdName = GetDirectoryName() + "chooseNewVolume"; - newVolCmd = new G4UIcmdWithAString(cmdName,this); - newVolCmd->SetGuidance("Choose a volume for intrinsic blurring"); -} - - -GateBlurringWithIntrinsicResolutionMessenger::~GateBlurringWithIntrinsicResolutionMessenger() -{ - delete newVolCmd; - for (G4int i=0;iChooseVolume(newValue) == 1) { - m_volDirectory.push_back(new G4UIdirectory( (GetDirectoryName() + newValue + "/").c_str() )); - m_volDirectory[m_count]->SetGuidance((G4String("characteristics of ") + newValue).c_str()); - - m_name.push_back(newValue); - - cmdName2 = m_volDirectory[m_count]->GetCommandPath() + "setIntrinsicResolution"; - resolutionCmd.push_back(new G4UIcmdWithADouble(cmdName2,this)); - resolutionCmd[m_count]->SetGuidance("Set the intrinsic resolution in energie for this crystal"); - - cmdName3 = m_volDirectory[m_count]->GetCommandPath() + "setEnergyOfReference"; - erefCmd.push_back(new G4UIcmdWithADoubleAndUnit(cmdName3,this)); - erefCmd[m_count]->SetGuidance("Set the energy of reference (in keV) for the selected resolution"); - erefCmd[m_count]->SetUnitCategory("Energy"); - - m_count++; - } - } - else - SetNewValue2(command,newValue); -} - -void GateBlurringWithIntrinsicResolutionMessenger::SetNewValue2(G4UIcommand* command, G4String newValue) -{ - G4int test=0; - for (G4int i=0;iSetIntrinsicResolution(m_name[i], resolutionCmd[i]->GetNewDoubleValue(newValue)); - test=1; - } - } - if(test==0) - for (G4int i=0;iSetRefEnergy(m_name[i], erefCmd[i]->GetNewDoubleValue(newValue)); - test=1; - } - } - if(test==0) - GatePulseProcessorMessenger::SetNewValue(command,newValue); -} diff --git a/source/digits_hits/src/GateCalibration.cc b/source/digits_hits/src/GateCalibration.cc deleted file mode 100644 index 4024d64c5..000000000 --- a/source/digits_hits/src/GateCalibration.cc +++ /dev/null @@ -1,98 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#include "GateCalibration.hh" - -#include "G4UnitsTable.hh" - -#include "GateCalibrationMessenger.hh" -#include "GateTransferEfficiency.hh" -#include "GateQuantumEfficiency.hh" -#include "GateLightYield.hh" -#include "GateTools.hh" -#include "GateVolumeID.hh" - - -GateCalibration::GateCalibration(GatePulseProcessorChain* itsChain, - const G4String& itsName) - : GateVPulseProcessor(itsChain, itsName) -{ - m_messenger = new GateCalibrationMessenger(this); - m_calib = 1; -} - - - - -GateCalibration::~GateCalibration() -{ - delete m_messenger; -} - - - -void GateCalibration::ProcessOnePulse(const GatePulse* inputPulse,GatePulseList& outputPulseList) -{ - GatePulse* outputPulse = new GatePulse(*inputPulse); - G4String LayerName = ((inputPulse->GetVolumeID()).GetBottomCreator())->GetObjectName(); - - G4double lightOutput = (GateLightYield::GetInstance(NULL,"name")) ? - GateLightYield::GetInstance(NULL,"name")->GetLightOutput(LayerName) : 1.; - - G4double TECoef = (GateTransferEfficiency::GetInstance(NULL,"name")) ? - GateTransferEfficiency::GetInstance(NULL,"name")->GetTECrystCoeff(LayerName) : 1.; - - G4double QECoef; - 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.; - - outputPulse->SetEnergy(inputPulse->GetEnergy()/(lightOutput*TECoef*QECoef)*m_calib); - outputPulseList.push_back(outputPulse); -} - - -void GateCalibration::FindInputPulseParams(const GateVolumeID* aVolumeID) -{ - m_depth = (size_t)(aVolumeID->GetCreatorDepth(m_volumeName)); - m_volumeIDNo = aVolumeID->GetCopyNo(m_depth); - if (aVolumeID->GetCopyNo(m_depth-1)==-1) { - m_k=0; - m_j=0; - m_i=0; - } - else { - m_k = aVolumeID->GetCopyNo(m_depth-1); - if (aVolumeID->GetCopyNo(m_depth-2)==-1) { - m_j=0; - m_i=0; - } - else { - m_j = aVolumeID->GetCopyNo(m_depth-2); - if(aVolumeID->GetCopyNo(m_depth-3)==-1) - m_i=0; - else - m_i = aVolumeID->GetCopyNo(m_depth-3); - } - } -} - - -void GateCalibration::DescribeMyself(size_t indent) -{ - G4cout << GateTools::Indent(indent) << "Calibration Nphotoelectrons->Energy \n"; -} diff --git a/source/digits_hits/src/GateCalibrationMessenger.cc b/source/digits_hits/src/GateCalibrationMessenger.cc deleted file mode 100644 index bcc1207d8..000000000 --- a/source/digits_hits/src/GateCalibrationMessenger.cc +++ /dev/null @@ -1,33 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#include "GateCalibrationMessenger.hh" - -#include "GateCalibration.hh" - -#include "G4UIcmdWithADouble.hh" - -GateCalibrationMessenger::GateCalibrationMessenger(GateCalibration* itsCalibration) - : GatePulseProcessorMessenger(itsCalibration) -{ - G4String guidance; - G4String cmdName; - - cmdName = GetDirectoryName() + "setCalibration"; - calibCmd = new G4UIcmdWithADouble(cmdName,this); - calibCmd->SetGuidance("Set calibration factor"); -} - -void GateCalibrationMessenger::SetNewValue(G4UIcommand* command, G4String newValue) -{ - if ( command==calibCmd ) - { GetCalibration()->SetCalibrationFactor(calibCmd->GetNewDoubleValue(newValue)); } - else - GatePulseProcessorMessenger::SetNewValue(command,newValue); -} diff --git a/source/digits_hits/src/GateIntrinsicResolution.cc b/source/digits_hits/src/GateIntrinsicResolution.cc new file mode 100755 index 000000000..9d9b0747f --- /dev/null +++ b/source/digits_hits/src/GateIntrinsicResolution.cc @@ -0,0 +1,307 @@ + +/*---------------------- + 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 GateIntrinsicResolution + + \brief Digitizer Module for simulating a special Gaussian blurring + ex GateBlurringWithIntrinsicResolution, GateLightYield, GateTransferEfficiency, GateQuantumEfficiency + + - GateIntrinsicResolution - by Martin.Rey@epfl.ch (mai 2003) + + - Digitizer Module for simulating a Gaussian blurring on the energy spectrum + based on model (modeling with a parameterization of number of optical photons + generated in a detector and the number of photoelectrons on a cathode : + \f[R=\sqrt{\frac{1.1}{N_{ph}\cdot QE\cdot TE}\cdot 2.35^2+R_i^2}\f] + where \f$N_{ph}=LY\cdot E_{inputHit}\f$. + + Light Yield and Transfer Efficiency are also included in this class + since Gate9.3 (before they were separate classes) + + - Light Yield - the effect of the light yield + - Transfer Efficiency - Allows to specify a transfer coefficients. + - Quantum Efficiency - Allows to specify a quantum eff coefficients. + + 4/12/23 - Added to GND by kochebina@cea.fr + + \sa GateVDigitizerModule +*/ + + +#include "GateIntrinsicResolution.hh" +#include "GateIntrinsicResolutionMessenger.hh" +#include "GateDigi.hh" + +#include "GateDigitizerMgr.hh" + +#include "G4SystemOfUnits.hh" +#include "G4EventManager.hh" +#include "G4Event.hh" +#include "G4SDManager.hh" +#include "G4DigiManager.hh" +#include "G4ios.hh" +#include "G4UnitsTable.hh" + +#include "GateConstants.hh" +#include "GateObjectStore.hh" + +GateIntrinsicResolution::GateIntrinsicResolution(GateSinglesDigitizer *digitizer, G4String name) + :GateVDigitizerModule(name,"digitizerMgr/"+digitizer->GetSD()->GetName()+"/SinglesDigitizer/"+digitizer->m_digitizerName+"/"+name,digitizer,digitizer->GetSD()), + m_resolution(-1), + m_Eref(-1), + m_LY(1), + m_TE(1), + m_QE(1), + isFirstEvent(true), + m_outputDigi(0), + m_OutputDigiCollection(0), + m_digitizer(digitizer) + { + G4String colName = digitizer->GetOutputName() ; + collectionName.push_back(colName); + m_Messenger = new GateIntrinsicResolutionMessenger(this); + + m_nbTables = 0; + m_uniqueQE = 1; + m_nbFiles = 0; + +} + + +GateIntrinsicResolution::~GateIntrinsicResolution() +{ + delete m_Messenger; + +} + + +void GateIntrinsicResolution::Digitize() +{ + G4double XtalkpCent; + + if(isFirstEvent) + { + if(m_resolution < 0 ) { + G4cerr << Gateendl << "[GateBlurringWithIntrinsicResolution::Digitize]:\n" + << "Sorry, but the resolution (" << m_resolution << ") for " << m_digitizer->GetSD()->GetName() << " is invalid\n"; + G4String msg = "You must set the energy of reference AND the resolution or disable the intrinsic resolution"; + G4Exception( "GateBlurringWithIntrinsicResolution::Digitize", "Digitize", FatalException, msg ); + } + else if(m_Eref < 0) { + G4cerr << Gateendl << "[GateBlurringWithIntrinsicResolution::Digitize]:\n" + << "Sorry, but the energy of reference (" << G4BestUnit(m_Eref,"Energy") << ") for " + << m_digitizer->GetSD()->GetName() <<" is invalid\n"; + G4String msg = "You must set the resolution AND the energy of reference or disable the intrinsic resolution"; + G4Exception( "GateBlurringWithIntrinsicResolution::Digitize", "Digitize", FatalException, msg ); + } + + // 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.; + */ + isFirstEvent=false; + } + + 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 << "[ GateIntrinsicResolution::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_digitizer->GetSD()->GetName())); + std::vector pulseLevels = m_levelFinder->FindInputPulseParams(&inputDigi->GetVolumeID(), + m_depth); + m_volumeIDNo = pulseLevels[0]; + m_k = (pulseLevels.size() >= 1) ? pulseLevels[1] : 0; + m_j = (pulseLevels.size() >= 2) ? pulseLevels[2] : 0; + m_i = (pulseLevels.size() >= 3) ? pulseLevels[3] : 0; + + m_QE = m_table[m_k + m_j*m_level3No + m_i*m_level3No*m_level2No][m_volumeIDNo]; + // end for QE + + + m_outputDigi = new GateDigi(*inputDigi); + + G4double energy = inputDigi->GetEnergy(); + G4double Nph = energy*m_LY*m_TE*m_QE;//*XtalkpCent GND TODO; + G4double Ri = m_resolution * sqrt((m_Eref / energy)); + + G4double resol = sqrt((1.1/Nph)*(GateConstants::fwhm_to_sigma*GateConstants::fwhm_to_sigma) + Ri*Ri); + + m_outputDigi->SetEnergy(G4RandGauss::shoot(energy,(resol * energy)/GateConstants::fwhm_to_sigma)); + + + + if (nVerboseLevel>1) + G4cout << "Created new pulse for volume " << inputDigi->GetVolumeID() << ".\n" + << "Resulting pulse is: \n" + << *m_outputDigi << Gateendl << Gateendl ; + + m_OutputDigiCollection->insert(m_outputDigi); + + + if (nVerboseLevel==1) { + G4cout << "[GateIntrinsicResolution::Digitize]: returning output pulse-list with " << OutputDigiCollectionVector->size() << " entries\n"; + for (iter=OutputDigiCollectionVector->begin(); iter!= OutputDigiCollectionVector->end() ; ++iter) + G4cout << **iter << Gateendl; + G4cout << Gateendl; + } + } //loop over input digits + } //IDC + else + { + if (nVerboseLevel>1) + G4cout << "[GateIntrinsicResolution::Digitize]: input digi collection is null -> nothing to do\n\n"; + return; + } + StoreDigiCollection(m_OutputDigiCollection); + +} + + +void GateIntrinsicResolution::UseFile(G4String aFile) +{ + std::ifstream in(aFile); + G4double temp; + G4int count = 0; + while (1) { + in >> temp; + if (!in.good()) break; + count++; + } + in.close(); + if (count==m_nbCrystals) { + m_file.push_back(aFile); + m_nbFiles++; + } +} + + + +void GateIntrinsicResolution::CreateTable() +{ + + m_nbTables = m_level1No * m_level2No * m_level3No; + G4int r, n; + m_table = new G4double* [m_nbTables]; + std::ifstream in; + std::ofstream out; + + if (nVerboseLevel > 1) + G4cout << "Creation of a file called 'QETables.dat' which contains the quantum efficiencies tables\n"; + + for (r = 0; r < m_nbTables; r++) { + m_table[r] = new G4double [m_nbCrystals]; + if (m_nbFiles > 0) { + size_t rmd = G4RandFlat::shootInt(m_nbFiles); + in.open(m_file[rmd].c_str()); + for (n = 0; n < m_nbCrystals; n++){ + G4double rmd2 = G4RandFlat::shoot(-0.025, 0.025); + in >> m_table[r][n]; + m_table[r][n]*=(rmd2+1); + } + in.close(); + } + else + for (n = 0; n < (m_nbCrystals); n++) { + if (m_uniqueQE) + m_table[r][n] = m_uniqueQE; + else + m_table[r][n] = 1; + } + if (nVerboseLevel > 1) + { + if (! out.is_open()) + out.open("QETables.dat"); + out << "#Table nb: " << r << Gateendl; + for (n = 0; n < (m_nbCrystals); n++) + out << m_table[r][n] << Gateendl; + } + } + if (out.is_open()) + out.close(); +} + + +void GateIntrinsicResolution::CheckVolumeName(G4String val) +{ + //Retrieve the inserter store to check if the volume name is valid + GateObjectStore* anInserterStore = GateObjectStore::GetInstance(); + + + if (anInserterStore->FindCreator(val)) { + m_volumeName = val; + //Find the level params + GateVVolume* anInserter = anInserterStore->FindCreator(m_volumeName); + std::vector levels; + m_levelFinder = new GateLevelsFinder(anInserter, levels); + m_nbCrystals = levels[0]; + m_level3No = (levels.size() >= 1) ? levels[1] : 1; + m_level2No = (levels.size() >= 2) ? levels[2] : 1; + m_level1No = (levels.size() >= 3) ? levels[3] : 1; + + m_testVolume = 1; + + } + else { + G4cout << "Wrong Volume Name\n"; + } +} + +void GateIntrinsicResolution::DescribeMyself(size_t indent ) +{ + ; +} diff --git a/source/digits_hits/src/GateIntrinsicResolutionMessenger.cc b/source/digits_hits/src/GateIntrinsicResolutionMessenger.cc new file mode 100755 index 000000000..7cc75d066 --- /dev/null +++ b/source/digits_hits/src/GateIntrinsicResolutionMessenger.cc @@ -0,0 +1,119 @@ +/*---------------------- + 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 +----------------------*/ + + +// OK GND 2022 + +/*! \class GateIntrinsicResolutionMessenger + \brief Messenger for the GateIntrinsicResolution + + \sa GateEnergyResolution, GateEnergyResolutionMessenger +*/ + + +#include "GateIntrinsicResolutionMessenger.hh" +#include "GateIntrinsicResolution.hh" +#include "GateDigitizerMgr.hh" + +#include "G4SystemOfUnits.hh" +#include "G4UIcmdWithADouble.hh" +#include "G4UIcmdWithADoubleAndUnit.hh" +#include "G4UIdirectory.hh" + + + +GateIntrinsicResolutionMessenger::GateIntrinsicResolutionMessenger (GateIntrinsicResolution* IntrinsicResolution) +:GateClockDependentMessenger(IntrinsicResolution), + m_IntrinsicResolution(IntrinsicResolution) +{ + G4String guidance; + G4String cmdName; + + cmdName = GetDirectoryName() + "setIntrinsicResolution"; + resolutionCmd = new G4UIcmdWithADouble(cmdName,this); + resolutionCmd->SetGuidance("Set the intrinsic resolution in energy for this crystal"); + + cmdName = GetDirectoryName() + "setEnergyOfReference"; + erefCmd = new G4UIcmdWithADoubleAndUnit(cmdName,this); + erefCmd->SetGuidance("Set the energy of reference (in keV) for the selected resolution"); + erefCmd->SetUnitCategory("Energy"); + + cmdName = GetDirectoryName() + "setLightOutput"; + lightOutputCmd=new G4UIcmdWithADouble(cmdName,this); + lightOutputCmd->SetGuidance("Set the Light Output for this crystal (ph/MeV):"); + + cmdName = GetDirectoryName() + "setTECoef"; + coeffTECmd=new G4UIcmdWithADouble(cmdName,this); + coeffTECmd->SetGuidance("Set the coefficient for transfer efficiency"); + + cmdName = GetDirectoryName() + "useFileDataForQE"; + newFileQECmd = new G4UIcmdWithAString(cmdName,this); + newFileQECmd->SetGuidance("Use data from a file to set your quantum efficiency inhomogeneity"); + + cmdName = GetDirectoryName() + "setUniqueQE"; + uniqueQECmd = new G4UIcmdWithADouble(cmdName,this); + uniqueQECmd->SetGuidance("Set an unique quantum efficiency"); +} + + +GateIntrinsicResolutionMessenger::~GateIntrinsicResolutionMessenger() +{ + delete resolutionCmd; + delete erefCmd; + delete lightOutputCmd; + delete coeffTECmd; + delete newFileQECmd; + delete uniqueQECmd; +} + + +void GateIntrinsicResolutionMessenger::SetNewValue(G4UIcommand * aCommand,G4String newValue) +{ + if (aCommand == resolutionCmd) + { + m_IntrinsicResolution->SetResolution(resolutionCmd->GetNewDoubleValue(newValue)); + } + else if (aCommand ==erefCmd) + { + m_IntrinsicResolution->SetEref(erefCmd->GetNewDoubleValue(newValue)); + } + else if (aCommand ==lightOutputCmd) + { + m_IntrinsicResolution->SetLightOutput(lightOutputCmd->GetNewDoubleValue(newValue)); + } + else if (aCommand ==coeffTECmd) + { + m_IntrinsicResolution->SetTransferEff(coeffTECmd->GetNewDoubleValue(newValue)); + } + else if ( aCommand==newFileQECmd ) + { + m_IntrinsicResolution->UseFile(newValue); + } + else if ( aCommand==uniqueQECmd ) + { + m_IntrinsicResolution->SetUniqueQE(uniqueQECmd->GetNewDoubleValue(newValue)); + } + + else + { + GateClockDependentMessenger::SetNewValue(aCommand,newValue); + } +} + + + + + + + + + + + + + diff --git a/source/digits_hits/src/GateLightYield.cc b/source/digits_hits/src/GateLightYield.cc deleted file mode 100644 index dca23e3a8..000000000 --- a/source/digits_hits/src/GateLightYield.cc +++ /dev/null @@ -1,108 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#include "GateLightYield.hh" -#include "GateLightYieldMessenger.hh" -#include "GateTools.hh" -#include "GateVolumeID.hh" -#include "Randomize.hh" - -#include "G4UnitsTable.hh" - -#include "GateObjectStore.hh" - -// Static pointer to the GateLightYield singleton -GateLightYield* GateLightYield::theGateLightYield=0; - - - -/* This function allows to retrieve the current instance of the GateLightYield singleton - If the GateLightYield already exists, GetInstance only returns a pointer to this singleton. - If this singleton does not exist yet, GetInstance creates it by calling the private - GateLightYield constructor -*/ -GateLightYield* GateLightYield::GetInstance(GatePulseProcessorChain* itsChain, - const G4String& itsName) -{ - if (!theGateLightYield) - if (itsChain) - theGateLightYield = new GateLightYield(itsChain, itsName); - return theGateLightYield; -} - -// Private constructor -GateLightYield::GateLightYield(GatePulseProcessorChain* itsChain, - const G4String& itsName) - : GateVPulseProcessor(itsChain, itsName) -{ - m_messenger = new GateLightYieldMessenger(this); - m_lightOutput = 1.; -} - -GateLightYield::~GateLightYield() -{ - delete m_messenger; -} - -G4int GateLightYield::ChooseVolume(G4String val) -{ - //Retrieve the inserter store to check if the volume name is valid - GateObjectStore* m_store = GateObjectStore::GetInstance(); - if (m_store->FindCreator(val)!=0) { - m_table[val] = 1.; - return 1; - } - else { - G4cout << "Wrong Volume Name\n"; - return 0; - } -} - -void GateLightYield::ProcessOnePulse(const GatePulse* inputPulse,GatePulseList& outputPulseList) -{ - //Set the table iterator at the one which correspond to the layer volume name of the pulse - im=m_table.find(((inputPulse->GetVolumeID()).GetBottomCreator())->GetObjectName()); - GatePulse* outputPulse = new GatePulse(*inputPulse); - if(im != m_table.end()) - { - if((*im).second < 0 ) { - G4cerr << Gateendl << "[GateLightYield::ProcessOnePulse]:\n" - << "Sorry, but the light output (" << (*im).second << ") for " << (*im).first << " is invalid\n"; - - G4String msg = "You must set the light output:\n\t/gate/digitizer/Singles/lightYield/" + (*im).first + "/setLightOutput NBphotons/ENERGY\n or disable the light yield module using:\n\t/gate/digitizer/Singles/lightYield/disable"; - G4Exception( "GateLightYield::ProcessOnePulse", "ProcessOnePulse", FatalException, msg ); - } - else { - m_lightOutput = (*im).second; - outputPulse->SetEnergy(inputPulse->GetEnergy() * m_lightOutput); - } - } - outputPulseList.push_back(outputPulse); -} - -G4double GateLightYield::GetMinLightOutput() -{ - im=m_table.begin(); - m_minLightOutput = (*im).second; - m_minLightOutputName = (*im).first; - for (im=m_table.begin(); im!=m_table.end(); im++) - if ((*im).second <= m_minLightOutput) - { - m_minLightOutput = (*im).second; - m_minLightOutputName = (*im).first; - } - return m_minLightOutput; -} - -void GateLightYield::DescribeMyself(size_t indent) -{ - for (im=m_table.begin(); im!=m_table.end(); im++) - G4cout << GateTools::Indent(indent) << (*im).first << " :\n" - << GateTools::Indent(indent+1) << "Light output: " << (*im).second * MeV << " photons/MeV\n" << Gateendl; -} diff --git a/source/digits_hits/src/GateLightYieldMessenger.cc b/source/digits_hits/src/GateLightYieldMessenger.cc deleted file mode 100644 index b649983f2..000000000 --- a/source/digits_hits/src/GateLightYieldMessenger.cc +++ /dev/null @@ -1,73 +0,0 @@ -/*---------------------- - 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 - ----------------------*/ - - -#include "GateLightYieldMessenger.hh" -#include "GateLightYield.hh" - -#include "G4UIdirectory.hh" -#include "G4UIcmdWithAString.hh" -#include "G4UIcmdWithADouble.hh" - -GateLightYieldMessenger::GateLightYieldMessenger(GateLightYield* itsLightYield) - : GatePulseProcessorMessenger(itsLightYield) -{ - G4String guidance; - G4String cmdName; - m_count=0; - - cmdName = GetDirectoryName() + "chooseNewVolume"; - newVolCmd = new G4UIcmdWithAString(cmdName,this); - newVolCmd->SetGuidance("Choose a volume for light yield"); -} - - -GateLightYieldMessenger::~GateLightYieldMessenger() -{ - delete newVolCmd; - for (G4int i=0;iChooseVolume(newValue) == 1) { - m_volDirectory.push_back(new G4UIdirectory( (GetDirectoryName() + newValue + "/").c_str() )); - m_volDirectory[m_count]->SetGuidance((G4String("light yield of ") + newValue).c_str()); - - m_name.push_back(newValue); - - cmdName2 = m_volDirectory[m_count]->GetCommandPath() + "setLightOutput"; - lightOutputCmd.push_back(new G4UIcmdWithADouble(cmdName2,this)); - lightOutputCmd[m_count]->SetGuidance("Set the Light Output for this crystal (ph/MeV):"); - - m_count++; - } - } - else - SetNewValue2(command,newValue); -} - -void GateLightYieldMessenger::SetNewValue2(G4UIcommand* command, G4String newValue) -{ - G4int test=0; - for (G4int i=0;iSetLightOutput(m_name[i], lightOutputCmd[i]->GetNewDoubleValue(newValue)/MeV); - test=1; - } - } - if(test==0) - GatePulseProcessorMessenger::SetNewValue(command,newValue); -} diff --git a/source/digits_hits/src/GateQuantumEfficiency.cc b/source/digits_hits/src/GateQuantumEfficiency.cc deleted file mode 100644 index 8c65f7610..000000000 --- a/source/digits_hits/src/GateQuantumEfficiency.cc +++ /dev/null @@ -1,206 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#include "GateQuantumEfficiency.hh" - -#include "GateQuantumEfficiencyMessenger.hh" -#include "GateTools.hh" - -#include "GateVolumeID.hh" -#include "GateOutputVolumeID.hh" -#include "GateDetectorConstruction.hh" -#include "GateCrystalSD.hh" -#include "GateVSystem.hh" -#include "GateObjectChildList.hh" -#include "GateVVolume.hh" - -#include "GateMaps.hh" -#include "GateObjectStore.hh" - -#include "G4UnitsTable.hh" - - -// Static pointer to the GateQuantumEfficiency singleton -GateQuantumEfficiency* GateQuantumEfficiency::theGateQuantumEfficiency=0; - - -/* This function allows to retrieve the current instance of the GateQuantumEfficiency singleton - If the GateQuantumEfficiency already exists, GetInstance only returns a pointer to this singleton. - If this singleton does not exist yet, GetInstance creates it by calling the private - GateQuantumEfficiency constructor -*/ -GateQuantumEfficiency* GateQuantumEfficiency::GetInstance(GatePulseProcessorChain* itsChain, - const G4String& itsName) -{ - if (!theGateQuantumEfficiency) - if (itsChain) - theGateQuantumEfficiency = new GateQuantumEfficiency(itsChain, itsName); - return theGateQuantumEfficiency; -} - - -// Private constructor -GateQuantumEfficiency::GateQuantumEfficiency(GatePulseProcessorChain* itsChain, - const G4String& itsName) - : GateVPulseProcessor(itsChain,itsName) -{ - m_messenger = new GateQuantumEfficiencyMessenger(this); - m_count = 0; - m_testVolume = 0; - m_nbTables = 0; - m_uniqueQE = 1; - m_nbFiles = 0; - m_QECoef = 1; -} - -// Public destructor -GateQuantumEfficiency::~GateQuantumEfficiency() -{ - delete m_messenger; - delete [] m_table; -} - - - -void GateQuantumEfficiency::CheckVolumeName(G4String val) -{ - //Retrieve the inserter store to check if the volume name is valid - GateObjectStore* anInserterStore = GateObjectStore::GetInstance(); - - - if (anInserterStore->FindCreator(val)) { - m_volumeName = val; - //Find the level params - GateVVolume* anInserter = anInserterStore->FindCreator(m_volumeName); - std::vector levels; - m_levelFinder = new GateLevelsFinder(anInserter, levels); - m_nbCrystals = levels[0]; - m_level3No = (levels.size() >= 1) ? levels[1] : 1; - m_level2No = (levels.size() >= 2) ? levels[2] : 1; - m_level1No = (levels.size() >= 3) ? levels[3] : 1; - - m_testVolume = 1; - - } - else { - G4cout << "Wrong Volume Name\n"; - } -} - -void GateQuantumEfficiency::ProcessOnePulse(const GatePulse* inputPulse,GatePulseList& outputPulseList) -{ - if(!m_count) - { - if(!m_testVolume) - { - G4cerr << Gateendl << "[GateQuantumEfficiency::ProcessOnePulse]:\n" - << "Sorry, but you don't have choosen any volume !\n"; - G4Exception( "GateQuantumEfficiency::ProcessOnePulse", "ProcessOnePulse", FatalException, "You must choose a volume for crosstalk, e.g. crystal:\n\t/gate/digitizer/Singles/quantumEfficiency/chooseQEVolume VOLUME NAME\n or disable the quantumEfficiency using:\n\t/gate/digitizer/Singles/quantumEfficiency/disable\n"); - } - //Create the table containing the quantum efficiencies - CreateTable(); - m_count++; - }; - m_depth = (size_t)(inputPulse->GetVolumeID().GetCreatorDepth(m_volumeName)); - std::vector pulseLevels = m_levelFinder->FindInputPulseParams(&inputPulse->GetVolumeID(), - m_depth); - m_volumeIDNo = pulseLevels[0]; - m_k = (pulseLevels.size() >= 1) ? pulseLevels[1] : 0; - m_j = (pulseLevels.size() >= 2) ? pulseLevels[2] : 0; - m_i = (pulseLevels.size() >= 3) ? pulseLevels[3] : 0; - - GatePulse* outputPulse = new GatePulse(*inputPulse); - m_QECoef = m_table[m_k + m_j*m_level3No + m_i*m_level3No*m_level2No][m_volumeIDNo]; - outputPulse->SetEnergy(inputPulse->GetEnergy() * m_QECoef); - outputPulseList.push_back(outputPulse); -} - - -void GateQuantumEfficiency::UseFile(G4String aFile) -{ - std::ifstream in(aFile); - G4double temp; - G4int count = 0; - while (1) { - in >> temp; - if (!in.good()) break; - count++; - } - in.close(); - if (count==m_nbCrystals) { - m_file.push_back(aFile); - m_nbFiles++; - } -} - - -void GateQuantumEfficiency::CreateTable() -{ - m_nbTables = m_level1No * m_level2No * m_level3No; - G4int r, n; - m_table = new G4double* [m_nbTables]; - std::ifstream in; - std::ofstream out; - - if (nVerboseLevel > 1) - G4cout << "Creation of a file called 'QETables.dat' which contains the quantum efficiencies tables\n"; - - for (r = 0; r < m_nbTables; r++) { - m_table[r] = new G4double [m_nbCrystals]; - if (m_nbFiles > 0) { - size_t rmd = G4RandFlat::shootInt(m_nbFiles); - in.open(m_file[rmd].c_str()); - for (n = 0; n < m_nbCrystals; n++){ - G4double rmd2 = G4RandFlat::shoot(-0.025, 0.025); - in >> m_table[r][n]; - m_table[r][n]*=(rmd2+1); - } - in.close(); - } - else - for (n = 0; n < (m_nbCrystals); n++) { - if (m_uniqueQE) - m_table[r][n] = m_uniqueQE; - else - m_table[r][n] = 1; - } - if (nVerboseLevel > 1) - { - if (! out.is_open()) - out.open("QETables.dat"); - out << "#Table nb: " << r << Gateendl; - for (n = 0; n < (m_nbCrystals); n++) - out << m_table[r][n] << Gateendl; - } - } - if (out.is_open()) - out.close(); -} - -G4double GateQuantumEfficiency::GetMinQECoeff() { - m_minQECoef=1.; - for (G4int r = 0; r < m_nbTables; r++) - for (G4int n = 0; n < m_nbCrystals; n++) - m_minQECoef = (m_table[r][n] <= m_minQECoef) ? - m_table[r][n] : m_minQECoef; - - return m_minQECoef; -} - -void GateQuantumEfficiency::DescribeMyself(size_t indent) -{ - if (m_nbFiles > 0) { - G4cout << GateTools::Indent(indent) << "Variable quantum efficiency based on the file(s): \n"; - std::vector::iterator im; - for (im=m_file.begin(); im!=m_file.end(); im++) - G4cout << GateTools::Indent(indent+1) << *im << Gateendl; - } - else - G4cout << GateTools::Indent(indent) << "Fixed quantum efficiency equal to " << m_uniqueQE << Gateendl; -} diff --git a/source/digits_hits/src/GateQuantumEfficiencyMessenger.cc b/source/digits_hits/src/GateQuantumEfficiencyMessenger.cc deleted file mode 100644 index 8fbc9ab03..000000000 --- a/source/digits_hits/src/GateQuantumEfficiencyMessenger.cc +++ /dev/null @@ -1,58 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#include "GateQuantumEfficiencyMessenger.hh" - -#include "GateQuantumEfficiency.hh" - -#include "G4UIcmdWithAString.hh" -#include "G4UIcmdWithADouble.hh" - -GateQuantumEfficiencyMessenger::GateQuantumEfficiencyMessenger(GateQuantumEfficiency* itsQE) - : GatePulseProcessorMessenger(itsQE) -{ - G4String guidance; - G4String cmdName; - G4String cmdName2; - G4String cmdName3; - - cmdName = GetDirectoryName() + "chooseQEVolume"; - newVolCmd = new G4UIcmdWithAString(cmdName,this); - newVolCmd->SetGuidance("Choose a volume for quantum efficiency (e.g. crystal)"); - - cmdName2 = GetDirectoryName() + "useFileDataForQE"; - newFileCmd = new G4UIcmdWithAString(cmdName2,this); - newFileCmd->SetGuidance("Use data from a file to set your quantum efficiency inhomogeneity"); - - cmdName3 = GetDirectoryName() + "setUniqueQE"; - uniqueQECmd = new G4UIcmdWithADouble(cmdName3,this); - uniqueQECmd->SetGuidance("Set an unique quantum efficiency"); -} - - - -GateQuantumEfficiencyMessenger::~GateQuantumEfficiencyMessenger() -{ - delete newVolCmd; - delete newFileCmd; - delete uniqueQECmd; -} - - -void GateQuantumEfficiencyMessenger::SetNewValue(G4UIcommand* command, G4String newValue) -{ - if ( command==newVolCmd ) - GetQE()->CheckVolumeName(newValue); - else if ( command==newFileCmd ) - GetQE()->UseFile(newValue); - else if ( command==uniqueQECmd ) - GetQE()->SetUniqueQE(uniqueQECmd->GetNewDoubleValue(newValue)); - else - GatePulseProcessorMessenger::SetNewValue(command,newValue); -} diff --git a/source/digits_hits/src/GateSinglesDigitizerMessenger.cc b/source/digits_hits/src/GateSinglesDigitizerMessenger.cc index 421f6306c..3cfe8fdb4 100755 --- a/source/digits_hits/src/GateSinglesDigitizerMessenger.cc +++ b/source/digits_hits/src/GateSinglesDigitizerMessenger.cc @@ -42,6 +42,8 @@ See LICENSE.md for further details #include "GateOpticalAdder.hh" #include "GateNoise.hh" #include "GateDigitizerMerger.hh" +#include "GateIntrinsicResolution.hh" + #include "GateDoIModels.hh" /* @@ -112,7 +114,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 doIModels"; + static G4String theList = "readout adder energyFraming timeResolution energyResolution spatialResolution efficiency deadtime pileup adderCompton opticaladder noise merger intrinsicResolution doIModels"; return theList; } @@ -200,6 +202,11 @@ void GateSinglesDigitizerMessenger::DoInsertion(const G4String& childTypeName) newDM = new GateDigitizerMerger(m_digitizer, DMname); m_digitizer->AddNewModule(newDM); } + else if (childTypeName=="intrinsicResolution") + { + newDM = new GateIntrinsicResolution(m_digitizer, DMname); + m_digitizer->AddNewModule(newDM); + } else if (childTypeName=="doIModels") { newDM = new GateDoIModels(m_digitizer, DMname); diff --git a/source/digits_hits/src/GateTransferEfficiency.cc b/source/digits_hits/src/GateTransferEfficiency.cc deleted file mode 100644 index e4daf7dd4..000000000 --- a/source/digits_hits/src/GateTransferEfficiency.cc +++ /dev/null @@ -1,113 +0,0 @@ -/*---------------------- - 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 -----------------------*/ - - -#include "GateTransferEfficiency.hh" - -#include "GateTransferEfficiencyMessenger.hh" -#include "GateTools.hh" -#include "GateVolumeID.hh" -#include "G4VSolid.hh" -#include "G4Box.hh" - -#include "G4UnitsTable.hh" - -#include "GateObjectStore.hh" - - -// Static pointer to the GateTransferEfficiency singleton -GateTransferEfficiency* GateTransferEfficiency::theGateTransferEfficiency=0; - - - -/* This function allows to retrieve the current instance of the GateTransferEfficiency singleton - If the GateTransferEfficiency already exists, GetInstance only returns a pointer to this singleton. - If this singleton does not exist yet, GetInstance creates it by calling the private - GateTransferEfficiency constructor -*/ -GateTransferEfficiency* GateTransferEfficiency::GetInstance(GatePulseProcessorChain* itsChain, - const G4String& itsName) -{ - if (!theGateTransferEfficiency) - if (itsChain) - theGateTransferEfficiency = new GateTransferEfficiency(itsChain, itsName); - return theGateTransferEfficiency; -} - - -// Private constructor -GateTransferEfficiency::GateTransferEfficiency(GatePulseProcessorChain* itsChain, - const G4String& itsName) - : GateVPulseProcessor(itsChain, itsName) -{ - m_messenger = new GateTransferEfficiencyMessenger(this); -} - -// Public destructor -GateTransferEfficiency::~GateTransferEfficiency() -{ - delete m_messenger; -} - -G4int GateTransferEfficiency::ChooseVolume(G4String val) -{ - //Retrieve the inserter store to check if the volume name is valid - GateObjectStore* m_store = GateObjectStore::GetInstance(); - if (m_store->FindCreator(val)!=0) { - m_table[val]=1.; - return 1; - } - else { - G4cout << "Wrong Volume Name\n"; - return 0; - } -} - -void GateTransferEfficiency::ProcessOnePulse(const GatePulse* inputPulse,GatePulseList& outputPulseList) -{ - im=m_table.find(((inputPulse->GetVolumeID()).GetBottomCreator())->GetObjectName()); - GatePulse* outputPulse = new GatePulse(*inputPulse); - if(im != m_table.end()) - { - if(((*im).second < 0) | ((*im).second > 1)) { - G4cerr << Gateendl << "[GateLightYield::ProcessOnePulse]:\n" - << "Sorry, but the transfer efficiency (" << (*im).second << ") for " - << (*im).first << " is invalid\n"; - G4String msg = "It must be a number between 0 and 1 !!!\n" - "You must set the transfer efficiency:\n" - "\t/gate/digitizer/Singles/transferEfficiency/" + - (*im).first + "/setTECoef NUMBER\n" - "or disable the transfer efficiency module using:\n" - "\t/gate/digitizer/Singles/transferEfficiency/disable\n"; - G4Exception( "GateTransferEfficiency::ProcessOnePulse", "ProcessOnePulse", FatalException, msg ); - } - else - { - m_TECoef = (*im).second; - outputPulse->SetEnergy( m_TECoef * inputPulse->GetEnergy() ); - } - } - outputPulseList.push_back(outputPulse); -} - -G4double GateTransferEfficiency::GetTEMin() -{ - im=m_table.begin(); - m_TEMin = (*im).second; - for (im=m_table.begin(); im!=m_table.end(); im++) - m_TEMin = ((*im).second <= m_TEMin) ? - (*im).second : m_TEMin; - return m_TEMin; -} - -void GateTransferEfficiency::DescribeMyself(size_t indent) -{ - for (im=m_table.begin(); im!=m_table.end(); im++) - G4cout << GateTools::Indent(indent) << (*im).first << ":\n" - << GateTools::Indent(indent+1) << "Transfer Efficiency: " << (*im).second << Gateendl; -} diff --git a/source/digits_hits/src/GateTransferEfficiencyMessenger.cc b/source/digits_hits/src/GateTransferEfficiencyMessenger.cc deleted file mode 100644 index 48ac1666b..000000000 --- a/source/digits_hits/src/GateTransferEfficiencyMessenger.cc +++ /dev/null @@ -1,72 +0,0 @@ -/*---------------------- - 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 - ----------------------*/ - - -#include "GateTransferEfficiencyMessenger.hh" -#include "GateTransferEfficiency.hh" - -#include "G4UIcmdWithAString.hh" -#include "G4UIcmdWithADouble.hh" - -GateTransferEfficiencyMessenger::GateTransferEfficiencyMessenger(GateTransferEfficiency* itsTE) - : GatePulseProcessorMessenger(itsTE) -{ - G4String guidance; - G4String cmdName; - m_count=0; - - cmdName = GetDirectoryName() + "chooseNewVolume"; - newVolCmd = new G4UIcmdWithAString(cmdName,this); - newVolCmd->SetGuidance("Choose a volume for transfer efficiency"); -} - - -GateTransferEfficiencyMessenger::~GateTransferEfficiencyMessenger() -{ - delete newVolCmd; - for (G4int i=0;iChooseVolume(newValue) == 1) { - m_volDirectory.push_back(new G4UIdirectory( (GetDirectoryName() + newValue + "/").c_str() )); - m_volDirectory[m_count]->SetGuidance((G4String("Transfert efficiency for") + newValue).c_str()); - - m_name.push_back(newValue); - - cmdName2 = m_volDirectory[m_count]->GetCommandPath() + "setTECoef"; - coeffTECmd.push_back(new G4UIcmdWithADouble(cmdName2,this)); - coeffTECmd[m_count]->SetGuidance("Set the coefficient for transfer efficiency"); - - m_count++; - } - } - else - SetNewValue2(command,newValue); -} - -void GateTransferEfficiencyMessenger::SetNewValue2(G4UIcommand* command, G4String newValue) -{ - G4int test=0; - for (G4int i=0;iSetTECoeff(m_name[i], coeffTECmd[i]->GetNewDoubleValue(newValue)); - test=1; - } - } - if(test==0) - GatePulseProcessorMessenger::SetNewValue(command,newValue); -} From eb793ca3d6680d2e618fc6f2263a281def227b4e Mon Sep 17 00:00:00 2001 From: kochebina <42149373+kochebina@users.noreply.github.com> Date: Mon, 4 Dec 2023 16:50:58 +0100 Subject: [PATCH 2/2] Update digitizer_and_detector_modeling.rst --- docs/digitizer_and_detector_modeling.rst | 85 ++++++++---------------- 1 file changed, 26 insertions(+), 59 deletions(-) diff --git a/docs/digitizer_and_detector_modeling.rst b/docs/digitizer_and_detector_modeling.rst index afd6e0ce4..190346cd2 100644 --- a/docs/digitizer_and_detector_modeling.rst +++ b/docs/digitizer_and_detector_modeling.rst @@ -809,22 +809,11 @@ Thus, the output of *Singles_crystal2* should be used in the following analysis /gate/digitizerMgr/CoincidenceSorter/Coincidences/setInputCollection Singles_crystal2 - - - - - - - -Modules to be addapted (NOT YET INCLUDED IN GATE NEW DIGITIZER) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Blurring: Intrinsic resolution blurring with crystals of different compositions +Intrinsic resolution ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +*(Previously blurring with crystals of different compositions, now includes GateLightYield, GateTransferEfficiency, and GateQuantumEfficiency)* - - -This blurring pulse-processor simulates a local Gaussian blurring of the energy spectrum (different for different crystals) based on the following model: +This resolution simulates a Gaussian blurring of the energy spectrum based on the following model: :math:`R=\sqrt{{2.35}^2\cdot\frac{1+\bar{\nu}}{{\bar{N}}_{ph}\cdot \bar{\epsilon} \cdot \bar{p}} +{R_i}^2}` @@ -834,7 +823,11 @@ where :math:`N_{ph}=LY\cdot E` and :math:`LY`, :math:`\bar p` and :math:`\bar \e If the intrinsic resolutions, :math:`( R_i )`, of the individual crystals are not defined, then they are set to one. -To use this *digitizer* module properly, several modules must be set first. These digitizer modules are **GateLightYield**, **GateTransferEfficiency**, and **GateQuantumEfficiency**. The light yield pulse-processor simulates the crystal light yield. Each crystal must be given the correct light yield. This module converts the *pulse* energy into the number of scintillation photons emitted, :math:`N_{ph}`. The transfer efficiency pulse-processor simulates the transfer efficiencies of the light photons in each crystal. This digitizer reduces the "pulse" energy (by reducing the number of scintillation photons) by a transfer efficiency coefficient which must be a number between 0 and 1. The quantum efficiency pulse-processor simulates the quantum efficiency for each channel of a photo-detector, which can be a Photo Multiplier Tube (PMT) or an Avalanche Photo Diode (APD). +LightYield: It converts the *digi* energy into the number of scintillation photons emitted, :math:`N_{ph}`. + +TransferEfficiency: the transfer efficiencies of the light photons in each crystal. It reduces the "pulse" energy (by reducing the number of scintillation photons) by a transfer efficiency coefficient which must be a number between 0 and 1. + +QuantumEfficiency: simulates the quantum efficiency for each channel of a photo-detector, which can be a Photo Multiplier Tube (PMT) or an Avalanche Photo Diode (APD). The command lines are illustrated using an example of a phoswich module made of two layers of different crystals. One crystal has a light yield of 27000 photons per MeV (LSO crystal), a transfer efficiency of 28%, and an intrinsic resolution of 8.8%. The other crystal has a light yield of 8500 photons per MeV (LuYAP crystal), a transfer efficiency of 24% and an intrinsic resolution of 5.3% @@ -858,33 +851,21 @@ In the case of a *cylindricalPET* system, the construction of the crystal geomet # In this example the phoswich module is represented by the *crystal* volume and is made of two different material layers. # To apply the resolution blurring of equation , the parameters discussed above must be defined for each layer #(i.e. Light Yield, Transfer, Intrinsic Resolution, and the Quantum Efficiency). - # DEFINE TRANSFER EFFICIENCY FOR EACH LAYER - /gate/digitizer/Singles/insert transferEfficiency - /gate/digitizer/Singles/transferEfficiency/chooseNewVolume LSOlayer - /gate/digitizer/Singles/transferEfficiency/LSOlayer/setTECoef 0.28 - /gate/digitizer/Singles/transferEfficiency/chooseNewVolume LuYAPlayer - /gate/digitizer/Singles/transferEfficiency/LuYAPlayer/setTECoef 0.24 - - # DEFINE LIGHT YIELD FOR EACH LAYER - /gate/digitizer/Singles/insert lightYield - /gate/digitizer/Singles/lightYield/chooseNewVolume LSOlayer - /gate/digitizer/Singles/lightYield/LSOlayer/setLightOutput 27000 - /gate/digitizer/Singles/lightYield/chooseNewVolume LuYAPlayer - /gate/digitizer/Singles/lightYield/LuYAPlayer/setLightOutput 8500 - - # DEFINE INTRINSIC RESOLUTION FOR EACH LAYER - /gate/digitizer/Singles/insert intrinsicResolutionBlurring - /gate/digitizer/Singles/intrinsicResolutionBlurring/ chooseNewVolume LSOlayer - /gate/digitizer/Singles/intrinsicResolutionBlurring/ LSOlayer/setIntrinsicResolution 0.088 - /gate/digitizer/Singles/intrinsicResolutionBlurring/ LSOlayer/setEnergyOfReference 511 keV - /gate/digitizer/Singles/intrinsicResolutionBlurring/ chooseNewVolume LuYAPlayer - /gate/digitizer/Singles/intrinsicResolutionBlurring/ LuYAPlayer/setIntrinsicResolution 0.053 - /gate/digitizer/Singles/intrinsicResolutionBlurring/ LuYAPlayer/setEnergyOfReference 511 keV + # DEFINE INTRINSIC RESOLUTION + /gate/digitizerMgr/LSOlayer/SinglesDigitizer/Singles/insert intrinsicResolution + /gate/digitizerMgr/LSOlayer/SinglesDigitizer/Singles/intrinsicResolution/setIntrinsicResolution 0.088 + /gate/digitizerMgr/LSOlayer/SinglesDigitizer/Singles/intrinsicResolution/setEnergyOfReference 511 keV + /gate/digitizerMgr/LSOlayer/SinglesDigitizer/Singles/intrinsicResolution/setTECoef 0.28 + /gate/digitizerMgr/LSOlayer/SinglesDigitizer/Singles/intrinsicResolution/setLightOutput 27000 + /gate/digitizerMgr/LSOlayer/SinglesDigitizer/Singles/intrinsicResolution/setUniqueQE 0.1 + + /gate/digitizerMgr/LuYAPlayer/SinglesDigitizer/Singles/insert intrinsicResolution + /gate/digitizerMgr/LuYAPlayer/SinglesDigitizer/Singles/intrinsicResolution/setIntrinsicResolution 0.088 + /gate/digitizerMgr/LuYAPlayer/SinglesDigitizer/Singles/intrinsicResolution/setEnergyOfReference 511 keV + /gate/digitizerMgr/LuYAPlayer/SinglesDigitizer/Singles/intrinsicResolution/setTECoef 0.24 + /gate/digitizerMgr/LuYAPlayer/SinglesDigitizer/Singles/intrinsicResolution/setLightOutput 8500 + /gate/digitizerMgr/LuYAPlayer/SinglesDigitizer/Singles/intrinsicResolution/setUniqueQE 0.1 - # DEFINE QUANTUM EFFICIENCY OF THE PHOTODETECTOR - /gate/digitizer/Singles/insert quantumEfficiency - /gate/digitizer/Singles/quantumEfficiency/chooseQEVolume crystal - /gate/digitizer/Singles/quantumEfficiency/setUniqueQE 0.1 Note: A complete example of a phoswich module can be in the PET benchmark. @@ -895,29 +876,15 @@ With the previous commands, the same quantum efficiency will be applied to all t To set multiple quantum efficiencies using files (*fileName1*, *fileName2*, ... for each of the different modules), the following commands can be used:: /gate/digitizer/Singles/insert quantumEfficiency - /gate/digitizer/Singles/quantumEfficiency/chooseQEVolume crystal - /gate/digitizer/Singles/quantumEfficiency/useFileDataForQE fileName1 - /gate/digitizer/Singles/quantumEfficiency/useFileDataForQE fileName2 + /gate/digitizerMgr/crystal/SinglesDigitizer/Singles/intrinsicResolution/useFileDataForQE fileName1 + /gate/digitizerMgr/crystal/SinglesDigitizer/Singles/intrinsicResolution/useFileDataForQE fileName2 If the *crystal* volume is a daughter of a *module* volume which is an array of 8 x 8 crystals, the file *fileName1* will contain 64 values of quantum efficiency. If several files are given (in this example two files), the program will choose randomly between theses files for each *module*. -**Important note** - -After the introduction of the lightYield (LY), transferEfficiency :math:`(\bar{p})` and quantumEfficiency} :math:`(\bar{\epsilon})` modules, the energy variable of a *pulse* is not in energy unit (MeV) but in number of photoelectrons :math:`N_{pe}`. - -:math:`N_{phe}={N}_{ph} \cdot \bar{\epsilon} \cdot \bar{p} = LY \cdot E \cdot \bar{\epsilon} \cdot \bar{p}` - -In order to correctly apply a threshold on a phoswhich module, the threshold should be based on this number and not on the real energy. In this situation, to apply a threshold at this step of the digitizer chain, the threshold should be applied as explained in :ref:`thresholder_upholder-label`. In this case, the GATE program knows that these modules have been used, and will apply threshold based upon the number :math:`N_{pe}` rather than energy. The threshold set with this sigmoidal function in energy unit by the user is translated into number :math:`N_{pe}` with the lower light yield of the phoswish module. To retrieve the energy it is necessary to apply a calibration module. - -Calibration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The Calibration module of the pulse-processor models a calibration between :math:`N_{phe}` and :math:`Energy`. This is useful when using the class(es) GateLightYield, GateTransferEfficiency, and GateQuantumEfficiency. In addition, a user specified calibration factor can be used. To set a calibration factor on the energy, use the following commands:: +Modules to be addapted (NOT YET INCLUDED IN GATE NEW DIGITIZER) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /gate/digitizer/Singles/insert calibration - /gate/digitizer/Singles/setCalibration VALUE -If the calibration digitizer is used without any value, it will correct the energy as a function of values used in GateLightYield, GateTransferEfficiency, and GateQuantumEfficiency. Crosstalk ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^