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.11 2000/10/04 16:30:22 fca
19 Add include for exit()
21 Revision 1.10 2000/10/02 21:28:16 fca
22 Removal of useless dependecies via forward declarations
24 Revision 1.9 2000/09/12 14:36:17 morsch
25 In gudcay(): call ForceDecay() before Decay()
27 Revision 1.8 2000/09/06 14:56:34 morsch
28 gudcay() method implemented.
29 Decays are performed using the AliDecayer interface. The pointer to the instance of AliDecayer
30 is obtained from geant3 (will be gMC once it has been implemented for Geant4).
32 Revision 1.7 2000/07/13 16:19:10 fca
33 Mainly coding conventions + some small bug fixes
35 Revision 1.6 2000/07/11 18:24:59 fca
36 Coding convention corrections + few minor bug fixes
38 Revision 1.5 2000/05/20 14:49:48 fca
39 Call gdebug at the end of gustep
41 Revision 1.4 2000/04/26 10:17:32 fca
42 Changes in Lego for G4 compatibility
44 Revision 1.3 2000/04/07 11:12:35 fca
45 G4 compatibility changes
47 Revision 1.2 2000/02/29 19:11:17 fca
48 Move gucode into AliGeant3.cxx
50 Revision 1.1 2000/02/23 16:25:25 fca
51 AliVMC and AliGeant3 classes introduced
52 ReadEuclid moved from AliRun to AliModule
58 #include <TParticle.h>
60 #include "AliDecayer.h"
61 #include "AliGeant3.h"
64 #include "AliCallf77.h"
65 #include "AliModule.h"
70 # define rxgtrak rxgtrak_
71 # define rxstrak rxstrak_
72 # define rxkeep rxkeep_
73 # define rxouth rxouth_
76 # define rxgtrak RXGTRAK
77 # define rxstrak RXSTRAK
78 # define rxkeep RXKEEP
79 # define rxouth RXOUTH
84 AliGeant3::AliGeant3(const char *title) :
87 //____________________________________________________________________________
88 void AliGeant3::FinishGeometry()
91 // Finalise geometry construction
93 TGeant3::FinishGeometry();
94 //Create the color table
98 //____________________________________________________________________________
99 void AliGeant3::Init()
102 //=================Create Materials and geometry
104 TObjArray *modules = gAlice->Modules();
107 while((detector = (AliModule*)next())) {
108 // Initialise detector materials and geometry
109 detector->CreateMaterials();
110 detector->CreateGeometry();
112 detector->BuildGeometry();
115 //Terminate building of geometry
119 //____________________________________________________________________________
120 void AliGeant3::ProcessRun(Int_t nevent)
125 Int_t todo = TMath::Abs(nevent);
126 for (Int_t i=0; i<todo; i++) {
127 // Process one run (one run = one event)
128 gAlice->BeginEvent();
130 gAlice->FinishEvent();
134 //_____________________________________________________________________________
135 void AliGeant3::ProcessEvent()
145 //_____________________________________________________________________________
146 void AliGeant3::SetColors()
149 // Set the colors for all the volumes
150 // this is done sequentially for all volumes
151 // based on the number of their medium
154 Int_t jvolum=fGclink->jvolum;
155 //Int_t jtmed=fGclink->jtmed;
156 //Int_t jmate=fGclink->jmate;
157 Int_t nvolum=fGcnum->nvolum;
160 // Now for all the volumes
161 for(kv=1;kv<=nvolum;kv++) {
162 // Get the tracking medium
163 Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
165 //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
167 //Float_t z=fZq[fZlq[jmate-ima]+7];
169 //icol = Int_t(z)%6+2;
170 //icol = 17+Int_t(z*150./92.);
173 strncpy(name,(char*)&fZiq[jvolum+kv],4);
175 Gsatt(name,"COLO",icol);
179 //_____________________________________________________________________________
181 // Interfaces to Fortran
183 //_____________________________________________________________________________
185 extern "C" void type_of_call rxgtrak (Int_t &mtrack, Int_t &ipart, Float_t *pmom,
186 Float_t &e, Float_t *vpos, Float_t *polar,
190 // Fetches next track from the ROOT stack for transport. Called by the
191 // modified version of GTREVE.
193 // Track number in the ROOT stack. If MTRACK=0 no
194 // mtrack more tracks are left in the stack to be
196 // ipart Particle code in the GEANT conventions.
197 // pmom[3] Particle momentum in GeV/c
198 // e Particle energy in GeV
199 // vpos[3] Particle position
200 // tof Particle time of flight in seconds
203 gAlice->GetNextTrack(mtrack, pdg, pmom, e, vpos, polar, tof);
204 ipart = gMC->IdFromPDG(pdg);
208 //_____________________________________________________________________________
209 extern "C" void type_of_call
211 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom,
212 Float_t *vpos, Float_t &tof, const char* cmech, Int_t &ntr, const int cmlen)
214 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom,
215 Float_t *vpos, Float_t &tof, const char* cmech, const int cmlen,
220 // Fetches next track from the ROOT stack for transport. Called by GUKINE
223 // Status of the track. If keep=0 the track is put
224 // keep on the ROOT stack but it is not fetched for
226 // parent Parent track. If parent=0 the track is a primary.
227 // In GUSTEP the routine is normally called to store
228 // secondaries generated by the current track whose
229 // ROOT stack number is MTRACK (common SCKINE.
230 // ipart Particle code in the GEANT conventions.
231 // pmom[3] Particle momentum in GeV/c
232 // vpos[3] Particle position
233 // tof Particle time of flight in seconds
235 // cmech (CHARACTER*10) Particle origin. This field is user
236 // defined and it is not used inside the GALICE code.
237 // ntr Number assigned to the particle in the ROOT stack.
240 Float_t polar[3]={0.,0.,0.};
241 for(int i=0; i<10 && i<cmlen; i++) mecha[i]=cmech[i];
243 Int_t pdg=gMC->PDGFromId(ipart);
244 gAlice->SetTrack(keep, parent-1, pdg, pmom, vpos, polar, tof, mecha, ntr);
248 //_____________________________________________________________________________
249 extern "C" void type_of_call rxkeep(const Int_t &n)
251 if( NULL==gAlice ) exit(1);
253 if( n<=0 || n>gAlice->Particles()->GetEntries() )
255 printf(" Bad index n=%d must be 0<n<=%d\n",
256 n,gAlice->Particles()->GetEntries());
260 ((TParticle*)(gAlice->Particles()->UncheckedAt(n-1)))->SetBit(kKeepBit);
263 //_____________________________________________________________________________
264 extern "C" void type_of_call rxouth ()
267 // Called by Gtreve at the end of each primary track
269 gAlice->FinishPrimary();
274 # define gudigi gudigi_
275 # define guhadr guhadr_
276 # define guout guout_
277 # define guphad guphad_
278 # define gudcay gudcay_
279 # define guiget guiget_
280 # define guinme guinme_
281 # define guinti guinti_
282 # define gunear gunear_
283 # define guskip guskip_
284 # define guview guview_
285 # define gupara gupara_
286 # define gudtim gudtim_
287 # define guplsh guplsh_
288 # define gutrev gutrev_
289 # define gutrak gutrak_
290 # define guswim guswim_
291 # define gufld gufld_
292 # define gustep gustep_
293 # define gukine gukine_
294 # define uglast uglast_
296 # define gheish gheish_
297 # define flufin flufin_
298 # define gfmfin gfmfin_
299 # define gpghei gpghei_
300 # define fldist fldist_
301 # define gfmdis gfmdis_
302 # define ghelx3 ghelx3_
303 # define ghelix ghelix_
304 # define grkuta grkuta_
305 # define gtrack gtrack_
306 # define gtreveroot gtreveroot_
307 # define glast glast_
310 # define gudigi GUDIGI
311 # define guhadr GUHADR
313 # define guphad GUPHAD
314 # define gudcay GUDCAY
315 # define guiget GUIGET
316 # define guinme GUINME
317 # define guinti GUINTI
318 # define gunear GUNEAR
319 # define guskip GUSKIP
320 # define guview GUVIEW
321 # define gupara GUPARA
322 # define gudtim GUDTIM
323 # define guplsh GUPLSH
324 # define gutrev GUTREV
325 # define gutrak GUTRAK
326 # define guswim GUSWIM
328 # define gustep GUSTEP
329 # define gukine GUKINE
330 # define uglast UGLAST
332 # define gheish GHEISH
333 # define flufin FLUFIN
334 # define gfmfin GFMFIN
335 # define gpghei GPGHEI
336 # define fldist FLDIST
337 # define gfmdis GFMDIS
338 # define ghelx3 GHELX3
339 # define ghelix GHELIX
340 # define grkuta GRKUTA
341 # define gtrack GTRACK
342 # define gtreveroot GTREVEROOT
347 extern "C" type_of_call void gheish();
348 extern "C" type_of_call void flufin();
349 extern "C" type_of_call void gfmfin();
350 extern "C" type_of_call void gpghei();
351 extern "C" type_of_call void fldist();
352 extern "C" type_of_call void gfmdis();
353 extern "C" type_of_call void ghelx3(Float_t&, Float_t&, Float_t*, Float_t*);
354 extern "C" type_of_call void ghelix(Float_t&, Float_t&, Float_t*, Float_t*);
355 extern "C" type_of_call void grkuta(Float_t&, Float_t&, Float_t*, Float_t*);
356 extern "C" type_of_call void gtrack();
357 extern "C" type_of_call void gtreveroot();
358 extern "C" type_of_call void glast();
360 extern "C" type_of_call {
362 //______________________________________________________________________
366 // ******************************************************************
368 // * User routine to digitize one event *
370 // * ==>Called by : GTRIG *
372 // ******************************************************************
377 //______________________________________________________________________
381 // ******************************************************************
383 // * User routine to generate one hadronic interaction *
385 // * ==>Called by : GTHADR,GTNEUT *
387 // ******************************************************************
390 // ------------------------------------------------------------------
392 TGeant3* geant3 = (TGeant3*) gMC;
393 Int_t ihadr=geant3->Gcphys()->ihadr;
394 if (ihadr<4) gheish();
395 else if (ihadr==4) flufin();
399 //______________________________________________________________________
403 // ******************************************************************
405 // * User routine called at the end of each event *
407 // * ==>Called by : GTRIG *
409 // ******************************************************************
412 // ------------------------------------------------------------------
416 //______________________________________________________________________
420 // ******************************************************************
422 // * User routine to compute Hadron. inter. probabilities *
424 // * ==>Called by : GTHADR,GTNEUT *
426 // ******************************************************************
429 // ------------------------------------------------------------------
431 TGeant3* geant3 = (TGeant3*) gMC;
432 Int_t ihadr=geant3->Gcphys()->ihadr;
433 if (ihadr<4) gpghei();
434 else if (ihadr==4) fldist();
438 //______________________________________________________________________
442 // ******************************************************************
444 // * User routine to decay particles *
446 // * ==>Called by : GDECAY *
448 // ******************************************************************
451 // ------------------------------------------------------------------
454 TGeant3* geant3=(TGeant3*) gMC;
456 gMC->Decayer()->ForceDecay();
458 // Initialize 4-momentum vector
459 Int_t ipart = geant3->Gckine()->ipart;
462 p[0]=geant3->Gctrak()->vect[3];
463 p[1]=geant3->Gctrak()->vect[4];
464 p[2]=geant3->Gctrak()->vect[5];
465 p[3]=geant3->Gctrak()->vect[6];
467 // Convert from geant to lund particle code
468 Int_t iplund=gMC->PDGFromId(ipart);
470 static TClonesArray *particles;
471 if(!particles) particles=new TClonesArray("TParticle",1000);
473 gMC->Decayer()->Decay(iplund, &p);
476 Int_t np = geant3->Decayer()->ImportParticles(particles);
479 for (Int_t i=0; i< np; i++)
481 TParticle * iparticle = (TParticle *) particles->At(i);
482 Int_t ks = iparticle->GetStatusCode();
483 // Final state particles only
484 if (ks < 1 || ks > 10) continue;
486 Int_t kf=iparticle->GetPdgCode();
487 if (kf==12 || kf ==-12) continue;
488 if (kf==14 || kf ==-14) continue;
489 if (kf==16 || kf ==-16) continue;
491 Int_t index=geant3->Gcking()->ngkine;
492 // Put particle on geant stack
495 (geant3->Gcking()->gkin[index][0]) = iparticle->Px();
496 (geant3->Gcking()->gkin[index][1]) = iparticle->Py();
497 (geant3->Gcking()->gkin[index][2]) = iparticle->Pz();
498 (geant3->Gcking()->gkin[index][3]) = iparticle->Energy();
499 Int_t ilu = gMC->IdFromPDG(kf);
502 (geant3->Gcking()->gkin[index][4]) = Float_t(ilu);
504 (geant3->Gckin3()->gpos[index][0]) = geant3->Gctrak()->vect[0];
505 (geant3->Gckin3()->gpos[index][1]) = geant3->Gctrak()->vect[1];
506 (geant3->Gckin3()->gpos[index][2]) = geant3->Gctrak()->vect[2];
507 // time of flight offset (mm)
508 (geant3->Gcking()->tofd[index]) = 0.;
509 // (geant3->Gcking()->tofd[index]) = iparticle->T()/(10*kSpeedOfLight);
510 // increase stack counter
511 (geant3->Gcking()->ngkine)=index+1;
515 //______________________________________________________________________
516 void guiget(Int_t&, Int_t&, Int_t&)
519 // ******************************************************************
521 // * User routine for interactive control of GEANT *
523 // * ==>Called by : <GXINT>, GINCOM *
525 // ******************************************************************
528 // ------------------------------------------------------------------
532 //______________________________________________________________________
533 void guinme(Float_t*, Int_t&, Float_t*, Int_t& IYES)
536 // **********************************************
538 // * USER ROUTINE TO PROVIDE GINME FUNCTION *
539 // * FOR ALL USER SHAPES IDENTIFIED BY THE *
540 // * SHAPE NUMBER SH. POINT IS GIVEN IN X *
541 // * THE PARAMETERS ARE GIVEN IN P. IYES IS *
542 // * RETURNED 1 IF POINT IS IN, 0 IF POINT *
543 // * IS OUT AND LESS THAN ZERO IF SHAPE *
544 // * NUMBER IS NOT SUPPORTED. *
546 // * ==>Called by : GINME *
548 // **********************************************
553 //______________________________________________________________________
557 // ******************************************************************
559 // * User routine for interactive version *
561 // * ==>Called by : <GXINT>, GINTRI *
563 // ******************************************************************
566 // ------------------------------------------------------------------
570 //______________________________________________________________________
571 void gunear(Int_t&, Int_t&, Float_t*, Int_t&)
574 // ******************************************************************
577 // * ISEARC to identify the given volume *
578 // * ICALL to identify the calling routine *
581 // * X coordinates (+direction for ICALL=2) *
582 // * JNEAR address of default list of neighbours *
583 // * (list to be overwriten by user) *
585 // * Called by : GFTRAC, GINVOL, GTMEDI, GTNEXT, GNEXT, GMEDIA *
587 // ******************************************************************
590 // ------------------------------------------------------------------
594 //______________________________________________________________________
595 void guskip(Int_t& ISKIP)
598 // ******************************************************************
600 // * User routine to skip unwanted tracks *
602 // * Called by : GSSTAK *
603 // * Author : F.Bruyant *
605 // ******************************************************************
608 // ------------------------------------------------------------------
613 //______________________________________________________________________
614 void guswim(Float_t& CHARGE, Float_t& STEP, Float_t* VECT, Float_t* VOUT)
617 // ******************************************************************
619 // * User routine to control tracking of one track *
620 // * in a magnetic field *
622 // * ==>Called by : GTELEC,GTHADR,GTMUON *
624 // ******************************************************************
627 // ------------------------------------------------------------------
629 TGeant3* geant3 = (TGeant3*) gMC;
630 Int_t ifield=geant3->Gctmed()->ifield;
631 Float_t fieldm=geant3->Gctmed()->fieldm;
634 Float_t fldcharge = fieldm*CHARGE;
635 ghelx3(fldcharge,STEP,VECT,VOUT);
637 else if (ifield==2) ghelix(CHARGE,STEP,VECT,VOUT);
638 else grkuta(CHARGE,STEP,VECT,VOUT);
641 //______________________________________________________________________
642 void guview(Int_t&, Int_t&, DEFCHARD, Int_t& DEFCHARL)
645 // ******************************************************************
647 // * User routine for interactive version *
649 // * ==>Called by : <GXINT>, GINC1 *
651 // ******************************************************************
654 // ------------------------------------------------------------------
658 //______________________________________________________________________
662 // ******************************************************************
664 // * User routine called every time a particle falls below *
665 // * parametrization threshold. This routine should create *
666 // * the parametrization stack, and, when this is full, *
667 // * parametrize the shower and track the geantinos. *
669 // * ==>Called by : GTRACK *
671 // ******************************************************************
674 // ------------------------------------------------------------------
678 //______________________________________________________________________
679 Float_t gudtim(Float_t&, Float_t&, Int_t&, Int_t&)
682 // ******************************************************************
684 // * User function called by GCDRIF to return drift time *
686 // * ==>Called by : GCDRIF *
688 // ******************************************************************
691 // ------------------------------------------------------------------
697 //______________________________________________________________________
698 Float_t guplsh(Int_t&, Int_t&)
701 // ******************************************************************
704 // * ==>Called by : GLISUR *
706 // ******************************************************************
709 // ------------------------------------------------------------------
712 //*** By default this defines perfect smoothness
716 //______________________________________________________________________
720 // ******************************************************************
722 // * User routine to control tracking of one track *
724 // * ==>Called by : GTREVE *
726 // ******************************************************************
729 // ------------------------------------------------------------------
731 Int_t ndet = gAlice->Modules()->GetLast();
732 TObjArray &dets = *gAlice->Modules();
736 for(i=0; i<=ndet; i++)
737 if((module = (AliModule*)dets[i]))
742 for(i=0; i<=ndet; i++)
743 if((module = (AliModule*)dets[i]))
747 //______________________________________________________________________
751 // ******************************************************************
753 // * User routine to control tracking of one event *
755 // * ==>Called by : GTRIG *
757 // ******************************************************************
760 // ------------------------------------------------------------------
766 //______________________________________________________________________
767 void gufld(Float_t *x, Float_t *b)
769 if(gAlice->Field()) {
770 gAlice->Field()->Field(x,b);
772 printf("No mag field defined!\n");
777 //______________________________________________________________________
781 // ******************************************************************
783 // * User routine called at the end of each tracking step *
784 // * INWVOL is different from 0 when the track has reached *
785 // * a volume boundary *
786 // * ISTOP is different from 0 if the track has stopped *
788 // * ==>Called by : GTRACK *
790 // ******************************************************************
796 Int_t ipp, jk, id, nt;
797 Float_t polar[3]={0,0,0};
802 TGeant3* geant3 = (TGeant3*) gMC;
803 // Stop particle if outside user defined tracking region
804 gMC->TrackPosition(x);
805 r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
806 if (r > gAlice->TrackingRmax() || TMath::Abs(x[2]) > gAlice->TrackingZmax()) {
810 // --- Add new created particles
811 if (gMC->NSecondaries() > 0) {
812 kChproc=gMC->ProdProcess();
813 for (jk = 0; jk < geant3->Gcking()->ngkine; ++jk) {
814 ipp = Int_t (geant3->Gcking()->gkin[jk][4]+0.5);
815 // --- Skip neutrinos!
817 gAlice->SetTrack(1,gAlice->CurrentTrack(),gMC->PDGFromId(ipp), geant3->Gcking()->gkin[jk],
818 geant3->Gckin3()->gpos[jk], polar,geant3->Gctrak()->tofg, kChproc, nt);
822 // Cherenkov photons here
823 if ( geant3->Gckin2()->ngphot ) {
824 for (jk = 0; jk < geant3->Gckin2()->ngphot; ++jk) {
825 mom[0]=geant3->Gckin2()->xphot[jk][3]*geant3->Gckin2()->xphot[jk][6];
826 mom[1]=geant3->Gckin2()->xphot[jk][4]*geant3->Gckin2()->xphot[jk][6];
827 mom[2]=geant3->Gckin2()->xphot[jk][5]*geant3->Gckin2()->xphot[jk][6];
828 gAlice->SetTrack(1, gAlice->CurrentTrack(), gMC->PDGFromId(50),
830 geant3->Gckin2()->xphot[jk], //position
831 &geant3->Gckin2()->xphot[jk][7], //polarisation
832 geant3->Gckin2()->xphot[jk][10], //time of flight
836 // --- Particle leaving the setup ?
837 if (!gMC->IsTrackOut())
838 if ((id=gAlice->DetFromMate(geant3->Gctmed()->numed)) >= 0) gAlice->StepManager(id);
840 // --- Standard GEANT debug routine
841 if(geant3->Gcflag()->idebug) geant3->Gdebug();
844 //______________________________________________________________________
848 // ******************************************************************
850 // * Read or Generates Kinematics for primary tracks *
852 // * ==>Called by : GTRIG *
854 // ******************************************************************
857 // ------------------------------------------------------------------
859 gAlice->Generator()->Generate();
863 //______________________________________________________________________
867 // ******************************************************************
869 // * User routine called at the end of the run *
871 // * ==>Called by : GRUN *
873 // ******************************************************************