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