Removal of useless dependecies via forward declarations
[u/mrichter/AliRoot.git] / TGeant3 / AliGeant3.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.9  2000/09/12 14:36:17  morsch
19 In gudcay(): call ForceDecay() before Decay()
20
21 Revision 1.8  2000/09/06 14:56:34  morsch
22 gudcay() method implemented.
23 Decays are performed using  the AliDecayer interface. The pointer to the instance of AliDecayer
24 is obtained from geant3 (will be gMC once it has been implemented for Geant4).
25
26 Revision 1.7  2000/07/13 16:19:10  fca
27 Mainly coding conventions + some small bug fixes
28
29 Revision 1.6  2000/07/11 18:24:59  fca
30 Coding convention corrections + few minor bug fixes
31
32 Revision 1.5  2000/05/20 14:49:48  fca
33 Call gdebug at the end of gustep
34
35 Revision 1.4  2000/04/26 10:17:32  fca
36 Changes in Lego for G4 compatibility
37
38 Revision 1.3  2000/04/07 11:12:35  fca
39 G4 compatibility changes
40
41 Revision 1.2  2000/02/29 19:11:17  fca
42 Move gucode into AliGeant3.cxx
43
44 Revision 1.1  2000/02/23 16:25:25  fca
45 AliVMC and AliGeant3 classes introduced
46 ReadEuclid moved from AliRun to AliModule
47
48 */
49
50 #include <TParticle.h>
51
52 #include "AliDecayer.h"
53 #include "AliGeant3.h"
54 #include "AliRun.h"
55 #include "TGeant3.h"
56 #include "AliCallf77.h" 
57 #include "AliModule.h"
58 #include "AliMagF.h"
59
60 #ifndef WIN32
61
62 # define rxgtrak rxgtrak_
63 # define rxstrak rxstrak_
64 # define rxkeep  rxkeep_ 
65 # define rxouth  rxouth_
66 #else
67
68 # define rxgtrak RXGTRAK 
69 # define rxstrak RXSTRAK 
70 # define rxkeep  RXKEEP  
71 # define rxouth  RXOUTH
72 #endif
73
74 ClassImp(AliGeant3)
75
76 AliGeant3::AliGeant3(const char *title) : 
77   TGeant3(title) {}
78
79 //____________________________________________________________________________
80 void AliGeant3::FinishGeometry()
81 {
82   //
83   // Finalise geometry construction
84   //
85   TGeant3::FinishGeometry();
86   //Create the color table
87   SetColors();
88 }
89
90 //____________________________________________________________________________
91 void AliGeant3::Init()
92 {
93   //
94   //=================Create Materials and geometry
95   //
96   TObjArray *modules = gAlice->Modules();
97   TIter next(modules);
98   AliModule *detector;
99   while((detector = (AliModule*)next())) {
100     // Initialise detector materials and geometry
101     detector->CreateMaterials();
102     detector->CreateGeometry();
103     detector->BuildGeometry();
104     detector->Init();
105   }
106
107   //Terminate building of geometry
108   FinishGeometry();
109 }
110
111 //____________________________________________________________________________
112 void AliGeant3::ProcessRun(Int_t nevent)
113 {
114   //
115   // Process the run
116   //
117   Int_t todo = TMath::Abs(nevent);
118   for (Int_t i=0; i<todo; i++) {
119   // Process one run (one run = one event)
120      gAlice->BeginEvent();
121      ProcessEvent();
122      gAlice->FinishEvent();
123   }
124 }
125
126 //_____________________________________________________________________________
127 void AliGeant3::ProcessEvent()
128 {
129   //
130   // Process one event
131   //
132   Gtrigi();
133   Gtrigc();
134   Gtrig();
135 }
136
137 //_____________________________________________________________________________
138 void AliGeant3::SetColors()
139 {
140   //
141   // Set the colors for all the volumes
142   // this is done sequentially for all volumes
143   // based on the number of their medium
144   //
145   Int_t kv, icol;
146   Int_t jvolum=fGclink->jvolum;
147   //Int_t jtmed=fGclink->jtmed;
148   //Int_t jmate=fGclink->jmate;
149   Int_t nvolum=fGcnum->nvolum;
150   char name[5];
151   //
152   //    Now for all the volumes
153   for(kv=1;kv<=nvolum;kv++) {
154     //     Get the tracking medium
155     Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
156     //     Get the material
157     //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
158     //     Get z
159     //Float_t z=fZq[fZlq[jmate-ima]+7];
160     //     Find color number
161     //icol = Int_t(z)%6+2;
162     //icol = 17+Int_t(z*150./92.);
163     //icol = kv%6+2;
164     icol = itm%6+2;
165     strncpy(name,(char*)&fZiq[jvolum+kv],4);
166     name[4]='\0';
167     Gsatt(name,"COLO",icol);
168   }
169 }
170
171 //_____________________________________________________________________________
172 //
173 //                 Interfaces to Fortran
174 //
175 //_____________________________________________________________________________
176
177 extern "C" void type_of_call  rxgtrak (Int_t &mtrack, Int_t &ipart, Float_t *pmom, 
178                                        Float_t &e, Float_t *vpos, Float_t *polar,
179                                        Float_t &tof)
180 {
181   //
182   //     Fetches next track from the ROOT stack for transport. Called by the
183   //     modified version of GTREVE.
184   //
185   //              Track number in the ROOT stack. If MTRACK=0 no
186   //      mtrack  more tracks are left in the stack to be
187   //              transported.
188   //      ipart   Particle code in the GEANT conventions.
189   //      pmom[3] Particle momentum in GeV/c
190   //      e       Particle energy in GeV
191   //      vpos[3] Particle position
192   //      tof     Particle time of flight in seconds
193   //
194   Int_t pdg;
195   gAlice->GetNextTrack(mtrack, pdg, pmom, e, vpos, polar, tof);
196   ipart = gMC->IdFromPDG(pdg);
197   mtrack++;
198 }
199
200 //_____________________________________________________________________________
201 extern "C" void type_of_call 
202 #ifndef WIN32
203 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom, 
204                Float_t *vpos, Float_t &tof, const char* cmech, Int_t &ntr, const int cmlen)
205 #else
206 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom,
207          Float_t *vpos, Float_t &tof, const char* cmech, const int cmlen,
208          Int_t &ntr)
209 #endif
210 {
211   //
212   //     Fetches next track from the ROOT stack for transport. Called by GUKINE
213   //     and GUSTEP.
214   //
215   //              Status of the track. If keep=0 the track is put
216   //      keep    on the ROOT stack but it is not fetched for
217   //              transport.
218   //      parent  Parent track. If parent=0 the track is a primary.
219   //              In GUSTEP the routine is normally called to store
220   //              secondaries generated by the current track whose
221   //              ROOT stack number is MTRACK (common SCKINE.
222   //      ipart   Particle code in the GEANT conventions.
223   //      pmom[3] Particle momentum in GeV/c
224   //      vpos[3] Particle position
225   //      tof     Particle time of flight in seconds
226   //
227   //      cmech   (CHARACTER*10) Particle origin. This field is user
228   //              defined and it is not used inside the GALICE code.
229   //      ntr     Number assigned to the particle in the ROOT stack.
230   //
231   char mecha[11];
232   Float_t polar[3]={0.,0.,0.};
233   for(int i=0; i<10 && i<cmlen; i++) mecha[i]=cmech[i];
234   mecha[10]=0;
235   Int_t pdg=gMC->PDGFromId(ipart);
236   gAlice->SetTrack(keep, parent-1, pdg, pmom, vpos, polar, tof, mecha, ntr);
237   ntr++;
238 }
239
240 //_____________________________________________________________________________
241 extern "C" void type_of_call  rxkeep(const Int_t &n)
242 {
243   if( NULL==gAlice ) exit(1);
244   
245   if( n<=0 || n>gAlice->Particles()->GetEntries() )
246     {
247       printf("  Bad index n=%d must be 0<n<=%d\n",
248              n,gAlice->Particles()->GetEntries());
249       exit(1);
250     }
251   
252   ((TParticle*)(gAlice->Particles()->UncheckedAt(n-1)))->SetBit(kKeepBit);
253 }
254
255 //_____________________________________________________________________________
256 extern "C" void type_of_call  rxouth ()
257 {
258   //
259   // Called by Gtreve at the end of each primary track
260   //
261   gAlice->FinishPrimary();
262 }
263
264
265 #ifndef WIN32
266 #  define gudigi gudigi_
267 #  define guhadr guhadr_
268 #  define guout  guout_
269 #  define guphad guphad_
270 #  define gudcay gudcay_
271 #  define guiget guiget_
272 #  define guinme guinme_
273 #  define guinti guinti_
274 #  define gunear gunear_
275 #  define guskip guskip_
276 #  define guview guview_
277 #  define gupara gupara_
278 #  define gudtim gudtim_
279 #  define guplsh guplsh_
280 #  define gutrev gutrev_
281 #  define gutrak gutrak_
282 #  define guswim guswim_
283 #  define gufld  gufld_
284 #  define gustep gustep_
285 #  define gukine gukine_
286 #  define uglast uglast_
287
288 #  define gheish gheish_
289 #  define flufin flufin_
290 #  define gfmfin gfmfin_
291 #  define gpghei gpghei_
292 #  define fldist fldist_
293 #  define gfmdis gfmdis_
294 #  define ghelx3 ghelx3_
295 #  define ghelix ghelix_
296 #  define grkuta grkuta_
297 #  define gtrack gtrack_
298 #  define gtreveroot gtreveroot_
299 #  define glast  glast_
300
301 #else
302 #  define gudigi GUDIGI
303 #  define guhadr GUHADR
304 #  define guout  GUOUT
305 #  define guphad GUPHAD
306 #  define gudcay GUDCAY
307 #  define guiget GUIGET
308 #  define guinme GUINME
309 #  define guinti GUINTI
310 #  define gunear GUNEAR
311 #  define guskip GUSKIP
312 #  define guview GUVIEW
313 #  define gupara GUPARA
314 #  define gudtim GUDTIM
315 #  define guplsh GUPLSH
316 #  define gutrev GUTREV
317 #  define gutrak GUTRAK
318 #  define guswim GUSWIM
319 #  define gufld  GUFLD
320 #  define gustep GUSTEP
321 #  define gukine GUKINE
322 #  define uglast UGLAST
323
324 #  define gheish GHEISH
325 #  define flufin FLUFIN
326 #  define gfmfin GFMFIN
327 #  define gpghei GPGHEI
328 #  define fldist FLDIST
329 #  define gfmdis GFMDIS
330 #  define ghelx3 GHELX3
331 #  define ghelix GHELIX
332 #  define grkuta GRKUTA
333 #  define gtrack GTRACK
334 #  define gtreveroot GTREVEROOT
335 #  define glast  GLAST
336
337 #endif
338
339 extern "C" type_of_call void gheish();
340 extern "C" type_of_call void flufin();
341 extern "C" type_of_call void gfmfin();
342 extern "C" type_of_call void gpghei();
343 extern "C" type_of_call void fldist();
344 extern "C" type_of_call void gfmdis();
345 extern "C" type_of_call void ghelx3(Float_t&, Float_t&, Float_t*, Float_t*);
346 extern "C" type_of_call void ghelix(Float_t&, Float_t&, Float_t*, Float_t*);
347 extern "C" type_of_call void grkuta(Float_t&, Float_t&, Float_t*, Float_t*);
348 extern "C" type_of_call void gtrack();
349 extern "C" type_of_call void gtreveroot();
350 extern "C" type_of_call void glast();
351
352 extern "C" type_of_call {
353
354 //______________________________________________________________________
355 void gudigi() 
356 {
357 //
358 //    ******************************************************************
359 //    *                                                                *
360 //    *       User routine to digitize one event                       *
361 //    *                                                                *
362 //    *    ==>Called by : GTRIG                                        *
363 //    *                                                                *
364 //    ******************************************************************
365
366 }
367
368
369 //______________________________________________________________________
370 void guhadr()
371 {
372 //
373 //    ******************************************************************
374 //    *                                                                *
375 //    *       User routine to generate one hadronic interaction        *
376 //    *                                                                *
377 //    *    ==>Called by : GTHADR,GTNEUT                                *
378 //    *                                                                *
379 //    ******************************************************************
380 //
381 //
382 //    ------------------------------------------------------------------
383 //
384       TGeant3* geant3 = (TGeant3*) gMC;
385       Int_t ihadr=geant3->Gcphys()->ihadr;
386       if (ihadr<4)       gheish();
387       else if (ihadr==4) flufin();
388       else               gfmfin();
389 }
390
391 //______________________________________________________________________
392 void guout()
393 {
394 //
395 //    ******************************************************************
396 //    *                                                                *
397 //    *       User routine called at the end of each event             *
398 //    *                                                                *
399 //    *    ==>Called by : GTRIG                                        *
400 //    *                                                                *
401 //    ******************************************************************
402 //
403 //
404 //    ------------------------------------------------------------------
405 //
406 }
407
408 //______________________________________________________________________
409 void guphad()
410 {
411 //
412 //    ******************************************************************
413 //    *                                                                *
414 //    *       User routine to compute Hadron. inter. probabilities     *
415 //    *                                                                *
416 //    *    ==>Called by : GTHADR,GTNEUT                                *
417 //    *                                                                *
418 //    ******************************************************************
419 //
420 //
421 //    ------------------------------------------------------------------
422 //
423       TGeant3* geant3 = (TGeant3*) gMC;
424       Int_t ihadr=geant3->Gcphys()->ihadr;
425       if (ihadr<4)       gpghei();
426       else if (ihadr==4) fldist();
427       else               gfmdis();
428 }
429
430 //______________________________________________________________________
431 void gudcay()
432 {
433 //
434 //    ******************************************************************
435 //    *                                                                *
436 //    *       User routine to decay particles                          *
437 //    *                                                                *
438 //    *    ==>Called by : GDECAY                                       *
439 //    *                                                                *
440 //    ******************************************************************
441 //
442 //
443 //    ------------------------------------------------------------------
444 //
445     
446     TGeant3* geant3=(TGeant3*) gMC;
447   // set decay table
448   gMC->Decayer()->ForceDecay();
449
450 // Initialize 4-momentum vector    
451     Int_t ipart = geant3->Gckine()->ipart;
452     TLorentzVector p;
453     
454     p[0]=geant3->Gctrak()->vect[3];
455     p[1]=geant3->Gctrak()->vect[4];
456     p[2]=geant3->Gctrak()->vect[5];
457     p[3]=geant3->Gctrak()->vect[6];    
458     
459 // Convert from geant to lund particle code
460     Int_t iplund=gMC->PDGFromId(ipart);
461 // Particle list
462     static TClonesArray *particles;
463     if(!particles) particles=new TClonesArray("TParticle",1000);
464 // Decay
465     gMC->Decayer()->Decay(iplund, &p);
466     
467 // Fetch Particles
468     Int_t np = geant3->Decayer()->ImportParticles(particles);
469     if (np <=1) return;
470     
471     for (Int_t i=0; i< np; i++) 
472     {
473         TParticle *  iparticle = (TParticle *) particles->At(i);
474         Int_t ks = iparticle->GetStatusCode();
475 // Final state particles only
476         if (ks < 1 || ks >  10) continue;
477 // Skip neutrinos
478         Int_t  kf=iparticle->GetPdgCode();
479         if (kf==12 || kf ==-12) continue;
480         if (kf==14 || kf ==-14) continue;
481         if (kf==16 || kf ==-16) continue;
482         
483         Int_t index=geant3->Gcking()->ngkine;
484 // Put particle on geant stack
485 // momentum vector
486
487         (geant3->Gcking()->gkin[index][0]) = iparticle->Px();
488         (geant3->Gcking()->gkin[index][1]) = iparticle->Py();
489         (geant3->Gcking()->gkin[index][2]) = iparticle->Pz();
490         (geant3->Gcking()->gkin[index][3]) = iparticle->Energy();
491         Int_t ilu = gMC->IdFromPDG(kf);
492
493 // particle type        
494         (geant3->Gcking()->gkin[index][4]) = Float_t(ilu);
495 // position
496         (geant3->Gckin3()->gpos[index][0]) = geant3->Gctrak()->vect[0];
497         (geant3->Gckin3()->gpos[index][1]) = geant3->Gctrak()->vect[1];
498         (geant3->Gckin3()->gpos[index][2]) = geant3->Gctrak()->vect[2];
499 // time of flight offset (mm)
500         (geant3->Gcking()->tofd[index])    = 0.;
501 //      (geant3->Gcking()->tofd[index])    = iparticle->T()/(10*kSpeedOfLight);
502 // increase stack counter
503         (geant3->Gcking()->ngkine)=index+1;
504     }
505 }
506
507 //______________________________________________________________________
508 void guiget(Int_t&, Int_t&, Int_t&)
509 {
510 //
511 //    ******************************************************************
512 //    *                                                                *
513 //    *       User routine for interactive control of GEANT            *
514 //    *                                                                *
515 //    *    ==>Called by : <GXINT>, GINCOM                              *
516 //    *                                                                *
517 //    ******************************************************************
518 //
519 //
520 //    ------------------------------------------------------------------
521 //
522 }
523
524 //______________________________________________________________________
525 void guinme(Float_t*, Int_t&, Float_t*, Int_t& IYES)
526 {
527 //
528 //    **********************************************
529 //    *                                            *
530 //    *    USER ROUTINE TO PROVIDE GINME FUNCTION  *
531 //    *    FOR ALL USER SHAPES IDENTIFIED BY THE   *
532 //    *    SHAPE NUMBER SH. POINT IS GIVEN IN X    *
533 //    *    THE PARAMETERS ARE GIVEN IN P. IYES IS  *
534 //    *    RETURNED 1 IF POINT IS IN, 0 IF POINT   *
535 //    *    IS OUT AND LESS THAN ZERO IF SHAPE      *
536 //    *    NUMBER IS NOT SUPPORTED.                *
537 //    *                                            *
538 //    *    ==>Called by : GINME                    *
539 //    *                                            *
540 //    **********************************************
541 //
542       IYES=-1;
543 }
544
545 //______________________________________________________________________
546 void guinti()
547 {
548 //
549 //    ******************************************************************
550 //    *                                                                *
551 //    *       User routine for interactive version                     *
552 //    *                                                                *
553 //    *    ==>Called by : <GXINT>,  GINTRI                             *
554 //    *                                                                *
555 //    ******************************************************************
556 //
557 //
558 //    ------------------------------------------------------------------
559 //
560 }
561
562 //______________________________________________________________________
563 void gunear(Int_t&, Int_t&, Float_t*, Int_t&)
564 {
565 //
566 //    ******************************************************************
567 //    *                                                                *
568 //    *    User search                                                 *
569 //    *       ISEARC to identify the given volume                      *
570 //    *       ICALL  to identify the calling routine                   *
571 //    *              1 GMEDIA like                                     *
572 //    *              2 GNEXT like                                      *
573 //    *       X      coordinates (+direction for ICALL=2)              *
574 //    *       JNEAR  address of default list of neighbours             *
575 //    *              (list to be overwriten by user)                   *
576 //    *                                                                *
577 //    *    Called by : GFTRAC, GINVOL, GTMEDI, GTNEXT, GNEXT, GMEDIA   *
578 //    *                                                                *
579 //    ******************************************************************
580 //
581 //
582 //    ------------------------------------------------------------------
583 //
584 }
585
586 //______________________________________________________________________
587 void guskip(Int_t& ISKIP)
588 {
589 //
590 //    ******************************************************************
591 //    *                                                                *
592 //    *   User routine to skip unwanted tracks                         *
593 //    *                                                                *
594 //    *   Called by : GSSTAK                                           *
595 //    *   Author    : F.Bruyant                                        *
596 //    *                                                                *
597 //    ******************************************************************
598 //
599 //
600 //    ------------------------------------------------------------------
601 //
602       ISKIP = 0;
603 }
604
605 //______________________________________________________________________
606 void guswim(Float_t& CHARGE, Float_t& STEP, Float_t* VECT, Float_t* VOUT)
607 {
608 //
609 //    ******************************************************************
610 //    *                                                                *
611 //    *       User routine to control tracking of one track            *
612 //    *       in a magnetic field                                      *
613 //    *                                                                *
614 //    *    ==>Called by : GTELEC,GTHADR,GTMUON                         *
615 //    *                                                                *
616 //    ******************************************************************
617 //
618 //
619 //    ------------------------------------------------------------------
620 //
621   TGeant3* geant3 = (TGeant3*) gMC;
622   Int_t ifield=geant3->Gctmed()->ifield;
623   Float_t fieldm=geant3->Gctmed()->fieldm;
624
625   if (ifield==3) {
626     Float_t fldcharge = fieldm*CHARGE;
627     ghelx3(fldcharge,STEP,VECT,VOUT);
628   }
629   else if (ifield==2) ghelix(CHARGE,STEP,VECT,VOUT);
630   else                grkuta(CHARGE,STEP,VECT,VOUT);
631 }
632
633 //______________________________________________________________________
634 void guview(Int_t&, Int_t&, DEFCHARD, Int_t& DEFCHARL)
635 {
636 //
637 //    ******************************************************************
638 //    *                                                                *
639 //    *       User routine for interactive version                     *
640 //    *                                                                *
641 //    *    ==>Called by : <GXINT>, GINC1                               *
642 //    *                                                                *
643 //    ******************************************************************
644 //
645 //
646 //    ------------------------------------------------------------------
647 //
648 }
649
650 //______________________________________________________________________
651 void gupara()
652 {
653 //
654 //    ******************************************************************
655 //    *                                                                *
656 //    *       User routine called every time a particle falls below    *
657 //    *       parametrization threshold. This routine should create    *
658 //    *       the parametrization stack, and, when this is full,       *
659 //    *       parametrize the shower and track the geantinos.          *
660 //    *                                                                *
661 //    *    ==>Called by : GTRACK                                       *
662 //    *                                                                *
663 //    ******************************************************************
664 //
665 //
666 //    ------------------------------------------------------------------
667 //
668 }
669
670 //______________________________________________________________________
671 Float_t gudtim(Float_t&, Float_t&, Int_t&, Int_t&)
672 {
673 //
674 //    ******************************************************************
675 //    *                                                                *
676 //    *       User function called by GCDRIF to return drift time      *
677 //    *                                                                *
678 //    *    ==>Called by : GCDRIF                                       *
679 //    *                                                                *
680 //    ******************************************************************
681 //
682 //
683 //    ------------------------------------------------------------------
684 //
685       return 0;
686 }
687
688
689 //______________________________________________________________________
690 Float_t guplsh(Int_t&, Int_t&)
691 {
692 //
693 //    ******************************************************************
694 //    *                                                                *
695 //    *                                                                *
696 //    *    ==>Called by : GLISUR                                       *
697 //    *                                                                *
698 //    ******************************************************************
699 //
700 //
701 //    ------------------------------------------------------------------
702 //
703 //
704 //*** By default this defines perfect smoothness
705       return 1;
706 }
707
708 //______________________________________________________________________
709 void gutrak()
710 {
711 //
712 //    ******************************************************************
713 //    *                                                                *
714 //    *       User routine to control tracking of one track            *
715 //    *                                                                *
716 //    *    ==>Called by : GTREVE                                       *
717 //    *                                                                *
718 //    ******************************************************************
719 //
720 //
721 //    ------------------------------------------------------------------
722 //
723      Int_t ndet = gAlice->Modules()->GetLast();
724      TObjArray &dets = *gAlice->Modules();
725      AliModule *module;
726      Int_t i;
727
728      for(i=0; i<=ndet; i++)
729        if((module = (AliModule*)dets[i]))
730          module->PreTrack();
731
732      gtrack();
733
734      for(i=0; i<=ndet; i++)
735        if((module = (AliModule*)dets[i]))
736          module->PostTrack();
737 }
738
739 //______________________________________________________________________
740 void gutrev()
741 {
742 //
743 //    ******************************************************************
744 //    *                                                                *
745 //    *       User routine to control tracking of one event            *
746 //    *                                                                *
747 //    *    ==>Called by : GTRIG                                        *
748 //    *                                                                *
749 //    ******************************************************************
750 //
751 //
752 //    ------------------------------------------------------------------
753 //
754   gtreveroot();
755 }
756
757
758 //______________________________________________________________________
759 void gufld(Float_t *x, Float_t *b)
760 {
761       if(gAlice->Field()) {
762          gAlice->Field()->Field(x,b);
763       } else {
764          printf("No mag field defined!\n");
765          b[0]=b[1]=b[2]=0;
766       }
767 }
768
769 //______________________________________________________________________
770 void gustep()
771 {
772 //
773 //    ******************************************************************
774 //    *                                                                *
775 //    *       User routine called at the end of each tracking step     *
776 //    *       INWVOL is different from 0 when the track has reached    *
777 //    *              a volume boundary                                 *
778 //    *       ISTOP is different from 0 if the track has stopped       *
779 //    *                                                                *
780 //    *    ==>Called by : GTRACK                                       *
781 //    *                                                                *
782 //    ******************************************************************
783 //
784
785
786   TLorentzVector x;
787   Float_t r;
788   Int_t ipp, jk, id, nt;
789   Float_t polar[3]={0,0,0};
790   Float_t mom[3];
791   const char *kChproc;
792
793   
794   TGeant3* geant3 = (TGeant3*) gMC;
795   //     Stop particle if outside user defined tracking region 
796   gMC->TrackPosition(x);
797   r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
798   if (r > gAlice->TrackingRmax() || TMath::Abs(x[2]) > gAlice->TrackingZmax()) {
799         gMC->StopTrack();
800   }
801
802   // --- Add new created particles 
803   if (gMC->NSecondaries() > 0) {
804     kChproc=gMC->ProdProcess();
805     for (jk = 0; jk < geant3->Gcking()->ngkine; ++jk) {
806       ipp = Int_t (geant3->Gcking()->gkin[jk][4]+0.5);
807       // --- Skip neutrinos! 
808       if (ipp != 4) {
809         gAlice->SetTrack(1,gAlice->CurrentTrack(),gMC->PDGFromId(ipp), geant3->Gcking()->gkin[jk], 
810                          geant3->Gckin3()->gpos[jk], polar,geant3->Gctrak()->tofg, kChproc, nt);
811       }
812     }
813   }
814   // Cherenkov photons here
815   if ( geant3->Gckin2()->ngphot ) {
816     for (jk = 0; jk < geant3->Gckin2()->ngphot; ++jk) {
817       mom[0]=geant3->Gckin2()->xphot[jk][3]*geant3->Gckin2()->xphot[jk][6];
818       mom[1]=geant3->Gckin2()->xphot[jk][4]*geant3->Gckin2()->xphot[jk][6];
819       mom[2]=geant3->Gckin2()->xphot[jk][5]*geant3->Gckin2()->xphot[jk][6];
820       gAlice->SetTrack(1, gAlice->CurrentTrack(), gMC->PDGFromId(50),
821                        mom,                             //momentum
822                        geant3->Gckin2()->xphot[jk],     //position
823                        &geant3->Gckin2()->xphot[jk][7], //polarisation
824                        geant3->Gckin2()->xphot[jk][10], //time of flight
825                        "Cherenkov", nt);
826       }
827   }
828   // --- Particle leaving the setup ?
829   if (!gMC->IsTrackOut()) 
830     if ((id=gAlice->DetFromMate(geant3->Gctmed()->numed)) >= 0) gAlice->StepManager(id);
831
832   // --- Standard GEANT debug routine 
833   if(geant3->Gcflag()->idebug) geant3->Gdebug();
834 }
835
836 //______________________________________________________________________
837 void gukine ()
838 {
839 //
840 //    ******************************************************************
841 //    *                                                                *
842 //    *       Read or Generates Kinematics for primary tracks          *
843 //    *                                                                *
844 //    *    ==>Called by : GTRIG                                        *
845 //    *                                                                *
846 //    ******************************************************************
847 //
848 //
849 //    ------------------------------------------------------------------
850 //
851   gAlice->Generator()->Generate();
852 }
853
854
855 //______________________________________________________________________
856 void uglast()
857 {
858 //
859 //    ******************************************************************
860 //    *                                                                *
861 //    *       User routine called at the end of the run                *
862 //    *                                                                *
863 //    *    ==>Called by : GRUN                                         *
864 //    *                                                                *
865 //    ******************************************************************
866 //
867 //
868 }
869 }
870