Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//==========================================================================
// AIDA Detector description implementation
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author : M.Frank
//
//==========================================================================
//
// Please note:
//
// These shower parametrizations is a generalized form of the Geant4 example:
// <geant4-source-dir>/examples/extended/parameterisations/Par02
//
//==========================================================================
// Framework include files
#include <DDG4/Geant4FastSimShowerModel.inl.h>
#include <DDG4/Geant4FastSimSpot.h>
#include <DDG4/Geant4Random.h>
// Geant4 include files
#include "G4SystemOfUnits.hh"
#include "G4FastStep.hh"
/// Namespace for the AIDA detector description toolkit
namespace dd4hep {
/// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
namespace sim {
///===================================================================================================
///
/// Par02 electromagnetic shower model (e+, e-)
///
///===================================================================================================
/// Configuration structure for the fast simulation shower model Geant4FSShowerModel<par02_em_model>
class calo_smear_model {
public:
G4FastSimHitMaker hitMaker { };
double StocasticEnergyResolution { -1e0 };
double ConstantEnergyResolution { -1e0 };
double NoiseEnergyResolution { -1e0 };
double resolution(double momentum) const {
double res = -1e0;
double mom = momentum/CLHEP::GeV;
if ( this->StocasticEnergyResolution > 0 &&
this->ConstantEnergyResolution > 0 &&
this->NoiseEnergyResolution > 0 ) {
res = std::sqrt(std::pow( this->StocasticEnergyResolution / std::sqrt( mom ), 2 ) + // stochastic
std::pow( this->ConstantEnergyResolution, 2 ) + // constant
std::pow( this->NoiseEnergyResolution / mom, 2 ) ); // noise
}
else if ( this->StocasticEnergyResolution > 0 &&
this->ConstantEnergyResolution > 0 ) {
res = std::sqrt(std::pow( this->StocasticEnergyResolution / std::sqrt( mom ), 2 ) + // stochastic
std::pow( this->ConstantEnergyResolution, 2 ) ); // constant
}
else if ( this->StocasticEnergyResolution > 0 ) {
res = this->StocasticEnergyResolution / std::sqrt( mom ); // stochastic
}
else if ( this->ConstantEnergyResolution > 0 ) {
res = this->ConstantEnergyResolution; // constant
}
return res;
}
double smearEnergy(double mom) const {
double resolution = this->resolution(mom);
double smeared = mom;
if ( resolution > 0e0 ) {
for( smeared = -1e0; smeared < 0e0; ) { // Ensure that the resulting value is not negative
smeared = mom * Geant4Random::instance()->gauss(1e0, resolution);
}
}
return smeared;
}
};
/// Declare optional properties from embedded structure
template <>
void Geant4FSShowerModel<calo_smear_model>::initialize() {
declareProperty("StocasticResolution", locals.StocasticEnergyResolution );
declareProperty("ConstantResolution", locals.ConstantEnergyResolution );
declareProperty("NoiseResolution", locals.NoiseEnergyResolution );
}
/// Sensitive detector construction callback. Called at "ConstructSDandField()"
template <>
void Geant4FSShowerModel<calo_smear_model>::constructSensitives(Geant4DetectorConstructionContext* ctxt) {
this->Geant4FastSimShowerModel::constructSensitives(ctxt);
}
/// User callback to model the particle/energy shower
template <>
void Geant4FSShowerModel<calo_smear_model>::modelShower(const G4FastTrack& track, G4FastStep& step) {
auto* primary = track.GetPrimaryTrack();
// Kill the parameterised particle:
this->killParticle(step, primary->GetKineticEnergy(), 0e0);
//-----------------------------------------------------
G4FastHit hit;
Geant4FastSimSpot spot(&hit, &track);
G4ThreeVector position = spot.trackPosition();
double deposit = spot.kineticEnergy();
hit.SetPosition(spot.trackPosition());
// Consider only primary tracks and smear according to the parametrized resolution
// ELSE: simply set the value of the (initial) energy of the particle is deposited in the step
if ( !spot.primary->GetParentID() ) {
deposit = locals.smearEnergy(deposit);
}
hit.SetEnergy(deposit);
step.ProposeTotalEnergyDeposited(deposit);
this->locals.hitMaker.make(hit, track);
}
typedef Geant4FSShowerModel<calo_smear_model> Geant4CaloSmearShowerModel;
}
}
#include <DDG4/Factories.h>
DECLARE_GEANT4ACTION_NS(dd4hep::sim,Geant4CaloSmearShowerModel)