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