File indexing completed on 2025-01-30 09:17:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <DDG4/Geant4FastSimShowerModel.inl.h>
0023 #include <DDG4/Geant4FastSimSpot.h>
0024 #include <DDG4/Geant4Random.h>
0025
0026
0027 #include <G4SystemOfUnits.hh>
0028 #include <G4FastStep.hh>
0029
0030
0031 namespace dd4hep {
0032
0033
0034 namespace sim {
0035
0036
0037
0038
0039
0040
0041
0042
0043 class calo_smear_model {
0044 public:
0045 G4FastSimHitMaker hitMaker { };
0046 double StocasticEnergyResolution { -1e0 };
0047 double ConstantEnergyResolution { -1e0 };
0048 double NoiseEnergyResolution { -1e0 };
0049
0050 double resolution(double momentum) const {
0051 double res = -1e0;
0052 double mom = momentum/CLHEP::GeV;
0053 if ( this->StocasticEnergyResolution > 0 &&
0054 this->ConstantEnergyResolution > 0 &&
0055 this->NoiseEnergyResolution > 0 ) {
0056 res = std::sqrt(std::pow( this->StocasticEnergyResolution / std::sqrt( mom ), 2 ) +
0057 std::pow( this->ConstantEnergyResolution, 2 ) +
0058 std::pow( this->NoiseEnergyResolution / mom, 2 ) );
0059 }
0060 else if ( this->StocasticEnergyResolution > 0 &&
0061 this->ConstantEnergyResolution > 0 ) {
0062 res = std::sqrt(std::pow( this->StocasticEnergyResolution / std::sqrt( mom ), 2 ) +
0063 std::pow( this->ConstantEnergyResolution, 2 ) );
0064 }
0065 else if ( this->StocasticEnergyResolution > 0 ) {
0066 res = this->StocasticEnergyResolution / std::sqrt( mom );
0067 }
0068 else if ( this->ConstantEnergyResolution > 0 ) {
0069 res = this->ConstantEnergyResolution;
0070 }
0071 return res;
0072 }
0073
0074 double smearEnergy(double mom) const {
0075 double resolution = this->resolution(mom);
0076 double smeared = mom;
0077 if ( resolution > 0e0 ) {
0078 for( smeared = -1e0; smeared < 0e0; ) {
0079 smeared = mom * Geant4Random::instance()->gauss(1e0, resolution);
0080 }
0081 }
0082 return smeared;
0083 }
0084 };
0085
0086
0087 template <>
0088 void Geant4FSShowerModel<calo_smear_model>::initialize() {
0089 declareProperty("StocasticResolution", locals.StocasticEnergyResolution );
0090 declareProperty("ConstantResolution", locals.ConstantEnergyResolution );
0091 declareProperty("NoiseResolution", locals.NoiseEnergyResolution );
0092 }
0093
0094
0095 template <>
0096 void Geant4FSShowerModel<calo_smear_model>::constructSensitives(Geant4DetectorConstructionContext* ctxt) {
0097 this->Geant4FastSimShowerModel::constructSensitives(ctxt);
0098 }
0099
0100
0101 template <>
0102 void Geant4FSShowerModel<calo_smear_model>::modelShower(const G4FastTrack& track, G4FastStep& step) {
0103 auto* primary = track.GetPrimaryTrack();
0104
0105 this->killParticle(step, primary->GetKineticEnergy(), 0e0);
0106
0107 G4FastHit hit;
0108 Geant4FastSimSpot spot(&hit, &track);
0109 G4ThreeVector position = spot.trackPosition();
0110 double deposit = spot.kineticEnergy();
0111
0112 hit.SetPosition(spot.trackPosition());
0113
0114
0115 if ( !spot.primary->GetParentID() ) {
0116 deposit = locals.smearEnergy(deposit);
0117 }
0118 hit.SetEnergy(deposit);
0119 step.ProposeTotalEnergyDeposited(deposit);
0120 this->locals.hitMaker.make(hit, track);
0121 }
0122
0123 typedef Geant4FSShowerModel<calo_smear_model> Geant4CaloSmearShowerModel;
0124 }
0125 }
0126
0127 #include <DDG4/Factories.h>
0128 DECLARE_GEANT4ACTION_NS(dd4hep::sim,Geant4CaloSmearShowerModel)
0129