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.10 2000/10/02 21:28:16 fca
19 Removal of useless dependecies via forward declarations
21 Revision 1.9 2000/09/12 14:36:17 morsch
22 In gudcay(): call ForceDecay() before Decay()
24 Revision 1.8 2000/09/06 14:56:34 morsch
25 gudcay() method implemented.
26 Decays are performed using the AliDecayer interface. The pointer to the instance of AliDecayer
27 is obtained from geant3 (will be gMC once it has been implemented for Geant4).
29 Revision 1.7 2000/07/13 16:19:10 fca
30 Mainly coding conventions + some small bug fixes
32 Revision 1.6 2000/07/11 18:24:59 fca
33 Coding convention corrections + few minor bug fixes
35 Revision 1.5 2000/05/20 14:49:48 fca
36 Call gdebug at the end of gustep
38 Revision 1.4 2000/04/26 10:17:32 fca
39 Changes in Lego for G4 compatibility
41 Revision 1.3 2000/04/07 11:12:35 fca
42 G4 compatibility changes
44 Revision 1.2 2000/02/29 19:11:17 fca
45 Move gucode into AliGeant3.cxx
47 Revision 1.1 2000/02/23 16:25:25 fca
48 AliVMC and AliGeant3 classes introduced
49 ReadEuclid moved from AliRun to AliModule
55 #include <TParticle.h>
57 #include "AliDecayer.h"
58 #include "AliGeant3.h"
61 #include "AliCallf77.h"
62 #include "AliModule.h"
67 # define rxgtrak rxgtrak_
68 # define rxstrak rxstrak_
69 # define rxkeep rxkeep_
70 # define rxouth rxouth_
73 # define rxgtrak RXGTRAK
74 # define rxstrak RXSTRAK
75 # define rxkeep RXKEEP
76 # define rxouth RXOUTH
81 AliGeant3::AliGeant3(const char *title) :
84 //____________________________________________________________________________
85 void AliGeant3::FinishGeometry()
88 // Finalise geometry construction
90 TGeant3::FinishGeometry();
91 //Create the color table
95 //____________________________________________________________________________
96 void AliGeant3::Init()
99 //=================Create Materials and geometry
101 TObjArray *modules = gAlice->Modules();
104 while((detector = (AliModule*)next())) {
105 // Initialise detector materials and geometry
106 detector->CreateMaterials();
107 detector->CreateGeometry();
108 detector->BuildGeometry();
112 //Terminate building of geometry
116 //____________________________________________________________________________
117 void AliGeant3::ProcessRun(Int_t nevent)
122 Int_t todo = TMath::Abs(nevent);
123 for (Int_t i=0; i<todo; i++) {
124 // Process one run (one run = one event)
125 gAlice->BeginEvent();
127 gAlice->FinishEvent();
131 //_____________________________________________________________________________
132 void AliGeant3::ProcessEvent()
142 //_____________________________________________________________________________
143 void AliGeant3::SetColors()
146 // Set the colors for all the volumes
147 // this is done sequentially for all volumes
148 // based on the number of their medium
151 Int_t jvolum=fGclink->jvolum;
152 //Int_t jtmed=fGclink->jtmed;
153 //Int_t jmate=fGclink->jmate;
154 Int_t nvolum=fGcnum->nvolum;
157 // Now for all the volumes
158 for(kv=1;kv<=nvolum;kv++) {
159 // Get the tracking medium
160 Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
162 //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
164 //Float_t z=fZq[fZlq[jmate-ima]+7];
166 //icol = Int_t(z)%6+2;
167 //icol = 17+Int_t(z*150./92.);
170 strncpy(name,(char*)&fZiq[jvolum+kv],4);
172 Gsatt(name,"COLO",icol);
176 //_____________________________________________________________________________
178 // Interfaces to Fortran
180 //_____________________________________________________________________________
182 extern "C" void type_of_call rxgtrak (Int_t &mtrack, Int_t &ipart, Float_t *pmom,
183 Float_t &e, Float_t *vpos, Float_t *polar,
187 // Fetches next track from the ROOT stack for transport. Called by the
188 // modified version of GTREVE.
190 // Track number in the ROOT stack. If MTRACK=0 no
191 // mtrack more tracks are left in the stack to be
193 // ipart Particle code in the GEANT conventions.
194 // pmom[3] Particle momentum in GeV/c
195 // e Particle energy in GeV
196 // vpos[3] Particle position
197 // tof Particle time of flight in seconds
200 gAlice->GetNextTrack(mtrack, pdg, pmom, e, vpos, polar, tof);
201 ipart = gMC->IdFromPDG(pdg);
205 //_____________________________________________________________________________
206 extern "C" void type_of_call
208 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom,
209 Float_t *vpos, Float_t &tof, const char* cmech, Int_t &ntr, const int cmlen)
211 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom,
212 Float_t *vpos, Float_t &tof, const char* cmech, const int cmlen,
217 // Fetches next track from the ROOT stack for transport. Called by GUKINE
220 // Status of the track. If keep=0 the track is put
221 // keep on the ROOT stack but it is not fetched for
223 // parent Parent track. If parent=0 the track is a primary.
224 // In GUSTEP the routine is normally called to store
225 // secondaries generated by the current track whose
226 // ROOT stack number is MTRACK (common SCKINE.
227 // ipart Particle code in the GEANT conventions.
228 // pmom[3] Particle momentum in GeV/c
229 // vpos[3] Particle position
230 // tof Particle time of flight in seconds
232 // cmech (CHARACTER*10) Particle origin. This field is user
233 // defined and it is not used inside the GALICE code.
234 // ntr Number assigned to the particle in the ROOT stack.
237 Float_t polar[3]={0.,0.,0.};
238 for(int i=0; i<10 && i<cmlen; i++) mecha[i]=cmech[i];
240 Int_t pdg=gMC->PDGFromId(ipart);
241 gAlice->SetTrack(keep, parent-1, pdg, pmom, vpos, polar, tof, mecha, ntr);
245 //_____________________________________________________________________________
246 extern "C" void type_of_call rxkeep(const Int_t &n)
248 if( NULL==gAlice ) exit(1);
250 if( n<=0 || n>gAlice->Particles()->GetEntries() )
252 printf(" Bad index n=%d must be 0<n<=%d\n",
253 n,gAlice->Particles()->GetEntries());
257 ((TParticle*)(gAlice->Particles()->UncheckedAt(n-1)))->SetBit(kKeepBit);
260 //_____________________________________________________________________________
261 extern "C" void type_of_call rxouth ()
264 // Called by Gtreve at the end of each primary track
266 gAlice->FinishPrimary();
271 # define gudigi gudigi_
272 # define guhadr guhadr_
273 # define guout guout_
274 # define guphad guphad_
275 # define gudcay gudcay_
276 # define guiget guiget_
277 # define guinme guinme_
278 # define guinti guinti_
279 # define gunear gunear_
280 # define guskip guskip_
281 # define guview guview_
282 # define gupara gupara_
283 # define gudtim gudtim_
284 # define guplsh guplsh_
285 # define gutrev gutrev_
286 # define gutrak gutrak_
287 # define guswim guswim_
288 # define gufld gufld_
289 # define gustep gustep_
290 # define gukine gukine_
291 # define uglast uglast_
293 # define gheish gheish_
294 # define flufin flufin_
295 # define gfmfin gfmfin_
296 # define gpghei gpghei_
297 # define fldist fldist_
298 # define gfmdis gfmdis_
299 # define ghelx3 ghelx3_
300 # define ghelix ghelix_
301 # define grkuta grkuta_
302 # define gtrack gtrack_
303 # define gtreveroot gtreveroot_
304 # define glast glast_
307 # define gudigi GUDIGI
308 # define guhadr GUHADR
310 # define guphad GUPHAD
311 # define gudcay GUDCAY
312 # define guiget GUIGET
313 # define guinme GUINME
314 # define guinti GUINTI
315 # define gunear GUNEAR
316 # define guskip GUSKIP
317 # define guview GUVIEW
318 # define gupara GUPARA
319 # define gudtim GUDTIM
320 # define guplsh GUPLSH
321 # define gutrev GUTREV
322 # define gutrak GUTRAK
323 # define guswim GUSWIM
325 # define gustep GUSTEP
326 # define gukine GUKINE
327 # define uglast UGLAST
329 # define gheish GHEISH
330 # define flufin FLUFIN
331 # define gfmfin GFMFIN
332 # define gpghei GPGHEI
333 # define fldist FLDIST
334 # define gfmdis GFMDIS
335 # define ghelx3 GHELX3
336 # define ghelix GHELIX
337 # define grkuta GRKUTA
338 # define gtrack GTRACK
339 # define gtreveroot GTREVEROOT
344 extern "C" type_of_call void gheish();
345 extern "C" type_of_call void flufin();
346 extern "C" type_of_call void gfmfin();
347 extern "C" type_of_call void gpghei();
348 extern "C" type_of_call void fldist();
349 extern "C" type_of_call void gfmdis();
350 extern "C" type_of_call void ghelx3(Float_t&, Float_t&, Float_t*, Float_t*);
351 extern "C" type_of_call void ghelix(Float_t&, Float_t&, Float_t*, Float_t*);
352 extern "C" type_of_call void grkuta(Float_t&, Float_t&, Float_t*, Float_t*);
353 extern "C" type_of_call void gtrack();
354 extern "C" type_of_call void gtreveroot();
355 extern "C" type_of_call void glast();
357 extern "C" type_of_call {
359 //______________________________________________________________________
363 // ******************************************************************
365 // * User routine to digitize one event *
367 // * ==>Called by : GTRIG *
369 // ******************************************************************
374 //______________________________________________________________________
378 // ******************************************************************
380 // * User routine to generate one hadronic interaction *
382 // * ==>Called by : GTHADR,GTNEUT *
384 // ******************************************************************
387 // ------------------------------------------------------------------
389 TGeant3* geant3 = (TGeant3*) gMC;
390 Int_t ihadr=geant3->Gcphys()->ihadr;
391 if (ihadr<4) gheish();
392 else if (ihadr==4) flufin();
396 //______________________________________________________________________
400 // ******************************************************************
402 // * User routine called at the end of each event *
404 // * ==>Called by : GTRIG *
406 // ******************************************************************
409 // ------------------------------------------------------------------
413 //______________________________________________________________________
417 // ******************************************************************
419 // * User routine to compute Hadron. inter. probabilities *
421 // * ==>Called by : GTHADR,GTNEUT *
423 // ******************************************************************
426 // ------------------------------------------------------------------
428 TGeant3* geant3 = (TGeant3*) gMC;
429 Int_t ihadr=geant3->Gcphys()->ihadr;
430 if (ihadr<4) gpghei();
431 else if (ihadr==4) fldist();
435 //______________________________________________________________________
439 // ******************************************************************
441 // * User routine to decay particles *
443 // * ==>Called by : GDECAY *
445 // ******************************************************************
448 // ------------------------------------------------------------------
451 TGeant3* geant3=(TGeant3*) gMC;
453 gMC->Decayer()->ForceDecay();
455 // Initialize 4-momentum vector
456 Int_t ipart = geant3->Gckine()->ipart;
459 p[0]=geant3->Gctrak()->vect[3];
460 p[1]=geant3->Gctrak()->vect[4];
461 p[2]=geant3->Gctrak()->vect[5];
462 p[3]=geant3->Gctrak()->vect[6];
464 // Convert from geant to lund particle code
465 Int_t iplund=gMC->PDGFromId(ipart);
467 static TClonesArray *particles;
468 if(!particles) particles=new TClonesArray("TParticle",1000);
470 gMC->Decayer()->Decay(iplund, &p);
473 Int_t np = geant3->Decayer()->ImportParticles(particles);
476 for (Int_t i=0; i< np; i++)
478 TParticle * iparticle = (TParticle *) particles->At(i);
479 Int_t ks = iparticle->GetStatusCode();
480 // Final state particles only
481 if (ks < 1 || ks > 10) continue;
483 Int_t kf=iparticle->GetPdgCode();
484 if (kf==12 || kf ==-12) continue;
485 if (kf==14 || kf ==-14) continue;
486 if (kf==16 || kf ==-16) continue;
488 Int_t index=geant3->Gcking()->ngkine;
489 // Put particle on geant stack
492 (geant3->Gcking()->gkin[index][0]) = iparticle->Px();
493 (geant3->Gcking()->gkin[index][1]) = iparticle->Py();
494 (geant3->Gcking()->gkin[index][2]) = iparticle->Pz();
495 (geant3->Gcking()->gkin[index][3]) = iparticle->Energy();
496 Int_t ilu = gMC->IdFromPDG(kf);
499 (geant3->Gcking()->gkin[index][4]) = Float_t(ilu);
501 (geant3->Gckin3()->gpos[index][0]) = geant3->Gctrak()->vect[0];
502 (geant3->Gckin3()->gpos[index][1]) = geant3->Gctrak()->vect[1];
503 (geant3->Gckin3()->gpos[index][2]) = geant3->Gctrak()->vect[2];
504 // time of flight offset (mm)
505 (geant3->Gcking()->tofd[index]) = 0.;
506 // (geant3->Gcking()->tofd[index]) = iparticle->T()/(10*kSpeedOfLight);
507 // increase stack counter
508 (geant3->Gcking()->ngkine)=index+1;
512 //______________________________________________________________________
513 void guiget(Int_t&, Int_t&, Int_t&)
516 // ******************************************************************
518 // * User routine for interactive control of GEANT *
520 // * ==>Called by : <GXINT>, GINCOM *
522 // ******************************************************************
525 // ------------------------------------------------------------------
529 //______________________________________________________________________
530 void guinme(Float_t*, Int_t&, Float_t*, Int_t& IYES)
533 // **********************************************
535 // * USER ROUTINE TO PROVIDE GINME FUNCTION *
536 // * FOR ALL USER SHAPES IDENTIFIED BY THE *
537 // * SHAPE NUMBER SH. POINT IS GIVEN IN X *
538 // * THE PARAMETERS ARE GIVEN IN P. IYES IS *
539 // * RETURNED 1 IF POINT IS IN, 0 IF POINT *
540 // * IS OUT AND LESS THAN ZERO IF SHAPE *
541 // * NUMBER IS NOT SUPPORTED. *
543 // * ==>Called by : GINME *
545 // **********************************************
550 //______________________________________________________________________
554 // ******************************************************************
556 // * User routine for interactive version *
558 // * ==>Called by : <GXINT>, GINTRI *
560 // ******************************************************************
563 // ------------------------------------------------------------------
567 //______________________________________________________________________
568 void gunear(Int_t&, Int_t&, Float_t*, Int_t&)
571 // ******************************************************************
574 // * ISEARC to identify the given volume *
575 // * ICALL to identify the calling routine *
578 // * X coordinates (+direction for ICALL=2) *
579 // * JNEAR address of default list of neighbours *
580 // * (list to be overwriten by user) *
582 // * Called by : GFTRAC, GINVOL, GTMEDI, GTNEXT, GNEXT, GMEDIA *
584 // ******************************************************************
587 // ------------------------------------------------------------------
591 //______________________________________________________________________
592 void guskip(Int_t& ISKIP)
595 // ******************************************************************
597 // * User routine to skip unwanted tracks *
599 // * Called by : GSSTAK *
600 // * Author : F.Bruyant *
602 // ******************************************************************
605 // ------------------------------------------------------------------
610 //______________________________________________________________________
611 void guswim(Float_t& CHARGE, Float_t& STEP, Float_t* VECT, Float_t* VOUT)
614 // ******************************************************************
616 // * User routine to control tracking of one track *
617 // * in a magnetic field *
619 // * ==>Called by : GTELEC,GTHADR,GTMUON *
621 // ******************************************************************
624 // ------------------------------------------------------------------
626 TGeant3* geant3 = (TGeant3*) gMC;
627 Int_t ifield=geant3->Gctmed()->ifield;
628 Float_t fieldm=geant3->Gctmed()->fieldm;
631 Float_t fldcharge = fieldm*CHARGE;
632 ghelx3(fldcharge,STEP,VECT,VOUT);
634 else if (ifield==2) ghelix(CHARGE,STEP,VECT,VOUT);
635 else grkuta(CHARGE,STEP,VECT,VOUT);
638 //______________________________________________________________________
639 void guview(Int_t&, Int_t&, DEFCHARD, Int_t& DEFCHARL)
642 // ******************************************************************
644 // * User routine for interactive version *
646 // * ==>Called by : <GXINT>, GINC1 *
648 // ******************************************************************
651 // ------------------------------------------------------------------
655 //______________________________________________________________________
659 // ******************************************************************
661 // * User routine called every time a particle falls below *
662 // * parametrization threshold. This routine should create *
663 // * the parametrization stack, and, when this is full, *
664 // * parametrize the shower and track the geantinos. *
666 // * ==>Called by : GTRACK *
668 // ******************************************************************
671 // ------------------------------------------------------------------
675 //______________________________________________________________________
676 Float_t gudtim(Float_t&, Float_t&, Int_t&, Int_t&)
679 // ******************************************************************
681 // * User function called by GCDRIF to return drift time *
683 // * ==>Called by : GCDRIF *
685 // ******************************************************************
688 // ------------------------------------------------------------------
694 //______________________________________________________________________
695 Float_t guplsh(Int_t&, Int_t&)
698 // ******************************************************************
701 // * ==>Called by : GLISUR *
703 // ******************************************************************
706 // ------------------------------------------------------------------
709 //*** By default this defines perfect smoothness
713 //______________________________________________________________________
717 // ******************************************************************
719 // * User routine to control tracking of one track *
721 // * ==>Called by : GTREVE *
723 // ******************************************************************
726 // ------------------------------------------------------------------
728 Int_t ndet = gAlice->Modules()->GetLast();
729 TObjArray &dets = *gAlice->Modules();
733 for(i=0; i<=ndet; i++)
734 if((module = (AliModule*)dets[i]))
739 for(i=0; i<=ndet; i++)
740 if((module = (AliModule*)dets[i]))
744 //______________________________________________________________________
748 // ******************************************************************
750 // * User routine to control tracking of one event *
752 // * ==>Called by : GTRIG *
754 // ******************************************************************
757 // ------------------------------------------------------------------
763 //______________________________________________________________________
764 void gufld(Float_t *x, Float_t *b)
766 if(gAlice->Field()) {
767 gAlice->Field()->Field(x,b);
769 printf("No mag field defined!\n");
774 //______________________________________________________________________
778 // ******************************************************************
780 // * User routine called at the end of each tracking step *
781 // * INWVOL is different from 0 when the track has reached *
782 // * a volume boundary *
783 // * ISTOP is different from 0 if the track has stopped *
785 // * ==>Called by : GTRACK *
787 // ******************************************************************
793 Int_t ipp, jk, id, nt;
794 Float_t polar[3]={0,0,0};
799 TGeant3* geant3 = (TGeant3*) gMC;
800 // Stop particle if outside user defined tracking region
801 gMC->TrackPosition(x);
802 r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
803 if (r > gAlice->TrackingRmax() || TMath::Abs(x[2]) > gAlice->TrackingZmax()) {
807 // --- Add new created particles
808 if (gMC->NSecondaries() > 0) {
809 kChproc=gMC->ProdProcess();
810 for (jk = 0; jk < geant3->Gcking()->ngkine; ++jk) {
811 ipp = Int_t (geant3->Gcking()->gkin[jk][4]+0.5);
812 // --- Skip neutrinos!
814 gAlice->SetTrack(1,gAlice->CurrentTrack(),gMC->PDGFromId(ipp), geant3->Gcking()->gkin[jk],
815 geant3->Gckin3()->gpos[jk], polar,geant3->Gctrak()->tofg, kChproc, nt);
819 // Cherenkov photons here
820 if ( geant3->Gckin2()->ngphot ) {
821 for (jk = 0; jk < geant3->Gckin2()->ngphot; ++jk) {
822 mom[0]=geant3->Gckin2()->xphot[jk][3]*geant3->Gckin2()->xphot[jk][6];
823 mom[1]=geant3->Gckin2()->xphot[jk][4]*geant3->Gckin2()->xphot[jk][6];
824 mom[2]=geant3->Gckin2()->xphot[jk][5]*geant3->Gckin2()->xphot[jk][6];
825 gAlice->SetTrack(1, gAlice->CurrentTrack(), gMC->PDGFromId(50),
827 geant3->Gckin2()->xphot[jk], //position
828 &geant3->Gckin2()->xphot[jk][7], //polarisation
829 geant3->Gckin2()->xphot[jk][10], //time of flight
833 // --- Particle leaving the setup ?
834 if (!gMC->IsTrackOut())
835 if ((id=gAlice->DetFromMate(geant3->Gctmed()->numed)) >= 0) gAlice->StepManager(id);
837 // --- Standard GEANT debug routine
838 if(geant3->Gcflag()->idebug) geant3->Gdebug();
841 //______________________________________________________________________
845 // ******************************************************************
847 // * Read or Generates Kinematics for primary tracks *
849 // * ==>Called by : GTRIG *
851 // ******************************************************************
854 // ------------------------------------------------------------------
856 gAlice->Generator()->Generate();
860 //______________________________________________________________________
864 // ******************************************************************
866 // * User routine called at the end of the run *
868 // * ==>Called by : GRUN *
870 // ******************************************************************