Changeset 1313 for trunk/examples/advanced/hadrontherapy/src
- Timestamp:
- Jun 14, 2010, 3:54:58 PM (15 years ago)
- Location:
- trunk/examples/advanced/hadrontherapy/src
- Files:
-
- 10 edited
-
HadrontherapyAnalysisManager.cc (modified) (2 diffs)
-
HadrontherapyDetectorConstruction.cc (modified) (7 diffs)
-
HadrontherapyDetectorMessenger.cc (modified) (9 diffs)
-
HadrontherapyEventAction.cc (modified) (4 diffs)
-
HadrontherapyMatrix.cc (modified) (1 diff)
-
HadrontherapyPhysicsList.cc (modified) (7 diffs)
-
HadrontherapyPhysicsListMessenger.cc (modified) (4 diffs)
-
HadrontherapyPrimaryGeneratorAction.cc (modified) (5 diffs)
-
HadrontherapyRunAction.cc (modified) (4 diffs)
-
HadrontherapySteppingAction.cc (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/examples/advanced/hadrontherapy/src/HadrontherapyAnalysisManager.cc
r1230 r1313 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: HadrontherapyAnalisysManager.cc;27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy1 // 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: HadrontherapyAnalisysManager.cc; 27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy 28 28 29 29 #include "HadrontherapyAnalysisManager.hh" … … 31 31 #include "HadrontherapyAnalysisFileMessenger.hh" 32 32 #include <time.h> 33 #ifdef ANALYSIS_USE 33 34 34 HadrontherapyAnalysisManager* HadrontherapyAnalysisManager::instance = 0; 35 35 36 #ifdef G4ANALYSIS_USE_ROOT 37 #undef G4ANALYSIS_USE 38 #endif 39 40 ///////////////////////////////////////////////////////////////////////////// 41 42 #ifdef G4ANALYSIS_USE 43 HadrontherapyAnalysisManager::HadrontherapyAnalysisManager() : 44 analysisFileName("DoseDistribution.root"), aFact(0), theTree(0), histFact(0), tupFact(0), h1(0), h2(0), h3(0), 45 h4(0), h5(0), h6(0), h7(0), h8(0), h9(0), h10(0), h11(0), h12(0), h13(0), h14(0), h15(0), h16(0), ntuple(0), 46 ionTuple(0), 47 fragmentTuple(0), 48 eventCounter(0) 49 { 50 fMess = new HadrontherapyAnalysisFileMessenger(this); 51 } 52 #endif 53 #ifdef G4ANALYSIS_USE_ROOT 54 HadrontherapyAnalysisManager::HadrontherapyAnalysisManager() : 55 analysisFileName("DoseDistribution.root"),theTFile(0), histo1(0), histo2(0), histo3(0), 56 histo4(0), histo5(0), histo6(0), histo7(0), histo8(0), histo9(0), histo10(0), histo11(0), histo12(0), histo13(0), histo14(0), histo15(0), histo16(0), 57 theROOTNtuple(0), 58 theROOTIonTuple(0), 59 fragmentNtuple(0), 60 metaData(0), 61 eventCounter(0) 62 { 63 fMess = new HadrontherapyAnalysisFileMessenger(this); 36 HadrontherapyAnalysisManager::HadrontherapyAnalysisManager(): 37 #ifdef G4ANALYSIS_USE_ROOT 38 analysisFileName("DoseDistribution.root"),theTFile(0), histo1(0), histo2(0), histo3(0), 39 histo4(0), histo5(0), histo6(0), histo7(0), histo8(0), histo9(0), histo10(0), histo11(0), histo12(0), histo13(0), histo14(0), histo15(0), histo16(0), 40 kinFragNtuple(0), 41 kineticEnergyPrimaryNtuple(0), 42 doseFragNtuple(0), 43 fluenceFragNtuple(0), 44 letFragNtuple(0), 45 theROOTNtuple(0), 46 theROOTIonTuple(0), 47 fragmentNtuple(0), 48 metaData(0), 49 eventCounter(0) 50 { 51 fMess = new HadrontherapyAnalysisFileMessenger(this); 64 52 } 65 53 #endif 66 54 ///////////////////////////////////////////////////////////////////////////// 55 67 56 HadrontherapyAnalysisManager::~HadrontherapyAnalysisManager() 68 57 { 69 delete(fMess); //kill the messenger 70 #ifdef G4ANALYSIS_USE 71 delete fragmentTuple; 72 fragmentTuple = 0; 73 74 delete ionTuple; 75 ionTuple = 0; 76 77 delete ntuple; 78 ntuple = 0; 79 80 delete h16; 81 h16 = 0; 82 83 delete h15; 84 h15 = 0; 85 86 delete h14; 87 h14 = 0; 88 89 delete h13; 90 h13 = 0; 91 92 delete h12; 93 h12 = 0; 94 95 delete h11; 96 h11 = 0; 97 98 delete h10; 99 h10 = 0; 100 101 delete h9; 102 h9 = 0; 103 104 delete h8; 105 h8 = 0; 106 107 delete h7; 108 h7 = 0; 109 110 delete h6; 111 h6 = 0; 112 113 delete h5; 114 h5 = 0; 115 116 delete h4; 117 h4 = 0; 118 119 delete h3; 120 h3 = 0; 121 122 delete h2; 123 h2 = 0; 124 125 delete h1; 126 h1 = 0; 127 128 delete tupFact; 129 tupFact = 0; 130 131 delete histFact; 132 histFact = 0; 133 134 delete theTree; 135 theTree = 0; 136 137 delete aFact; 138 aFact = 0; 58 delete(fMess); 59 #ifdef G4ANALYSIS_USE_ROOT 60 Clear(); 139 61 #endif 62 } 63 64 HadrontherapyAnalysisManager* HadrontherapyAnalysisManager::GetInstance() 65 { 66 if (instance == 0) instance = new HadrontherapyAnalysisManager; 67 return instance; 68 } 140 69 #ifdef G4ANALYSIS_USE_ROOT 141 delete metaData; 142 metaData = 0; 143 144 delete fragmentNtuple; 145 fragmentNtuple = 0; 146 147 delete theROOTIonTuple; 148 theROOTIonTuple = 0; 149 150 delete theROOTNtuple; 151 theROOTNtuple = 0; 152 153 delete histo16; 154 histo14 = 0; 155 156 delete histo15; 157 histo14 = 0; 158 159 delete histo14; 160 histo14 = 0; 161 162 delete histo13; 163 histo13 = 0; 164 165 delete histo12; 166 histo12 = 0; 167 168 delete histo11; 169 histo11 = 0; 170 171 delete histo10; 172 histo10 = 0; 173 174 delete histo9; 175 histo9 = 0; 176 177 delete histo8; 178 histo8 = 0; 179 180 delete histo7; 181 histo7 = 0; 182 183 delete histo6; 184 histo6 = 0; 185 186 delete histo5; 187 histo5 = 0; 188 189 delete histo4; 190 histo4 = 0; 191 192 delete histo3; 193 histo3 = 0; 194 195 delete histo2; 196 histo2 = 0; 197 198 delete histo1; 199 histo1 = 0; 70 void HadrontherapyAnalysisManager::Clear() 71 { 72 // XXX delete ALL variables!! 73 // but this seems to be automatically done by 74 // theTFile->Close() command! 75 // so we get a *double free or corruption* 76 77 delete metaData; 78 metaData = 0; 79 80 delete fragmentNtuple; 81 fragmentNtuple = 0; 82 83 delete theROOTIonTuple; 84 theROOTIonTuple = 0; 85 86 delete theROOTNtuple; 87 theROOTNtuple = 0; 88 89 delete histo16; 90 histo16 = 0; 91 92 delete histo15; 93 histo15 = 0; 94 95 delete histo14; 96 histo14 = 0; 97 98 delete histo13; 99 histo13 = 0; 100 101 delete histo12; 102 histo12 = 0; 103 104 delete histo11; 105 histo11 = 0; 106 107 delete histo10; 108 histo10 = 0; 109 110 delete histo9; 111 histo9 = 0; 112 113 delete histo8; 114 histo8 = 0; 115 116 delete histo7; 117 histo7 = 0; 118 119 delete histo6; 120 histo6 = 0; 121 122 delete histo5; 123 histo5 = 0; 124 125 delete histo4; 126 histo4 = 0; 127 128 delete histo3; 129 histo3 = 0; 130 131 delete histo2; 132 histo2 = 0; 133 134 delete histo1; 135 histo1 = 0; 136 } 137 ///////////////////////////////////////////////////////////////////////////// 138 139 void HadrontherapyAnalysisManager::SetAnalysisFileName(G4String aFileName) 140 { 141 this->analysisFileName = aFileName; 142 } 143 144 ///////////////////////////////////////////////////////////////////////////// 145 void HadrontherapyAnalysisManager::book() 146 { 147 delete theTFile; // this is similar to theTFile->Close() => delete all associated variables created via new, moreover it delete itself. 148 149 theTFile = new TFile(analysisFileName, "RECREATE"); 150 151 // Create the histograms with the energy deposit along the X axis 152 histo1 = createHistogram1D("braggPeak","slice, energy", 400, 0., 80); //<different waterthicknesses are accoutned for in ROOT-analysis stage 153 histo2 = createHistogram1D("h20","Secondary protons - slice, energy", 400, 0., 400.); 154 histo3 = createHistogram1D("h30","Secondary neutrons - slice, energy", 400, 0., 400.); 155 histo4 = createHistogram1D("h40","Secondary alpha - slice, energy", 400, 0., 400.); 156 histo5 = createHistogram1D("h50","Secondary gamma - slice, energy", 400, 0., 400.); 157 histo6 = createHistogram1D("h60","Secondary electron - slice, energy", 400, 0., 400.); 158 histo7 = createHistogram1D("h70","Secondary triton - slice, energy", 400, 0., 400.); 159 histo8 = createHistogram1D("h80","Secondary deuteron - slice, energy", 400, 0., 400.); 160 histo9 = createHistogram1D("h90","Secondary pion - slice, energy", 400, 0., 400.); 161 histo10 = createHistogram1D("h100","Energy distribution of secondary electrons", 70, 0., 70.); 162 histo11 = createHistogram1D("h110","Energy distribution of secondary photons", 70, 0., 70.); 163 histo12 = createHistogram1D("h120","Energy distribution of secondary deuterons", 70, 0., 70.); 164 histo13 = createHistogram1D("h130","Energy distribution of secondary tritons", 70, 0., 70.); 165 histo14 = createHistogram1D("h140","Energy distribution of secondary alpha particles", 70, 0., 70.); 166 histo15 = createHistogram1D("heliumEnergyAfterPhantom","Energy distribution of secondary helium fragments after the phantom", 167 70, 0., 500.); 168 histo16 = createHistogram1D("hydrogenEnergyAfterPhantom","Energy distribution of secondary helium fragments after the phantom", 169 70, 0., 500.); 170 171 kinFragNtuple = new TNtuple("kinFragNtuple", 172 "Kinetic energy by voxel & fragment", 173 "i:j:k:A:Z:kineticEnergy"); 174 kineticEnergyPrimaryNtuple= new TNtuple("kineticEnergyPrimaryNtuple", 175 "Kinetic energy by voxel of primary", 176 "i:j:k:kineticEnergy"); 177 doseFragNtuple = new TNtuple("doseFragNtuple", 178 "Energy deposit by voxel & fragment", 179 "i:j:k:A:Z:energy"); 180 181 fluenceFragNtuple = new TNtuple("fluenceFragNtuple", 182 "Fluence by voxel & fragment", 183 "i:j:k:A:Z:fluence"); 184 185 letFragNtuple = new TNtuple("letFragNtuple", 186 "Let by voxel & fragment", 187 "i:j:k:A:Z:letT:letD"); 188 189 theROOTNtuple = new TNtuple("theROOTNtuple", 190 "Energy deposit by slice", 191 "i:j:k:energy"); 192 193 theROOTIonTuple = new TNtuple("theROOTIonTuple", 194 "Generic ion information", 195 "a:z:occupancy:energy"); 196 197 fragmentNtuple = new TNtuple("fragmentNtuple", 198 "Fragments", 199 "A:Z:energy:posX:posY:posZ"); 200 201 metaData = new TNtuple("metaData", 202 "Metadata", 203 "events:detectorDistance:waterThickness:beamEnergy:energyError:phantomCenterDistance"); 204 } 205 206 ///////////////////////////////////////////////////////////////////////////// 207 void HadrontherapyAnalysisManager::FillEnergyDeposit(G4int i, 208 G4int j, 209 G4int k, 210 G4double energy) 211 { 212 if (theROOTNtuple) { 213 theROOTNtuple->Fill(i, j, k, energy); 214 } 215 } 216 217 ///////////////////////////////////////////////////////////////////////////// 218 void HadrontherapyAnalysisManager::BraggPeak(G4int slice, G4double energy) 219 { 220 histo1->SetBinContent(slice, energy); //This uses setbincontent instead of fill to get labels correct 221 } 222 223 ///////////////////////////////////////////////////////////////////////////// 224 void HadrontherapyAnalysisManager::SecondaryProtonEnergyDeposit(G4int slice, G4double energy) 225 { 226 histo2->Fill(slice, energy); 227 } 228 229 ///////////////////////////////////////////////////////////////////////////// 230 void HadrontherapyAnalysisManager::SecondaryNeutronEnergyDeposit(G4int slice, G4double energy) 231 { 232 histo3->Fill(slice, energy); 233 } 234 235 ///////////////////////////////////////////////////////////////////////////// 236 void HadrontherapyAnalysisManager::SecondaryAlphaEnergyDeposit(G4int slice, G4double energy) 237 { 238 histo4->Fill(slice, energy); 239 } 240 241 ///////////////////////////////////////////////////////////////////////////// 242 void HadrontherapyAnalysisManager::SecondaryGammaEnergyDeposit(G4int slice, G4double energy) 243 { 244 histo5->Fill(slice, energy); 245 } 246 247 ///////////////////////////////////////////////////////////////////////////// 248 void HadrontherapyAnalysisManager::SecondaryElectronEnergyDeposit(G4int slice, G4double energy) 249 { 250 histo6->Fill(slice, energy); 251 } 252 253 ///////////////////////////////////////////////////////////////////////////// 254 void HadrontherapyAnalysisManager::SecondaryTritonEnergyDeposit(G4int slice, G4double energy) 255 { 256 histo7->Fill(slice, energy); 257 } 258 259 ///////////////////////////////////////////////////////////////////////////// 260 void HadrontherapyAnalysisManager::SecondaryDeuteronEnergyDeposit(G4int slice, G4double energy) 261 { 262 histo8->Fill(slice, energy); 263 } 264 265 ///////////////////////////////////////////////////////////////////////////// 266 void HadrontherapyAnalysisManager::SecondaryPionEnergyDeposit(G4int slice, G4double energy) 267 { 268 histo9->Fill(slice, energy); 269 } 270 271 ///////////////////////////////////////////////////////////////////////////// 272 void HadrontherapyAnalysisManager::electronEnergyDistribution(G4double energy) 273 { 274 histo10->Fill(energy); 275 } 276 277 ///////////////////////////////////////////////////////////////////////////// 278 void HadrontherapyAnalysisManager::gammaEnergyDistribution(G4double energy) 279 { 280 histo11->Fill(energy); 281 } 282 283 ///////////////////////////////////////////////////////////////////////////// 284 void HadrontherapyAnalysisManager::deuteronEnergyDistribution(G4double energy) 285 { 286 histo12->Fill(energy); 287 } 288 289 ///////////////////////////////////////////////////////////////////////////// 290 void HadrontherapyAnalysisManager::tritonEnergyDistribution(G4double energy) 291 { 292 histo13->Fill(energy); 293 } 294 295 ///////////////////////////////////////////////////////////////////////////// 296 void HadrontherapyAnalysisManager::alphaEnergyDistribution(G4double energy) 297 { 298 histo14->Fill(energy); 299 } 300 ///////////////////////////////////////////////////////////////////////////// 301 void HadrontherapyAnalysisManager::heliumEnergy(G4double secondaryParticleKineticEnergy) 302 { 303 histo15->Fill(secondaryParticleKineticEnergy); 304 } 305 306 ///////////////////////////////////////////////////////////////////////////// 307 void HadrontherapyAnalysisManager::hydrogenEnergy(G4double secondaryParticleKineticEnergy) 308 { 309 histo16->Fill(secondaryParticleKineticEnergy); 310 } 311 312 ///////////////////////////////////////////////////////////////////////////// 313 // FillKineticFragmentTuple create an ntuple where the voxel indexs, the atomic number and mass and the kinetic 314 // energy of all the particles interacting with the phantom, are stored 315 void HadrontherapyAnalysisManager::FillKineticFragmentTuple(G4int i, G4int j, G4int k, G4int A, G4double Z, G4double kinEnergy) 316 { 317 kinFragNtuple -> Fill(i, j, k, A, Z, kinEnergy); 318 } 319 320 ///////////////////////////////////////////////////////////////////////////// 321 // FillKineticEnergyPrimaryNTuple creates a ntuple where the voxel indexs and the kinetic 322 // energies of ONLY primary particles interacting with the phantom, are stored 323 void HadrontherapyAnalysisManager::FillKineticEnergyPrimaryNTuple(G4int i, G4int j, G4int k, G4double kinEnergy) 324 { 325 kineticEnergyPrimaryNtuple -> Fill(i, j, k, kinEnergy); 326 } 327 328 ///////////////////////////////////////////////////////////////////////////// 329 // This function is called only if ROOT is activated. 330 // It is called by the HadrontherapyMatric.cc class file and it is used to create two ntuples containing 331 // the total energy deposited and the fluence values, in each voxel and per any particle (primary beam 332 // and secondaries ) 333 void HadrontherapyAnalysisManager::FillVoxelFragmentTuple(G4int i, G4int j, G4int k, G4int A, G4double Z, G4double energy, G4double fluence) 334 { 335 // Fill the ntuple containing the voxel, mass and atomic number and the energy deposited 336 doseFragNtuple -> Fill( i, j, k, A, Z, energy ); 337 338 // Fill the ntuple containing the voxel, mass and atomic number and the fluence 339 if (i==1 && Z==1) { 340 fluenceFragNtuple -> Fill( i, j, k, A, Z, fluence ); 341 342 } 343 } 344 345 void HadrontherapyAnalysisManager::FillLetFragmentTuple(G4int i, G4int j, G4int k, G4int A, G4double Z, G4double letT, G4double letD) 346 { 347 letFragNtuple -> Fill( i, j, k, A, Z, letT, letD); 348 349 } 350 ///////////////////////////////////////////////////////////////////////////// 351 void HadrontherapyAnalysisManager::FillFragmentTuple(G4int A, G4double Z, G4double energy, G4double posX, G4double posY, G4double posZ) 352 { 353 fragmentNtuple->Fill(A, Z, energy, posX, posY, posZ); 354 } 355 356 ///////////////////////////////////////////////////////////////////////////// 357 void HadrontherapyAnalysisManager::genericIonInformation(G4int a, 358 G4double z, 359 G4int electronOccupancy, 360 G4double energy) 361 { 362 if (theROOTIonTuple) { 363 theROOTIonTuple->Fill(a, z, electronOccupancy, energy); 364 } 365 } 366 367 ///////////////////////////////////////////////////////////////////////////// 368 void HadrontherapyAnalysisManager::startNewEvent() 369 { 370 eventCounter++; 371 } 372 ///////////////////////////////////////////////////////////////////////////// 373 void HadrontherapyAnalysisManager::setGeometryMetaData(G4double endDetectorPosition, G4double waterThickness, G4double phantomCenter) 374 { 375 this->detectorDistance = endDetectorPosition; 376 this->phantomDepth = waterThickness; 377 this->phantomCenterDistance = phantomCenter; 378 } 379 void HadrontherapyAnalysisManager::setBeamMetaData(G4double meanKineticEnergy,G4double sigmaEnergy) 380 { 381 this->beamEnergy = meanKineticEnergy; 382 this->energyError = sigmaEnergy; 383 } 384 ///////////////////////////////////////////////////////////////////////////// 385 // Flush data & close the file 386 void HadrontherapyAnalysisManager::flush() 387 { 388 if (theTFile) 389 { 390 theTFile -> Write(); 391 theTFile -> Close(); 392 } 393 eventCounter = 0; 394 } 395 200 396 #endif 201 }202 /////////////////////////////////////////////////////////////////////////////203 HadrontherapyAnalysisManager* HadrontherapyAnalysisManager::getInstance()204 {205 if (instance == 0) instance = new HadrontherapyAnalysisManager;206 return instance;207 }208 209 /////////////////////////////////////////////////////////////////////////////210 void HadrontherapyAnalysisManager::SetAnalysisFileName(G4String aFileName)211 {212 this->analysisFileName = aFileName;213 }214 215 /////////////////////////////////////////////////////////////////////////////216 void HadrontherapyAnalysisManager::book()217 {218 #ifdef G4ANALYSIS_USE219 // Build up the analysis factory220 aFact = AIDA_createAnalysisFactory();221 AIDA::ITreeFactory* treeFact = aFact -> createTreeFactory();222 223 // Create the .hbk or the .root file224 G4String fileName = "DoseDistribution.hbk";225 226 std::string opts = "export=root";227 228 theTree = treeFact -> create(fileName,"hbook",false,true);229 theTree = treeFact -> create(analysisFileName,"ROOT",false,true,opts);230 231 // Factories are not "managed" by an AIDA analysis system.232 // They must be deleted by the AIDA user code.233 delete treeFact;234 235 // Create the histogram and the ntuple factory236 histFact = aFact -> createHistogramFactory(*theTree);237 tupFact = aFact -> createTupleFactory(*theTree);238 239 // Create the histograms with the enrgy deposit along the X axis240 h1 = histFact -> createHistogram1D("10","slice, energy", 400, 0., 400. );241 242 h2 = histFact -> createHistogram1D("20","Secondary protons - slice, energy", 400, 0., 400. );243 244 h3 = histFact -> createHistogram1D("30","Secondary neutrons - slice, energy", 400, 0., 400. );245 246 h4 = histFact -> createHistogram1D("40","Secondary alpha - slice, energy", 400, 0., 400. );247 248 h5 = histFact -> createHistogram1D("50","Secondary gamma - slice, energy", 400, 0., 400. );249 250 h6 = histFact -> createHistogram1D("60","Secondary electron - slice, energy", 400, 0., 400. );251 252 h7 = histFact -> createHistogram1D("70","Secondary triton - slice, energy", 400, 0., 400. );253 254 h8 = histFact -> createHistogram1D("80","Secondary deuteron - slice, energy", 400, 0., 400. );255 256 h9 = histFact -> createHistogram1D("90","Secondary pion - slice, energy", 400, 0., 400. );257 258 h10 = histFact -> createHistogram1D("100","Energy distribution of secondary electrons", 70, 0., 70. );259 260 h11 = histFact -> createHistogram1D("110","Energy distribution of secondary photons", 70, 0., 70. );261 262 h12 = histFact -> createHistogram1D("120","Energy distribution of secondary deuterons", 70, 0., 70. );263 264 h13 = histFact -> createHistogram1D("130","Energy distribution of secondary tritons", 70, 0., 70. );265 266 h14 = histFact -> createHistogram1D("140","Energy distribution of secondary alpha particles", 70, 0., 70. );267 268 h15 = histFact -> createHistogram1D("150","Energy distribution of helium fragments after the phantom", 70, 0., 500.);269 270 h16 = histFact -> createHistogram1D("160","Energy distribution of hydrogen fragments after the phantom", 70, 0., 500.);271 272 // Create the ntuple273 G4String columnNames = "int i; int j; int k; double energy;";274 G4String options = "";275 if (tupFact) ntuple = tupFact -> create("1","1",columnNames, options);276 277 // Create the ntuple278 G4String columnNames2 = "int a; double z; int occupancy; double energy;";279 G4String options2 = "";280 if (tupFact) ionTuple = tupFact -> create("2","2", columnNames2, options2);281 282 // Create the fragment ntuple283 G4String columnNames3 = "int a; double z; double energy; double posX; double posY; double posZ;";284 G4String options3 = "";285 if (tupFact) fragmentTuple = tupFact -> create("3","3", columnNames3, options3);286 #endif287 #ifdef G4ANALYSIS_USE_ROOT288 // Use ROOT289 theTFile = new TFile(analysisFileName, "RECREATE");290 291 // Create the histograms with the energy deposit along the X axis292 histo1 = createHistogram1D("braggPeak","slice, energy", 400, 0., 27.9); //<different waterthicknesses are accoutned for in ROOT-analysis stage293 histo2 = createHistogram1D("h20","Secondary protons - slice, energy", 400, 0., 400.);294 histo3 = createHistogram1D("h30","Secondary neutrons - slice, energy", 400, 0., 400.);295 histo4 = createHistogram1D("h40","Secondary alpha - slice, energy", 400, 0., 400.);296 histo5 = createHistogram1D("h50","Secondary gamma - slice, energy", 400, 0., 400.);297 histo6 = createHistogram1D("h60","Secondary electron - slice, energy", 400, 0., 400.);298 histo7 = createHistogram1D("h70","Secondary triton - slice, energy", 400, 0., 400.);299 histo8 = createHistogram1D("h80","Secondary deuteron - slice, energy", 400, 0., 400.);300 histo9 = createHistogram1D("h90","Secondary pion - slice, energy", 400, 0., 400.);301 histo10 = createHistogram1D("h100","Energy distribution of secondary electrons", 70, 0., 70.);302 histo11 = createHistogram1D("h110","Energy distribution of secondary photons", 70, 0., 70.);303 histo12 = createHistogram1D("h120","Energy distribution of secondary deuterons", 70, 0., 70.);304 histo13 = createHistogram1D("h130","Energy distribution of secondary tritons", 70, 0., 70.);305 histo14 = createHistogram1D("h140","Energy distribution of secondary alpha particles", 70, 0., 70.);306 histo15 = createHistogram1D("heliumEnergyAfterPhantom","Energy distribution of secondary helium fragments after the phantom",307 70, 0., 500.);308 histo16 = createHistogram1D("hydrogenEnergyAfterPhantom","Energy distribution of secondary helium fragments after the phantom",309 70, 0., 500.);310 311 theROOTNtuple = new TNtuple("theROOTNtuple", "Energy deposit by slice", "i:j:k:energy");312 theROOTIonTuple = new TNtuple("theROOTIonTuple", "Generic ion information", "a:z:occupancy:energy");313 fragmentNtuple = new TNtuple("fragmentNtuple", "Fragments", "A:Z:energy:posX:posY:posZ");314 metaData = new TNtuple("metaData", "Metadata", "events:detectorDistance:waterThickness:beamEnergy:energyError:phantomCenterDistance");315 #endif316 }317 318 /////////////////////////////////////////////////////////////////////////////319 void HadrontherapyAnalysisManager::FillEnergyDeposit(G4int i,320 G4int j,321 G4int k,322 G4double energy)323 {324 #ifdef G4ANALYSIS_USE325 if (ntuple) {326 G4int iSlice = ntuple -> findColumn("i");327 G4int jSlice = ntuple -> findColumn("j");328 G4int kSlice = ntuple -> findColumn("k");329 G4int iEnergy = ntuple -> findColumn("energy");330 331 ntuple -> fill(iSlice,i);332 ntuple -> fill(jSlice,j);333 ntuple -> fill(kSlice,k);334 ntuple -> fill(iEnergy, energy); }335 336 ntuple -> addRow();337 #endif338 #ifdef G4ANALYSIS_USE_ROOT339 if (theROOTNtuple) {340 theROOTNtuple->Fill(i, j, k, energy);341 }342 #endif343 }344 345 /////////////////////////////////////////////////////////////////////////////346 void HadrontherapyAnalysisManager::BraggPeak(G4int slice, G4double energy)347 {348 #ifdef G4ANALYSIS_USE349 h1 -> fill(slice,energy);350 #endif351 #ifdef G4ANALYSIS_USE_ROOT352 histo1->SetBinContent(slice, energy); //This uses setbincontent instead of fill to get labels correct353 #endif354 }355 356 /////////////////////////////////////////////////////////////////////////////357 void HadrontherapyAnalysisManager::SecondaryProtonEnergyDeposit(G4int slice, G4double energy)358 {359 #ifdef G4ANALYSIS_USE360 h2 -> fill(slice,energy);361 #endif362 #ifdef G4ANALYSIS_USE_ROOT363 histo2->Fill(slice, energy);364 #endif365 }366 367 /////////////////////////////////////////////////////////////////////////////368 void HadrontherapyAnalysisManager::SecondaryNeutronEnergyDeposit(G4int slice, G4double energy)369 {370 #ifdef G4ANALYSIS_USE371 h3 -> fill(slice,energy);372 #endif373 #ifdef G4ANALYSIS_USE_ROOT374 histo3->Fill(slice, energy);375 #endif376 }377 378 /////////////////////////////////////////////////////////////////////////////379 void HadrontherapyAnalysisManager::SecondaryAlphaEnergyDeposit(G4int slice, G4double energy)380 {381 #ifdef G4ANALYSIS_USE382 h4 -> fill(slice,energy);383 #endif384 #ifdef G4ANALYSIS_USE_ROOT385 histo4->Fill(slice, energy);386 #endif387 }388 389 /////////////////////////////////////////////////////////////////////////////390 void HadrontherapyAnalysisManager::SecondaryGammaEnergyDeposit(G4int slice, G4double energy)391 {392 #ifdef G4ANALYSIS_USE393 h5 -> fill(slice,energy);394 #endif395 #ifdef G4ANALYSIS_USE_ROOT396 histo5->Fill(slice, energy);397 #endif398 }399 400 /////////////////////////////////////////////////////////////////////////////401 void HadrontherapyAnalysisManager::SecondaryElectronEnergyDeposit(G4int slice, G4double energy)402 {403 #ifdef G4ANALYSIS_USE404 h6 -> fill(slice,energy);405 #endif406 #ifdef G4ANALYSIS_USE_ROOT407 histo6->Fill(slice, energy);408 #endif409 }410 411 /////////////////////////////////////////////////////////////////////////////412 void HadrontherapyAnalysisManager::SecondaryTritonEnergyDeposit(G4int slice, G4double energy)413 {414 #ifdef G4ANALYSIS_USE415 h7 -> fill(slice,energy);416 #endif417 #ifdef G4ANALYSIS_USE_ROOT418 histo7->Fill(slice, energy);419 #endif420 }421 422 /////////////////////////////////////////////////////////////////////////////423 void HadrontherapyAnalysisManager::SecondaryDeuteronEnergyDeposit(G4int slice, G4double energy)424 {425 #ifdef G4ANALYSIS_USE426 h8 -> fill(slice,energy);427 #endif428 #ifdef G4ANALYSIS_USE_ROOT429 histo8->Fill(slice, energy);430 #endif431 }432 433 /////////////////////////////////////////////////////////////////////////////434 void HadrontherapyAnalysisManager::SecondaryPionEnergyDeposit(G4int slice, G4double energy)435 {436 #ifdef G4ANALYSIS_USE437 h9 -> fill(slice,energy);438 #endif439 #ifdef G4ANALYSIS_USE_ROOT440 histo9->Fill(slice, energy);441 #endif442 }443 444 /////////////////////////////////////////////////////////////////////////////445 void HadrontherapyAnalysisManager::electronEnergyDistribution(G4double energy)446 {447 #ifdef G4ANALYSIS_USE448 h10 -> fill(energy);449 #endif450 #ifdef G4ANALYSIS_USE_ROOT451 histo10->Fill(energy);452 #endif453 }454 455 /////////////////////////////////////////////////////////////////////////////456 void HadrontherapyAnalysisManager::gammaEnergyDistribution(G4double energy)457 {458 #ifdef G4ANALYSIS_USE459 h11 -> fill(energy);460 #endif461 #ifdef G4ANALYSIS_USE_ROOT462 histo11->Fill(energy);463 #endif464 }465 466 /////////////////////////////////////////////////////////////////////////////467 void HadrontherapyAnalysisManager::deuteronEnergyDistribution(G4double energy)468 {469 #ifdef G4ANALYSIS_USE470 h12 -> fill(energy);471 #endif472 #ifdef G4ANALYSIS_USE_ROOT473 histo12->Fill(energy);474 #endif475 }476 477 /////////////////////////////////////////////////////////////////////////////478 void HadrontherapyAnalysisManager::tritonEnergyDistribution(G4double energy)479 {480 #ifdef G4ANALYSIS_USE481 h13 -> fill(energy);482 #endif483 #ifdef G4ANALYSIS_USE_ROOT484 histo13->Fill(energy);485 #endif486 }487 488 /////////////////////////////////////////////////////////////////////////////489 void HadrontherapyAnalysisManager::alphaEnergyDistribution(G4double energy)490 {491 #ifdef G4ANALYSIS_USE492 h14 -> fill(energy);493 #endif494 #ifdef G4ANALYSIS_USE_ROOT495 histo14->Fill(energy);496 #endif497 }498 /////////////////////////////////////////////////////////////////////////////499 void HadrontherapyAnalysisManager::heliumEnergy(G4double secondaryParticleKineticEnergy)500 {501 #ifdef G4ANALYSIS_USE502 h15->fill(secondaryParticleKineticEnergy);503 #endif504 #ifdef G4ANALYSIS_USE_ROOT505 histo15->Fill(secondaryParticleKineticEnergy);506 #endif507 }508 509 /////////////////////////////////////////////////////////////////////////////510 void HadrontherapyAnalysisManager::hydrogenEnergy(G4double secondaryParticleKineticEnergy)511 {512 #ifdef G4ANALYSIS_USE513 h16->fill(secondaryParticleKineticEnergy);514 #endif515 #ifdef G4ANALYSIS_USE_ROOT516 histo16->Fill(secondaryParticleKineticEnergy);517 #endif518 }519 520 521 522 void HadrontherapyAnalysisManager::fillFragmentTuple(G4int A, G4double Z, G4double energy, G4double posX, G4double posY, G4double posZ)523 {524 #ifdef G4ANALYSIS_USE525 if (fragmentTuple) {526 G4int aIndex = fragmentTuple -> findColumn("a");527 G4int zIndex = fragmentTuple -> findColumn("z");528 G4int energyIndex = fragmentTuple -> findColumn("energy");529 G4int posXIndex = fragmentTuple -> findColumn("posX");530 G4int posYIndex = fragmentTuple -> findColumn("posY");531 G4int posZIndex = fragmentTuple -> findColumn("posZ");532 533 fragmentTuple -> fill(aIndex,A);534 fragmentTuple -> fill(zIndex,Z);535 fragmentTuple -> fill(energyIndex, energy);536 fragmentTuple -> fill(posXIndex, posX);537 fragmentTuple -> fill(posYIndex, posY);538 fragmentTuple -> fill(posZIndex, posZ);539 fragmentTuple -> addRow();540 }541 #endif542 #ifdef G4ANALYSIS_USE_ROOT543 //G4cout <<" A = " << A << " Z = " << Z << " energy = " << energy << G4endl;544 fragmentNtuple->Fill(A, Z, energy, posX, posY, posZ);545 #endif546 }547 548 /////////////////////////////////////////////////////////////////////////////549 void HadrontherapyAnalysisManager::genericIonInformation(G4int a,550 G4double z,551 G4int electronOccupancy,552 G4double energy)553 {554 #ifdef G4ANALYSIS_USE555 if (ionTuple) {556 G4int aIndex = ionTuple -> findColumn("a");557 G4int zIndex = ionTuple -> findColumn("z");558 G4int electronIndex = ionTuple -> findColumn("occupancy");559 G4int energyIndex = ionTuple -> findColumn("energy");560 561 ionTuple -> fill(aIndex,a);562 ionTuple -> fill(zIndex,z);563 ionTuple -> fill(electronIndex, electronOccupancy);564 ionTuple -> fill(energyIndex, energy);565 }566 ionTuple -> addRow();567 #endif568 #ifdef G4ANALYSIS_USE_ROOT569 if (theROOTIonTuple) {570 theROOTIonTuple->Fill(a, z, electronOccupancy, energy);571 }572 #endif573 }574 575 /////////////////////////////////////////////////////////////////////////////576 void HadrontherapyAnalysisManager::startNewEvent()577 {578 eventCounter++;579 }580 /////////////////////////////////////////////////////////////////////////////581 void HadrontherapyAnalysisManager::setGeometryMetaData(G4double endDetectorPosition, G4double waterThickness, G4double phantomCenter)582 {583 this->detectorDistance = endDetectorPosition;584 this->phantomDepth = waterThickness;585 this->phantomCenterDistance = phantomCenter;586 }587 void HadrontherapyAnalysisManager::setBeamMetaData(G4double meanKineticEnergy,G4double sigmaEnergy)588 {589 this->beamEnergy = meanKineticEnergy;590 this->energyError = sigmaEnergy;591 }592 /////////////////////////////////////////////////////////////////////////////593 void HadrontherapyAnalysisManager::flush()594 {595 HadrontherapyMatrix* matrix = HadrontherapyMatrix::getInstance();596 597 matrix->TotalEnergyDeposit();598 #ifdef G4ANALYSIS_USE599 theTree -> commit();600 theTree ->close();601 #endif602 #ifdef G4ANALYSIS_USE_ROOT603 metaData->Fill((Float_t) eventCounter,(Float_t) detectorDistance, (Float_t) phantomDepth, (Float_t) beamEnergy,(Float_t) energyError, (Float_t) phantomCenterDistance);604 metaData->Write();605 theROOTNtuple->Write();606 theROOTIonTuple->Write();607 fragmentNtuple->Write();608 theTFile->Write();609 // theTFile->Clear();610 theTFile->Close();611 #endif612 eventCounter = 0;613 matrix->flush();614 }615 /////////////////////////////////////////////////////////////////////////////616 void HadrontherapyAnalysisManager::finish()617 {618 #ifdef G4ANALYSIS_USE619 // Write all histograms to file620 theTree -> commit();621 // Close (will again commit)622 theTree ->close();623 #endif624 #ifdef G4ANALYSIS_USE_ROOT625 metaData->Fill((Float_t) eventCounter,(Float_t) detectorDistance, (Float_t) phantomDepth, (Float_t) beamEnergy,(Float_t) energyError, (Float_t) phantomCenterDistance);626 metaData->Write();627 theROOTNtuple->Write();628 theROOTIonTuple->Write();629 fragmentNtuple->Write();630 theTFile->Write();631 theTFile->Close();632 #endif633 eventCounter = 0;634 }635 636 #endif637 638 639 640 641 642 643 644 645 -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyDetectorConstruction.cc
r1230 r1313 28 28 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy 29 29 30 30 31 #include "G4SDManager.hh" 31 32 #include "G4RunManager.hh" 33 #include "G4GeometryManager.hh" 34 #include "G4SolidStore.hh" 35 #include "G4PhysicalVolumeStore.hh" 36 #include "G4LogicalVolumeStore.hh" 32 37 #include "G4Box.hh" 33 38 #include "G4LogicalVolume.hh" … … 42 47 #include "G4VisAttributes.hh" 43 48 #include "G4NistManager.hh" 49 50 #include "HadrontherapyDetectorConstruction.hh" 44 51 #include "HadrontherapyDetectorROGeometry.hh" 45 52 #include "HadrontherapyDetectorMessenger.hh" 46 53 #include "HadrontherapyDetectorSD.hh" 47 #include "HadrontherapyDetectorConstruction.hh"48 54 #include "HadrontherapyMatrix.hh" 55 #include "HadrontherapyAnalysisManager.hh" 56 57 #include <cmath> 49 58 50 59 ///////////////////////////////////////////////////////////////////////////// 51 60 HadrontherapyDetectorConstruction::HadrontherapyDetectorConstruction(G4VPhysicalVolume* physicalTreatmentRoom) 52 : motherPhys(physicalTreatmentRoom), 61 : motherPhys(physicalTreatmentRoom), // pointer to WORLD volume 53 62 detectorSD(0), detectorROGeometry(0), matrix(0), 54 phantom PhysicalVolume(0),55 detectorLogicalVolume(0), detectorPhysicalVolume(0),56 phantom SizeX(20.*cm), phantomSizeY(20.*cm), phantomSizeZ(20.*cm), // Default half dimensions57 detectorSizeX(2.*cm), detectorSizeY(2.*cm), detectorSizeZ(2.*cm),58 phantomPosition(20.*cm, 0.*cm, 0.*cm), 59 detectorToPhantomPosition(0.*cm,18.*cm,18.*cm)// Default displacement of the detector respect to the phantom60 { 63 phantom(0), detector(0), 64 phantomLogicalVolume(0), detectorLogicalVolume(0), 65 phantomPhysicalVolume(0), detectorPhysicalVolume(0), 66 aRegion(0) 67 { 68 HadrontherapyAnalysisManager::GetInstance(); 69 61 70 // NOTE! that the HadrontherapyDetectorConstruction class 62 71 // does NOT inherit from G4VUserDetectorConstruction G4 class … … 69 78 // Default detector voxels size 70 79 // 200 slabs along the beam direction (X) 71 sizeOfVoxelAlongX = 200 *um; 72 sizeOfVoxelAlongY = 2 * detectorSizeY; 73 sizeOfVoxelAlongZ = 2 * detectorSizeZ; 74 75 // Calculate (and eventually set) detector position by displacement, phantom size and detector size 76 SetDetectorPosition(); 77 78 // Build phantom and associated detector 79 ConstructPhantom(); 80 ConstructDetector(); 81 // Set number of the detector voxels along X Y and Z directions. 82 // This will construct also the sensitive detector, the ROGeometry 83 // and the matrix where the energy deposited is collected! 84 SetNumberOfVoxelBySize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ); 80 sizeOfVoxelAlongX = 200 *um; 81 sizeOfVoxelAlongY = 4 *cm; 82 sizeOfVoxelAlongZ = 4 *cm; 83 84 // Define here the material of the water phantom and of the detector 85 SetPhantomMaterial("G4_WATER"); 86 // Construct geometry (messenger commands) 87 SetDetectorSize(4.*cm, 4.*cm, 4.*cm); 88 SetPhantomSize(40. *cm, 40. *cm, 40. *cm); 89 SetPhantomPosition(G4ThreeVector(20. *cm, 0. *cm, 0. *cm)); 90 SetDetectorToPhantomPosition(G4ThreeVector(0. *cm, 18. *cm, 18. *cm)); 91 92 93 // Write virtual parameters to the real ones and check for consistency 94 UpdateGeometry(); 85 95 } 86 96 … … 88 98 HadrontherapyDetectorConstruction::~HadrontherapyDetectorConstruction() 89 99 { 90 delete detectorROGeometry; // This should be safe in C++ even if the argument is a NULL pointer100 delete detectorROGeometry; 91 101 delete matrix; 92 102 delete detectorMessenger; 93 103 } 94 104 105 ///////////////////////////////////////////////////////////////////////////// 106 // ConstructPhantom() is the method that reconstuct a water box (called phantom 107 // (or water phantom) in the usual Medical physicists slang). 108 // A water phantom can be considered a good 109 // approximation of a an human body. 95 110 void HadrontherapyDetectorConstruction::ConstructPhantom() 96 111 { 97 //---------------------------------------- 98 // Phantom: 99 // A box used to approximate tissues 100 //---------------------------------------- 101 102 G4bool isotopes = false; 103 G4Material* waterNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER", isotopes); 104 phantom = new G4Box("Phantom",phantomSizeX, phantomSizeY, phantomSizeZ); 112 // Definition of the solid volume of the Phantom 113 phantom = new G4Box("Phantom", 114 phantomSizeX/2, 115 phantomSizeY/2, 116 phantomSizeZ/2); 117 118 // Definition of the logical volume of the Phantom 105 119 phantomLogicalVolume = new G4LogicalVolume(phantom, 106 waterNist,120 phantomMaterial, 107 121 "phantomLog", 0, 0, 0); 108 122 123 // Definition of the physics volume of the Phantom 109 124 phantomPhysicalVolume = new G4PVPlacement(0, 110 125 phantomPosition, … … 119 134 red -> SetVisibility(true); 120 135 red -> SetForceSolid(true); 121 //red -> SetForceWireframe(true);136 //red -> SetForceWireframe(true); 122 137 phantomLogicalVolume -> SetVisAttributes(red); 123 138 } 124 139 125 140 ///////////////////////////////////////////////////////////////////////////// 141 // ConstructDetector() it the method the reconstruct a detector region 142 // inside the water phantom. It is a volume, located inside the water phantom 143 // and with two coincident faces: 144 // 145 // ************************** 146 // * water phantom * 147 // * * 148 // * * 149 // *--------------- * 150 // Beam * - * 151 // -----> * detector - * 152 // * - * 153 // *--------------- * 154 // * * 155 // * * 156 // * * 157 // ************************** 158 // 159 // The detector is the volume that can be dived in slices or voxelized 160 // and in it we can collect a number of usefull information: 161 // dose distribution, fluence distribution, LET and so on 126 162 void HadrontherapyDetectorConstruction::ConstructDetector() 127 163 { 128 //----------- 129 // Detector 130 //----------- 131 G4bool isotopes = false; 132 G4Material* waterNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER", isotopes); 133 detector = new G4Box("Detector",detectorSizeX,detectorSizeY,detectorSizeZ); 164 165 // Definition of the solid volume of the Detector 166 detector = new G4Box("Detector", 167 detectorSizeX/2, 168 detectorSizeY/2, 169 detectorSizeZ/2); 170 171 // Definition of the logic volume of the Phantom 134 172 detectorLogicalVolume = new G4LogicalVolume(detector, 135 waterNist,173 detectorMaterial, 136 174 "DetectorLog", 137 175 0,0,0); 138 // De tector is attached by default to the phantom face directly exposed to the beam139 detectorPhysicalVolume = new G4PVPlacement(0, 140 detectorPosition, // Setted by displacement141 "DetectorPhys",142 detectorLogicalVolume,143 phantomPhysicalVolume,144 false,0);145 176 // Definition of the physical volume of the Phantom 177 detectorPhysicalVolume = new G4PVPlacement(0, 178 detectorPosition, // Setted by displacement 179 "DetectorPhys", 180 detectorLogicalVolume, 181 phantomPhysicalVolume, 182 false,0); 183 146 184 // Visualisation attributes of the detector 147 185 skyBlue = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. )); 148 186 skyBlue -> SetVisibility(true); 149 187 skyBlue -> SetForceSolid(true); 150 //skyBlue -> SetForceWireframe(true);188 //skyBlue -> SetForceWireframe(true); 151 189 detectorLogicalVolume -> SetVisAttributes(skyBlue); 190 191 // ************** 192 // Cut per Region 193 // ************** 152 194 153 } 154 ///////////////////////////////////////////////////////////////////////////// 195 // A smaller cut is fixed in the phantom to calculate the energy deposit with the 196 // required accuracy 197 if (!aRegion) 198 { 199 aRegion = new G4Region("DetectorLog"); 200 detectorLogicalVolume -> SetRegion(aRegion); 201 aRegion -> AddRootLogicalVolume(detectorLogicalVolume); 202 } 203 204 } 205 206 ///////////////////////////////////////////////////////////////////////////// 207 155 208 void HadrontherapyDetectorConstruction::ConstructSensitiveDetector(G4ThreeVector detectorToWorldPosition) 156 209 { 157 210 // Install new Sensitive Detector and ROGeometry 158 211 delete detectorROGeometry; // this should be safe in C++ also if we have a NULL pointer 159 212 //if (detectorSD) detectorSD->PrintAll(); 213 //delete detectorSD; 160 214 // Sensitive Detector and ReadOut geometry definition 161 215 G4SDManager* sensitiveDetectorManager = G4SDManager::GetSDMpointer(); 162 216 163 G4String sensitiveDetectorName = "Detector";217 static G4String sensitiveDetectorName = "Detector"; 164 218 if (!detectorSD) 165 219 { … … 168 222 } 169 223 // The Read Out Geometry is instantiated 170 G4String ROGeometryName = "DetectorROGeometry";224 static G4String ROGeometryName = "DetectorROGeometry"; 171 225 detectorROGeometry = new HadrontherapyDetectorROGeometry(ROGeometryName, 172 226 detectorToWorldPosition, 173 detectorSizeX ,174 detectorSizeY ,175 detectorSizeZ ,227 detectorSizeX/2, 228 detectorSizeY/2, 229 detectorSizeZ/2, 176 230 numberOfVoxelsAlongX, 177 231 numberOfVoxelsAlongY, … … 193 247 } 194 248 } 195 249 void HadrontherapyDetectorConstruction::ParametersCheck() 250 { 251 // Check phantom/detector sizes & relative position 252 if (!IsInside(detectorSizeX, 253 detectorSizeY, 254 detectorSizeZ, 255 phantomSizeX, 256 phantomSizeY, 257 phantomSizeZ, 258 detectorToPhantomPosition 259 )) 260 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector is not fully inside Phantom!"); 261 262 // Check Detector sizes respect to the voxel ones 263 264 if ( detectorSizeX < sizeOfVoxelAlongX) { 265 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector X size must be bigger or equal than that of Voxel X"); 266 } 267 if ( detectorSizeY < sizeOfVoxelAlongY) { 268 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector Y size must be bigger or equal than that of Voxel Y"); 269 } 270 if ( detectorSizeZ < sizeOfVoxelAlongZ) { 271 G4Exception("Error at HadrontherapyDetectorConstruction::ParametersCheck(). Detector Z size must be bigger or equal than that of Voxel Z"); 272 } 273 274 } 196 275 ///////////////// 197 276 // MESSENGERS // 198 277 //////////////// 199 G4bool HadrontherapyDetectorConstruction::SetNumberOfVoxelBySize(G4double sizeX, G4double sizeY, G4double sizeZ) 200 { 201 // Only change positive dimensions 202 // XXX numberOfVoxels must be an integer, warn the user 203 204 if (sizeX > 0) 278 279 G4bool HadrontherapyDetectorConstruction::SetPhantomMaterial(G4String material) 280 { 281 282 if (G4Material* pMat = G4NistManager::Instance()->FindOrBuildMaterial(material, false) ) 205 283 { 206 if (sizeX > 2*detectorSizeX) 284 phantomMaterial = pMat; 285 detectorMaterial = pMat; 286 if (detectorLogicalVolume && phantomLogicalVolume) 207 287 { 208 G4cout << "WARNING: Voxel X size must be smaller or equal than that of detector X" << G4endl; 209 return false; 288 detectorLogicalVolume -> SetMaterial(pMat); 289 phantomLogicalVolume -> SetMaterial(pMat); 290 291 G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 292 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 293 G4cout << "The material of Phantom/Detector has been changed to " << material << G4endl; 210 294 } 211 // Round to the nearest integer 212 numberOfVoxelsAlongX = lrint(2 * detectorSizeX / sizeX); 213 sizeOfVoxelAlongX = (2 * detectorSizeX / numberOfVoxelsAlongX ); 214 if(sizeOfVoxelAlongX!=sizeX) G4cout << "Rounding " << 215 G4BestUnit(sizeX, "Length") << " to " << 216 G4BestUnit(sizeOfVoxelAlongX, "Length") << G4endl; 217 } 218 219 if (sizeY > 0) 295 } 296 else 220 297 { 221 if (sizeY > 2*detectorSizeY) 222 { 223 G4cout << "WARNING: Voxel Y size must be smaller or equal than that of detector Y" << G4endl; 224 return false; 225 } 226 numberOfVoxelsAlongY = lrint(2 * detectorSizeY / sizeY); 227 sizeOfVoxelAlongY = (2 * detectorSizeY / numberOfVoxelsAlongY ); 228 if(sizeOfVoxelAlongY!=sizeY) G4cout << "Rounding " << 229 G4BestUnit(sizeY, "Length") << " to " << 230 G4BestUnit(sizeOfVoxelAlongY, "Length") << G4endl; 231 } 232 if (sizeZ > 0) 298 G4cout << "WARNING: material \"" << material << "\" doesn't exist in NIST elements/materials" 299 " table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl; 300 G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl; 301 return false; 302 } 303 304 return true; 305 } 306 ///////////////////////////////////////////////////////////////////////////// 307 void HadrontherapyDetectorConstruction::SetPhantomSize(G4double sizeX, G4double sizeY, G4double sizeZ) 308 { 309 if (sizeX > 0.) phantomSizeX = sizeX; 310 if (sizeY > 0.) phantomSizeY = sizeY; 311 if (sizeZ > 0.) phantomSizeZ = sizeZ; 312 } 313 ///////////////////////////////////////////////////////////////////////////// 314 ///////////////////////////////////////////////////////////////////////////// 315 void HadrontherapyDetectorConstruction::SetDetectorSize(G4double sizeX, G4double sizeY, G4double sizeZ) 316 { 317 if (sizeX > 0.) {detectorSizeX = sizeX;} 318 if (sizeY > 0.) {detectorSizeY = sizeY;} 319 if (sizeZ > 0.) {detectorSizeZ = sizeZ;} 320 SetVoxelSize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ); 321 } 322 ///////////////////////////////////////////////////////////////////////////// 323 324 void HadrontherapyDetectorConstruction::SetVoxelSize(G4double sizeX, G4double sizeY, G4double sizeZ) 325 { 326 if (sizeX > 0.) {sizeOfVoxelAlongX = sizeX;} 327 if (sizeY > 0.) {sizeOfVoxelAlongY = sizeY;} 328 if (sizeZ > 0.) {sizeOfVoxelAlongZ = sizeZ;} 329 } 330 void HadrontherapyDetectorConstruction::SetPhantomPosition(G4ThreeVector pos) 331 { 332 phantomPosition = pos; 333 } 334 335 ///////////////////////////////////////////////////////////////////////////// 336 void HadrontherapyDetectorConstruction::SetDetectorToPhantomPosition(G4ThreeVector displ) 337 { 338 detectorToPhantomPosition = displ; 339 } 340 ///////////////////////////////////////////////////////////////////////////// 341 void HadrontherapyDetectorConstruction::UpdateGeometry() 342 { 343 ParametersCheck(); 344 345 //G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 346 G4GeometryManager::GetInstance() -> OpenGeometry(); 347 if (phantom) 233 348 { 234 if (sizeZ > 2*detectorSizeZ) 235 { 236 G4cout << "WARNING: Voxel Z size must be smaller or equal than that of detector Z" << G4endl; 237 return false; 238 } 239 numberOfVoxelsAlongZ = lrint(2 * detectorSizeZ / sizeZ); 240 sizeOfVoxelAlongZ = (2 * detectorSizeZ / numberOfVoxelsAlongZ ); 241 if(sizeOfVoxelAlongZ!=sizeZ) G4cout << "Rounding " << 242 G4BestUnit(sizeZ, "Length") << " to " << 243 G4BestUnit(sizeOfVoxelAlongZ, "Length") << G4endl; 244 } 245 246 G4cout << "The (X, Y, Z) sizes of the Voxels are: (" << 247 G4BestUnit(sizeOfVoxelAlongX, "Length") << ", " << 248 G4BestUnit(sizeOfVoxelAlongY, "Length") << ", " << 249 G4BestUnit(sizeOfVoxelAlongZ, "Length") << ')' << G4endl; 349 phantom -> SetXHalfLength(phantomSizeX/2); 350 phantom -> SetYHalfLength(phantomSizeY/2); 351 phantom -> SetZHalfLength(phantomSizeZ/2); 352 phantomPhysicalVolume -> SetTranslation(phantomPosition); 353 } 354 else ConstructPhantom(); 355 356 // Get the center of the detector 357 SetDetectorPosition(); 358 if (detector) 359 { 360 detector -> SetXHalfLength(detectorSizeX/2); 361 detector -> SetYHalfLength(detectorSizeY/2); 362 detector -> SetZHalfLength(detectorSizeZ/2); 363 detectorPhysicalVolume -> SetTranslation(detectorPosition); 364 } 365 else ConstructDetector(); 366 367 // Round to nearest integer number of voxel 368 numberOfVoxelsAlongX = lrint(detectorSizeX / sizeOfVoxelAlongX); 369 sizeOfVoxelAlongX = ( detectorSizeX / numberOfVoxelsAlongX ); 370 371 numberOfVoxelsAlongY = lrint(detectorSizeY / sizeOfVoxelAlongY); 372 sizeOfVoxelAlongY = ( detectorSizeY / numberOfVoxelsAlongY ); 373 374 numberOfVoxelsAlongZ = lrint(detectorSizeZ / sizeOfVoxelAlongZ); 375 sizeOfVoxelAlongZ = ( detectorSizeZ / numberOfVoxelsAlongZ ); 376 377 //G4cout << "*************** DetectorToWorldPosition " << GetDetectorToWorldPosition()/cm << "\n"; 378 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 379 380 volumeOfVoxel = sizeOfVoxelAlongX * sizeOfVoxelAlongY * sizeOfVoxelAlongZ; 381 massOfVoxel = detectorMaterial -> GetDensity() * volumeOfVoxel; 382 // This will clear the existing matrix (together with all data inside it)! 383 matrix = HadrontherapyMatrix::GetInstance(numberOfVoxelsAlongX, 384 numberOfVoxelsAlongY, 385 numberOfVoxelsAlongZ, 386 massOfVoxel); 387 388 // Inform the kernel about the new geometry 389 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 390 G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 391 392 PrintParameters(); 393 } 394 395 void HadrontherapyDetectorConstruction::PrintParameters() 396 { 397 398 G4cout << "The (X,Y,Z) dimensions of the phantom are : (" << 399 G4BestUnit( phantom -> GetXHalfLength()*2., "Length") << ',' << 400 G4BestUnit( phantom -> GetYHalfLength()*2., "Length") << ',' << 401 G4BestUnit( phantom -> GetZHalfLength()*2., "Length") << ')' << G4endl; 402 403 G4cout << "The (X,Y,Z) dimensions of the detector are : (" << 404 G4BestUnit( detector -> GetXHalfLength()*2., "Length") << ',' << 405 G4BestUnit( detector -> GetYHalfLength()*2., "Length") << ',' << 406 G4BestUnit( detector -> GetZHalfLength()*2., "Length") << ')' << G4endl; 407 408 G4cout << "Displacement between Phantom and World is: "; 409 G4cout << "DX= "<< G4BestUnit(phantomPosition.getX(),"Length") << 410 "DY= "<< G4BestUnit(phantomPosition.getY(),"Length") << 411 "DZ= "<< G4BestUnit(phantomPosition.getZ(),"Length") << G4endl; 412 413 G4cout << "The (X,Y,Z) sizes of the Voxels are: (" << 414 G4BestUnit(sizeOfVoxelAlongX, "Length") << ',' << 415 G4BestUnit(sizeOfVoxelAlongY, "Length") << ',' << 416 G4BestUnit(sizeOfVoxelAlongZ, "Length") << ')' << G4endl; 250 417 251 418 G4cout << "The number of Voxels along (X,Y,Z) is: (" << 252 numberOfVoxelsAlongX << ", " << 253 numberOfVoxelsAlongY << ", " << 254 numberOfVoxelsAlongZ << ')' << G4endl; 255 256 // This will clear the existing matrix (together with data inside it)! 257 matrix = HadrontherapyMatrix::getInstance(numberOfVoxelsAlongX, 258 numberOfVoxelsAlongY, 259 numberOfVoxelsAlongZ); 260 261 // Here construct the Sensitive Detector and Read Out Geometry 262 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 263 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 264 return true; 265 } 266 ///////////////////////////////////////////////////////////////////////////// 267 G4bool HadrontherapyDetectorConstruction::SetDetectorSize(G4double sizeX, G4double sizeY, G4double sizeZ) 268 { 269 // Check that the detector stay inside the phantom 270 if (sizeX > 0 && sizeX < sizeOfVoxelAlongX) {G4cout << "WARNING: Detector X size must be bigger than that of Voxel X" << G4endl; return false;} 271 if (sizeY > 0 && sizeY < sizeOfVoxelAlongY) {G4cout << "WARNING: Detector Y size must be bigger than that of Voxel Y" << G4endl; return false;} 272 if (sizeZ > 0 && sizeZ < sizeOfVoxelAlongZ) {G4cout << "WARNING: Detector Z size must be bigger than that of Voxel Z" << G4endl; return false;} 273 274 if (!IsInside(sizeX/2, 275 sizeY/2, 276 sizeZ/2, 277 phantomSizeX, 278 phantomSizeY, 279 phantomSizeZ, 280 detectorToPhantomPosition)) 281 {return false;} 282 // Negative or null values mean don't change it! 283 if (sizeX > 0) { 284 detectorSizeX = sizeX/2; 285 detector -> SetXHalfLength(detectorSizeX); 286 } 287 288 if (sizeY > 0) { 289 detectorSizeY = sizeY/2; 290 detector -> SetYHalfLength(detectorSizeY); 291 } 292 293 if (sizeZ > 0) { 294 detectorSizeZ = sizeZ/2; 295 detector -> SetZHalfLength(detectorSizeZ); 296 } 297 298 299 G4cout << "The (X, Y, Z) dimensions of the detector are : (" << 300 G4BestUnit( detector -> GetXHalfLength()*2., "Length") << ", " << 301 G4BestUnit( detector -> GetYHalfLength()*2., "Length") << ", " << 302 G4BestUnit( detector -> GetZHalfLength()*2., "Length") << ')' << G4endl; 303 // Adjust detector position 304 SetDetectorPosition(); 305 // Adjust voxels number accordingly to new detector geometry 306 // Matrix will be re-instantiated! 307 // Voxels and ROGeometry must follow the detector! 308 SetNumberOfVoxelBySize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ); 309 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 310 return true; 311 } 312 313 ///////////////////////////////////////////////////////////////////////////// 314 G4bool HadrontherapyDetectorConstruction::SetPhantomSize(G4double sizeX, G4double sizeY, G4double sizeZ) 315 { 316 317 if (!IsInside(detectorSizeX, 318 detectorSizeY, 319 detectorSizeZ, 320 sizeX/2,//method parameters 321 sizeY/2, 322 sizeZ/2, 323 detectorToPhantomPosition 324 )) 325 return false; 326 327 // Only change positive dimensions 328 if (sizeX > 0) { 329 phantomSizeX = sizeX/2; 330 phantom -> SetXHalfLength(phantomSizeX); 331 } 332 if (sizeY > 0) { 333 phantomSizeY = sizeY/2; 334 phantom -> SetYHalfLength(phantomSizeY); 335 } 336 337 if (sizeZ > 0) { 338 phantomSizeZ = sizeZ/2; 339 phantom -> SetZHalfLength(phantomSizeZ); 340 } 341 342 343 G4cout << "The (X, Y, Z) dimensions of the phantom are : (" << 344 G4BestUnit( phantom -> GetXHalfLength()*2., "Length") << ", " << 345 G4BestUnit( phantom -> GetYHalfLength()*2., "Length") << ", " << 346 G4BestUnit( phantom -> GetZHalfLength()*2., "Length") << ')' << G4endl; 347 //G4cout << '\n' << "Coordinate volume: " << phantomPhysicalVolume -> GetTranslation() << G4endl; 348 // Adjust detector position inside phantom 349 SetDetectorPosition(); 350 351 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 352 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 353 return true; 354 } 355 ///////////////////////////////////////////////////////////////////////////// 356 G4bool HadrontherapyDetectorConstruction::SetPhantomPosition(G4ThreeVector displacement) 357 { 358 // Set Phantom position respect to the World 359 // TODO check for overlap! 360 phantomPosition = displacement; 361 if (phantomPhysicalVolume) 362 { 363 phantomPhysicalVolume -> SetTranslation(phantomPosition); 364 G4cout << "Displacement between Phantom and World is: "; 365 G4cout << "DX= "<< G4BestUnit(phantomPosition.getX(),"Length") << ", " << 366 "DY= "<< G4BestUnit(phantomPosition.getY(),"Length") << ", " << 367 "DZ= "<< G4BestUnit(phantomPosition.getZ(),"Length") << G4endl; 368 369 // Redraw ROGeometry! 370 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 371 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 372 } 373 return true; 374 } 375 376 ///////////////////////////////////////////////////////////////////////////// 377 G4bool HadrontherapyDetectorConstruction::SetDetectorToPhantomPosition(G4ThreeVector displacement) 378 { 379 // Ignore negative values 380 if (displacement[0] < 0.) displacement[0] = detectorToPhantomPosition[0]; 381 if (displacement[1] < 0.) displacement[1] = detectorToPhantomPosition[1]; 382 if (displacement[2] < 0.) displacement[2] = detectorToPhantomPosition[2]; 383 384 if (!IsInside(detectorSizeX, 385 detectorSizeY, 386 detectorSizeZ, 387 phantomSizeX, 388 phantomSizeY, 389 phantomSizeZ, 390 displacement // method parameter! 391 )) 392 {return false;} 393 detectorToPhantomPosition = displacement; 394 395 // Adjust detector position inside phantom 396 SetDetectorPosition(); 397 398 ConstructSensitiveDetector(GetDetectorToWorldPosition()); 399 G4RunManager::GetRunManager() -> GeometryHasBeenModified(); 400 return true; 401 } 419 numberOfVoxelsAlongX << ',' << 420 numberOfVoxelsAlongY <<',' << 421 numberOfVoxelsAlongZ << ')' << G4endl; 422 423 } -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyDetectorMessenger.cc
r1230 r1313 31 31 #include "HadrontherapyDetectorConstruction.hh" 32 32 #include "G4UIdirectory.hh" 33 #include "G4UIcmdWithADoubleAndUnit.hh" 33 #include "G4UIcmdWith3VectorAndUnit.hh" 34 #include "G4UIcmdWithoutParameter.hh" 34 35 #include "G4UIcmdWithAString.hh" 35 #include "G4UIcmdWith3VectorAndUnit.hh"36 36 37 37 ///////////////////////////////////////////////////////////////////////////// … … 49 49 "PhantomSizeAlongZ", false); 50 50 changeThePhantomSizeCmd -> SetDefaultUnit("mm"); 51 changeThePhantomSizeCmd -> SetUnitCandidates(" um mm cm");51 changeThePhantomSizeCmd -> SetUnitCandidates("nm um mm cm"); 52 52 changeThePhantomSizeCmd -> AvailableForStates(G4State_Idle); 53 53 54 55 // Change Phantom material 56 changeThePhantomMaterialCmd = new G4UIcmdWithAString("/changePhantom/material", this); 57 changeThePhantomMaterialCmd -> SetGuidance("Change the Phantom and the detector material"); 58 changeThePhantomMaterialCmd -> SetParameterName("PhantomMaterial", false); 59 changeThePhantomMaterialCmd -> SetDefaultValue("G4_WATER"); 60 changeThePhantomMaterialCmd -> AvailableForStates(G4State_Idle); 54 61 55 62 // Change Phantom position … … 61 68 "PositionAlongZ", false); 62 69 changeThePhantomPositionCmd -> SetDefaultUnit("mm"); 63 changeThePhantomPositionCmd -> SetUnitCandidates(" mm cm m");70 changeThePhantomPositionCmd -> SetUnitCandidates("um mm cm m"); 64 71 changeThePhantomPositionCmd -> AvailableForStates(G4State_Idle); 65 72 73 74 updateCmd = new G4UIcmdWithoutParameter("/changePhantom/update",this); 75 updateCmd->SetGuidance("Update Phantom/Detector geometry."); 76 updateCmd->SetGuidance("This command MUST be applied before \"beamOn\" "); 77 updateCmd->SetGuidance("if you changed geometrical value(s)."); 78 updateCmd->AvailableForStates(G4State_Idle); 66 79 67 80 // Change detector size … … 74 87 changeTheDetectorSizeCmd -> SetParameterName("DetectorSizeAlongX", "DetectorSizeAlongY", "DetectorSizeAlongZ", false); 75 88 changeTheDetectorSizeCmd -> SetDefaultUnit("mm"); 76 changeTheDetectorSizeCmd -> SetUnitCandidates(" um mm cm");89 changeTheDetectorSizeCmd -> SetUnitCandidates("nm um mm cm"); 77 90 changeTheDetectorSizeCmd -> AvailableForStates(G4State_Idle); 78 91 … … 85 98 "DisplacementAlongZ", false); 86 99 changeTheDetectorToPhantomPositionCmd -> SetDefaultUnit("mm"); 87 changeTheDetectorToPhantomPositionCmd -> SetUnitCandidates(" um mm cm");100 changeTheDetectorToPhantomPositionCmd -> SetUnitCandidates("nm um mm cm"); 88 101 changeTheDetectorToPhantomPositionCmd -> AvailableForStates(G4State_Idle); 89 102 … … 94 107 changeTheDetectorVoxelCmd -> SetParameterName("VoxelSizeAlongX", "VoxelSizeAlongY", "VoxelSizeAlongZ", false); 95 108 changeTheDetectorVoxelCmd -> SetDefaultUnit("mm"); 96 changeTheDetectorVoxelCmd -> SetUnitCandidates(" um mm cm");109 changeTheDetectorVoxelCmd -> SetUnitCandidates("nm um mm cm"); 97 110 changeTheDetectorVoxelCmd -> AvailableForStates(G4State_Idle); 98 111 } … … 104 117 delete changeThePhantomSizeCmd; 105 118 delete changeThePhantomPositionCmd; 119 delete changeThePhantomMaterialCmd; 120 delete updateCmd; 106 121 delete changeTheDetectorDir; 107 122 delete changeTheDetectorSizeCmd; … … 124 139 hadrontherapyDetector -> SetPhantomPosition(size); 125 140 } 141 else if (command == changeThePhantomMaterialCmd) 142 { 143 hadrontherapyDetector -> SetPhantomMaterial(newValue); 144 } 126 145 else if (command == changeTheDetectorSizeCmd) 127 146 { … … 137 156 { 138 157 G4ThreeVector size = changeTheDetectorVoxelCmd -> GetNew3VectorValue(newValue); 139 hadrontherapyDetector -> SetNumberOfVoxelBySize(size.getX(),size.getY(),size.getZ()); 158 hadrontherapyDetector -> SetVoxelSize(size.getX(),size.getY(),size.getZ()); 159 } 160 else if (command == updateCmd) 161 { 162 hadrontherapyDetector -> UpdateGeometry(); 140 163 } 141 164 } -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyEventAction.cc
r1230 r1313 24 24 // ******************************************************************** 25 25 // 26 // $Id: HadrontherapyEventAction.cc; 27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy 28 26 // $Id: HadrontherapyEventAction.cc; 27 // 28 // See more at: http://workgroup.lngs.infn.it/geant4lns 29 // 30 // ---------------------------------------------------------------------------- 31 // GEANT 4 - Hadrontherapy example 32 // ---------------------------------------------------------------------------- 33 // Code developed by: 34 // 35 // G.A.P. Cirrone(a)*, G. Candiano, F. Di Rosa(a), S. Guatelli(b), G. Russo(a) 36 // 37 // (a) Laboratori Nazionali del Sud 38 // of the National Institute for Nuclear Physics, Catania, Italy 39 // (b) National Institute for Nuclear Physics Section of Genova, genova, Italy 40 // 41 // * cirrone@lns.infn.it 42 // -------------------------------------------------------------- 29 43 #include "G4Event.hh" 30 44 #include "G4EventManager.hh" 31 45 #include "G4HCofThisEvent.hh" 32 46 #include "G4VHitsCollection.hh" 33 #include "G4TrajectoryContainer.hh"34 #include "G4Trajectory.hh"35 #include "G4VVisManager.hh"36 47 #include "G4SDManager.hh" 37 48 #include "G4VVisManager.hh" 49 38 50 #include "HadrontherapyEventAction.hh" 39 51 #include "HadrontherapyDetectorHit.hh" … … 64 76 //printing survey 65 77 if (evtNb%printModulo == 0) 66 G4cout << "\n---> Begin of Event: " << evtNb << G4endl;78 G4cout << "\n---> Begin of Event: " << evtNb << G4endl; 67 79 68 80 G4SDManager* pSDManager = G4SDManager::GetSDMpointer(); 69 81 if(hitsCollectionID == -1) 70 82 hitsCollectionID = pSDManager -> GetCollectionID("HadrontherapyDetectorHitsCollection"); 83 71 84 } 72 85 73 86 ///////////////////////////////////////////////////////////////////////////// 74 87 void HadrontherapyEventAction::EndOfEventAction(const G4Event* evt) 75 { 88 { 76 89 if(hitsCollectionID < 0) 77 90 return; 78 91 G4HCofThisEvent* HCE = evt -> GetHCofThisEvent(); 79 92 93 // Clear voxels hit list 94 HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance(); 95 if (matrix) matrix -> ClearHitTrack(); 96 80 97 if(HCE) 81 98 { … … 83 100 if(CHC) 84 101 { 85 matrix = HadrontherapyMatrix::getInstance();86 102 if(matrix) 87 103 { … … 101 117 } 102 118 } 103 // Extract the trajectories and draw them in the visualisation104 105 if (G4VVisManager::GetConcreteInstance())106 {107 G4TrajectoryContainer * trajectoryContainer = evt -> GetTrajectoryContainer();108 G4int n_trajectories = 0;109 if (trajectoryContainer) n_trajectories = trajectoryContainer -> entries();110 111 for (G4int i = 0; i < n_trajectories; i++)112 {113 G4Trajectory* trj = (G4Trajectory*)114 ((*(evt -> GetTrajectoryContainer()))[i]);115 if(drawFlag == "all") trj -> DrawTrajectory(50);116 else if((drawFlag == "charged")&&(trj -> GetCharge() != 0.))117 trj -> DrawTrajectory(50);118 else if ((drawFlag == "neutral")&&(trj -> GetCharge() == 0.))119 trj -> DrawTrajectory(50);120 }121 }122 119 } 123 120 -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyMatrix.cc
r1230 r1313 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: HadrontherapyMatrix.cc;27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy//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: HadrontherapyMatrix.cc; 27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy// 28 28 29 29 #include "HadrontherapyMatrix.hh" 30 30 #include "HadrontherapyAnalysisManager.hh" 31 #include "G4RunManager.hh" 32 #include "HadrontherapyPrimaryGeneratorAction.hh" 33 #include "G4ParticleGun.hh" 34 35 #include <fstream> 36 #include <unistd.h> 37 #include <iostream> 38 #include <sstream> 39 #include <iomanip> 31 40 #include "globals.hh" 32 #include <fstream> 33 41 42 // Units definition: CLHEP/Units/SystemOfUnits.h 43 // 34 44 HadrontherapyMatrix* HadrontherapyMatrix::instance = NULL; 35 // Static method that only return a pointer to the matrix object 36 HadrontherapyMatrix* HadrontherapyMatrix::getInstance() 37 { 38 return instance; 39 } 40 // This STATIC method delete (!) the old matrix and rewrite a new object returning a pointer to it 41 HadrontherapyMatrix* HadrontherapyMatrix::getInstance(G4int voxelX, G4int voxelY, G4int voxelZ) 42 { 43 if (instance) delete instance; 44 instance = new HadrontherapyMatrix(voxelX, voxelY, voxelZ); 45 instance -> Initialize(); 46 return instance; 47 } 48 49 HadrontherapyMatrix::HadrontherapyMatrix(G4int voxelX, G4int voxelY, G4int voxelZ): 50 matrix(0) 45 G4bool HadrontherapyMatrix::secondaries = false; 46 // Only return a pointer to matrix 47 HadrontherapyMatrix* HadrontherapyMatrix::GetInstance() 48 { 49 return instance; 50 } 51 // This STATIC method delete (!) the old matrix and rewrite a new object returning a pointer to it 52 // TODO A check on the parameters is required! 53 HadrontherapyMatrix* HadrontherapyMatrix::GetInstance(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass) 54 { 55 if (instance) delete instance; 56 instance = new HadrontherapyMatrix(voxelX, voxelY, voxelZ, mass); 57 instance -> Initialize();// XXX 58 return instance; 59 } 60 HadrontherapyMatrix::HadrontherapyMatrix(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass): 61 filename("Dose.out"), 62 doseUnit(MeV/g) 51 63 { 52 // Number of the voxels of the phantom 53 // For Y = Z = 1 the phantom is divided in slices (and not in voxels) 54 // orthogonal to the beam axis 55 numberVoxelX = voxelX; 56 numberVoxelY = voxelY; 57 numberVoxelZ = voxelZ; 58 // Create the dose matrix 59 matrix = new G4double[numberVoxelX*numberVoxelY*numberVoxelZ]; 60 if (matrix) G4cout << "Matrix: Memory space to store physical dose into " << 61 numberVoxelX*numberVoxelY*numberVoxelZ << 62 " voxels has been allocated " << G4endl; 63 else G4Exception("Can't allocate memory to store physical dose!"); 64 } 65 64 // Number of the voxels of the phantom 65 // For Y = Z = 1 the phantom is divided in slices (and not in voxels) 66 // orthogonal to the beam axis 67 numberOfVoxelAlongX = voxelX; 68 numberOfVoxelAlongY = voxelY; 69 numberOfVoxelAlongZ = voxelZ; 70 massOfVoxel = mass; 71 // Create the dose matrix 72 matrix = new G4double[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ]; 73 if (matrix) 74 { 75 G4cout << "HadrontherapyMatrix: Memory space to store physical dose into " << 76 numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ << 77 " voxels has been allocated " << G4endl; 78 } 79 else G4Exception(" HadrontherapyMatrix::HadrontherapyMatrix. Can't allocate memory to store physical dose!"); 80 // Hit voxel (TrackID) marker 81 // This array mark the status of voxel, if a hit occur, with the trackID of the particle 82 // Must be initialized 83 hitTrack = new G4int[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ]; 84 ClearHitTrack(); 85 } 86 87 ///////////////////////////////////////////////////////////////////////////// 66 88 HadrontherapyMatrix::~HadrontherapyMatrix() 67 89 { 68 90 delete[] matrix; 69 } 70 71 void HadrontherapyMatrix::flush() 72 { 73 if(matrix) 74 for(int i=0; i<numberVoxelX*numberVoxelY*numberVoxelZ; i++) 75 { 76 matrix[i] = 0; 77 } 78 } 91 delete[] hitTrack; 92 // clear fluences/dose data 93 Clear(); 94 } 95 96 ///////////////////////////////////////////////////////////////////////////// 97 void HadrontherapyMatrix::Clear() 98 { 99 for (size_t i=0; i<ionStore.size(); i++) 100 { 101 delete[] ionStore[i].dose; 102 delete[] ionStore[i].fluence; 103 } 104 ionStore.clear(); 105 } 106 107 ///////////////////////////////////////////////////////////////////////////// 108 // Initialise the elements of the matrix to zero 79 109 void HadrontherapyMatrix::Initialize() 80 110 { 81 // Initialise the elements of the matrix to zero 82 for(G4int i = 0; i < numberVoxelX; i++) 83 { 84 for(G4int j = 0; j < numberVoxelY; j++) 85 { 86 for(G4int k = 0; k < numberVoxelZ; k++) 87 88 matrix[Index(i,j,k)] = 0.; 89 } 90 } 91 } 111 Clear(); 112 for(int i=0;i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ;i++) 113 { 114 matrix[i] = 0; 115 } 116 } 117 ///////////////////////////////////////////////////////////////////////////// 118 ///////////////////////////////////////////////////////////////////////////// 119 // Print generated nuclides list 120 void HadrontherapyMatrix::PrintNuclides() 121 { 122 for (size_t i=0; i<ionStore.size(); i++) 123 { 124 G4cout << ionStore[i].name << G4endl; 125 } 126 } 127 ///////////////////////////////////////////////////////////////////////////// 128 // Clear Hit voxel (TrackID) markers 129 void HadrontherapyMatrix::ClearHitTrack() 130 { 131 for(G4int i=0; i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; i++) hitTrack[i] = 0; 132 } 133 // Return Hit status 134 G4int* HadrontherapyMatrix::GetHitTrack(G4int i, G4int j, G4int k) 135 { 136 return &(hitTrack[Index(i,j,k)]); 137 } 138 ///////////////////////////////////////////////////////////////////////////// 139 // Dose methods... 140 // Fill DOSE/fluence matrix for particle/ion: 141 // If fluence parameter is true (default value is FALSE) then fluence at voxel (i, j, k) is increased. 142 // The energyDeposit parameter fill the dose matrix for voxel (i,j,k) 143 ///////////////////////////////////////////////////////////////////////////// 144 145 G4bool HadrontherapyMatrix::Fill(G4int trackID, 146 G4ParticleDefinition* particleDef, 147 G4int i, G4int j, G4int k, 148 G4double energyDeposit, 149 G4bool fluence) 150 { 151 if (energyDeposit <=0. && !fluence || !secondaries) return false; 152 // Get Particle Data Group particle ID 153 G4int PDGencoding = particleDef -> GetPDGEncoding(); 154 PDGencoding -= PDGencoding%10; 155 156 // Search for already allocated data... 157 for (size_t l=0; l < ionStore.size(); l++) 158 { 159 if (ionStore[l].PDGencoding == PDGencoding ) 160 { // Is it a primary or a secondary particle? 161 if ( trackID ==1 && ionStore[l].isPrimary || trackID !=1 && !ionStore[l].isPrimary) 162 { 163 if (energyDeposit > 0.) ionStore[l].dose[Index(i, j, k)] += energyDeposit/massOfVoxel; 164 165 // Fill a matrix per each ion with the fluence 166 if (fluence) ionStore[l].fluence[Index(i, j, k)]++; 167 return true; 168 } 169 } 170 } 171 172 G4int Z = particleDef-> GetAtomicNumber(); 173 G4int A = particleDef-> GetAtomicMass(); 174 175 G4String fullName = particleDef -> GetParticleName(); 176 G4String name = fullName.substr (0, fullName.find("[") ); // cut excitation energy 177 // Let's put a new particle in our store... 178 ion newIon = 179 { 180 (trackID == 1) ? true:false, 181 PDGencoding, 182 name, 183 name.length(), 184 Z, 185 A, 186 new G4double[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ], 187 new unsigned int[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ] 188 }; 189 // Initialize data 190 if (newIon.dose && newIon.fluence) 191 { 192 for(G4int m=0; m<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; m++) 193 { 194 newIon.dose[m] = 0.; 195 newIon.fluence[m] = 0; 196 } 197 if (energyDeposit > 0.) newIon.dose[Index(i, j, k)] += energyDeposit/massOfVoxel; 198 if (fluence) newIon.fluence[Index(i, j, k)]++; 199 200 ionStore.push_back(newIon); 201 202 // TODO Put some verbosity check 203 /* 204 G4cout << "Memory space to store the DOSE/FLUENCE into " << 205 numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ << 206 " voxels has been allocated for the nuclide " << newIon.name << 207 " (Z = " << Z << ", A = " << A << ")" << G4endl ; 208 */ 209 return true; 210 } 211 else // XXX Out of memory! XXX 212 { 213 return false; 214 } 215 216 } 217 218 ///////////////////////////////////////////////////////////////////////////// 219 ///////////////////////////////////////////////////////////////////////////// 220 // Methods to store data to filenames... 221 //////////////////////////////////////////////////////////////////////////// 222 //////////////////////////////////////////////////////////////////////////// 223 // 224 // General method to store matrix data to filename 225 void HadrontherapyMatrix::StoreMatrix(G4String file, void* data, size_t psize) 226 { 227 if (data) 228 { 229 ofs.open(file, std::ios::out); 230 if (ofs.is_open()) 231 { 232 for(G4int i = 0; i < numberOfVoxelAlongX; i++) 233 for(G4int j = 0; j < numberOfVoxelAlongY; j++) 234 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) 235 { 236 G4int n = Index(i, j, k); 237 // Check for data type: u_int, G4double, XXX 238 if (psize == sizeof(unsigned int)) 239 { 240 unsigned int* pdata = (unsigned int*)data; 241 if (pdata[n]) ofs << i << '\t' << j << '\t' << 242 k << '\t' << pdata[n] << G4endl; 243 } 244 else if (psize == sizeof(G4double)) 245 { 246 G4double* pdata = (G4double*)data; 247 if (pdata[n]) ofs << i << '\t' << j << '\t' << 248 k << '\t' << pdata[n] << G4endl; 249 } 250 } 251 ofs.close(); 252 } 253 } 254 } 255 256 // Store fluence per single ion in multiple files 257 void HadrontherapyMatrix::StoreFluenceData() 258 { 259 for (size_t i=0; i < ionStore.size(); i++){ 260 StoreMatrix(ionStore[i].name + "_Fluence.out", ionStore[i].fluence, sizeof(unsigned int)); 261 } 262 } 263 // Store dose per single ion in multiple files 264 void HadrontherapyMatrix::StoreDoseData() 265 { 266 267 for (size_t i=0; i < ionStore.size(); i++){ 268 StoreMatrix(ionStore[i].name + "_Dose.out", ionStore[i].dose, sizeof(G4double)); 269 } 270 } 271 ///////////////////////////////////////////////////////////////////////// 272 // Store dose for all ions into a single file and into ntuples. 273 // Please note that this function is called via messenger commands 274 // defined in the HadrontherapyAnalysisFileMessenger.cc class file 275 void HadrontherapyMatrix::StoreDoseFluenceAscii() 276 { 277 // Sort like periodic table 278 std::sort(ionStore.begin(), ionStore.end()); 279 #define width 15L 280 ofs.open(filename, std::ios::out); 281 if (ofs.is_open()) 282 { 283 284 // 285 // Write the voxels index and the list of particles/ions 286 ofs << std::setprecision(6) << std::left << 287 "i\tj\tk\t"; 288 /* 289 G4RunManager *runManager = G4RunManager::GetRunManager(); 290 HadrontherapyPrimaryGeneratorAction *pPGA = (HadrontherapyPrimaryGeneratorAction*)runManager -> GetUserPrimaryGeneratorAction(); 291 G4String name = pPGA -> GetParticleGun() -> GetParticleDefinition() -> GetParticleName(); 292 */ 293 // Total dose 294 ofs << std::setw(width) << "Dose"; 295 296 for (size_t l=0; l < ionStore.size(); l++) 297 { 298 G4String a = (ionStore[l].isPrimary) ? "_1":""; // is it a primary? 299 ofs << std::setw(width) << ionStore[l].name + a << 300 std::setw(width) << ionStore[l].name + a; 301 } 302 ofs << G4endl; 303 304 /* 305 // PDGencoding 306 ofs << std::setprecision(6) << std::left << 307 "0\t0\t0\t"; 308 309 // Total dose 310 ofs << std::setw(width) << '0'; 311 for (size_t l=0; l < ionStore.size(); l++) 312 { 313 ofs << std::setw(width) << ionStore[l].PDGencoding << 314 std::setw(width) << ionStore[l].PDGencoding; 315 } 316 ofs << G4endl; 317 */ 318 // Write data 319 for(G4int i = 0; i < numberOfVoxelAlongX; i++) 320 for(G4int j = 0; j < numberOfVoxelAlongY; j++) 321 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) 322 { 323 G4int n = Index(i, j, k); 324 // Write only not identically null data lines 325 if (matrix[n]) 326 { 327 ofs << G4endl; 328 ofs << i << '\t' << j << '\t' << k << '\t'; 329 // Total dose 330 ofs << std::setw(width) << matrix[n]/(doseUnit); 331 { 332 for (size_t l=0; l < ionStore.size(); l++) 333 { 334 // Fill ASCII file rows 335 ofs << std::setw(width) << ionStore[l].dose[n]/(doseUnit) << 336 std::setw(width) << ionStore[l].fluence[n]; 337 } 338 } 339 } 340 } 341 ofs.close(); 342 } 343 } 344 ///////////////////////////////////////////////////////////////////////////// 345 346 #ifdef G4ANALYSIS_USE_ROOT 347 void HadrontherapyMatrix::StoreDoseFluenceRoot() 348 { 349 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); 350 for(G4int i = 0; i < numberOfVoxelAlongX; i++) 351 for(G4int j = 0; j < numberOfVoxelAlongY; j++) 352 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) 353 { 354 G4int n = Index(i, j, k); 355 for (size_t l=0; l < ionStore.size(); l++) 356 357 { 358 // Do the same work for .root file: fill dose/fluence ntuple 359 analysis -> FillVoxelFragmentTuple( i, j, k, 360 ionStore[l].A, 361 ionStore[l].Z, 362 ionStore[l].dose[n]/(doseUnit), 363 ionStore[l].fluence[n] ); 364 365 366 } 367 } 368 } 369 #endif 92 370 93 371 void HadrontherapyMatrix::Fill(G4int i, G4int j, G4int k, 94 372 G4double energyDeposit) 95 373 { 96 if (matrix) 97 matrix[Index(i,j,k)] += energyDeposit; 98 99 // Store the energy deposit in the matrix element corresponding 100 // to the phantom voxel i, j, k 101 } 102 374 if (matrix) 375 matrix[Index(i,j,k)] += energyDeposit; 376 377 // Store the energy deposit in the matrix element corresponding 378 // to the phantom voxel 379 } 103 380 void HadrontherapyMatrix::TotalEnergyDeposit() 104 381 { 382 // Convert energy deposited to dose. 105 383 // Store the information of the matrix in a ntuple and in 106 384 // a 1D Histogram 107 385 108 G4int k; 109 G4int j; 110 G4int i; 111 112 if (matrix) 386 #ifdef G4ANALYSIS_USE_ROOT 387 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); 388 #endif 389 if (matrix) 113 390 { 114 std::ofstream ofs; 115 ofs.open("DoseDistribution.out"); 116 117 for(G4int l = 0; l < numberVoxelZ; l++) 118 { 119 k = l; 120 121 for(G4int m = 0; m < numberVoxelY; m++) 122 { 123 j = m * numberVoxelZ + k; 124 125 for(G4int n = 0; n < numberVoxelX; n++) 126 { 127 i = n* numberVoxelZ * numberVoxelY + j; 128 if(matrix[i] != 0) 129 { 130 ofs << n << '\t' << m << '\t' << 131 k << '\t' << matrix[i] << G4endl; 132 133 #ifdef ANALYSIS_USE 134 HadrontherapyAnalysisManager* analysis = 135 HadrontherapyAnalysisManager::getInstance(); 136 analysis -> FillEnergyDeposit(n, m, k, matrix[i]); 137 analysis -> BraggPeak(n, matrix[i]); 391 for(G4int i = 0; i < numberOfVoxelAlongX; i++) 392 for(G4int j = 0; j < numberOfVoxelAlongY; j++) 393 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) 394 { 395 G4int n = Index(i,j,k); 396 matrix[n] = matrix[n] / massOfVoxel; 397 #ifdef G4ANALYSIS_USE_ROOT 398 analysis -> FillEnergyDeposit(i, j, k, matrix[n]/doseUnit); 399 analysis -> BraggPeak(i, matrix[n]/doseUnit); 138 400 #endif 139 } 140 } 141 } 142 } 143 } 144 } 401 } 402 } 403 } 404 -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyPhysicsList.cc
r1230 r1313 76 76 // and local physic for ion-ion enelastic processes) 77 77 78 #include "G4RunManager.hh" 79 #include "G4Region.hh" 80 #include "G4RegionStore.hh" 78 81 #include "HadrontherapyPhysicsList.hh" 79 82 #include "HadrontherapyPhysicsListMessenger.hh" … … 86 89 #include "LocalINCLIonIonInelasticPhysic.hh" // Physic dedicated to the ion-ion inelastic processes using INCL/ABLA 87 90 88 // Physic lists (contained inside the Geant4 distribution)91 // Physic lists (contained inside the Geant4 source code, in the 'physicslists folder') 89 92 #include "G4EmStandardPhysics_option3.hh" 90 93 #include "G4EmLivermorePhysics.hh" … … 173 176 { 174 177 // transportation 175 //176 178 AddTransportation(); 177 179 178 180 // electromagnetic physics list 179 //180 181 emPhysicsList->ConstructProcess(); 181 182 em_config.AddModels(); 182 183 183 184 // decay physics list 184 //185 185 decPhysicsList->ConstructProcess(); 186 186 … … 207 207 // ELECTROMAGNETIC MODELS 208 208 ///////////////////////////////////////////////////////////////////////////// 209 210 if (name == "standard_opt3") { 209 if (name == "standard_opt3") { 211 210 emName = name; 212 211 delete emPhysicsList; 213 212 emPhysicsList = new G4EmStandardPhysics_option3(); 213 G4RunManager::GetRunManager() -> PhysicsHasBeenModified(); 214 214 G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmStandardPhysics_option3" << G4endl; 215 215 … … 218 218 delete emPhysicsList; 219 219 emPhysicsList = new G4EmLivermorePhysics(); 220 G4RunManager::GetRunManager()-> PhysicsHasBeenModified(); 220 221 G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmLivermorePhysics" << G4endl; 221 222 … … 308 309 SetCutValue(cutForPositron, "e+"); 309 310 311 // Set cuts for detector 312 SetDetectorCut(defaultCutValue); 310 313 if (verboseLevel>0) DumpCutValuesTable(); 311 314 } … … 331 334 SetParticleCuts(cutForPositron, G4Positron::Positron()); 332 335 } 336 337 void HadrontherapyPhysicsList::SetDetectorCut(G4double cut) 338 { 339 340 G4String regionName = "DetectorLog"; 341 G4Region* region = G4RegionStore::GetInstance()->GetRegion(regionName); 342 343 G4ProductionCuts* cuts = new G4ProductionCuts ; 344 cuts -> SetProductionCut(cut,G4ProductionCuts::GetIndex("gamma")); 345 cuts -> SetProductionCut(cut,G4ProductionCuts::GetIndex("e-")); 346 cuts -> SetProductionCut(cut,G4ProductionCuts::GetIndex("e+")); 347 region -> SetProductionCuts(cuts); 348 } 349 -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyPhysicsListMessenger.cc
r1230 r1313 69 69 allCutCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 70 70 71 allDetectorCmd = new G4UIcmdWithADoubleAndUnit("/physic/setDetectorCuts",this); 72 allDetectorCmd->SetGuidance("Set cut for all. into Detector"); 73 allDetectorCmd->SetParameterName("cut",false); 74 allDetectorCmd->SetUnitCategory("Length"); 75 allDetectorCmd->SetRange("cut>0.0"); 76 allDetectorCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 77 71 78 pListCmd = new G4UIcmdWithAString("/physic/addPhysics",this); 72 79 pListCmd->SetGuidance("Add physics list."); 73 80 pListCmd->SetParameterName("PList",false); 74 pListCmd->AvailableForStates(G4State_PreInit );81 pListCmd->AvailableForStates(G4State_PreInit, G4State_Idle); 75 82 76 83 packageListCmd = new G4UIcmdWithAString("/physic/addPackage",this); 77 84 packageListCmd->SetGuidance("Add physics package."); 78 85 packageListCmd->SetParameterName("package",false); 79 packageListCmd->AvailableForStates(G4State_PreInit );86 packageListCmd->AvailableForStates(G4State_PreInit, G4State_Idle); 80 87 } 81 88 … … 87 94 delete protoCutCmd; 88 95 delete allCutCmd; 96 delete allDetectorCmd; 89 97 delete pListCmd; 90 98 delete physDir; … … 99 107 { pPhysicsList->SetCutForGamma(gammaCutCmd->GetNewDoubleValue(newValue));} 100 108 101 if( command == electCutCmd )109 else if( command == electCutCmd ) 102 110 { pPhysicsList->SetCutForElectron(electCutCmd->GetNewDoubleValue(newValue));} 103 111 104 if( command == protoCutCmd )112 else if( command == protoCutCmd ) 105 113 { pPhysicsList->SetCutForPositron(protoCutCmd->GetNewDoubleValue(newValue));} 106 114 107 if( command == allCutCmd )115 else if( command == allCutCmd ) 108 116 { 109 117 G4double cut = allCutCmd->GetNewDoubleValue(newValue); … … 112 120 pPhysicsList->SetCutForPositron(cut); 113 121 } 114 115 if( command == pListCmd ) 122 else if( command == allDetectorCmd) 123 { 124 G4double cut = allDetectorCmd -> GetNewDoubleValue(newValue); 125 pPhysicsList -> SetDetectorCut(cut); 126 } 127 else if( command == pListCmd ) 116 128 { pPhysicsList->AddPhysicsList(newValue);} 117 129 118 130 119 if( command == packageListCmd )131 else if( command == packageListCmd ) 120 132 { pPhysicsList->AddPackage(newValue);} 121 133 -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyPrimaryGeneratorAction.cc
r1230 r1313 86 86 sigmaEnergy = defaultsigmaEnergy; 87 87 88 #ifdef ANALYSIS_USE88 #ifdef G4ANALYSIS_USE_ROOT 89 89 // Write these values into the analysis if needed. Have to be written separately on change. 90 HadrontherapyAnalysisManager:: getInstance()->setBeamMetaData(meanKineticEnergy, sigmaEnergy);90 HadrontherapyAnalysisManager::GetInstance()->setBeamMetaData(meanKineticEnergy, sigmaEnergy); 91 91 #endif 92 92 … … 120 120 void HadrontherapyPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) 121 121 { 122 #ifdef ANALYSIS_USE122 #ifdef G4ANALYSIS_USE_ROOT 123 123 // Increment the event counter 124 HadrontherapyAnalysisManager:: getInstance()->startNewEvent();124 HadrontherapyAnalysisManager::GetInstance()->startNewEvent(); 125 125 #endif 126 126 … … 178 178 { 179 179 meanKineticEnergy = val; 180 #ifdef ANALYSIS_USE180 #ifdef G4ANALYSIS_USE_ROOT 181 181 // Update the beam-data in the analysis manager 182 HadrontherapyAnalysisManager:: getInstance()->setBeamMetaData(meanKineticEnergy, sigmaEnergy);182 HadrontherapyAnalysisManager::GetInstance()->setBeamMetaData(meanKineticEnergy, sigmaEnergy); 183 183 #endif 184 184 … … 188 188 { 189 189 sigmaEnergy = val; 190 #ifdef ANALYSIS_USE190 #ifdef G4ANALYSIS_USE_ROOT 191 191 // Update the sigmaenergy in the metadata. 192 HadrontherapyAnalysisManager:: getInstance()->setBeamMetaData(meanKineticEnergy, sigmaEnergy);192 HadrontherapyAnalysisManager::GetInstance()->setBeamMetaData(meanKineticEnergy, sigmaEnergy); 193 193 #endif 194 194 } … … 217 217 G4double HadrontherapyPrimaryGeneratorAction::GetmeanKineticEnergy(void) 218 218 { return meanKineticEnergy;} 219 -
trunk/examples/advanced/hadrontherapy/src/HadrontherapyRunAction.cc
r1230 r1313 27 27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy 28 28 29 29 30 #include "HadrontherapyRunAction.hh" 30 31 #include "HadrontherapyEventAction.hh" … … 38 39 #include "HadrontherapyRunAction.hh" 39 40 41 42 #include "HadrontherapyAnalysisManager.hh" 43 #include "HadrontherapyMatrix.hh" 44 40 45 HadrontherapyRunAction::HadrontherapyRunAction() 41 46 { … … 48 53 void HadrontherapyRunAction::BeginOfRunAction(const G4Run* aRun) 49 54 { 50 G4RunManager::GetRunManager()->SetRandomNumberStore(true);51 G4cout << "Run " << aRun -> GetRunID() << " starts ..." << G4endl;55 G4RunManager::GetRunManager()-> SetRandomNumberStore(true); 56 G4cout << "Run " << aRun -> GetRunID() << " starts ..." << G4endl; 52 57 53 electromagnetic = 0; 54 hadronic = 0; 58 // Warning! any beamOn will reset all data (dose, fluence, histograms, etc)! 59 // 60 61 // Initialize matrix with energy of primaries clearing data inside 62 if (HadrontherapyMatrix::GetInstance()) 63 { 64 HadrontherapyMatrix::GetInstance() -> Initialize(); 65 } 66 67 #ifdef G4ANALYSIS_USE_ROOT 68 HadrontherapyAnalysisManager::GetInstance() -> flush(); // Finalize the root file 69 // Initialize root analysis ----> book 70 HadrontherapyAnalysisManager::GetInstance() -> book(); 71 #endif 72 electromagnetic = 0; 73 hadronic = 0; 55 74 } 56 75 57 76 void HadrontherapyRunAction::EndOfRunAction(const G4Run*) 58 77 { 59 // G4cout << " Summary of Run " << aRun -> GetRunID() <<" :"<< G4endl; 60 //G4cout << "Number of electromagnetic processes of primary particles in the phantom:" 61 // << electromagnetic << G4endl; 62 //G4cout << "Number of hadronic processes of primary particles in the phantom:" 63 // << hadronic << G4endl; 78 // Store dose & fluence data to ASCII & ROOT files 79 if ( HadrontherapyMatrix::GetInstance() ) 80 { 81 HadrontherapyMatrix::GetInstance() -> TotalEnergyDeposit(); 82 HadrontherapyMatrix::GetInstance() -> StoreDoseFluenceAscii(); 83 84 #ifdef G4ANALYSIS_USE_ROOT 85 if (HadrontherapyAnalysisManager::GetInstance()) 86 { 87 HadrontherapyMatrix::GetInstance() -> StoreDoseFluenceRoot(); 88 } 89 #endif 90 } 91 92 //G4cout << " Summary of Run " << aRun -> GetRunID() <<" :"<< G4endl; 93 //G4cout << "Number of electromagnetic processes of primary particles in the phantom:" 94 // << electromagnetic << G4endl; 95 //G4cout << "Number of hadronic processes of primary particles in the phantom:" 96 // << hadronic << G4endl; 64 97 } 65 98 void HadrontherapyRunAction::AddEMProcess() … … 72 105 } 73 106 74 75 -
trunk/examples/advanced/hadrontherapy/src/HadrontherapySteppingAction.cc
r1230 r1313 39 39 #include "G4ParticleDefinition.hh" 40 40 #include "G4ParticleTypes.hh" 41 #include "G4UserEventAction.hh" 41 42 42 43 #include "HadrontherapyAnalysisManager.hh" … … 47 48 HadrontherapySteppingAction::HadrontherapySteppingAction( HadrontherapyRunAction *run) 48 49 { 49 runAction = run;50 runAction = run; 50 51 } 51 52 … … 58 59 void HadrontherapySteppingAction::UserSteppingAction(const G4Step* aStep) 59 60 { 61 /* 62 // USEFULL METHODS TO RETRIEVE INFORMATION DURING THE STEPS 63 if( (aStep->GetTrack()->GetVolume()->GetName() == "DetectorPhys") 64 && aStep->GetTrack()->GetDefinition()->GetParticleName() == "proton") 65 //G4int evtNb = G4RunManager::GetRunManager()->GetCurrentEvent() -> GetEventID(); 66 { 67 G4cout << "ENERGIA: " << aStep->GetTrack()->GetKineticEnergy() 68 << " VOLUME " << aStep->GetTrack()->GetVolume()->GetName() 69 << " MATERIALE " << aStep -> GetTrack() -> GetMaterial() -> GetName() 70 << " EVENTO " << G4RunManager::GetRunManager()->GetCurrentEvent() -> GetEventID() 71 << " POS " << aStep->GetTrack()->GetPosition().x() 72 << G4endl; 73 } 74 */ 75 60 76 if( aStep->GetTrack()->GetVolume()->GetName() == "NewDetectorPhys"){ 61 #ifdef ANALYSIS_USE62 G4ParticleDefinition *def = aStep->GetTrack()->GetDefinition();63 G4double secondaryParticleKineticEnergy = aStep->GetTrack()->GetKineticEnergy();64 G4String particleType = def->GetParticleType(); // particle type = nucleus for d, t, He3, alpha, and heavier nuclei65 G4String particleName = def->GetParticleName(); // e.g. for alpha: the name = "alpha" and type = "nucleus"66 if(particleType == "nucleus") {67 G4int A = def->GetBaryonNumber();68 G4double Z = def->GetPDGCharge();69 G4double posX = aStep->GetTrack()->GetPosition().x() / cm;70 G4double posY = aStep->GetTrack()->GetPosition().y() / cm;71 G4double posZ = aStep->GetTrack()->GetPosition().z() / cm;72 G4double energy = secondaryParticleKineticEnergy / A / MeV;73 74 HadrontherapyAnalysisManager* analysisMgr = HadrontherapyAnalysisManager::getInstance();75 analysisMgr->fillFragmentTuple(A, Z, energy, posX, posY, posZ);76 } else if(particleName == "proton") { // proton (hydrogen-1) is a special case77 G4double posX = aStep->GetTrack()->GetPosition().x() / cm ;78 G4double posY = aStep->GetTrack()->GetPosition().y() / cm ;79 G4double posZ = aStep->GetTrack()->GetPosition().z() / cm ;80 G4double energy = secondaryParticleKineticEnergy * MeV; // Hydrogen-1: A = 1, Z = 181 HadrontherapyAnalysisManager::getInstance()->fillFragmentTuple(1, 1.0, energy, posX, posY, posZ);82 }83 84 G4String secondaryParticleName = def -> GetParticleName();85 //G4cout <<"Particle: " << secondaryParticleName << G4endl;86 //G4cout <<"Energy: " << secondaryParticleKineticEnergy << G4endl;87 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager:: getInstance();77 #ifdef G4ANALYSIS_USE_ROOT 78 G4ParticleDefinition *def = aStep->GetTrack()->GetDefinition(); 79 G4double secondaryParticleKineticEnergy = aStep->GetTrack()->GetKineticEnergy(); 80 G4String particleType = def->GetParticleType(); // particle type = nucleus for d, t, He3, alpha, and heavier nuclei 81 G4String particleName = def->GetParticleName(); // e.g. for alpha: the name = "alpha" and type = "nucleus" 82 if(particleType == "nucleus") { 83 G4int A = def->GetBaryonNumber(); 84 G4double Z = def->GetPDGCharge(); 85 G4double posX = aStep->GetTrack()->GetPosition().x() / cm; 86 G4double posY = aStep->GetTrack()->GetPosition().y() / cm; 87 G4double posZ = aStep->GetTrack()->GetPosition().z() / cm; 88 G4double energy = secondaryParticleKineticEnergy / A / MeV; 89 90 HadrontherapyAnalysisManager* analysisMgr = HadrontherapyAnalysisManager::GetInstance(); 91 analysisMgr->FillFragmentTuple(A, Z, energy, posX, posY, posZ); 92 } else if(particleName == "proton") { // proton (hydrogen-1) is a special case 93 G4double posX = aStep->GetTrack()->GetPosition().x() / cm ; 94 G4double posY = aStep->GetTrack()->GetPosition().y() / cm ; 95 G4double posZ = aStep->GetTrack()->GetPosition().z() / cm ; 96 G4double energy = secondaryParticleKineticEnergy * MeV; // Hydrogen-1: A = 1, Z = 1 97 HadrontherapyAnalysisManager::GetInstance()->FillFragmentTuple(1, 1.0, energy, posX, posY, posZ); 98 } 99 100 G4String secondaryParticleName = def -> GetParticleName(); 101 //G4cout <<"Particle: " << secondaryParticleName << G4endl; 102 //G4cout <<"Energy: " << secondaryParticleKineticEnergy << G4endl; 103 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); 88 104 //There is a bunch of stuff recorded with the energy 0, something should perhaps be done about this. 89 105 if(secondaryParticleName == "proton") { 90 analysis->hydrogenEnergy(secondaryParticleKineticEnergy / MeV);106 analysis->hydrogenEnergy(secondaryParticleKineticEnergy / MeV); 91 107 } 92 108 if(secondaryParticleName == "deuteron") { 93 analysis->hydrogenEnergy((secondaryParticleKineticEnergy/2) / MeV);109 analysis->hydrogenEnergy((secondaryParticleKineticEnergy/2) / MeV); 94 110 } 95 111 if(secondaryParticleName == "triton") { 96 analysis->hydrogenEnergy((secondaryParticleKineticEnergy/3) / MeV);112 analysis->hydrogenEnergy((secondaryParticleKineticEnergy/3) / MeV); 97 113 } 98 114 if(secondaryParticleName == "alpha") { 99 analysis->heliumEnergy((secondaryParticleKineticEnergy/4) / MeV);115 analysis->heliumEnergy((secondaryParticleKineticEnergy/4) / MeV); 100 116 } 101 117 if(secondaryParticleName == "He3"){ 102 analysis->heliumEnergy((secondaryParticleKineticEnergy/3) / MeV);118 analysis->heliumEnergy((secondaryParticleKineticEnergy/3) / MeV); 103 119 } 104 120 #endif … … 107 123 } 108 124 109 // Electromagnetic and hadronic processes of primary particles in the phantom 110 //setting phantomPhys correctly will break something here fixme 111 if ((aStep -> GetTrack() -> GetTrackID() == 1) && 112 (aStep -> GetTrack() -> GetVolume() -> GetName() == "PhantomPhys") && 113 (aStep -> GetPostStepPoint() -> GetProcessDefinedStep() != NULL)) 125 // Electromagnetic and hadronic processes of primary particles in the phantom 126 //setting phantomPhys correctly will break something here fixme 127 if ((aStep -> GetTrack() -> GetTrackID() == 1) && 128 (aStep -> GetTrack() -> GetVolume() -> GetName() == "PhantomPhys") && 129 (aStep -> GetPostStepPoint() -> GetProcessDefinedStep() != NULL)) 130 { 131 G4String process = aStep -> GetPostStepPoint() -> 132 GetProcessDefinedStep() -> GetProcessName(); 133 134 if ((process == "Transportation") || (process == "StepLimiter")) {;} 135 else 136 { 137 if ((process == "msc") || (process == "hLowEIoni") || (process == "hIoni")) 138 { 139 runAction -> AddEMProcess(); 140 } 141 else 114 142 { 115 G4String process = aStep -> GetPostStepPoint() -> 116 GetProcessDefinedStep() -> GetProcessName(); 117 118 if ((process == "Transportation") || (process == "StepLimiter")) {;} 119 else { 120 if ((process == "msc") || (process == "hLowEIoni") || (process == "hIoni")) 121 { 122 runAction -> AddEMProcess(); 123 } 124 else 125 { 126 runAction -> AddHadronicProcess(); 127 128 if ( (process != "LElastic") && (process != "ProtonInelastic") && (process != "hElastic") ) 129 G4cout << "Warning! Unknown proton process: "<< process << G4endl; 130 } 131 } 143 runAction -> AddHadronicProcess(); 144 145 if ( (process != "LElastic") && (process != "ProtonInelastic") && (process != "hElastic") ) 146 G4cout << "Warning! Unknown proton process: "<< process << G4endl; 132 147 } 133 134 // Retrieve information about the secondaries originated in the phantom 135 136 G4SteppingManager* steppingManager = fpSteppingManager; 137 138 // check if it is alive 139 //if(theTrack-> GetTrackStatus() == fAlive) { return; } 140 141 // Retrieve the secondary particles 142 G4TrackVector* fSecondary = steppingManager -> GetfSecondary(); 143 144 for(size_t lp1=0;lp1<(*fSecondary).size(); lp1++) 148 } 149 } 150 151 // Retrieve information about the secondaries originated in the phantom 152 153 G4SteppingManager* steppingManager = fpSteppingManager; 154 155 // check if it is alive 156 //if(theTrack-> GetTrackStatus() == fAlive) { return; } 157 158 // Retrieve the secondary particles 159 G4TrackVector* fSecondary = steppingManager -> GetfSecondary(); 160 161 for(size_t lp1=0;lp1<(*fSecondary).size(); lp1++) 145 162 { 146 G4String volumeName = (*fSecondary)[lp1] -> GetVolume() -> GetName();147 148 if (volumeName == "phantomPhys")163 G4String volumeName = (*fSecondary)[lp1] -> GetVolume() -> GetName(); 164 165 if (volumeName == "phantomPhys") 149 166 { 150 #ifdef ANALYSIS_USE151 G4String secondaryParticleName = (*fSecondary)[lp1]->GetDefinition() -> GetParticleName();152 G4double secondaryParticleKineticEnergy = (*fSecondary)[lp1] -> GetKineticEnergy();153 154 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::getInstance();155 156 if (secondaryParticleName == "e-")157 analysis -> electronEnergyDistribution(secondaryParticleKineticEnergy/MeV);158 159 if (secondaryParticleName == "gamma")160 analysis -> gammaEnergyDistribution(secondaryParticleKineticEnergy/MeV);161 162 if (secondaryParticleName == "deuteron")163 analysis -> deuteronEnergyDistribution(secondaryParticleKineticEnergy/MeV);164 165 if (secondaryParticleName == "triton")166 analysis -> tritonEnergyDistribution(secondaryParticleKineticEnergy/MeV);167 168 if (secondaryParticleName == "alpha")169 analysis -> alphaEnergyDistribution(secondaryParticleKineticEnergy/MeV);170 171 G4double z = (*fSecondary)[lp1]-> GetDynamicParticle() -> GetDefinition() -> GetPDGCharge();172 if (z > 0.)173 {174 G4int a = (*fSecondary)[lp1]-> GetDynamicParticle() -> GetDefinition() -> GetBaryonNumber();175 G4int electronOccupancy = (*fSecondary)[lp1] -> GetDynamicParticle() -> GetTotalOccupancy();176 177 // If a generic ion is originated in the detector, its baryonic number, PDG charge,178 // total number of electrons in the orbitals are stored in a ntuple179 analysis -> genericIonInformation(a, z, electronOccupancy, secondaryParticleKineticEnergy/MeV);167 #ifdef G4ANALYSIS_USE_ROOT 168 G4String secondaryParticleName = (*fSecondary)[lp1]->GetDefinition() -> GetParticleName(); 169 G4double secondaryParticleKineticEnergy = (*fSecondary)[lp1] -> GetKineticEnergy(); 170 171 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); 172 173 if (secondaryParticleName == "e-") 174 analysis -> electronEnergyDistribution(secondaryParticleKineticEnergy/MeV); 175 176 if (secondaryParticleName == "gamma") 177 analysis -> gammaEnergyDistribution(secondaryParticleKineticEnergy/MeV); 178 179 if (secondaryParticleName == "deuteron") 180 analysis -> deuteronEnergyDistribution(secondaryParticleKineticEnergy/MeV); 181 182 if (secondaryParticleName == "triton") 183 analysis -> tritonEnergyDistribution(secondaryParticleKineticEnergy/MeV); 184 185 if (secondaryParticleName == "alpha") 186 analysis -> alphaEnergyDistribution(secondaryParticleKineticEnergy/MeV); 187 188 G4double z = (*fSecondary)[lp1]-> GetDynamicParticle() -> GetDefinition() -> GetPDGCharge(); 189 if (z > 0.) 190 { 191 G4int a = (*fSecondary)[lp1]-> GetDynamicParticle() -> GetDefinition() -> GetBaryonNumber(); 192 G4int electronOccupancy = (*fSecondary)[lp1] -> GetDynamicParticle() -> GetTotalOccupancy(); 193 194 // If a generic ion is originated in the detector, its baryonic number, PDG charge, 195 // total number of electrons in the orbitals are stored in a ntuple 196 analysis -> genericIonInformation(a, z, electronOccupancy, secondaryParticleKineticEnergy/MeV); 180 197 } 181 198 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
