Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 // 28 29 #include "G4ScoreSplittingProcess.hh" 30 31 #include "G4EnergySplitter.hh" 32 #include "G4ParticleChange.hh" 33 #include "G4RegularNavigationHelper.hh" 34 #include "G4SDManager.hh" 35 #include "G4Step.hh" 36 #include "G4StepPoint.hh" 37 #include "G4SystemOfUnits.hh" 38 #include "G4TouchableHistory.hh" 39 #include "G4TransportationManager.hh" 40 #include "G4VPhysicalVolume.hh" 41 #include "G4VSensitiveDetector.hh" 42 #include "G4VTouchable.hh" 43 #include "G4ios.hh" 44 45 //-------------------------------- 46 // Constructor with name and type: 47 //-------------------------------- 48 G4ScoreSplittingProcess::G4ScoreSplittingProce 49 : G4VProcess(processName, theType) 50 { 51 pParticleChange = &xParticleChange; 52 53 fSplitStep = new G4Step(); 54 fSplitPreStepPoint = fSplitStep->GetPreStepP 55 fSplitPostStepPoint = fSplitStep->GetPostSte 56 57 if (verboseLevel > 0) { 58 G4cout << GetProcessName() << " is created 59 } 60 fpEnergySplitter = new G4EnergySplitter(); 61 } 62 63 // ----------- 64 // Destructor: 65 // ----------- 66 G4ScoreSplittingProcess::~G4ScoreSplittingProc 67 { 68 delete fSplitStep; 69 delete fpEnergySplitter; 70 } 71 72 //-------------------------------------------- 73 // 74 // StartTracking 75 // 76 //-------------------------------------------- 77 void G4ScoreSplittingProcess::StartTracking(G4 78 { 79 // Setup initial touchables for the first st 80 const G4Step* pStep = trk->GetStep(); 81 82 fOldTouchableH = trk->GetTouchableHandle(); 83 *fSplitPreStepPoint = *(pStep->GetPreStepPoi 84 fSplitPreStepPoint->SetTouchableHandle(fOldT 85 fNewTouchableH = fOldTouchableH; 86 *fSplitPostStepPoint = *(pStep->GetPostStepP 87 fSplitPostStepPoint->SetTouchableHandle(fNew 88 89 /// Initialize 90 fSplitPreStepPoint->SetStepStatus(fUndefined 91 fSplitPostStepPoint->SetStepStatus(fUndefine 92 } 93 94 //-------------------------------------------- 95 // 96 // PostStepGetPhysicalInteractionLength() 97 // 98 //-------------------------------------------- 99 G4double G4ScoreSplittingProcess::PostStepGetP 100 const G4Track& /*track*/, G4double /*previou 101 { 102 // This process must be invoked anyway to sc 103 // - to do the scoring if the current volu 104 // - else to toggle the flag so that the S 105 *condition = StronglyForced; 106 107 // Future optimisation: check whether in reg 108 // If it is in regular structure, be Stron 109 // If not in regular structure, 110 // ask to be called only if Stepping 111 // in order to reset it to NormalCon 112 113 return DBL_MAX; 114 } 115 116 //------------------------------------ 117 // 118 // PostStepDoIt() 119 // 120 //------------------------------------ 121 G4VParticleChange* G4ScoreSplittingProcess::Po 122 { 123 G4VPhysicalVolume* pCurrentVolume = track.Ge 124 G4LogicalVolume* pLogicalVolume = pCurrentVo 125 G4VSensitiveDetector* ptrSD = pLogicalVolume 126 127 pParticleChange->Initialize(track); 128 if ((!pCurrentVolume->IsRegularStructure()) 129 || G4RegularNavigationHelper::Instance() 130 { 131 // Set the flag to make sure that Stepping 132 pParticleChange->ProposeSteppingControl(No 133 } 134 else { 135 G4ThreeVector preStepPosition, postStepPos 136 pParticleChange->ProposeSteppingControl(Av 137 138 G4double totalEnergyDeposit = step.GetTota 139 G4StepStatus fullStepStatus = step.GetPost 140 141 CopyStepStart(step); 142 fSplitPreStepPoint->SetSensitiveDetector(p 143 fOldTouchableH = fInitialTouchableH; 144 fNewTouchableH = fOldTouchableH; 145 *fSplitPostStepPoint = *(step.GetPreStepPo 146 147 // Split the energy 148 // ---------------- 149 G4int numberVoxelsInStep = fpEnergySplitte 150 151 preStepPosition = step.GetPreStepPoint()-> 152 finalPostStepPosition = step.GetPostStepPo 153 direction = (finalPostStepPosition - preSt 154 155 fFinalTouchableH = track.GetNextTouchableH 156 157 postStepPosition = preStepPosition; 158 // Loop over the sub-parts of this step 159 G4int iStep; 160 for (iStep = 0; iStep < numberVoxelsInStep 161 G4int idVoxel = -1; // Voxel ID 162 G4double stepLength = 0.0, energyLoss = 163 164 *fSplitPreStepPoint = *fSplitPostStepPoi 165 fOldTouchableH = fNewTouchableH; 166 167 preStepPosition = postStepPosition; 168 fSplitPreStepPoint->SetPosition(preStepP 169 fSplitPreStepPoint->SetTouchableHandle(f 170 171 fpEnergySplitter->GetLengthAndEnergyDepo 172 173 // Correct the material, so that the tra 174 pLogicalVolume->SetMaterial(fpEnergySpli 175 176 postStepPosition = preStepPosition + ste 177 fSplitPostStepPoint->SetPosition(postSte 178 179 // Load the Step with the new values 180 fSplitStep->SetStepLength(stepLength); 181 fSplitStep->SetTotalEnergyDeposit(energy 182 if (iStep < numberVoxelsInStep - 1) { 183 fSplitStep->GetPostStepPoint()->SetSte 184 G4int nextVoxelId = -1; 185 fpEnergySplitter->GetVoxelID(iStep + 1 186 187 // Create new "next" touchable for eac 188 G4VTouchable* fNewTouchablePtr = Creat 189 fNewTouchableH = G4TouchableHandle(fNe 190 fSplitPostStepPoint->SetTouchableHandl 191 } 192 else { 193 fSplitStep->GetPostStepPoint()->SetSte 194 fSplitPostStepPoint->SetTouchableHandl 195 } 196 197 // As first approximation, split the NIE 198 G4double eLossFraction; 199 eLossFraction = (totalEnergyDeposit > 0. 200 fSplitStep->SetNonIonizingEnergyDeposit( 201 202 fSplitPostStepPoint->SetSensitiveDetecto 203 204 // Call the Sensitive Detector 205 ptrSD->Hit(fSplitStep); 206 207 if (verboseLevel > 1) Verbose(step); 208 } 209 } 210 211 // This must change the Stepping Control 212 return pParticleChange; 213 } 214 215 G4TouchableHistory* G4ScoreSplittingProcess::C 216 217 { 218 auto oldTouchableHistory = dynamic_cast<G4To 219 G4TouchableHistory* ptrTouchableHistory = 220 G4TransportationManager::GetTransportation 221 ->GetNavigatorForTracking() 222 ->CreateTouchableHistory(oldTouchableHis 223 224 // Change the history 225 auto ptrNavHistory = const_cast<G4Navigation 226 G4VPhysicalVolume* curPhysicalVol = ptrNavHi 227 228 EVolume curVolumeType = ptrNavHistory->GetTo 229 if (curVolumeType == kParameterised) { 230 ptrNavHistory->BackLevel(); 231 // G4VPVParameterised parameterisedPV= pNe 232 G4VPVParameterisation* curParamstn = curPh 233 234 // From G4ParameterisedNavigation::Identif 235 G4VSolid* sampleSolid = curParamstn->Compu 236 sampleSolid->ComputeDimensions(curParamstn 237 curParamstn->ComputeTransformation(newVoxe 238 239 ptrNavHistory->NewLevel(curPhysicalVol, kP 240 } 241 else { 242 G4cout << " Current volume type is not Par 243 G4Exception( 244 "G4ScoreSplittingProcess::CreateTouchabl 245 JustWarning, 246 "Score Splitting Process is used for Reg 247 } 248 return ptrTouchableHistory; 249 } 250 251 void G4ScoreSplittingProcess::CopyStepStart(co 252 { 253 fSplitStep->SetTrack(step.GetTrack()); 254 fSplitStep->SetStepLength(step.GetStepLength 255 fSplitStep->SetTotalEnergyDeposit(step.GetTo 256 fSplitStep->SetNonIonizingEnergyDeposit(step 257 fSplitStep->SetControlFlag(step.GetControlFl 258 259 *fSplitPreStepPoint = *(step.GetPreStepPoint 260 261 fInitialTouchableH = (step.GetPreStepPoint() 262 fFinalTouchableH = (step.GetPostStepPoint()) 263 } 264 265 void G4ScoreSplittingProcess::Verbose(const G4 266 { 267 G4cout << "In mass geometry ---------------- 268 G4cout << " StepLength : " << step.GetStepLe 269 << " TotalEnergyDeposit : " << s 270 G4cout << " PreStepPoint : " << step.GetPreS 271 if (step.GetPreStepPoint()->GetProcessDefine 272 G4cout << step.GetPreStepPoint()->GetProce 273 } 274 else { 275 G4cout << "NoProcessAssigned"; 276 } 277 G4cout << G4endl; 278 G4cout << " " << step.GetPreS 279 G4cout << " PostStepPoint : "; 280 if (step.GetPostStepPoint()->GetPhysicalVolu 281 G4cout << step.GetPostStepPoint()->GetPhys 282 } 283 else { 284 G4cout << "OutOfWorld"; 285 } 286 G4cout << " - "; 287 if (step.GetPostStepPoint()->GetProcessDefin 288 G4cout << step.GetPostStepPoint()->GetProc 289 } 290 else { 291 G4cout << "NoProcessAssigned"; 292 } 293 G4cout << G4endl; 294 G4cout << " " << step.GetPos 295 296 G4cout << "In ghost geometry --------------- 297 G4cout << " StepLength : " << fSplitStep->Ge 298 << " TotalEnergyDeposit : " << f 299 G4cout << " PreStepPoint : " << fSplitStep-> 300 << " [" << fSplitStep->GetPreStepPoin 301 << " - "; 302 if (fSplitStep->GetPreStepPoint()->GetProces 303 G4cout << fSplitStep->GetPreStepPoint()->G 304 } 305 else { 306 G4cout << "NoProcessAssigned"; 307 } 308 G4cout << G4endl; 309 G4cout << " " << fSplitStep-> 310 G4cout << " PostStepPoint : "; 311 if (fSplitStep->GetPostStepPoint()->GetPhysi 312 G4cout << fSplitStep->GetPostStepPoint()-> 313 << fSplitStep->GetPostStepPoint()-> 314 } 315 else { 316 G4cout << "OutOfWorld"; 317 } 318 G4cout << " - "; 319 if (fSplitStep->GetPostStepPoint()->GetProce 320 G4cout << fSplitStep->GetPostStepPoint()-> 321 } 322 else { 323 G4cout << "NoProcessAssigned"; 324 } 325 G4cout << G4endl; 326 G4cout << " " << fSplitStep- 327 << " == " << fSplitStep->GetTrack()-> 328 } 329 330 //-------------------------------------------- 331 // 332 // AtRestGetPhysicalInteractionLength() 333 // 334 //-------------------------------------------- 335 G4double G4ScoreSplittingProcess::AtRestGetPhy 336 337 { 338 *condition = NotForced; // Was Forced 339 return DBL_MAX; 340 } 341 342 //--------------------------------------- 343 // AlongStepGetPhysicalInteractionLength 344 //--------------------------------------- 345 G4double 346 G4ScoreSplittingProcess::AlongStepGetPhysicalI 347 348 349 350 351 { 352 *selection = NotCandidateForSelection; 353 return DBL_MAX; 354 } 355 356 //------------------------------------ 357 // AlongStepDoIt() 358 //------------------------------------ 359 360 G4VParticleChange* G4ScoreSplittingProcess::Al 361 { 362 // Dummy ParticleChange ie: does nothing 363 // Expecting G4Transportation to move the tr 364 dummyParticleChange.Initialize(track); 365 return &dummyParticleChange; 366 } 367 368 //------------------------------------ 369 // AtRestDoIt() 370 //------------------------------------ 371 G4VParticleChange* G4ScoreSplittingProcess::At 372 { 373 pParticleChange->Initialize(track); 374 return pParticleChange; 375 } 376