]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TGeant4/TG4StepManager.cxx
arguments in the constructor changed
[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"
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
28TG4StepManager* TG4StepManager::fgInstance = 0;
29
30TG4StepManager::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
45TG4StepManager::TG4StepManager(const TG4StepManager& right) {
46//
47 TG4Globals::Exception(
48 "Attempt to copy TG4StepManager singleton.");
49}
50
51TG4StepManager::~TG4StepManager() {
52//
53}
54
55// operators
56
57TG4StepManager& 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 70void 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 80void 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
93void 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 103void 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 115G4VPhysicalVolume* 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
144void 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
167void 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 182void 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
207void 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 216void 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 225G4VPhysicalVolume* 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 266Int_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
280Int_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
303const char* TG4StepManager::CurrentVolName() const
304{
305// Returns the current physical volume name.
306// ---
307
f2510df1 308 return GetCurrentPhysicalVolume()->GetName();
2817d3e2 309}
310
311const 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
326Int_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
362void 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
417void 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
473Float_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
501Int_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
511void 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
534Int_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
549void 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
567void 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
589void 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
608Float_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
629Float_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
643Float_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
660Float_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
681Int_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
702Float_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
718Float_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
734Float_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
749Bool_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
763Bool_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
777Bool_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
795Bool_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
816Bool_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
852Bool_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
876Bool_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
893Bool_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
904Int_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
922void 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 976AliMCProcess 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
1029Int_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}