00001 #ifndef GLG4Scint_h 00002 #define GLG4Scint_h 1 00003 /** @file GLG4Scint.hh 00004 Declares GLG4Scint class and helpers. 00005 00006 This file is part of the GenericLAND software library. 00007 $Id: GLG4Scint.hh,v 1.2 2005/03/13 06:34:20 GLG4sim Exp $ 00008 00009 @author Glenn Horton-Smith (Tohoku) 28-Jan-1999 00010 */ 00011 00012 // [see detailed class documentation below] 00013 00014 ///////////// 00015 // Includes 00016 ///////////// 00017 00018 #include "globals.hh" 00019 #include "local_g4compat.hh" 00020 #include "templates.hh" 00021 #include "vector" 00022 #include "G4ThreeVector.hh" 00023 #include "G4ParticleMomentum.hh" 00024 #include "G4Step.hh" 00025 #include "G4OpticalPhoton.hh" 00026 #include "G4DynamicParticle.hh" 00027 #include "G4Material.hh" 00028 #include "G4PhysicsTable.hh" 00029 #include "G4MaterialPropertiesTable.hh" 00030 #include "G4PhysicsOrderedFreeVector.hh" 00031 #include "G4ParticleChange.hh" 00032 #include "G4UImessenger.hh" 00033 00034 class G4UIcommand; 00035 class G4UIdirectory; 00036 00037 ///////////////////// 00038 // Class Definition 00039 ///////////////////// 00040 00041 /** 00042 GLG4Scint is an extremely modified version of the G4Scintillation 00043 process, so much so that it's not even a G4Process anymore! 00044 Features include arbitrary scintillation light time profile and 00045 spectra, Birks' law, particle-dependent specification of all 00046 parameters, and reemission of optical photons killed by other processes. 00047 00048 - Has a GenericPostPostStepDoIt() function (note two "Post"s) 00049 instead of a PostStepDoIt() function. GenericPostPostStepDoIt() 00050 should be called by user in UserSteppingAction. This guarantees 00051 that GLG4Scint will absolutely be the last process considered, and 00052 will definitely see the energy loss by charged particles accurately. 00053 00054 - Modified to allow specification of absolute yield spectra, 00055 resolution scale, Birk's-law coefficient, and digitized waveform, 00056 customized for medium and (optionally) particle type. 00057 00058 - No longer calls G4MaterialPropertiesTable::GetProperty() in 00059 [Post]PostStepDoit() -- all needed data can be found quickly in 00060 the internal physics table. 00061 00062 - Uses poisson random distribution for number of photons if 00063 mean number of photons <= 12. 00064 00065 - The total scintillation yield is now found implicitly from 00066 the integral of the scintillation spectrum, which must now be 00067 in units of photons per photon energy. 00068 00069 - The above feature has been modified by Dario Motta: a scintillation yield 00070 CAN be defined and -if found- used instead of the implicit integral of the 00071 scintillation spectrum. This allows having scintillators with the same 00072 spectrum, but different light yields. 00073 00074 - The materials property tables used are 00075 SCINTILLATION == scintillation spectrum 00076 SCINTWAVEFORM == scintillation waveform or time constant 00077 SCINTMOD == resolution scale, Birk's constant, reference dE/dx 00078 00079 - SCINTILLATION is required in each scintillating medium. 00080 (Okay to omit if you don't want the medium to scintillate.) 00081 00082 - If SCINTWAVEFORM is missing, uses exponential waveform with default 00083 ScintillationTime. If SCINTWAVEFORM contains negative "Momentum"'s 00084 then each "Momentum" is the decay time and its corresponding value 00085 is the relative strength of that exponential decay. 00086 Otherwise, the "PhotonEnergy" of each element is a time, and the 00087 Value of each element is the relative strength. 00088 00089 - Default values of resolution scale (=1.0), Birk's constant (=0.0) 00090 and reference dE/dx (=0.0) are used if all or part of SCINTMOD is 00091 is missing. SCINTMOD "PhotonEnergy" values should be set to the 00092 index number (0.0, 1.0, 2.0, with no units). 00093 00094 - Birk's law (see 1998 Particle Data Booklet eq. 25.1) is implemented 00095 as 00096 yield(dE/dx) = yield_ref * dE/dx * (1 + kb*(dE/dx)_ref) / (1 + kb*(dE/dx)). 00097 I.e., the scintillation spectrum given in SCINTILLATION is 00098 measured for particles with dE/dx = (dE/dx)_ref. The usual 00099 formula is recovered if (dE/dx)_ref = 0.0 (the default). 00100 This is useful if you have an empirically-measured spectrum for 00101 some densely-ionizing particle (like an alpha). 00102 00103 - The constructor now accepts an additional string argument, tablename, 00104 which allows selection of alternate property tables. E.g, 00105 tablename = "neutron" might be used to allow specification of a 00106 different waveform for scintillation due to neutron energy deposition. 00107 The code then searches for tables with names of the form 00108 "SCINTILLATIONneutron" 00109 If it finds such a table, that table is used in preference to 00110 the default (un-suffixed) table when stepping particles of that type. 00111 00112 - The process generates at most maxTracksPerStep secondaries per step. 00113 If more "real" photons are needed, it increases the weight of the 00114 tracked opticalphotons. Opticalphotons are thus macro-particles in 00115 the high-scintillation case. The code preserves an integer number 00116 of real photons per macro-particle. 00117 */ 00118 00119 class GLG4Scint 00120 : public G4UImessenger // not creating a separate class is my laziness -GHS. 00121 { 00122 00123 private: 00124 00125 ////////////// 00126 // Operators 00127 ////////////// 00128 00129 // GLG4Scint& operator=(const GLG4Scint &right); 00130 00131 public: 00132 00133 //////////////// 00134 // Nested class 00135 //////////////// 00136 00137 class MyPhysicsTable { 00138 public: 00139 G4String* name; 00140 class Entry { 00141 public: 00142 G4PhysicsOrderedFreeVector* spectrumIntegral; 00143 G4PhysicsOrderedFreeVector* reemissionIntegral; 00144 G4PhysicsOrderedFreeVector* timeIntegral; 00145 int I_own_spectrumIntegral, I_own_timeIntegral; 00146 G4double resolutionScale; 00147 G4double birksConstant; 00148 G4double ref_dE_dx; 00149 G4double light_yield; 00150 Entry(); 00151 ~Entry(); 00152 void Build(const G4String& name, int material_index, 00153 G4MaterialPropertiesTable *matprops); 00154 }; 00155 00156 private: 00157 static MyPhysicsTable *head; 00158 MyPhysicsTable* next; 00159 G4int used_by_count; 00160 00161 Entry* data; 00162 G4int length; 00163 00164 MyPhysicsTable(); 00165 ~MyPhysicsTable(); 00166 00167 void Build(const G4String& newname); 00168 00169 friend class GLG4Scint; 00170 00171 public: 00172 static MyPhysicsTable* FindOrBuild(const G4String& name); 00173 static const MyPhysicsTable* GetDefault(void) { return head; } 00174 void IncUsedBy(void) { ++used_by_count; } 00175 void DecUsedBy(void) { if (--used_by_count <= 0) delete this; } 00176 const Entry * GetEntry(int i) const { return data+i; } 00177 void Dump(void) const; 00178 }; 00179 00180 //////////////////////////////// 00181 // Constructors and Destructor 00182 //////////////////////////////// 00183 00184 GLG4Scint(const G4String& tableName= "", 00185 G4double lowerMassLimit= 0.0); 00186 00187 // GLG4Scint(const GLG4Scint &right); 00188 00189 ~GLG4Scint(); 00190 00191 //////////// 00192 // Methods 00193 //////////// 00194 00195 G4VParticleChange* PostPostStepDoIt(const G4Track& aTrack, 00196 const G4Step& aStep); 00197 00198 G4double GetLowerMassLimit(void) const; 00199 00200 void DumpInfo() const; 00201 00202 MyPhysicsTable* GetMyPhysicsTable(void) const; 00203 00204 G4int GetVerboseLevel(void) const; 00205 void SetVerboseLevel(G4int level); 00206 00207 // following two methods are for G4UImessenger 00208 void SetNewValue(G4UIcommand * command,G4String newValues); 00209 G4String GetCurrentValue(G4UIcommand * command); 00210 00211 //////////////// 00212 // static methods 00213 //////////////// 00214 00215 static G4VParticleChange* GenericPostPostStepDoIt(const G4Step *pStep); 00216 00217 // following are for energy deposition diagnosis 00218 static void ResetTotEdep() { 00219 totEdep= totEdep_quenched= 0.0; 00220 scintCentroidSum *= 0.0; 00221 } 00222 static G4double GetTotEdep() { return totEdep; } 00223 static G4double GetTotEdepQuenched() { return totEdep_quenched; } 00224 static G4bool GetDoScintillation() { return doScintillation; } 00225 static G4ThreeVector GetScintCentroid() { 00226 return scintCentroidSum*(1.0/totEdep_quenched); 00227 } 00228 00229 /////////////////////// 00230 // Class Data Members 00231 /////////////////////// 00232 00233 protected: 00234 int verboseLevel; 00235 00236 static int quenchtype; 00237 00238 // Below is the pointer to the physics table which this instance 00239 // of GLG4Scint will use. You may create a separate instance 00240 // of GLG4Scint for each particle, if you like. 00241 MyPhysicsTable * myPhysicsTable; 00242 00243 // below is the lower mass limit for this instance of GLG4Scint 00244 G4double myLowerMassLimit; 00245 00246 // return value of PostPostStepDoIt 00247 G4ParticleChange aParticleChange; 00248 00249 //////////////// 00250 // static variables 00251 //////////////// 00252 00253 // vector of all existing GLG4Scint objects. 00254 // They register themselves when created, 00255 // remove themselves when deleted. 00256 // Used by GenericPostPostStepDoIt 00257 static G4std::vector<GLG4Scint *> masterVectorOfGLG4Scint; 00258 00259 // top level of scintillation command 00260 static G4UIdirectory* GLG4ScintDir; 00261 00262 // universal maximum number of secondary tracks per step for GLG4Scint 00263 static G4int maxTracksPerStep; 00264 00265 // universal mean number of true photons per secondary track in GLG4Scint 00266 static G4double meanPhotonsPerSecondary; 00267 00268 // universal on/off flag 00269 static G4bool doScintillation; 00270 00271 // on/off flag for absorbed opticalphoton reemission 00272 static G4bool doReemission; 00273 00274 // total real energy deposited and total quenched energy deposited 00275 static G4double totEdep; 00276 static G4double totEdep_quenched; 00277 static G4ThreeVector scintCentroidSum; 00278 }; 00279 00280 //////////////////// 00281 // Inline methods 00282 //////////////////// 00283 00284 inline 00285 GLG4Scint::MyPhysicsTable * GLG4Scint::GetMyPhysicsTable() const 00286 { 00287 return myPhysicsTable; 00288 } 00289 00290 inline 00291 void GLG4Scint::DumpInfo() const 00292 { 00293 G4cout << "GLG4Scint[" << *(myPhysicsTable->name) << "] {\n" 00294 << " myLowerMassLimit=" << myLowerMassLimit << G4endl; 00295 if (myPhysicsTable) 00296 { 00297 if (verboseLevel >= 2) 00298 myPhysicsTable->Dump(); 00299 } 00300 G4cout << "}" << G4endl; 00301 } 00302 00303 inline 00304 G4double GLG4Scint::GetLowerMassLimit(void) const 00305 { 00306 return myLowerMassLimit; 00307 } 00308 00309 inline void GLG4Scint::SetVerboseLevel(int level) { verboseLevel= level; } 00310 inline G4int GLG4Scint::GetVerboseLevel(void) const { return verboseLevel; } 00311 00312 #endif /* GLG4Scint_h */