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