Additional protection 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 <TClonesArray.h>
38 #include <TTree.h>
39 #include <TSystem.h>
40 #include <TDirectory.h>
41
42 #include "AliModule.h"
43 #include "AliRun.h"
44 #include "AliMagF.h"
45 #include "AliConfig.h"
46 #include "AliTrackReference.h"
47
48 ClassImp(AliModule)
49  
50 //_______________________________________________________________________
51 AliModule::AliModule():
52   fEuclidMaterial(""),
53   fEuclidGeometry(""),
54   fIdtmed(0),
55   fIdmate(0),
56   fLoMedium(0),
57   fHiMedium(0),
58   fActive(0),
59   fHistograms(0),
60   fNodes(0),
61   fDebug(0),
62   fEnable(1),
63   fTrackReferences(0),
64   fMaxIterTrackRef(0),
65   fCurrentIterTrackRef(0)
66 {
67   //
68   // Default constructor for the AliModule class
69   //
70 }
71  
72 //_______________________________________________________________________
73 AliModule::AliModule(const char* name,const char *title):
74   TNamed(name,title),
75   fEuclidMaterial(""),
76   fEuclidGeometry(""),
77   fIdtmed(new TArrayI(100)),
78   fIdmate(new TArrayI(100)),
79   fLoMedium(65536),
80   fHiMedium(0),
81   fActive(0),
82   fHistograms(new TList()),
83   fNodes(new TList()),
84   fDebug(0),
85   fEnable(1),
86   fTrackReferences(new TClonesArray("AliTrackReference", 100)),
87   fMaxIterTrackRef(0),
88   fCurrentIterTrackRef(0)
89 {
90   //
91   // Normal constructor invoked by all Modules.
92   // Create the list for Module specific histograms
93   // Add this Module to the global list of Modules in Run.
94   //
95   // Get the Module numeric ID
96   Int_t id = gAlice->GetModuleID(name);
97   if (id>=0) {
98     // Module already added !
99      Warning("Ctor","Module: %s already present at %d\n",name,id);
100      return;
101   }
102   //
103   // Add this Module to the list of Modules
104   gAlice->Modules()->Add(this);
105   //
106   //
107   SetMarkerColor(3);
108   //
109   // Clear space for tracking media and material indexes
110
111   for(Int_t i=0;i<100;i++) (*fIdmate)[i]=(*fIdtmed)[i]=0;
112
113   AliConfig::Instance()->Add(this);    
114     
115   SetDebug(gAlice->GetDebug());
116 }
117  
118 //_______________________________________________________________________
119 AliModule::AliModule(const AliModule &mod):
120   TNamed(mod),
121   TAttLine(mod),
122   TAttMarker(mod),
123   AliRndm(mod),
124   fEuclidMaterial(""),
125   fEuclidGeometry(""),
126   fIdtmed(0),
127   fIdmate(0),
128   fLoMedium(0),
129   fHiMedium(0),
130   fActive(0),
131   fHistograms(0),
132   fNodes(0),
133   fDebug(0),
134   fEnable(0),
135   fTrackReferences(0),
136   fMaxIterTrackRef(0),
137   fCurrentIterTrackRef(0)
138 {
139   //
140   // Copy constructor
141   //
142   mod.Copy(*this);
143 }
144
145 //_______________________________________________________________________
146 AliModule::~AliModule()
147 {
148   //
149   // Destructor
150   //
151
152   // Remove this Module from the list of Modules
153   if (gAlice) {
154     TObjArray * modules = gAlice->Modules();
155     if (modules) modules->Remove(this);
156   }
157   // Delete ROOT geometry
158   if(fNodes) {
159     fNodes->Clear();
160     delete fNodes;
161   }
162   //
163   // Delete TArray objects
164   delete fIdtmed;
165   delete fIdmate;
166 }
167  
168 //_______________________________________________________________________
169 void AliModule::Copy(AliModule & /* mod */) const
170 {
171   //
172   // Copy *this onto mod, not implemented for AliModule
173   //
174   Fatal("Copy","Not implemented!\n");
175 }
176
177 //_______________________________________________________________________
178 void AliModule::Disable()
179 {
180   //
181   // Disable Module on viewer
182   //
183   fActive = kFALSE;
184   TIter next(fNodes);
185   TNode *node;
186   //
187   // Loop through geometry to disable all
188   // nodes for this Module
189   while((node = dynamic_cast<TNode*>(next()))) {
190     node->SetVisibility(-1);
191   }   
192 }
193
194 //_______________________________________________________________________
195 Int_t AliModule::DistancetoPrimitive(Int_t, Int_t) const
196 {
197   //
198   // Return distance from mouse pointer to object
199   // Dummy routine for the moment
200   //
201   return 9999;
202 }
203
204 //_______________________________________________________________________
205 void AliModule::Enable()
206 {
207   //
208   // Enable Module on the viewver
209   //
210   fActive = kTRUE;
211   TIter next(fNodes);
212   TNode *node;
213   //
214   // Loop through geometry to enable all
215   // nodes for this Module
216   while((node = dynamic_cast<TNode*>(next()))) {
217     node->SetVisibility(3);
218   }   
219 }
220
221 //_______________________________________________________________________
222 void AliModule::AliMaterial(Int_t imat, const char* name, Float_t a, 
223                             Float_t z, Float_t dens, Float_t radl,
224                             Float_t absl, Float_t *buf, Int_t nwbuf) const
225 {
226   //
227   // Store the parameters for a material
228   //
229   // imat        the material index will be stored in (*fIdmate)[imat]
230   // name        material name
231   // a           atomic mass
232   // z           atomic number
233   // dens        density
234   // radl        radiation length
235   // absl        absorbtion length
236   // buf         adress of an array user words
237   // nwbuf       number of user words
238   //
239   Int_t kmat;
240   gMC->Material(kmat, name, a, z, dens, radl, absl, buf, nwbuf);
241   (*fIdmate)[imat]=kmat;
242 }
243   
244 //_______________________________________________________________________
245 void AliModule::AliGetMaterial(Int_t imat, char* name, Float_t &a, 
246                                Float_t &z, Float_t &dens, Float_t &radl,
247                                Float_t &absl) const
248 {
249   //
250   // Store the parameters for a material
251   //
252   // imat        the material index will be stored in (*fIdmate)[imat]
253   // name        material name
254   // a           atomic mass
255   // z           atomic number
256   // dens        density
257   // radl        radiation length
258   // absl        absorbtion length
259   // buf         adress of an array user words
260   // nwbuf       number of user words
261   //
262
263   Float_t buf[10];
264   Int_t nwbuf, kmat;
265   kmat=(*fIdmate)[imat];
266   gMC->Gfmate(kmat, name, a, z, dens, radl, absl, buf, nwbuf);
267 }
268   
269
270 //_______________________________________________________________________
271 void AliModule::AliMixture(Int_t imat, const char *name, Float_t *a,
272                            Float_t *z, Float_t dens, Int_t nlmat,
273                            Float_t *wmat) const
274
275   //
276   // Defines mixture or compound imat as composed by 
277   // nlmat materials defined by arrays a, z and wmat
278   // 
279   // If nlmat > 0 wmat contains the proportion by
280   // weights of each basic material in the mixture  
281   // 
282   // If nlmat < 0 wmat contains the number of atoms 
283   // of eack kind in the molecule of the compound
284   // In this case, wmat is changed on output to the relative weigths.
285   //
286   // imat        the material index will be stored in (*fIdmate)[imat]
287   // name        material name
288   // a           array of atomic masses
289   // z           array of atomic numbers
290   // dens        density
291   // nlmat       number of components
292   // wmat        array of concentrations
293   //
294   Int_t kmat;
295   gMC->Mixture(kmat, name, a, z, dens, nlmat, wmat);
296   (*fIdmate)[imat]=kmat;
297
298  
299 //_______________________________________________________________________
300 void AliModule::AliMedium(Int_t numed, const char *name, Int_t nmat,
301                           Int_t isvol, Int_t ifield, Float_t fieldm,
302                           Float_t tmaxfd, Float_t stemax, Float_t deemax,
303                           Float_t epsil, Float_t stmin, Float_t *ubuf,
304                           Int_t nbuf) const
305
306   //
307   // Store the parameters of a tracking medium
308   //
309   // numed       the medium number is stored into (*fIdtmed)[numed]
310   // name        medium name
311   // nmat        the material number is stored into (*fIdmate)[nmat]
312   // isvol       sensitive volume if isvol!=0
313   // ifield      magnetic field flag (see below)
314   // fieldm      maximum magnetic field
315   // tmaxfd      maximum deflection angle due to magnetic field
316   // stemax      maximum step allowed
317   // deemax      maximum fractional energy loss in one step
318   // epsil       tracking precision in cm
319   // stmin       minimum step due to continuous processes
320   //
321   // ifield =  0       no magnetic field
322   //        = -1       user decision in guswim
323   //        =  1       tracking performed with Runge Kutta
324   //        =  2       tracking performed with helix
325   //        =  3       constant magnetic field along z
326   //  
327   Int_t kmed;
328   gMC->Medium(kmed,name, (*fIdmate)[nmat], isvol, ifield, fieldm,
329                          tmaxfd, stemax, deemax, epsil, stmin, ubuf, nbuf); 
330   (*fIdtmed)[numed]=kmed;
331
332  
333 //_______________________________________________________________________
334 void AliModule::AliMatrix(Int_t &nmat, Float_t theta1, Float_t phi1,
335                           Float_t theta2, Float_t phi2, Float_t theta3,
336                           Float_t phi3) const
337 {
338   // 
339   // Define a rotation matrix. Angles are in degrees.
340   //
341   // nmat        on output contains the number assigned to the rotation matrix
342   // theta1      polar angle for axis I
343   // phi1        azimuthal angle for axis I
344   // theta2      polar angle for axis II
345   // phi2        azimuthal angle for axis II
346   // theta3      polar angle for axis III
347   // phi3        azimuthal angle for axis III
348   //
349   gMC->Matrix(nmat, theta1, phi1, theta2, phi2, theta3, phi3); 
350
351
352 //_______________________________________________________________________
353 Float_t AliModule::ZMin() const
354 {
355   return -500;
356 }
357
358 //_______________________________________________________________________
359 Float_t AliModule::ZMax() const
360 {
361   return 500;
362 }
363
364 //_______________________________________________________________________
365 void AliModule::SetEuclidFile(char* material, char* geometry)
366 {
367   //
368   // Sets the name of the Euclid file
369   //
370   fEuclidMaterial=material;
371   if(geometry) {
372     fEuclidGeometry=geometry;
373   } else {
374     char* name = new char[strlen(material)];
375     strcpy(name,material);
376     strcpy(&name[strlen(name)-4],".euc");
377     fEuclidGeometry=name;
378     delete [] name;
379   }
380 }
381  
382 //_______________________________________________________________________
383 void AliModule::ReadEuclid(const char* filnam, char* topvol)
384 {
385   //                                                                     
386   //       read in the geometry of the detector in euclid file format    
387   //                                                                     
388   //        id_det : the detector identification (2=its,...)            
389   //        topvol : return parameter describing the name of the top    
390   //        volume of geometry.                                          
391   //                                                                     
392   //            author : m. maire                                        
393   //                                                                     
394   //     28.07.98
395   //     several changes have been made by miroslav helbich
396   //     subroutine is rewrited to follow the new established way of memory
397   //     booking for tracking medias and rotation matrices.
398   //     all used tracking media have to be defined first, for this you can use
399   //     subroutine  greutmed.
400   //     top volume is searched as only volume not positioned into another 
401   //
402
403   Int_t i, nvol, iret, itmed, irot, numed, npar, ndiv, iaxe;
404   Int_t ndvmx, nr, flag;
405   char key[5], card[77], natmed[21];
406   char name[5], mother[5], shape[5], konly[5], volst[7000][5];
407   char *filtmp;
408   Float_t par[100];
409   Float_t teta1, phi1, teta2, phi2, teta3, phi3, orig, step;
410   Float_t xo, yo, zo;
411   const Int_t kMaxRot=5000;
412   Int_t idrot[kMaxRot],istop[7000];
413   FILE *lun;
414   //
415   // *** The input filnam name will be with extension '.euc'
416   filtmp=gSystem->ExpandPathName(filnam);
417   lun=fopen(filtmp,"r");
418   delete [] filtmp;
419   if(!lun) {
420     Error("ReadEuclid","Could not open file %s\n",filnam);
421     return;
422   }
423   //* --- definition of rotation matrix 0 ---  
424   TArrayI &idtmed = *fIdtmed;
425   for(i=1; i<kMaxRot; ++i) idrot[i]=-99;
426   idrot[0]=0;
427   nvol=0;
428  L10:
429   for(i=0;i<77;i++) card[i]=0;
430   iret=fscanf(lun,"%77[^\n]",card);
431   if(iret<=0) goto L20;
432   fscanf(lun,"%*c");
433   //*
434   strncpy(key,card,4);
435   key[4]='\0';
436   if (!strcmp(key,"TMED")) {
437     sscanf(&card[5],"%d '%[^']'",&itmed,natmed);
438     if( itmed<0 || itmed>=100 ) {
439       Error("ReadEuclid","TMED illegal medium number %d for %s\n",itmed,natmed);
440       exit(1);
441     }
442     //Pad the string with blanks
443     i=-1;
444     while(natmed[++i]);
445     while(i<20) natmed[i++]=' ';
446     natmed[i]='\0';
447     //
448     if( idtmed[itmed]<=0 ) {
449       Error("ReadEuclid","TMED undefined medium number %d for %s\n",itmed,natmed);
450       exit(1);
451     }
452     gMC->Gckmat(idtmed[itmed],natmed);
453     //*
454   } else if (!strcmp(key,"ROTM")) {
455     sscanf(&card[4],"%d %f %f %f %f %f %f",&irot,&teta1,&phi1,&teta2,&phi2,&teta3,&phi3);
456     if( irot<=0 || irot>=kMaxRot ) {
457       Error("ReadEuclid","ROTM rotation matrix number %d illegal\n",irot);
458       exit(1);
459     }
460     AliMatrix(idrot[irot],teta1,phi1,teta2,phi2,teta3,phi3);
461     //*
462   } else if (!strcmp(key,"VOLU")) {
463     sscanf(&card[5],"'%[^']' '%[^']' %d %d", name, shape, &numed, &npar);
464     if (npar>0) {
465       for(i=0;i<npar;i++) fscanf(lun,"%f",&par[i]);
466       fscanf(lun,"%*c");
467     }
468     gMC->Gsvolu( name, shape, idtmed[numed], par, npar);
469     //*     save the defined volumes
470     strcpy(volst[++nvol],name);
471     istop[nvol]=1;
472     //*
473   } else if (!strcmp(key,"DIVN")) {
474     sscanf(&card[5],"'%[^']' '%[^']' %d %d", name, mother, &ndiv, &iaxe);
475     gMC->Gsdvn  ( name, mother, ndiv, iaxe );
476     //*
477   } else if (!strcmp(key,"DVN2")) {
478     sscanf(&card[5],"'%[^']' '%[^']' %d %d %f %d",name, mother, &ndiv, &iaxe, &orig, &numed);
479     gMC->Gsdvn2( name, mother, ndiv, iaxe, orig,idtmed[numed]);
480     //*
481   } else if (!strcmp(key,"DIVT")) {
482     sscanf(&card[5],"'%[^']' '%[^']' %f %d %d %d", name, mother, &step, &iaxe, &numed, &ndvmx);
483     gMC->Gsdvt ( name, mother, step, iaxe, idtmed[numed], ndvmx);
484     //*
485   } else if (!strcmp(key,"DVT2")) {
486     sscanf(&card[5],"'%[^']' '%[^']' %f %d %f %d %d", name, mother, &step, &iaxe, &orig, &numed, &ndvmx);
487     gMC->Gsdvt2 ( name, mother, step, iaxe, orig, idtmed[numed], ndvmx );
488     //*
489   } else if (!strcmp(key,"POSI")) {
490     sscanf(&card[5],"'%[^']' %d '%[^']' %f %f %f %d '%[^']'", name, &nr, mother, &xo, &yo, &zo, &irot, konly);
491     if( irot<0 || irot>=kMaxRot ) {
492       Error("ReadEuclid","POSI %s#%d rotation matrix number %d illegal\n",name,nr,irot);
493       exit(1);
494     }
495     if( idrot[irot] == -99) {
496       Error("ReadEuclid","POSI %s#%d undefined matrix number %d\n",name,nr,irot);
497       exit(1);
498     }
499     //*** volume name cannot be the top volume
500     for(i=1;i<=nvol;i++) {
501       if (!strcmp(volst[i],name)) istop[i]=0;
502     }
503     //*
504     gMC->Gspos  ( name, nr, mother, xo, yo, zo, idrot[irot], konly );
505     //*
506   } else if (!strcmp(key,"POSP")) {
507     sscanf(&card[5],"'%[^']' %d '%[^']' %f %f %f %d '%[^']' %d", name, &nr, mother, &xo, &yo, &zo, &irot, konly, &npar);
508     if( irot<0 || irot>=kMaxRot ) {
509       Error("ReadEuclid","POSP %s#%d rotation matrix number %d illegal\n",name,nr,irot);
510       exit(1);
511     }
512     if( idrot[irot] == -99) {
513       Error("ReadEuclid","POSP %s#%d undefined matrix number %d\n",name,nr,irot);
514       exit(1);
515     }
516     if (npar > 0) {
517       for(i=0;i<npar;i++) fscanf(lun,"%f",&par[i]);
518       fscanf(lun,"%*c");
519     }
520     //*** volume name cannot be the top volume
521     for(i=1;i<=nvol;i++) {
522       if (!strcmp(volst[i],name)) istop[i]=0;
523     }
524     //*
525     gMC->Gsposp ( name, nr, mother, xo,yo,zo, idrot[irot], konly, par, npar);
526   }
527   //*
528   if (strcmp(key,"END")) goto L10;
529   //* find top volume in the geometry
530   flag=0;
531   for(i=1;i<=nvol;i++) {
532     if (istop[i] && flag) {
533       Warning("ReadEuclid"," %s is another possible top volume\n",volst[i]);
534     }
535     if (istop[i] && !flag) {
536       strcpy(topvol,volst[i]);
537       if(fDebug) printf("%s::ReadEuclid: volume %s taken as a top volume\n",ClassName(),topvol);
538       flag=1;
539     }
540   }
541   if (!flag) {
542     Warning("ReadEuclid","top volume not found\n");
543   }
544   fclose (lun);
545   //*
546   //*     commented out only for the not cernlib version
547   if(fDebug) printf("%s::ReadEuclid: file: %s is now read in\n",ClassName(),filnam);
548   //
549   return;
550   //*
551   L20:
552   Error("ReadEuclid","reading error or premature end of file\n");
553 }
554
555 //_______________________________________________________________________
556 void AliModule::ReadEuclidMedia(const char* filnam)
557 {
558   //                                                                     
559   //       read in the materials and tracking media for the detector     
560   //                   in euclid file format                             
561   //                                                                     
562   //       filnam: name of the input file                                
563   //       id_det: id_det is the detector identification (2=its,...)     
564   //                                                                     
565   //            author : miroslav helbich                                
566   //
567   Float_t sxmgmx = gAlice->Field()->Max();
568   Int_t   isxfld = gAlice->Field()->Integ();
569   Int_t end, i, iret, itmed;
570   char key[5], card[130], natmed[21], namate[21];
571   Float_t ubuf[50];
572   char* filtmp;
573   FILE *lun;
574   Int_t imate;
575   Int_t nwbuf, isvol, ifield, nmat;
576   Float_t a, z, dens, radl, absl, fieldm, tmaxfd, stemax, deemax, epsil, stmin;
577   //
578   end=strlen(filnam);
579   for(i=0;i<end;i++) if(filnam[i]=='.') {
580     end=i;
581     break;
582   }
583   //
584   // *** The input filnam name will be with extension '.euc'
585   if(fDebug) printf("%s::ReadEuclid: The file name is %s\n",ClassName(),filnam); //Debug
586   filtmp=gSystem->ExpandPathName(filnam);
587   lun=fopen(filtmp,"r");
588   delete [] filtmp;
589   if(!lun) {
590     Warning("ReadEuclidMedia","Could not open file %s\n",filnam);
591     return;
592   }
593   //
594   // Retrieve Mag Field parameters
595   Int_t globField=gAlice->Field()->Integ();
596   Float_t globMaxField=gAlice->Field()->Max();
597   //  TArrayI &idtmed = *fIdtmed;
598   //
599  L10:
600   for(i=0;i<130;i++) card[i]=0;
601   iret=fscanf(lun,"%4s %[^\n]",key,card);
602   if(iret<=0) goto L20;
603   fscanf(lun,"%*c");
604   //*
605   //* read material
606   if (!strcmp(key,"MATE")) {
607     sscanf(card,"%d '%[^']' %f %f %f %f %f %d",&imate,namate,&a,&z,&dens,&radl,&absl,&nwbuf);
608     if (nwbuf>0) for(i=0;i<nwbuf;i++) fscanf(lun,"%f",&ubuf[i]);
609     //Pad the string with blanks
610     i=-1;
611     while(namate[++i]);
612     while(i<20) namate[i++]=' ';
613     namate[i]='\0';
614     //
615     AliMaterial(imate,namate,a,z,dens,radl,absl,ubuf,nwbuf);
616     //* read tracking medium
617   } else if (!strcmp(key,"TMED")) {
618     sscanf(card,"%d '%[^']' %d %d %d %f %f %f %f %f %f %d",
619            &itmed,natmed,&nmat,&isvol,&ifield,&fieldm,&tmaxfd,
620            &stemax,&deemax,&epsil,&stmin,&nwbuf);
621     if (nwbuf>0) for(i=0;i<nwbuf;i++) fscanf(lun,"%f",&ubuf[i]);
622     if (ifield<0) ifield=isxfld;
623     if (fieldm<0) fieldm=sxmgmx;
624     //Pad the string with blanks
625     i=-1;
626     while(natmed[++i]);
627     while(i<20) natmed[i++]=' ';
628     natmed[i]='\0';
629     //
630     AliMedium(itmed,natmed,nmat,isvol,globField,globMaxField,tmaxfd,
631                    stemax,deemax,epsil,stmin,ubuf,nwbuf);
632     //    (*fImedia)[idtmed[itmed]-1]=id_det;
633     //*
634   }
635   //*
636   if (strcmp(key,"END")) goto L10;
637   fclose (lun);
638   //*
639   //*     commented out only for the not cernlib version
640   if(fDebug) printf("%s::ReadEuclidMedia: file %s is now read in\n",
641         ClassName(),filnam);
642   //*
643   return;
644   //*
645  L20:
646   Warning("ReadEuclidMedia","reading error or premature end of file\n");
647
648
649 //_______________________________________________________________________
650 void AliModule::RemapTrackReferencesIDs(Int_t *map)
651 {
652   // 
653   // Remapping track reference
654   // Called at finish primary
655   //
656   if (!fTrackReferences) return;
657   for (Int_t i=0;i<fTrackReferences->GetEntries();i++){
658     AliTrackReference * ref = dynamic_cast<AliTrackReference*>(fTrackReferences->UncheckedAt(i));
659     if (ref) {
660       Int_t newID = map[ref->GetTrack()];
661       if (newID>=0) ref->SetTrack(newID);
662       else ref->SetTrack(-1);
663       
664     }
665   }
666 }
667
668
669 //_______________________________________________________________________
670 AliTrackReference* AliModule::FirstTrackReference(Int_t track)
671 {
672   //
673   // Initialise the hit iterator
674   // Return the address of the first hit for track
675   // If track>=0 the track is read from disk
676   // while if track<0 the first hit of the current
677   // track is returned
678   // 
679   if(track>=0) {
680     gAlice->ResetTrackReferences();
681     gAlice->TreeTR()->GetEvent(track);
682   }
683   //
684   fMaxIterTrackRef     = fTrackReferences->GetEntriesFast();
685   fCurrentIterTrackRef = 0;
686   if(fMaxIterTrackRef) return dynamic_cast<AliTrackReference*>(fTrackReferences->UncheckedAt(0));
687   else            return 0;
688 }
689
690 //_______________________________________________________________________
691 AliTrackReference* AliModule::NextTrackReference()
692 {
693   //
694   // Return the next hit for the current track
695   //
696   if(fMaxIterTrackRef) {
697     if(++fCurrentIterTrackRef<fMaxIterTrackRef) 
698       return dynamic_cast<AliTrackReference*>(fTrackReferences->UncheckedAt(fCurrentIterTrackRef));
699     else        
700       return 0;
701   } else {
702     printf("* AliDetector::NextTrackReference * TrackReference  Iterator called without calling FistTrackReference before\n");
703     return 0;
704   }
705 }
706
707
708 //_______________________________________________________________________
709 void AliModule::ResetTrackReferences()
710 {
711   //
712   // Reset number of hits and the hits array
713   //
714   fMaxIterTrackRef   = 0;
715   if (fTrackReferences)   fTrackReferences->Clear();
716 }
717  
718  
719
720 void AliModule::SetTreeAddress()
721 {
722   //
723   // Set branch address for the Hits and Digits Trees
724   //
725     TBranch *branch;
726     char branchname[20];
727     sprintf(branchname,"%s",GetName());
728     // Branch address for track reference tree
729     TTree *treeTR = gAlice->TreeTR();
730     if (treeTR && fTrackReferences) {
731         branch = treeTR->GetBranch(branchname);
732         if (branch) branch->SetAddress(&fTrackReferences);
733     }
734 }
735
736 void  AliModule::AddTrackReference(Int_t label){
737   //
738   // add a trackrefernce to the list
739   if (!fTrackReferences) {
740     cerr<<"Container trackrefernce not active\n";
741     return;
742   }
743   Int_t nref = fTrackReferences->GetEntriesFast();
744   TClonesArray &lref = *fTrackReferences;
745   new(lref[nref]) AliTrackReference(label);
746 }
747
748
749 void AliModule::MakeBranchTR(Option_t *option, const char *file)
750
751     //
752     // Makes branch in treeTR
753     //  
754     char name[10];
755     sprintf(name,"%s",GetName());
756
757     if (GetDebug()>1)
758         printf("* MakeBranch * Making Branch %s \n",name);
759     
760     TDirectory *cwd = gDirectory;
761     TBranch *branch = 0;
762     TTree* tree = gAlice->TreeTR();
763     if (tree) {
764         branch = tree->Branch(name, &fTrackReferences, 1600);
765         if (file) {
766             char * outFile = new char[strlen(gAlice->GetBaseFile())+strlen(file)+2];
767             sprintf(outFile,"%s/%s",gAlice->GetBaseFile(),file);
768             branch->SetFile(outFile);
769             TIter next( branch->GetListOfBranches());
770             while ((branch=dynamic_cast<TBranch*>(next()))) {
771                 branch->SetFile(outFile);
772             } 
773             delete outFile;
774             
775             cwd->cd();
776             
777             if (GetDebug()>1)
778                 printf("* MakeBranch * Diverting Branch %s to file %s\n",name,file);
779         }
780     }
781 }