GEMC  1.8
Geant4 Monte-Carlo Framework
HTCC_hitprocess.cc
Go to the documentation of this file.
1 // %%%%%%%%%%
2 // G4 headers
3 // %%%%%%%%%%
4 #include "G4UnitsTable.hh"
5 #include "G4MaterialPropertyVector.hh"
6 #include "Randomize.hh"
7 
8 // %%%%%%%%%%%%%
9 // gemc headers
10 // %%%%%%%%%%%%%
11 #include "HTCC_hitprocess.h"
12 #include "detector.h"
13 #include <set>
14 
16 {
17  string hd_msg = Opt.args["LOG_MSG"].args + " HTCC Hit Process " ;
18  double HIT_VERBOSITY = Opt.args["HIT_VERBOSITY"].arg;
19  PH_output out;
20  out.identity = aHit->GetId();
21  HCname = "HTCC Hit Process";
22 
23  // if the particle is not an opticalphoton?
24  if(aHit->GetPID() != 0) return out;
25 
26  // Since the HTCC hit involves a PMT which detects photons with a certain quantum efficiency (QE)
27  // we want to implement QE here in a flexible way:
28  // That means we want to find out if the material of the photocathode has been defined,
29  // and if so, find out if it has a material properties table which defines an efficiency.
30  // if we find both of these properties, then we accept this event with probability QE:
31 
32  // %%%%%%%%%%%%%%%%%%%
33  // Raw hit information
34  // %%%%%%%%%%%%%%%%%%%
35  int nsteps = aHit->GetPos().size();
36 
37 
38 
39  vector<int> tids = aHit->GetTIds(); //track ID at EACH STEP!
40  vector<int> pids = aHit->GetPIDs(); //particle ID at EACH STEP!
41  set<int> TIDS; //an array containing all UNIQUE tracks in this hit!
42  vector<double> photon_energies;
43 
44  // average global, local positions of the hit
45  double x, y, z;
46  double lx, ly, lz;
47  x = y = z = lx = ly = lz = 0;
48  vector<G4ThreeVector> pos = aHit->GetPos();
49  vector<G4ThreeVector> Lpos = aHit->GetLPos();
50 
51  for(int s=0; s<nsteps; s++)
52  {
53  if(pids[s] == 0) { //the particle in the hit at this step is an optical photon
54  pair< set<int> ::iterator, bool> newtrack = TIDS.insert(tids[s]); //insert this step into the set of track ids (set can only have unique values).
55  if( newtrack.second ) photon_energies.push_back( (aHit->GetEs())[s] ); //if we found a new track, then add the initial photon energy of this track to the list of photon energies, for when we calculate quantum efficiency later!
56  }
57 
58  x = x + pos[s].x();
59  y = y + pos[s].y();
60  z = z + pos[s].z();
61  lx = lx + Lpos[s].x();
62  ly = ly + Lpos[s].y();
63  lz = lz + Lpos[s].z();
64  }
65 
66  x = x / nsteps;
67  y = y / nsteps;
68  z = z / nsteps;
69  lx = lx / nsteps;
70  ly = ly / nsteps;
71  lz = lz / nsteps;
72 
73 
74 
75 
76  // average time
77  double time = 0;
78  vector<G4double> times = aHit->GetTime();
79  for(int s=0; s<nsteps; s++) time = time + times[s]/nsteps;
80 
81  // Energy of the track
82  double Ene = aHit->GetE();
83 
84  out.raws.push_back(x);
85  out.raws.push_back(y);
86  out.raws.push_back(z);
87  out.raws.push_back(lx);
88  out.raws.push_back(ly);
89  out.raws.push_back(lz);
90  out.raws.push_back(time);
91  out.raws.push_back(aHit->GetVert().getX());
92  out.raws.push_back(aHit->GetVert().getY());
93  out.raws.push_back(aHit->GetVert().getZ());
94  out.raws.push_back(Ene);
95  out.raws.push_back((double) aHit->GetmPID());
96  out.raws.push_back(aHit->GetmVert().getX());
97  out.raws.push_back(aHit->GetmVert().getY());
98  out.raws.push_back(aHit->GetmVert().getZ());
99 
100 
101  // %%%%%%%%%%%%
102  // Digitization
103  // %%%%%%%%%%%%
104 
105  //int pmt = out.identity[0].id;
106  //we no longer use pmt. Now we use sector, ring, half:
107 
108  int idsector=-1, idring=-1, idhalf=-1;
109  if( out.identity.size() >= 3 ){
110  for(unsigned int id=0; id<out.identity.size(); id++){
111  if( TrimSpaces(out.identity[id].name) == "sector" ) idsector = id;
112  if( TrimSpaces(out.identity[id].name) == "ring" ) idring = id;
113  if( TrimSpaces(out.identity[id].name) == "half" ) idhalf = id;
114  }
115  } else return out; //no valid ID
116 
117 
118  // if identifiers for theta and phi indices have been defined, use them.
119  // otherwise, calculate itheta and iphi from the (mandatory) pmt index
120  // assuming the default configuration:
121  int isector=-1, iring=-1, ihalf=-1;
122 
123  if( idsector >= 0 && idring >= 0 && idhalf >= 0 ){
124  isector = out.identity[idsector].id;
125  iring = out.identity[idring].id;
126  ihalf = out.identity[idhalf].id;
127  } else return out; //no valid ID
128 
129  //here is the fun part: figure out the number of photons we detect based on the quantum efficiency of the photocathode material, if defined:
130 
131  int ndetected = 0;
132 
133  // If the detector corresponding to this hit has a material properties table with "Efficiency" defined:
134  G4MaterialPropertiesTable* MPT = aHit->GetDetector().GetLogical()->GetMaterial()->GetMaterialPropertiesTable();
135  G4MaterialPropertyVector* efficiency;
136 
137  bool gotefficiency = false;
138  if( MPT != NULL ){
139  efficiency = (G4MaterialPropertyVector*) MPT->GetProperty("EFFICIENCY");
140  if( efficiency != NULL ) gotefficiency = true;
141  }
142 
143  for( unsigned int iphoton = 0; iphoton<TIDS.size(); iphoton++ ){ //loop over all unique photons contributing to the hit:
144  if( gotefficiency ){ //If the material of this detector has a material properties table with "EFFICIENCY" defined, then "detect" this photon with probability = efficiency
145  bool outofrange = false;
146  if( G4UniformRand() <= efficiency->GetValue( photon_energies[iphoton], outofrange ) )
147  ndetected++;
148 
149  if( HIT_VERBOSITY > 4 ){
150  cout << "Found efficiency definition for material " << aHit->GetDetector().GetLogical()->GetMaterial()->GetName()
151  << ": (Ephoton, efficiency)=(" << photon_energies[iphoton] << ", "
152  << ( (G4MaterialPropertyVector*) efficiency )->GetValue( photon_energies[iphoton], outofrange )
153  << ")" << endl;
154  }
155  } else { //No efficiency definition, "detect" all photons
156  ndetected++;
157  }
158  }
159 
160  if(HIT_VERBOSITY>4)
161  cout << hd_msg << " (sector, ring, half)=(" << isector << ", " << iring << ", " << ihalf << ")"
162  << " x=" << x/cm << " y=" << y/cm << " z=" << z/cm << endl;
163 
164  out.dgtz.push_back(isector);
165  out.dgtz.push_back(iring);
166  out.dgtz.push_back(ihalf);
167  //out.dgtz.push_back(TIDS.size());
168  out.dgtz.push_back( ndetected );
169 
170  return out;
171 }
172 
173 
174 vector<identifier> HTCC_HitProcess :: ProcessID(vector<identifier> id, G4Step *step, detector Detector, gemc_opts Opt)
175 {
176  id[id.size()-1].id_sharing = 1;
177  return id;
178 }
179 
180 
181 
182 
183 
184 
G4LogicalVolume * GetLogical()
Returns Logical Volume pointer.
Definition: detector.h:93
PH_output ProcessHit(MHit *, gemc_opts)
Method to process the hit.
G4ThreeVector GetVert()
Definition: MHit.h:72
vector< double > raws
Raw information.
Definition: MPHBaseClass.h:26
int GetPID()
Definition: MHit.h:107
int GetmPID()
Definition: MHit.h:122
vector< identifier > GetId()
Definition: MHit.h:96
string HCname
Hit Collection name.
Definition: MPHBaseClass.h:41
G4ThreeVector GetmVert()
Definition: MHit.h:127
vector< identifier > identity
Identifier.
Definition: MPHBaseClass.h:28
vector< G4ThreeVector > GetLPos()
Definition: MHit.h:69
double GetE()
Definition: MHit.h:89
vector< G4ThreeVector > GetPos()
Definition: MHit.h:65
Definition: MHit.h:29
vector< double > GetEs()
Definition: MHit.h:90
vector< double > GetTime()
Definition: MHit.h:82
map< string, opts > args
Options map.
Definition: usage.h:68
vector< int > GetTIds()
Definition: MHit.h:94
vector< int > GetPIDs()
Definition: MHit.h:108
string TrimSpaces(string in)
Removes leading and trailing spaces.
vector< identifier > ProcessID(vector< identifier >, G4Step *, detector, gemc_opts)
Method to calculate new identifier.
detector GetDetector()
Definition: MHit.h:101
vector< int > dgtz
Digitized information.
Definition: MPHBaseClass.h:27