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