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.13 2000/11/30 07:12:54 alibrary
19 Introducing new Rndm and QA classes
21 Revision 1.12 2000/11/06 11:35:46 morsch
22 Call BuildGeometry() after Init() to be able to share common detector parameters.
24 Revision 1.11 2000/10/04 16:30:22 fca
25 Add include for exit()
27 Revision 1.10 2000/10/02 21:28:16 fca
28 Removal of useless dependecies via forward declarations
30 Revision 1.9 2000/09/12 14:36:17 morsch
31 In gudcay(): call ForceDecay() before Decay()
33 Revision 1.8 2000/09/06 14:56:34 morsch
34 gudcay() method implemented.
35 Decays are performed using the AliDecayer interface. The pointer to the instance of AliDecayer
36 is obtained from geant3 (will be gMC once it has been implemented for Geant4).
38 Revision 1.7 2000/07/13 16:19:10 fca
39 Mainly coding conventions + some small bug fixes
41 Revision 1.6 2000/07/11 18:24:59 fca
42 Coding convention corrections + few minor bug fixes
44 Revision 1.5 2000/05/20 14:49:48 fca
45 Call gdebug at the end of gustep
47 Revision 1.4 2000/04/26 10:17:32 fca
48 Changes in Lego for G4 compatibility
50 Revision 1.3 2000/04/07 11:12:35 fca
51 G4 compatibility changes
53 Revision 1.2 2000/02/29 19:11:17 fca
54 Move gucode into AliGeant3.cxx
56 Revision 1.1 2000/02/23 16:25:25 fca
57 AliVMC and AliGeant3 classes introduced
58 ReadEuclid moved from AliRun to AliModule
64 #include <TParticle.h>
66 #include "AliDecayer.h"
67 #include "AliGeant3.h"
70 #include "AliCallf77.h"
71 #include "AliModule.h"
73 #include "AliGenerator.h"
77 # define rxgtrak rxgtrak_
78 # define rxouth rxouth_
81 # define rxgtrak RXGTRAK
82 # define rxouth RXOUTH
87 AliGeant3::AliGeant3(const char *title) :
90 //____________________________________________________________________________
91 void AliGeant3::FinishGeometry()
94 // Finalise geometry construction
96 TGeant3::FinishGeometry();
97 //Create the color table
101 //____________________________________________________________________________
102 void AliGeant3::Init()
105 //=================Create Materials and geometry
107 TObjArray *modules = gAlice->Modules();
110 while((detector = (AliModule*)next())) {
111 // Initialise detector materials and geometry
112 detector->CreateMaterials();
113 detector->CreateGeometry();
115 detector->BuildGeometry();
118 //Terminate building of geometry
122 //____________________________________________________________________________
123 void AliGeant3::ProcessRun(Int_t nevent)
128 Int_t todo = TMath::Abs(nevent);
129 for (Int_t i=0; i<todo; i++) {
130 // Process one run (one run = one event)
131 gAlice->BeginEvent();
133 gAlice->FinishEvent();
137 //_____________________________________________________________________________
138 void AliGeant3::ProcessEvent()
148 //_____________________________________________________________________________
149 void AliGeant3::SetColors()
152 // Set the colors for all the volumes
153 // this is done sequentially for all volumes
154 // based on the number of their medium
157 Int_t jvolum=fGclink->jvolum;
158 //Int_t jtmed=fGclink->jtmed;
159 //Int_t jmate=fGclink->jmate;
160 Int_t nvolum=fGcnum->nvolum;
163 // Now for all the volumes
164 for(kv=1;kv<=nvolum;kv++) {
165 // Get the tracking medium
166 Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
168 //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
170 //Float_t z=fZq[fZlq[jmate-ima]+7];
172 //icol = Int_t(z)%6+2;
173 //icol = 17+Int_t(z*150./92.);
176 strncpy(name,(char*)&fZiq[jvolum+kv],4);
178 Gsatt(name,"COLO",icol);
182 //_____________________________________________________________________________
184 // Interfaces to Fortran
186 //_____________________________________________________________________________
188 extern "C" void type_of_call rxgtrak (Int_t &mtrack, Int_t &ipart, Float_t *pmom,
189 Float_t &e, Float_t *vpos, Float_t *polar,
193 // Fetches next track from the ROOT stack for transport. Called by the
194 // modified version of GTREVE.
196 // Track number in the ROOT stack. If MTRACK=0 no
197 // mtrack more tracks are left in the stack to be
199 // ipart Particle code in the GEANT conventions.
200 // pmom[3] Particle momentum in GeV/c
201 // e Particle energy in GeV
202 // vpos[3] Particle position
203 // tof Particle time of flight in seconds
206 gAlice->GetNextTrack(mtrack, pdg, pmom, e, vpos, polar, tof);
207 ipart = gMC->IdFromPDG(pdg);
211 //_____________________________________________________________________________
212 extern "C" void type_of_call rxouth ()
215 // Called by Gtreve at the end of each primary track
217 gAlice->FinishPrimary();
221 # define gudigi gudigi_
222 # define guhadr guhadr_
223 # define guout guout_
224 # define guphad guphad_
225 # define gudcay gudcay_
226 # define guiget guiget_
227 # define guinme guinme_
228 # define guinti guinti_
229 # define gunear gunear_
230 # define guskip guskip_
231 # define guview guview_
232 # define gupara gupara_
233 # define gudtim gudtim_
234 # define guplsh guplsh_
235 # define gutrev gutrev_
236 # define gutrak gutrak_
237 # define guswim guswim_
238 # define gufld gufld_
239 # define gustep gustep_
240 # define gukine gukine_
241 # define uglast uglast_
243 # define gheish gheish_
244 # define flufin flufin_
245 # define gfmfin gfmfin_
246 # define gpghei gpghei_
247 # define fldist fldist_
248 # define gfmdis gfmdis_
249 # define ghelx3 ghelx3_
250 # define ghelix ghelix_
251 # define grkuta grkuta_
252 # define gtrack gtrack_
253 # define gtreveroot gtreveroot_
254 # define glast glast_
257 # define gudigi GUDIGI
258 # define guhadr GUHADR
260 # define guphad GUPHAD
261 # define gudcay GUDCAY
262 # define guiget GUIGET
263 # define guinme GUINME
264 # define guinti GUINTI
265 # define gunear GUNEAR
266 # define guskip GUSKIP
267 # define guview GUVIEW
268 # define gupara GUPARA
269 # define gudtim GUDTIM
270 # define guplsh GUPLSH
271 # define gutrev GUTREV
272 # define gutrak GUTRAK
273 # define guswim GUSWIM
275 # define gustep GUSTEP
276 # define gukine GUKINE
277 # define uglast UGLAST
279 # define gheish GHEISH
280 # define flufin FLUFIN
281 # define gfmfin GFMFIN
282 # define gpghei GPGHEI
283 # define fldist FLDIST
284 # define gfmdis GFMDIS
285 # define ghelx3 GHELX3
286 # define ghelix GHELIX
287 # define grkuta GRKUTA
288 # define gtrack GTRACK
289 # define gtreveroot GTREVEROOT
294 extern "C" type_of_call void gheish();
295 extern "C" type_of_call void flufin();
296 extern "C" type_of_call void gfmfin();
297 extern "C" type_of_call void gpghei();
298 extern "C" type_of_call void fldist();
299 extern "C" type_of_call void gfmdis();
300 extern "C" type_of_call void ghelx3(Float_t&, Float_t&, Float_t*, Float_t*);
301 extern "C" type_of_call void ghelix(Float_t&, Float_t&, Float_t*, Float_t*);
302 extern "C" type_of_call void grkuta(Float_t&, Float_t&, Float_t*, Float_t*);
303 extern "C" type_of_call void gtrack();
304 extern "C" type_of_call void gtreveroot();
305 extern "C" type_of_call void glast();
307 extern "C" type_of_call {
309 //______________________________________________________________________
313 // ******************************************************************
315 // * User routine to digitize one event *
317 // * ==>Called by : GTRIG *
319 // ******************************************************************
324 //______________________________________________________________________
328 // ******************************************************************
330 // * User routine to generate one hadronic interaction *
332 // * ==>Called by : GTHADR,GTNEUT *
334 // ******************************************************************
337 // ------------------------------------------------------------------
339 TGeant3* geant3 = (TGeant3*) gMC;
340 Int_t ihadr=geant3->Gcphys()->ihadr;
341 if (ihadr<4) gheish();
342 else if (ihadr==4) flufin();
346 //______________________________________________________________________
350 // ******************************************************************
352 // * User routine called at the end of each event *
354 // * ==>Called by : GTRIG *
356 // ******************************************************************
359 // ------------------------------------------------------------------
363 //______________________________________________________________________
367 // ******************************************************************
369 // * User routine to compute Hadron. inter. probabilities *
371 // * ==>Called by : GTHADR,GTNEUT *
373 // ******************************************************************
376 // ------------------------------------------------------------------
378 TGeant3* geant3 = (TGeant3*) gMC;
379 Int_t ihadr=geant3->Gcphys()->ihadr;
380 if (ihadr<4) gpghei();
381 else if (ihadr==4) fldist();
385 //______________________________________________________________________
389 // ******************************************************************
391 // * User routine to decay particles *
393 // * ==>Called by : GDECAY *
395 // ******************************************************************
398 // ------------------------------------------------------------------
401 TGeant3* geant3=(TGeant3*) gMC;
403 gMC->Decayer()->ForceDecay();
405 // Initialize 4-momentum vector
406 Int_t ipart = geant3->Gckine()->ipart;
409 p[0]=geant3->Gctrak()->vect[3];
410 p[1]=geant3->Gctrak()->vect[4];
411 p[2]=geant3->Gctrak()->vect[5];
412 p[3]=geant3->Gctrak()->vect[6];
414 // Convert from geant to lund particle code
415 Int_t iplund=gMC->PDGFromId(ipart);
417 static TClonesArray *particles;
418 if(!particles) particles=new TClonesArray("TParticle",1000);
420 gMC->Decayer()->Decay(iplund, &p);
423 Int_t np = geant3->Decayer()->ImportParticles(particles);
426 for (Int_t i=0; i< np; i++)
428 TParticle * iparticle = (TParticle *) particles->At(i);
429 Int_t ks = iparticle->GetStatusCode();
430 // Final state particles only
431 if (ks < 1 || ks > 10) continue;
433 Int_t kf=iparticle->GetPdgCode();
434 if (kf==12 || kf ==-12) continue;
435 if (kf==14 || kf ==-14) continue;
436 if (kf==16 || kf ==-16) continue;
438 Int_t index=geant3->Gcking()->ngkine;
439 // Put particle on geant stack
442 (geant3->Gcking()->gkin[index][0]) = iparticle->Px();
443 (geant3->Gcking()->gkin[index][1]) = iparticle->Py();
444 (geant3->Gcking()->gkin[index][2]) = iparticle->Pz();
445 (geant3->Gcking()->gkin[index][3]) = iparticle->Energy();
446 Int_t ilu = gMC->IdFromPDG(kf);
449 (geant3->Gcking()->gkin[index][4]) = Float_t(ilu);
451 (geant3->Gckin3()->gpos[index][0]) = geant3->Gctrak()->vect[0];
452 (geant3->Gckin3()->gpos[index][1]) = geant3->Gctrak()->vect[1];
453 (geant3->Gckin3()->gpos[index][2]) = geant3->Gctrak()->vect[2];
454 // time of flight offset (mm)
455 (geant3->Gcking()->tofd[index]) = 0.;
456 // (geant3->Gcking()->tofd[index]) = iparticle->T()/(10*kSpeedOfLight);
457 // increase stack counter
458 (geant3->Gcking()->ngkine)=index+1;
462 //______________________________________________________________________
463 void guiget(Int_t&, Int_t&, Int_t&)
466 // ******************************************************************
468 // * User routine for interactive control of GEANT *
470 // * ==>Called by : <GXINT>, GINCOM *
472 // ******************************************************************
475 // ------------------------------------------------------------------
479 //______________________________________________________________________
480 void guinme(Float_t*, Int_t&, Float_t*, Int_t& IYES)
483 // **********************************************
485 // * USER ROUTINE TO PROVIDE GINME FUNCTION *
486 // * FOR ALL USER SHAPES IDENTIFIED BY THE *
487 // * SHAPE NUMBER SH. POINT IS GIVEN IN X *
488 // * THE PARAMETERS ARE GIVEN IN P. IYES IS *
489 // * RETURNED 1 IF POINT IS IN, 0 IF POINT *
490 // * IS OUT AND LESS THAN ZERO IF SHAPE *
491 // * NUMBER IS NOT SUPPORTED. *
493 // * ==>Called by : GINME *
495 // **********************************************
500 //______________________________________________________________________
504 // ******************************************************************
506 // * User routine for interactive version *
508 // * ==>Called by : <GXINT>, GINTRI *
510 // ******************************************************************
513 // ------------------------------------------------------------------
517 //______________________________________________________________________
518 void gunear(Int_t&, Int_t&, Float_t*, Int_t&)
521 // ******************************************************************
524 // * ISEARC to identify the given volume *
525 // * ICALL to identify the calling routine *
528 // * X coordinates (+direction for ICALL=2) *
529 // * JNEAR address of default list of neighbours *
530 // * (list to be overwriten by user) *
532 // * Called by : GFTRAC, GINVOL, GTMEDI, GTNEXT, GNEXT, GMEDIA *
534 // ******************************************************************
537 // ------------------------------------------------------------------
541 //______________________________________________________________________
542 void guskip(Int_t& ISKIP)
545 // ******************************************************************
547 // * User routine to skip unwanted tracks *
549 // * Called by : GSSTAK *
550 // * Author : F.Bruyant *
552 // ******************************************************************
555 // ------------------------------------------------------------------
560 //______________________________________________________________________
561 void guswim(Float_t& CHARGE, Float_t& STEP, Float_t* VECT, Float_t* VOUT)
564 // ******************************************************************
566 // * User routine to control tracking of one track *
567 // * in a magnetic field *
569 // * ==>Called by : GTELEC,GTHADR,GTMUON *
571 // ******************************************************************
574 // ------------------------------------------------------------------
576 TGeant3* geant3 = (TGeant3*) gMC;
577 Int_t ifield=geant3->Gctmed()->ifield;
578 Float_t fieldm=geant3->Gctmed()->fieldm;
581 Float_t fldcharge = fieldm*CHARGE;
582 ghelx3(fldcharge,STEP,VECT,VOUT);
584 else if (ifield==2) ghelix(CHARGE,STEP,VECT,VOUT);
585 else grkuta(CHARGE,STEP,VECT,VOUT);
588 //______________________________________________________________________
589 void guview(Int_t&, Int_t&, DEFCHARD, Int_t& DEFCHARL)
592 // ******************************************************************
594 // * User routine for interactive version *
596 // * ==>Called by : <GXINT>, GINC1 *
598 // ******************************************************************
601 // ------------------------------------------------------------------
605 //______________________________________________________________________
609 // ******************************************************************
611 // * User routine called every time a particle falls below *
612 // * parametrization threshold. This routine should create *
613 // * the parametrization stack, and, when this is full, *
614 // * parametrize the shower and track the geantinos. *
616 // * ==>Called by : GTRACK *
618 // ******************************************************************
621 // ------------------------------------------------------------------
625 //______________________________________________________________________
626 Float_t gudtim(Float_t&, Float_t&, Int_t&, Int_t&)
629 // ******************************************************************
631 // * User function called by GCDRIF to return drift time *
633 // * ==>Called by : GCDRIF *
635 // ******************************************************************
638 // ------------------------------------------------------------------
644 //______________________________________________________________________
645 Float_t guplsh(Int_t&, Int_t&)
648 // ******************************************************************
651 // * ==>Called by : GLISUR *
653 // ******************************************************************
656 // ------------------------------------------------------------------
659 //*** By default this defines perfect smoothness
663 //______________________________________________________________________
667 // ******************************************************************
669 // * User routine to control tracking of one track *
671 // * ==>Called by : GTREVE *
673 // ******************************************************************
676 // ------------------------------------------------------------------
685 //______________________________________________________________________
689 // ******************************************************************
691 // * User routine to control tracking of one event *
693 // * ==>Called by : GTRIG *
695 // ******************************************************************
698 // ------------------------------------------------------------------
704 //______________________________________________________________________
705 void gufld(Float_t *x, Float_t *b)
707 if(gAlice->Field()) {
708 gAlice->Field()->Field(x,b);
710 printf("No mag field defined!\n");
715 //______________________________________________________________________
719 // ******************************************************************
721 // * User routine called at the end of each tracking step *
722 // * INWVOL is different from 0 when the track has reached *
723 // * a volume boundary *
724 // * ISTOP is different from 0 if the track has stopped *
726 // * ==>Called by : GTRACK *
728 // ******************************************************************
734 Int_t ipp, jk, id, nt;
735 Float_t polar[3]={0,0,0};
740 TGeant3* geant3 = (TGeant3*) gMC;
741 // Stop particle if outside user defined tracking region
742 gMC->TrackPosition(x);
743 r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
744 if (r > gAlice->TrackingRmax() || TMath::Abs(x[2]) > gAlice->TrackingZmax()) {
748 // --- Add new created particles
749 if (gMC->NSecondaries() > 0) {
750 pProc=gMC->ProdProcess(0);
751 for (jk = 0; jk < geant3->Gcking()->ngkine; ++jk) {
752 ipp = Int_t (geant3->Gcking()->gkin[jk][4]+0.5);
753 // --- Skip neutrinos!
755 gAlice->SetTrack(1,gAlice->CurrentTrack(),gMC->PDGFromId(ipp), geant3->Gcking()->gkin[jk],
756 geant3->Gckin3()->gpos[jk], polar,geant3->Gctrak()->tofg, pProc, nt);
760 // Cherenkov photons here
761 if ( geant3->Gckin2()->ngphot ) {
762 for (jk = 0; jk < geant3->Gckin2()->ngphot; ++jk) {
763 mom[0]=geant3->Gckin2()->xphot[jk][3]*geant3->Gckin2()->xphot[jk][6];
764 mom[1]=geant3->Gckin2()->xphot[jk][4]*geant3->Gckin2()->xphot[jk][6];
765 mom[2]=geant3->Gckin2()->xphot[jk][5]*geant3->Gckin2()->xphot[jk][6];
766 gAlice->SetTrack(1, gAlice->CurrentTrack(), gMC->PDGFromId(50),
768 geant3->Gckin2()->xphot[jk], //position
769 &geant3->Gckin2()->xphot[jk][7], //polarisation
770 geant3->Gckin2()->xphot[jk][10], //time of flight
774 // --- Particle leaving the setup ?
775 if (!gMC->IsTrackOut())
776 if ((id=gAlice->DetFromMate(geant3->Gctmed()->numed)) >= 0) gAlice->StepManager(id);
778 // --- Standard GEANT debug routine
779 if(geant3->Gcflag()->idebug) geant3->Gdebug();
782 //______________________________________________________________________
786 // ******************************************************************
788 // * Read or Generates Kinematics for primary tracks *
790 // * ==>Called by : GTRIG *
792 // ******************************************************************
795 // ------------------------------------------------------------------
797 gAlice->Generator()->Generate();
801 //______________________________________________________________________
805 // ******************************************************************
807 // * User routine called at the end of the run *
809 // * ==>Called by : GRUN *
811 // ******************************************************************