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