source: trunk/examples/extended/electromagnetic/TestEm3/src/RunAction.cc@ 1348

Last change on this file since 1348 was 1337, checked in by garnier, 15 years ago

tag geant4.9.4 beta 1 + modifs locales

File size: 13.1 KB
RevLine 
[807]1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
[1337]26// $Id: RunAction.cc,v 1.38 2010/01/24 17:25:07 vnivanch Exp $
27// GEANT4 tag $Name: geant4-09-04-beta-01 $
[807]28//
29//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
30//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
31
32#include "RunAction.hh"
33
34#include "PrimaryGeneratorAction.hh"
35#include "RunActionMessenger.hh"
36#include "HistoManager.hh"
37#include "EmAcceptance.hh"
38
39#include "G4Run.hh"
40#include "G4RunManager.hh"
41#include "G4UnitsTable.hh"
42
[1337]43#include "G4ParticleTable.hh"
44#include "G4ParticleDefinition.hh"
45#include "G4Track.hh"
46#include "G4Gamma.hh"
47#include "G4Electron.hh"
48#include "G4Positron.hh"
49#include "G4ProductionCutsTable.hh"
50#include "G4LossTableManager.hh"
51
[807]52#include "Randomize.hh"
53
54//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
55
56RunAction::RunAction(DetectorConstruction* det, PrimaryGeneratorAction* prim,
57 HistoManager* hist)
58:Detector(det), Primary(prim), histoManager(hist)
59{
60 runMessenger = new RunActionMessenger(this);
61 applyLimit = false;
62
63 for (G4int k=0; k<MaxAbsor; k++) { edeptrue[k] = rmstrue[k] = 1.;
64 limittrue[k] = DBL_MAX;
65 }
66}
67
68//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
69
70RunAction::~RunAction()
71{
72 delete runMessenger;
73}
74
75//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
76
77void RunAction::BeginOfRunAction(const G4Run* aRun)
78{
79 G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl;
80
81 // save Rndm status
82 //
83 G4RunManager::GetRunManager()->SetRandomNumberStore(true);
84 CLHEP::HepRandom::showEngineStatus();
85
86 //initialize cumulative quantities
87 //
88 for (G4int k=0; k<MaxAbsor; k++) {
89 sumEAbs[k] = sum2EAbs[k] = sumLAbs[k] = sum2LAbs[k] = 0.;
90 energyDeposit[k].clear();
91 }
92
[1337]93 n_gamma = 0;
94 n_elec = 0;
95 n_pos = 0;
96
[807]97 //initialize Eflow
98 //
99 G4int nbPlanes = (Detector->GetNbOfLayers())*(Detector->GetNbOfAbsor()) + 2;
100 EnergyFlow.resize(nbPlanes);
101 lateralEleak.resize(nbPlanes);
102 for (G4int k=0; k<nbPlanes; k++) {EnergyFlow[k] = lateralEleak[k] = 0.; }
103
104 //histograms
105 //
106 histoManager->book();
107
108 //example of print dEdx tables
109 //
110 ////PrintDedxTables();
111}
112
113//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
114
115void RunAction::fillPerEvent(G4int kAbs, G4double EAbs, G4double LAbs)
116{
117 //accumulate statistic with restriction
118 //
119 if(applyLimit) energyDeposit[kAbs].push_back(EAbs);
120 sumEAbs[kAbs] += EAbs; sum2EAbs[kAbs] += EAbs*EAbs;
121 sumLAbs[kAbs] += LAbs; sum2LAbs[kAbs] += LAbs*LAbs;
122}
123
124//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
125
126
127void RunAction::EndOfRunAction(const G4Run* aRun)
128{
129 G4int nEvt = aRun->GetNumberOfEvent();
130 G4double norm = G4double(nEvt);
131 if(norm > 0) norm = 1./norm;
132 G4double qnorm = std::sqrt(norm);
133
134 //compute and print statistic
135 //
136 G4double beamEnergy = Primary->GetParticleGun()->GetParticleEnergy();
137 G4double sqbeam = std::sqrt(beamEnergy/GeV);
138
139 G4double MeanEAbs,MeanEAbs2,rmsEAbs,resolution,rmsres;
140 G4double MeanLAbs,MeanLAbs2,rmsLAbs;
141
142 std::ios::fmtflags mode = G4cout.flags();
143 G4int prec = G4cout.precision(2);
144 G4cout << "\n------------------------------------------------------------\n";
145 G4cout << std::setw(14) << "material"
[1230]146 << std::setw(17) << "Edep RMS"
[807]147 << std::setw(33) << "sqrt(E0(GeV))*rmsE/Emean"
148 << std::setw(23) << "total tracklen \n \n";
149
150 for (G4int k=1; k<=Detector->GetNbOfAbsor(); k++)
151 {
152 MeanEAbs = sumEAbs[k]*norm;
153 MeanEAbs2 = sum2EAbs[k]*norm;
[1230]154 rmsEAbs = std::sqrt(std::abs(MeanEAbs2 - MeanEAbs*MeanEAbs));
155 //G4cout << "k= " << k << " RMS= " << rmsEAbs
156 // << " applyLimit: " << applyLimit << G4endl;
[807]157 if(applyLimit) {
158 G4int nn = 0;
159 G4double sume = 0.0;
160 G4double sume2 = 0.0;
161 // compute trancated means
162 G4double lim = rmsEAbs * 2.5;
163 for(G4int i=0; i<nEvt; i++) {
164 G4double e = (energyDeposit[k])[i];
165 if(std::abs(e - MeanEAbs) < lim) {
166 sume += e;
167 sume2 += e*e;
168 nn++;
169 }
170 }
171 G4double norm1 = G4double(nn);
172 if(norm1 > 0.0) norm1 = 1.0/norm1;
173 MeanEAbs = sume*norm1;
174 MeanEAbs2 = sume2*norm1;
[1230]175 rmsEAbs = std::sqrt(std::abs(MeanEAbs2 - MeanEAbs*MeanEAbs));
[807]176 }
177
178 resolution= 100.*sqbeam*rmsEAbs/MeanEAbs;
179 rmsres = resolution*qnorm;
180
181 // Save mean and RMS
182 sumEAbs[k] = MeanEAbs;
183 sum2EAbs[k] = rmsEAbs;
184
185 MeanLAbs = sumLAbs[k]*norm;
186 MeanLAbs2 = sum2LAbs[k]*norm;
[1230]187 rmsLAbs = std::sqrt(std::abs(MeanLAbs2 - MeanLAbs*MeanLAbs));
[807]188
189 //print
190 //
191 G4cout
192 << std::setw(14) << Detector->GetAbsorMaterial(k)->GetName() << ": "
193 << std::setprecision(5)
[1230]194 << std::setw(6) << G4BestUnit(MeanEAbs,"Energy") << " : "
[807]195 << std::setprecision(4)
196 << std::setw(5) << G4BestUnit( rmsEAbs,"Energy")
197 << std::setw(10) << resolution << " +- "
198 << std::setw(5) << rmsres << " %"
199 << std::setprecision(3)
200 << std::setw(10) << G4BestUnit(MeanLAbs,"Length") << " +- "
201 << std::setw(4) << G4BestUnit( rmsLAbs,"Length")
202 << G4endl;
203 }
204 G4cout << "\n------------------------------------------------------------\n";
[1230]205
206 G4cout << " Beam particle "
207 << Primary->GetParticleGun()->
208 GetParticleDefinition()->GetParticleName()
209 << " E = " << G4BestUnit(beamEnergy,"Energy") << G4endl;
[1337]210 G4cout << " Mean number of gamma " << (G4double)n_gamma*norm << G4endl;
211 G4cout << " Mean number of e- " << (G4double)n_elec*norm << G4endl;
212 G4cout << " Mean number of e+ " << (G4double)n_pos*norm << G4endl;
213 G4cout << "------------------------------------------------------------\n";
[807]214
215 //Energy flow
216 //
217 G4int Idmax = (Detector->GetNbOfLayers())*(Detector->GetNbOfAbsor());
218 for (G4int Id=1; Id<=Idmax+1; Id++) {
219 histoManager->FillHisto(2*MaxAbsor+1, (G4double)Id, EnergyFlow[Id]);
220 histoManager->FillHisto(2*MaxAbsor+2, (G4double)Id, lateralEleak[Id]);
221 }
222
223 //Energy deposit from energy flow balance
224 //
225 G4double EdepTot[MaxAbsor];
226 for (G4int k=0; k<MaxAbsor; k++) EdepTot[k] = 0.;
227
228 G4int nbOfAbsor = Detector->GetNbOfAbsor();
229 for (G4int Id=1; Id<=Idmax; Id++) {
230 G4int iAbsor = Id%nbOfAbsor; if (iAbsor==0) iAbsor = nbOfAbsor;
231 EdepTot [iAbsor] += (EnergyFlow[Id] - EnergyFlow[Id+1] - lateralEleak[Id]);
232 }
233
234 G4cout << "\n Energy deposition from Energy flow balance : \n"
235 << std::setw(10) << " material \t Total Edep \n \n";
236 G4cout.precision(6);
237
238 for (G4int k=1; k<=nbOfAbsor; k++) {
239 EdepTot [k] *= norm;
240 G4cout << std::setw(10) << Detector->GetAbsorMaterial(k)->GetName() << ":"
241 << "\t " << G4BestUnit(EdepTot [k],"Energy") << "\n";
242 }
243
244 G4cout << "\n------------------------------------------------------------\n"
245 << G4endl;
246
247 G4cout.setf(mode,std::ios::floatfield);
248 G4cout.precision(prec);
249
250 // Acceptance
251 EmAcceptance acc;
252 G4bool isStarted = false;
253 for (G4int j=1; j<=Detector->GetNbOfAbsor(); j++) {
254 if (limittrue[j] < DBL_MAX) {
255 if (!isStarted) {
256 acc.BeginOfAcceptance("Sampling Calorimeter",nEvt);
257 isStarted = true;
258 }
259 MeanEAbs = sumEAbs[j];
260 rmsEAbs = sum2EAbs[j];
261 G4String mat = Detector->GetAbsorMaterial(j)->GetName();
262 acc.EmAcceptanceGauss("Edep"+mat, nEvt, MeanEAbs,
263 edeptrue[j], rmstrue[j], limittrue[j]);
264 acc.EmAcceptanceGauss("Erms"+mat, nEvt, rmsEAbs,
265 rmstrue[j], rmstrue[j], 2.0*limittrue[j]);
266 }
267 }
268 if(isStarted) acc.EndOfAcceptance();
269
270 //normalize histograms
271 //
272 for (G4int ih = MaxAbsor+1; ih < MaxHisto; ih++) {
273 histoManager->Normalize(ih,norm/MeV);
274 }
275
276 //save histograms
277 histoManager->save();
278
279 // show Rndm status
280 CLHEP::HepRandom::showEngineStatus();
281}
282
283//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
284
285void RunAction::PrintDedxTables()
286{
287 //Print dE/dx tables with binning identical to the Geant3 JMATE bank.
288 //The printout is readable as Geant3 ffread data cards (by the program g4mat).
289 //
290 const G4double tkmin=10*keV, tkmax=10*TeV;
291 const G4int nbin=90;
292 G4double tk[nbin];
293
294 const G4int ncolumn = 5;
295
296 //compute the kinetic energies
297 //
298 const G4double dp = std::log10(tkmax/tkmin)/nbin;
299 const G4double dt = std::pow(10.,dp);
300 tk[0] = tkmin;
301 for (G4int i=1; i<nbin; ++i) tk[i] = tk[i-1]*dt;
302
303 //print the kinetic energies
304 //
305 std::ios::fmtflags mode = G4cout.flags();
306 G4cout.setf(std::ios::fixed,std::ios::floatfield);
307 G4int prec = G4cout.precision(3);
308
309 G4cout << "\n kinetic energies \n ";
310 for (G4int j=0; j<nbin; ++j) {
311 G4cout << G4BestUnit(tk[j],"Energy") << "\t";
312 if ((j+1)%ncolumn == 0) G4cout << "\n ";
313 }
314 G4cout << G4endl;
315
316 //print the dE/dx tables
317 //
318 G4cout.setf(std::ios::scientific,std::ios::floatfield);
319
320 G4ParticleDefinition*
321 part = Primary->GetParticleGun()->GetParticleDefinition();
322
323 G4ProductionCutsTable* theCoupleTable =
324 G4ProductionCutsTable::GetProductionCutsTable();
325 size_t numOfCouples = theCoupleTable->GetTableSize();
326 const G4MaterialCutsCouple* couple = 0;
327
328 for (G4int iab=1;iab <= Detector->GetNbOfAbsor(); iab++)
329 {
330 G4Material* mat = Detector->GetAbsorMaterial(iab);
331 G4int index = 0;
332 for (size_t i=0; i<numOfCouples; i++) {
333 couple = theCoupleTable->GetMaterialCutsCouple(i);
334 if (couple->GetMaterial() == mat) {index = i; break;}
335 }
336 G4cout << "\nLIST";
337 G4cout << "\nC \nC dE/dx (MeV/cm) for " << part->GetParticleName()
338 << " in " << mat ->GetName() << "\nC";
339 G4cout << "\nKINE (" << part->GetParticleName() << ")";
340 G4cout << "\nMATE (" << mat ->GetName() << ")";
341 G4cout.precision(2);
342 G4cout << "\nERAN " << tkmin/GeV << " (ekmin)\t"
343 << tkmax/GeV << " (ekmax)\t"
344 << nbin << " (nekbin)";
345 G4double cutgam =
346 (*(theCoupleTable->GetEnergyCutsVector(idxG4GammaCut)))[index];
347 if (cutgam < tkmin) cutgam = tkmin;
348 if (cutgam > tkmax) cutgam = tkmax;
349 G4double cutele =
350 (*(theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut)))[index];
351 if (cutele < tkmin) cutele = tkmin;
352 if (cutele > tkmax) cutele = tkmax;
353 G4cout << "\nCUTS " << cutgam/GeV << " (cutgam)\t"
354 << cutele/GeV << " (cutele)";
355
356 G4cout.precision(6);
357 G4cout << "\nG4VAL \n ";
358 for (G4int l=0;l<nbin; ++l)
359 {
360 G4double dedx = G4LossTableManager::Instance()
361 ->GetDEDX(part,tk[l],couple);
362 G4cout << dedx/(MeV/cm) << "\t";
363 if ((l+1)%ncolumn == 0) G4cout << "\n ";
364 }
365 G4cout << G4endl;
366 }
367
368 G4cout.precision(prec);
369 G4cout.setf(mode,std::ios::floatfield);
370}
371
372//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
373
[1337]374void RunAction::AddSecondaryTrack(const G4Track* track)
375{
376 const G4ParticleDefinition* d = track->GetDefinition();
377 if(d == G4Gamma::Gamma()) { ++n_gamma; }
378 else if (d == G4Electron::Electron()) { ++n_elec; }
379 else if (d == G4Positron::Positron()) { ++n_pos; }
380}
381
382//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
383
[807]384void RunAction::SetEdepAndRMS(G4int i, G4double edep, G4double rms, G4double lim)
385{
386 if (i>=0 && i<MaxAbsor) {
387 edeptrue [i] = edep;
388 rmstrue [i] = rms;
389 limittrue[i] = lim;
390 }
391}
392
393//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Note: See TracBrowser for help on using the repository browser.