GEMC  2.3
Geant4 Monte-Carlo Framework
htcc_hitprocess.cc
Go to the documentation of this file.
1 // G4 headers
2 #include "G4MaterialPropertyVector.hh"
3 #include "Randomize.hh"
4 
5 // gemc headers
6 #include "htcc_hitprocess.h"
7 #include "detector.h"
8 #include <set>
9 
10 // CLHEP units
11 #include "CLHEP/Units/PhysicalConstants.h"
12 using namespace CLHEP;
13 
14 map<string, double> htcc_HitProcess :: integrateDgt(MHit* aHit, int hitn)
15 {
16  map<string, double> dgtz;
17 
18  // we want to crash if identity doesn't have size 3
19  vector<identifier> identity = aHit->GetId();
20  int idsector = identity[0].id;
21  int idring = identity[1].id;
22  int idhalf = identity[2].id;
23  int thisPid = aHit->GetPID();
24 
25  trueInfos tInfos(aHit);
26 
27  // if anything else than a photon hits the PMT
28  // the nphe is the particle id
29  // and identifiers are negative
30  // this should be changed, what if we still have a photon later?
31  dgtz["sector"] = -idsector;
32  dgtz["ring"] = -idring;
33  dgtz["half"] = -idhalf;
34  dgtz["nphe"] = thisPid;
35  dgtz["time"] = tInfos.time;
36  dgtz["hitn"] = hitn;
37 
38 
39  // if the particle is not an opticalphoton return bank filled with negative identifiers
40  if(thisPid != 0)
41  return dgtz;
42 
43  // Since the HTCC hit involves a PMT which detects photons with a certain quantum efficiency (QE)
44  // we want to implement QE here in a flexible way:
45 
46  // That means we want to find out if the material of the photocathode has been defined,
47  // and if so, find out if it has a material properties table which defines an efficiency.
48  // if we find both of these properties, then we accept this event with probability QE:
49 
50  vector<int> tids = aHit->GetTIds(); // track ID at EACH STEP
51  vector<int> pids = aHit->GetPIDs(); // particle ID at EACH STEP
52  set<int> TIDS; // an array containing all UNIQUE tracks in this hit
53  vector<double> photon_energies;
54 
55  vector<double> Energies = aHit->GetEs();
56 
57 
58  // this needs to be optimized
59  // uaing the return value of insert is unnecessary
60  for(unsigned int s=0; s<tids.size(); s++)
61  {
62  // selecting optical photons
63  if(pids[s] == 0)
64  {
65  // insert this step into the set of track ids (set can only have unique values).
66  pair< set<int> ::iterator, bool> newtrack = TIDS.insert(tids[s]);
67 
68  // if we found a new track, then add the initial photon energy of this
69  // track to the list of photon energies, for when we calculate quantum efficiency later
70  if( newtrack.second ) photon_energies.push_back( Energies[s] );
71  }
72  }
73 
74 
75  // here is the fun part: figure out the number of photons we detect based
76  // on the quantum efficiency of the photocathode material, if defined:
77 
78  int ndetected = 0;
79 
80  // If the detector corresponding to this hit has a material properties table with "Efficiency" defined:
81  G4MaterialPropertiesTable* MPT = aHit->GetDetector().GetLogical()->GetMaterial()->GetMaterialPropertiesTable();
82  G4MaterialPropertyVector* efficiency = NULL;
83 
84  bool gotefficiency = false;
85  if( MPT != NULL )
86  {
87  efficiency = (G4MaterialPropertyVector*) MPT->GetProperty("EFFICIENCY");
88  if( efficiency != NULL ) gotefficiency = true;
89  }
90 
91  for( unsigned int iphoton = 0; iphoton<TIDS.size(); iphoton++ )
92  {
93  //loop over all unique photons contributing to the hit:
94  if( gotefficiency )
95  {
96  // If the material of this detector has a material properties table
97  // with "EFFICIENCY" defined, then "detect" this photon with probability = efficiency
98  bool outofrange = false;
99  if( G4UniformRand() <= efficiency->GetValue( photon_energies[iphoton], outofrange ) )
100  ndetected++;
101 
102  if( verbosity > 4 )
103  {
104  cout << log_msg << " Found efficiency definition for material "
105  << aHit->GetDetector().GetLogical()->GetMaterial()->GetName()
106  << ": (Ephoton, efficiency)=(" << photon_energies[iphoton] << ", "
107  << ( (G4MaterialPropertyVector*) efficiency )->GetValue( photon_energies[iphoton], outofrange )
108  << ")" << endl;
109  }
110  }
111  else
112  {
113  // No efficiency definition, "detect" all photons
114  ndetected++;
115  }
116  }
117 
118  if(verbosity>4)
119  {
120 
121  cout << log_msg << " (sector, ring, half)=(" << idsector << ", " << idring << ", " << idhalf << ")"
122  << " x=" << tInfos.x/cm << " y=" << tInfos.y/cm << " z=" << tInfos.z/cm << endl;
123  }
124 
125  dgtz["sector"] = idsector;
126  dgtz["ring"] = idring;
127  dgtz["half"] = idhalf;
128  dgtz["nphe"] = ndetected;
129  dgtz["time"] = tInfos.time;
130  dgtz["hitn"] = hitn;
131 
132  return dgtz;
133 }
134 
135 
136 vector<identifier> htcc_HitProcess :: processID(vector<identifier> id, G4Step *step, detector Detector)
137 {
138  id[id.size()-1].id_sharing = 1;
139  return id;
140 }
141 
142 
143 
144 map< string, vector <int> > htcc_HitProcess :: multiDgt(MHit* aHit, int hitn)
145 {
146  map< string, vector <int> > MH;
147  return MH;
148 }
149 
150 
151 
152 
153 
154 
155 
156 
vector< identifier > processID(vector< identifier >, G4Step *, detector)
map< string, vector< int > > multiDgt(MHit *, int)
G4LogicalVolume * GetLogical()
Returns Logical Volume pointer.
Definition: detector.h:113
int GetPID()
Definition: Hit.h:111
double verbosity
vector< identifier > GetId()
Definition: Hit.h:103
double time
Definition: HitProcess.h:43
double z
Definition: HitProcess.h:41
map< string, double > integrateDgt(MHit *, int)
double x
Definition: HitProcess.h:41
Definition: Hit.h:22
vector< double > GetEs()
Definition: Hit.h:97
double y
Definition: HitProcess.h:41
vector< int > GetTIds()
Definition: Hit.h:101
vector< int > GetPIDs()
Definition: Hit.h:112
detector GetDetector()
Definition: Hit.h:108