aboutsummaryrefslogtreecommitdiffstats
path: root/src/G4TankIceSD.cxx
blob: 29748372bdae62d82801c1a5929f916e6fe6c8ba (plain)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "G4TankIceSD.h"
#include "G4BeamTestTank.h"

#include <G4Step.hh>
#include <G4HCofThisEvent.hh>
#include <G4TouchableHistory.hh>
#include <G4ios.hh>
#include <iostream>
#include <ios>
#include <fstream>

#include <G4VProcess.hh>
#include <G4OpticalPhoton.hh>
#include "G4Poisson.hh"

/* #include <icetray/I3Units.h> */

#include "G4Version.hh"

#if G4VERSION_NUMBER >= 950
// The G4MaterialPropertyVector is gone since 4.9.5.
// It has been typedef'd to a G4UnorderedPhysicsVector
// with a different interface. Try to support both
// versions with an ifdef.
#define MATERIAL_PROPERTY_VECTOR_IS_PHYSICS_VECTOR
#endif


G4TankIceSD::G4TankIceSD(G4String name/* , const std::map<OMKey, G4ThreeVector>& domPositions */)
  : G4VSensitiveDetector(name)/* , domPositions_(domPositions) */
{}


G4TankIceSD::~G4TankIceSD() {}


void G4TankIceSD::Initialize(G4HCofThisEvent* HCE)
{
  // std::map<OMKey, G4ThreeVector>::const_iterator om_iter;
  // for(om_iter=domPositions_.begin(); om_iter!=domPositions_.end(); ++om_iter)
  // {
  sumEdep_ = 0;
  cogTime_ = 0;
  cherenkovCounter_ = 0;
  cherenkovCounterWeight_ = 0;
  // }
}


G4bool G4TankIceSD::ProcessHits(G4Step* aStep, G4TouchableHistory*)
{
  // Get energy deposit/time --> CHECK WHAT THESE QUANTITIES ACTUALLY MEAN !!!!!!!!!!!!!!!!!!!!!!!!
  G4double edep = aStep->GetTotalEnergyDeposit();
  G4double time = aStep->GetPreStepPoint()->GetGlobalTime();
  G4double cherenkovNumber = GetCerenkovNumber(aStep);

  if(edep<=0 && cherenkovNumber<=0) return false;

  // Get Position relative to ice center
  G4ThreeVector preStepPoint = aStep->GetPreStepPoint()->GetPosition();
  G4ThreeVector postStepPoint = aStep->GetPostStepPoint()->GetPosition();
  G4TouchableHandle theTouchable = aStep->GetPreStepPoint()->GetTouchableHandle();
  G4ThreeVector worldPosition = (preStepPoint + postStepPoint) / 2.0;
  G4ThreeVector localPosition = theTouchable->GetHistory()->
                                GetTopTransform().TransformPoint(worldPosition);

  // std::map<OMKey, G4ThreeVector>::const_iterator om_iter;
  // for(om_iter=domPositions_.begin(); om_iter!=domPositions_.end(); ++om_iter)
  // {
  G4double radius = sqrt(pow(domPositions_.x() - localPosition.x(), 2) +
                         pow(domPositions_.y() - localPosition.y(), 2));
  G4double height = (domPositions_.z() - localPosition.z());

  sumEdep_ += edep;
  cogTime_ += edep*time;
  cherenkovCounterWeight_ += GetProbability(radius, height) * cherenkovNumber;
  cherenkovCounter_ += cherenkovNumber;
  // }
  return true;
}


void G4TankIceSD::EndOfEvent(G4HCofThisEvent*)
{
  // std::map<OMKey, G4ThreeVector>::const_iterator om_iter;
  // for(om_iter=domPositions_.begin(); om_iter!=domPositions_.end(); ++om_iter)
  // {
  if(sumEdep_>0)
  {
    cogTime_ /= sumEdep_;
  }
  // }
}


G4double G4TankIceSD::GetCerenkovNumber(G4Step* aStep)
{
  // same function as in "source/processes/electromagnetic/xrays/src/G4Cerenkov.cc" but without
  // cerenkov angle and only for an energy independent refraction index
  G4Track* aTrack = aStep->GetTrack();
  const G4DynamicParticle* aParticle = aTrack->GetDynamicParticle();
  const G4Material* aMaterial = aTrack->GetMaterial();

  G4StepPoint* pPreStepPoint  = aStep->GetPreStepPoint();
  G4StepPoint* pPostStepPoint = aStep->GetPostStepPoint();

  G4MaterialPropertiesTable* aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable();
  if (!aMaterialPropertiesTable) return 0.0;

  G4MaterialPropertyVector* Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
  if (!Rindex) return 0.0;

  const G4double Rfact = 369.81 / (CLHEP::eV * CLHEP::cm); // TODO(shivesh): check this
  const G4double charge = aParticle->GetDefinition()->GetPDGCharge();
  const G4double beta = (pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta()) / 2.;
  if (beta <= 0.0) return 0.0;
  G4double BetaInverse = 1. / beta;

  // Min and Max photon energies
#ifdef MATERIAL_PROPERTY_VECTOR_IS_PHYSICS_VECTOR
  G4double Pmin = Rindex->GetMinLowEdgeEnergy();
  G4double Pmax = Rindex->GetMaxLowEdgeEnergy();
#else
  G4double Pmin = Rindex->GetMinPhotonEnergy();
  G4double Pmax = Rindex->GetMaxPhotonEnergy();
#endif

  // Min and Max Refraction Indices
#ifdef MATERIAL_PROPERTY_VECTOR_IS_PHYSICS_VECTOR
  G4double nMin = Rindex->GetMinValue();
  G4double nMax = Rindex->GetMaxValue();
#else
  G4double nMin = Rindex->GetMinProperty();
  G4double nMax = Rindex->GetMaxProperty();
#endif
  if (nMin!=nMax)
  {
    /* log_error("Support for energy dependent refraction index not yet implemented!"); */
    G4cout << "Support for energy dependent refraction index not yet implemented!";
    return 0.0;
  }

  // If n(Pmax) < 1/Beta -- no photons generated
  if (nMax < BetaInverse) return 0.0;

  G4double MeanNumberOfPhotons = Rfact * charge/CLHEP::eplus * charge/CLHEP::eplus * (Pmax - Pmin) *
                                 (1. - BetaInverse * BetaInverse / nMin / nMin);

  G4double step_length = aStep->GetStepLength();

  return MeanNumberOfPhotons * step_length;
}


// TODO(shivesh): what is this
G4double G4TankIceSD::GetProbability(G4double radius, G4double height)
{
  height = 0.90 - height / CLHEP::m;
  radius = radius / CLHEP::m;
  G4double p0 = 0.0340 +  0.0120 * height;
  G4double p1 = 0.0400 + 0.000622 * exp(-1.13 + 8.03 * height);
  G4double p2 = 0.917 + 2.34 * exp(-1.82 + 3.12 * height);
  G4double p3 = -0.00325 - 0.00199 * height - 0.0121 * height*height;

  return (p0 + p3 * radius) + (p1 - p0) * exp(-p2*p2 * radius*radius);
}