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 >> 35 #include <CLHEP/Units/SystemOfUnits.h> 28 36 29 #include "HadrontherapyDetectorSD.hh" 37 #include "HadrontherapyDetectorSD.hh" >> 38 #include "HadrontherapyAnalysisManager.hh" 30 #include "HadrontherapyDetectorHit.hh" 39 #include "HadrontherapyDetectorHit.hh" 31 #include "G4Step.hh" 40 #include "G4Step.hh" 32 #include "G4VTouchable.hh" 41 #include "G4VTouchable.hh" 33 #include "G4TouchableHistory.hh" 42 #include "G4TouchableHistory.hh" 34 #include "G4SDManager.hh" 43 #include "G4SDManager.hh" 35 #include "HadrontherapyMatrix.hh" 44 #include "HadrontherapyMatrix.hh" 36 #include "HadrontherapyLet.hh" << 37 #include "G4Track.hh" << 38 #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 45 63 ////////////////////////////////////////////// 46 ///////////////////////////////////////////////////////////////////////////// 64 HadrontherapyDetectorSD::HadrontherapyDetector 47 HadrontherapyDetectorSD::HadrontherapyDetectorSD(G4String name): 65 G4VSensitiveDetector(name) << 48 G4VSensitiveDetector(name) 66 { << 49 { 67 G4String HCname; 50 G4String HCname; 68 collectionName.insert(HCname="Hadrontherap 51 collectionName.insert(HCname="HadrontherapyDetectorHitsCollection"); 69 HitsCollection = NULL; << 52 HitsCollection = NULL; 70 sensitiveDetectorName = name; 53 sensitiveDetectorName = name; 71 << 54 72 } 55 } 73 56 74 ////////////////////////////////////////////// 57 ///////////////////////////////////////////////////////////////////////////// 75 HadrontherapyDetectorSD::~HadrontherapyDetecto 58 HadrontherapyDetectorSD::~HadrontherapyDetectorSD() 76 {} << 59 { >> 60 } 77 61 78 ////////////////////////////////////////////// 62 ///////////////////////////////////////////////////////////////////////////// 79 void HadrontherapyDetectorSD::Initialize(G4HCo 63 void HadrontherapyDetectorSD::Initialize(G4HCofThisEvent*) 80 { 64 { 81 << 82 HitsCollection = new HadrontherapyDetector 65 HitsCollection = new HadrontherapyDetectorHitsCollection(sensitiveDetectorName, 83 << 66 collectionName[0]); 84 } 67 } 85 68 86 ////////////////////////////////////////////// 69 ///////////////////////////////////////////////////////////////////////////// 87 G4bool HadrontherapyDetectorSD::ProcessHits(G4 << 70 G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* ROhist) 88 { 71 { 89 << 72 //The code doesn't seem to get here if we use the IAEA geometry. FIXME 90 << 73 if(!ROhist) 91 if (aStep -> GetPreStepPoint() -> GetPhysi << 74 return false; 92 << 75 93 << 76 if (aStep -> GetPreStepPoint() -> GetPhysicalVolume() -> GetName() != "DetectorPhys") >> 77 return false; 94 // Get kinetic energy 78 // Get kinetic energy 95 G4Track * theTrack = aStep -> GetTrack() 79 G4Track * theTrack = aStep -> GetTrack(); 96 G4double kineticEnergy = theTrack->GetKine << 80 //G4double kineticEnergy = theTrack -> GetKineticEnergy(); >> 81 97 G4ParticleDefinition *particleDef = theTra 82 G4ParticleDefinition *particleDef = theTrack -> GetDefinition(); 98 //Get particle name << 83 //Get particle name 99 G4String particleName = particleDef -> Ge << 84 G4String particleName = particleDef -> GetParticleName(); 100 << 85 // G4cout << particleDef -> GetParticleType() << '\n'; 101 // Get particle PDG code << 102 G4int pdg = particleDef ->GetPDGEncoding() << 103 << 104 // Get unique track_id (in an event) 86 // Get unique track_id (in an event) 105 G4int trackID = theTrack -> GetTrackID(); 87 G4int trackID = theTrack -> GetTrackID(); 106 << 88 107 G4double energyDeposit = aStep -> GetTotal 89 G4double energyDeposit = aStep -> GetTotalEnergyDeposit(); 108 << 90 109 G4double DX = aStep -> GetStepLength(); << 110 G4int Z = particleDef-> GetAtomicNumber(); 91 G4int Z = particleDef-> GetAtomicNumber(); 111 G4int A = particleDef-> GetAtomicMass(); << 92 //G4int A = particleDef-> GetAtomicMass(); 112 G4StepPoint* PreStep = aStep->GetPreStepPo << 93 113 << 114 // Read voxel indexes: i is the x index, k 94 // Read voxel indexes: i is the x index, k is the z index 115 const G4VTouchable* touchable = aStep->Get << 95 G4int k = ROhist -> GetReplicaNumber(0); 116 G4int k = touchable->GetReplicaNumber(0); << 96 G4int i = ROhist -> GetReplicaNumber(2); 117 G4int i = touchable->GetReplicaNumber(2); << 97 G4int j = ROhist -> GetReplicaNumber(1); 118 G4int j = touchable->GetReplicaNumber(1); << 98 119 << 99 #ifdef G4ANALYSIS_USE_ROOT 120 G4TouchableHandle touchPreStep = PreStep-> << 100 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); 121 G4VPhysicalVolume* volumePre = touchPreSte << 101 #endif 122 G4String namePre = volumePre->GetName(); << 123 << 124 102 125 << 126 HadrontherapyMatrix* matrix = Hadrontherap 103 HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance(); 127 HadrontherapyLet* let = HadrontherapyLet:: << 104 128 << 129 G4int* hitTrack = matrix -> GetHitTrack(i, << 130 << 131 << 132 // ******************** let ************* << 133 if (let) << 134 { << 135 if ( !(Z==0 && A==1) ) // All but not << 136 { << 137 if( energyDeposit>0. && DX >0. )// << 138 { << 139 if (pdg !=22 && pdg !=11) // n << 140 { << 141 << 142 // Get the pre-step kineti << 143 G4double eKinPre = aStep - << 144 // Get the post-step kinet << 145 G4double eKinPost = aStep << 146 // Get the step average ki << 147 G4double eKinMean = (eKinP << 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 } << 184 << 185 << 186 if (matrix) 105 if (matrix) 187 { 106 { 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 107 223 auto rbe = HadrontherapyRBE::GetInstance() << 108 // Increment Fluences & accumulate energy spectra 224 if (rbe->IsCalculationEnabled()) << 109 // Hit voxels are marked with track_id throught hitTrack matrix 225 { << 110 G4int* hitTrack = matrix -> GetHitTrack(i,j,k); // hitTrack MUST BE cleared at every eventAction! 226 if (!fRBEAccumulable) << 111 if ( *hitTrack != trackID ) 227 { << 112 { 228 fRBEAccumulable = dynamic_cast<Had << 113 *hitTrack = trackID; 229 if (!fRBEAccumulable) << 114 /* 230 { << 115 * Fill FLUENCE data for every single nuclide 231 G4Exception("HadrontherapyDete << 116 * Exclude e-, neutrons, gamma, ... 232 } << 117 */ 233 } << 118 if ( Z >= 1) 234 if (A>0) //protect against gammas, e- , etc << 119 matrix -> Fill(trackID, particleDef, i, j, k, 0, true); 235 { << 120 #ifdef G4ANALYSIS_USE_ROOT 236 fRBEAccumulable->Accumulate(kineticEnerg << 121 /* 237 } << 122 // Fragments kinetic energy (ntuple) >> 123 if (trackID !=1 && Z>=1) >> 124 { >> 125 // First step kinetic energy for every fragment >> 126 analysis -> FillKineticFragmentTuple(i, j, k, A, Z, kineticEnergy/MeV); >> 127 } >> 128 // Kinetic energy spectra for primary particles >> 129 >> 130 if ( trackID == 1 && i == 0) >> 131 { >> 132 // First step kinetic energy for primaries only >> 133 analysis -> FillKineticEnergyPrimaryNTuple(i, j, k, kineticEnergy/MeV); >> 134 } >> 135 */ >> 136 #endif >> 137 } >> 138 >> 139 if(energyDeposit != 0) >> 140 { >> 141 /* >> 142 * This method will fill a dose matrix for every single nuclide. >> 143 * A method of the HadrontherapyMatrix class (StoreDoseFluenceAscii()) >> 144 * is called automatically at the end of main (or via the macro command /analysis/writeDoseFile. >> 145 * It permits to store all dose/fluence data into a single plane ASCII file. >> 146 */ >> 147 // if (A==1 && Z==1) // primary and sec. protons >> 148 if ( Z>=1 ) // exclude e-, neutrons, gamma, ... >> 149 matrix -> Fill(trackID, particleDef, i, j, k, energyDeposit); >> 150 /* >> 151 * Create a hit with the information of position is in the detector >> 152 */ >> 153 HadrontherapyDetectorHit* detectorHit = new HadrontherapyDetectorHit(); >> 154 detectorHit -> SetEdepAndPosition(i, j, k, energyDeposit); >> 155 HitsCollection -> insert(detectorHit); >> 156 } 238 } 157 } 239 158 >> 159 #ifdef G4ANALYSIS_USE_ROOT >> 160 if(energyDeposit != 0) >> 161 { >> 162 if(trackID != 1) >> 163 { >> 164 if (particleName == "proton") >> 165 analysis -> SecondaryProtonEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 166 >> 167 else if (particleName == "neutron") >> 168 analysis -> SecondaryNeutronEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 169 >> 170 else if (particleName == "alpha") >> 171 analysis -> SecondaryAlphaEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 172 >> 173 else if (particleName == "gamma") >> 174 analysis -> SecondaryGammaEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 175 >> 176 else if (particleName == "e-") >> 177 analysis -> SecondaryElectronEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 178 >> 179 else if (particleName == "triton") >> 180 analysis -> SecondaryTritonEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 181 >> 182 else if (particleName == "deuteron") >> 183 analysis -> SecondaryDeuteronEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 184 >> 185 else if (particleName == "pi+" || particleName == "pi-" || particleName == "pi0") >> 186 analysis -> SecondaryPionEnergyDeposit(i, energyDeposit/CLHEP::MeV); >> 187 } >> 188 } >> 189 #endif 240 190 241 return true; 191 return true; 242 } 192 } 243 193 244 ////////////////////////////////////////////// 194 ///////////////////////////////////////////////////////////////////////////// 245 void HadrontherapyDetectorSD::EndOfEvent(G4HCo 195 void HadrontherapyDetectorSD::EndOfEvent(G4HCofThisEvent* HCE) 246 { 196 { 247 << 248 static G4int HCID = -1; 197 static G4int HCID = -1; 249 if(HCID < 0) 198 if(HCID < 0) 250 { << 199 { 251 HCID = GetCollectionID(0); << 200 HCID = GetCollectionID(0); 252 } 201 } 253 << 202 254 HCE -> AddHitsCollection(HCID,HitsCollecti 203 HCE -> AddHitsCollection(HCID,HitsCollection); 255 } 204 } 256 205 257 206