1a23486c8eef49d845ed907f5c21743a4e8a1c3b
[u/mrichter/AliRoot.git] / MFT / AliMFT.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 //
18 //      Main class of the ALICE Muon Forward Tracker
19 //
20 //      Contact author: antonio.uras@cern.ch
21 //
22 //====================================================================================================================================================
23
24 #include "AliLog.h"
25 #include "TFile.h"  
26 #include "TGeoManager.h"    
27 #include "TGeoVolume.h"
28 #include "TGeoMatrix.h"
29 #include "TVirtualMC.h"
30 #include "TClonesArray.h"
31 #include "TGeoGlobalMagField.h"
32 #include "AliRun.h"
33 #include "AliLoader.h"
34 #include "AliDetector.h"
35 #include "AliMC.h"
36 #include "AliMagF.h"
37 #include "AliMFT.h"
38 #include "AliMFTHit.h"
39 #include "AliMFTDigit.h"
40 #include "AliMFTCluster.h"
41 #include "AliTrackReference.h"
42 #include "AliMFTSegmentation.h"
43 #include "AliMFTDigitizer.h"
44 #include "AliMFTPlane.h"
45 #include "TString.h"
46 #include "TObjArray.h"
47
48 ClassImp(AliMFT) 
49
50 //====================================================================================================================================================
51
52 AliMFT::AliMFT():
53   AliDetector(),
54   fVersion(1),
55   fNPlanes(0),
56   fNSlices(0),
57   fSDigitsPerPlane(0),
58   fDigitsPerPlane(0),
59   fRecPointsPerPlane(0),
60   fSideDigits(0),
61   fSegmentation(0),
62   fNameGeomFile(0),
63   fChargeDispersion(0),
64   fSingleStepForChargeDispersion(0),
65   fNStepForChargeDispersion(0),
66   fDensitySiOverSupport(10)
67 {
68
69   // default constructor
70
71 }
72
73 //====================================================================================================================================================
74
75 AliMFT::AliMFT(const Char_t *name, const Char_t *title):
76   AliDetector(name, title),
77   fVersion(1),
78   fNPlanes(0),
79   fNSlices(0),
80   fSDigitsPerPlane(0),
81   fDigitsPerPlane(0),
82   fRecPointsPerPlane(0),
83   fSideDigits(0),
84   fSegmentation(0),
85   fNameGeomFile(0),
86   fChargeDispersion(0),
87   fSingleStepForChargeDispersion(0),
88   fNStepForChargeDispersion(0),
89   fDensitySiOverSupport(10)
90 {
91
92   fNameGeomFile = "AliMFTGeometry.root";
93
94   SetGeometry();
95
96   Init();
97
98 }
99
100 //====================================================================================================================================================
101
102 AliMFT::AliMFT(const Char_t *name, const Char_t *title, Char_t *nameGeomFile):
103   AliDetector(name, title),
104   fVersion(1),
105   fNPlanes(0),
106   fNSlices(0),
107   fSDigitsPerPlane(0),
108   fDigitsPerPlane(0),
109   fRecPointsPerPlane(0),
110   fSideDigits(0),
111   fSegmentation(0),
112   fNameGeomFile(0),
113   fChargeDispersion(0),
114   fSingleStepForChargeDispersion(0),
115   fNStepForChargeDispersion(0),
116   fDensitySiOverSupport(10)
117 {
118
119   fNameGeomFile = nameGeomFile;
120
121   SetGeometry();
122
123   Init();
124
125 }
126
127 //====================================================================================================================================================
128
129 AliMFT::~AliMFT() {
130
131   if (fSDigitsPerPlane)   { fSDigitsPerPlane->Delete();    delete fSDigitsPerPlane;   }
132   if (fDigitsPerPlane)    { fDigitsPerPlane->Delete();     delete fDigitsPerPlane;    }
133   if (fRecPointsPerPlane) { fRecPointsPerPlane->Delete();  delete fRecPointsPerPlane; }
134
135 }
136
137 //====================================================================================================================================================
138
139 void AliMFT::CreateMaterials() {
140
141   // Definition of MFT materials  - to be updated to the most recent values
142
143   AliInfo("Start MFT materials");
144
145   // data from PDG booklet 2002     density [gr/cm^3] rad len [cm] abs len [cm]    
146   Float_t   aAir[4]={12,14,16,36} ,   zAir[4]={6,7,8,18} ,   wAir[4]={0.000124,0.755267,0.231781,0.012827} , dAir=0.00120479; Int_t nAir=4;   // Air mixture
147   Float_t   aSi = 28.085 ,            zSi   = 14 ,           dSi   =  2.329    ,   radSi   =  21.82/dSi , absSi   = 108.4/dSi  ;              // Silicon
148
149   Int_t   matId  = 0;                        // tmp material id number
150   Int_t   unsens = 0, sens=1;                // sensitive or unsensitive medium
151   Int_t   itgfld = 3;                        // type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z
152   Float_t maxfld = 5.;                       // max field value
153
154   Float_t tmaxfd = -10.0;                    // max deflection angle due to magnetic field in one step
155   Float_t stemax =  0.001;                   // max step allowed [cm]
156   Float_t deemax = -0.2;                     // maximum fractional energy loss in one step 0<deemax<=1  
157   Float_t epsil  =  0.001;                   // tracking precision [cm]   
158   Float_t stmin  = -0.001;                   // minimum step due to continuous processes [cm] (negative value: choose it automatically)
159
160   Float_t tmaxfdSi =  0.1;                    // max deflection angle due to magnetic field in one step
161   Float_t stemaxSi =  5.0e-4;                 // maximum step allowed [cm]
162   Float_t deemaxSi =  0.1;                    // maximum fractional energy loss in one step 0<deemax<=1
163   Float_t epsilSi  =  0.5e-4;                 // tracking precision [cm]
164   Float_t stminSi  = -0.001;                 // minimum step due to continuous processes [cm] (negative value: choose it automatically)
165
166   Int_t   isxfld = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();   // from CreateMaterials in STRUCT/AliPIPEv3.cxx
167   Float_t sxmgmx = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();     // from CreateMaterials in STRUCT/AliPIPEv3.cxx
168       
169   AliMixture(++matId,"Air", aAir,  zAir,   dAir,   nAir,   wAir); 
170   AliMedium(kAir,    "Air", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
171   
172   AliMaterial(++matId, "Si", aSi,   zSi,  dSi,    radSi,  absSi  );  
173   AliMedium(kSi,       "Si", matId, sens, isxfld, sxmgmx, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
174
175   AliMaterial(++matId, "Readout", aSi,   zSi,    dSi,    radSi,  absSi  );  
176   AliMedium(kReadout,  "Readout", matId, unsens, isxfld, sxmgmx, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
177
178   AliMaterial(++matId, "Support", aSi,   zSi,    dSi/fDensitySiOverSupport, fDensitySiOverSupport*radSi, fDensitySiOverSupport*absSi);  
179   AliMedium(kSupport,  "Support", matId, unsens, isxfld,  sxmgmx,    tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
180     
181   AliInfo("End MFT materials");
182           
183 }
184
185 //====================================================================================================================================================
186
187 void AliMFT::CreateGeometry() {
188
189   // Creates detailed geometry simulation (currently GEANT volumes tree)        
190
191   AliInfo("Start MFT preliminary version building");
192   if(!gMC->IsRootGeometrySupported()) return;                
193   TGeoVolumeAssembly *vol = CreateVol();
194   AliInfo("TGeoVolumeAssembly created!");
195   gGeoManager->GetVolume("ALIC")->AddNode(vol,0);
196   AliInfo("Stop MFT preliminary version building");
197
198   if (fNStepForChargeDispersion) fSingleStepForChargeDispersion = fChargeDispersion/Double_t(fNStepForChargeDispersion);
199
200
201
202 //====================================================================================================================================================
203
204 void AliMFT::StepManager() {
205
206   // Full Step Manager
207
208   if (!fSegmentation) AliFatal("No segmentation available");    // DO WE HAVE A SEGMENTATION???
209
210   if (!(this->IsActive())) return;
211   if (!(gMC->TrackCharge())) return;
212
213   TString planeNumber   = gMC->CurrentVolName();
214   TString detElemNumber = gMC->CurrentVolName();
215   if (planeNumber.Contains("support")) return;
216   if (planeNumber.Contains("readout")) return;
217   planeNumber.Remove(0,9);
218   detElemNumber.Remove(0,19);
219   planeNumber.Remove(2);
220   detElemNumber.Remove(3);
221   Int_t detElemID = fSegmentation->GetDetElemID(planeNumber.Atoi(), detElemNumber.Atoi());
222
223   if (gMC->IsTrackExiting()) {
224     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kMFT);
225   }
226
227   static TLorentzVector position, momentum;
228   static AliMFTHit hit;
229   
230   Int_t  status = 0;
231   
232   // Track status
233   if (gMC->IsTrackInside())      status +=  1;
234   if (gMC->IsTrackEntering())    status +=  2;
235   if (gMC->IsTrackExiting())     status +=  4;
236   if (gMC->IsTrackOut())         status +=  8;
237   if (gMC->IsTrackDisappeared()) status += 16;
238   if (gMC->IsTrackStop())        status += 32;
239   if (gMC->IsTrackAlive())       status += 64;
240
241   // ---------- Fill hit structure
242
243   hit.SetDetElemID(detElemID);
244   hit.SetPlane(planeNumber.Atoi());
245   hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
246     
247   gMC->TrackPosition(position);
248   gMC->TrackMomentum(momentum);
249
250   AliDebug(1, Form("AliMFT::StepManager()->%s Hit #%06d (z=%f) belongs to track %02d\n", 
251                    gMC->CurrentVolName(), fNhits, position.Z(), gAlice->GetMCApp()->GetCurrentTrackNumber())); 
252
253   hit.SetPosition(position);
254   hit.SetTOF(gMC->TrackTime());
255   hit.SetMomentum(momentum);
256   hit.SetStatus(status);
257   hit.SetEloss(gMC->Edep());
258   //  hit.SetShunt(GetIshunt());
259 //   if (gMC->IsTrackEntering()) {
260 //     hit.SetStartPosition(position);
261 //     hit.SetStartTime(gMC->TrackTime());
262 //     hit.SetStartStatus(status);
263 //     return; // don't save entering hit.
264 //   } 
265
266   // Fill hit structure with this new hit.
267   new ((*fHits)[fNhits++]) AliMFTHit(hit);
268
269   // Save old position... for next hit.
270 //   hit.SetStartPosition(position);
271 //   hit.SetStartTime(gMC->TrackTime());
272 //   hit.SetStartStatus(status);
273
274   return;
275
276 }
277
278 //====================================================================================================================================================
279
280 TGeoVolumeAssembly* AliMFT::CreateVol() {
281
282   // method to create the MFT Geometry (silicon circular planes)
283
284   if (!fSegmentation) CreateGeometry();
285   
286   TGeoVolumeAssembly *vol = new TGeoVolumeAssembly("MFT");
287   TGeoMedium *silicon = gGeoManager->GetMedium("MFT_Si");
288   TGeoMedium *readout = gGeoManager->GetMedium("MFT_Readout");
289   TGeoMedium *support = gGeoManager->GetMedium("MFT_Support");
290   for (Int_t iPar=0; iPar<8; iPar++) AliInfo(Form("silicon->GetParam(%d) = %f", iPar, silicon->GetParam(iPar)));
291   for (Int_t iPar=0; iPar<8; iPar++) AliInfo(Form("readout->GetParam(%d) = %f", iPar, readout->GetParam(iPar)));
292   for (Int_t iPar=0; iPar<8; iPar++) AliInfo(Form("support->GetParam(%d) = %f", iPar, support->GetParam(iPar)));
293
294   Double_t origin[3] = {0};
295
296   for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
297
298     AliDebug(1, Form("Creating volumes for MFT plane %02d",iPlane));
299
300     AliMFTPlane *plane = fSegmentation->GetPlane(iPlane);
301
302     // --------- support element(s)
303     
304     origin[0] =  0.5*(plane->GetSupportElement(0)->GetAxis(0)->GetXmax() + plane->GetSupportElement(0)->GetAxis(0)->GetXmin());
305     origin[1] =  0.5*(plane->GetSupportElement(0)->GetAxis(1)->GetXmax() + plane->GetSupportElement(0)->GetAxis(1)->GetXmin());
306     origin[2] = -0.5*(plane->GetSupportElement(0)->GetAxis(2)->GetXmax() + plane->GetSupportElement(0)->GetAxis(2)->GetXmin());
307     TGeoVolume *supportElem = gGeoManager->MakeTube(Form("MFT_plane%02d_support", iPlane), support, 
308                                                     plane->GetRMinSupport(), 
309                                                     plane->GetRMaxSupport(),
310                                                     0.5*(plane->GetSupportElement(0)->GetAxis(2)->GetXmax() - 
311                                                          plane->GetSupportElement(0)->GetAxis(2)->GetXmin()) );
312     vol -> AddNode(supportElem, 0, new TGeoTranslation(origin[0], origin[1], origin[2]));
313
314     AliDebug(1, "support elements created!");
315     
316     // --------- active elements
317
318     for (Int_t iActive=0; iActive<plane->GetNActiveElements(); iActive++) {
319       
320       Double_t dx = 0.5*TMath::Abs(plane->GetActiveElement(iActive)->GetAxis(0)->GetXmax() - plane->GetActiveElement(iActive)->GetAxis(0)->GetXmin());
321       Double_t dy = 0.5*TMath::Abs(plane->GetActiveElement(iActive)->GetAxis(1)->GetXmax() - plane->GetActiveElement(iActive)->GetAxis(1)->GetXmin());
322       Double_t dz = 0.5*TMath::Abs(plane->GetActiveElement(iActive)->GetAxis(2)->GetXmax() - plane->GetActiveElement(iActive)->GetAxis(2)->GetXmin());
323       dz /= Double_t(fNSlices);
324
325       origin[0] =  0.5*(plane->GetActiveElement(iActive)->GetAxis(0)->GetXmax() + plane->GetActiveElement(iActive)->GetAxis(0)->GetXmin());
326       origin[1] =  0.5*(plane->GetActiveElement(iActive)->GetAxis(1)->GetXmax() + plane->GetActiveElement(iActive)->GetAxis(1)->GetXmin());
327
328       for (Int_t iSlice=0; iSlice<fNSlices; iSlice++) {
329         origin[2] = -0.5*(plane->GetActiveElement(iActive)->GetAxis(2)->GetXmin() + 2*dz*(iSlice+1) + plane->GetActiveElement(iActive)->GetAxis(2)->GetXmin() + 2*dz*(iSlice) );
330         TGeoVolume *activeElem = gGeoManager->MakeBox(Form("MFT_plane%02d_active%03d_slice%02d", iPlane, iActive, iSlice), silicon, dx, dy, dz);
331         vol -> AddNode(activeElem, 0, new TGeoTranslation(origin[0], origin[1], origin[2]));
332       }
333
334     }
335
336     AliDebug(1, "active elements created!");
337
338     // --------- readout elements
339
340     for (Int_t iReadout=0; iReadout<plane->GetNReadoutElements(); iReadout++) {
341       
342       Double_t dx = 0.5*TMath::Abs(plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmax() - plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmin());
343       Double_t dy = 0.5*TMath::Abs(plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmax() - plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmin());
344       Double_t dz = 0.5*TMath::Abs(plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmax() - plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmin());
345
346       origin[0] =  0.5*(plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmax() + plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmin());
347       origin[1] =  0.5*(plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmax() + plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmin());
348       origin[2] = -0.5*(plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmax() + plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmin());
349
350       TGeoVolume *readoutElem = gGeoManager->MakeBox(Form("MFT_plane%02d_readout%03d", iPlane, iReadout), readout, dx, dy, dz);
351       vol -> AddNode(readoutElem, 0, new TGeoTranslation(origin[0], origin[1], origin[2]));
352       
353     }
354
355     AliDebug(1, "readout elements created!");
356
357   }
358
359   return vol;
360
361 }
362
363 //====================================================================================================================================================
364
365 void AliMFT::Hits2SDigits(){
366   
367   // Interface method invoked from AliSimulation to create a list of sdigits corresponding to list of hits. Every hit generates one sdigit.
368
369   AliDebug(1,"Start Hits2SDigits.");
370   
371   if (!fSegmentation) CreateGeometry();
372  
373   if (!fLoader->TreeH()) fLoader->LoadHits();
374
375   if (!fLoader->TreeS()) {
376
377     for (Int_t iEvt=0;iEvt<fLoader->GetRunLoader()->GetNumberOfEvents(); iEvt++) {
378
379       fLoader->GetRunLoader()->GetEvent(iEvt);
380       fLoader->MakeTree("S");
381       MakeBranch("S");
382       SetTreeAddress();
383
384       AliDebug(1, Form("Event %03d: fLoader->TreeH()->GetEntries() = %2d", iEvt, Int_t(fLoader->TreeH()->GetEntries())));
385
386       for (Int_t iTrack=0; iTrack<fLoader->TreeH()->GetEntries(); iTrack++) {
387         fLoader->TreeH()->GetEntry(iTrack);     
388         Hits2SDigitsLocal(Hits(), GetSDigitsList(), iTrack);    // convert these hits to a list of sdigits  
389       }
390       
391       fLoader->TreeS()->Fill();
392       fLoader->WriteSDigits("OVERWRITE");
393       ResetSDigits();
394
395     }
396   }
397
398   fLoader->UnloadHits();
399   fLoader->UnloadSDigits();
400
401   AliDebug(1,"Stop Hits2SDigits.");
402   
403 }
404
405 //====================================================================================================================================================
406
407 void AliMFT::Hits2SDigitsLocal(TClonesArray *hits, const TObjArray *pSDig, Int_t track) {
408
409   //  Add sdigits of these hits to the list
410   
411   AliDebug(1, "Start Hits2SDigitsLocal");
412   
413   if (!fSegmentation) CreateGeometry();
414   
415   TClonesArray *pSDigList[fNMaxPlanes];
416   for (Int_t iPlane=0; iPlane<fNMaxPlanes; iPlane++) pSDigList[iPlane] = NULL; 
417   for (Int_t iPlane=0; iPlane<fNPlanes;    iPlane++) { 
418     pSDigList[iPlane] = (TClonesArray*) (*pSDig)[iPlane];
419     AliDebug(1,Form("Entries of pSDigList %3d; plane: %02d,",pSDigList[iPlane]->GetEntries(),iPlane));
420     if (!track && pSDigList[iPlane]->GetEntries()!=0) AliErrorClass("Some of sdigits lists is not empty");
421   }
422   
423   for (Int_t iHit=0; iHit<hits->GetEntries(); iHit++) {
424
425     AliMFTHit *hit = (AliMFTHit*) hits->At(iHit);
426
427     AliMFTDigit sDigit;
428     sDigit.SetEloss(hit->GetEloss());
429     sDigit.SetDetElemID(hit->GetDetElemID());
430     sDigit.SetPlane(hit->GetPlane());
431     sDigit.AddMCLabel(hit->GetTrack()); 
432
433     Int_t xPixel = -1;
434     Int_t yPixel = -1;
435     if (fSegmentation->Hit2PixelID(hit->X(), hit->Y(), sDigit.GetDetElemID(), xPixel, yPixel)) {
436       sDigit.SetPixID(xPixel, yPixel, 0);
437       sDigit.SetPixWidth(fSegmentation->GetPixelSizeX(sDigit.GetDetElemID()), 
438                          fSegmentation->GetPixelSizeY(sDigit.GetDetElemID()),
439                          fSegmentation->GetPixelSizeZ(sDigit.GetDetElemID()));  
440       sDigit.SetPixCenter(fSegmentation->GetPixelCenterX(sDigit.GetDetElemID(), xPixel), 
441                           fSegmentation->GetPixelCenterY(sDigit.GetDetElemID(), yPixel),
442                           fSegmentation->GetPixelCenterZ(sDigit.GetDetElemID(), 0));  
443       new ((*pSDigList[sDigit.GetPlane()])[pSDigList[sDigit.GetPlane()]->GetEntries()]) AliMFTDigit(sDigit);
444       AliDebug(1, Form("Created new sdigit (%f, %f, %f) from hit (%f, %f, %f)",
445                        sDigit.GetPixelCenterX(), sDigit.GetPixelCenterY(), sDigit.GetPixelCenterZ(), hit->X(), hit->Y(), hit->Z()));
446 //       AliDebug(1, Form("Created new sdigit from hit: residual is (%f, %f, %f)",
447 //                     sDigit.GetPixelCenterX()-hit->X(), sDigit.GetPixelCenterY()-hit->Y(), sDigit.GetPixelCenterZ()-hit->Z()));
448     }
449
450     // creating "side hits" to simulate the effect of charge dispersion
451
452     Int_t xPixelNew = -1;
453     Int_t yPixelNew = -1;
454     Double_t x0 = hit->X();
455     Double_t y0 = hit->Y();
456     Double_t pi4 = TMath::Pi()/4.;
457     for (Int_t iStep=0; iStep<fNStepForChargeDispersion; iStep++) {
458       Double_t shift = (iStep+1) * fSingleStepForChargeDispersion;
459       for (Int_t iAngle=0; iAngle<8; iAngle++) {
460         Double_t shiftX = shift*TMath::Cos(iAngle*pi4);
461         Double_t shiftY = shift*TMath::Sin(iAngle*pi4);
462         if (fSegmentation->Hit2PixelID(x0+shiftX, y0+shiftY, hit->GetDetElemID(), xPixelNew, yPixelNew)) {
463           Bool_t digitExists = kFALSE;
464           if (xPixelNew==xPixel && yPixelNew==yPixel) digitExists = kTRUE;
465           if (!digitExists) {
466             for (Int_t iSideDigit=0; iSideDigit<fSideDigits->GetEntries(); iSideDigit++) {
467               if (xPixelNew==((AliMFTDigit*) fSideDigits->At(iSideDigit))->GetPixelX() && 
468                   yPixelNew==((AliMFTDigit*) fSideDigits->At(iSideDigit))->GetPixelY()) {
469                 digitExists = kTRUE;
470                 break;
471               }
472             }
473           }
474           if (!digitExists) {
475             AliMFTDigit newSDigit;
476             newSDigit.SetEloss(0.);
477             newSDigit.SetDetElemID(hit->GetDetElemID());
478             newSDigit.SetPlane(hit->GetPlane());
479             newSDigit.AddMCLabel(hit->GetTrack());
480             newSDigit.SetPixID(xPixelNew, yPixelNew, 0);
481             newSDigit.SetPixWidth(fSegmentation->GetPixelSizeX(sDigit.GetDetElemID()), 
482                                   fSegmentation->GetPixelSizeY(sDigit.GetDetElemID()),
483                                   fSegmentation->GetPixelSizeZ(sDigit.GetDetElemID()));  
484             newSDigit.SetPixCenter(fSegmentation->GetPixelCenterX(sDigit.GetDetElemID(), xPixelNew), 
485                                    fSegmentation->GetPixelCenterY(sDigit.GetDetElemID(), yPixelNew),
486                                    fSegmentation->GetPixelCenterZ(sDigit.GetDetElemID(), 0)); 
487             new ((*fSideDigits)[fSideDigits->GetEntries()]) AliMFTDigit(newSDigit);
488           }
489         }
490       }
491     }
492
493     for (Int_t iSideDigit=0; iSideDigit<fSideDigits->GetEntries(); iSideDigit++) {
494       AliMFTDigit *newDigit = (AliMFTDigit*) fSideDigits->At(iSideDigit);
495       new ((*pSDigList[sDigit.GetPlane()])[pSDigList[sDigit.GetPlane()]->GetEntries()]) AliMFTDigit(*newDigit);
496     }
497
498     fSideDigits->Clear();    
499
500   }
501   
502   AliDebug(1,"Stop Hits2SDigitsLocal");
503
504 }
505
506 //====================================================================================================================================================
507
508 void AliMFT::MakeBranch(Option_t *option) {
509
510   printf("AliMFT::MakeBranch(...)\n");
511
512   // Create Tree branches 
513   AliDebug(1, Form("Start with option= %s.",option));
514   
515   const Int_t kBufSize = 4000;
516   
517   const Char_t *cH = strstr(option,"H");
518   const Char_t *cD = strstr(option,"D");
519   const Char_t *cS = strstr(option,"S");
520
521   if (cH && fLoader->TreeH()) {
522     CreateHits();
523     MakeBranchInTree(fLoader->TreeH(), "MFT", &fHits, kBufSize, 0);   
524   }
525
526   if (cS && fLoader->TreeS()) {
527     CreateSDigits();
528     for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) MakeBranchInTree(fLoader->TreeS(), 
529                                                                     Form("Plane_%02d",iPlane), 
530                                                                     &((*fSDigitsPerPlane)[iPlane]), 
531                                                                     kBufSize, 0);
532   }
533   
534   if (cD && fLoader->TreeD()) {
535     CreateDigits();
536     for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) MakeBranchInTree(fLoader->TreeD(), 
537                                                                     Form("Plane_%02d",iPlane), 
538                                                                     &((*fDigitsPerPlane)[iPlane]),
539                                                                     kBufSize, 0);
540   }
541
542   AliDebug(1,"Stop.");
543
544 }
545
546 //====================================================================================================================================================
547
548 void AliMFT::SetTreeAddress() {
549
550   AliDebug(1, "AliMFT::SetTreeAddress()");
551
552   //Set branch address for the Hits and Digits Tree.
553   AliDebug(1, "Start.");
554
555   AliDebug(1, Form("AliMFT::SetTreeAddress Hits  fLoader->TreeH() = %p\n", fLoader->TreeH()));
556   if (fLoader->TreeH() && fLoader->TreeH()->GetBranch("MFT")) {
557     CreateHits();
558     fLoader->TreeH()->SetBranchAddress("MFT", &fHits);
559   }
560     
561   AliDebug(1, Form("AliMFT::SetTreeAddress SDigits  fLoader->TreeS() = %p\n", fLoader->TreeS()));
562   if (fLoader->TreeS() && fLoader->TreeS()->GetBranch("Plane_00")) {
563     CreateSDigits();
564     for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
565       fLoader->TreeS()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fSDigitsPerPlane)[iPlane]));
566     }
567   }
568     
569   AliDebug(1, Form("AliMFT::SetTreeAddress Digits  fLoader->TreeD() = %p\n", fLoader->TreeD()));
570   if (fLoader->TreeD() && fLoader->TreeD()->GetBranch("Plane_00")) {
571     CreateDigits(); 
572     for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
573       fLoader->TreeD()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fDigitsPerPlane)[iPlane]));
574     }
575   }
576
577   AliDebug(1, Form("AliMFT::SetTreeAddress RecPoints  fLoader->TreeR() = %p\n", fLoader->TreeR()));
578   if (fLoader->TreeR() && fLoader->TreeR()->GetBranch("Plane_00")) {
579     CreateRecPoints(); 
580     for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
581       fLoader->TreeR()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fRecPointsPerPlane)[iPlane]));
582     }
583   }
584
585   AliDebug(1,"Stop.");
586
587 }
588
589 //====================================================================================================================================================
590
591 void AliMFT::SetGeometry() {
592
593   printf("AliMFT::SetGeometry\n");
594
595   fSegmentation = new AliMFTSegmentation(fNameGeomFile.Data());
596
597   fNPlanes = fSegmentation->GetNPlanes();
598
599 }
600
601 //====================================================================================================================================================
602
603 void AliMFT::CreateHits() { 
604
605   // create array of hits
606
607   AliDebug(1, "AliMFT::CreateHits()");
608
609   if (fHits) return;    
610   fHits = new TClonesArray("AliMFTHit");  
611
612 }
613
614 //====================================================================================================================================================
615
616 void AliMFT::CreateSDigits() { 
617  
618   // create sdigits list
619
620   AliDebug(1, "AliMFT::CreateSDigits()");
621  
622   if (fSDigitsPerPlane) return; 
623   fSDigitsPerPlane = new TObjArray(fNPlanes); 
624   for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) fSDigitsPerPlane->AddAt(new TClonesArray("AliMFTDigit"), iPlane);
625
626   fSideDigits = new TClonesArray("AliMFTDigit");
627
628 }
629
630 //====================================================================================================================================================
631
632 void AliMFT::CreateDigits() {
633
634   // create digits list
635
636   AliDebug(1, "AliMFT::CreateDigits()");
637
638   if (fDigitsPerPlane) return; 
639   fDigitsPerPlane = new TObjArray(fNPlanes);
640   for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) fDigitsPerPlane->AddAt(new TClonesArray("AliMFTDigit"), iPlane);
641
642 }
643
644 //====================================================================================================================================================
645
646 void AliMFT::CreateRecPoints() {
647
648   // create recPoints list
649
650   AliDebug(1, "AliMFT::CreateRecPoints()");
651
652   if (fRecPointsPerPlane) return; 
653   fRecPointsPerPlane = new TObjArray(fNPlanes);
654   for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) fRecPointsPerPlane->AddAt(new TClonesArray("AliMFTCluster"), iPlane);
655
656 }
657
658 //====================================================================================================================================================