1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.19 2001/10/03 08:39:03 morsch
19 Bug in user decay routine leading to segmentation violation corrected.
21 Revision 1.18 2001/07/19 09:10:23 morsch
22 In decays with AliDecayer put long-lived particles undecayed on the stack.
24 Revision 1.17 2001/06/15 09:31:23 morsch
25 In gudcay: write only first generation decay products to stack to respect the possibility of secondary, tertiary, ... vertices during tracking.
27 Revision 1.16 2001/05/16 14:57:23 alibrary
28 New files for folders and Stack
30 Revision 1.15 2001/03/20 06:28:49 alibrary
31 New detector loop split in 2
33 Revision 1.14 2000/12/20 08:39:39 fca
34 Support for Cerenkov and process list in Virtual MC
36 Revision 1.13 2000/11/30 07:12:54 alibrary
37 Introducing new Rndm and QA classes
39 Revision 1.12 2000/11/06 11:35:46 morsch
40 Call BuildGeometry() after Init() to be able to share common detector parameters.
42 Revision 1.11 2000/10/04 16:30:22 fca
43 Add include for exit()
45 Revision 1.10 2000/10/02 21:28:16 fca
46 Removal of useless dependecies via forward declarations
48 Revision 1.9 2000/09/12 14:36:17 morsch
49 In gudcay(): call ForceDecay() before Decay()
51 Revision 1.8 2000/09/06 14:56:34 morsch
52 gudcay() method implemented.
53 Decays are performed using the AliDecayer interface. The pointer to the instance of AliDecayer
54 is obtained from geant3 (will be gMC once it has been implemented for Geant4).
56 Revision 1.7 2000/07/13 16:19:10 fca
57 Mainly coding conventions + some small bug fixes
59 Revision 1.6 2000/07/11 18:24:59 fca
60 Coding convention corrections + few minor bug fixes
62 Revision 1.5 2000/05/20 14:49:48 fca
63 Call gdebug at the end of gustep
65 Revision 1.4 2000/04/26 10:17:32 fca
66 Changes in Lego for G4 compatibility
68 Revision 1.3 2000/04/07 11:12:35 fca
69 G4 compatibility changes
71 Revision 1.2 2000/02/29 19:11:17 fca
72 Move gucode into AliGeant3.cxx
74 Revision 1.1 2000/02/23 16:25:25 fca
75 AliVMC and AliGeant3 classes introduced
76 ReadEuclid moved from AliRun to AliModule
82 #include <TParticle.h>
83 #include <TStopwatch.h>
85 #include "AliDecayer.h"
86 #include "AliGeant3.h"
89 #include "AliCallf77.h"
90 #include "AliModule.h"
92 #include "AliGenerator.h"
96 # define rxgtrak rxgtrak_
97 # define rxouth rxouth_
101 # define rxgtrak RXGTRAK
102 # define rxouth RXOUTH
108 AliGeant3::AliGeant3(const char *title) :
111 //____________________________________________________________________________
112 void AliGeant3::FinishGeometry()
115 // Finalise geometry construction
117 TGeant3::FinishGeometry();
118 //Create the color table
122 //____________________________________________________________________________
123 void AliGeant3::Init()
126 //=================Create Materials and geometry
129 TObjArray *modules = gAlice->Modules();
132 printf("Geometry creation:\n");
133 while((detector = (AliModule*)next())) {
135 // Initialise detector materials and geometry
136 detector->CreateMaterials();
137 detector->CreateGeometry();
138 printf("%10s R:%.2fs C:%.2fs\n",
139 detector->GetName(),stw.RealTime(),stw.CpuTime());
141 //Terminate building of geometry
144 printf("Initialisation:\n");
146 while((detector = (AliModule*)next())) {
148 // Initialise detector and display geometry
150 detector->BuildGeometry();
151 printf("%10s R:%.2fs C:%.2fs\n",
152 detector->GetName(),stw.RealTime(),stw.CpuTime());
157 //____________________________________________________________________________
158 void AliGeant3::ProcessRun(Int_t nevent)
163 Int_t todo = TMath::Abs(nevent);
164 for (Int_t i=0; i<todo; i++) {
165 // Process one run (one run = one event)
166 gAlice->BeginEvent();
168 gAlice->FinishEvent();
172 //_____________________________________________________________________________
173 void AliGeant3::ProcessEvent()
183 //_____________________________________________________________________________
184 void AliGeant3::SetColors()
187 // Set the colors for all the volumes
188 // this is done sequentially for all volumes
189 // based on the number of their medium
192 Int_t jvolum=fGclink->jvolum;
193 //Int_t jtmed=fGclink->jtmed;
194 //Int_t jmate=fGclink->jmate;
195 Int_t nvolum=fGcnum->nvolum;
198 // Now for all the volumes
199 for(kv=1;kv<=nvolum;kv++) {
200 // Get the tracking medium
201 Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
203 //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
205 //Float_t z=fZq[fZlq[jmate-ima]+7];
207 //icol = Int_t(z)%6+2;
208 //icol = 17+Int_t(z*150./92.);
211 strncpy(name,(char*)&fZiq[jvolum+kv],4);
213 Gsatt(name,"COLO",icol);
217 //_____________________________________________________________________________
219 // Interfaces to Fortran
221 //_____________________________________________________________________________
223 extern "C" void type_of_call rxgtrak (Int_t &mtrack, Int_t &ipart, Float_t *pmom,
224 Float_t &e, Float_t *vpos, Float_t *polar,
228 // Fetches next track from the ROOT stack for transport. Called by the
229 // modified version of GTREVE.
231 // Track number in the ROOT stack. If MTRACK=0 no
232 // mtrack more tracks are left in the stack to be
234 // ipart Particle code in the GEANT conventions.
235 // pmom[3] Particle momentum in GeV/c
236 // e Particle energy in GeV
237 // vpos[3] Particle position
238 // tof Particle time of flight in seconds
241 gAlice->GetNextTrack(mtrack, pdg, pmom, e, vpos, polar, tof);
242 ipart = gMC->IdFromPDG(pdg);
246 //_____________________________________________________________________________
247 extern "C" void type_of_call rxouth ()
250 // Called by Gtreve at the end of each primary track
252 gAlice->FinishPrimary();
255 //_____________________________________________________________________________
256 extern "C" void type_of_call rxinh ()
259 // Called by Gtreve at the beginning of each primary track
261 gAlice->BeginPrimary();
265 # define gudigi gudigi_
266 # define guhadr guhadr_
267 # define guout guout_
268 # define guphad guphad_
269 # define gudcay gudcay_
270 # define guiget guiget_
271 # define guinme guinme_
272 # define guinti guinti_
273 # define gunear gunear_
274 # define guskip guskip_
275 # define guview guview_
276 # define gupara gupara_
277 # define gudtim gudtim_
278 # define guplsh guplsh_
279 # define gutrev gutrev_
280 # define gutrak gutrak_
281 # define guswim guswim_
282 # define gufld gufld_
283 # define gustep gustep_
284 # define gukine gukine_
285 # define uglast uglast_
287 # define gheish gheish_
288 # define flufin flufin_
289 # define gfmfin gfmfin_
290 # define gpghei gpghei_
291 # define fldist fldist_
292 # define gfmdis gfmdis_
293 # define ghelx3 ghelx3_
294 # define ghelix ghelix_
295 # define grkuta grkuta_
296 # define gtrack gtrack_
297 # define gtreveroot gtreveroot_
298 # define glast glast_
301 # define gudigi GUDIGI
302 # define guhadr GUHADR
304 # define guphad GUPHAD
305 # define gudcay GUDCAY
306 # define guiget GUIGET
307 # define guinme GUINME
308 # define guinti GUINTI
309 # define gunear GUNEAR
310 # define guskip GUSKIP
311 # define guview GUVIEW
312 # define gupara GUPARA
313 # define gudtim GUDTIM
314 # define guplsh GUPLSH
315 # define gutrev GUTREV
316 # define gutrak GUTRAK
317 # define guswim GUSWIM
319 # define gustep GUSTEP
320 # define gukine GUKINE
321 # define uglast UGLAST
323 # define gheish GHEISH
324 # define flufin FLUFIN
325 # define gfmfin GFMFIN
326 # define gpghei GPGHEI
327 # define fldist FLDIST
328 # define gfmdis GFMDIS
329 # define ghelx3 GHELX3
330 # define ghelix GHELIX
331 # define grkuta GRKUTA
332 # define gtrack GTRACK
333 # define gtreveroot GTREVEROOT
338 extern "C" type_of_call void gheish();
339 extern "C" type_of_call void flufin();
340 extern "C" type_of_call void gfmfin();
341 extern "C" type_of_call void gpghei();
342 extern "C" type_of_call void fldist();
343 extern "C" type_of_call void gfmdis();
344 extern "C" type_of_call void ghelx3(Float_t&, Float_t&, Float_t*, Float_t*);
345 extern "C" type_of_call void ghelix(Float_t&, Float_t&, Float_t*, Float_t*);
346 extern "C" type_of_call void grkuta(Float_t&, Float_t&, Float_t*, Float_t*);
347 extern "C" type_of_call void gtrack();
348 extern "C" type_of_call void gtreveroot();
349 extern "C" type_of_call void glast();
351 extern "C" type_of_call {
353 //______________________________________________________________________
357 // ******************************************************************
359 // * User routine to digitize one event *
361 // * ==>Called by : GTRIG *
363 // ******************************************************************
368 //______________________________________________________________________
372 // ******************************************************************
374 // * User routine to generate one hadronic interaction *
376 // * ==>Called by : GTHADR,GTNEUT *
378 // ******************************************************************
381 // ------------------------------------------------------------------
383 TGeant3* geant3 = (TGeant3*) gMC;
384 Int_t ihadr=geant3->Gcphys()->ihadr;
385 if (ihadr<4) gheish();
386 else if (ihadr==4) flufin();
390 //______________________________________________________________________
394 // ******************************************************************
396 // * User routine called at the end of each event *
398 // * ==>Called by : GTRIG *
400 // ******************************************************************
403 // ------------------------------------------------------------------
407 //______________________________________________________________________
411 // ******************************************************************
413 // * User routine to compute Hadron. inter. probabilities *
415 // * ==>Called by : GTHADR,GTNEUT *
417 // ******************************************************************
420 // ------------------------------------------------------------------
422 TGeant3* geant3 = (TGeant3*) gMC;
423 Int_t ihadr=geant3->Gcphys()->ihadr;
424 if (ihadr<4) gpghei();
425 else if (ihadr==4) fldist();
429 //______________________________________________________________________
433 // ******************************************************************
435 // * User routine to decay particles *
437 // * ==>Called by : GDECAY *
439 // ******************************************************************
442 // ------------------------------------------------------------------
445 TGeant3* geant3=(TGeant3*) gMC;
447 gMC->Decayer()->ForceDecay();
449 // Initialize 4-momentum vector
450 Int_t ipart = geant3->Gckine()->ipart;
453 p[0]=geant3->Gctrak()->vect[3];
454 p[1]=geant3->Gctrak()->vect[4];
455 p[2]=geant3->Gctrak()->vect[5];
456 p[3]=geant3->Gctrak()->vect[6];
458 // Convert from geant to lund particle code
459 Int_t iplund=gMC->PDGFromId(ipart);
461 static TClonesArray *particles;
462 if(!particles) particles=new TClonesArray("TParticle",1000);
464 gMC->Decayer()->Decay(iplund, &p);
467 Int_t np = geant3->Decayer()->ImportParticles(particles);
470 TParticle * iparticle = (TParticle *) particles->At(0);
471 Int_t ipF = 0, ipL = 0 ;
474 // Array to flag deselected particles
475 Int_t* pFlag = new Int_t[np];
476 for (i=0; i<np; i++) pFlag[i]=0;
478 for (i=1; i < np; i++)
480 iparticle = (TParticle *) particles->At(i);
481 ipF = iparticle->GetFirstDaughter();
482 ipL = iparticle->GetLastDaughter();
483 Int_t kf = iparticle->GetPdgCode();
484 Int_t ks = iparticle->GetStatusCode();
486 // Deselect daughters of deselected particles
487 // and jump skip the current particle
489 if (ipF > 0) for (j=ipF-1; j<ipL; j++) pFlag[j]=1;
492 // Particles with long life-time are put on the stack for further tracking
493 // Decay products are deselected
496 Double_t lifeTime = gMC->Decayer()->GetLifetime(kf);
497 if (lifeTime > (Double_t) 1.e-15) {
498 if (ipF > 0) for (j=ipF-1; j<ipL; j++) pFlag[j]=1;
504 if (kf==12 || kf ==-12) continue;
505 if (kf==14 || kf ==-14) continue;
506 if (kf==16 || kf ==-16) continue;
508 Int_t index=geant3->Gcking()->ngkine;
509 // Put particle on geant stack
512 (geant3->Gcking()->gkin[index][0]) = iparticle->Px();
513 (geant3->Gcking()->gkin[index][1]) = iparticle->Py();
514 (geant3->Gcking()->gkin[index][2]) = iparticle->Pz();
515 (geant3->Gcking()->gkin[index][3]) = iparticle->Energy();
516 Int_t ilu = gMC->IdFromPDG(kf);
519 (geant3->Gcking()->gkin[index][4]) = Float_t(ilu);
521 (geant3->Gckin3()->gpos[index][0]) = geant3->Gctrak()->vect[0];
522 (geant3->Gckin3()->gpos[index][1]) = geant3->Gctrak()->vect[1];
523 (geant3->Gckin3()->gpos[index][2]) = geant3->Gctrak()->vect[2];
524 // time of flight offset (mm)
525 (geant3->Gcking()->tofd[index]) = 0.;
526 // increase stack counter
527 (geant3->Gcking()->ngkine)=index+1;
532 //______________________________________________________________________
533 void guiget(Int_t&, Int_t&, Int_t&)
536 // ******************************************************************
538 // * User routine for interactive control of GEANT *
540 // * ==>Called by : <GXINT>, GINCOM *
542 // ******************************************************************
545 // ------------------------------------------------------------------
549 //______________________________________________________________________
550 void guinme(Float_t*, Int_t&, Float_t*, Int_t& IYES)
553 // **********************************************
555 // * USER ROUTINE TO PROVIDE GINME FUNCTION *
556 // * FOR ALL USER SHAPES IDENTIFIED BY THE *
557 // * SHAPE NUMBER SH. POINT IS GIVEN IN X *
558 // * THE PARAMETERS ARE GIVEN IN P. IYES IS *
559 // * RETURNED 1 IF POINT IS IN, 0 IF POINT *
560 // * IS OUT AND LESS THAN ZERO IF SHAPE *
561 // * NUMBER IS NOT SUPPORTED. *
563 // * ==>Called by : GINME *
565 // **********************************************
570 //______________________________________________________________________
574 // ******************************************************************
576 // * User routine for interactive version *
578 // * ==>Called by : <GXINT>, GINTRI *
580 // ******************************************************************
583 // ------------------------------------------------------------------
587 //______________________________________________________________________
588 void gunear(Int_t&, Int_t&, Float_t*, Int_t&)
591 // ******************************************************************
594 // * ISEARC to identify the given volume *
595 // * ICALL to identify the calling routine *
598 // * X coordinates (+direction for ICALL=2) *
599 // * JNEAR address of default list of neighbours *
600 // * (list to be overwriten by user) *
602 // * Called by : GFTRAC, GINVOL, GTMEDI, GTNEXT, GNEXT, GMEDIA *
604 // ******************************************************************
607 // ------------------------------------------------------------------
611 //______________________________________________________________________
612 void guskip(Int_t& ISKIP)
615 // ******************************************************************
617 // * User routine to skip unwanted tracks *
619 // * Called by : GSSTAK *
620 // * Author : F.Bruyant *
622 // ******************************************************************
625 // ------------------------------------------------------------------
630 //______________________________________________________________________
631 void guswim(Float_t& CHARGE, Float_t& STEP, Float_t* VECT, Float_t* VOUT)
634 // ******************************************************************
636 // * User routine to control tracking of one track *
637 // * in a magnetic field *
639 // * ==>Called by : GTELEC,GTHADR,GTMUON *
641 // ******************************************************************
644 // ------------------------------------------------------------------
646 TGeant3* geant3 = (TGeant3*) gMC;
647 Int_t ifield=geant3->Gctmed()->ifield;
648 Float_t fieldm=geant3->Gctmed()->fieldm;
651 Float_t fldcharge = fieldm*CHARGE;
652 ghelx3(fldcharge,STEP,VECT,VOUT);
654 else if (ifield==2) ghelix(CHARGE,STEP,VECT,VOUT);
655 else grkuta(CHARGE,STEP,VECT,VOUT);
658 //______________________________________________________________________
659 void guview(Int_t&, Int_t&, DEFCHARD, Int_t& DEFCHARL)
662 // ******************************************************************
664 // * User routine for interactive version *
666 // * ==>Called by : <GXINT>, GINC1 *
668 // ******************************************************************
671 // ------------------------------------------------------------------
675 //______________________________________________________________________
679 // ******************************************************************
681 // * User routine called every time a particle falls below *
682 // * parametrization threshold. This routine should create *
683 // * the parametrization stack, and, when this is full, *
684 // * parametrize the shower and track the geantinos. *
686 // * ==>Called by : GTRACK *
688 // ******************************************************************
691 // ------------------------------------------------------------------
695 //______________________________________________________________________
696 Float_t gudtim(Float_t&, Float_t&, Int_t&, Int_t&)
699 // ******************************************************************
701 // * User function called by GCDRIF to return drift time *
703 // * ==>Called by : GCDRIF *
705 // ******************************************************************
708 // ------------------------------------------------------------------
714 //______________________________________________________________________
715 Float_t guplsh(Int_t&, Int_t&)
718 // ******************************************************************
721 // * ==>Called by : GLISUR *
723 // ******************************************************************
726 // ------------------------------------------------------------------
729 //*** By default this defines perfect smoothness
733 //______________________________________________________________________
737 // ******************************************************************
739 // * User routine to control tracking of one track *
741 // * ==>Called by : GTREVE *
743 // ******************************************************************
746 // ------------------------------------------------------------------
755 //______________________________________________________________________
759 // ******************************************************************
761 // * User routine to control tracking of one event *
763 // * ==>Called by : GTRIG *
765 // ******************************************************************
768 // ------------------------------------------------------------------
774 //______________________________________________________________________
775 void gufld(Float_t *x, Float_t *b)
777 if(gAlice->Field()) {
778 gAlice->Field()->Field(x,b);
780 printf("No mag field defined!\n");
785 //______________________________________________________________________
789 // ******************************************************************
791 // * User routine called at the end of each tracking step *
792 // * INWVOL is different from 0 when the track has reached *
793 // * a volume boundary *
794 // * ISTOP is different from 0 if the track has stopped *
796 // * ==>Called by : GTRACK *
798 // ******************************************************************
804 Int_t ipp, jk, id, nt;
805 Float_t polar[3]={0,0,0};
810 TGeant3* geant3 = (TGeant3*) gMC;
811 // Stop particle if outside user defined tracking region
812 gMC->TrackPosition(x);
813 r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
814 if (r > gAlice->TrackingRmax() || TMath::Abs(x[2]) > gAlice->TrackingZmax()) {
818 // --- Add new created particles
819 if (gMC->NSecondaries() > 0) {
820 pProc=gMC->ProdProcess(0);
821 for (jk = 0; jk < geant3->Gcking()->ngkine; ++jk) {
822 ipp = Int_t (geant3->Gcking()->gkin[jk][4]+0.5);
823 // --- Skip neutrinos!
825 gAlice->SetTrack(1,gAlice->CurrentTrack(),gMC->PDGFromId(ipp), geant3->Gcking()->gkin[jk],
826 geant3->Gckin3()->gpos[jk], polar,geant3->Gctrak()->tofg, pProc, nt);
830 // Cherenkov photons here
831 if ( geant3->Gckin2()->ngphot ) {
832 for (jk = 0; jk < geant3->Gckin2()->ngphot; ++jk) {
833 mom[0]=geant3->Gckin2()->xphot[jk][3]*geant3->Gckin2()->xphot[jk][6];
834 mom[1]=geant3->Gckin2()->xphot[jk][4]*geant3->Gckin2()->xphot[jk][6];
835 mom[2]=geant3->Gckin2()->xphot[jk][5]*geant3->Gckin2()->xphot[jk][6];
836 gAlice->SetTrack(1, gAlice->CurrentTrack(), gMC->PDGFromId(50),
838 geant3->Gckin2()->xphot[jk], //position
839 &geant3->Gckin2()->xphot[jk][7], //polarisation
840 geant3->Gckin2()->xphot[jk][10], //time of flight
844 // --- Particle leaving the setup ?
845 if (!gMC->IsTrackOut())
846 if ((id=gAlice->DetFromMate(geant3->Gctmed()->numed)) >= 0) gAlice->StepManager(id);
848 // --- Standard GEANT debug routine
849 if(geant3->Gcflag()->idebug) geant3->Gdebug();
852 //______________________________________________________________________
856 // ******************************************************************
858 // * Read or Generates Kinematics for primary tracks *
860 // * ==>Called by : GTRIG *
862 // ******************************************************************
865 // ------------------------------------------------------------------
867 gAlice->Generator()->Generate();
871 //______________________________________________________________________
875 // ******************************************************************
877 // * User routine called at the end of the run *
879 // * ==>Called by : GRUN *
881 // ******************************************************************