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