]>
Commit | Line | Data |
---|---|---|
2817d3e2 | 1 | // $Id$ |
2 | // Category: event | |
3 | // | |
4 | // See the class description in the header file. | |
5 | ||
6 | #include "TG4StepManager.h" | |
da99be38 | 7 | #include "TG4GeometryServices.h" |
1d28d5b2 | 8 | #include "TG4ParticlesManager.h" |
2817d3e2 | 9 | #include "TG4PhysicsManager.h" |
10 | #include "TG4VSensitiveDetector.h" | |
8658d09c | 11 | #include "TG4Limits.h" |
2817d3e2 | 12 | #include "TG4Globals.h" |
1d28d5b2 | 13 | #include "TG4G3Units.h" |
2817d3e2 | 14 | |
2817d3e2 | 15 | #include <G4SteppingManager.hh> |
16 | #include <G4UserLimits.hh> | |
2817d3e2 | 17 | #include <G4UImanager.hh> |
18 | #include <G4AffineTransform.hh> | |
f2510df1 | 19 | #include <G4TransportationManager.hh> |
20 | #include <G4Navigator.hh> | |
62c4bd4b | 21 | #include <G4VProcess.hh> |
22 | #include <G4ProcessManager.hh> | |
23 | #include <G4ProcessVector.hh> | |
2817d3e2 | 24 | |
25 | #include <Randomize.hh> | |
2817d3e2 | 26 | #include <TLorentzVector.h> |
27 | ||
28 | TG4StepManager* TG4StepManager::fgInstance = 0; | |
29 | ||
30 | TG4StepManager::TG4StepManager() | |
f2510df1 | 31 | : fTrack(0), |
32 | fStep(0), | |
33 | fStepStatus(kNormalStep), | |
2817d3e2 | 34 | fSteppingManager(0) |
35 | { | |
36 | // | |
37 | if (fgInstance) { | |
38 | TG4Globals::Exception( | |
39 | "TG4StepManager: attempt to create two instances of singleton."); | |
40 | } | |
41 | ||
42 | fgInstance = this; | |
43 | } | |
44 | ||
45 | TG4StepManager::TG4StepManager(const TG4StepManager& right) { | |
46 | // | |
47 | TG4Globals::Exception( | |
48 | "Attempt to copy TG4StepManager singleton."); | |
49 | } | |
50 | ||
51 | TG4StepManager::~TG4StepManager() { | |
52 | // | |
53 | } | |
54 | ||
55 | // operators | |
56 | ||
57 | TG4StepManager& TG4StepManager::operator=(const TG4StepManager& right) | |
58 | { | |
59 | // check assignement to self | |
60 | if (this == &right) return *this; | |
61 | ||
62 | TG4Globals::Exception( | |
63 | "Attempt to assign TG4StepManager singleton."); | |
64 | ||
65 | return *this; | |
66 | } | |
67 | ||
68 | // private methods | |
69 | ||
f2510df1 | 70 | void TG4StepManager::CheckTrack() const |
71 | { | |
72 | // Gives exception in case the track is not defined. | |
73 | // --- | |
74 | ||
75 | if (!fTrack) | |
76 | TG4Globals::Exception("TG4StepManager: Track is not defined."); | |
77 | } | |
78 | ||
79 | ||
12139627 | 80 | void TG4StepManager::CheckStep(const G4String& method) const |
f2510df1 | 81 | { |
82 | // Gives exception in case the step is not defined. | |
83 | // --- | |
84 | ||
12139627 | 85 | if (!fStep) { |
86 | G4String text = "TG4StepManager::"; | |
87 | text = text + method + ": Step is not defined."; | |
88 | TG4Globals::Exception(text); | |
89 | } | |
f2510df1 | 90 | } |
91 | ||
92 | ||
93 | void TG4StepManager::CheckSteppingManager() const | |
94 | { | |
95 | // Gives exception in case the step is not defined. | |
96 | // --- | |
97 | ||
98 | if (!fSteppingManager) | |
99 | TG4Globals::Exception("TG4StepManager: Stepping manager is not defined."); | |
100 | } | |
101 | ||
102 | ||
2817d3e2 | 103 | void TG4StepManager::SetTLorentzVector(G4ThreeVector xyz, G4double t, |
104 | TLorentzVector& lv) const | |
105 | { | |
106 | // Fills TLorentzVector with G4ThreeVector and G4double. | |
107 | // --- | |
108 | ||
109 | lv[0] = xyz.x(); | |
110 | lv[1] = xyz.y(); | |
111 | lv[2] = xyz.z(); | |
112 | lv[3] = t; | |
113 | } | |
114 | ||
f2510df1 | 115 | G4VPhysicalVolume* TG4StepManager::GetCurrentOffPhysicalVolume(G4int off) const |
116 | { | |
117 | // Returns the physical volume of the off-th mother's | |
118 | // of the current volume. | |
119 | // --- | |
120 | ||
121 | G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume(); | |
122 | ||
12139627 | 123 | G4VPhysicalVolume* mother = physVolume; |
124 | ||
f2510df1 | 125 | Int_t level = off; |
126 | while (level > 0) { | |
127 | if (mother) mother = mother->GetMother(); | |
128 | level--; | |
129 | } | |
130 | ||
131 | if (!mother) { | |
132 | G4String text = "TG4StepManager::CurrentVolOff: \n"; | |
133 | text = text + " Volume "; | |
134 | text = text + physVolume->GetName(); | |
135 | text = text + " has not defined mother in the required level."; | |
136 | TG4Globals::Warning(text); | |
137 | } | |
138 | ||
139 | return mother; | |
140 | } | |
141 | ||
2817d3e2 | 142 | // public methods |
143 | ||
144 | void TG4StepManager::StopTrack() | |
145 | { | |
146 | // Stops the current track and skips to the next. | |
147 | // ?? do we want to invoke rest processes? | |
148 | // ?? do we want to stop secondaries too? | |
149 | // possible "stop" track status from G4: | |
150 | // fStopButAlive, // Invoke active rest physics processes and | |
151 | // // and kill the current track afterward | |
152 | // fStopAndKill, // Kill the current track | |
153 | // fKillTrackAndSecondaries, | |
154 | // // Kill the current track and also associated | |
155 | // // secondaries. | |
156 | // --- | |
157 | ||
12139627 | 158 | #ifdef TGEANT4_DEBUG |
f2510df1 | 159 | CheckTrack(); |
12139627 | 160 | #endif |
f2510df1 | 161 | |
162 | fTrack->SetTrackStatus(fStopAndKill); | |
163 | // fTrack->SetTrackStatus(fStopButAlive); | |
164 | // fTrack->SetTrackStatus(fKillTrackAndSecondaries); | |
2817d3e2 | 165 | } |
166 | ||
167 | void TG4StepManager::StopEvent() | |
168 | { | |
169 | // Aborts the current event processing. | |
170 | // --- | |
171 | ||
12139627 | 172 | #ifdef TGEANT4_DEBUG |
f2510df1 | 173 | CheckTrack(); |
12139627 | 174 | #endif |
f2510df1 | 175 | |
176 | fTrack->SetTrackStatus(fKillTrackAndSecondaries); | |
177 | //StopTrack(); // cannot be used as it keeps secondaries | |
178 | G4UImanager::GetUIpointer()->ApplyCommand("/event/abort"); | |
179 | G4UImanager::GetUIpointer()->ApplyCommand("/alStacking/clearStack"); | |
2817d3e2 | 180 | } |
181 | ||
2817d3e2 | 182 | void TG4StepManager::SetMaxStep(Float_t step) |
183 | { | |
184 | // Maximum step allowed in the current logical volume. | |
2817d3e2 | 185 | // --- |
186 | ||
f2510df1 | 187 | G4LogicalVolume* curLogVolume |
188 | = GetCurrentPhysicalVolume()->GetLogicalVolume(); | |
189 | G4UserLimits* userLimits | |
190 | = curLogVolume->GetUserLimits(); | |
8658d09c | 191 | |
f2510df1 | 192 | if (userLimits == 0) { |
8658d09c | 193 | // create new limits |
194 | userLimits = new TG4Limits(); | |
195 | ||
196 | // set limits to all logical volumes | |
197 | // corresponding to the current "G3" volume | |
198 | TG4GeometryServices* geometryServices = TG4GeometryServices::Instance(); | |
199 | G4int nofLV = geometryServices->SetUserLimits(userLimits, curLogVolume); | |
2817d3e2 | 200 | } |
8658d09c | 201 | |
202 | // set max step | |
1d28d5b2 | 203 | userLimits->SetMaxAllowedStep(step*TG4G3Units::Length()); |
40c3fb9e | 204 | |
2817d3e2 | 205 | } |
206 | ||
207 | void TG4StepManager::SetMaxNStep(Int_t maxNofSteps) | |
208 | { | |
209 | // Not yet implemented. | |
210 | // --- | |
211 | ||
212 | TG4Globals::Warning( | |
213 | "TG4StepManager::SetMaxNStep(..) is not yet implemented."); | |
214 | } | |
215 | ||
5025108a | 216 | void TG4StepManager::SetUserDecay(Int_t pdg) |
2817d3e2 | 217 | { |
218 | // Not yet implemented. | |
219 | // --- | |
220 | ||
221 | TG4Globals::Exception( | |
222 | "TG4StepManager::SetUserDecay(..) is not yet implemented."); | |
223 | } | |
224 | ||
f2510df1 | 225 | G4VPhysicalVolume* TG4StepManager::GetCurrentPhysicalVolume() const |
226 | { | |
227 | // Returns the current physical volume. | |
228 | // According to fStepStatus the volume from track vertex, | |
229 | // pre step point or post step point is returned. | |
230 | // --- | |
231 | ||
232 | G4VPhysicalVolume* physVolume; | |
233 | if (fStepStatus == kNormalStep) { | |
12139627 | 234 | |
235 | #ifdef TGEANT4_DEBUG | |
236 | CheckStep("GetCurrentPhysicalVolume"); | |
237 | #endif | |
238 | ||
f2510df1 | 239 | physVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); |
240 | } | |
241 | else if (fStepStatus == kBoundary) { | |
12139627 | 242 | |
243 | #ifdef TGEANT4_DEBUG | |
244 | CheckStep("GetCurrentPhysicalVolume"); | |
245 | #endif | |
246 | ||
f2510df1 | 247 | physVolume = fStep->GetPostStepPoint()->GetPhysicalVolume(); |
248 | } | |
249 | else { | |
12139627 | 250 | |
251 | #ifdef TGEANT4_DEBUG | |
f2510df1 | 252 | CheckTrack(); |
12139627 | 253 | #endif |
254 | ||
f2510df1 | 255 | G4ThreeVector position = fTrack->GetPosition(); |
256 | G4Navigator* navigator = | |
257 | G4TransportationManager::GetTransportationManager()-> | |
258 | GetNavigatorForTracking(); | |
259 | physVolume | |
260 | = navigator->LocateGlobalPointAndSetup(position); | |
261 | } | |
262 | ||
263 | return physVolume; | |
264 | } | |
265 | ||
2817d3e2 | 266 | Int_t TG4StepManager::CurrentVolID(Int_t& copyNo) const |
267 | { | |
268 | // Returns the current sensitive detector ID | |
269 | // and the copy number of the current physical volume. | |
270 | // --- | |
271 | ||
f2510df1 | 272 | G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume(); |
feb86ea5 | 273 | copyNo = physVolume->GetCopyNo() + 1; |
2817d3e2 | 274 | |
f2510df1 | 275 | // sensitive detector ID |
da99be38 | 276 | TG4GeometryServices* geometryServices = TG4GeometryServices::Instance(); |
277 | return geometryServices->GetVolumeID(physVolume->GetLogicalVolume()); | |
f2510df1 | 278 | } |
2817d3e2 | 279 | |
280 | Int_t TG4StepManager::CurrentVolOffID(Int_t off, Int_t& copyNo) const | |
281 | { | |
282 | // Returns the off-th mother's of the current volume | |
283 | // the sensitive detector ID and the copy number. | |
284 | // --- | |
285 | ||
286 | if (off == 0) return CurrentVolID(copyNo); | |
287 | ||
f2510df1 | 288 | G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off); |
289 | ||
290 | if (mother) { | |
feb86ea5 | 291 | copyNo = mother->GetCopyNo() + 1; |
f2510df1 | 292 | |
293 | // sensitive detector ID | |
da99be38 | 294 | TG4GeometryServices* geometryServices = TG4GeometryServices::Instance(); |
295 | return geometryServices->GetVolumeID(mother->GetLogicalVolume()); | |
2817d3e2 | 296 | } |
f2510df1 | 297 | else { |
298 | copyNo = 0; | |
299 | return 0; | |
300 | } | |
2817d3e2 | 301 | } |
302 | ||
303 | const char* TG4StepManager::CurrentVolName() const | |
304 | { | |
305 | // Returns the current physical volume name. | |
306 | // --- | |
307 | ||
f2510df1 | 308 | return GetCurrentPhysicalVolume()->GetName(); |
2817d3e2 | 309 | } |
310 | ||
311 | const char* TG4StepManager::CurrentVolOffName(Int_t off) const | |
312 | { | |
313 | // Returns the off-th mother's physical volume name. | |
314 | // --- | |
315 | ||
f2510df1 | 316 | if (off == 0) return CurrentVolName(); |
2817d3e2 | 317 | |
f2510df1 | 318 | G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off); |
319 | ||
320 | if (mother) | |
321 | return mother->GetName(); | |
322 | else | |
2817d3e2 | 323 | return 0; |
2817d3e2 | 324 | } |
325 | ||
326 | Int_t TG4StepManager::CurrentMaterial(Float_t &a, Float_t &z, Float_t &dens, | |
327 | Float_t &radl, Float_t &absl) const | |
328 | { | |
329 | // Returns the parameters of the current material during transport | |
330 | // the return value is the number of elements in the mixture. | |
331 | // --- | |
332 | ||
f2510df1 | 333 | G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume(); |
334 | ||
335 | G4Material* material | |
336 | = physVolume->GetLogicalVolume()->GetMaterial(); | |
337 | ||
12139627 | 338 | if (material) { |
f2510df1 | 339 | G4int nofElements = material->GetNumberOfElements(); |
da99be38 | 340 | TG4GeometryServices* geometryServices = TG4GeometryServices::Instance(); |
341 | a = geometryServices->GetEffA(material); | |
342 | z = geometryServices->GetEffZ(material); | |
2817d3e2 | 343 | |
f2510df1 | 344 | // density |
345 | dens = material->GetDensity(); | |
1d28d5b2 | 346 | dens /= TG4G3Units::MassDensity(); |
2817d3e2 | 347 | |
f2510df1 | 348 | // radiation length |
349 | radl = material->GetRadlen(); | |
1d28d5b2 | 350 | radl /= TG4G3Units::Length(); |
2817d3e2 | 351 | |
f2510df1 | 352 | absl = 0.; // this parameter is not defined in Geant4 |
353 | return nofElements; | |
354 | } | |
355 | else { | |
356 | TG4Globals::Exception( | |
357 | "TG4StepManager::CurrentMaterial(..): material is not defined."); | |
2817d3e2 | 358 | return 0; |
359 | } | |
360 | } | |
361 | ||
362 | void TG4StepManager::Gmtod(Float_t* xm, Float_t* xd, Int_t iflag) | |
363 | { | |
364 | // Transforms a position from the world reference frame | |
365 | // to the current volume reference frame. | |
366 | // | |
367 | // Geant3 desription: | |
368 | // ================== | |
369 | // Computes coordinates XD (in DRS) | |
370 | // from known coordinates XM in MRS | |
371 | // The local reference system can be initialized by | |
372 | // - the tracking routines and GMTOD used in GUSTEP | |
373 | // - a call to GMEDIA(XM,NUMED) | |
374 | // - a call to GLVOLU(NLEVEL,NAMES,NUMBER,IER) | |
375 | // (inverse routine is GDTOM) | |
376 | // | |
377 | // If IFLAG=1 convert coordinates | |
378 | // IFLAG=2 convert direction cosinus | |
379 | // | |
380 | // --- | |
381 | ||
12139627 | 382 | G4AffineTransform affineTransform; |
f2510df1 | 383 | |
12139627 | 384 | if (fStepStatus == kVertex) { |
385 | G4Navigator* navigator = | |
386 | G4TransportationManager::GetTransportationManager()-> | |
387 | GetNavigatorForTracking(); | |
388 | ||
389 | affineTransform = navigator->GetGlobalToLocalTransform(); | |
390 | } | |
391 | else { | |
f2510df1 | 392 | |
12139627 | 393 | #ifdef TGEANT4_DEBUG |
394 | CheckStep("Gmtod"); | |
395 | #endif | |
396 | ||
397 | affineTransform | |
398 | = fStep->GetPreStepPoint()->GetTouchable()->GetHistory() | |
399 | ->GetTopTransform(); | |
400 | } | |
401 | ||
402 | G4ThreeVector theGlobalPoint(xm[0],xm[1],xm[2]); | |
f2510df1 | 403 | G4ThreeVector theLocalPoint; |
404 | if(iflag == 1) | |
405 | theLocalPoint = affineTransform.TransformPoint(theGlobalPoint); | |
406 | else if ( iflag == 2) | |
407 | theLocalPoint = affineTransform.TransformAxis(theGlobalPoint); | |
408 | else | |
409 | TG4Globals::Exception( | |
410 | "TG4StepManager::Gmtod(..,iflag): iflag is not in 1..2"); | |
2817d3e2 | 411 | |
f2510df1 | 412 | xd[0] = theLocalPoint.x(); |
413 | xd[1] = theLocalPoint.y(); | |
414 | xd[2] = theLocalPoint.z(); | |
2817d3e2 | 415 | } |
416 | ||
417 | void TG4StepManager::Gdtom(Float_t* xd, Float_t* xm, Int_t iflag) | |
418 | { | |
419 | // Transforms a position from the current volume reference frame | |
420 | // to the world reference frame. | |
421 | // | |
422 | // Geant3 desription: | |
423 | // ================== | |
424 | // Computes coordinates XM (Master Reference System | |
425 | // knowing the coordinates XD (Detector Ref System) | |
426 | // The local reference system can be initialized by | |
427 | // - the tracking routines and GDTOM used in GUSTEP | |
428 | // - a call to GSCMED(NLEVEL,NAMES,NUMBER) | |
429 | // (inverse routine is GMTOD) | |
430 | // | |
431 | // If IFLAG=1 convert coordinates | |
432 | // IFLAG=2 convert direction cosinus | |
433 | // | |
434 | // --- | |
435 | ||
12139627 | 436 | G4AffineTransform affineTransform; |
f2510df1 | 437 | |
12139627 | 438 | if (fStepStatus == kVertex) { |
439 | G4Navigator* navigator = | |
440 | G4TransportationManager::GetTransportationManager()-> | |
441 | GetNavigatorForTracking(); | |
442 | ||
443 | affineTransform = navigator->GetLocalToGlobalTransform(); | |
444 | } | |
445 | else { | |
2817d3e2 | 446 | |
12139627 | 447 | #ifdef TGEANT4_DEBUG |
448 | CheckStep("Gdtom"); | |
449 | #endif | |
450 | ||
451 | // check this | |
452 | ||
453 | affineTransform | |
454 | = fStep->GetPreStepPoint()->GetTouchable()->GetHistory() | |
2817d3e2 | 455 | ->GetTopTransform().Inverse(); |
12139627 | 456 | } |
2817d3e2 | 457 | |
12139627 | 458 | G4ThreeVector theLocalPoint(xd[0],xd[1],xd[2]); |
f2510df1 | 459 | G4ThreeVector theGlobalPoint; |
460 | if(iflag == 1) | |
461 | theGlobalPoint = affineTransform.TransformPoint(theLocalPoint); | |
462 | else if( iflag == 2) | |
463 | theGlobalPoint = affineTransform.TransformAxis(theLocalPoint); | |
464 | else | |
465 | TG4Globals::Warning( | |
466 | "TG4StepManager::Gdtom(...,iflag): iflag is not in 1..2"); | |
467 | ||
468 | xm[0] = theGlobalPoint.x(); | |
469 | xm[1] = theGlobalPoint.y(); | |
470 | xm[2] = theGlobalPoint.z(); | |
2817d3e2 | 471 | } |
472 | ||
473 | Float_t TG4StepManager::MaxStep() const | |
474 | { | |
475 | // Returns maximum step allowed in the current logical volume | |
476 | // by User Limits. | |
477 | // --- | |
478 | ||
12139627 | 479 | G4LogicalVolume* curLogVolume |
f2510df1 | 480 | = GetCurrentPhysicalVolume()->GetLogicalVolume(); |
12139627 | 481 | |
482 | // check this | |
f2510df1 | 483 | G4UserLimits* userLimits |
484 | = curLogVolume->GetUserLimits(); | |
485 | ||
486 | G4double maxStep; | |
487 | if (userLimits == 0) { | |
488 | G4String text = "User Limits are not defined for log volume "; | |
489 | text = text + curLogVolume->GetName(); | |
490 | TG4Globals::Warning(text); | |
2acb5b6d | 491 | return FLT_MAX; |
2817d3e2 | 492 | } |
f2510df1 | 493 | else { |
494 | const G4Track& trackRef = *(fTrack); | |
495 | maxStep = userLimits->GetMaxAllowedStep(trackRef); | |
1d28d5b2 | 496 | maxStep /= TG4G3Units::Length(); |
f2510df1 | 497 | return maxStep; |
498 | } | |
2817d3e2 | 499 | } |
500 | ||
501 | Int_t TG4StepManager::GetMaxNStep() const | |
502 | { | |
503 | // Not yet implemented. | |
504 | // --- | |
505 | ||
506 | TG4Globals::Warning( | |
507 | "Method GetMaxNStep is not yet implemented in TG4StepManager."); | |
508 | return 0; | |
509 | } | |
510 | ||
511 | void TG4StepManager::TrackPosition(TLorentzVector& position) const | |
512 | { | |
513 | // Current particle position (in the world reference frame) | |
514 | // and the local time since the current track is created | |
515 | // (position of the PostStepPoint). | |
516 | // --- | |
517 | ||
12139627 | 518 | #ifdef TGEANT4_DEBUG |
f2510df1 | 519 | CheckTrack(); |
12139627 | 520 | #endif |
521 | ||
f2510df1 | 522 | // get position |
523 | // check if this is == to PostStepPoint position !! | |
524 | G4ThreeVector positionVector = fTrack->GetPosition(); | |
1d28d5b2 | 525 | positionVector *= 1./(TG4G3Units::Length()); |
2817d3e2 | 526 | |
f2510df1 | 527 | // local time |
528 | G4double time = fTrack->GetLocalTime(); | |
1d28d5b2 | 529 | time /= TG4G3Units::Time(); |
f2510df1 | 530 | |
531 | SetTLorentzVector(positionVector, time, position); | |
2817d3e2 | 532 | } |
533 | ||
534 | Int_t TG4StepManager::GetMedium() const | |
535 | { | |
536 | // Returns the second index of the current material (corresponding to | |
537 | // G3 tracking medium index). | |
538 | // --- | |
539 | ||
f2510df1 | 540 | // current material |
541 | G4Material* curMaterial | |
542 | = GetCurrentPhysicalVolume()->GetLogicalVolume()->GetMaterial(); | |
2817d3e2 | 543 | |
f2510df1 | 544 | // medium index |
da99be38 | 545 | TG4GeometryServices* geometryServices = TG4GeometryServices::Instance(); |
546 | return geometryServices->GetMediumId(curMaterial); | |
2817d3e2 | 547 | } |
548 | ||
549 | void TG4StepManager::TrackMomentum(TLorentzVector& momentum) const | |
550 | { | |
551 | // Current particle "momentum" (px, py, pz, Etot). | |
552 | // --- | |
553 | ||
12139627 | 554 | #ifdef TGEANT4_DEBUG |
f2510df1 | 555 | CheckTrack(); |
12139627 | 556 | #endif |
2817d3e2 | 557 | |
f2510df1 | 558 | G4ThreeVector momentumVector = fTrack->GetMomentum(); |
1d28d5b2 | 559 | momentumVector *= 1./(TG4G3Units::Energy()); |
2817d3e2 | 560 | |
f2510df1 | 561 | G4double energy = fTrack->GetDynamicParticle()->GetTotalEnergy(); |
1d28d5b2 | 562 | energy /= TG4G3Units::Energy(); |
f2510df1 | 563 | |
564 | SetTLorentzVector(momentumVector, energy, momentum); | |
2817d3e2 | 565 | } |
566 | ||
567 | void TG4StepManager::TrackVertexPosition(TLorentzVector& position) const | |
568 | { | |
569 | // The vertex particle position (in the world reference frame) | |
570 | // and the local time since the current track is created. | |
571 | // --- | |
572 | ||
12139627 | 573 | #ifdef TGEANT4_DEBUG |
f2510df1 | 574 | CheckTrack(); |
12139627 | 575 | #endif |
f2510df1 | 576 | |
577 | // position | |
578 | G4ThreeVector positionVector = fTrack->GetVertexPosition(); | |
1d28d5b2 | 579 | positionVector *= 1./(TG4G3Units::Length()); |
2817d3e2 | 580 | |
f2510df1 | 581 | // local time |
582 | // to be checked | |
583 | G4double time = fTrack->GetLocalTime(); | |
1d28d5b2 | 584 | time /= TG4G3Units::Time(); |
2817d3e2 | 585 | |
f2510df1 | 586 | SetTLorentzVector(positionVector, time, position); |
2817d3e2 | 587 | } |
588 | ||
589 | void TG4StepManager::TrackVertexMomentum(TLorentzVector& momentum) const | |
590 | { | |
591 | // The vertex particle "momentum" (px, py, pz, Ekin) | |
592 | // to do: change Ekin -> Etot | |
593 | // --- | |
594 | ||
12139627 | 595 | #ifdef TGEANT4_DEBUG |
f2510df1 | 596 | CheckTrack(); |
12139627 | 597 | #endif |
598 | ||
f2510df1 | 599 | G4ThreeVector momentumVector = fTrack->GetVertexMomentumDirection(); |
1d28d5b2 | 600 | momentumVector *= 1./(TG4G3Units::Energy()); |
2817d3e2 | 601 | |
f2510df1 | 602 | G4double energy = fTrack->GetVertexKineticEnergy(); |
1d28d5b2 | 603 | energy /= TG4G3Units::Energy(); |
2817d3e2 | 604 | |
f2510df1 | 605 | SetTLorentzVector(momentumVector, energy, momentum); |
2817d3e2 | 606 | } |
607 | ||
608 | Float_t TG4StepManager::TrackStep() const | |
609 | { | |
610 | // Returns the current step length. | |
611 | // --- | |
612 | ||
f2510df1 | 613 | G4double length; |
614 | if (fStepStatus == kNormalStep) { | |
12139627 | 615 | |
616 | #ifdef TGEANT4_DEBUG | |
617 | CheckStep("TrackStep"); | |
618 | #endif | |
619 | ||
f2510df1 | 620 | length = fStep->GetStepLength(); |
1d28d5b2 | 621 | length /= TG4G3Units::Length(); |
f2510df1 | 622 | } |
623 | else | |
624 | length = 0; | |
625 | ||
626 | return length; | |
2817d3e2 | 627 | } |
628 | ||
629 | Float_t TG4StepManager::TrackLength() const | |
630 | { | |
631 | // Returns the length of the current track from its origin. | |
632 | // --- | |
633 | ||
12139627 | 634 | #ifdef TGEANT4_DEBUG |
f2510df1 | 635 | CheckTrack(); |
12139627 | 636 | #endif |
f2510df1 | 637 | |
638 | G4double length = fTrack->GetTrackLength(); | |
1d28d5b2 | 639 | length /= TG4G3Units::Length(); |
f2510df1 | 640 | return length; |
2817d3e2 | 641 | } |
642 | ||
643 | Float_t TG4StepManager::TrackTime() const | |
644 | { | |
645 | // Returns the local time since the current track is created. | |
646 | // Comment: | |
647 | // in Geant4: there is also defined proper time as | |
648 | // the proper time of the dynamical particle of the current track. | |
649 | // --- | |
650 | ||
12139627 | 651 | #ifdef TGEANT4_DEBUG |
f2510df1 | 652 | CheckTrack(); |
12139627 | 653 | #endif |
f2510df1 | 654 | |
655 | G4double time = fTrack->GetLocalTime(); | |
1d28d5b2 | 656 | time /= TG4G3Units::Time(); |
f2510df1 | 657 | return time; |
2817d3e2 | 658 | } |
659 | ||
660 | Float_t TG4StepManager::Edep() const | |
661 | { | |
662 | // Returns total energy deposit in this step. | |
663 | // --- | |
664 | ||
f2510df1 | 665 | G4double energyDeposit; |
666 | if (fStepStatus == kNormalStep) { | |
12139627 | 667 | |
668 | #ifdef TGEANT4_DEBUG | |
669 | CheckStep("Edep"); | |
670 | #endif | |
671 | ||
f2510df1 | 672 | energyDeposit = fStep->GetTotalEnergyDeposit(); |
1d28d5b2 | 673 | energyDeposit /= TG4G3Units::Energy(); |
2817d3e2 | 674 | } |
f2510df1 | 675 | else |
676 | energyDeposit = 0; | |
677 | ||
678 | return energyDeposit; | |
2817d3e2 | 679 | } |
680 | ||
681 | Int_t TG4StepManager::TrackPid() const | |
682 | { | |
683 | // Returns the current particle PDG encoding. | |
684 | // --- | |
685 | ||
12139627 | 686 | #ifdef TGEANT4_DEBUG |
f2510df1 | 687 | CheckTrack(); |
12139627 | 688 | #endif |
2817d3e2 | 689 | |
f2510df1 | 690 | G4ParticleDefinition* particle |
691 | = fTrack->GetDynamicParticle()->GetDefinition(); | |
692 | ||
1d28d5b2 | 693 | // ask TG4ParticlesManager to get PDG encoding |
f2510df1 | 694 | // (in order to get PDG from extended TDatabasePDG |
695 | // in case the standard PDG code is not defined) | |
1d28d5b2 | 696 | G4int pdgEncoding |
697 | = TG4ParticlesManager::Instance()->GetPDGEncodingFast(particle); | |
f2510df1 | 698 | |
699 | return pdgEncoding; | |
2817d3e2 | 700 | } |
701 | ||
702 | Float_t TG4StepManager::TrackCharge() const | |
703 | { | |
704 | // Returns the current particle charge. | |
705 | // --- | |
706 | ||
12139627 | 707 | #ifdef TGEANT4_DEBUG |
f2510df1 | 708 | CheckTrack(); |
12139627 | 709 | #endif |
710 | ||
f2510df1 | 711 | G4double charge |
712 | = fTrack->GetDynamicParticle()->GetDefinition() | |
713 | ->GetPDGCharge(); | |
1d28d5b2 | 714 | charge /= TG4G3Units::Charge(); |
f2510df1 | 715 | return charge; |
2817d3e2 | 716 | } |
717 | ||
718 | Float_t TG4StepManager::TrackMass() const | |
719 | { | |
720 | // Returns current particle rest mass. | |
721 | // --- | |
722 | ||
12139627 | 723 | #ifdef TGEANT4_DEBUG |
f2510df1 | 724 | CheckTrack(); |
12139627 | 725 | #endif |
f2510df1 | 726 | |
727 | G4double mass | |
728 | = fTrack->GetDynamicParticle()->GetDefinition() | |
729 | ->GetPDGMass(); | |
1d28d5b2 | 730 | mass /= TG4G3Units::Mass(); |
f2510df1 | 731 | return mass; |
2817d3e2 | 732 | } |
733 | ||
734 | Float_t TG4StepManager::Etot() const | |
735 | { | |
736 | // Returns total energy of the current particle. | |
737 | // --- | |
738 | ||
12139627 | 739 | #ifdef TGEANT4_DEBUG |
f2510df1 | 740 | CheckTrack(); |
12139627 | 741 | #endif |
f2510df1 | 742 | |
743 | G4double energy | |
744 | = fTrack->GetDynamicParticle()->GetTotalEnergy(); | |
1d28d5b2 | 745 | energy /= TG4G3Units::Energy(); |
f2510df1 | 746 | return energy; |
2817d3e2 | 747 | } |
748 | ||
749 | Bool_t TG4StepManager::IsTrackInside() const | |
750 | { | |
751 | // Returns true if particle does not cross geometrical boundary | |
f2510df1 | 752 | // and is not in vertex. |
2817d3e2 | 753 | // --- |
754 | ||
f2510df1 | 755 | if (fStepStatus == kNormalStep && !(IsTrackExiting()) ) { |
756 | // track is always inside during a normal step | |
757 | return true; | |
758 | } | |
759 | ||
760 | return false; | |
2817d3e2 | 761 | } |
762 | ||
763 | Bool_t TG4StepManager::IsTrackEntering() const | |
764 | { | |
765 | // Returns true if particle cross a geometrical boundary | |
f2510df1 | 766 | // or is in vertex. |
2817d3e2 | 767 | // --- |
768 | ||
f2510df1 | 769 | if (fStepStatus != kNormalStep) { |
770 | // track is entering during a vertex or boundary step | |
771 | return true; | |
772 | } | |
773 | ||
774 | return false; | |
2817d3e2 | 775 | } |
776 | ||
777 | Bool_t TG4StepManager::IsTrackExiting() const | |
778 | { | |
f2510df1 | 779 | // Returns true if particle cross a geometrical boundary. |
2817d3e2 | 780 | // --- |
781 | ||
f2510df1 | 782 | if (fStepStatus == kNormalStep) { |
12139627 | 783 | |
784 | #ifdef TGEANT4_DEBUG | |
785 | CheckStep("IsTrackExiting"); | |
786 | #endif | |
787 | ||
f2510df1 | 788 | if (fStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary) |
789 | return true; | |
2817d3e2 | 790 | } |
f2510df1 | 791 | |
792 | return false; | |
2817d3e2 | 793 | } |
794 | ||
795 | Bool_t TG4StepManager::IsTrackOut() const | |
796 | { | |
68f491b7 | 797 | // Returns true if particle cross the world boundary |
2817d3e2 | 798 | // at post-step point. |
799 | // --- | |
800 | ||
f2510df1 | 801 | if (fStepStatus == kVertex) return false; |
802 | ||
12139627 | 803 | #ifdef TGEANT4_DEBUG |
804 | CheckStep("IsTrackCut"); | |
805 | #endif | |
f2510df1 | 806 | |
807 | // check | |
808 | G4StepStatus status | |
809 | = fStep->GetPostStepPoint()->GetStepStatus(); | |
810 | if (status == fWorldBoundary) | |
811 | return true; | |
812 | else | |
2817d3e2 | 813 | return false; |
2817d3e2 | 814 | } |
815 | ||
816 | Bool_t TG4StepManager::IsTrackStop() const | |
817 | { | |
818 | // Returns true if particle has stopped | |
819 | // or has been killed, suspended or postponed to next event. | |
820 | // | |
821 | // Possible track status from G4: | |
822 | // fAlive, // Continue the tracking | |
823 | // fStopButAlive, // Invoke active rest physics processes and | |
824 | // // and kill the current track afterward | |
825 | // fStopAndKill, // Kill the current track | |
826 | // fKillTrackAndSecondaries, | |
827 | // // Kill the current track and also associated | |
828 | // // secondaries. | |
829 | // fSuspend, // Suspend the current track | |
830 | // fPostponeToNextEvent | |
831 | // // Postpones the tracking of thecurrent track | |
832 | // // to the next event. | |
833 | // --- | |
834 | ||
12139627 | 835 | #ifdef TGEANT4_DEBUG |
f2510df1 | 836 | CheckTrack(); |
12139627 | 837 | #endif |
f2510df1 | 838 | |
839 | // check | |
840 | G4TrackStatus status | |
841 | = fTrack->GetTrackStatus(); | |
842 | if ((status == fStopAndKill) || | |
843 | (status == fKillTrackAndSecondaries) || | |
844 | (status == fSuspend) || | |
845 | (status == fPostponeToNextEvent)) { | |
846 | return true; | |
2817d3e2 | 847 | } |
f2510df1 | 848 | else |
849 | return false; | |
2817d3e2 | 850 | } |
851 | ||
852 | Bool_t TG4StepManager::IsTrackDisappeared() const | |
853 | { | |
854 | // Returns true if particle has disappeared | |
855 | // (due to any physical process) | |
856 | // or has been killed, suspended or postponed to next event. | |
857 | // --- | |
858 | ||
12139627 | 859 | #ifdef TGEANT4_DEBUG |
f2510df1 | 860 | CheckTrack(); |
12139627 | 861 | #endif |
f2510df1 | 862 | |
863 | // check | |
864 | G4TrackStatus status | |
865 | = fTrack->GetTrackStatus(); | |
866 | if ((status == fStopButAlive) || | |
867 | (status == fKillTrackAndSecondaries) || | |
868 | (status == fSuspend) || | |
869 | (status == fPostponeToNextEvent)) { | |
870 | return true; | |
2817d3e2 | 871 | } |
f2510df1 | 872 | else |
873 | return false; | |
2817d3e2 | 874 | } |
875 | ||
876 | Bool_t TG4StepManager::IsTrackAlive() const | |
877 | { | |
878 | // Returns true if particle continues tracking. | |
879 | // --- | |
880 | ||
12139627 | 881 | #ifdef TGEANT4_DEBUG |
f2510df1 | 882 | CheckTrack(); |
12139627 | 883 | #endif |
f2510df1 | 884 | |
885 | G4TrackStatus status | |
886 | = fTrack->GetTrackStatus(); | |
887 | if (status == fAlive) | |
888 | return true; | |
889 | else | |
890 | return false; | |
2817d3e2 | 891 | } |
892 | ||
893 | Bool_t TG4StepManager::IsNewTrack() const | |
894 | { | |
895 | // Returns true when track performs the first step. | |
896 | // --- | |
897 | ||
f2510df1 | 898 | if (fStepStatus == kVertex) |
2817d3e2 | 899 | return true; |
900 | else | |
901 | return false; | |
902 | } | |
903 | ||
904 | Int_t TG4StepManager::NSecondaries() const | |
905 | { | |
906 | // Returns the number of secondary particles generated | |
907 | // in the current step. | |
908 | // --- | |
909 | ||
12139627 | 910 | #ifdef TGEANT4_DEBUG |
f2510df1 | 911 | CheckSteppingManager(); |
12139627 | 912 | #endif |
2817d3e2 | 913 | |
f2510df1 | 914 | G4int nofSecondaries = 0; |
915 | nofSecondaries += fSteppingManager->GetfN2ndariesAtRestDoIt(); | |
916 | nofSecondaries += fSteppingManager->GetfN2ndariesAlongStepDoIt(); | |
917 | nofSecondaries += fSteppingManager->GetfN2ndariesPostStepDoIt(); | |
918 | ||
919 | return nofSecondaries; | |
2817d3e2 | 920 | } |
921 | ||
922 | void TG4StepManager::GetSecondary(Int_t index, Int_t& particleId, | |
923 | TLorentzVector& position, TLorentzVector& momentum) | |
924 | { | |
925 | // Fills the parameters (particle encoding, position, momentum) | |
926 | // of the generated secondary particle which is specified by index. | |
927 | // !! Check if indexing of secondaries is same !! | |
928 | // --- | |
929 | ||
12139627 | 930 | #ifdef TGEANT4_DEBUG |
f2510df1 | 931 | CheckSteppingManager(); |
12139627 | 932 | #endif |
f2510df1 | 933 | |
934 | G4int nofSecondaries = NSecondaries(); | |
935 | G4TrackVector* secondaryTracks = fSteppingManager->GetSecondary(); | |
936 | ||
937 | if (secondaryTracks){ | |
938 | if (index < nofSecondaries) { | |
939 | ||
940 | // the index of the first secondary of this step | |
941 | G4int startIndex | |
40c3fb9e | 942 | = secondaryTracks->size() - nofSecondaries; |
f2510df1 | 943 | // (the secondaryTracks vector contains secondaries |
944 | // produced by the track at previous steps, too) | |
945 | G4Track* track | |
946 | = (*secondaryTracks)[startIndex + index]; | |
2817d3e2 | 947 | |
f2510df1 | 948 | // particle encoding |
949 | particleId | |
950 | = track->GetDynamicParticle()->GetDefinition()->GetPDGEncoding(); | |
2817d3e2 | 951 | |
f2510df1 | 952 | // position & time |
953 | G4ThreeVector positionVector = track->GetPosition(); | |
1d28d5b2 | 954 | positionVector *= 1./(TG4G3Units::Length()); |
f2510df1 | 955 | G4double time = track->GetLocalTime(); |
1d28d5b2 | 956 | time /= TG4G3Units::Time(); |
f2510df1 | 957 | SetTLorentzVector(positionVector, time, position); |
958 | ||
959 | // momentum & energy | |
960 | G4ThreeVector momentumVector = track->GetMomentum(); | |
961 | G4double energy = track->GetDynamicParticle()->GetTotalEnergy(); | |
1d28d5b2 | 962 | energy /= TG4G3Units::Energy(); |
f2510df1 | 963 | SetTLorentzVector(momentumVector, energy, momentum); |
2817d3e2 | 964 | } |
965 | else { | |
966 | TG4Globals::Exception( | |
f2510df1 | 967 | "TG4StepManager::GetSecondary(): wrong secondary track index."); |
2817d3e2 | 968 | } |
969 | } | |
f2510df1 | 970 | else { |
971 | TG4Globals::Exception( | |
972 | "TG4StepManager::GetSecondary(): secondary tracks vector is empty"); | |
2817d3e2 | 973 | } |
974 | } | |
975 | ||
da99be38 | 976 | AliMCProcess TG4StepManager::ProdProcess(Int_t isec) const |
2817d3e2 | 977 | { |
da99be38 | 978 | // The process that has produced the secondary particles specified |
979 | // with isec index in the current step. | |
2817d3e2 | 980 | // --- |
981 | ||
12139627 | 982 | G4int nofSecondaries = NSecondaries(); |
7bfb4926 | 983 | if (fStepStatus == kVertex || !nofSecondaries) return kPNoProcess; |
984 | ||
12139627 | 985 | #ifdef TGEANT4_DEBUG |
986 | CheckStep("ProdProcess"); | |
987 | #endif | |
2817d3e2 | 988 | |
7bfb4926 | 989 | G4TrackVector* secondaryTracks = fSteppingManager->GetSecondary(); |
990 | ||
991 | // should never happen | |
992 | if (!secondaryTracks) { | |
993 | TG4Globals::Exception( | |
994 | "TG4StepManager::ProdProcess(): secondary tracks vector is empty."); | |
da99be38 | 995 | |
996 | return kPNoProcess; | |
7bfb4926 | 997 | } |
f2510df1 | 998 | |
da99be38 | 999 | if (isec < nofSecondaries) { |
7bfb4926 | 1000 | |
da99be38 | 1001 | // the index of the first secondary of this step |
1002 | G4int startIndex | |
40c3fb9e | 1003 | = secondaryTracks->size() - nofSecondaries; |
62c4bd4b | 1004 | // the secondaryTracks vector contains secondaries |
1005 | // produced by the track at previous steps, too | |
da99be38 | 1006 | |
1007 | // the secondary track with specified isec index | |
1008 | G4Track* track = (*secondaryTracks)[startIndex + isec]; | |
1009 | ||
62c4bd4b | 1010 | const G4VProcess* kpProcess = track->GetCreatorProcess(); |
da99be38 | 1011 | |
1d28d5b2 | 1012 | AliMCProcess mcProcess |
1013 | = TG4PhysicsManager::Instance()->GetMCProcess(kpProcess); | |
7bfb4926 | 1014 | |
da99be38 | 1015 | // distinguish kPDeltaRay from kPEnergyLoss |
1016 | if (mcProcess == kPEnergyLoss) mcProcess = kPDeltaRay; | |
7bfb4926 | 1017 | |
da99be38 | 1018 | return mcProcess; |
1019 | } | |
1020 | else { | |
1021 | TG4Globals::Exception( | |
1022 | "TG4StepManager::GetSecondary(): wrong secondary track index."); | |
1023 | ||
1024 | return kPNoProcess; | |
1025 | } | |
1026 | } | |
1027 | ||
1028 | ||
1029 | Int_t TG4StepManager::StepProcesses(TArrayI &proc) const | |
1030 | { | |
62c4bd4b | 1031 | // Fills the array of processes that were active in the current step |
1032 | // and returns the number of them. | |
1033 | // TBD: Distinguish between kPDeltaRay and kPEnergyLoss | |
da99be38 | 1034 | // --- |
1035 | ||
62c4bd4b | 1036 | if (fStepStatus == kVertex) { |
1037 | G4cout << "kVertex" << G4endl; | |
1038 | G4int nofProcesses = 1; | |
1039 | proc.Set(nofProcesses); | |
1040 | proc[0] = kPNull; | |
1041 | return nofProcesses; | |
1042 | } | |
1043 | ||
1044 | #ifdef TGEANT4_DEBUG | |
1045 | CheckSteppingManager(); | |
1046 | CheckStep("StepProcesses"); | |
1047 | #endif | |
1048 | ||
1049 | // along step processes | |
1050 | G4ProcessManager* processManager | |
1051 | = fStep->GetTrack()->GetDefinition()->GetProcessManager(); | |
1052 | G4ProcessVector* alongStepProcessVector | |
1053 | = processManager->GetAlongStepProcessVector(); | |
1054 | G4int nofProcesses = alongStepProcessVector->entries(); | |
1055 | ||
1056 | // process defined step | |
1057 | const G4VProcess* kpLastProcess | |
1058 | = fStep->GetPostStepPoint()->GetProcessDefinedStep(); | |
1059 | ||
1060 | // fill the array of processes | |
1061 | proc.Set(nofProcesses); | |
1062 | TG4PhysicsManager* physicsManager = TG4PhysicsManager::Instance(); | |
1063 | G4int i; | |
1064 | for (i=0; i<nofProcesses-1; i++) { | |
1065 | G4VProcess* g4Process = (*alongStepProcessVector)[i]; | |
1066 | // do not fill transportation along step process | |
1067 | if (g4Process->GetProcessName() != "Transportation") { | |
1068 | physicsManager->GetMCProcess(g4Process); | |
1069 | proc[i] = physicsManager->GetMCProcess(g4Process); | |
1070 | } | |
1071 | } | |
1072 | proc[nofProcesses-1] = physicsManager->GetMCProcess(kpLastProcess); | |
1073 | ||
1074 | return nofProcesses; | |
2817d3e2 | 1075 | } |