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