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.20 2001/10/03 10:19:13 morsch
19 gudcay(): previous problem fixed by correct checking of indices.
21 Revision 1.19 2001/10/03 08:39:03 morsch
22 Bug in user decay routine leading to segmentation violation corrected.
24 Revision 1.18 2001/07/19 09:10:23 morsch
25 In decays with AliDecayer put long-lived particles undecayed on the stack.
27 Revision 1.17 2001/06/15 09:31:23 morsch
28 In gudcay: write only first generation decay products to stack to respect the possibility of secondary, tertiary, ... vertices during tracking.
30 Revision 1.16 2001/05/16 14:57:23 alibrary
31 New files for folders and Stack
33 Revision 1.15 2001/03/20 06:28:49 alibrary
34 New detector loop split in 2
36 Revision 1.14 2000/12/20 08:39:39 fca
37 Support for Cerenkov and process list in Virtual MC
39 Revision 1.13 2000/11/30 07:12:54 alibrary
40 Introducing new Rndm and QA classes
42 Revision 1.12 2000/11/06 11:35:46 morsch
43 Call BuildGeometry() after Init() to be able to share common detector parameters.
45 Revision 1.11 2000/10/04 16:30:22 fca
46 Add include for exit()
48 Revision 1.10 2000/10/02 21:28:16 fca
49 Removal of useless dependecies via forward declarations
51 Revision 1.9 2000/09/12 14:36:17 morsch
52 In gudcay(): call ForceDecay() before Decay()
54 Revision 1.8 2000/09/06 14:56:34 morsch
55 gudcay() method implemented.
56 Decays are performed using the AliDecayer interface. The pointer to the instance of AliDecayer
57 is obtained from geant3 (will be gMC once it has been implemented for Geant4).
59 Revision 1.7 2000/07/13 16:19:10 fca
60 Mainly coding conventions + some small bug fixes
62 Revision 1.6 2000/07/11 18:24:59 fca
63 Coding convention corrections + few minor bug fixes
65 Revision 1.5 2000/05/20 14:49:48 fca
66 Call gdebug at the end of gustep
68 Revision 1.4 2000/04/26 10:17:32 fca
69 Changes in Lego for G4 compatibility
71 Revision 1.3 2000/04/07 11:12:35 fca
72 G4 compatibility changes
74 Revision 1.2 2000/02/29 19:11:17 fca
75 Move gucode into AliGeant3.cxx
77 Revision 1.1 2000/02/23 16:25:25 fca
78 AliVMC and AliGeant3 classes introduced
79 ReadEuclid moved from AliRun to AliModule
85 #include <TParticle.h>
86 #include <TStopwatch.h>
87 #include <TClonesArray.h>
89 #include "AliDecayer.h"
90 #include "AliGeant3.h"
93 #include "AliCallf77.h"
94 #include "AliModule.h"
96 #include "AliGenerator.h"
100 # define rxgtrak rxgtrak_
101 # define rxouth rxouth_
102 # define rxinh rxinh_
105 # define rxgtrak RXGTRAK
106 # define rxouth RXOUTH
112 AliGeant3::AliGeant3(const char *title) :
115 //____________________________________________________________________________
116 void AliGeant3::FinishGeometry()
119 // Finalise geometry construction
121 TGeant3::FinishGeometry();
122 //Create the color table
126 //____________________________________________________________________________
127 void AliGeant3::Init()
130 //=================Create Materials and geometry
133 TObjArray *modules = gAlice->Modules();
136 printf("Geometry creation:\n");
137 while((detector = (AliModule*)next())) {
139 // Initialise detector materials and geometry
140 detector->CreateMaterials();
141 detector->CreateGeometry();
142 printf("%10s R:%.2fs C:%.2fs\n",
143 detector->GetName(),stw.RealTime(),stw.CpuTime());
145 //Terminate building of geometry
148 printf("Initialisation:\n");
150 while((detector = (AliModule*)next())) {
152 // Initialise detector and display geometry
154 detector->BuildGeometry();
155 printf("%10s R:%.2fs C:%.2fs\n",
156 detector->GetName(),stw.RealTime(),stw.CpuTime());
161 //____________________________________________________________________________
162 void AliGeant3::ProcessRun(Int_t nevent)
167 Int_t todo = TMath::Abs(nevent);
168 for (Int_t i=0; i<todo; i++) {
169 // Process one run (one run = one event)
170 gAlice->BeginEvent();
172 gAlice->FinishEvent();
176 //_____________________________________________________________________________
177 void AliGeant3::ProcessEvent()
187 //_____________________________________________________________________________
188 void AliGeant3::SetColors()
191 // Set the colors for all the volumes
192 // this is done sequentially for all volumes
193 // based on the number of their medium
196 Int_t jvolum=fGclink->jvolum;
197 //Int_t jtmed=fGclink->jtmed;
198 //Int_t jmate=fGclink->jmate;
199 Int_t nvolum=fGcnum->nvolum;
202 // Now for all the volumes
203 for(kv=1;kv<=nvolum;kv++) {
204 // Get the tracking medium
205 Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
207 //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
209 //Float_t z=fZq[fZlq[jmate-ima]+7];
211 //icol = Int_t(z)%6+2;
212 //icol = 17+Int_t(z*150./92.);
215 strncpy(name,(char*)&fZiq[jvolum+kv],4);
217 Gsatt(name,"COLO",icol);
221 //_____________________________________________________________________________
223 // Interfaces to Fortran
225 //_____________________________________________________________________________
227 extern "C" void type_of_call rxgtrak (Int_t &mtrack, Int_t &ipart, Float_t *pmom,
228 Float_t &e, Float_t *vpos, Float_t *polar,
232 // Fetches next track from the ROOT stack for transport. Called by the
233 // modified version of GTREVE.
235 // Track number in the ROOT stack. If MTRACK=0 no
236 // mtrack more tracks are left in the stack to be
238 // ipart Particle code in the GEANT conventions.
239 // pmom[3] Particle momentum in GeV/c
240 // e Particle energy in GeV
241 // vpos[3] Particle position
242 // tof Particle time of flight in seconds
245 gAlice->GetNextTrack(mtrack, pdg, pmom, e, vpos, polar, tof);
246 ipart = gMC->IdFromPDG(pdg);
250 //_____________________________________________________________________________
251 extern "C" void type_of_call rxouth ()
254 // Called by Gtreve at the end of each primary track
256 gAlice->FinishPrimary();
259 //_____________________________________________________________________________
260 extern "C" void type_of_call rxinh ()
263 // Called by Gtreve at the beginning of each primary track
265 gAlice->BeginPrimary();
269 # define gudigi gudigi_
270 # define guhadr guhadr_
271 # define guout guout_
272 # define guphad guphad_
273 # define gudcay gudcay_
274 # define guiget guiget_
275 # define guinme guinme_
276 # define guinti guinti_
277 # define gunear gunear_
278 # define guskip guskip_
279 # define guview guview_
280 # define gupara gupara_
281 # define gudtim gudtim_
282 # define guplsh guplsh_
283 # define gutrev gutrev_
284 # define gutrak gutrak_
285 # define guswim guswim_
286 # define gufld gufld_
287 # define gustep gustep_
288 # define gukine gukine_
289 # define uglast uglast_
291 # define gheish gheish_
292 # define flufin flufin_
293 # define gfmfin gfmfin_
294 # define gpghei gpghei_
295 # define fldist fldist_
296 # define gfmdis gfmdis_
297 # define ghelx3 ghelx3_
298 # define ghelix ghelix_
299 # define grkuta grkuta_
300 # define gtrack gtrack_
301 # define gtreveroot gtreveroot_
302 # define glast glast_
305 # define gudigi GUDIGI
306 # define guhadr GUHADR
308 # define guphad GUPHAD
309 # define gudcay GUDCAY
310 # define guiget GUIGET
311 # define guinme GUINME
312 # define guinti GUINTI
313 # define gunear GUNEAR
314 # define guskip GUSKIP
315 # define guview GUVIEW
316 # define gupara GUPARA
317 # define gudtim GUDTIM
318 # define guplsh GUPLSH
319 # define gutrev GUTREV
320 # define gutrak GUTRAK
321 # define guswim GUSWIM
323 # define gustep GUSTEP
324 # define gukine GUKINE
325 # define uglast UGLAST
327 # define gheish GHEISH
328 # define flufin FLUFIN
329 # define gfmfin GFMFIN
330 # define gpghei GPGHEI
331 # define fldist FLDIST
332 # define gfmdis GFMDIS
333 # define ghelx3 GHELX3
334 # define ghelix GHELIX
335 # define grkuta GRKUTA
336 # define gtrack GTRACK
337 # define gtreveroot GTREVEROOT
342 extern "C" type_of_call void gheish();
343 extern "C" type_of_call void flufin();
344 extern "C" type_of_call void gfmfin();
345 extern "C" type_of_call void gpghei();
346 extern "C" type_of_call void fldist();
347 extern "C" type_of_call void gfmdis();
348 extern "C" type_of_call void ghelx3(Float_t&, Float_t&, Float_t*, Float_t*);
349 extern "C" type_of_call void ghelix(Float_t&, Float_t&, Float_t*, Float_t*);
350 extern "C" type_of_call void grkuta(Float_t&, Float_t&, Float_t*, Float_t*);
351 extern "C" type_of_call void gtrack();
352 extern "C" type_of_call void gtreveroot();
353 extern "C" type_of_call void glast();
355 extern "C" type_of_call {
357 //______________________________________________________________________
361 // ******************************************************************
363 // * User routine to digitize one event *
365 // * ==>Called by : GTRIG *
367 // ******************************************************************
372 //______________________________________________________________________
376 // ******************************************************************
378 // * User routine to generate one hadronic interaction *
380 // * ==>Called by : GTHADR,GTNEUT *
382 // ******************************************************************
385 // ------------------------------------------------------------------
387 TGeant3* geant3 = (TGeant3*) gMC;
388 Int_t ihadr=geant3->Gcphys()->ihadr;
389 if (ihadr<4) gheish();
390 else if (ihadr==4) flufin();
394 //______________________________________________________________________
398 // ******************************************************************
400 // * User routine called at the end of each event *
402 // * ==>Called by : GTRIG *
404 // ******************************************************************
407 // ------------------------------------------------------------------
411 //______________________________________________________________________
415 // ******************************************************************
417 // * User routine to compute Hadron. inter. probabilities *
419 // * ==>Called by : GTHADR,GTNEUT *
421 // ******************************************************************
424 // ------------------------------------------------------------------
426 TGeant3* geant3 = (TGeant3*) gMC;
427 Int_t ihadr=geant3->Gcphys()->ihadr;
428 if (ihadr<4) gpghei();
429 else if (ihadr==4) fldist();
433 //______________________________________________________________________
437 // ******************************************************************
439 // * User routine to decay particles *
441 // * ==>Called by : GDECAY *
443 // ******************************************************************
446 // ------------------------------------------------------------------
449 TGeant3* geant3=(TGeant3*) gMC;
451 gMC->Decayer()->ForceDecay();
453 // Initialize 4-momentum vector
454 Int_t ipart = geant3->Gckine()->ipart;
457 p[0]=geant3->Gctrak()->vect[3];
458 p[1]=geant3->Gctrak()->vect[4];
459 p[2]=geant3->Gctrak()->vect[5];
460 p[3]=geant3->Gctrak()->vect[6];
462 // Convert from geant to lund particle code
463 Int_t iplund=gMC->PDGFromId(ipart);
465 static TClonesArray *particles;
466 if(!particles) particles=new TClonesArray("TParticle",1000);
468 gMC->Decayer()->Decay(iplund, &p);
471 Int_t np = geant3->Decayer()->ImportParticles(particles);
474 TParticle * iparticle = (TParticle *) particles->At(0);
475 Int_t ipF = 0, ipL = 0 ;
478 // Array to flag deselected particles
479 Int_t* pFlag = new Int_t[np];
480 for (i=0; i<np; i++) pFlag[i]=0;
482 for (i=1; i < np; i++)
484 iparticle = (TParticle *) particles->At(i);
485 ipF = iparticle->GetFirstDaughter();
486 ipL = iparticle->GetLastDaughter();
487 Int_t kf = iparticle->GetPdgCode();
488 Int_t ks = iparticle->GetStatusCode();
490 // Deselect daughters of deselected particles
491 // and jump skip the current particle
493 if (ipF > 0) for (j=ipF-1; j<ipL; j++) pFlag[j]=1;
496 // Particles with long life-time are put on the stack for further tracking
497 // Decay products are deselected
500 Double_t lifeTime = gMC->Decayer()->GetLifetime(kf);
501 if (lifeTime > (Double_t) 1.e-15) {
502 if (ipF > 0) for (j=ipF-1; j<ipL; j++) pFlag[j]=1;
508 if (kf==12 || kf ==-12) continue;
509 if (kf==14 || kf ==-14) continue;
510 if (kf==16 || kf ==-16) continue;
512 Int_t index=geant3->Gcking()->ngkine;
513 // Put particle on geant stack
516 (geant3->Gcking()->gkin[index][0]) = iparticle->Px();
517 (geant3->Gcking()->gkin[index][1]) = iparticle->Py();
518 (geant3->Gcking()->gkin[index][2]) = iparticle->Pz();
519 (geant3->Gcking()->gkin[index][3]) = iparticle->Energy();
520 Int_t ilu = gMC->IdFromPDG(kf);
523 (geant3->Gcking()->gkin[index][4]) = Float_t(ilu);
525 (geant3->Gckin3()->gpos[index][0]) = geant3->Gctrak()->vect[0];
526 (geant3->Gckin3()->gpos[index][1]) = geant3->Gctrak()->vect[1];
527 (geant3->Gckin3()->gpos[index][2]) = geant3->Gctrak()->vect[2];
528 // time of flight offset (mm)
529 (geant3->Gcking()->tofd[index]) = 0.;
530 // increase stack counter
531 (geant3->Gcking()->ngkine)=index+1;
536 //______________________________________________________________________
537 void guiget(Int_t&, Int_t&, Int_t&)
540 // ******************************************************************
542 // * User routine for interactive control of GEANT *
544 // * ==>Called by : <GXINT>, GINCOM *
546 // ******************************************************************
549 // ------------------------------------------------------------------
553 //______________________________________________________________________
554 void guinme(Float_t*, Int_t&, Float_t*, Int_t& IYES)
557 // **********************************************
559 // * USER ROUTINE TO PROVIDE GINME FUNCTION *
560 // * FOR ALL USER SHAPES IDENTIFIED BY THE *
561 // * SHAPE NUMBER SH. POINT IS GIVEN IN X *
562 // * THE PARAMETERS ARE GIVEN IN P. IYES IS *
563 // * RETURNED 1 IF POINT IS IN, 0 IF POINT *
564 // * IS OUT AND LESS THAN ZERO IF SHAPE *
565 // * NUMBER IS NOT SUPPORTED. *
567 // * ==>Called by : GINME *
569 // **********************************************
574 //______________________________________________________________________
578 // ******************************************************************
580 // * User routine for interactive version *
582 // * ==>Called by : <GXINT>, GINTRI *
584 // ******************************************************************
587 // ------------------------------------------------------------------
591 //______________________________________________________________________
592 void gunear(Int_t&, Int_t&, Float_t*, Int_t&)
595 // ******************************************************************
598 // * ISEARC to identify the given volume *
599 // * ICALL to identify the calling routine *
602 // * X coordinates (+direction for ICALL=2) *
603 // * JNEAR address of default list of neighbours *
604 // * (list to be overwriten by user) *
606 // * Called by : GFTRAC, GINVOL, GTMEDI, GTNEXT, GNEXT, GMEDIA *
608 // ******************************************************************
611 // ------------------------------------------------------------------
615 //______________________________________________________________________
616 void guskip(Int_t& ISKIP)
619 // ******************************************************************
621 // * User routine to skip unwanted tracks *
623 // * Called by : GSSTAK *
624 // * Author : F.Bruyant *
626 // ******************************************************************
629 // ------------------------------------------------------------------
634 //______________________________________________________________________
635 void guswim(Float_t& CHARGE, Float_t& STEP, Float_t* VECT, Float_t* VOUT)
638 // ******************************************************************
640 // * User routine to control tracking of one track *
641 // * in a magnetic field *
643 // * ==>Called by : GTELEC,GTHADR,GTMUON *
645 // ******************************************************************
648 // ------------------------------------------------------------------
650 TGeant3* geant3 = (TGeant3*) gMC;
651 Int_t ifield=geant3->Gctmed()->ifield;
652 Float_t fieldm=geant3->Gctmed()->fieldm;
655 Float_t fldcharge = fieldm*CHARGE;
656 ghelx3(fldcharge,STEP,VECT,VOUT);
658 else if (ifield==2) ghelix(CHARGE,STEP,VECT,VOUT);
659 else grkuta(CHARGE,STEP,VECT,VOUT);
662 //______________________________________________________________________
663 void guview(Int_t&, Int_t&, DEFCHARD, Int_t& DEFCHARL)
666 // ******************************************************************
668 // * User routine for interactive version *
670 // * ==>Called by : <GXINT>, GINC1 *
672 // ******************************************************************
675 // ------------------------------------------------------------------
679 //______________________________________________________________________
683 // ******************************************************************
685 // * User routine called every time a particle falls below *
686 // * parametrization threshold. This routine should create *
687 // * the parametrization stack, and, when this is full, *
688 // * parametrize the shower and track the geantinos. *
690 // * ==>Called by : GTRACK *
692 // ******************************************************************
695 // ------------------------------------------------------------------
699 //______________________________________________________________________
700 Float_t gudtim(Float_t&, Float_t&, Int_t&, Int_t&)
703 // ******************************************************************
705 // * User function called by GCDRIF to return drift time *
707 // * ==>Called by : GCDRIF *
709 // ******************************************************************
712 // ------------------------------------------------------------------
718 //______________________________________________________________________
719 Float_t guplsh(Int_t&, Int_t&)
722 // ******************************************************************
725 // * ==>Called by : GLISUR *
727 // ******************************************************************
730 // ------------------------------------------------------------------
733 //*** By default this defines perfect smoothness
737 //______________________________________________________________________
741 // ******************************************************************
743 // * User routine to control tracking of one track *
745 // * ==>Called by : GTREVE *
747 // ******************************************************************
750 // ------------------------------------------------------------------
759 //______________________________________________________________________
763 // ******************************************************************
765 // * User routine to control tracking of one event *
767 // * ==>Called by : GTRIG *
769 // ******************************************************************
772 // ------------------------------------------------------------------
778 //______________________________________________________________________
779 void gufld(Float_t *x, Float_t *b)
781 if(gAlice->Field()) {
782 gAlice->Field()->Field(x,b);
784 printf("No mag field defined!\n");
789 //______________________________________________________________________
793 // ******************************************************************
795 // * User routine called at the end of each tracking step *
796 // * INWVOL is different from 0 when the track has reached *
797 // * a volume boundary *
798 // * ISTOP is different from 0 if the track has stopped *
800 // * ==>Called by : GTRACK *
802 // ******************************************************************
808 Int_t ipp, jk, id, nt;
809 Float_t polar[3]={0,0,0};
814 TGeant3* geant3 = (TGeant3*) gMC;
815 // Stop particle if outside user defined tracking region
816 gMC->TrackPosition(x);
817 r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
818 if (r > gAlice->TrackingRmax() || TMath::Abs(x[2]) > gAlice->TrackingZmax()) {
822 // --- Add new created particles
823 if (gMC->NSecondaries() > 0) {
824 pProc=gMC->ProdProcess(0);
825 for (jk = 0; jk < geant3->Gcking()->ngkine; ++jk) {
826 ipp = Int_t (geant3->Gcking()->gkin[jk][4]+0.5);
827 // --- Skip neutrinos!
829 gAlice->SetTrack(1,gAlice->CurrentTrack(),gMC->PDGFromId(ipp), geant3->Gcking()->gkin[jk],
830 geant3->Gckin3()->gpos[jk], polar,geant3->Gctrak()->tofg, pProc, nt);
834 // Cherenkov photons here
835 if ( geant3->Gckin2()->ngphot ) {
836 for (jk = 0; jk < geant3->Gckin2()->ngphot; ++jk) {
837 mom[0]=geant3->Gckin2()->xphot[jk][3]*geant3->Gckin2()->xphot[jk][6];
838 mom[1]=geant3->Gckin2()->xphot[jk][4]*geant3->Gckin2()->xphot[jk][6];
839 mom[2]=geant3->Gckin2()->xphot[jk][5]*geant3->Gckin2()->xphot[jk][6];
840 gAlice->SetTrack(1, gAlice->CurrentTrack(), gMC->PDGFromId(50),
842 geant3->Gckin2()->xphot[jk], //position
843 &geant3->Gckin2()->xphot[jk][7], //polarisation
844 geant3->Gckin2()->xphot[jk][10], //time of flight
848 // --- Particle leaving the setup ?
849 if (!gMC->IsTrackOut())
850 if ((id=gAlice->DetFromMate(geant3->Gctmed()->numed)) >= 0) gAlice->StepManager(id);
852 // --- Standard GEANT debug routine
853 if(geant3->Gcflag()->idebug) geant3->Gdebug();
856 //______________________________________________________________________
860 // ******************************************************************
862 // * Read or Generates Kinematics for primary tracks *
864 // * ==>Called by : GTRIG *
866 // ******************************************************************
869 // ------------------------------------------------------------------
871 gAlice->Generator()->Generate();
875 //______________________________________________________________________
879 // ******************************************************************
881 // * User routine called at the end of the run *
883 // * ==>Called by : GRUN *
885 // ******************************************************************