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