00001
00002
00003
00004
00005
00006 #include "RunAction.hh"
00007 #include "DetectorConstruction.hh"
00008
00009 #include "G4Run.hh"
00010 #include "G4RunManager.hh"
00011 #include "G4UnitsTable.hh"
00012
00013 #include <iomanip>
00014
00015
00016
00017 RunAction::RunAction(DetectorConstruction* det)
00018 :m_detector(det)
00019 { }
00020
00021
00022
00023 RunAction::~RunAction()
00024 { }
00025
00026
00027
00028 void RunAction::BeginOfRunAction(const G4Run* run)
00029 {
00030 G4cout << "### Run " << run->GetRunID() << " start." << G4endl;
00031
00032
00033
00034 m_sumEdep = m_sumEdep2 = 0.;
00035 m_nbEntry = 0;
00036
00037
00038
00039 m_nbSlices = 100;
00040 m_astronautHeight = m_detector->GetAstronautHeight();
00041 m_sliceWidth = m_astronautHeight/m_nbSlices;
00042 m_depthDose.resize(m_nbSlices, 0.);
00043 m_depthDoseSD .resize(m_nbSlices, 0.);
00044 m_depthTotalEkin.resize(m_nbSlices, 0.);
00045 m_depthNbProton .resize(m_nbSlices, 0 );
00046
00047 }
00048
00049
00050
00051 void RunAction::SumDepthDose(G4double zLocal, G4double edep)
00052 {
00053
00054 if (zLocal > m_astronautHeight) {
00055 G4cout << "\n --> warning from RunAction::SumDepthDose() : "
00056 << " zLocal beyond astronaut height : " << zLocal/mm << G4endl;
00057 return;
00058 }
00059
00060
00061 G4int k = int(zLocal/m_sliceWidth);
00062
00063
00064 m_depthDose[k] += edep;
00065 }
00066
00067
00068 void RunAction::SumDepthDoseSD(G4double zLocal, G4double edep)
00069 {
00070
00071 if (zLocal > m_astronautHeight) {
00072 G4cout << "\n --> warning from RunAction::SumDepthDose() : "
00073 << " zLocal beyond astronaut height : " << zLocal/mm << G4endl;
00074 return;
00075 }
00076
00077
00078 G4int k = int(zLocal/m_sliceWidth);
00079
00080
00081 m_depthDoseSD[k] += edep;
00082 }
00083
00084
00085 void RunAction::SumDepthDoseSD(G4int k, G4double edep, G4int nbProton, G4double totalEkin)
00086 {
00087
00088 if (k >= m_nbSlices) {
00089 G4cout << "\n --> warning from RunAction::SumDepthDoseSD() : "
00090 << " k beyond nb slices : " << k << G4endl;
00091 return;
00092 }
00093
00094
00095 m_depthDoseSD[k] += edep;
00096 m_depthNbProton[k] += nbProton;
00097 m_depthTotalEkin[k] += totalEkin;
00098 }
00099
00100
00101 G4int RunAction::GetSliceNumber(G4double zLocal) const
00102 {
00103
00104 G4int k = int(zLocal/m_sliceWidth);
00105
00106
00107 if (k >= m_nbSlices) {
00108 G4cout << "\n --> warning from RunAction::GetSliceNumber() : "
00109 << " k beyond nb slices : " << k << " returning -1" << G4endl;
00110 k = -1;
00111 }
00112
00113 return k;
00114 }
00115
00116
00117
00118 void RunAction::EndOfRunAction(const G4Run*)
00119 {
00120 G4double meanEd = 0., meanEd2 = 0., rmsEd = 0., error_rel_sum = 0.;
00121 if (m_nbEntry) {
00122 meanEd = m_sumEdep/m_nbEntry; meanEd2 = m_sumEdep2/m_nbEntry;
00123 G4double variance = meanEd2 - meanEd*meanEd;
00124 if (variance > 0.) rmsEd = std::sqrt(variance);
00125 error_rel_sum = rmsEd/(meanEd*std::sqrt(double(m_nbEntry)));
00126 }
00127
00128
00129 std::ios::fmtflags mode = G4cout.flags();
00130 G4cout.setf(std::ios::fixed,std::ios::floatfield);
00131 G4int prec = G4cout.precision(3);
00132
00133
00134
00135 G4cout
00136 << "\n ---> Nb of non-empty events = " << m_nbEntry
00137 << "\n ---> Mean Edep per event = " << G4BestUnit(meanEd,"Energy")
00138 << "\n ---> Total Energy deposited = " << G4BestUnit(m_sumEdep,"Energy")
00139 << " +- " << G4BestUnit(m_sumEdep*error_rel_sum,"Energy")
00140 << " (-> " << 100*error_rel_sum << " %)"
00141 << G4endl;
00142
00143
00144
00145 G4double mass = m_detector->GetAstronaut()->GetLogicalVolume()->GetMass();
00146
00147
00148
00149 G4double dose = m_sumEdep/mass;
00150 G4cout.setf(mode,std::ios::floatfield);
00151 G4cout.precision(5);
00152 G4cout << " ---> Dose = " << G4BestUnit(dose,"Dose")
00153 << " +- " << G4BestUnit(dose*error_rel_sum,"Dose") << "\n"
00154 << G4endl;
00155
00156
00157 G4cout.setf(mode,std::ios::floatfield);
00158 G4cout.precision(prec);
00159
00160
00161
00162 for (G4int k=0; k<m_nbSlices; k++) m_depthDose[k] /= mass;
00163
00164 for (G4int k=0; k<m_nbSlices; k++) m_depthDoseSD[k] /= mass;
00165
00166
00167
00168
00169
00170 WriteDepthDose("depthDose");
00171
00172
00173 G4cout.setf(mode,std::ios::floatfield);
00174 G4cout.precision(prec);
00175 }
00176
00177
00178
00179 #include <fstream>
00180
00181 void RunAction::WriteDepthDose(G4String name)
00182 {
00183 G4String fileName = name + ".ascii";
00184 std::ofstream File(fileName, std::ios::out);
00185
00186 G4String fileNameSD = name + "SD"+ ".ascii";
00187 std::ofstream FileSD(fileNameSD, std::ios::out);
00188
00189 std::ios::fmtflags mode = File.flags();
00190 File.setf( std::ios::scientific, std::ios::floatfield );
00191 G4int prec = File.precision(4);
00192
00193 std::ios::fmtflags modeSD = FileSD.flags();
00194 FileSD.setf( std::ios::scientific, std::ios::floatfield );
00195 G4int precSD = FileSD.precision(4);
00196
00197 File << " Longitudinal depth dose distribution \n "
00198 << "\n zLocal (mm)\t m_depthDose(gray) \n" << G4endl;
00199
00200 FileSD << " Longitudinal depth dose distribution \n "
00201 << "\n zLocal (mm)\t Dose(gray) \t #proton \t <eKin> (MeV) \n" << G4endl;
00202
00203 G4double zLocal;
00204 for (G4int k=0; k<m_nbSlices; k++) {
00205 zLocal = (k+0.5)*m_sliceWidth;
00206 File << " " << zLocal/mm
00207 << "\t " << m_depthDose[k]/gray << G4endl;
00208 }
00209
00210
00211 for (G4int k=0; k<m_nbSlices; k++) {
00212 zLocal = (k+0.5)*m_sliceWidth;
00213 G4double meanEkin(-1.*MeV);
00214 if (m_depthNbProton[k]>0) meanEkin = m_depthTotalEkin[k]/m_depthNbProton[k];
00215 FileSD << " " << zLocal/mm
00216 << "\t " << m_depthDoseSD[k]/gray
00217 << "\t " << m_depthNbProton[k]
00218 << "\t " << meanEkin / MeV
00219 << G4endl;
00220 }
00221
00222
00223 File.setf(mode,std::ios::floatfield);
00224 File.precision(prec);
00225
00226 FileSD.setf(modeSD,std::ios::floatfield);
00227 FileSD.precision(precSD);
00228
00229 }
00230
00231
00232