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.9 2000/09/12 14:36:17 morsch
19 In gudcay(): call ForceDecay() before Decay()
21 Revision 1.8 2000/09/06 14:56:34 morsch
22 gudcay() method implemented.
23 Decays are performed using the AliDecayer interface. The pointer to the instance of AliDecayer
24 is obtained from geant3 (will be gMC once it has been implemented for Geant4).
26 Revision 1.7 2000/07/13 16:19:10 fca
27 Mainly coding conventions + some small bug fixes
29 Revision 1.6 2000/07/11 18:24:59 fca
30 Coding convention corrections + few minor bug fixes
32 Revision 1.5 2000/05/20 14:49:48 fca
33 Call gdebug at the end of gustep
35 Revision 1.4 2000/04/26 10:17:32 fca
36 Changes in Lego for G4 compatibility
38 Revision 1.3 2000/04/07 11:12:35 fca
39 G4 compatibility changes
41 Revision 1.2 2000/02/29 19:11:17 fca
42 Move gucode into AliGeant3.cxx
44 Revision 1.1 2000/02/23 16:25:25 fca
45 AliVMC and AliGeant3 classes introduced
46 ReadEuclid moved from AliRun to AliModule
50 #include <TParticle.h>
52 #include "AliDecayer.h"
53 #include "AliGeant3.h"
56 #include "AliCallf77.h"
57 #include "AliModule.h"
62 # define rxgtrak rxgtrak_
63 # define rxstrak rxstrak_
64 # define rxkeep rxkeep_
65 # define rxouth rxouth_
68 # define rxgtrak RXGTRAK
69 # define rxstrak RXSTRAK
70 # define rxkeep RXKEEP
71 # define rxouth RXOUTH
76 AliGeant3::AliGeant3(const char *title) :
79 //____________________________________________________________________________
80 void AliGeant3::FinishGeometry()
83 // Finalise geometry construction
85 TGeant3::FinishGeometry();
86 //Create the color table
90 //____________________________________________________________________________
91 void AliGeant3::Init()
94 //=================Create Materials and geometry
96 TObjArray *modules = gAlice->Modules();
99 while((detector = (AliModule*)next())) {
100 // Initialise detector materials and geometry
101 detector->CreateMaterials();
102 detector->CreateGeometry();
103 detector->BuildGeometry();
107 //Terminate building of geometry
111 //____________________________________________________________________________
112 void AliGeant3::ProcessRun(Int_t nevent)
117 Int_t todo = TMath::Abs(nevent);
118 for (Int_t i=0; i<todo; i++) {
119 // Process one run (one run = one event)
120 gAlice->BeginEvent();
122 gAlice->FinishEvent();
126 //_____________________________________________________________________________
127 void AliGeant3::ProcessEvent()
137 //_____________________________________________________________________________
138 void AliGeant3::SetColors()
141 // Set the colors for all the volumes
142 // this is done sequentially for all volumes
143 // based on the number of their medium
146 Int_t jvolum=fGclink->jvolum;
147 //Int_t jtmed=fGclink->jtmed;
148 //Int_t jmate=fGclink->jmate;
149 Int_t nvolum=fGcnum->nvolum;
152 // Now for all the volumes
153 for(kv=1;kv<=nvolum;kv++) {
154 // Get the tracking medium
155 Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
157 //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
159 //Float_t z=fZq[fZlq[jmate-ima]+7];
161 //icol = Int_t(z)%6+2;
162 //icol = 17+Int_t(z*150./92.);
165 strncpy(name,(char*)&fZiq[jvolum+kv],4);
167 Gsatt(name,"COLO",icol);
171 //_____________________________________________________________________________
173 // Interfaces to Fortran
175 //_____________________________________________________________________________
177 extern "C" void type_of_call rxgtrak (Int_t &mtrack, Int_t &ipart, Float_t *pmom,
178 Float_t &e, Float_t *vpos, Float_t *polar,
182 // Fetches next track from the ROOT stack for transport. Called by the
183 // modified version of GTREVE.
185 // Track number in the ROOT stack. If MTRACK=0 no
186 // mtrack more tracks are left in the stack to be
188 // ipart Particle code in the GEANT conventions.
189 // pmom[3] Particle momentum in GeV/c
190 // e Particle energy in GeV
191 // vpos[3] Particle position
192 // tof Particle time of flight in seconds
195 gAlice->GetNextTrack(mtrack, pdg, pmom, e, vpos, polar, tof);
196 ipart = gMC->IdFromPDG(pdg);
200 //_____________________________________________________________________________
201 extern "C" void type_of_call
203 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom,
204 Float_t *vpos, Float_t &tof, const char* cmech, Int_t &ntr, const int cmlen)
206 rxstrak (Int_t &keep, Int_t &parent, Int_t &ipart, Float_t *pmom,
207 Float_t *vpos, Float_t &tof, const char* cmech, const int cmlen,
212 // Fetches next track from the ROOT stack for transport. Called by GUKINE
215 // Status of the track. If keep=0 the track is put
216 // keep on the ROOT stack but it is not fetched for
218 // parent Parent track. If parent=0 the track is a primary.
219 // In GUSTEP the routine is normally called to store
220 // secondaries generated by the current track whose
221 // ROOT stack number is MTRACK (common SCKINE.
222 // ipart Particle code in the GEANT conventions.
223 // pmom[3] Particle momentum in GeV/c
224 // vpos[3] Particle position
225 // tof Particle time of flight in seconds
227 // cmech (CHARACTER*10) Particle origin. This field is user
228 // defined and it is not used inside the GALICE code.
229 // ntr Number assigned to the particle in the ROOT stack.
232 Float_t polar[3]={0.,0.,0.};
233 for(int i=0; i<10 && i<cmlen; i++) mecha[i]=cmech[i];
235 Int_t pdg=gMC->PDGFromId(ipart);
236 gAlice->SetTrack(keep, parent-1, pdg, pmom, vpos, polar, tof, mecha, ntr);
240 //_____________________________________________________________________________
241 extern "C" void type_of_call rxkeep(const Int_t &n)
243 if( NULL==gAlice ) exit(1);
245 if( n<=0 || n>gAlice->Particles()->GetEntries() )
247 printf(" Bad index n=%d must be 0<n<=%d\n",
248 n,gAlice->Particles()->GetEntries());
252 ((TParticle*)(gAlice->Particles()->UncheckedAt(n-1)))->SetBit(kKeepBit);
255 //_____________________________________________________________________________
256 extern "C" void type_of_call rxouth ()
259 // Called by Gtreve at the end of each primary track
261 gAlice->FinishPrimary();
266 # define gudigi gudigi_
267 # define guhadr guhadr_
268 # define guout guout_
269 # define guphad guphad_
270 # define gudcay gudcay_
271 # define guiget guiget_
272 # define guinme guinme_
273 # define guinti guinti_
274 # define gunear gunear_
275 # define guskip guskip_
276 # define guview guview_
277 # define gupara gupara_
278 # define gudtim gudtim_
279 # define guplsh guplsh_
280 # define gutrev gutrev_
281 # define gutrak gutrak_
282 # define guswim guswim_
283 # define gufld gufld_
284 # define gustep gustep_
285 # define gukine gukine_
286 # define uglast uglast_
288 # define gheish gheish_
289 # define flufin flufin_
290 # define gfmfin gfmfin_
291 # define gpghei gpghei_
292 # define fldist fldist_
293 # define gfmdis gfmdis_
294 # define ghelx3 ghelx3_
295 # define ghelix ghelix_
296 # define grkuta grkuta_
297 # define gtrack gtrack_
298 # define gtreveroot gtreveroot_
299 # define glast glast_
302 # define gudigi GUDIGI
303 # define guhadr GUHADR
305 # define guphad GUPHAD
306 # define gudcay GUDCAY
307 # define guiget GUIGET
308 # define guinme GUINME
309 # define guinti GUINTI
310 # define gunear GUNEAR
311 # define guskip GUSKIP
312 # define guview GUVIEW
313 # define gupara GUPARA
314 # define gudtim GUDTIM
315 # define guplsh GUPLSH
316 # define gutrev GUTREV
317 # define gutrak GUTRAK
318 # define guswim GUSWIM
320 # define gustep GUSTEP
321 # define gukine GUKINE
322 # define uglast UGLAST
324 # define gheish GHEISH
325 # define flufin FLUFIN
326 # define gfmfin GFMFIN
327 # define gpghei GPGHEI
328 # define fldist FLDIST
329 # define gfmdis GFMDIS
330 # define ghelx3 GHELX3
331 # define ghelix GHELIX
332 # define grkuta GRKUTA
333 # define gtrack GTRACK
334 # define gtreveroot GTREVEROOT
339 extern "C" type_of_call void gheish();
340 extern "C" type_of_call void flufin();
341 extern "C" type_of_call void gfmfin();
342 extern "C" type_of_call void gpghei();
343 extern "C" type_of_call void fldist();
344 extern "C" type_of_call void gfmdis();
345 extern "C" type_of_call void ghelx3(Float_t&, Float_t&, Float_t*, Float_t*);
346 extern "C" type_of_call void ghelix(Float_t&, Float_t&, Float_t*, Float_t*);
347 extern "C" type_of_call void grkuta(Float_t&, Float_t&, Float_t*, Float_t*);
348 extern "C" type_of_call void gtrack();
349 extern "C" type_of_call void gtreveroot();
350 extern "C" type_of_call void glast();
352 extern "C" type_of_call {
354 //______________________________________________________________________
358 // ******************************************************************
360 // * User routine to digitize one event *
362 // * ==>Called by : GTRIG *
364 // ******************************************************************
369 //______________________________________________________________________
373 // ******************************************************************
375 // * User routine to generate one hadronic interaction *
377 // * ==>Called by : GTHADR,GTNEUT *
379 // ******************************************************************
382 // ------------------------------------------------------------------
384 TGeant3* geant3 = (TGeant3*) gMC;
385 Int_t ihadr=geant3->Gcphys()->ihadr;
386 if (ihadr<4) gheish();
387 else if (ihadr==4) flufin();
391 //______________________________________________________________________
395 // ******************************************************************
397 // * User routine called at the end of each event *
399 // * ==>Called by : GTRIG *
401 // ******************************************************************
404 // ------------------------------------------------------------------
408 //______________________________________________________________________
412 // ******************************************************************
414 // * User routine to compute Hadron. inter. probabilities *
416 // * ==>Called by : GTHADR,GTNEUT *
418 // ******************************************************************
421 // ------------------------------------------------------------------
423 TGeant3* geant3 = (TGeant3*) gMC;
424 Int_t ihadr=geant3->Gcphys()->ihadr;
425 if (ihadr<4) gpghei();
426 else if (ihadr==4) fldist();
430 //______________________________________________________________________
434 // ******************************************************************
436 // * User routine to decay particles *
438 // * ==>Called by : GDECAY *
440 // ******************************************************************
443 // ------------------------------------------------------------------
446 TGeant3* geant3=(TGeant3*) gMC;
448 gMC->Decayer()->ForceDecay();
450 // Initialize 4-momentum vector
451 Int_t ipart = geant3->Gckine()->ipart;
454 p[0]=geant3->Gctrak()->vect[3];
455 p[1]=geant3->Gctrak()->vect[4];
456 p[2]=geant3->Gctrak()->vect[5];
457 p[3]=geant3->Gctrak()->vect[6];
459 // Convert from geant to lund particle code
460 Int_t iplund=gMC->PDGFromId(ipart);
462 static TClonesArray *particles;
463 if(!particles) particles=new TClonesArray("TParticle",1000);
465 gMC->Decayer()->Decay(iplund, &p);
468 Int_t np = geant3->Decayer()->ImportParticles(particles);
471 for (Int_t i=0; i< np; i++)
473 TParticle * iparticle = (TParticle *) particles->At(i);
474 Int_t ks = iparticle->GetStatusCode();
475 // Final state particles only
476 if (ks < 1 || ks > 10) continue;
478 Int_t kf=iparticle->GetPdgCode();
479 if (kf==12 || kf ==-12) continue;
480 if (kf==14 || kf ==-14) continue;
481 if (kf==16 || kf ==-16) continue;
483 Int_t index=geant3->Gcking()->ngkine;
484 // Put particle on geant stack
487 (geant3->Gcking()->gkin[index][0]) = iparticle->Px();
488 (geant3->Gcking()->gkin[index][1]) = iparticle->Py();
489 (geant3->Gcking()->gkin[index][2]) = iparticle->Pz();
490 (geant3->Gcking()->gkin[index][3]) = iparticle->Energy();
491 Int_t ilu = gMC->IdFromPDG(kf);
494 (geant3->Gcking()->gkin[index][4]) = Float_t(ilu);
496 (geant3->Gckin3()->gpos[index][0]) = geant3->Gctrak()->vect[0];
497 (geant3->Gckin3()->gpos[index][1]) = geant3->Gctrak()->vect[1];
498 (geant3->Gckin3()->gpos[index][2]) = geant3->Gctrak()->vect[2];
499 // time of flight offset (mm)
500 (geant3->Gcking()->tofd[index]) = 0.;
501 // (geant3->Gcking()->tofd[index]) = iparticle->T()/(10*kSpeedOfLight);
502 // increase stack counter
503 (geant3->Gcking()->ngkine)=index+1;
507 //______________________________________________________________________
508 void guiget(Int_t&, Int_t&, Int_t&)
511 // ******************************************************************
513 // * User routine for interactive control of GEANT *
515 // * ==>Called by : <GXINT>, GINCOM *
517 // ******************************************************************
520 // ------------------------------------------------------------------
524 //______________________________________________________________________
525 void guinme(Float_t*, Int_t&, Float_t*, Int_t& IYES)
528 // **********************************************
530 // * USER ROUTINE TO PROVIDE GINME FUNCTION *
531 // * FOR ALL USER SHAPES IDENTIFIED BY THE *
532 // * SHAPE NUMBER SH. POINT IS GIVEN IN X *
533 // * THE PARAMETERS ARE GIVEN IN P. IYES IS *
534 // * RETURNED 1 IF POINT IS IN, 0 IF POINT *
535 // * IS OUT AND LESS THAN ZERO IF SHAPE *
536 // * NUMBER IS NOT SUPPORTED. *
538 // * ==>Called by : GINME *
540 // **********************************************
545 //______________________________________________________________________
549 // ******************************************************************
551 // * User routine for interactive version *
553 // * ==>Called by : <GXINT>, GINTRI *
555 // ******************************************************************
558 // ------------------------------------------------------------------
562 //______________________________________________________________________
563 void gunear(Int_t&, Int_t&, Float_t*, Int_t&)
566 // ******************************************************************
569 // * ISEARC to identify the given volume *
570 // * ICALL to identify the calling routine *
573 // * X coordinates (+direction for ICALL=2) *
574 // * JNEAR address of default list of neighbours *
575 // * (list to be overwriten by user) *
577 // * Called by : GFTRAC, GINVOL, GTMEDI, GTNEXT, GNEXT, GMEDIA *
579 // ******************************************************************
582 // ------------------------------------------------------------------
586 //______________________________________________________________________
587 void guskip(Int_t& ISKIP)
590 // ******************************************************************
592 // * User routine to skip unwanted tracks *
594 // * Called by : GSSTAK *
595 // * Author : F.Bruyant *
597 // ******************************************************************
600 // ------------------------------------------------------------------
605 //______________________________________________________________________
606 void guswim(Float_t& CHARGE, Float_t& STEP, Float_t* VECT, Float_t* VOUT)
609 // ******************************************************************
611 // * User routine to control tracking of one track *
612 // * in a magnetic field *
614 // * ==>Called by : GTELEC,GTHADR,GTMUON *
616 // ******************************************************************
619 // ------------------------------------------------------------------
621 TGeant3* geant3 = (TGeant3*) gMC;
622 Int_t ifield=geant3->Gctmed()->ifield;
623 Float_t fieldm=geant3->Gctmed()->fieldm;
626 Float_t fldcharge = fieldm*CHARGE;
627 ghelx3(fldcharge,STEP,VECT,VOUT);
629 else if (ifield==2) ghelix(CHARGE,STEP,VECT,VOUT);
630 else grkuta(CHARGE,STEP,VECT,VOUT);
633 //______________________________________________________________________
634 void guview(Int_t&, Int_t&, DEFCHARD, Int_t& DEFCHARL)
637 // ******************************************************************
639 // * User routine for interactive version *
641 // * ==>Called by : <GXINT>, GINC1 *
643 // ******************************************************************
646 // ------------------------------------------------------------------
650 //______________________________________________________________________
654 // ******************************************************************
656 // * User routine called every time a particle falls below *
657 // * parametrization threshold. This routine should create *
658 // * the parametrization stack, and, when this is full, *
659 // * parametrize the shower and track the geantinos. *
661 // * ==>Called by : GTRACK *
663 // ******************************************************************
666 // ------------------------------------------------------------------
670 //______________________________________________________________________
671 Float_t gudtim(Float_t&, Float_t&, Int_t&, Int_t&)
674 // ******************************************************************
676 // * User function called by GCDRIF to return drift time *
678 // * ==>Called by : GCDRIF *
680 // ******************************************************************
683 // ------------------------------------------------------------------
689 //______________________________________________________________________
690 Float_t guplsh(Int_t&, Int_t&)
693 // ******************************************************************
696 // * ==>Called by : GLISUR *
698 // ******************************************************************
701 // ------------------------------------------------------------------
704 //*** By default this defines perfect smoothness
708 //______________________________________________________________________
712 // ******************************************************************
714 // * User routine to control tracking of one track *
716 // * ==>Called by : GTREVE *
718 // ******************************************************************
721 // ------------------------------------------------------------------
723 Int_t ndet = gAlice->Modules()->GetLast();
724 TObjArray &dets = *gAlice->Modules();
728 for(i=0; i<=ndet; i++)
729 if((module = (AliModule*)dets[i]))
734 for(i=0; i<=ndet; i++)
735 if((module = (AliModule*)dets[i]))
739 //______________________________________________________________________
743 // ******************************************************************
745 // * User routine to control tracking of one event *
747 // * ==>Called by : GTRIG *
749 // ******************************************************************
752 // ------------------------------------------------------------------
758 //______________________________________________________________________
759 void gufld(Float_t *x, Float_t *b)
761 if(gAlice->Field()) {
762 gAlice->Field()->Field(x,b);
764 printf("No mag field defined!\n");
769 //______________________________________________________________________
773 // ******************************************************************
775 // * User routine called at the end of each tracking step *
776 // * INWVOL is different from 0 when the track has reached *
777 // * a volume boundary *
778 // * ISTOP is different from 0 if the track has stopped *
780 // * ==>Called by : GTRACK *
782 // ******************************************************************
788 Int_t ipp, jk, id, nt;
789 Float_t polar[3]={0,0,0};
794 TGeant3* geant3 = (TGeant3*) gMC;
795 // Stop particle if outside user defined tracking region
796 gMC->TrackPosition(x);
797 r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
798 if (r > gAlice->TrackingRmax() || TMath::Abs(x[2]) > gAlice->TrackingZmax()) {
802 // --- Add new created particles
803 if (gMC->NSecondaries() > 0) {
804 kChproc=gMC->ProdProcess();
805 for (jk = 0; jk < geant3->Gcking()->ngkine; ++jk) {
806 ipp = Int_t (geant3->Gcking()->gkin[jk][4]+0.5);
807 // --- Skip neutrinos!
809 gAlice->SetTrack(1,gAlice->CurrentTrack(),gMC->PDGFromId(ipp), geant3->Gcking()->gkin[jk],
810 geant3->Gckin3()->gpos[jk], polar,geant3->Gctrak()->tofg, kChproc, nt);
814 // Cherenkov photons here
815 if ( geant3->Gckin2()->ngphot ) {
816 for (jk = 0; jk < geant3->Gckin2()->ngphot; ++jk) {
817 mom[0]=geant3->Gckin2()->xphot[jk][3]*geant3->Gckin2()->xphot[jk][6];
818 mom[1]=geant3->Gckin2()->xphot[jk][4]*geant3->Gckin2()->xphot[jk][6];
819 mom[2]=geant3->Gckin2()->xphot[jk][5]*geant3->Gckin2()->xphot[jk][6];
820 gAlice->SetTrack(1, gAlice->CurrentTrack(), gMC->PDGFromId(50),
822 geant3->Gckin2()->xphot[jk], //position
823 &geant3->Gckin2()->xphot[jk][7], //polarisation
824 geant3->Gckin2()->xphot[jk][10], //time of flight
828 // --- Particle leaving the setup ?
829 if (!gMC->IsTrackOut())
830 if ((id=gAlice->DetFromMate(geant3->Gctmed()->numed)) >= 0) gAlice->StepManager(id);
832 // --- Standard GEANT debug routine
833 if(geant3->Gcflag()->idebug) geant3->Gdebug();
836 //______________________________________________________________________
840 // ******************************************************************
842 // * Read or Generates Kinematics for primary tracks *
844 // * ==>Called by : GTRIG *
846 // ******************************************************************
849 // ------------------------------------------------------------------
851 gAlice->Generator()->Generate();
855 //______________________________________________________________________
859 // ******************************************************************
861 // * User routine called at the end of the run *
863 // * ==>Called by : GRUN *
865 // ******************************************************************