Geant4 Cross Reference |
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 // This example is provided by the Geant4-DNA collaboration 27 // Any report or published results obtained using the Geant4-DNA software 28 // shall cite the following Geant4-DNA collaboration publications: 29 // Med. Phys. 45 (2018) e722-e739 30 // Phys. Med. 31 (2015) 861-874 31 // Med. Phys. 37 (2010) 4692-4708 32 // Int. J. Model. Simul. Sci. Comput. 1 (2010) 157–178 33 // The Geant4-DNA web site is available at http://geant4-dna.org 34 // 35 /// \file TrackerSD.cc 36 /// \brief Implementation of the TrackerSD class 37 38 #include "TrackerSD.hh" 39 40 #include "G4AnalysisManager.hh" 41 #include "G4SDManager.hh" 42 #include "G4SystemOfUnits.hh" 43 #include "Randomize.hh" 44 45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 46 47 TrackerSD::TrackerSD(const G4String& name, const G4String& hitsCollectionName) 48 : G4VSensitiveDetector(name), fHitsCollection(nullptr) 49 { 50 collectionName.insert(hitsCollectionName); 51 } 52 53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 54 55 TrackerSD::~TrackerSD() = default; 56 57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 58 59 void TrackerSD::Initialize(G4HCofThisEvent* hce) 60 { 61 // Create hits collection 62 fHitsCollection = new TrackerHitsCollection(SensitiveDetectorName, collectionName[0]); 63 64 // Add this collection in hce 65 G4int hcID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]); 66 67 hce->AddHitsCollection(hcID, fHitsCollection); 68 } 69 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 71 72 G4bool TrackerSD::ProcessHits(G4Step* aStep, G4TouchableHistory*) 73 { 74 // Energy deposit 75 G4double edep = aStep->GetTotalEnergyDeposit(); 76 77 if (edep == 0.) return false; 78 79 auto newHit = new TrackerHit(); 80 81 newHit->SetTrackID(aStep->GetTrack()->GetTrackID()); 82 newHit->SetEdep(edep); 83 newHit->SetPos(aStep->GetPostStepPoint()->GetPosition()); 84 85 if (aStep->GetTrack()->GetTrackID() == 1 && aStep->GetTrack()->GetParentID() == 0) { 86 newHit->SetIncidentEnergy(aStep->GetTrack()->GetVertexKineticEnergy()); 87 } 88 fHitsCollection->insert(newHit); 89 // newHit->Print(); 90 91 return true; 92 } 93 94 void TrackerSD::SetRadius(const G4double& value) 95 { 96 fRadius = value; 97 } 98 99 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 100 101 void TrackerSD::EndOfEvent(G4HCofThisEvent*) 102 { 103 G4int nofHits = fHitsCollection->entries(); 104 105 G4double Einc = 0; 106 107 /* 108 G4cout << G4endl 109 << "-------->Hits Collection: in this event they are " 110 << nofHits 111 << " hits in the target volume " << G4endl; 112 */ 113 114 // PROCESSING OF MICRODOSIMETRY Y & Z SPECTRA 115 116 // ************************************* 117 // Please select herebelow : 118 // the radius of the target sphere: 119 // variable name = radius 120 // it is set to 5 nm by default) 121 122 G4double radius = fRadius; 123 124 // 125 126 //*************** 127 // y and z 128 //*************** 129 130 // Select random hit 131 G4int randHit = 0; // Runs from 0 to number of hits - 1 132 randHit = static_cast<G4int>(G4UniformRand() * nofHits); 133 134 /* 135 G4cout 136 << "======> random selection of hit number randHit =" 137 << randHit << G4endl; 138 */ 139 140 // Get selected random hit position 141 G4ThreeVector hitPos = (*fHitsCollection)[randHit]->GetPos(); 142 // G4cout << "======> random hit position x/nm =" << hitPos.x()/nm << G4endl; 143 // G4cout << "======> random hit position y/nm =" << hitPos.y()/nm << G4endl; 144 // G4cout << "======> random hit position z/nm =" << hitPos.z()/nm << G4endl; 145 146 // Set random position of center of sphere within radius 147 G4double chord = 4. * radius / 3; 148 G4double density = 1 * g / cm3; 149 G4double mass = (4. / 3) * CLHEP::pi * radius * radius * radius * density; 150 151 // Random placement of sphere: method 1 152 /* 153 G4ThreeVector randDir = G4RandomDirection(); 154 G4double randRadius = G4UniformRand()*radius; 155 G4ThreeVector randCenterPos = randRadius*randDir + hitPos; 156 */ 157 158 // Random placement of sphere: method 2 159 160 G4double xRand = 1.01 * radius; 161 G4double yRand = 1.01 * radius; 162 G4double zRand = 1.01 * radius; 163 G4double randRad = 1.01 * radius; 164 do { 165 xRand = (2 * G4UniformRand() - 1) * radius; 166 yRand = (2 * G4UniformRand() - 1) * radius; 167 zRand = (2 * G4UniformRand() - 1) * radius; 168 randRad = std::sqrt(xRand * xRand + yRand * yRand + zRand * zRand); 169 } while (randRad > radius); 170 171 G4ThreeVector randCenterPos(xRand + hitPos.x(), yRand + hitPos.y(), zRand + hitPos.z()); 172 173 // Search for neighbouring hits in the sphere and cumulate deposited energy 174 // in epsilon 175 G4double epsilon = 0; 176 G4int nbEdep = 0; 177 178 for (G4int i = 0; i < nofHits; i++) { 179 if ((*fHitsCollection)[i]->GetIncidentEnergy() > 0) 180 Einc = (*fHitsCollection)[i]->GetIncidentEnergy(); 181 182 G4ThreeVector localPos = (*fHitsCollection)[i]->GetPos(); 183 184 // G4cout << i << " " << (*fHitsCollection)[i] << G4endl; 185 // G4cout << i << " " << (*fHitsCollection)[i]->GetEdep()/eV << G4endl; 186 187 if ((localPos.x() - randCenterPos.x()) * (localPos.x() - randCenterPos.x()) 188 + (localPos.y() - randCenterPos.y()) * (localPos.y() - randCenterPos.y()) 189 + (localPos.z() - randCenterPos.z()) * (localPos.z() - randCenterPos.z()) 190 <= radius * radius) 191 192 { 193 epsilon = epsilon + (*fHitsCollection)[i]->GetEdep(); 194 nbEdep = nbEdep + 1; 195 } 196 } 197 198 // For testing only 199 /* 200 G4cout << "======> for hit number #" << randHit << 201 ", we collect " 202 << nbEdep << " energy depositions in a sphere of radius " 203 << radius/nm << " nm and mass " 204 << mass/kg << " kg for a total of " 205 << epsilon/eV << " eV or " 206 << (epsilon/joule)/(mass/kg) << " Gy" << G4endl; 207 G4cout << "-" << G4endl; 208 */ 209 210 /* 211 FILE* myFile; 212 myFile=fopen("yz.txt","a"); 213 fprintf(myFile,"%e %e %e\n",radius/nm,(epsilon/eV)/(chord/nm), 214 (epsilon/joule)/(mass/kg)); 215 fclose(myFile); 216 */ 217 218 // Get analysis manager 219 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); 220 221 // Fill ntuple including weighting 222 analysisManager->FillNtupleDColumn(0, radius / nm); 223 analysisManager->FillNtupleDColumn(2, nofHits); 224 analysisManager->FillNtupleDColumn(3, nbEdep); 225 analysisManager->FillNtupleDColumn(4, (epsilon / eV) / (chord / nm)); 226 analysisManager->FillNtupleDColumn(5, (epsilon / mass) / gray); 227 analysisManager->FillNtupleDColumn(6, Einc / eV); 228 analysisManager->AddNtupleRow(); 229 } 230 231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 232