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