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