Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // Hadrontherapy advanced example for Geant4 << 26 // This is the *BASIC* version of Hadrontherapy, a Geant4-based application 27 // See more at: https://twiki.cern.ch/twiki/bi << 27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy >> 28 // >> 29 // Visit the Hadrontherapy web site (http://www.lns.infn.it/link/Hadrontherapy) to request >> 30 // the *COMPLETE* version of this program, together with its documentation; >> 31 // Hadrontherapy (both basic and full version) are supported by the Italian INFN >> 32 // Institute in the framework of the MC-INFN Group >> 33 // >> 34 28 35 29 #include "HadrontherapyDetectorSD.hh" 36 #include "HadrontherapyDetectorSD.hh" 30 #include "HadrontherapyDetectorHit.hh" 37 #include "HadrontherapyDetectorHit.hh" 31 #include "G4Step.hh" 38 #include "G4Step.hh" 32 #include "G4VTouchable.hh" 39 #include "G4VTouchable.hh" 33 #include "G4TouchableHistory.hh" 40 #include "G4TouchableHistory.hh" 34 #include "G4SDManager.hh" 41 #include "G4SDManager.hh" 35 #include "HadrontherapyMatrix.hh" 42 #include "HadrontherapyMatrix.hh" 36 #include "HadrontherapyLet.hh" 43 #include "HadrontherapyLet.hh" 37 #include "G4Track.hh" 44 #include "G4Track.hh" >> 45 #include "HadrontherapyAnalysisManager.hh" 38 #include "G4SystemOfUnits.hh" 46 #include "G4SystemOfUnits.hh" 39 #include "HadrontherapyMatrix.hh" << 40 << 41 << 42 #include "G4SteppingManager.hh" << 43 #include "G4TrackVector.hh" << 44 #include "HadrontherapySteppingAction.hh" << 45 #include "G4ios.hh" << 46 #include "G4SteppingManager.hh" << 47 #include "G4Track.hh" << 48 #include "G4Step.hh" << 49 #include "G4StepPoint.hh" << 50 #include "G4TrackStatus.hh" << 51 #include "G4TrackVector.hh" << 52 #include "G4ParticleDefinition.hh" << 53 #include "G4ParticleTypes.hh" << 54 #include "G4UserEventAction.hh" << 55 #include "G4TransportationManager.hh" << 56 #include "G4VSensitiveDetector.hh" << 57 #include "HadrontherapyRunAction.hh" << 58 #include "G4SystemOfUnits.hh" << 59 #include "HadrontherapyRBE.hh" << 60 #include <G4AccumulableManager.hh> << 61 << 62 47 63 ////////////////////////////////////////////// 48 ///////////////////////////////////////////////////////////////////////////// 64 HadrontherapyDetectorSD::HadrontherapyDetector 49 HadrontherapyDetectorSD::HadrontherapyDetectorSD(G4String name): 65 G4VSensitiveDetector(name) << 50 G4VSensitiveDetector(name) 66 { << 51 { 67 G4String HCname; 52 G4String HCname; 68 collectionName.insert(HCname="Hadrontherap 53 collectionName.insert(HCname="HadrontherapyDetectorHitsCollection"); 69 HitsCollection = NULL; << 54 HitsCollection = NULL; 70 sensitiveDetectorName = name; 55 sensitiveDetectorName = name; 71 << 56 72 } 57 } 73 58 74 ////////////////////////////////////////////// 59 ///////////////////////////////////////////////////////////////////////////// 75 HadrontherapyDetectorSD::~HadrontherapyDetecto 60 HadrontherapyDetectorSD::~HadrontherapyDetectorSD() 76 {} << 61 { >> 62 } 77 63 78 ////////////////////////////////////////////// 64 ///////////////////////////////////////////////////////////////////////////// 79 void HadrontherapyDetectorSD::Initialize(G4HCo 65 void HadrontherapyDetectorSD::Initialize(G4HCofThisEvent*) 80 { 66 { 81 << 67 82 HitsCollection = new HadrontherapyDetector 68 HitsCollection = new HadrontherapyDetectorHitsCollection(sensitiveDetectorName, 83 << 69 collectionName[0]); 84 } 70 } 85 71 86 ////////////////////////////////////////////// 72 ///////////////////////////////////////////////////////////////////////////// 87 G4bool HadrontherapyDetectorSD::ProcessHits(G4 73 G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* ) 88 { 74 { 89 << 75 90 << 76 91 if (aStep -> GetPreStepPoint() -> GetPhysi << 77 if (aStep -> GetPreStepPoint() -> GetPhysicalVolume() -> GetName() != "RODetectorZDivisionPhys") return false; 92 << 78 93 << 79 94 // Get kinetic energy 80 // Get kinetic energy 95 G4Track * theTrack = aStep -> GetTrack() 81 G4Track * theTrack = aStep -> GetTrack(); 96 G4double kineticEnergy = theTrack->GetKine << 82 G4double kineticEnergy = theTrack -> GetKineticEnergy(); >> 83 97 G4ParticleDefinition *particleDef = theTra 84 G4ParticleDefinition *particleDef = theTrack -> GetDefinition(); 98 //Get particle name << 85 //Get particle name 99 G4String particleName = particleDef -> Ge << 86 G4String particleName = particleDef -> GetParticleName(); 100 << 87 101 // Get particle PDG code << 102 G4int pdg = particleDef ->GetPDGEncoding() 88 G4int pdg = particleDef ->GetPDGEncoding(); 103 << 89 104 // Get unique track_id (in an event) 90 // Get unique track_id (in an event) 105 G4int trackID = theTrack -> GetTrackID(); 91 G4int trackID = theTrack -> GetTrackID(); 106 << 92 107 G4double energyDeposit = aStep -> GetTotal 93 G4double energyDeposit = aStep -> GetTotalEnergyDeposit(); 108 << 94 109 G4double DX = aStep -> GetStepLength(); 95 G4double DX = aStep -> GetStepLength(); 110 G4int Z = particleDef-> GetAtomicNumber(); 96 G4int Z = particleDef-> GetAtomicNumber(); 111 G4int A = particleDef-> GetAtomicMass(); 97 G4int A = particleDef-> GetAtomicMass(); 112 G4StepPoint* PreStep = aStep->GetPreStepPo << 98 113 << 99 114 // Read voxel indexes: i is the x index, k << 100 // Read voxel indexes: i is the x index, k is the z index 115 const G4VTouchable* touchable = aStep->Get << 101 const G4VTouchable* touchable = aStep->GetPreStepPoint()->GetTouchable(); 116 G4int k = touchable->GetReplicaNumber(0); << 102 G4int k = touchable->GetReplicaNumber(0); 117 G4int i = touchable->GetReplicaNumber(2); << 103 G4int i = touchable->GetReplicaNumber(2); 118 G4int j = touchable->GetReplicaNumber(1); << 104 G4int j = touchable->GetReplicaNumber(1); 119 << 120 G4TouchableHandle touchPreStep = PreStep-> << 121 G4VPhysicalVolume* volumePre = touchPreSte << 122 G4String namePre = volumePre->GetName(); << 123 << 124 105 125 106 >> 107 >> 108 #ifdef G4ANALYSIS_USE_ROOT >> 109 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); >> 110 #endif >> 111 126 HadrontherapyMatrix* matrix = Hadrontherap 112 HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance(); 127 HadrontherapyLet* let = HadrontherapyLet:: 113 HadrontherapyLet* let = HadrontherapyLet::GetInstance(); 128 114 129 G4int* hitTrack = matrix -> GetHitTrack(i, << 130 115 131 << 116 // ******************** let *************************** 132 // ******************** let ************* << 117 if (let) 133 if (let) << 118 { >> 119 if ( !(Z==0 && A==1) ) // All but not neutrons 134 { 120 { 135 if ( !(Z==0 && A==1) ) // All but not << 121 if( energyDeposit>0. && DX >0. ) 136 { << 122 { 137 if( energyDeposit>0. && DX >0. )// << 123 if (pdg !=22) // not gamma 138 { << 124 { 139 if (pdg !=22 && pdg !=11) // n << 125 let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i, j, k); 140 { << 126 } 141 << 127 else if (kineticEnergy > 50.*keV) // gamma cut 142 // Get the pre-step kineti << 128 { 143 G4double eKinPre = aStep - << 129 let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i , j, k); 144 // Get the post-step kinet << 130 } 145 G4double eKinPost = aStep << 131 146 // Get the step average ki << 132 } 147 G4double eKinMean = (eKinP << 133 } 148 << 149 // get the material << 150 const G4Material * materia << 151 << 152 // get the secondary patic << 153 G4Step fstep = *theTrack - << 154 // store all the secondary << 155 const std::vector<const G4 << 156 << 157 size_t SecondarySize = (*s << 158 G4double EnergySecondary = << 159 << 160 // get secondary electrons << 161 if (SecondarySize) // calc << 162 { << 163 for (size_t numsec = 0 << 164 { << 165 //Get the PDG code << 166 G4int PDGSecondary << 167 << 168 if(PDGSecondary == << 169 { << 170 // calculate t << 171 EnergySecondar << 172 } << 173 } << 174 << 175 } << 176 << 177 // call the let filldatas << 178 let -> FillEnergySpectrum( << 179 << 180 } << 181 } << 182 } << 183 } 134 } 184 135 185 136 >> 137 >> 138 // ******************** let *************************** >> 139 >> 140 186 if (matrix) 141 if (matrix) 187 { 142 { 188 << 189 // Increment Fluences & accumulate ene << 190 // Hit voxels are marked with track_id << 191 //G4int* hitTrack = matrix -> GetHitTr << 192 if ( *hitTrack != trackID ) << 193 { << 194 *hitTrack = trackID; << 195 /* << 196 * Fill FLUENCE data for every sin << 197 * Exclude e-, neutrons, gamma, .. << 198 */ << 199 if ( Z >= 1) matrix -> Fill(trackI << 200 << 201 } << 202 << 203 if(energyDeposit != 0) << 204 { << 205 /* << 206 * This method will fill a dose m << 207 * A method of the HadrontherapyM << 208 * is called automatically at the << 209 * It permits to store all dose/f << 210 */ << 211 // if (A==1 && Z==1) // primary an << 212 if ( Z>=1 ) // exclude e-, neu << 213 matrix -> Fill(trackID, partic << 214 /* << 215 * Create a hit with the informati << 216 */ << 217 HadrontherapyDetectorHit* detector << 218 detectorHit -> SetEdepAndPosition( << 219 HitsCollection -> insert(detectorH << 220 } << 221 } << 222 143 223 auto rbe = HadrontherapyRBE::GetInstance() << 144 // Increment Fluences & accumulate energy spectra 224 if (rbe->IsCalculationEnabled()) << 145 // Hit voxels are marked with track_id throught hitTrack matrix 225 { << 146 G4int* hitTrack = matrix -> GetHitTrack(i,j,k); // hitTrack MUST BE cleared at every eventAction! 226 if (!fRBEAccumulable) << 147 if ( *hitTrack != trackID ) 227 { << 148 { 228 fRBEAccumulable = dynamic_cast<Had << 149 *hitTrack = trackID; 229 if (!fRBEAccumulable) << 150 /* 230 { << 151 * Fill FLUENCE data for every single nuclide 231 G4Exception("HadrontherapyDete << 152 * Exclude e-, neutrons, gamma, ... 232 } << 153 */ 233 } << 154 if ( Z >= 1) matrix -> Fill(trackID, particleDef, i, j, k, 0, true); 234 if (A>0) //protect against gammas, e- , etc << 155 235 { << 156 236 fRBEAccumulable->Accumulate(kineticEnerg << 157 #ifdef G4ANALYSIS_USE_ROOT 237 } << 158 /* >> 159 // Fragments kinetic energy (ntuple) >> 160 if (trackID !=1 && Z>=1) >> 161 { >> 162 // First step kinetic energy for every fragment >> 163 analysis -> FillKineticFragmentTuple(i, j, k, A, Z, kineticEnergy/MeV); >> 164 } >> 165 // Kinetic energy spectra for primary particles >> 166 >> 167 if ( trackID == 1 && i == 0) >> 168 { >> 169 // First step kinetic energy for primaries only >> 170 analysis -> FillKineticEnergyPrimaryNTuple(i, j, k, kineticEnergy/MeV); >> 171 } >> 172 */ >> 173 #endif >> 174 } >> 175 >> 176 if(energyDeposit != 0) >> 177 { >> 178 /* >> 179 * This method will fill a dose matrix for every single nuclide. >> 180 * A method of the HadrontherapyMatrix class (StoreDoseFluenceAscii()) >> 181 * is called automatically at the end of main (or via the macro command /analysis/writeDoseFile. >> 182 * It permits to store all dose/fluence data into a single plane ASCII file. >> 183 */ >> 184 // if (A==1 && Z==1) // primary and sec. protons >> 185 if ( Z>=1 ) // exclude e-, neutrons, gamma, ... >> 186 matrix -> Fill(trackID, particleDef, i, j, k, energyDeposit); >> 187 /* >> 188 * Create a hit with the information of position is in the detector >> 189 */ >> 190 HadrontherapyDetectorHit* detectorHit = new HadrontherapyDetectorHit(); >> 191 detectorHit -> SetEdepAndPosition(i, j, k, energyDeposit); >> 192 HitsCollection -> insert(detectorHit); >> 193 } 238 } 194 } 239 195 >> 196 #ifdef G4ANALYSIS_USE_ROOT >> 197 if(energyDeposit != 0) >> 198 { >> 199 if(trackID != 1) >> 200 { >> 201 if (particleName == "proton") >> 202 analysis -> SecondaryProtonEnergyDeposit(i, energyDeposit/MeV); >> 203 >> 204 else if (particleName == "neutron") >> 205 analysis -> SecondaryNeutronEnergyDeposit(i, energyDeposit/MeV); >> 206 >> 207 else if (particleName == "alpha") >> 208 analysis -> SecondaryAlphaEnergyDeposit(i, energyDeposit/MeV); >> 209 >> 210 else if (particleName == "gamma") >> 211 analysis -> SecondaryGammaEnergyDeposit(i, energyDeposit/MeV); >> 212 >> 213 else if (particleName == "e-") >> 214 analysis -> SecondaryElectronEnergyDeposit(i, energyDeposit/MeV); >> 215 >> 216 else if (particleName == "triton") >> 217 analysis -> SecondaryTritonEnergyDeposit(i, energyDeposit/MeV); >> 218 >> 219 else if (particleName == "deuteron") >> 220 analysis -> SecondaryDeuteronEnergyDeposit(i, energyDeposit/MeV); >> 221 >> 222 else if (particleName == "pi+" || particleName == "pi-" || particleName == "pi0") >> 223 analysis -> SecondaryPionEnergyDeposit(i, energyDeposit/MeV); >> 224 } >> 225 } >> 226 #endif 240 227 241 return true; 228 return true; 242 } 229 } 243 230 244 ////////////////////////////////////////////// 231 ///////////////////////////////////////////////////////////////////////////// 245 void HadrontherapyDetectorSD::EndOfEvent(G4HCo 232 void HadrontherapyDetectorSD::EndOfEvent(G4HCofThisEvent* HCE) 246 { 233 { 247 << 234 248 static G4int HCID = -1; 235 static G4int HCID = -1; 249 if(HCID < 0) 236 if(HCID < 0) 250 { << 237 { 251 HCID = GetCollectionID(0); << 238 HCID = GetCollectionID(0); 252 } 239 } 253 << 240 254 HCE -> AddHitsCollection(HCID,HitsCollecti 241 HCE -> AddHitsCollection(HCID,HitsCollection); 255 } 242 } 256 243 257 244