46 #include "G4THitsCollection.hh"
60 RMC01AnalysisManager::RMC01AnalysisManager()
61 :fAccumulated_edep(0.), fAccumulated_edep2(0.), fMean_edep(0.),
62 fError_mean_edep(0.), fRelative_error(0.), fElapsed_time(0.),
63 fPrecision_to_reach(0.),fStop_run_if_precision_reached(true),
64 fNb_evt_modulo_for_convergence_test(5000),
65 fEdep_rmatrix_vs_electron_prim_energy(0),
66 fElectron_current_rmatrix_vs_electron_prim_energy(0),
67 fGamma_current_rmatrix_vs_electron_prim_energy(0),
68 fEdep_rmatrix_vs_gamma_prim_energy(0),
69 fElectron_current_rmatrix_vs_gamma_prim_energy(0),
70 fGamma_current_rmatrix_vs_gamma_prim_energy(0),
71 fEdep_rmatrix_vs_proton_prim_energy(0),
72 fElectron_current_rmatrix_vs_proton_prim_energy(0),
73 fProton_current_rmatrix_vs_proton_prim_energy(0),
74 fGamma_current_rmatrix_vs_proton_prim_energy(0),
76 fPrimSpectrumType(
EXPO),
77 fAlpha_or_E0(.5*
MeV),fAmplitude_prim_spectrum (1.),
78 fEmin_prim_spectrum(1.*
keV),fEmax_prim_spectrum (20.*
MeV),
79 fAdjoint_sim_mode(true),fNb_evt_per_adj_evt(2)
119 fAccumulated_edep =0.;
120 fAccumulated_edep2 =0.;
127 if (fAdjoint_sim_mode){
130 fConvergenceFileOutput.open(
"ConvergenceOfAdjointSimulationResults.txt",
132 fConvergenceFileOutput<<
133 "Normalised Edep[MeV]\terror[MeV]\tcomputing_time[s]"<<std::endl;
136 fConvergenceFileOutput.open(
"ConvergenceOfForwardSimulationResults.txt",
138 fConvergenceFileOutput<<
139 "Edep per event [MeV]\terror[MeV]\tcomputing_time[s]"
142 fConvergenceFileOutput.setf(std::ios::scientific);
143 fConvergenceFileOutput.precision(6);
157 if (!fAdjoint_sim_mode){
158 G4cout<<
"Results of forward simulation!"<<std::endl;
159 G4cout<<
"edep per event [MeV] = "<<fMean_edep<<std::endl;
160 G4cout<<
"error[MeV] = "<<fError_mean_edep<<std::endl;
164 G4cout<<
"Results of reverse/adjoint simulation!"<<std::endl;
165 G4cout<<
"normalised edep [MeV] = "<<fMean_edep<<std::endl;
166 G4cout<<
"error[MeV] = "<<fError_mean_edep<<std::endl;
171 fConvergenceFileOutput.close();
184 if (fAdjoint_sim_mode) EndOfEventForAdjointSimulation(anEvent);
185 else EndOfEventForForwardSimulation(anEvent);
191 if (fAdjoint_sim_mode) {
192 G4double n_adj_evt= nb_event/fNb_evt_per_adj_evt;
194 if (n_adj_evt*fNb_evt_per_adj_evt == nb_event) {
195 nb_event =
static_cast<G4int>(n_adj_evt);
200 if (nb_event>100 && fStop_run_if_precision_reached &&
201 fPrecision_to_reach >fRelative_error) {
202 G4cout<<fPrecision_to_reach*100.<<
"% Precision reached!"<<std::endl;
205 fConvergenceFileOutput<<fMean_edep<<
'\t'<<fError_mean_edep
206 <<
'\t'<<fElapsed_time<<std::endl;
210 if (nb_event>0 && nb_event % fNb_evt_modulo_for_convergence_test == 0) {
214 fConvergenceFileOutput<<fMean_edep<<
'\t'<<fError_mean_edep<<
'\t'
215 <<fElapsed_time<<std::endl;
221 void RMC01AnalysisManager::EndOfEventForForwardSimulation(
247 for (i=0;i<edepCollection->
entries();i++)
248 totEdep+=(*edepCollection)[i]->GetValue()
249 *(*edepCollection)[i]->GetWeight();
252 fAccumulated_edep +=totEdep ;
253 fAccumulated_edep2 +=totEdep*totEdep;
259 G4double prim_ekin =std::sqrt(E0*E0+P*P)-E0;
260 fEdep_vs_prim_ekin->fill(prim_ekin,totEdep);
262 ComputeMeanEdepAndError(anEvent,fMean_edep,fError_mean_edep);
263 if (fError_mean_edep>0) fRelative_error= fError_mean_edep/fMean_edep;
268 for (i=0;i<electronCurrentCollection->
entries();i++) {
269 G4double ekin =(*electronCurrentCollection)[i]->GetValue();
270 G4double weight=(*electronCurrentCollection)[i]->GetWeight();
271 fElectron_current->fill(ekin,weight);
274 for (i=0;i<protonCurrentCollection->
entries();i++) {
275 G4double ekin =(*protonCurrentCollection)[i]->GetValue();
276 G4double weight=(*protonCurrentCollection)[i]->GetWeight();
277 fProton_current->fill(ekin,weight);
280 for (i=0;i<gammaCurrentCollection->
entries();i++) {
281 G4double ekin =(*gammaCurrentCollection)[i]->GetValue();
282 G4double weight=(*gammaCurrentCollection)[i]->GetWeight();
283 fGamma_current->fill(ekin,weight);
290 void RMC01AnalysisManager::EndOfEventForAdjointSimulation(
317 for (i=0;i<edepCollection->
entries();i++)
318 totEdep+=(*edepCollection)[i]->GetValue()*
319 (*edepCollection)[i]->GetWeight();
327 size_t nb_adj_track =
329 G4double total_normalised_weight = 0.;
333 for (
size_t j=0;j<nb_adj_track;j++) {
334 G4int pdg_nb =theAdjointSimManager
336 G4double prim_ekin=theAdjointSimManager
338 G4double adj_weight=theAdjointSimManager
345 if (pdg_nb== fPrimPDG_ID && prim_ekin>= fEmin_prim_spectrum
346 && prim_ekin<= fEmax_prim_spectrum)
348 adj_weight*PrimDiffAndDirFluxForAdjointSim(prim_ekin);
349 total_normalised_weight += normalised_weight;
354 G4AnaH2* electron_current_rmatrix =0;
355 G4AnaH2* gamma_current_rmatrix =0;
356 G4AnaH2* proton_current_rmatrix =0;
359 edep_rmatrix = fEdep_rmatrix_vs_electron_prim_energy;
360 electron_current_rmatrix =
361 fElectron_current_rmatrix_vs_electron_prim_energy;
362 gamma_current_rmatrix = fGamma_current_rmatrix_vs_electron_prim_energy;
366 edep_rmatrix = fEdep_rmatrix_vs_gamma_prim_energy;
367 electron_current_rmatrix = fElectron_current_rmatrix_vs_gamma_prim_energy;
368 gamma_current_rmatrix = fGamma_current_rmatrix_vs_gamma_prim_energy;
372 edep_rmatrix = fEdep_rmatrix_vs_proton_prim_energy;
373 electron_current_rmatrix =
374 fElectron_current_rmatrix_vs_proton_prim_energy;
375 gamma_current_rmatrix = fGamma_current_rmatrix_vs_proton_prim_energy;
376 proton_current_rmatrix = fProton_current_rmatrix_vs_proton_prim_energy;
380 if (normalised_weight>0) fEdep_vs_prim_ekin
381 ->fill(prim_ekin,totEdep*normalised_weight);
384 edep_rmatrix->fill(prim_ekin,totEdep*adj_weight/
cm2);
389 for (i=0;i<electronCurrentCollection->
entries();i++) {
390 G4double ekin =(*electronCurrentCollection)[i]->GetValue();
391 G4double weight=(*electronCurrentCollection)[i]->GetWeight();
392 fElectron_current->fill(ekin,weight*normalised_weight);
393 electron_current_rmatrix->fill(prim_ekin,ekin,weight*adj_weight/
cm2);
395 for (i=0;i<protonCurrentCollection->
entries();i++) {
396 G4double ekin =(*protonCurrentCollection)[i]->GetValue();
397 G4double weight=(*protonCurrentCollection)[i]->GetWeight();
398 fProton_current->fill(ekin,weight*normalised_weight);
399 proton_current_rmatrix->fill(prim_ekin,ekin,weight*adj_weight/
cm2);
401 for (i=0;i<gammaCurrentCollection->
entries();i++) {
402 G4double ekin =(*gammaCurrentCollection)[i]->GetValue();
403 G4double weight=(*gammaCurrentCollection)[i]->GetWeight();
404 fGamma_current->fill(ekin,weight*normalised_weight);
405 gamma_current_rmatrix->fill(prim_ekin,ekin,weight*adj_weight/
cm2);
411 G4bool new_mean_computed=
false;
413 if (total_normalised_weight>0.){
414 G4double edep=totEdep* total_normalised_weight;
419 fAccumulated_edep +=edep;
420 fAccumulated_edep2 +=edep*edep;
422 ComputeMeanEdepAndError(anEvent,new_mean,new_error);
424 if ( new_error >0) new_relative_error = new_error/ new_mean;
425 if (fRelative_error <0.10 && new_relative_error>1.5*fRelative_error) {
426 G4cout<<
"Potential wrong adjoint weight!"<<std::endl;
427 G4cout<<
"The results of this event will not be registered!"
429 G4cout<<
"previous mean edep [MeV] "<< fMean_edep<<std::endl;
430 G4cout<<
"previous relative error "<< fRelative_error<<std::endl;
431 G4cout<<
"new rejected mean edep [MeV] "<< new_mean<<std::endl;
432 G4cout<<
"new rejected relative error "<< new_relative_error
434 fAccumulated_edep -=edep;
435 fAccumulated_edep2 -=edep*edep;
440 fMean_edep = new_mean;
441 fError_mean_edep = new_error;
442 fRelative_error =new_relative_error;
443 new_mean_computed=
true;
447 if (!new_mean_computed){
448 ComputeMeanEdepAndError(anEvent,fMean_edep,fError_mean_edep);
449 if (fError_mean_edep>0) fRelative_error= fError_mean_edep/fMean_edep;
456 G4double RMC01AnalysisManager::PrimDiffAndDirFluxForAdjointSim(
459 G4double flux=fAmplitude_prim_spectrum;
460 if ( fPrimSpectrumType ==
EXPO) flux*=std::exp(-prim_energy/fAlpha_or_E0);
461 else flux*=std::pow(prim_energy, -fAlpha_or_E0);
507 void RMC01AnalysisManager::ComputeMeanEdepAndError(
512 if (fAdjoint_sim_mode) {
513 nb_event /=fNb_evt_per_adj_evt;
523 if (nb_event_float >1.) {
524 mean = fAccumulated_edep/nb_event_float;
525 G4double mean_x2 = fAccumulated_edep2/nb_event_float;
531 error = factor*std::sqrt(mean_x2-mean*mean)/std::sqrt(nb_event_float);
546 { fPrimSpectrumType =
EXPO;
547 if (particle_name ==
"e-" ) fPrimPDG_ID =
549 else if (particle_name ==
"gamma") fPrimPDG_ID =
551 else if (particle_name ==
"proton") fPrimPDG_ID =
554 G4cout<<
"The particle that you did select is not in the candidate "<<
555 "list for primary [e-, gamma, proton]!"<<
G4endl;
559 fAmplitude_prim_spectrum = omni_fluence/E0/
560 (std::exp(-Emin/E0)-std::exp(-Emax/E0))/4./
pi;
561 fEmin_prim_spectrum =
Emin ;
562 fEmax_prim_spectrum =
Emax;
570 { fPrimSpectrumType =
POWER;
571 if (particle_name ==
"e-" ) fPrimPDG_ID =
573 else if (particle_name ==
"gamma") fPrimPDG_ID =
575 else if (particle_name ==
"proton") fPrimPDG_ID =
578 G4cout<<
"The particle that you did select is not in the candidate"<<
579 " list for primary [e-, gamma, proton]!"<<
G4endl;
585 fAmplitude_prim_spectrum = omni_fluence/std::log(Emax/Emin)/4./
pi;
589 fAmplitude_prim_spectrum = omni_fluence/p/(std::pow(Emax,p)
590 -std::pow(Emin,p))/4./
pi;
593 fAlpha_or_E0 =
alpha ;
594 fEmin_prim_spectrum =
Emin ;
595 fEmax_prim_spectrum =
Emax;
613 fFileName[0]=
"forward_sim";
614 if (fAdjoint_sim_mode) fFileName[0]=
"adjoint_sim";
619 fFileName[1] = fFileName[0] +
"." + extension;
624 G4cout <<
"\n---> RMC01AnalysisManager::Book(): cannot open "
640 G4String(
"edep vs e- primary energy"),60,emin,emax,
642 fEdep_vs_prim_ekin = theHistoManager->
GetH1(idHisto);
648 fElectron_current = theHistoManager->
GetH1(idHisto);
653 fProton_current=theHistoManager->
GetH1(idHisto);
658 fGamma_current=theHistoManager->
GetH1(idHisto);
662 if (fAdjoint_sim_mode){
668 G4String(
"electron RM vs e- primary energy"),60,emin,emax,
670 fEdep_rmatrix_vs_electron_prim_energy = theHistoManager->
GetH1(idHisto);
674 CreateH2(
G4String(
"Electron_current_rmatrix_vs_electron_prim_energy"),
675 G4String(
"electron current RM vs e- primary energy"),
676 60,emin,emax,60,emin,emax,
679 fElectron_current_rmatrix_vs_electron_prim_energy =
680 theHistoManager->
GetH2(idHisto);
684 CreateH2(
G4String(
"Gamma_current_rmatrix_vs_electron_prim_energy"),
685 G4String(
"gamma current RM vs e- primary energy"),
686 60,emin,emax,60,emin,emax,
689 fGamma_current_rmatrix_vs_electron_prim_energy =
690 theHistoManager->
GetH2(idHisto);
696 G4String(
"electron RM vs gamma primary energy"),60,emin,emax,
698 fEdep_rmatrix_vs_gamma_prim_energy = theHistoManager->
GetH1(idHisto);
702 CreateH2(
G4String(
"Electron_current_rmatrix_vs_gamma_prim_energy"),
703 G4String(
"electron current RM vs gamma primary energy"),
704 60,emin,emax,60,emin,emax,
707 fElectron_current_rmatrix_vs_gamma_prim_energy =
708 theHistoManager->
GetH2(idHisto);
712 CreateH2(
G4String(
"Gamma_current_rmatrix_vs_gamma_prim_energy"),
713 G4String(
"gamma current RM vs gamma primary energy"),
714 60,emin,emax,60,emin,emax,
717 fGamma_current_rmatrix_vs_gamma_prim_energy =
718 theHistoManager->
GetH2(idHisto);
723 G4String(
"electron RM vs proton primary energy"),60,emin,emax,
725 fEdep_rmatrix_vs_proton_prim_energy = theHistoManager->
GetH1(idHisto);
729 CreateH2(
G4String(
"Electron_current_rmatrix_vs_proton_prim_energy"),
730 G4String(
"electron current RM vs proton primary energy"),
731 60,emin,emax,60,emin,emax,
734 fElectron_current_rmatrix_vs_proton_prim_energy =
735 theHistoManager->
GetH2(idHisto);
739 CreateH2(
G4String(
"Gamma_current_rmatrix_vs_proton_prim_energy"),
740 G4String(
"gamma current RM vs proton primary energy"),
741 60,emin,emax,60,emin,emax,
744 fGamma_current_rmatrix_vs_proton_prim_energy =
745 theHistoManager->
GetH2(idHisto);
749 CreateH2(
G4String(
"Proton_current_rmatrix_vs_proton_prim_energy"),
750 G4String(
"proton current RM vs proton primary energy"),
751 60,emin,emax,60,emin,emax,
754 fProton_current_rmatrix_vs_proton_prim_energy =
755 theHistoManager->
GetH2(idHisto);
758 G4cout <<
"\n----> Histogram Tree is opened in " << fFileName[1] <<
G4endl;
769 for (
int ind=1; ind<=theHistoManager->
GetNofH1s();ind++){
771 theHistoManager->
ScaleH1(ind,scaling_factor);
773 for (
int ind=1; ind<=theHistoManager->
GetNofH2s();ind++)
774 theHistoManager->
ScaleH2(ind,scaling_factor);
776 theHistoManager->
Write();
778 G4cout <<
"\n----> Histogram Tree is saved in " << fFileName[1] <<
G4endl;
780 delete G4AnalysisManager::Instance();
static G4AdjointSimManager * GetInstance()
G4bool SetHistoDirectoryName(const G4String &dirName)
virtual void AbortRun(G4bool softAbort=false)
void SetPrimaryPowerLawSpectrumForAdjointSim(const G4String &particle_name, G4double fluence, G4double alpha, G4double Emin, G4double Emax)
G4ThreeVector GetMomentum() const
G4bool SetFirstHistoId(G4int firstId)
G4VHitsCollection * GetHC(G4int i)
G4int GetCollectionID(G4String colName)
G4int CreateH1(const G4String &name, const G4String &title, G4int nbins, G4double xmin, G4double xmax, const G4String &unitName="none", const G4String &fcnName="none", const G4String &binSchemeName="linear")
static constexpr double cm2
G4bool ScaleH1(G4int id, G4double factor)
G4bool ScaleH2(G4int id, G4double factor)
G4bool GetAdjointSimMode()
G4int GetPDGEncoding() const
void SetPrimaryExpSpectrumForAdjointSim(const G4String &particle_name, G4double fluence, G4double E0, G4double Emin, G4double Emax)
void BeginOfEvent(const G4Event *)
G4bool OpenFile(const G4String &fileName="")
G4ParticleDefinition * GetG4code() const
G4int GetNbEvtOfLastRun()
Definition of the RMC01SD class.
G4PrimaryParticle * GetPrimary(G4int i=0) const
void SetH1Ascii(G4int id, G4bool ascii)
G4GLOB_DLL std::ostream G4cout
G4int GetNumberOfEvent() const
G4String GetFileType() const
static G4Proton * Proton()
void EndOfRun(const G4Run *)
G4PrimaryVertex * GetPrimaryVertex(G4int i=0) const
Definition of the RMC01AnalysisManager class.
G4double GetWeightAtEndOfLastAdjointTrack(size_t i=0)
static const G4double emax
void Save(G4double scaling_factor)
static G4RunManager * GetRunManager()
Definition of the RMC01AnalysisManagerMessenger class.
G4double GetPDGMass() const
G4double GetRealElapsed() const
static RMC01AnalysisManager * GetInstance()
static G4SDManager * GetSDMpointer()
void EndOfEvent(const G4Event *)
void BeginOfRun(const G4Run *)
static constexpr double GeV
static const G4double Emin
G4int GetFwdParticlePDGEncodingAtEndOfLastAdjointTrack(size_t i=0)
G4int GetNumberOfEventToBeProcessed() const
static G4Electron * Electron()
static const G4double Emax
static constexpr double MeV
tools::histo::h1d G4AnaH1
static constexpr double pi
static PROLOG_HANDLER error
tools::histo::h2d G4AnaH2
G4HCofThisEvent * GetHCofThisEvent() const
static const G4double alpha
static constexpr double keV
G4double GetEkinAtEndOfLastAdjointTrack(size_t i=0)
size_t GetNbOfAdointTracksReachingTheExternalSurface()