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