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