All printout under verbosity level control.
[u/mrichter/AliRoot.git] / TFluka / TFluka.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.16  2003/03/26 13:30:35  morsch
19 SetTrackIsExiting, SetTrackIsEntering, SetTrackIsInside added.
20
21 Revision 1.15  2003/02/18 16:12:17  morsch
22 Protect  mpdgha against negative argument.
23
24 Revision 1.14  2003/02/18 12:47:59  morsch
25 Gmtod and Gdtom added.
26
27 Revision 1.13  2003/01/31 14:01:51  morsch
28 Major update on
29 - Getters related to geometry.
30 - Communication with run manager (event steering)
31
32 Revision 1.12  2003/01/31 12:18:53  morsch
33 Corrected indices. (E. Futo)
34
35 Revision 1.9  2002/12/06 12:41:29  morsch
36 Mess from last merge cleaned up.
37
38 Revision 1.8  2002/12/06 12:28:44  morsch
39 Region to media mapping corrected and improved.
40
41 Revision 1.7  2002/12/06 12:21:32  morsch
42 User stepping methods added (E. Futo)
43
44 Revision 1.6  2002/11/21 18:40:06  iglez2
45 Media handling added
46
47 Revision 1.5  2002/11/07 17:59:10  iglez2
48 Included the geometry through geant4_vmc/FLUGG
49
50 Revision 1.4  2002/11/04 16:00:46  iglez2
51 The conversion between ID and PDG now uses Fluka routines and arrays which is more consistent.
52
53 Revision 1.3  2002/10/22 15:12:14  alibrary
54 Introducing Riostream.h
55
56 Revision 1.2  2002/10/14 14:57:40  hristov
57 Merging the VirtualMC branch to the main development branch (HEAD)
58
59 Revision 1.1.2.8  2002/10/08 16:33:17  iglez2
60 LSOUIT is set to true before the second call to flukam.
61
62 Revision 1.1.2.7  2002/10/08 09:30:37  iglez2
63 Solved stupid missing ;
64
65 Revision 1.1.2.6  2002/10/07 13:40:22  iglez2
66 First implementations of the PDG <--> Fluka Id conversion routines
67
68 Revision 1.1.2.5  2002/09/26 16:26:03  iglez2
69 Added verbosity
70 Call to gAlice->Generator()->Generate()
71
72 Revision 1.1.2.4  2002/09/26 13:22:23  iglez2
73 Naive implementation of ProcessRun and ProcessEvent
74 Opening/Closing of input file (fInputFileName) with FORTRAN unit 5 before/after the first call to flukam inside Init()
75
76 Revision 1.1.2.3  2002/09/20 15:35:51  iglez2
77 Modification of LFDRTR. Value is passed to FLUKA !!!
78
79 Revision 1.1.2.2  2002/09/18 14:34:44  iglez2
80 Revised version with all pure virtual methods implemented
81
82 Revision 1.1.2.1  2002/07/24 08:49:41  alibrary
83 Adding TFluka to VirtualMC
84
85 Revision 1.1  2002/07/05 13:10:07  morsch
86 First commit of Fluka interface.
87
88 */
89
90 #include <Riostream.h>
91
92 #include "TClonesArray.h"
93 #include "TFluka.h"
94 #include "TCallf77.h"      //For the fortran calls
95 #include "Fdblprc.h"       //(DBLPRC) fluka common
96 #include "Fepisor.h"       //(EPISOR) fluka common
97 #include "Ffinuc.h"        //(FINUC) fluka common
98 #include "Fiounit.h"       //(IOUNIT) fluka common
99 #include "Fpaprop.h"       //(PAPROP) fluka common
100 #include "Fpart.h"         //(PART)   fluka common
101 #include "Ftrackr.h"       //(TRACKR) fluka common
102 #include "Fpaprop.h"       //(PAPROP) fluka common
103 #include "Ffheavy.h"       //(FHEAVY) fluka common
104
105 #include "TVirtualMC.h"
106 #include "TG4GeometryManager.h" //For the geometry management
107 #include "TG4DetConstruction.h" //For the detector construction
108
109 #include "FGeometryInit.hh"
110 #include "TLorentzVector.h"
111 #include "FlukaVolume.h"
112
113 // Fluka methods that may be needed.
114 #ifndef WIN32 
115 # define flukam  flukam_
116 # define fluka_openinp fluka_openinp_
117 # define fluka_closeinp fluka_closeinp_
118 # define mcihad mcihad_
119 # define mpdgha mpdgha_
120 #else 
121 # define flukam  FLUKAM
122 # define fluka_openinp FLUKA_OPENINP
123 # define fluka_closeinp FLUKA_CLOSEINP
124 # define mcihad MCIHAD
125 # define mpdgha MPDGHA
126 #endif
127
128 extern "C" 
129 {
130   //
131   // Prototypes for FLUKA functions
132   //
133   void type_of_call flukam(const int&);
134   void type_of_call fluka_openinp(const int&, DEFCHARA);
135   void type_of_call fluka_closeinp(const int&);
136   int  type_of_call mcihad(const int&);
137   int  type_of_call mpdgha(const int&);
138 }
139
140 //
141 // Class implementation for ROOT
142 //
143 ClassImp(TFluka)
144
145 //
146 //----------------------------------------------------------------------------
147 // TFluka constructors and destructors.
148 //____________________________________________________________________________ 
149 TFluka::TFluka()
150   :TVirtualMC(),
151    fVerbosityLevel(0),
152    fInputFileName(""),
153    fDetector(0),
154    fCurrentFlukaRegion(-1)
155
156   //
157   // Default constructor
158   //
159
160  
161 TFluka::TFluka(const char *title, Int_t verbosity)
162   :TVirtualMC("TFluka",title),
163    fVerbosityLevel(verbosity),
164    fInputFileName(""),
165    fTrackIsEntering(0),
166    fTrackIsExiting(0),
167    fDetector(0),
168    fCurrentFlukaRegion(-1)
169 {
170   if (fVerbosityLevel >=3)
171     cout << "==> TFluka::TFluka(" << title << ") constructor called." << endl;
172
173   
174   // create geometry manager
175   if (fVerbosityLevel >=2)
176     cout << "\t* Creating G4 Geometry manager..." << endl;
177   fGeometryManager = new TG4GeometryManager();
178   if (fVerbosityLevel >=2)
179     cout << "\t* Creating G4 Detector..." << endl;
180   fDetector = new TG4DetConstruction();
181   FGeometryInit* geominit = FGeometryInit::GetInstance();
182   if (geominit)
183     geominit->setDetConstruction(fDetector);
184   else {
185     cerr << "ERROR: Could not create FGeometryInit!" << endl;
186     cerr << "       Exiting!!!" << endl;
187     abort();
188   }
189
190   if (fVerbosityLevel >=3)
191     cout << "<== TFluka::TFluka(" << title << ") constructor called." << endl;
192
193   fVolumeMediaMap = new TClonesArray("FlukaVolume",1000);
194   fNVolumes      = 0;
195   fMediaByRegion = 0;
196 }
197
198 TFluka::~TFluka() {
199   if (fVerbosityLevel >=3)
200     cout << "==> TFluka::~TFluka() destructor called." << endl;
201
202   delete fGeometryManager;
203   fVolumeMediaMap->Delete();
204   delete  fVolumeMediaMap;
205   
206
207   if (fVerbosityLevel >=3)
208     cout << "<== TFluka::~TFluka() destructor called." << endl;
209 }
210
211 //
212 //_____________________________________________________________________________
213 // TFluka control methods
214 //____________________________________________________________________________ 
215 void TFluka::Init() {
216   if (fVerbosityLevel >=3)
217     cout << "==> TFluka::Init() called." << endl;
218
219   if (fVerbosityLevel >=2)
220     cout << "\t* Changing lfdrtr = (" << (GLOBAL.lfdrtr?'T':'F')
221          << ") in fluka..." << endl;
222   GLOBAL.lfdrtr = true;
223
224   if (fVerbosityLevel >=2)
225     cout << "\t* Opening file " << fInputFileName << endl;
226   const char* fname = fInputFileName;
227   fluka_openinp(lunin, PASSCHARA(fname));
228
229   if (fVerbosityLevel >=2)
230     cout << "\t* Calling flukam..." << endl;
231   flukam(1);
232
233   if (fVerbosityLevel >=2)
234     cout << "\t* Closing file " << fInputFileName << endl;
235   fluka_closeinp(lunin);
236
237   if (fVerbosityLevel >=3)
238     cout << "<== TFluka::Init() called." << endl;
239
240   FinishGeometry();
241
242 }
243
244 void TFluka::FinishGeometry() {
245 //
246 // Build-up table with region to medium correspondance
247 //
248     char tmp[5];
249     
250   if (fVerbosityLevel >=3)
251     cout << "==> TFluka::FinishGeometry() called." << endl;
252
253 //  fGeometryManager->Ggclos();
254
255   FGeometryInit* flugg = FGeometryInit::GetInstance();  
256   
257   fMediaByRegion = new Int_t[fNVolumes+2];
258   for (Int_t i = 0; i < fNVolumes; i++)
259   {
260       FlukaVolume* vol = dynamic_cast<FlukaVolume*>((*fVolumeMediaMap)[i]);
261       TString volName = vol->GetName();
262       Int_t   media   = vol->GetMedium();
263       if (fVerbosityLevel >= 3)
264       printf("Finish Geometry: volName, media %d %s %d \n", i, volName.Data(), media);
265       strcpy(tmp, volName.Data());
266       tmp[4] = '\0';
267       flugg->SetMediumFromName(tmp, media, i+1);
268       fMediaByRegion[i] = media;
269   }
270
271   flugg->BuildMediaMap();
272   
273   if (fVerbosityLevel >=3)
274     cout << "<== TFluka::FinishGeometry() called." << endl;
275
276
277 void TFluka::BuildPhysics() {
278   if (fVerbosityLevel >=3)
279     cout << "==> TFluka::BuildPhysics() called." << endl;
280
281
282   if (fVerbosityLevel >=3)
283     cout << "<== TFluka::BuildPhysics() called." << endl;
284 }  
285
286 void TFluka::ProcessEvent() {
287   if (fVerbosityLevel >=3)
288     cout << "==> TFluka::ProcessEvent() called." << endl;
289   fApplication->GeneratePrimaries();
290   EPISOR.lsouit = true;
291   flukam(1);
292   if (fVerbosityLevel >=3)
293     cout << "<== TFluka::ProcessEvent() called." << endl;
294 }
295
296
297 void TFluka::ProcessRun(Int_t nevent) {
298   if (fVerbosityLevel >=3)
299     cout << "==> TFluka::ProcessRun(" << nevent << ") called." 
300          << endl;
301
302   if (fVerbosityLevel >=2) {
303     cout << "\t* GLOBAL.fdrtr = " << (GLOBAL.lfdrtr?'T':'F') << endl;
304     cout << "\t* Calling flukam again..." << endl;
305   }
306   fApplication->InitGeometry();
307   fApplication->BeginEvent();
308   ProcessEvent();
309   fApplication->FinishEvent();
310   if (fVerbosityLevel >=3)
311     cout << "<== TFluka::ProcessRun(" << nevent << ") called." 
312          << endl;
313
314 }
315
316 //_____________________________________________________________________________
317 // methods for building/management of geometry
318 //____________________________________________________________________________ 
319 // functions from GCONS 
320 void TFluka::Gfmate(Int_t imat, char *name, Float_t &a, Float_t &z,  
321                     Float_t &dens, Float_t &radl, Float_t &absl,
322                     Float_t* ubuf, Int_t& nbuf) {
323 //
324   fGeometryManager->Gfmate(imat, name, a, z, dens, radl, absl, ubuf, nbuf);
325
326
327 void TFluka::Gfmate(Int_t imat, char *name, Double_t &a, Double_t &z,  
328                     Double_t &dens, Double_t &radl, Double_t &absl,
329                     Double_t* ubuf, Int_t& nbuf) {
330 //
331   fGeometryManager->Gfmate(imat, name, a, z, dens, radl, absl, ubuf, nbuf);
332
333
334 // detector composition
335 void TFluka::Material(Int_t& kmat, const char* name, Double_t a, 
336                       Double_t z, Double_t dens, Double_t radl, Double_t absl,
337                       Float_t* buf, Int_t nwbuf) {
338 //
339   fGeometryManager
340     ->Material(kmat, name, a, z, dens, radl, absl, buf, nwbuf); 
341
342 void TFluka::Material(Int_t& kmat, const char* name, Double_t a, 
343                       Double_t z, Double_t dens, Double_t radl, Double_t absl,
344                       Double_t* buf, Int_t nwbuf) {
345 //
346   fGeometryManager
347     ->Material(kmat, name, a, z, dens, radl, absl, buf, nwbuf); 
348
349
350 void TFluka::Mixture(Int_t& kmat, const char *name, Float_t *a, 
351                      Float_t *z, Double_t dens, Int_t nlmat, Float_t *wmat) {
352 //
353    fGeometryManager
354      ->Mixture(kmat, name, a, z, dens, nlmat, wmat); 
355
356 void TFluka::Mixture(Int_t& kmat, const char *name, Double_t *a, 
357                      Double_t *z, Double_t dens, Int_t nlmat, Double_t *wmat) {
358 //
359    fGeometryManager
360      ->Mixture(kmat, name, a, z, dens, nlmat, wmat); 
361
362
363 void TFluka::Medium(Int_t& kmed, const char *name, Int_t nmat, 
364                     Int_t isvol, Int_t ifield, Double_t fieldm, Double_t tmaxfd, 
365                     Double_t stemax, Double_t deemax, Double_t epsil, 
366                     Double_t stmin, Float_t* ubuf, Int_t nbuf) { 
367   //
368   fGeometryManager
369     ->Medium(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax, 
370              epsil, stmin, ubuf, nbuf);
371
372 void TFluka::Medium(Int_t& kmed, const char *name, Int_t nmat, 
373                     Int_t isvol, Int_t ifield, Double_t fieldm, Double_t tmaxfd, 
374                     Double_t stemax, Double_t deemax, Double_t epsil, 
375                     Double_t stmin, Double_t* ubuf, Int_t nbuf) { 
376   //
377   fGeometryManager
378     ->Medium(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax, 
379              epsil, stmin, ubuf, nbuf);
380
381
382 void TFluka::Matrix(Int_t& krot, Double_t thetaX, Double_t phiX, 
383                     Double_t thetaY, Double_t phiY, Double_t thetaZ, 
384                     Double_t phiZ) {
385 //                   
386   fGeometryManager
387     ->Matrix(krot, thetaX, phiX, thetaY, phiY, thetaZ, phiZ); 
388
389
390 void TFluka::Gstpar(Int_t itmed, const char *param, Double_t parval) {
391 //
392   fGeometryManager->Gstpar(itmed, param, parval); 
393 }    
394
395 // functions from GGEOM 
396 Int_t TFluka::Gsvolu(const char *name, const char *shape, Int_t nmed,  
397                      Float_t *upar, Int_t np)  {
398 //
399 //  fVolumeMediaMap[TString(name)] = nmed;
400     if (fVerbosityLevel >= 3)
401     printf("TFluka::Gsvolu() name = %s, nmed = %d\n", name, nmed);
402     
403     TClonesArray &lvols = *fVolumeMediaMap;
404     new(lvols[fNVolumes++]) 
405         FlukaVolume(name, nmed);
406     return fGeometryManager->Gsvolu(name, shape, nmed, upar, np); 
407 }
408 Int_t TFluka::Gsvolu(const char *name, const char *shape, Int_t nmed,  
409                      Double_t *upar, Int_t np)  {
410 //
411     TClonesArray &lvols = *fVolumeMediaMap;
412     new(lvols[fNVolumes++]) 
413         FlukaVolume(name, nmed);
414
415     return fGeometryManager->Gsvolu(name, shape, nmed, upar, np); 
416 }
417  
418 void TFluka::Gsdvn(const char *name, const char *mother, Int_t ndiv, 
419                    Int_t iaxis) {
420 //
421 //  The medium of the daughter is the one of the mother
422     Int_t volid = TFluka::VolId(mother);
423     Int_t med   = TFluka::VolId2Mate(volid);
424     TClonesArray &lvols = *fVolumeMediaMap;
425     new(lvols[fNVolumes++]) 
426         FlukaVolume(name, med);
427     fGeometryManager->Gsdvn(name, mother, ndiv, iaxis); 
428
429
430 void TFluka::Gsdvn2(const char *name, const char *mother, Int_t ndiv, 
431                     Int_t iaxis, Double_t c0i, Int_t numed) {
432 //
433     TClonesArray &lvols = *fVolumeMediaMap;
434     new(lvols[fNVolumes++]) 
435         FlukaVolume(name, numed);
436     fGeometryManager->Gsdvn2(name, mother, ndiv, iaxis, c0i, numed); 
437
438
439 void TFluka::Gsdvt(const char *name, const char *mother, Double_t step, 
440                    Int_t iaxis, Int_t numed, Int_t ndvmx) {
441 //      
442     TClonesArray &lvols = *fVolumeMediaMap;
443     new(lvols[fNVolumes++]) 
444         FlukaVolume(name, numed);               
445     fGeometryManager->Gsdvt(name, mother, step, iaxis, numed, ndvmx); 
446
447
448 void TFluka::Gsdvt2(const char *name, const char *mother, Double_t step, 
449                     Int_t iaxis, Double_t c0, Int_t numed, Int_t ndvmx) { 
450 //
451     TClonesArray &lvols = *fVolumeMediaMap;
452     new(lvols[fNVolumes++]) 
453         FlukaVolume(name, numed);
454     fGeometryManager->Gsdvt2(name, mother, step, iaxis, c0, numed, ndvmx); 
455
456
457 void TFluka::Gsord(const char *name, Int_t iax) {
458 //
459   fGeometryManager->Gsord(name, iax); 
460
461
462 void TFluka::Gspos(const char *name, Int_t nr, const char *mother,  
463                    Double_t x, Double_t y, Double_t z, Int_t irot, 
464                    const char *konly) {
465 //
466   fGeometryManager->Gspos(name, nr, mother, x, y, z, irot, konly); 
467
468
469 void TFluka::Gsposp(const char *name, Int_t nr, const char *mother,  
470                     Double_t x, Double_t y, Double_t z, Int_t irot,
471                     const char *konly, Float_t *upar, Int_t np)  {
472   //
473   fGeometryManager->Gsposp(name, nr, mother, x, y, z, irot, konly, upar, np); 
474
475 void TFluka::Gsposp(const char *name, Int_t nr, const char *mother,  
476                     Double_t x, Double_t y, Double_t z, Int_t irot,
477                     const char *konly, Double_t *upar, Int_t np)  {
478   //
479   fGeometryManager->Gsposp(name, nr, mother, x, y, z, irot, konly, upar, np); 
480
481
482 void TFluka::Gsbool(const char* onlyVolName, const char* manyVolName) {
483 //
484   fGeometryManager->Gsbool(onlyVolName, manyVolName);
485 }
486
487 void TFluka::SetCerenkov(Int_t itmed, Int_t npckov, Float_t *ppckov,
488                          Float_t *absco, Float_t *effic, Float_t *rindex) {
489 //
490   fGeometryManager->SetCerenkov(itmed, npckov, ppckov, absco, effic, rindex);
491 }  
492 void TFluka::SetCerenkov(Int_t itmed, Int_t npckov, Double_t *ppckov,
493                          Double_t *absco, Double_t *effic, Double_t *rindex) {
494 //
495   fGeometryManager->SetCerenkov(itmed, npckov, ppckov, absco, effic, rindex);
496 }  
497     
498 // Euclid
499 void TFluka::WriteEuclid(const char* fileName, const char* topVol, 
500                           Int_t number, Int_t nlevel) {
501 //
502   fGeometryManager->WriteEuclid(fileName, topVol, number, nlevel); 
503
504
505
506
507 //_____________________________________________________________________________
508 // methods needed by the stepping
509 //____________________________________________________________________________ 
510
511 Int_t TFluka::GetMedium() const {
512 //
513 //  Get the medium number for the current fluka region
514 //
515     FGeometryInit* flugg = FGeometryInit::GetInstance();  
516     return flugg->GetMedium(fCurrentFlukaRegion);
517 }
518
519
520
521 //____________________________________________________________________________ 
522 // ID <--> PDG transformations
523 //_____________________________________________________________________________
524 Int_t TFluka::IdFromPDG(Int_t pdg) const 
525 {
526   //
527   // Return Fluka code from PDG and pseudo ENDF code
528
529   // MCIHAD() goes from pdg to fluka internal.
530   Int_t intfluka = mcihad(pdg);
531   // KPTOIP array goes from internal to official
532   return GetFlukaKPTOIP(intfluka);
533 }
534
535 Int_t TFluka::PDGFromId(Int_t id) const 
536 {
537   //
538   // Return PDG code and pseudo ENDF code from Fluka code
539
540   //IPTOKP array goes from official to internal
541     if (id == 0) {
542       if (fVerbosityLevel >= 1)
543         printf("PDGFromId: Error id = 0");
544         return -1;
545     }
546     
547   Int_t intfluka = GetFlukaIPTOKP(id);
548     if (intfluka == 0) {
549       if (fVerbosityLevel >= 1)
550         printf("PDGFromId: Error intfluka = 0");
551         return -1;
552     } else if (intfluka < 0) {
553       if (fVerbosityLevel >= 1)
554         printf("PDGFromId: Error intfluka < 0");
555         return -1;
556     }
557     if (fVerbosityLevel >= 3)
558     printf("mpdgha called with %d %d \n", id, intfluka);
559   return mpdgha(intfluka);
560 }
561
562 //_____________________________________________________________________________
563 // methods for step management
564 //____________________________________________________________________________ 
565 //
566 // set methods
567 //
568 void TFluka::SetMaxStep(Double_t)
569 {
570 // SetMaxStep is dummy procedure in TFluka !
571   if (fVerbosityLevel >=3)
572   cout << "SetMaxStep is dummy procedure in TFluka !" << endl;
573 }
574
575 void TFluka::SetMaxNStep(Int_t)
576 {
577 // SetMaxNStep is dummy procedure in TFluka !
578   if (fVerbosityLevel >=3)
579   cout << "SetMaxNStep is dummy procedure in TFluka !" << endl;
580 }
581
582 void TFluka::SetUserDecay(Int_t)
583 {
584 // SetUserDecay is dummy procedure in TFluka !
585   if (fVerbosityLevel >=3)
586   cout << "SetUserDecay is dummy procedure in TFluka !" << endl;
587 }
588
589 //
590 // dynamic properties
591 //
592 void TFluka::TrackPosition(TLorentzVector& position) const
593 {
594 // Return the current position in the master reference frame of the
595 // track being transported
596 // TRACKR.atrack = age of the particle
597 // TRACKR.xtrack = x-position of the last point
598 // TRACKR.ytrack = y-position of the last point
599 // TRACKR.ztrack = z-position of the last point
600   position.SetX(TRACKR.xtrack[TRACKR.ntrack]);
601   position.SetY(TRACKR.ytrack[TRACKR.ntrack]);
602   position.SetZ(TRACKR.ztrack[TRACKR.ntrack]);
603   position.SetT(TRACKR.atrack);
604 //
605 //
606 //
607
608 }
609
610 void TFluka::TrackMomentum(TLorentzVector& momentum) const
611 {
612 // Return the direction and the momentum (GeV/c) of the track
613 // currently being transported
614 // TRACKR.ptrack = momentum of the particle (not always defined, if
615 //               < 0 must be obtained from etrack) 
616 // TRACKR.cx,y,ztrck = direction cosines of the current particle
617 // TRACKR.etrack = total energy of the particle
618 // TRACKR.jtrack = identity number of the particle
619 // PAPROP.am[TRACKR.jtrack] = particle mass in gev
620   if (TRACKR.ptrack >= 0) {
621     momentum.SetPx(TRACKR.ptrack*TRACKR.cxtrck);
622     momentum.SetPy(TRACKR.ptrack*TRACKR.cytrck);
623     momentum.SetPz(TRACKR.ptrack*TRACKR.cztrck);
624     momentum.SetE(TRACKR.etrack);
625     return;
626   }
627   else {
628     Double_t p = sqrt(TRACKR.etrack*TRACKR.etrack - PAPROP.am[TRACKR.jtrack+6]*PAPROP.am[TRACKR.jtrack+6]);
629     momentum.SetPx(p*TRACKR.cxtrck);
630     momentum.SetPy(p*TRACKR.cytrck);
631     momentum.SetPz(p*TRACKR.cztrck);
632     momentum.SetE(TRACKR.etrack);
633     return;
634   }
635 }
636
637 Double_t TFluka::TrackStep() const
638 {
639 // Return the length in centimeters of the current step
640 // TRACKR.ctrack = total curved path
641     return TRACKR.ctrack;
642 }
643
644 Double_t TFluka::TrackLength() const
645 {
646 // Still wrong !!!
647 // This is the sum of substeps !!!
648 // TRACKR.ctrack = total curved path of the current step
649 // Sum of the substeps is identical to TRACKR.ctrack if the is no mag. field
650 // The sum of all step length starting from the beginning of the track
651 // for the time being returns only the length in centimeters of the current step
652     Double_t sum = 0;
653     for ( Int_t j=0;j<TRACKR.ntrack;j++) {
654       sum +=TRACKR.ttrack[j];
655     }
656     return sum;
657 }
658
659 Double_t TFluka::TrackTime() const
660 {
661 // Return the current time of flight of the track being transported
662 // TRACKR.atrack = age of the particle
663   return TRACKR.atrack;
664 }
665
666 Double_t TFluka::Edep() const
667 {
668 // Energy deposition
669 // if TRACKR.ntrack = 0, TRACKR.mtrack = 0:
670 // -->local energy deposition (the value and the point are not recorded in TRACKR)
671 //    but in the variable "rull" of the procedure "endraw.cxx"
672 // if TRACKR.ntrack > 0, TRACKR.mtrack = 0:
673 // -->no energy loss along the track
674 // if TRACKR.ntrack > 0, TRACKR.mtrack > 0:
675 // -->energy loss distributed along the track
676 // TRACKR.dtrack = energy deposition of the jth deposition even
677   if (TRACKR.ntrack == 0 && TRACKR.mtrack == 0)
678     return fRull;
679   else {
680     Double_t sum = 0;
681     for ( Int_t j=0;j<TRACKR.mtrack;j++) {
682       sum +=TRACKR.dtrack[j];  
683     }
684     return sum;
685   }
686 }
687
688 Int_t TFluka::TrackPid() const
689 {
690 // Return the id of the particle transported
691 // TRACKR.jtrack = identity number of the particle
692   return PDGFromId(TRACKR.jtrack);
693 }
694
695 Double_t TFluka::TrackCharge() const
696 {
697 // Return charge of the track currently transported
698 // PAPROP.ichrge = electric charge of the particle
699 // TRACKR.jtrack = identity number of the particle
700   return PAPROP.ichrge[TRACKR.jtrack+6];
701 }
702
703 Double_t TFluka::TrackMass() const
704 {
705 // PAPROP.am = particle mass in GeV
706 // TRACKR.jtrack = identity number of the particle
707   return PAPROP.am[TRACKR.jtrack+6];
708 }
709
710 Double_t TFluka::Etot() const
711 {
712 // TRACKR.etrack = total energy of the particle
713   return TRACKR.etrack;
714 }
715
716 //
717 // track status
718 //
719 Bool_t   TFluka::IsNewTrack() const
720 {
721 // ???????????????,
722 // True if the track is not at the boundary of the current volume
723 // Not true in some cases in bxdraw - to be solved
724   return 1;
725 }
726
727 Bool_t   TFluka::IsTrackInside() const
728 {
729 // True if the track is not at the boundary of the current volume
730 // In Fluka a step is always inside one kind of material
731 // If the step would go behind the region of one material,
732 // it will be shortened to reach only the boundary.
733 // Therefore IsTrackInside() is always true.
734 // Not true in some cases in bxdraw - to be solved
735   return 1;
736 }
737
738 Bool_t   TFluka::IsTrackEntering() const
739 {
740 // True if this is the first step of the track in the current volume
741 // Boundary- (X) crossing
742 // Icode = 19: boundary crossing - call from Kaskad
743 // Icode = 29: boundary crossing - call from Emfsco
744 // Icode = 39: boundary crossing - call from Kasneu
745 // Icode = 49: boundary crossing - call from Kashea
746 // Icode = 59: boundary crossing - call from Kasoph
747   if (fIcode == 19 ||
748       fIcode == 29 ||
749       fIcode == 39 ||
750       fIcode == 49 ||
751       fIcode == 59 ||
752       fTrackIsEntering) return 1;
753   else return 0;
754 }
755
756 Bool_t   TFluka::IsTrackExiting() const
757 {
758 // True if this is the last step of the track in the current volume
759 // Boundary- (X) crossing
760 // Icode = 19: boundary crossing - call from Kaskad
761 // Icode = 29: boundary crossing - call from Emfsco
762 // Icode = 39: boundary crossing - call from Kasneu
763 // Icode = 49: boundary crossing - call from Kashea
764 // Icode = 59: boundary crossing - call from Kasoph
765   if (fIcode == 19 ||
766       fIcode == 29 ||
767       fIcode == 39 ||
768       fIcode == 49 ||
769       fIcode == 59 ||
770       fTrackIsExiting) return 1;
771   else return 0;
772 }
773
774 Bool_t   TFluka::IsTrackOut() const
775 {
776 // True if the track is out of the setup
777 // means escape
778 // Icode = 14: escape - call from Kaskad
779 // Icode = 23: escape - call from Emfsco
780 // Icode = 32: escape - call from Kasneu
781 // Icode = 40: escape - call from Kashea
782 // Icode = 51: escape - call from Kasoph
783   if (fIcode == 14 ||
784       fIcode == 23 ||
785       fIcode == 32 ||
786       fIcode == 40 ||
787       fIcode == 51) return 1;
788   else return 0;
789 }
790
791 Bool_t   TFluka::IsTrackDisappeared() const
792 {
793 // means all inelastic interactions and decays
794 // fIcode from usdraw
795   if (fIcode == 101 || // inelastic interaction
796       fIcode == 102 || // particle decay
797       fIcode == 214 || // in-flight annihilation
798       fIcode == 215 || // annihilation at rest
799       fIcode == 217 || // pair production
800       fIcode == 221) return 1;
801   else return 0;
802 }
803
804 Bool_t   TFluka::IsTrackStop() const
805 {
806 // True if the track energy has fallen below the threshold
807 // means stopped by signal or below energy threshold
808 // Icode = 12: stopping particle       - call from Kaskad
809 // Icode = 15: time kill               - call from Kaskad
810 // Icode = 21: below threshold, iarg=1 - call from Emfsco
811 // Icode = 22: below threshold, iarg=2 - call from Emfsco
812 // Icode = 24: time kill               - call from Emfsco
813 // Icode = 31: below threshold         - call from Kasneu
814 // Icode = 33: time kill               - call from Kasneu
815 // Icode = 41: time kill               - call from Kashea
816 // Icode = 52: time kill               - call from Kasoph
817   if (fIcode == 12 ||
818       fIcode == 15 ||
819       fIcode == 21 ||
820       fIcode == 22 ||
821       fIcode == 24 ||
822       fIcode == 31 ||
823       fIcode == 33 ||
824       fIcode == 41 ||
825       fIcode == 52) return 1;
826   else return 0;
827 }
828
829 Bool_t   TFluka::IsTrackAlive() const
830 {
831 // means not disappeared or not out
832   if (IsTrackDisappeared() || IsTrackOut() ) return 0;
833   else return 1;
834 }
835
836 //
837 // secondaries
838 //
839
840 Int_t TFluka::NSecondaries() const
841 // Number of secondary particles generated in the current step
842 // FINUC.np = number of secondaries except light and heavy ions
843 // FHEAVY.npheav = number of secondaries for light and heavy secondary ions
844 {
845   return FINUC.np + FHEAVY.npheav;
846 }
847
848 void     TFluka::GetSecondary(Int_t isec, Int_t& particleId,
849                 TLorentzVector& position, TLorentzVector& momentum)
850 {
851   if (isec >= 0 && isec < FINUC.np) {
852           // more fine condition depending on icode
853           // icode = 100 ?
854           // icode = 101 OK
855           // icode = 102 OK
856           // icode = 103 ?
857           // icode = 104 ?
858           // icode = 105 ?
859           // icode = 208 ?
860           // icode = 210 ?
861           // icode = 212 ?
862           // icode = 214 OK
863           // icode = 215 OK
864           // icode = 219 ?
865           // icode = 221 OK
866           // icode = 225 ?
867           // icode = 300 ?
868           // icode = 400 ?
869           
870     particleId = PDGFromId(FINUC.kpart[isec]);
871     position.SetX(fXsco);
872     position.SetY(fYsco);
873     position.SetZ(fZsco);
874     position.SetT(TRACKR.atrack);
875 //  position.SetT(TRACKR.atrack+FINUC.agesec[isec]); //not yet implem.
876     momentum.SetPx(FINUC.plr[isec]*FINUC.cxr[isec]);
877     momentum.SetPy(FINUC.plr[isec]*FINUC.cyr[isec]);
878     momentum.SetPz(FINUC.plr[isec]*FINUC.czr[isec]);
879     momentum.SetE(FINUC.tki[isec] + PAPROP.am[FINUC.kpart[isec]+6]);
880   }
881   if (isec >= FINUC.np && isec < FINUC.np + FHEAVY.npheav) {
882     Int_t jsec = isec - FINUC.np;
883     particleId = FHEAVY.kheavy[jsec]; // this is Fluka id !!!
884     position.SetX(fXsco);
885     position.SetY(fYsco);
886     position.SetZ(fZsco);
887     position.SetT(TRACKR.atrack);
888 //  position.SetT(TRACKR.atrack+FHEAVY.agheav[jsec]); //not yet implem.
889     momentum.SetPx(FHEAVY.pheavy[jsec]*FHEAVY.cxheav[jsec]);
890     momentum.SetPy(FHEAVY.pheavy[jsec]*FHEAVY.cyheav[jsec]);
891     momentum.SetPz(FHEAVY.pheavy[jsec]*FHEAVY.czheav[jsec]);
892     if (FHEAVY.tkheav[jsec] >= 3 && FHEAVY.tkheav[jsec] <= 6) 
893       momentum.SetE(FHEAVY.tkheav[jsec] + PAPROP.am[jsec+6]);
894     else if (FHEAVY.tkheav[jsec] > 6)
895       momentum.SetE(FHEAVY.tkheav[jsec] + FHEAVY.amnhea[jsec]); // to be checked !!!
896     }
897 }
898
899 TMCProcess TFluka::ProdProcess(Int_t isec) const
900 // Name of the process that has produced the secondary particles
901 // in the current step
902 {
903   const TMCProcess kIpNoProc = kPNoProcess;
904   const TMCProcess kIpPDecay = kPDecay;
905   const TMCProcess kIpPPair = kPPair;
906 //const TMCProcess kIpPPairFromPhoton = kPPairFromPhoton;
907 //const TMCProcess kIpPPairFromVirtualPhoton = kPPairFromVirtualPhoton;
908   const TMCProcess kIpPCompton = kPCompton;
909   const TMCProcess kIpPPhotoelectric = kPPhotoelectric;
910   const TMCProcess kIpPBrem = kPBrem;
911 //const TMCProcess kIpPBremFromHeavy = kPBremFromHeavy;
912 //const TMCProcess kIpPBremFromElectronOrPositron = kPBremFromElectronOrPositron;
913   const TMCProcess kIpPDeltaRay = kPDeltaRay;
914 //const TMCProcess kIpPMoller = kPMoller;
915 //const TMCProcess kIpPBhabha = kPBhabha;
916   const TMCProcess kIpPAnnihilation = kPAnnihilation;
917 //const TMCProcess kIpPAnnihilInFlight = kPAnnihilInFlight;
918 //const TMCProcess kIpPAnnihilAtRest = kPAnnihilAtRest;
919   const TMCProcess kIpPHadronic = kPHadronic;
920   const TMCProcess kIpPMuonNuclear = kPMuonNuclear;
921   const TMCProcess kIpPPhotoFission = kPPhotoFission;
922   const TMCProcess kIpPRayleigh = kPRayleigh;
923 //  const TMCProcess kIpPCerenkov = kPCerenkov;
924 //  const TMCProcess kIpPSynchrotron = kPSynchrotron;
925
926   Int_t mugamma = TRACKR.jtrack == 7 || TRACKR.jtrack == 10 || TRACKR.jtrack == 11;
927   if (fIcode == 102) return kIpPDecay;
928   else if (fIcode == 104 || fIcode == 217) return kIpPPair;
929 //else if (fIcode == 104) return kIpPairFromPhoton;
930 //else if (fIcode == 217) return kIpPPairFromVirtualPhoton;
931   else if (fIcode == 219) return kIpPCompton;
932   else if (fIcode == 221) return kIpPPhotoelectric;
933   else if (fIcode == 105 || fIcode == 208) return kIpPBrem;
934 //else if (fIcode == 105) return kIpPBremFromHeavy;
935 //else if (fIcode == 208) return kPBremFromElectronOrPositron;
936   else if (fIcode == 103 || fIcode == 400) return kIpPDeltaRay;
937   else if (fIcode == 210 || fIcode == 212) return kIpPDeltaRay;
938 //else if (fIcode == 210) return kIpPMoller;
939 //else if (fIcode == 212) return kIpPBhabha;
940   else if (fIcode == 214 || fIcode == 215) return kIpPAnnihilation;
941 //else if (fIcode == 214) return kIpPAnnihilInFlight;
942 //else if (fIcode == 215) return kIpPAnnihilAtRest;
943   else if (fIcode == 101) return kIpPHadronic;
944   else if (fIcode == 101) {
945     if (!mugamma) return kIpPHadronic;
946     else if (TRACKR.jtrack == 7) return kIpPPhotoFission;
947     else return kIpPMuonNuclear;
948   }
949   else if (fIcode == 225) return kIpPRayleigh;
950 // Fluka codes 100, 300 and 400 still to be investigasted
951   else return kIpNoProc;
952 }
953
954 //Int_t StepProcesses(TArrayI &proc) const
955 // Return processes active in the current step
956 //{
957 //ck = total energy of the particl ???????????????? 
958 //}
959
960
961 Int_t TFluka::VolId2Mate(Int_t id) const
962 {
963 //
964 // Returns the material number for a given volume ID
965 //
966     if (fVerbosityLevel >= 3)
967     printf("VolId2Mate %d %d\n", id, fMediaByRegion[id]); 
968     return fMediaByRegion[id-1];
969 }
970
971 const char* TFluka::VolName(Int_t id) const
972 {
973 //
974 // Returns the volume name for a given volume ID
975 //
976     FlukaVolume* vol = dynamic_cast<FlukaVolume*>((*fVolumeMediaMap)[id-1]);
977     const char* name = vol->GetName();
978     if (fVerbosityLevel >= 3)
979     printf("VolName %d %s \n", id, name);
980     return name;
981 }
982
983 Int_t TFluka::VolId(const Text_t* volName) const
984 {
985 //
986 // Converts from volume name to volume ID.
987 // Time consuming. (Only used during set-up)
988 // Could be replaced by hash-table
989 //
990     char tmp[5];
991     Int_t i =0;
992     for (i = 0; i < fNVolumes; i++)
993   {
994       FlukaVolume* vol = dynamic_cast<FlukaVolume*>((*fVolumeMediaMap)[i]);
995       TString name = vol->GetName();
996       strcpy(tmp, name.Data());
997       tmp[4] = '\0';
998       if (!strcmp(tmp, volName)) break;
999   }
1000     i++;
1001
1002     return i;
1003 }
1004
1005
1006 Int_t TFluka::CurrentVolID(Int_t& copyNo) const
1007 {
1008 //
1009 // Return the logical id and copy number corresponding to the current fluka region
1010 //
1011     int ir = fCurrentFlukaRegion;
1012     int id = (FGeometryInit::GetInstance())->CurrentVolID(ir, copyNo);
1013     if (fVerbosityLevel >= 3)
1014     printf("CurrentVolID: %d %d %d \n", ir, id, copyNo); 
1015     return id;
1016
1017
1018
1019 Int_t TFluka::CurrentVolOffID(Int_t off, Int_t& copyNo) const
1020 {
1021 //
1022 // Return the logical id and copy number of off'th mother 
1023 // corresponding to the current fluka region
1024 //
1025     if (off == 0) 
1026         return CurrentVolID(copyNo);
1027     
1028     int ir = fCurrentFlukaRegion;
1029     int id = (FGeometryInit::GetInstance())->CurrentVolOffID(ir, off, copyNo);
1030     if (fVerbosityLevel >= 3)
1031     printf("CurrentVolOffID: %d %d %d \n", ir, id, copyNo); 
1032     if (id == -1) 
1033         if (fVerbosityLevel >= 0)
1034         printf("CurrentVolOffID: Warning Mother not found !!!\n"); 
1035     return id;
1036 }
1037
1038
1039 const char* TFluka::CurrentVolName() const
1040 {
1041 //
1042 // Return the current volume name
1043 //
1044     Int_t copy;
1045     Int_t id = TFluka::CurrentVolID(copy);
1046     const char* name = TFluka::VolName(id);
1047     if (fVerbosityLevel >= 3)
1048     printf("CurrentVolumeName: %d %s \n", fCurrentFlukaRegion,  name); 
1049     return name;
1050 }
1051
1052 const char* TFluka::CurrentVolOffName(Int_t off) const
1053 {
1054 //
1055 // Return the volume name of the off'th mother of the current volume
1056 //
1057     Int_t copy;
1058     Int_t id = TFluka::CurrentVolOffID(off, copy);
1059     const char* name = TFluka::VolName(id);
1060     if (fVerbosityLevel >= 3)
1061     printf("CurrentVolumeOffName: %d %s \n", fCurrentFlukaRegion,  name); 
1062     return name;
1063 }
1064
1065 Int_t TFluka::CurrentMaterial(Float_t &a, Float_t &z, 
1066                       Float_t &dens, Float_t &radl, Float_t &absl) const
1067 {
1068 //
1069 //  Return the current medium number
1070 //
1071     Int_t copy;
1072     Int_t id  =  TFluka::CurrentVolID(copy);
1073     Int_t med =  TFluka::VolId2Mate(id);
1074     if (fVerbosityLevel >= 3)
1075     printf("CurrentMaterial: %d %d \n", fCurrentFlukaRegion,  med); 
1076     return med;
1077 }
1078
1079 void TFluka::Gmtod(Float_t* xm, Float_t* xd, Int_t iflag)
1080     {
1081 // Transforms a position from the world reference frame
1082 // to the current volume reference frame.
1083 //
1084 //  Geant3 desription:
1085 //  ==================
1086 //       Computes coordinates XD (in DRS) 
1087 //       from known coordinates XM in MRS 
1088 //       The local reference system can be initialized by
1089 //         - the tracking routines and GMTOD used in GUSTEP
1090 //         - a call to GMEDIA(XM,NUMED)
1091 //         - a call to GLVOLU(NLEVEL,NAMES,NUMBER,IER) 
1092 //             (inverse routine is GDTOM) 
1093 //
1094 //        If IFLAG=1  convert coordinates 
1095 //           IFLAG=2  convert direction cosinus
1096 //
1097 // ---
1098         Double_t xmD[3], xdD[3];        
1099         xmD[0] = xm[0]; xmD[1] = xm[1]; xmD[2] = xm[2]; 
1100         (FGeometryInit::GetInstance())->Gmtod(xmD, xdD, iflag);
1101         xd[0] = xdD[0]; xd[1] = xdD[1]; xd[2] = xdD[2]; 
1102     }
1103
1104   
1105 void TFluka::Gmtod(Double_t* xm, Double_t* xd, Int_t iflag)
1106     {
1107 // Transforms a position from the world reference frame
1108 // to the current volume reference frame.
1109 //
1110 //  Geant3 desription:
1111 //  ==================
1112 //       Computes coordinates XD (in DRS) 
1113 //       from known coordinates XM in MRS 
1114 //       The local reference system can be initialized by
1115 //         - the tracking routines and GMTOD used in GUSTEP
1116 //         - a call to GMEDIA(XM,NUMED)
1117 //         - a call to GLVOLU(NLEVEL,NAMES,NUMBER,IER) 
1118 //             (inverse routine is GDTOM) 
1119 //
1120 //        If IFLAG=1  convert coordinates 
1121 //           IFLAG=2  convert direction cosinus
1122 //
1123 // ---
1124         Double_t xmD[3], xdD[3];        
1125         xdD[0] = xd[0]; xdD[1] = xd[1]; xdD[2] = xd[2]; 
1126         (FGeometryInit::GetInstance())->Gdtom(xmD, xdD, iflag);
1127         xm[0] = xmD[0]; xm[1] = xmD[1]; xm[2] = xmD[2]; 
1128     }
1129
1130 void TFluka::Gdtom(Float_t* xd, Float_t* xm, Int_t iflag)
1131     {
1132 // Transforms a position from the current volume reference frame
1133 // to the world reference frame.
1134 //
1135 //  Geant3 desription:
1136 //  ==================
1137 //  Computes coordinates XM (Master Reference System
1138 //  knowing the coordinates XD (Detector Ref System)
1139 //  The local reference system can be initialized by
1140 //    - the tracking routines and GDTOM used in GUSTEP
1141 //    - a call to GSCMED(NLEVEL,NAMES,NUMBER)
1142 //        (inverse routine is GMTOD)
1143 // 
1144 //   If IFLAG=1  convert coordinates
1145 //      IFLAG=2  convert direction cosinus
1146 //
1147 // ---
1148
1149
1150     }
1151 void TFluka::Gdtom(Double_t* xd, Double_t* xm, Int_t iflag)
1152     {
1153 // Transforms a position from the current volume reference frame
1154 // to the world reference frame.
1155 //
1156 //  Geant3 desription:
1157 //  ==================
1158 //  Computes coordinates XM (Master Reference System
1159 //  knowing the coordinates XD (Detector Ref System)
1160 //  The local reference system can be initialized by
1161 //    - the tracking routines and GDTOM used in GUSTEP
1162 //    - a call to GSCMED(NLEVEL,NAMES,NUMBER)
1163 //        (inverse routine is GMTOD)
1164 // 
1165 //   If IFLAG=1  convert coordinates
1166 //      IFLAG=2  convert direction cosinus
1167 //
1168 // ---
1169
1170         (FGeometryInit::GetInstance())->Gdtom(xm, xd, iflag);
1171     }
1172
1173 // ===============================================================
1174 void TFluka::FutoTest() 
1175 {
1176     Int_t icode, mreg, newreg, particleId;
1177     Double_t rull, xsco, ysco, zsco;
1178     TLorentzVector position, momentum;
1179     icode = GetIcode();
1180     if (icode == 0) {
1181         if (fVerbosityLevel >=3)
1182             cout << " icode=" << icode << endl;
1183     } else if (icode > 0 && icode <= 5) {
1184 // mgdraw
1185         mreg = GetMreg();
1186         if (fVerbosityLevel >=3)
1187             cout << " icode=" << icode
1188                  << " mreg=" << mreg
1189                  << endl;
1190         TrackPosition(position);
1191         TrackMomentum(momentum);
1192         if (fVerbosityLevel >=3) {
1193             cout << "TLorentzVector positionX=" << position.X()
1194                  << "positionY=" << position.Y()
1195                  << "positionZ=" << position.Z()
1196                  << "timeT=" << position.T() << endl;
1197             cout << "TLorentzVector momentumX=" << momentum.X()
1198                  << "momentumY=" << momentum.Y()
1199                  << "momentumZ=" << momentum.Z()
1200                  << "energyE=" << momentum.E() << endl;
1201             cout << "TrackStep=" << TrackStep() << endl;
1202             cout << "TrackLength=" << TrackLength() << endl;
1203             cout << "TrackTime=" << TrackTime() << endl;
1204             cout << "Edep=" << Edep() << endl;
1205             cout << "TrackPid=" << TrackPid() << endl;
1206             cout << "TrackCharge=" << TrackCharge() << endl;
1207             cout << "TrackMass=" << TrackMass() << endl;
1208             cout << "Etot=" << Etot() << endl;
1209             cout << "IsNewTrack=" << IsNewTrack() << endl;
1210             cout << "IsTrackInside=" << IsTrackInside() << endl;
1211             cout << "IsTrackEntering=" << IsTrackEntering() << endl;
1212             cout << "IsTrackExiting=" << IsTrackExiting() << endl;
1213             cout << "IsTrackOut=" << IsTrackOut() << endl;
1214             cout << "IsTrackDisappeared=" << IsTrackDisappeared() << endl;
1215             cout << "IsTrackAlive=" << IsTrackAlive() << endl;
1216         }
1217         
1218         Float_t x = position.X();
1219         Float_t y = position.Y();
1220         Float_t z = position.Z();
1221         Float_t xm[3];
1222         Float_t xd[3];
1223         xm[0] = x; xm[1] = y; xm[2] = z;
1224         if (fVerbosityLevel >= 3)
1225             printf("Global trackPosition: %f %f %f \n", x, y, z);
1226         Gmtod(xm, xd, 1);
1227         if (fVerbosityLevel >= 3)
1228             printf("Local trackPosition: %f %f %f \n", xd[0], xd[1], xd[2]);
1229         Gdtom(xd, xm, 1);
1230         if (fVerbosityLevel >= 3)
1231             printf("New trackPosition: %f %f %f \n", xm[0], xm[1], xm[2]);
1232     } else if((icode >= 10 && icode <= 15) ||
1233               (icode >= 20 && icode <= 24) ||
1234               (icode >= 30 && icode <= 33) ||
1235               (icode >= 40 && icode <= 41) ||
1236               (icode >= 50 && icode <= 52)) {
1237 // endraw
1238         mreg = GetMreg();
1239         rull = GetRull();
1240         xsco = GetXsco();
1241         ysco = GetYsco();
1242         zsco = GetZsco();
1243         
1244         if (fVerbosityLevel >=3) {     
1245             cout << " icode=" << icode
1246                  << " mreg=" << mreg
1247                  << " rull=" << rull
1248                  << " xsco=" << xsco
1249                  << " ysco=" << ysco
1250                  << " zsco=" << zsco << endl;
1251         }
1252         TrackPosition(position);
1253         TrackMomentum(momentum);
1254         if (fVerbosityLevel >=3) {
1255             cout << "Edep=" << Edep() << endl;
1256             cout << "Etot=" << Etot() << endl;
1257             cout << "TrackPid=" << TrackPid() << endl;
1258             cout << "TrackCharge=" << TrackCharge() << endl;
1259             cout << "TrackMass=" << TrackMass() << endl;
1260             cout << "IsTrackOut=" << IsTrackOut() << endl;
1261             cout << "IsTrackDisappeared=" << IsTrackDisappeared() << endl;
1262             cout << "IsTrackStop=" << IsTrackStop() << endl;
1263             cout << "IsTrackAlive=" << IsTrackAlive() << endl;
1264         }
1265     } else if((icode >= 100 && icode <= 105) ||
1266               (icode == 208) ||
1267               (icode == 210) ||
1268               (icode == 212) ||
1269               (icode >= 214 && icode <= 215) ||
1270               (icode == 217) ||
1271               (icode == 219) ||
1272               (icode == 221) ||
1273               (icode == 225) ||
1274               (icode == 300) ||
1275               (icode == 400)) {
1276 // usdraw
1277           mreg = GetMreg();
1278           xsco = GetXsco();
1279           ysco = GetYsco();
1280           zsco = GetZsco();
1281           
1282           if (fVerbosityLevel >=3) {
1283               cout << " icode=" << icode
1284                    << " mreg=" << mreg
1285                    << " xsco=" << xsco
1286                    << " ysco=" << ysco
1287                    << " zsco=" << zsco << endl;
1288               cout << "TrackPid=" << TrackPid() << endl;
1289               cout << "NSecondaries=" << NSecondaries() << endl;
1290           }
1291           
1292           for (Int_t isec=0; isec< NSecondaries(); isec++) {
1293               TFluka::GetSecondary(isec, particleId, position, momentum);
1294               if (fVerbosityLevel >=3) {
1295                   cout << "TLorentzVector positionX=" << position.X()
1296                        << "positionY=" << position.Y()
1297                        << "positionZ=" << position.Z()
1298                        << "timeT=" << position.T() << endl;
1299                   cout << "TLorentzVector momentumX=" << momentum.X()
1300                        << "momentumY=" << momentum.Y()
1301                        << "momentumZ=" << momentum.Z()
1302                        << "energyE=" << momentum.E() << endl;
1303                   cout << "TrackPid=" << particleId << endl;
1304               }
1305           }
1306     } else if((icode == 19) ||
1307               (icode == 29) ||
1308               (icode == 39) ||
1309               (icode == 49) ||
1310               (icode == 59)) {
1311         mreg = GetMreg();
1312         newreg = GetNewreg();
1313         xsco = GetXsco();
1314         ysco = GetYsco();
1315         zsco = GetZsco();
1316         if (fVerbosityLevel >=3) {
1317             cout << " icode=" << icode
1318                  << " mreg=" << mreg
1319                  << " newreg=" << newreg
1320                  << " xsco=" << xsco
1321                  << " ysco=" << ysco
1322                  << " zsco=" << zsco << endl;
1323         }
1324     }
1325 } // end of FutoTest
1326