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

Last change on this file since 1187 was 807, checked in by garnier, 16 years ago

update

File size: 12.1 KB
Line 
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//
26// $Id: RunAction.cc,v 1.34 2007/04/24 13:05:14 vnivanch Exp $
27// GEANT4 tag $Name: geant4-09-01-patch-02 $
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
43#include "Randomize.hh"
44
45//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
46
47RunAction::RunAction(DetectorConstruction* det, PrimaryGeneratorAction* prim,
48                     HistoManager* hist)
49:Detector(det), Primary(prim), histoManager(hist)
50{
51  runMessenger = new RunActionMessenger(this);
52  applyLimit = false;
53
54  for (G4int k=0; k<MaxAbsor; k++) { edeptrue[k] = rmstrue[k] = 1.;
55                                    limittrue[k] = DBL_MAX;
56  }
57}
58
59//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
60
61RunAction::~RunAction()
62{
63  delete runMessenger;
64}
65
66//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
67
68void RunAction::BeginOfRunAction(const G4Run* aRun)
69{
70  G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl;
71
72  // save Rndm status
73  //
74  G4RunManager::GetRunManager()->SetRandomNumberStore(true);
75  CLHEP::HepRandom::showEngineStatus();
76
77  //initialize cumulative quantities
78  //
79  for (G4int k=0; k<MaxAbsor; k++) {
80    sumEAbs[k] = sum2EAbs[k]  = sumLAbs[k] = sum2LAbs[k] = 0.;
81    energyDeposit[k].clear(); 
82  }
83
84  //initialize Eflow
85  //
86  G4int nbPlanes = (Detector->GetNbOfLayers())*(Detector->GetNbOfAbsor()) + 2;
87  EnergyFlow.resize(nbPlanes);
88  lateralEleak.resize(nbPlanes);
89  for (G4int k=0; k<nbPlanes; k++) {EnergyFlow[k] = lateralEleak[k] = 0.; }
90 
91  //histograms
92  //
93  histoManager->book();
94   
95  //example of print dEdx tables
96  //
97  ////PrintDedxTables();
98}
99
100//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
101
102void RunAction::fillPerEvent(G4int kAbs, G4double EAbs, G4double LAbs)
103{
104  //accumulate statistic with restriction
105  //
106  if(applyLimit) energyDeposit[kAbs].push_back(EAbs);
107  sumEAbs[kAbs]  += EAbs;  sum2EAbs[kAbs]  += EAbs*EAbs;
108  sumLAbs[kAbs]  += LAbs;  sum2LAbs[kAbs]  += LAbs*LAbs;
109}
110
111//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
112
113
114void RunAction::EndOfRunAction(const G4Run* aRun)
115{
116  G4int nEvt = aRun->GetNumberOfEvent();
117  G4double  norm = G4double(nEvt);
118  if(norm > 0) norm = 1./norm;
119  G4double qnorm = std::sqrt(norm);
120
121  //compute and print statistic
122  //
123  G4double beamEnergy = Primary->GetParticleGun()->GetParticleEnergy();
124  G4double sqbeam = std::sqrt(beamEnergy/GeV);
125
126  G4double MeanEAbs,MeanEAbs2,rmsEAbs,resolution,rmsres;
127  G4double MeanLAbs,MeanLAbs2,rmsLAbs;
128
129  std::ios::fmtflags mode = G4cout.flags();
130  G4int  prec = G4cout.precision(2);
131  G4cout << "\n------------------------------------------------------------\n";
132  G4cout << std::setw(14) << "material"
133         << std::setw(17) << "Total Edep"
134         << std::setw(33) << "sqrt(E0(GeV))*rmsE/Emean"
135         << std::setw(23) << "total tracklen \n \n";
136
137  for (G4int k=1; k<=Detector->GetNbOfAbsor(); k++)
138    {
139      MeanEAbs  = sumEAbs[k]*norm;
140      MeanEAbs2 = sum2EAbs[k]*norm;
141      rmsEAbs  = std::sqrt(std::fabs(MeanEAbs2 - MeanEAbs*MeanEAbs));
142
143      if(applyLimit) {
144        G4int    nn    = 0;
145        G4double sume  = 0.0;
146        G4double sume2 = 0.0;
147        // compute trancated means 
148        G4double lim   = rmsEAbs * 2.5;
149        for(G4int i=0; i<nEvt; i++) {
150          G4double e = (energyDeposit[k])[i];
151          if(std::abs(e - MeanEAbs) < lim) {
152            sume  += e;
153            sume2 += e*e;
154            nn++;
155          }
156        }
157        G4double norm1 = G4double(nn);
158        if(norm1 > 0.0) norm1 = 1.0/norm1;
159        MeanEAbs  = sume*norm1;
160        MeanEAbs2 = sume2*norm1;
161        rmsEAbs  = std::sqrt(std::fabs(MeanEAbs2 - MeanEAbs*MeanEAbs));
162      }
163
164      resolution= 100.*sqbeam*rmsEAbs/MeanEAbs;
165      rmsres    = resolution*qnorm;
166
167      // Save mean and RMS
168      sumEAbs[k] = MeanEAbs;
169      sum2EAbs[k] = rmsEAbs;
170
171      MeanLAbs  = sumLAbs[k]*norm;
172      MeanLAbs2 = sum2LAbs[k]*norm;
173      rmsLAbs  = std::sqrt(std::fabs(MeanLAbs2 - MeanLAbs*MeanLAbs));
174
175      //print
176      //
177      G4cout
178       << std::setw(14) << Detector->GetAbsorMaterial(k)->GetName() << ": "
179       << std::setprecision(5)
180       << std::setw(6) << G4BestUnit(MeanEAbs,"Energy") << " +- "
181       << std::setprecision(4)
182       << std::setw(5) << G4BestUnit( rmsEAbs,"Energy") 
183       << std::setw(10) << resolution  << " +- " 
184       << std::setw(5) << rmsres << " %"
185       << std::setprecision(3)
186       << std::setw(10) << G4BestUnit(MeanLAbs,"Length")  << " +- "
187       << std::setw(4) << G4BestUnit( rmsLAbs,"Length")
188       << G4endl;
189    }
190  G4cout << "\n------------------------------------------------------------\n";
191 
192  //Energy flow
193  //
194  G4int Idmax = (Detector->GetNbOfLayers())*(Detector->GetNbOfAbsor());
195  for (G4int Id=1; Id<=Idmax+1; Id++) {
196    histoManager->FillHisto(2*MaxAbsor+1, (G4double)Id, EnergyFlow[Id]);
197    histoManager->FillHisto(2*MaxAbsor+2, (G4double)Id, lateralEleak[Id]);
198  }
199 
200  //Energy deposit from energy flow balance
201  //
202  G4double EdepTot[MaxAbsor];
203  for (G4int k=0; k<MaxAbsor; k++) EdepTot[k] = 0.;
204 
205  G4int nbOfAbsor = Detector->GetNbOfAbsor();
206  for (G4int Id=1; Id<=Idmax; Id++) {
207    G4int iAbsor = Id%nbOfAbsor; if (iAbsor==0) iAbsor = nbOfAbsor;
208    EdepTot [iAbsor] += (EnergyFlow[Id] - EnergyFlow[Id+1] - lateralEleak[Id]);
209  }
210 
211  G4cout << "\n Energy deposition from Energy flow balance : \n"
212         << std::setw(10) << "  material \t Total Edep \n \n";
213  G4cout.precision(6);
214 
215  for (G4int k=1; k<=nbOfAbsor; k++) {
216    EdepTot [k] *= norm;
217    G4cout << std::setw(10) << Detector->GetAbsorMaterial(k)->GetName() << ":"
218           << "\t " << G4BestUnit(EdepTot [k],"Energy") << "\n";
219  }
220 
221  G4cout << "\n------------------------------------------------------------\n" 
222         << G4endl;
223   
224  G4cout.setf(mode,std::ios::floatfield);
225  G4cout.precision(prec);
226
227  // Acceptance
228  EmAcceptance acc;
229  G4bool isStarted = false;
230  for (G4int j=1; j<=Detector->GetNbOfAbsor(); j++) {
231    if (limittrue[j] < DBL_MAX) {
232      if (!isStarted) {
233        acc.BeginOfAcceptance("Sampling Calorimeter",nEvt);
234        isStarted = true;
235      }
236      MeanEAbs = sumEAbs[j];
237      rmsEAbs  = sum2EAbs[j];
238      G4String mat = Detector->GetAbsorMaterial(j)->GetName();
239      acc.EmAcceptanceGauss("Edep"+mat, nEvt, MeanEAbs,
240                             edeptrue[j], rmstrue[j], limittrue[j]);
241      acc.EmAcceptanceGauss("Erms"+mat, nEvt, rmsEAbs,
242                             rmstrue[j], rmstrue[j], 2.0*limittrue[j]);
243    }
244  }
245  if(isStarted) acc.EndOfAcceptance();
246
247  //normalize histograms
248  //
249  for (G4int ih = MaxAbsor+1; ih < MaxHisto; ih++) {
250    histoManager->Normalize(ih,norm/MeV);
251  }
252 
253  //save histograms   
254  histoManager->save();
255
256  // show Rndm status
257  CLHEP::HepRandom::showEngineStatus();
258}
259
260//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
261
262#include "G4ParticleTable.hh"
263#include "G4ParticleDefinition.hh"
264#include "G4Gamma.hh"
265#include "G4Electron.hh"
266#include "G4ProductionCutsTable.hh"
267#include "G4LossTableManager.hh"
268
269//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
270
271void RunAction::PrintDedxTables()
272{
273  //Print dE/dx tables with binning identical to the Geant3 JMATE bank.
274  //The printout is readable as Geant3 ffread data cards (by the program g4mat).
275  //
276  const G4double tkmin=10*keV, tkmax=10*TeV;
277  const G4int nbin=90;
278  G4double tk[nbin];
279
280  const G4int ncolumn = 5;
281
282  //compute the kinetic energies
283  //
284  const G4double dp = std::log10(tkmax/tkmin)/nbin;
285  const G4double dt = std::pow(10.,dp);
286  tk[0] = tkmin;
287  for (G4int i=1; i<nbin; ++i) tk[i] = tk[i-1]*dt;
288
289  //print the kinetic energies
290  //
291  std::ios::fmtflags mode = G4cout.flags();
292  G4cout.setf(std::ios::fixed,std::ios::floatfield);
293  G4int  prec = G4cout.precision(3);
294
295  G4cout << "\n kinetic energies \n ";
296  for (G4int j=0; j<nbin; ++j) {
297    G4cout << G4BestUnit(tk[j],"Energy") << "\t";
298    if ((j+1)%ncolumn == 0) G4cout << "\n ";
299  }
300  G4cout << G4endl;
301
302  //print the dE/dx tables
303  //
304  G4cout.setf(std::ios::scientific,std::ios::floatfield);
305
306  G4ParticleDefinition*
307  part = Primary->GetParticleGun()->GetParticleDefinition();
308 
309  G4ProductionCutsTable* theCoupleTable =
310        G4ProductionCutsTable::GetProductionCutsTable();
311  size_t numOfCouples = theCoupleTable->GetTableSize();
312  const G4MaterialCutsCouple* couple = 0;
313
314  for (G4int iab=1;iab <= Detector->GetNbOfAbsor(); iab++)
315     {
316      G4Material* mat = Detector->GetAbsorMaterial(iab);
317      G4int index = 0;
318      for (size_t i=0; i<numOfCouples; i++) {
319         couple = theCoupleTable->GetMaterialCutsCouple(i);
320         if (couple->GetMaterial() == mat) {index = i; break;}
321      }
322      G4cout << "\nLIST";
323      G4cout << "\nC \nC  dE/dx (MeV/cm) for " << part->GetParticleName()
324             << " in " << mat ->GetName() << "\nC";
325      G4cout << "\nKINE   (" << part->GetParticleName() << ")";
326      G4cout << "\nMATE   (" << mat ->GetName() << ")";
327      G4cout.precision(2);
328      G4cout << "\nERAN  " << tkmin/GeV << " (ekmin)\t"
329                           << tkmax/GeV << " (ekmax)\t"
330                           << nbin      << " (nekbin)";
331      G4double cutgam =
332         (*(theCoupleTable->GetEnergyCutsVector(idxG4GammaCut)))[index];
333      if (cutgam < tkmin) cutgam = tkmin;
334      if (cutgam > tkmax) cutgam = tkmax;
335      G4double cutele =
336         (*(theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut)))[index];
337      if (cutele < tkmin) cutele = tkmin;
338      if (cutele > tkmax) cutele = tkmax;
339      G4cout << "\nCUTS  " << cutgam/GeV << " (cutgam)\t"
340                           << cutele/GeV << " (cutele)";
341
342      G4cout.precision(6);
343      G4cout << "\nG4VAL \n ";
344      for (G4int l=0;l<nbin; ++l)
345         {
346           G4double dedx = G4LossTableManager::Instance()
347                                               ->GetDEDX(part,tk[l],couple);
348           G4cout << dedx/(MeV/cm) << "\t";
349           if ((l+1)%ncolumn == 0) G4cout << "\n ";
350         }
351      G4cout << G4endl;
352     }
353
354  G4cout.precision(prec);
355  G4cout.setf(mode,std::ios::floatfield);
356}
357
358//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
359
360void RunAction::SetEdepAndRMS(G4int i, G4double edep, G4double rms, G4double lim)
361{
362  if (i>=0 && i<MaxAbsor) {
363    edeptrue [i] = edep;
364    rmstrue  [i] = rms;
365    limittrue[i] = lim;
366  }
367}
368
369//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Note: See TracBrowser for help on using the repository browser.