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