AliVMC and AliGeant3 classes introduced
[u/mrichter/AliRoot.git] / STEER / AliModule.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.7  1999/09/29 09:24:29  fca
19 Introduction of the Copyright and cvs Log
20
21 */
22
23 ///////////////////////////////////////////////////////////////////////////////
24 //                                                                           //
25 // Base class for ALICE modules. Both sensitive modules (Modules) and      //
26 // non-sensitive ones are described by this base class. This class           //
27 // supports the hit and digit trees produced by the simulation and also      //
28 // the objects produced by the reconstruction.                               //
29 //                                                                           //
30 // This class is also responsible for building the geometry of the           //
31 // Modules.                                                                //
32 //                                                                           //
33 //Begin_Html
34 /*
35 <img src="picts/AliModuleClass.gif">
36 */
37 //End_Html
38 //                                                                           //
39 ///////////////////////////////////////////////////////////////////////////////
40 #include "AliModule.h"
41 #include "AliRun.h"
42 #include "AliHit.h"
43 #include "AliPoints.h"
44 #include <TClass.h>
45 #include <TNode.h>
46 #include <TRandom.h>
47
48 ClassImp(AliModule)
49  
50 //_____________________________________________________________________________
51 AliModule::AliModule()
52 {
53   //
54   // Default constructor for the AliModule class
55   //
56   fHistograms = 0;
57   fNodes      = 0;
58 }
59  
60 //_____________________________________________________________________________
61 AliModule::AliModule(const char* name,const char *title):TNamed(name,title)
62 {
63   //
64   // Normal constructor invoked by all Modules.
65   // Create the list for Module specific histograms
66   // Add this Module to the global list of Modules in Run.
67   //
68   //
69   // Initialises the histogram list
70   fHistograms = new TList();
71   //
72   // Initialises the list of ROOT TNodes
73   fNodes      = new TList();
74   //  
75   // Get the Module numeric ID
76   Int_t id = gAlice->GetModuleID(name);
77   if (id>=0) {
78     // Module already added !
79      Warning("Ctor","Module: %s already present at %d\n",name,id);
80      return;
81   }
82   //
83   // Add this Module to the list of Modules
84   gAlice->Modules()->Add(this);
85   //
86   //
87   SetMarkerColor(3);
88   //
89   // Allocate space for tracking media and material indexes
90   fIdtmed = new TArrayI(100);
91   fIdmate  = new TArrayI(100);
92   for(Int_t i=0;i<100;i++) (*fIdmate)[i]=(*fIdtmed)[i]=0;
93   //
94   // Prepare to find the tracking media range
95   fLoMedium = 65536;
96   fHiMedium = 0;
97 }
98  
99 //_____________________________________________________________________________
100 AliModule::~AliModule()
101 {
102   //
103   // Destructor
104   //
105   fHistograms = 0;
106   //
107   // Delete ROOT geometry
108   fNodes->Clear();
109   delete fNodes;
110   //
111   // Delete TArray objects
112   delete fIdtmed;
113   delete fIdmate;
114 }
115  
116 //_____________________________________________________________________________
117 void AliModule::Disable()
118 {
119   //
120   // Disable Module on viewer
121   //
122   fActive = kFALSE;
123   TIter next(fNodes);
124   TNode *node;
125   //
126   // Loop through geometry to disable all
127   // nodes for this Module
128   while((node = (TNode*)next())) {
129     node->SetVisibility(0);
130   }   
131 }
132
133 //_____________________________________________________________________________
134 Int_t AliModule::DistancetoPrimitive(Int_t, Int_t)
135 {
136   //
137   // Return distance from mouse pointer to object
138   // Dummy routine for the moment
139   //
140   return 9999;
141 }
142
143 //_____________________________________________________________________________
144 void AliModule::Enable()
145 {
146   //
147   // Enable Module on the viewver
148   //
149   fActive = kTRUE;
150   TIter next(fNodes);
151   TNode *node;
152   //
153   // Loop through geometry to enable all
154   // nodes for this Module
155   while((node = (TNode*)next())) {
156     node->SetVisibility(1);
157   }   
158 }
159
160 //_____________________________________________________________________________
161 void AliModule::AliMaterial(Int_t imat, const char* name, Float_t a, 
162                               Float_t z, Float_t dens, Float_t radl,
163                               Float_t absl, Float_t *buf, Int_t nwbuf) const
164 {
165   //
166   // Store the parameters for a material
167   //
168   // imat        the material index will be stored in (*fIdmate)[imat]
169   // name        material name
170   // a           atomic mass
171   // z           atomic number
172   // dens        density
173   // radl        radiation length
174   // absl        absorbtion length
175   // buf         adress of an array user words
176   // nwbuf       number of user words
177   //
178   Int_t kmat;
179   gMC->Material(kmat, name, a, z, dens, radl, absl, buf, nwbuf);
180   (*fIdmate)[imat]=kmat;
181 }
182   
183 //_____________________________________________________________________________
184 void AliModule::AliGetMaterial(Int_t imat, char* name, Float_t &a, 
185                               Float_t &z, Float_t &dens, Float_t &radl,
186                               Float_t &absl)
187 {
188   //
189   // Store the parameters for a material
190   //
191   // imat        the material index will be stored in (*fIdmate)[imat]
192   // name        material name
193   // a           atomic mass
194   // z           atomic number
195   // dens        density
196   // radl        radiation length
197   // absl        absorbtion length
198   // buf         adress of an array user words
199   // nwbuf       number of user words
200   //
201
202   Float_t buf[10];
203   Int_t nwbuf, kmat;
204   kmat=(*fIdmate)[imat];
205   gMC->Gfmate(kmat, name, a, z, dens, radl, absl, buf, nwbuf);
206 }
207   
208
209 //_____________________________________________________________________________
210 void AliModule::AliMixture(Int_t imat, const char *name, Float_t *a,
211                              Float_t *z, Float_t dens, Int_t nlmat,
212                              Float_t *wmat) const
213
214   //
215   // Defines mixture or compound imat as composed by 
216   // nlmat materials defined by arrays a, z and wmat
217   // 
218   // If nlmat > 0 wmat contains the proportion by
219   // weights of each basic material in the mixture  
220   // 
221   // If nlmat < 0 wmat contains the number of atoms 
222   // of eack kind in the molecule of the compound
223   // In this case, wmat is changed on output to the relative weigths.
224   //
225   // imat        the material index will be stored in (*fIdmate)[imat]
226   // name        material name
227   // a           array of atomic masses
228   // z           array of atomic numbers
229   // dens        density
230   // nlmat       number of components
231   // wmat        array of concentrations
232   //
233   Int_t kmat;
234   gMC->Mixture(kmat, name, a, z, dens, nlmat, wmat);
235   (*fIdmate)[imat]=kmat;
236
237  
238 //_____________________________________________________________________________
239 void AliModule::AliMedium(Int_t numed, const char *name, Int_t nmat,
240                             Int_t isvol, Int_t ifield, Float_t fieldm,
241                             Float_t tmaxfd, Float_t stemax, Float_t deemax,
242                             Float_t epsil, Float_t stmin, Float_t *ubuf,
243                             Int_t nbuf) const
244
245   //
246   // Store the parameters of a tracking medium
247   //
248   // numed       the medium number is stored into (*fIdtmed)[numed]
249   // name        medium name
250   // nmat        the material number is stored into (*fIdmate)[nmat]
251   // isvol       sensitive volume if isvol!=0
252   // ifield      magnetic field flag (see below)
253   // fieldm      maximum magnetic field
254   // tmaxfd      maximum deflection angle due to magnetic field
255   // stemax      maximum step allowed
256   // deemax      maximum fractional energy loss in one step
257   // epsil       tracking precision in cm
258   // stmin       minimum step due to continuous processes
259   //
260   // ifield =  0       no magnetic field
261   //        = -1       user decision in guswim
262   //        =  1       tracking performed with Runge Kutta
263   //        =  2       tracking performed with helix
264   //        =  3       constant magnetic field along z
265   //  
266   Int_t kmed;
267   gMC->Medium(kmed,name, (*fIdmate)[nmat], isvol, ifield, fieldm,
268                          tmaxfd, stemax, deemax, epsil, stmin, ubuf, nbuf); 
269   (*fIdtmed)[numed]=kmed;
270
271  
272 //_____________________________________________________________________________
273 void AliModule::AliMatrix(Int_t &nmat, Float_t theta1, Float_t phi1,
274                             Float_t theta2, Float_t phi2, Float_t theta3,
275                             Float_t phi3) const
276 {
277   // 
278   // Define a rotation matrix. Angles are in degrees.
279   //
280   // nmat        on output contains the number assigned to the rotation matrix
281   // theta1      polar angle for axis I
282   // phi1        azimuthal angle for axis I
283   // theta2      polar angle for axis II
284   // phi2        azimuthal angle for axis II
285   // theta3      polar angle for axis III
286   // phi3        azimuthal angle for axis III
287   //
288   gMC->Matrix(nmat, theta1, phi1, theta2, phi2, theta3, phi3); 
289
290
291 //_____________________________________________________________________________
292 void AliModule::SetEuclidFile(char* material, char* geometry)
293 {
294   //
295   // Sets the name of the Euclid file
296   //
297   fEuclidMaterial=material;
298   if(geometry) {
299     fEuclidGeometry=geometry;
300   } else {
301     char* name = new char[strlen(material)];
302     strcpy(name,material);
303     strcpy(&name[strlen(name)-4],".euc");
304     fEuclidGeometry=name;
305     delete [] name;
306   }
307 }
308  
309 //_____________________________________________________________________________
310 void AliModule::ReadEuclid(const char* filnam, char* topvol)
311 {
312   //                                                                     
313   //       read in the geometry of the detector in euclid file format    
314   //                                                                     
315   //        id_det : the detector identification (2=its,...)            
316   //        topvol : return parameter describing the name of the top    
317   //        volume of geometry.                                          
318   //                                                                     
319   //            author : m. maire                                        
320   //                                                                     
321   //     28.07.98
322   //     several changes have been made by miroslav helbich
323   //     subroutine is rewrited to follow the new established way of memory
324   //     booking for tracking medias and rotation matrices.
325   //     all used tracking media have to be defined first, for this you can use
326   //     subroutine  greutmed.
327   //     top volume is searched as only volume not positioned into another 
328   //
329
330   Int_t i, nvol, iret, itmed, irot, numed, npar, ndiv, iaxe;
331   Int_t ndvmx, nr, flag;
332   char key[5], card[77], natmed[21];
333   char name[5], mother[5], shape[5], konly[5], volst[7000][5];
334   char *filtmp;
335   Float_t par[50];
336   Float_t teta1, phi1, teta2, phi2, teta3, phi3, orig, step;
337   Float_t xo, yo, zo;
338   const Int_t maxrot=5000;
339   Int_t idrot[maxrot],istop[7000];
340   FILE *lun;
341   //
342   // *** The input filnam name will be with extension '.euc'
343   filtmp=gSystem->ExpandPathName(filnam);
344   lun=fopen(filtmp,"r");
345   delete [] filtmp;
346   if(!lun) {
347     Error("ReadEuclid","Could not open file %s\n",filnam);
348     return;
349   }
350   //* --- definition of rotation matrix 0 ---  
351   TArrayI &idtmed = *fIdtmed;
352   for(i=1; i<maxrot; ++i) idrot[i]=-99;
353   idrot[0]=0;
354   nvol=0;
355  L10:
356   for(i=0;i<77;i++) card[i]=0;
357   iret=fscanf(lun,"%77[^\n]",card);
358   if(iret<=0) goto L20;
359   fscanf(lun,"%*c");
360   //*
361   strncpy(key,card,4);
362   key[4]='\0';
363   if (!strcmp(key,"TMED")) {
364     sscanf(&card[5],"%d '%[^']'",&itmed,natmed);
365     if( itmed<0 || itmed>=100 ) {
366       Error("ReadEuclid","TMED illegal medium number %d for %s\n",itmed,natmed);
367       exit(1);
368     }
369     //Pad the string with blanks
370     i=-1;
371     while(natmed[++i]);
372     while(i<20) natmed[i++]=' ';
373     natmed[i]='\0';
374     //
375     if( idtmed[itmed]<=0 ) {
376       Error("ReadEuclid","TMED undefined medium number %d for %s\n",itmed,natmed);
377       exit(1);
378     }
379     gMC->Gckmat(idtmed[itmed],natmed);
380     //*
381   } else if (!strcmp(key,"ROTM")) {
382     sscanf(&card[4],"%d %f %f %f %f %f %f",&irot,&teta1,&phi1,&teta2,&phi2,&teta3,&phi3);
383     if( irot<=0 || irot>=maxrot ) {
384       Error("ReadEuclid","ROTM rotation matrix number %d illegal\n",irot);
385       exit(1);
386     }
387     AliMatrix(idrot[irot],teta1,phi1,teta2,phi2,teta3,phi3);
388     //*
389   } else if (!strcmp(key,"VOLU")) {
390     sscanf(&card[5],"'%[^']' '%[^']' %d %d", name, shape, &numed, &npar);
391     if (npar>0) {
392       for(i=0;i<npar;i++) fscanf(lun,"%f",&par[i]);
393       fscanf(lun,"%*c");
394     }
395     gMC->Gsvolu( name, shape, idtmed[numed], par, npar);
396     //*     save the defined volumes
397     strcpy(volst[++nvol],name);
398     istop[nvol]=1;
399     //*
400   } else if (!strcmp(key,"DIVN")) {
401     sscanf(&card[5],"'%[^']' '%[^']' %d %d", name, mother, &ndiv, &iaxe);
402     gMC->Gsdvn  ( name, mother, ndiv, iaxe );
403     //*
404   } else if (!strcmp(key,"DVN2")) {
405     sscanf(&card[5],"'%[^']' '%[^']' %d %d %f %d",name, mother, &ndiv, &iaxe, &orig, &numed);
406     gMC->Gsdvn2( name, mother, ndiv, iaxe, orig,idtmed[numed]);
407     //*
408   } else if (!strcmp(key,"DIVT")) {
409     sscanf(&card[5],"'%[^']' '%[^']' %f %d %d %d", name, mother, &step, &iaxe, &numed, &ndvmx);
410     gMC->Gsdvt ( name, mother, step, iaxe, idtmed[numed], ndvmx);
411     //*
412   } else if (!strcmp(key,"DVT2")) {
413     sscanf(&card[5],"'%[^']' '%[^']' %f %d %f %d %d", name, mother, &step, &iaxe, &orig, &numed, &ndvmx);
414     gMC->Gsdvt2 ( name, mother, step, iaxe, orig, idtmed[numed], ndvmx );
415     //*
416   } else if (!strcmp(key,"POSI")) {
417     sscanf(&card[5],"'%[^']' %d '%[^']' %f %f %f %d '%[^']'", name, &nr, mother, &xo, &yo, &zo, &irot, konly);
418     if( irot<0 || irot>=maxrot ) {
419       Error("ReadEuclid","POSI %s#%d rotation matrix number %d illegal\n",name,nr,irot);
420       exit(1);
421     }
422     if( idrot[irot] == -99) {
423       Error("ReadEuclid","POSI %s#%d undefined matrix number %d\n",name,nr,irot);
424       exit(1);
425     }
426     //*** volume name cannot be the top volume
427     for(i=1;i<=nvol;i++) {
428       if (!strcmp(volst[i],name)) istop[i]=0;
429     }
430     //*
431     gMC->Gspos  ( name, nr, mother, xo, yo, zo, idrot[irot], konly );
432     //*
433   } else if (!strcmp(key,"POSP")) {
434     sscanf(&card[5],"'%[^']' %d '%[^']' %f %f %f %d '%[^']' %d", name, &nr, mother, &xo, &yo, &zo, &irot, konly, &npar);
435     if( irot<0 || irot>=maxrot ) {
436       Error("ReadEuclid","POSP %s#%d rotation matrix number %d illegal\n",name,nr,irot);
437       exit(1);
438     }
439     if( idrot[irot] == -99) {
440       Error("ReadEuclid","POSP %s#%d undefined matrix number %d\n",name,nr,irot);
441       exit(1);
442     }
443     if (npar > 0) {
444       for(i=0;i<npar;i++) fscanf(lun,"%f",&par[i]);
445       fscanf(lun,"%*c");
446     }
447     //*** volume name cannot be the top volume
448     for(i=1;i<=nvol;i++) {
449       if (!strcmp(volst[i],name)) istop[i]=0;
450     }
451     //*
452     gMC->Gsposp ( name, nr, mother, xo,yo,zo, idrot[irot], konly, par, npar);
453   }
454   //*
455   if (strcmp(key,"END")) goto L10;
456   //* find top volume in the geometry
457   flag=0;
458   for(i=1;i<=nvol;i++) {
459     if (istop[i] && flag) {
460       Warning("ReadEuclid"," %s is another possible top volume\n",volst[i]);
461     }
462     if (istop[i] && !flag) {
463       strcpy(topvol,volst[i]);
464       printf(" *** GREUCL *** volume %s taken as a top volume\n",topvol);
465       flag=1;
466     }
467   }
468   if (!flag) {
469     Warning("ReadEuclid","top volume not found\n");
470   }
471   fclose (lun);
472   //*
473   //*     commented out only for the not cernlib version
474   printf(" *** GREUCL *** file: %s is now read in\n",filnam);
475   //
476   return;
477   //*
478   L20:
479   Error("ReadEuclid","reading error or premature end of file\n");
480 }
481
482 //_____________________________________________________________________________
483 void AliModule::ReadEuclidMedia(const char* filnam)
484 {
485   //                                                                     
486   //       read in the materials and tracking media for the detector     
487   //                   in euclid file format                             
488   //                                                                     
489   //       filnam: name of the input file                                
490   //       id_det: id_det is the detector identification (2=its,...)     
491   //                                                                     
492   //            author : miroslav helbich                                
493   //
494   Float_t sxmgmx = gAlice->Field()->Max();
495   Int_t   isxfld = gAlice->Field()->Integ();
496   Int_t end, i, iret, itmed;
497   char key[5], card[130], natmed[21], namate[21];
498   Float_t ubuf[50];
499   char* filtmp;
500   FILE *lun;
501   Int_t imate;
502   Int_t nwbuf, isvol, ifield, nmat;
503   Float_t a, z, dens, radl, absl, fieldm, tmaxfd, stemax, deemax, epsil, stmin;
504   //
505   end=strlen(filnam);
506   for(i=0;i<end;i++) if(filnam[i]=='.') {
507     end=i;
508     break;
509   }
510   //
511   // *** The input filnam name will be with extension '.euc'
512   printf("The file name is %s\n",filnam); //Debug
513   filtmp=gSystem->ExpandPathName(filnam);
514   lun=fopen(filtmp,"r");
515   delete [] filtmp;
516   if(!lun) {
517     Warning("ReadEuclidMedia","Could not open file %s\n",filnam);
518     return;
519   }
520   //
521   // Retrieve Mag Field parameters
522   Int_t ISXFLD=gAlice->Field()->Integ();
523   Float_t SXMGMX=gAlice->Field()->Max();
524   //  TArrayI &idtmed = *fIdtmed;
525   //
526  L10:
527   for(i=0;i<130;i++) card[i]=0;
528   iret=fscanf(lun,"%4s %[^\n]",key,card);
529   if(iret<=0) goto L20;
530   fscanf(lun,"%*c");
531   //*
532   //* read material
533   if (!strcmp(key,"MATE")) {
534     sscanf(card,"%d '%[^']' %f %f %f %f %f %d",&imate,namate,&a,&z,&dens,&radl,&absl,&nwbuf);
535     if (nwbuf>0) for(i=0;i<nwbuf;i++) fscanf(lun,"%f",&ubuf[i]);
536     //Pad the string with blanks
537     i=-1;
538     while(namate[++i]);
539     while(i<20) namate[i++]=' ';
540     namate[i]='\0';
541     //
542     AliMaterial(imate,namate,a,z,dens,radl,absl,ubuf,nwbuf);
543     //* read tracking medium
544   } else if (!strcmp(key,"TMED")) {
545     sscanf(card,"%d '%[^']' %d %d %d %f %f %f %f %f %f %d",
546            &itmed,natmed,&nmat,&isvol,&ifield,&fieldm,&tmaxfd,
547            &stemax,&deemax,&epsil,&stmin,&nwbuf);
548     if (nwbuf>0) for(i=0;i<nwbuf;i++) fscanf(lun,"%f",&ubuf[i]);
549     if (ifield<0) ifield=isxfld;
550     if (fieldm<0) fieldm=sxmgmx;
551     //Pad the string with blanks
552     i=-1;
553     while(natmed[++i]);
554     while(i<20) natmed[i++]=' ';
555     natmed[i]='\0';
556     //
557     AliMedium(itmed,natmed,nmat,isvol,ISXFLD,SXMGMX,tmaxfd,
558                    stemax,deemax,epsil,stmin,ubuf,nwbuf);
559     //    (*fImedia)[idtmed[itmed]-1]=id_det;
560     //*
561   }
562   //*
563   if (strcmp(key,"END")) goto L10;
564   fclose (lun);
565   //*
566   //*     commented out only for the not cernlib version
567   Warning("ReadEuclidMedia","file: %s is now read in\n",filnam);
568   //*
569   return;
570   //*
571  L20:
572   Warning("ReadEuclidMedia","reading error or premature end of file\n");
573
574  
575 //_____________________________________________________________________________
576 void AliModule::Streamer(TBuffer &R__b)
577 {
578   //
579   // Stream an object of class Module.
580   //
581   if (R__b.IsReading()) {
582     Version_t R__v = R__b.ReadVersion(); if (R__v) { }
583     TNamed::Streamer(R__b);
584     TAttLine::Streamer(R__b);
585     TAttMarker::Streamer(R__b);
586     fEuclidMaterial.Streamer(R__b);
587     fEuclidGeometry.Streamer(R__b);
588     R__b >> fActive;
589     R__b >> fHistograms;
590     //
591     // Stream the pointers but not the TClonesArrays
592     R__b >> fNodes; // diff
593   } else {
594     R__b.WriteVersion(AliModule::IsA());
595     TNamed::Streamer(R__b);
596     TAttLine::Streamer(R__b);
597     TAttMarker::Streamer(R__b);
598     fEuclidMaterial.Streamer(R__b);
599     fEuclidGeometry.Streamer(R__b);
600     R__b << fActive;
601     R__b << fHistograms;
602     //
603     // Stream the pointers but not the TClonesArrays
604     R__b << fNodes; // diff
605   }
606 }
607