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