46 #include "G4THitsCollection.hh"
62 RMC01AnalysisManager::RMC01AnalysisManager()
63 :fOmni_fluence_for_fwd_sim(1./
cm2),
64 fAccumulated_edep(0.), fAccumulated_edep2(0.), fMean_edep(0.),
65 fError_mean_edep(0.), fRelative_error(0.), fElapsed_time(0.),
66 fPrecision_to_reach(0.),fStop_run_if_precision_reached(true),
67 fNb_evt_modulo_for_convergence_test(5000),
68 fPrimSpectrumType(
EXPO),
69 fAlpha_or_E0(.5*
MeV),fAmplitude_prim_spectrum (1.),
70 fEmin_prim_spectrum(1.*
keV),fEmax_prim_spectrum (20.*
MeV),
71 fAdjoint_sim_mode(true),fNb_evt_per_adj_evt(2)
86 for (
size_t i=0; i <= nbin; i++) {
88 val_bin=emin * std::pow(10., i * std::log10(emax/emin)/nbin);
90 G4double factor =std::pow(10., exp_10);
91 val_bin=
int(factor*val_bin)/factor;
101 fEdep_vs_prim_ekin =
new Histo1DVar(
"Edep_vs_prim_ekin",bins, nbin+1,
LEFT);
102 fElectron_current =
new Histo1DVar(
"Electron_current",bins, nbin+1,
LEFT);
103 fProton_current=
new Histo1DVar(
"Proton_current",bins, nbin+1,
LEFT);
104 fGamma_current=
new Histo1DVar(
"Gamma_current",bins, nbin+1,
LEFT);
111 fEdep_rmatrix_vs_electron_prim_energy =
112 new Histo1DVar(
"Edep_rmatrix_vs_electron_prim_energy",
115 fElectron_current_rmatrix_vs_electron_prim_energy =
116 new Histo2DVar(
"Electron_current_rmatrix_vs_electron_prim_energy",
117 bins, nbin+1,
LEFT, bins, nbin+1,
LEFT);
119 fGamma_current_rmatrix_vs_electron_prim_energy =
120 new Histo2DVar(
"Gamma_current_rmatrix_vs_electron_prim_energy",
121 bins, nbin+1,
LEFT, bins, nbin+1,
LEFT);
126 fEdep_rmatrix_vs_gamma_prim_energy =
127 new Histo1DVar(
"Edep_rmatrix_vs_gamma_prim_energy",
130 fElectron_current_rmatrix_vs_gamma_prim_energy =
131 new Histo2DVar(
"Electron_current_rmatrix_vs_gamma_prim_energy",
132 bins, nbin+1,
LEFT, bins, nbin+1,
LEFT);
134 fGamma_current_rmatrix_vs_gamma_prim_energy =
135 new Histo2DVar(
"Gamma_current_rmatrix_vs_gamma_prim_energy",
136 bins, nbin+1,
LEFT, bins, nbin+1,
LEFT);
140 fEdep_rmatrix_vs_proton_prim_energy =
141 new Histo1DVar(
"Edep_rmatrix_vs_proton_prim_energy",
144 fElectron_current_rmatrix_vs_proton_prim_energy =
145 new Histo2DVar(
"Electron_current_rmatrix_vs_proton_prim_energy",
146 bins, nbin+1,
LEFT, bins, nbin+1,
LEFT);
148 fGamma_current_rmatrix_vs_proton_prim_energy =
149 new Histo2DVar(
"Gamma_current_rmatrix_vs_proton_prim_energy",
150 bins, nbin+1,
LEFT, bins, nbin+1,
LEFT);
152 fProton_current_rmatrix_vs_proton_prim_energy =
153 new Histo2DVar(
"Proton_current_rmatrix_vs_proton_prim_energy",
154 bins, nbin+1,
LEFT, bins, nbin+1,
LEFT);
174 delete fEdep_vs_prim_ekin;
175 delete fElectron_current;
176 delete fProton_current;
177 delete fGamma_current;
179 delete fEdep_rmatrix_vs_electron_prim_energy;
180 delete fElectron_current_rmatrix_vs_electron_prim_energy;
181 delete fGamma_current_rmatrix_vs_electron_prim_energy;
183 delete fEdep_rmatrix_vs_gamma_prim_energy;
184 delete fElectron_current_rmatrix_vs_gamma_prim_energy;
185 delete fGamma_current_rmatrix_vs_gamma_prim_energy;
187 delete fEdep_rmatrix_vs_proton_prim_energy;
188 delete fElectron_current_rmatrix_vs_proton_prim_energy;
189 delete fProton_current_rmatrix_vs_proton_prim_energy;
190 delete fGamma_current_rmatrix_vs_proton_prim_energy;
204 { fAccumulated_edep =0.;
205 fAccumulated_edep2 =0.;
211 if (fAdjoint_sim_mode){
214 fConvergenceFileOutput.open(
"ConvergenceOfAdjointSimulationResults.txt",
216 fConvergenceFileOutput<<
"Normalised Edep[MeV]\terror[MeV]\tcomputing_time[s]"
220 fConvergenceFileOutput.open(
"ConvergenceOfForwardSimulationResults.txt",
222 fConvergenceFileOutput<<
"Edep per event [MeV]\terror[MeV]\tcomputing_time[s]"
225 fConvergenceFileOutput.setf(std::ios::scientific);
226 fConvergenceFileOutput.precision(6);
237 if (!fAdjoint_sim_mode){
238 G4cout<<
"Results of forward simulation!"<<std::endl;
239 G4cout<<
"edep per event [MeV] = "<<fMean_edep<<std::endl;
240 G4cout<<
"error[MeV] = "<<fError_mean_edep<<std::endl;
242 WriteHisto(fEdep_vs_prim_ekin,1./nb_evt,
G4String(
"Fwd_Edep_vs_EkinPrim.txt"),
243 G4String(
"E1[MeV]\t\tE2[MeV]\t\tEdep[MeV]\terr_Edep[MeV]\n"));
244 WriteHisto(fElectron_current,1./nb_evt,
G4String(
"Fwd_ElectronCurrent.txt"),
245 G4String(
"E1[MeV]\t\tE2[MeV]\t\tnb entering electron\terr\n"));
246 WriteHisto(fProton_current,1./nb_evt,
G4String(
"Fwd_ProtonCurrent.txt"),
247 G4String(
"E1[MeV]\t\tE2[MeV]\t\tnb entering proton\terr[]\n"));
248 WriteHisto(fGamma_current,1./nb_evt,
G4String(
"Fwd_GammaCurrent.txt"),
249 G4String(
"E1[MeV]\t\tE2[MeV]\t\tnb entering gamma\terr[]\n"));
253 G4cout<<
"Results of reverse/adjoint simulation!"<<std::endl;
254 G4cout<<
"normalised edep [MeV] = "<<fMean_edep<<std::endl;
255 G4cout<<
"error[MeV] = "<<fError_mean_edep<<std::endl;
261 WriteHisto(fEdep_vs_prim_ekin,factor,
G4String(
"Adj_Edep_vs_EkinPrim.txt"),
262 G4String(
"E1[MeV]\t\tE2[MeV]\t\tEdep[MeV]\terr_Edep[MeV]\n"));
263 WriteHisto(fElectron_current,factor,
G4String(
"Adj_ElectronCurrent.txt"),
264 G4String(
"E1[MeV]\t\tE2[MeV]\t\tnb entering electron\terr\n"));
265 WriteHisto(fProton_current,factor,
G4String(
"Adj_ProtonCurrent.txt"),
266 G4String(
"E1[MeV]\t\tE2[MeV]\t\tnb entering proton\terr[]\n"));
267 WriteHisto(fGamma_current,factor,
G4String(
"Adj_GammaCurrent.txt"),
268 G4String(
"E1[MeV]\t\tE2[MeV]\t\tnb entering gamma\terr[]\n"));
271 WriteHisto(fEdep_rmatrix_vs_electron_prim_energy,factor,
272 G4String(
"Adj_Edep_vs_EkinPrimElectron_Answer.txt"),
273 G4String(
"E1[MeV]\t\tE2[MeV]\t\tEdep Efficiency[MeV*cm2*MeV*str]\terr_Edep[MeV*cm2*MeV*str]\n"));
275 WriteHisto(fElectron_current_rmatrix_vs_electron_prim_energy,factor,
276 G4String(
"Adj_ElectronCurrent_vs_EkinPrimElectron_Answer.txt"),
277 G4String(
"Eprim1[MeV]\t\tEprim2[MeV]\t\tEsec1[MeV]\t\tEsec2[MeV]\t Current Efficiency[cm2*MeV*str]\terr[cm2*MeV*str]\n"));
279 WriteHisto(fGamma_current_rmatrix_vs_electron_prim_energy,factor,
280 G4String(
"Adj_GammaCurrent_vs_EkinPrimElectron_Answer.txt"),
281 G4String(
"Eprim1[MeV]\t\tEprim2[MeV]\t\tEsec1[MeV]\t\tEsec2[MeV]\t Current Efficiency[cm2*MeV*str]\terr[cm2*MeV*str]\n"));
283 WriteHisto(fEdep_rmatrix_vs_gamma_prim_energy,factor,
284 G4String(
"Adj_Edep_vs_EkinPrimGamma_Answer.txt"),
285 G4String(
"E1[MeV]\t\tE2[MeV]\t\tEdep Efficiency[MeV*cm2*MeV*str]\terr_Edep[MeV*cm2*MeV*str]\n"));
287 WriteHisto(fElectron_current_rmatrix_vs_gamma_prim_energy,factor,
288 G4String(
"Adj_ElectronCurrent_vs_EkinPrimGamma_Answer.txt"),
289 G4String(
"Eprim1[MeV]\t\tEprim2[MeV]\t\tEsec1[MeV]\t\tEsec2[MeV]\t Current Efficiency[cm2*MeV*str]\terr[cm2*MeV*str]\n"));
291 WriteHisto(fGamma_current_rmatrix_vs_gamma_prim_energy,factor,
292 G4String(
"Adj_GammaCurrent_vs_EkinPrimGamma_Answer.txt"),
293 G4String(
"Eprim1[MeV]\t\tEprim2[MeV]\t\tEsec1[MeV]\t\tEsec2[MeV]\t Current Efficiency[cm2*MeV*str]\terr[cm2*MeV*str]\n"));
297 WriteHisto(fEdep_rmatrix_vs_proton_prim_energy,factor,
298 G4String(
"Adj_Edep_vs_EkinPrimProton_Answer.txt"),
299 G4String(
"E1[MeV]\t\tE2[MeV]\t\tEdep Efficiency[MeV*cm2*MeV*str]\terr_Edep[MeV*cm2*MeV*str]\n"));
301 WriteHisto(fElectron_current_rmatrix_vs_proton_prim_energy,factor,
302 G4String(
"Adj_ElectronCurrent_vs_EkinPrimProton_Answer.txt"),
303 G4String(
"Eprim1[MeV]\t\tEprim2[MeV]\t\tEsec1[MeV]\t\tEsec2[MeV]\t Current Efficiency[cm2*MeV*str]\terr[cm2*MeV*str]\n"));
305 WriteHisto(fGamma_current_rmatrix_vs_proton_prim_energy,factor,
306 G4String(
"Adj_GammaCurrent_vs_EkinPrimProton_Answer.txt"),
307 G4String(
"Eprim1[MeV]\t\tEprim2[MeV]\t\tEsec1[MeV]\t\tEsec2[MeV]\t Current Efficiency[cm2*MeV*str]\terr[cm2*MeV*str]\n"));
309 WriteHisto(fProton_current_rmatrix_vs_proton_prim_energy,factor,
310 G4String(
"Adj_ProtonCurrent_vs_EkinPrimProton_Answer.txt"),
311 G4String(
"Eprim1[MeV]\t\tEprim2[MeV]\t\tEsec1[MeV]\t\tEsec2[MeV]\t Current Efficiency[cm2*MeV*str]\terr[cm2*MeV*str]\n"));
313 fConvergenceFileOutput.close();
327 if (fAdjoint_sim_mode) EndOfEventForAdjointSimulation(anEvent);
328 else EndOfEventForForwardSimulation(anEvent);
334 if (fAdjoint_sim_mode) {
335 G4double n_adj_evt= nb_event/fNb_evt_per_adj_evt;
337 if (n_adj_evt*fNb_evt_per_adj_evt == nb_event) {
338 nb_event =
static_cast<G4int>(n_adj_evt);
345 if (nb_event>100 && fStop_run_if_precision_reached &&
346 fPrecision_to_reach >fRelative_error) {
347 G4cout<<fPrecision_to_reach*100.<<
"% Precision reached!"<<std::endl;
350 fConvergenceFileOutput<<fMean_edep<<
'\t'<<fError_mean_edep
351 <<
'\t'<<fElapsed_time<<std::endl;
355 if (nb_event>0 && nb_event % fNb_evt_modulo_for_convergence_test == 0) {
359 fConvergenceFileOutput<<fMean_edep<<
'\t'<<fError_mean_edep<<
'\t'
360 <<fElapsed_time<<std::endl;
366 void RMC01AnalysisManager::EndOfEventForForwardSimulation(
388 for (i=0;i<edepCollection->
entries();i++)
389 totEdep+=(*edepCollection)[i]->GetValue()*(*edepCollection)[i]->GetWeight();
392 fAccumulated_edep +=totEdep ;
393 fAccumulated_edep2 +=totEdep*totEdep;
397 G4double prim_ekin =std::sqrt(E0*E0+P*P)-E0;
398 fEdep_vs_prim_ekin->
fill(prim_ekin,totEdep);
400 ComputeMeanEdepAndError(anEvent,fMean_edep,fError_mean_edep);
401 if (fError_mean_edep>0) fRelative_error= fError_mean_edep/fMean_edep;
406 for (i=0;i<electronCurrentCollection->
entries();i++) {
407 G4double ekin =(*electronCurrentCollection)[i]->GetValue();
409 fElectron_current->
fill(ekin,weight);
412 for (i=0;i<protonCurrentCollection->
entries();i++) {
413 G4double ekin =(*protonCurrentCollection)[i]->GetValue();
414 G4double weight=(*protonCurrentCollection)[i]->GetWeight();
415 fProton_current->
fill(ekin,weight);
418 for (i=0;i<gammaCurrentCollection->
entries();i++) {
419 G4double ekin =(*gammaCurrentCollection)[i]->GetValue();
420 G4double weight=(*gammaCurrentCollection)[i]->GetWeight();
421 fGamma_current->
fill(ekin,weight);
428 void RMC01AnalysisManager::EndOfEventForAdjointSimulation(
461 if (pdg_nb== fPrimPDG_ID && prim_ekin>= fEmin_prim_spectrum
462 && prim_ekin<= fEmax_prim_spectrum)
464 adj_weight*PrimDiffAndDirFluxForAdjointSim(prim_ekin);
474 edep_rmatrix = fEdep_rmatrix_vs_electron_prim_energy;
476 electron_current_rmatrix = fElectron_current_rmatrix_vs_electron_prim_energy;
478 gamma_current_rmatrix = fGamma_current_rmatrix_vs_electron_prim_energy;
482 edep_rmatrix = fEdep_rmatrix_vs_gamma_prim_energy;
483 electron_current_rmatrix = fElectron_current_rmatrix_vs_gamma_prim_energy;
484 gamma_current_rmatrix = fGamma_current_rmatrix_vs_gamma_prim_energy;
487 edep_rmatrix = fEdep_rmatrix_vs_proton_prim_energy;
488 electron_current_rmatrix = fElectron_current_rmatrix_vs_proton_prim_energy;
489 gamma_current_rmatrix = fGamma_current_rmatrix_vs_proton_prim_energy;
490 proton_current_rmatrix = fProton_current_rmatrix_vs_proton_prim_energy;
497 for (i=0;i<edepCollection->
entries();i++)
498 totEdep+=(*edepCollection)[i]->GetValue()*
499 (*edepCollection)[i]->GetWeight();
501 G4bool new_mean_computed=
false;
503 if (normalised_weight>0.){
510 fAccumulated_edep +=
edep;
511 fAccumulated_edep2 +=edep*
edep;
513 ComputeMeanEdepAndError(anEvent,new_mean,new_error);
515 if ( new_error >0) new_relative_error = new_error/ new_mean;
516 if (fRelative_error <0.10 && new_relative_error>1.5*fRelative_error) {
517 G4cout<<
"Potential wrong adjoint weight!"<<std::endl;
518 G4cout<<
"The results of this event will not be registered!"
520 G4cout<<
"previous mean edep [MeV] "<< fMean_edep<<std::endl;
521 G4cout<<
"previous relative error "<< fRelative_error<<std::endl;
522 G4cout<<
"new rejected mean edep [MeV] "<< new_mean<<std::endl;
523 G4cout<<
"new rejected relative error "<< new_relative_error
525 fAccumulated_edep -=
edep;
526 fAccumulated_edep2 -=edep*
edep;
530 fMean_edep = new_mean;
531 fError_mean_edep = new_error;
532 fRelative_error =new_relative_error;
533 new_mean_computed=
true;
535 fEdep_vs_prim_ekin->
fill(prim_ekin,edep);
541 edep_rmatrix->
fill(prim_ekin,totEdep*adj_weight/
cm2);
543 if (!new_mean_computed){
544 ComputeMeanEdepAndError(anEvent,fMean_edep,fError_mean_edep);
545 if (fError_mean_edep>0) fRelative_error= fError_mean_edep/fMean_edep;
552 for (i=0;i<electronCurrentCollection->
entries();i++) {
553 G4double ekin =(*electronCurrentCollection)[i]->GetValue();
554 G4double weight=(*electronCurrentCollection)[i]->GetWeight();
555 fElectron_current->
fill(ekin,weight*normalised_weight);
556 electron_current_rmatrix->
fill(prim_ekin,ekin,weight*adj_weight/
cm2);
559 for (i=0;i<protonCurrentCollection->
entries();i++) {
560 G4double ekin =(*protonCurrentCollection)[i]->GetValue();
561 G4double weight=(*protonCurrentCollection)[i]->GetWeight();
562 fProton_current->
fill(ekin,weight*normalised_weight);
563 proton_current_rmatrix->
fill(prim_ekin,ekin,weight*adj_weight/
cm2);
566 for (i=0;i<gammaCurrentCollection->
entries();i++) {
567 G4double ekin =(*gammaCurrentCollection)[i]->GetValue();
568 G4double weight=(*gammaCurrentCollection)[i]->GetWeight();
569 fGamma_current->
fill(ekin,weight*normalised_weight);
570 gamma_current_rmatrix->
fill(prim_ekin,ekin,weight*adj_weight/
cm2);
577 G4double RMC01AnalysisManager::PrimDiffAndDirFluxForAdjointSim(
580 G4double flux=fAmplitude_prim_spectrum;
581 if ( fPrimSpectrumType ==
EXPO) flux*=std::exp(-prim_energy/fAlpha_or_E0);
582 else flux*=std::pow(prim_energy, -fAlpha_or_E0);
588 void RMC01AnalysisManager::WriteHisto(
Histo1DVar* anHisto,
590 { std::fstream FileOutput(fileName, std::ios::out);
591 FileOutput<<header_lines;
592 FileOutput.setf(std::ios::scientific);
593 FileOutput.precision(6);
595 for (
size_t i =0;i<nxbins;i++) {
599 <<
'\t'<<anHisto->
get_bin_error(
int(i))*scaling_factor<<std::endl;
605 void RMC01AnalysisManager::WriteHisto(
Histo2DVar* anHisto,
607 { std::fstream FileOutput(fileName, std::ios::out);
608 FileOutput<<header_lines;
610 FileOutput.setf(std::ios::scientific);
611 FileOutput.precision(6);
615 for (
size_t i =0;i<nxbins;i++) {
616 for (
size_t j =0;j<nybins;j++) {
630 void RMC01AnalysisManager::ResetHistograms()
631 { fEdep_vs_prim_ekin->
reset();
632 fElectron_current->
reset();
633 fProton_current->
reset();
634 fGamma_current->
reset();
636 fEdep_rmatrix_vs_electron_prim_energy->
reset();
637 fElectron_current_rmatrix_vs_electron_prim_energy->
reset();
638 fGamma_current_rmatrix_vs_electron_prim_energy->
reset();
640 fEdep_rmatrix_vs_gamma_prim_energy->
reset();
641 fElectron_current_rmatrix_vs_gamma_prim_energy->
reset();
642 fGamma_current_rmatrix_vs_gamma_prim_energy->
reset();
644 fEdep_rmatrix_vs_proton_prim_energy->
reset();
645 fElectron_current_rmatrix_vs_proton_prim_energy->
reset();
646 fProton_current_rmatrix_vs_proton_prim_energy->
reset();
647 fGamma_current_rmatrix_vs_proton_prim_energy->
reset();
652 void RMC01AnalysisManager::ComputeMeanEdepAndError(
657 if (fAdjoint_sim_mode) {
658 nb_event /=fNb_evt_per_adj_evt;
664 mean = fAccumulated_edep/nb_event;
665 G4double mean_x2 =fAccumulated_edep2/nb_event;
666 error = factor*std::sqrt(mean_x2-mean*mean)/std::sqrt(
G4double(nb_event));
679 { fPrimSpectrumType =
EXPO;
680 if (particle_name ==
"e-" ) fPrimPDG_ID =
682 else if (particle_name ==
"gamma") fPrimPDG_ID =
684 else if (particle_name ==
"proton") fPrimPDG_ID =
687 G4cout<<
"The particle that you did select is not in the candidate list for primary [e-, gamma, proton]!"<<
G4endl;
691 fAmplitude_prim_spectrum = omni_fluence/E0/
692 (std::exp(-Emin/E0)-std::exp(-Emax/E0))/4./
pi;
693 fEmin_prim_spectrum = Emin ;
694 fEmax_prim_spectrum = Emax;
702 { fPrimSpectrumType =
POWER;
703 if (particle_name ==
"e-" ) fPrimPDG_ID =
705 else if (particle_name ==
"gamma") fPrimPDG_ID =
707 else if (particle_name ==
"proton") fPrimPDG_ID =
710 G4cout<<
"The particle that you did select is not in the candidate list for primary [e-, gamma, proton]!"<<
G4endl;
716 fAmplitude_prim_spectrum = omni_fluence/std::log(Emax/Emin)/4./
pi;
720 fAmplitude_prim_spectrum = omni_fluence/p/(std::pow(Emax,p)
721 -std::pow(Emin,p))/4./
pi;
724 fAlpha_or_E0 =
alpha ;
725 fEmin_prim_spectrum = Emin ;
726 fEmax_prim_spectrum = Emax;