]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFClusterFinder.cxx
updates on TOF code to add and use new calibration object
[u/mrichter/AliRoot.git] / TOF / AliTOFClusterFinder.cxx
1 /***************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* 
17 $Log: AliTOFClusterFinder.cxx,v $
18 Revision 1.31  2007/11/24 14:53:19  zampolli
19 Status flag implemented as UChar_t
20
21 Revision 1.30  2007/10/04 13:08:52  arcelli
22 updates to comply with AliTOFGeometryV5 becoming AliTOFGeometry
23
24 Revision 1.29  2007/10/03 10:42:33  arcelli
25 updates to handle new AliTOFcluster, inheriting form AliCluster3D
26
27 Revision 1.28  2007/05/31 16:06:05  arcelli
28 move instance of AliRawStream outside loop on DDL
29
30 Revision 1.27  2007/05/02 16:31:49  arcelli
31 Add methods to handle single event reconstruction.  retrieval of Calib
32 info moved to AliTOFReconstructor ctor, and passed via a pointer to
33 AliTOFcalib
34
35 Revision 1.26  2007/04/30 19:02:24  arcelli
36 hopefully the last refinements for correct type conversion in calibration
37
38 Revision 1.25  2007/04/30 15:22:17  arcelli
39 Change TOF digit Time, Tot etc to int type
40
41 Revision 1.24  2007/04/27 11:19:31  arcelli
42 updates for the new decoder
43
44 Revision 1.23  2007/04/23 16:51:39  decaro
45 Digits-to-raw_data conversion: correction for a more real description
46 (A.De Caro, R.Preghenella)
47
48 Revision 1.22  2007/04/19 17:26:32  arcelli
49 Fix a bug (add some debug printout
50
51 Revision 1.21  2007/04/18 17:28:12  arcelli
52 Set the ToT bin width to the one actually used...
53
54 Revision 1.20  2007/03/09 09:57:23  arcelli
55  Remove a forgotten include of Riostrem
56
57 Revision 1.19  2007/03/08 15:41:20  arcelli
58 set uncorrected times when filling RecPoints
59
60 Revision 1.18  2007/03/06 16:31:20  arcelli
61 Add Uncorrected TOF Time signal
62
63 Revision 1.17  2007/02/28 18:09:11  arcelli
64 Add protection against failed retrieval of the CDB cal object,
65 now Reconstruction exits with AliFatal
66
67 Revision 1.16  2007/02/20 15:57:00  decaro
68 Raw data update: to read the TOF raw data defined in UNPACKED mode
69
70
71 Revision 0.03  2005/07/28 A. De Caro
72          Implement public method
73          Raw2Digits(Int_t, AliRawReader *)
74          to convert digits from raw data in MC digits
75          (temporary solution)
76
77 Revision 0.02  2005/07/27 A. De Caro
78          Implement public method
79          Digits2RecPoint(Int_t)
80          to convert digits in clusters
81
82 Revision 0.02  2005/07/26 A. De Caro
83          Implement private methods
84          InsertCluster(AliTOFcluster *)
85          FindClusterIndex(Double_t)
86          originally implemented in AliTOFtracker
87          by S. Arcelli and C. Zampolli
88
89 Revision 0.01  2005/07/25 A. De Caro
90          Implement public methods
91          Digits2RecPoint(AliRawReader *, TTree *)
92          Digits2RecPoint(Int_t, AliRawReader *)
93          to convert raw data in clusters
94  */
95
96 ////////////////////////////////////////////////////////////////
97 //                                                            //
98 //         Class for TOF cluster finder                       //
99 //                                                            //
100 // Starting from Raw Data, create rec points,                 //
101 //                         fill TreeR for TOF,                //
102 //                         write TOF.RecPoints.root file      //
103 //                                                            //
104 ////////////////////////////////////////////////////////////////
105
106 #include "Riostream.h"
107
108 #include "TClonesArray.h"
109 #include "TStopwatch.h"
110 #include "TTree.h"
111 //#include <TGeoManager.h>
112 #include <TGeoMatrix.h>
113 //#include <TGeoPhysicalNode.h>
114
115 #include "AliDAQ.h"
116 #include "AliLoader.h"
117 #include "AliLog.h"
118 #include "AliRawReader.h"
119 #include "AliRunLoader.h"
120 //#include "AliAlignObj.h"
121 #include <AliGeomManager.h>
122
123 #include "AliTOFcalib.h"
124 #include "AliTOFChannelOnlineArray.h"
125 #include "AliTOFChannelOnlineStatusArray.h"
126 #include "AliTOFChannelOffline.h"
127 #include "AliTOFClusterFinder.h"
128 #include "AliTOFcluster.h"
129 #include "AliTOFdigit.h"
130 #include "AliTOFGeometry.h"
131 #include "AliTOFrawData.h"
132 //#include "AliTOFRawStream.h"
133
134 #include "AliTOFDeltaBCOffset.h"
135 #include "AliTOFCTPLatency.h"
136 #include "AliTOFRunParams.h"
137
138 //extern TFile *gFile;
139
140 ClassImp(AliTOFClusterFinder)
141
142 AliTOFClusterFinder::AliTOFClusterFinder(AliTOFcalib *calib):
143   fRunLoader(0),
144   fTOFLoader(0),
145   fTreeD(0),
146   fTreeR(0),
147   fDigits(new TClonesArray("AliTOFdigit", 4000)),
148   fRecPoints(new TClonesArray("AliTOFcluster", 4000)),
149   fNumberOfTofClusters(0),
150   fVerbose(0),
151   fDecoderVersion(0),
152   fTOFcalib(calib),
153   fTOFRawStream(AliTOFRawStream())
154 {
155 //
156 // Constructor
157 //
158
159   TString validity = (TString)fTOFcalib->GetOfflineValidity();
160   if (validity.CompareTo("valid")==0) {
161     AliInfo(Form(" validity = %s - Using offline calibration parameters",validity.Data()));
162   } else {
163     AliInfo(Form(" validity = %s - Using online calibration parameters",validity.Data()));
164   }
165
166 }
167
168 //______________________________________________________________________________
169
170 AliTOFClusterFinder::AliTOFClusterFinder(AliRunLoader* runLoader, AliTOFcalib *calib):
171   fRunLoader(runLoader),
172   fTOFLoader(runLoader->GetLoader("TOFLoader")),
173   fTreeD(0),
174   fTreeR(0),
175   fDigits(new TClonesArray("AliTOFdigit", 4000)),
176   fRecPoints(new TClonesArray("AliTOFcluster", 4000)),
177   fNumberOfTofClusters(0),
178   fVerbose(0),
179   fDecoderVersion(0),
180   fTOFcalib(calib),
181   fTOFRawStream(AliTOFRawStream())
182 {
183 //
184 // Constructor
185 //
186
187   TString validity = (TString)fTOFcalib->GetOfflineValidity();
188   if (validity.CompareTo("valid")==0) {
189     AliInfo(Form(" validity = %s - Using offline calibration parameters",validity.Data()));
190   } else {
191     AliInfo(Form(" validity = %s - Using online calibration parameters",validity.Data()));
192   }
193
194 }
195
196 //------------------------------------------------------------------------
197 AliTOFClusterFinder::AliTOFClusterFinder(const AliTOFClusterFinder &source)
198   :TObject(source),
199   fRunLoader(0),
200   fTOFLoader(0),
201   fTreeD(0),
202   fTreeR(0),
203   fDigits(source.fDigits),
204   fRecPoints(source.fRecPoints),
205   fNumberOfTofClusters(0),
206   fVerbose(0),
207   fDecoderVersion(source.fDecoderVersion),
208   fTOFcalib(source.fTOFcalib),
209   fTOFRawStream(source.fTOFRawStream)
210 {
211   // copy constructor
212 }
213
214 //------------------------------------------------------------------------
215 AliTOFClusterFinder& AliTOFClusterFinder::operator=(const AliTOFClusterFinder &source)
216 {
217   // ass. op.
218
219   if (this == &source)
220     return *this;
221
222   TObject::operator=(source);  
223   fDigits=source.fDigits;
224   fRecPoints=source.fRecPoints;
225   fVerbose=source.fVerbose;
226   fDecoderVersion=source.fDecoderVersion;
227   fTOFcalib=source.fTOFcalib;
228   fTOFRawStream=source.fTOFRawStream;
229   return *this;
230
231 }
232 //______________________________________________________________________________
233
234 AliTOFClusterFinder::~AliTOFClusterFinder()
235 {
236
237   //
238   // Destructor
239   //
240
241   if (fDigits)
242     {
243       fDigits->Delete();
244       delete fDigits;
245       fDigits=0;
246     }
247   if (fRecPoints)
248     {
249       fRecPoints->Delete();
250       delete fRecPoints;
251       fRecPoints=0;
252     }
253
254 }
255 //______________________________________________________________________________
256
257 void AliTOFClusterFinder::Digits2RecPoints(Int_t iEvent)
258 {
259   //
260   // Converts digits to recpoints for TOF
261   //
262
263   TStopwatch stopwatch;
264   stopwatch.Start();
265
266   Int_t inholes = 0;
267
268   fRunLoader->GetEvent(iEvent);
269
270   fTreeD = fTOFLoader->TreeD();
271   if (fTreeD == 0x0)
272     {
273       AliFatal("AliTOFClusterFinder: Can not get TreeD");
274     }
275
276   TBranch *branch = fTreeD->GetBranch("TOF");
277   if (!branch) { 
278     AliError("can't get the branch with the TOF digits !");
279     return;
280   }
281
282   TClonesArray staticdigits("AliTOFdigit",10000);
283   staticdigits.Clear();
284   TClonesArray *digits =&staticdigits;
285   branch->SetAddress(&digits);
286
287   ResetRecpoint();
288
289   fTreeR = fTOFLoader->TreeR();
290   if (fTreeR == 0x0)
291     {
292       fTOFLoader->MakeTree("R");
293       fTreeR = fTOFLoader->TreeR();
294     }
295
296   Int_t bufsize = 32000;
297   fTreeR->Branch("TOF", &fRecPoints, bufsize);
298
299   fTreeD->GetEvent(0);
300   Int_t nDigits = digits->GetEntriesFast();
301   AliDebug(2,Form("Number of TOF digits: %d",nDigits));
302
303   Int_t ii;
304   Int_t dig[5]; //cluster detector indeces
305   Int_t  parTOF[7]; //The TOF signal parameters
306   Bool_t status=kTRUE; // assume all sim channels ok in the beginning...
307   for (ii=0; ii<nDigits; ii++) {
308     AliTOFdigit *d = (AliTOFdigit*)digits->UncheckedAt(ii);
309     dig[0]=d->GetSector();
310     dig[1]=d->GetPlate();
311     dig[2]=d->GetStrip();
312     dig[3]=d->GetPadz();
313     dig[4]=d->GetPadx();
314
315     /* check valid index */
316     if (dig[0]==-1||dig[1]==-1||dig[2]==-1||dig[3]==-1||dig[4]==-1) continue;
317
318     // Do not reconstruct anything in the holes
319     if (dig[0]==13 || dig[0]==14 || dig[0]==15 ) { // sectors with holes
320       if (dig[1]==2) { // plate with holes
321         inholes++;
322         continue;
323       }
324     }
325
326     AliDebug(2,Form(" %2d  %1d  %2d  %1d  %2d ",dig[0],dig[1],dig[2],dig[3],dig[4]));
327
328     parTOF[0] = d->GetTdc(); //the TDC signal
329     parTOF[1] = d->GetToT(); //the ToT signal
330     parTOF[2] = d->GetAdc(); // the adc charge
331     parTOF[3] = d->GetTdcND(); // non decalibrated sim time
332     parTOF[4] = d->GetTdc(); // raw time, == Tdc time for the moment
333     parTOF[5] = 0; // deltaBC
334     parTOF[6] = 0; // L0-L1 latency
335     Double_t posClus[3];
336     Double_t covClus[6];
337     UShort_t volIdClus=GetClusterVolIndex(dig);
338     GetClusterPars(dig, posClus,covClus);
339     AliTOFcluster *tofCluster = new AliTOFcluster(volIdClus,posClus[0],posClus[1],posClus[2],covClus[0],covClus[1],covClus[2],covClus[3],covClus[4],covClus[5],d->GetTracks(),dig,parTOF,status,ii);
340     InsertCluster(tofCluster);
341
342   }
343
344   AliDebug(1,Form("Number of found clusters: %d for event: %d", fNumberOfTofClusters, iEvent));
345
346   CalibrateRecPoint();
347   FillRecPoint();
348
349   fTreeR->Fill();
350   ResetRecpoint();
351
352   fTOFLoader = fRunLoader->GetLoader("TOFLoader");  
353   fTOFLoader->WriteRecPoints("OVERWRITE");
354
355   AliDebug(1,Form("Execution time to read TOF digits and to write TOF clusters : R:%.4fs C:%.4fs",
356                   stopwatch.RealTime(),stopwatch.CpuTime()));
357   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
358
359 }
360
361 //______________________________________________________________________________
362
363 void AliTOFClusterFinder::Digits2RecPoints(TTree* digitsTree, TTree* clusterTree)
364 {
365   //
366   // Converts digits to recpoints for TOF
367   //
368
369   TStopwatch stopwatch;
370   stopwatch.Start();
371
372   Int_t inholes = 0;
373
374   ///  fRunLoader->GetEvent(iEvent);
375
376   if (digitsTree == 0x0)
377     {
378       AliFatal("AliTOFClusterFinder: Can not get TreeD");
379     }
380
381   TBranch *branch = digitsTree->GetBranch("TOF");
382   if (!branch) { 
383     AliError("can't get the branch with the TOF digits !");
384     return;
385   }
386
387   TClonesArray staticdigits("AliTOFdigit",10000);
388   staticdigits.Clear();
389   TClonesArray *digits = & staticdigits;
390   branch->SetAddress(&digits);
391
392   ResetRecpoint();
393
394   fTreeR=clusterTree;
395   Int_t bufsize = 32000;
396   fTreeR->Branch("TOF", &fRecPoints, bufsize);
397
398   digitsTree->GetEvent(0);
399   Int_t nDigits = digits->GetEntriesFast();
400   AliDebug(2,Form("Number of TOF digits: %d",nDigits));
401
402   Int_t ii;
403   Int_t dig[5]; //cluster detector indeces
404   Int_t  parTOF[7]; //The TOF signal parameters
405   Bool_t status=kTRUE; // assume all sim channels ok in the beginning...
406   for (ii=0; ii<nDigits; ii++) {
407     AliTOFdigit *d = (AliTOFdigit*)digits->UncheckedAt(ii);
408     dig[0]=d->GetSector();
409     dig[1]=d->GetPlate();
410     dig[2]=d->GetStrip();
411     dig[3]=d->GetPadz();
412     dig[4]=d->GetPadx();
413
414     /* check valid index */
415     if (dig[0]==-1||dig[1]==-1||dig[2]==-1||dig[3]==-1||dig[4]==-1) continue;
416
417     // Do not reconstruct anything in the holes
418     if (dig[0]==13 || dig[0]==14 || dig[0]==15 ) { // sectors with holes
419       if (dig[1]==2) { // plate with holes
420         inholes++;
421         continue;
422       }
423     }
424
425     //    AliDebug(2,Form(" %2d  %1d  %2d  %1d  %2d ",dig[0],dig[1],dig[2],dig[3],dig[4]));
426
427     parTOF[0] = d->GetTdc(); //the TDC signal
428     parTOF[1] = d->GetToT(); //the ToT signal
429     parTOF[2] = d->GetAdc(); // the adc charge
430     parTOF[3] = d->GetTdcND(); // non decalibrated sim time
431     parTOF[4] = d->GetTdc(); // raw time, == Tdc time for the moment
432     parTOF[5] = 0; // deltaBC
433     parTOF[6] = 0; // L0-L1 latency
434     
435     Double_t posClus[3];
436     Double_t covClus[6];
437     UShort_t volIdClus=GetClusterVolIndex(dig);
438     GetClusterPars(dig,posClus,covClus);
439     AliTOFcluster *tofCluster = new AliTOFcluster(volIdClus,posClus[0],posClus[1],posClus[2],covClus[0],covClus[1],covClus[2],covClus[3],covClus[4],covClus[5],d->GetTracks(),dig,parTOF,status,ii);
440     InsertCluster(tofCluster);
441
442   }
443
444   AliDebug(1,Form("Number of found clusters: %d", fNumberOfTofClusters));
445
446   CalibrateRecPoint();
447   FillRecPoint();
448
449   clusterTree->Fill();
450   ResetRecpoint();
451
452   AliDebug(1,Form("Execution time to read TOF digits and to write TOF clusters : R:%.4fs C:%.4fs",
453                   stopwatch.RealTime(),stopwatch.CpuTime()));
454   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
455
456 }
457 //______________________________________________________________________________
458
459 void AliTOFClusterFinder::Digits2RecPoints(AliRawReader *rawReader,
460                                            TTree *clustersTree)
461 {
462   //
463   // Converts RAW data to recpoints for TOF
464   //
465
466   TStopwatch stopwatch;
467   stopwatch.Start();
468
469   Int_t inholes = 0;
470
471   const Int_t kDDL = AliDAQ::NumberOfDdls("TOF");
472
473   ResetRecpoint();
474
475   Int_t bufsize = 32000;
476   clustersTree->Branch("TOF", &fRecPoints, bufsize);
477
478   TClonesArray * clonesRawData;
479
480   Int_t dummy = -1;
481
482   Int_t detectorIndex[5];
483   Int_t parTOF[7];
484
485   ofstream ftxt;
486   if (fVerbose==2) ftxt.open("TOFdigitsRead.txt",ios::app);
487
488   //AliTOFRawStream tofInput(rawReader);
489   fTOFRawStream.Clear();
490   fTOFRawStream.SetRawReader(rawReader);
491
492   if (fDecoderVersion)
493     AliInfo("Using New Decoder");
494
495   Int_t indexDDL = 0;
496   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
497
498     rawReader->Reset();
499     if (fDecoderVersion)
500       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
501     else fTOFRawStream.LoadRawData(indexDDL);
502
503     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
504
505     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
506
507       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
508
509       //if (tofRawDatum->GetTOT()==-1 || tofRawDatum->GetTOF()==-1) continue;
510       if (tofRawDatum->GetTOF()==-1) continue;
511
512       if (fVerbose==2) {
513         if (indexDDL<10) ftxt << "  " << indexDDL;
514         else         ftxt << " " << indexDDL;
515         if (tofRawDatum->GetTRM()<10) ftxt << "  " << tofRawDatum->GetTRM();
516         else         ftxt << " " << tofRawDatum->GetTRM();
517         ftxt << "  " << tofRawDatum->GetTRMchain();
518         if (tofRawDatum->GetTDC()<10) ftxt << "  " << tofRawDatum->GetTDC();
519         else         ftxt << " " << tofRawDatum->GetTDC();
520         ftxt << "  " << tofRawDatum->GetTDCchannel();
521       }
522
523       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
524                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
525       dummy = detectorIndex[3];
526       detectorIndex[3] = detectorIndex[4];
527       detectorIndex[4] = dummy;
528
529       if (fVerbose==2) {
530         if (detectorIndex[0]<10) ftxt  << "  ->  " << detectorIndex[0];
531         else              ftxt  << "  -> " << detectorIndex[0];
532         ftxt << "  " << detectorIndex[1];
533         if (detectorIndex[2]<10) ftxt << "  " << detectorIndex[2];
534         else              ftxt << " " << detectorIndex[2];
535         ftxt << "  " << detectorIndex[3];
536         if (detectorIndex[4]<10) ftxt << "  " << detectorIndex[4];
537         else              ftxt << " " << detectorIndex[4];
538       }
539
540     /* check valid index */
541     if (detectorIndex[0]==-1||detectorIndex[1]==-1||detectorIndex[2]==-1||detectorIndex[3]==-1||detectorIndex[4]==-1) continue;
542
543       // Do not reconstruct anything in the holes
544       if (detectorIndex[0]==13 || detectorIndex[0]==14 || detectorIndex[0]==15 ) { // sectors with holes
545         if (detectorIndex[1]==2) { // plate with holes
546           inholes++;
547           continue;
548         }
549       }
550
551       parTOF[0] = tofRawDatum->GetTOF(); //TDC
552       parTOF[1] = tofRawDatum->GetTOT(); // TOT
553       parTOF[2] = tofRawDatum->GetTOT(); //ADC==TOF
554       parTOF[3] = -1;//raw data: no track of undecalib sim time
555       parTOF[4] = tofRawDatum->GetTOF(); // RAW time
556       parTOF[5] = tofRawDatum->GetDeltaBC(); // deltaBC
557       parTOF[6] = tofRawDatum->GetL0L1Latency(); // L0-L1 latency
558       Double_t posClus[3];
559       Double_t covClus[6];
560       UShort_t volIdClus=GetClusterVolIndex(detectorIndex);
561       Int_t lab[3]={-1,-1,-1};
562       Bool_t status=kTRUE;
563       GetClusterPars(detectorIndex,posClus,covClus);
564       AliTOFcluster *tofCluster = new AliTOFcluster(volIdClus,posClus[0],posClus[1],posClus[2],covClus[0],covClus[1],covClus[2],covClus[3],covClus[4],covClus[5],lab,detectorIndex,parTOF,status,-1);
565       InsertCluster(tofCluster);
566
567       if (fVerbose==2) {
568         if (parTOF[1]<10)ftxt << "        " << parTOF[1];
569         else if (parTOF[1]>=10 && parTOF[1]<100) ftxt << "      " << parTOF[1];
570         else ftxt << "      " << parTOF[1];
571         if (parTOF[0]<10) ftxt << "      " << parTOF[0] << endl;
572         else if (parTOF[0]>=10 && parTOF[0]<100)   ftxt << "    " << parTOF[0] << endl;
573         else if (parTOF[0]>=100 && parTOF[0]<1000) ftxt << "    " << parTOF[0] << endl;
574         else ftxt << "   " << parTOF[3] << endl;
575       }
576
577     } // closed loop on TOF raw data per current DDL file
578
579     clonesRawData->Clear();
580
581   } // closed loop on DDL index
582
583   if (fVerbose==2) ftxt.close();
584
585   AliDebug(1,Form("Number of found clusters: %d", fNumberOfTofClusters));
586
587   CalibrateRecPoint(rawReader->GetTimestamp());
588   FillRecPoint();
589
590   clustersTree->Fill();
591
592   ResetRecpoint();
593
594   AliDebug(1, Form("Execution time to read TOF raw data and to write TOF clusters : R:%.4fs C:%.4fs",
595                    stopwatch.RealTime(),stopwatch.CpuTime()));
596   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
597
598 }
599 //______________________________________________________________________________
600
601 void AliTOFClusterFinder::Digits2RecPoints(Int_t iEvent, AliRawReader *rawReader)
602 {
603   //
604   // Converts RAW data to recpoints for TOF
605   //
606
607   TStopwatch stopwatch;
608   stopwatch.Start();
609
610   Int_t inholes = 0;
611
612   const Int_t kDDL = AliDAQ::NumberOfDdls("TOF");
613
614   fRunLoader->GetEvent(iEvent);
615
616   AliDebug(2,Form(" Event number %2d ", iEvent));
617
618   fTreeR = fTOFLoader->TreeR();
619
620   if (fTreeR == 0x0){
621     fTOFLoader->MakeTree("R");
622     fTreeR = fTOFLoader->TreeR();
623   }
624
625   Int_t bufsize = 32000;
626   fTreeR->Branch("TOF", &fRecPoints, bufsize);
627
628   TClonesArray * clonesRawData;
629
630   Int_t dummy = -1;
631
632   Int_t detectorIndex[5] = {-1, -1, -1, -1, -1};
633   Int_t parTOF[7];
634   ofstream ftxt;
635   if (fVerbose==2) ftxt.open("TOFdigitsRead.txt",ios::app);
636
637   //AliTOFRawStream tofInput(rawReader);
638   fTOFRawStream.Clear();
639   fTOFRawStream.SetRawReader(rawReader);
640
641   if (fDecoderVersion)
642     AliInfo("Using New Decoder");
643
644   Int_t indexDDL = 0;
645   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
646
647     rawReader->Reset();
648     if (fDecoderVersion)
649       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
650     else fTOFRawStream.LoadRawData(indexDDL);
651
652     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
653
654     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
655
656       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
657
658       //if (tofRawDatum->GetTOT()==-1 || tofRawDatum->GetTOF()==-1) continue;
659       if (tofRawDatum->GetTOF()==-1) continue;
660
661       if (fVerbose==2) {
662         if (indexDDL<10) ftxt << "  " << indexDDL;
663         else         ftxt << " " << indexDDL;
664         if (tofRawDatum->GetTRM()<10) ftxt << "  " << tofRawDatum->GetTRM();
665         else         ftxt << " " << tofRawDatum->GetTRM();
666         ftxt << "  " << tofRawDatum->GetTRMchain();
667         if (tofRawDatum->GetTDC()<10) ftxt << "  " << tofRawDatum->GetTDC();
668         else         ftxt << " " << tofRawDatum->GetTDC();
669         ftxt << "  " << tofRawDatum->GetTDCchannel();
670       }
671
672       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
673                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
674       dummy = detectorIndex[3];
675       detectorIndex[3] = detectorIndex[4];
676       detectorIndex[4] = dummy;
677
678       if (fVerbose==2) {
679         if (detectorIndex[0]<10) ftxt  << "  ->  " << detectorIndex[0];
680         else              ftxt  << "  -> " << detectorIndex[0];
681         ftxt << "  " << detectorIndex[1];
682         if (detectorIndex[2]<10) ftxt << "  " << detectorIndex[2];
683         else              ftxt << " " << detectorIndex[2];
684         ftxt << "  " << detectorIndex[3];
685         if (detectorIndex[4]<10) ftxt << "  " << detectorIndex[4];
686         else              ftxt << " " << detectorIndex[4];
687       }
688
689     /* check valid index */
690     if (detectorIndex[0]==-1||detectorIndex[1]==-1||detectorIndex[2]==-1||detectorIndex[3]==-1||detectorIndex[4]==-1) continue;
691
692       // Do not reconstruct anything in the holes
693       if (detectorIndex[0]==13 || detectorIndex[0]==14 || detectorIndex[0]==15 ) { // sectors with holes
694         if (detectorIndex[1]==2) { // plate with holes
695           inholes++;
696           continue;
697         }
698       }
699
700       parTOF[0] = tofRawDatum->GetTOF(); // TDC
701       parTOF[1] = tofRawDatum->GetTOT(); // TOT
702       parTOF[2] = tofRawDatum->GetTOT(); // raw data have ADC=TOT
703       parTOF[3] = -1; //raw data: no track of the undecalib sim time
704       parTOF[4] = tofRawDatum->GetTOF(); // Raw time == TDC
705       parTOF[5] = tofRawDatum->GetDeltaBC(); // deltaBC
706       parTOF[6] = tofRawDatum->GetL0L1Latency(); // L0-L1 latency
707       Double_t posClus[3];
708       Double_t covClus[6];
709       UShort_t volIdClus=GetClusterVolIndex(detectorIndex);
710       Int_t lab[3]={-1,-1,-1};
711       Bool_t status=kTRUE;
712       GetClusterPars(detectorIndex,posClus,covClus);
713       AliTOFcluster *tofCluster = new AliTOFcluster(volIdClus,posClus[0],posClus[1],posClus[2],covClus[0],covClus[1],covClus[2],covClus[3],covClus[4],covClus[5],lab,detectorIndex,parTOF,status,-1);
714       InsertCluster(tofCluster);
715
716       if (fVerbose==2) {
717         if (parTOF[1]<10)ftxt << "        " << parTOF[1];
718         else if (parTOF[1]>=10 && parTOF[1]<100) ftxt << "      " << parTOF[1];
719         else ftxt << "      " << parTOF[1];
720         if (parTOF[0]<10) ftxt << "      " << parTOF[0] << endl;
721         else if (parTOF[0]>=10 && parTOF[0]<100)   ftxt << "    " << parTOF[0] << endl;
722         else if (parTOF[0]>=100 && parTOF[0]<1000) ftxt << "    " << parTOF[0] << endl;
723         else ftxt << "   " << parTOF[3] << endl;
724       }
725
726     } // closed loop on TOF raw data per current DDL file
727
728     clonesRawData->Clear();
729
730   } // closed loop on DDL index
731
732   if (fVerbose==2) ftxt.close();
733
734   AliDebug(1,Form("Number of found clusters: %d for event: %d", fNumberOfTofClusters, iEvent));
735
736   CalibrateRecPoint(rawReader->GetTimestamp());
737   FillRecPoint();
738
739   fTreeR->Fill();
740   ResetRecpoint();
741
742   fTOFLoader = fRunLoader->GetLoader("TOFLoader");
743   fTOFLoader->WriteRecPoints("OVERWRITE");
744   
745   AliDebug(1, Form("Execution time to read TOF raw data and to write TOF clusters : R:%.4fs C:%.4fs",
746                stopwatch.RealTime(),stopwatch.CpuTime()));
747   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
748
749 }
750 //______________________________________________________________________________
751
752 void AliTOFClusterFinder::Raw2Digits(Int_t iEvent, AliRawReader *rawReader)
753 {
754   //
755   // Converts RAW data to MC digits for TOF
756   //
757   //             (temporary solution)
758   //
759
760   TStopwatch stopwatch;
761   stopwatch.Start();
762
763   const Int_t kDDL = AliTOFGeometry::NDDL()*AliTOFGeometry::NSectors();
764
765   fRunLoader->GetEvent(iEvent);
766
767   fTreeD = fTOFLoader->TreeD();
768   if (fTreeD)
769     {
770     AliInfo("TreeD re-creation");
771     fTreeD = 0x0;
772     fTOFLoader->MakeTree("D");
773     fTreeD = fTOFLoader->TreeD();
774     }
775
776   TClonesArray *tofDigits = new TClonesArray("AliTOFdigit",10000);
777   Int_t bufsize = 32000;
778   fTreeD->Branch("TOF", &tofDigits, bufsize);
779
780   fRunLoader->GetEvent(iEvent);
781
782   AliDebug(2,Form(" Event number %2d ", iEvent));
783
784   TClonesArray * clonesRawData;
785
786   Int_t dummy = -1;
787
788   Int_t detectorIndex[5];
789   Int_t digit[4];
790
791   //AliTOFRawStream tofInput(rawReader);
792   fTOFRawStream.Clear();
793   fTOFRawStream.SetRawReader(rawReader);
794
795   if (fDecoderVersion)
796     AliInfo("Using New Decoder");
797
798   Int_t indexDDL = 0;
799   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
800
801     rawReader->Reset();
802     if (fDecoderVersion)
803       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
804     else fTOFRawStream.LoadRawData(indexDDL);
805
806     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
807
808     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
809
810       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
811
812       //if (!tofRawDatum->GetTOT() || !tofRawDatum->GetTOF()) continue;
813       if (tofRawDatum->GetTOF()==-1) continue;
814
815       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
816                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
817       dummy = detectorIndex[3];
818       detectorIndex[3] = detectorIndex[4];
819       detectorIndex[4] = dummy;
820
821       digit[0] = fTOFRawStream.GetTofBin();
822       digit[1] = fTOFRawStream.GetToTbin();
823       digit[2] = fTOFRawStream.GetToTbin();
824       digit[3] = -1;
825
826       Int_t tracknum[3]={-1,-1,-1};
827
828       TClonesArray &aDigits = *tofDigits;
829       Int_t last=tofDigits->GetEntriesFast();
830       new (aDigits[last]) AliTOFdigit(tracknum, detectorIndex, digit);
831
832     } // while loop
833
834     clonesRawData->Clear();
835
836   } // DDL Loop
837
838   fTreeD->Fill();
839
840   fTOFLoader = fRunLoader->GetLoader("TOFLoader");
841   fTOFLoader->WriteDigits("OVERWRITE");
842
843   delete tofDigits;
844
845   AliDebug(1, Form("Execution time to read TOF raw data and to write TOF clusters : R:%.2fs C:%.2fs",
846                    stopwatch.RealTime(),stopwatch.CpuTime()));
847
848 }
849
850 //______________________________________________________________________________
851
852 void AliTOFClusterFinder::Raw2Digits(AliRawReader *rawReader, TTree* digitsTree)
853 {
854   //
855   // Converts RAW data to MC digits for TOF for the current event
856   //
857   //
858
859   TStopwatch stopwatch;
860   stopwatch.Start();
861
862   const Int_t kDDL = AliTOFGeometry::NDDL()*AliTOFGeometry::NSectors();
863
864   if (!digitsTree)
865     {
866     AliError("No input digits Tree");
867     return;
868     }
869
870   TClonesArray *tofDigits = new TClonesArray("AliTOFdigit",10000);
871   Int_t bufsize = 32000;
872   digitsTree->Branch("TOF", &tofDigits, bufsize);
873
874   TClonesArray * clonesRawData;
875
876   Int_t dummy = -1;
877
878   Int_t detectorIndex[5];
879   Int_t digit[4];
880
881   //AliTOFRawStream tofInput(rawReader);
882   fTOFRawStream.Clear();
883   fTOFRawStream.SetRawReader(rawReader);
884
885   if (fDecoderVersion)
886     AliInfo("Using New Decoder");
887
888   Int_t indexDDL = 0;
889   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
890
891     rawReader->Reset();
892     if (fDecoderVersion)
893       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
894     else fTOFRawStream.LoadRawData(indexDDL);
895
896     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
897
898     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
899
900       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
901
902       //if (!tofRawDatum->GetTOT() || !tofRawDatum->GetTOF()) continue;
903       if (tofRawDatum->GetTOF()==-1) continue;
904
905       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
906                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
907       dummy = detectorIndex[3];
908       detectorIndex[3] = detectorIndex[4];
909       detectorIndex[4] = dummy;
910
911       digit[0] = fTOFRawStream.GetTofBin();
912       digit[1] = fTOFRawStream.GetToTbin();
913       digit[2] = fTOFRawStream.GetToTbin();
914       digit[3] = -1;
915
916       Int_t tracknum[3]={-1,-1,-1};
917
918       TClonesArray &aDigits = *tofDigits;
919       Int_t last=tofDigits->GetEntriesFast();
920       new (aDigits[last]) AliTOFdigit(tracknum, detectorIndex, digit);
921
922     } // while loop
923
924     clonesRawData->Clear();
925
926   } // DDL Loop
927
928   digitsTree->Fill();
929
930   delete tofDigits;
931
932   AliDebug(1, Form("Got %d digits: ", fDigits->GetEntries()));
933   AliDebug(1, Form("Execution time to read TOF raw data and fill TOF digit tree : R:%.2fs C:%.2fs",
934                    stopwatch.RealTime(),stopwatch.CpuTime()));
935
936 }
937 //______________________________________________________________________________
938
939 Int_t AliTOFClusterFinder::InsertCluster(AliTOFcluster *tofCluster) {
940   //---------------------------------------------------------------------------//
941   // This function adds a TOF cluster to the array of TOF clusters sorted in Z //
942   //---------------------------------------------------------------------------//
943   if (fNumberOfTofClusters==kTofMaxCluster) {
944     AliError("Too many clusters !");
945     return 1;
946   }
947
948   if (fNumberOfTofClusters==0) {
949     fTofClusters[fNumberOfTofClusters++] = tofCluster;
950     return 0;
951   }
952
953   Int_t ii = FindClusterIndex(tofCluster->GetZ());
954   memmove(fTofClusters+ii+1 ,fTofClusters+ii,(fNumberOfTofClusters-ii)*sizeof(AliTOFcluster*));
955   fTofClusters[ii] = tofCluster;
956   fNumberOfTofClusters++;
957   
958   return 0;
959
960 }
961 //_________________________________________________________________________
962
963 Int_t AliTOFClusterFinder::FindClusterIndex(Double_t z) const {
964   //--------------------------------------------------------------------
965   // This function returns the index of the nearest cluster in z
966   //--------------------------------------------------------------------
967   if (fNumberOfTofClusters==0) return 0;
968   if (z <= fTofClusters[0]->GetZ()) return 0;
969   if (z > fTofClusters[fNumberOfTofClusters-1]->GetZ()) return fNumberOfTofClusters;
970   Int_t b = 0, e = fNumberOfTofClusters-1, m = (b+e)/2;
971   for (; b<e; m=(b+e)/2) {
972     if (z > fTofClusters[m]->GetZ()) b=m+1;
973     else e=m;
974   }
975
976   return m;
977
978 }
979 //_________________________________________________________________________
980
981 void AliTOFClusterFinder::FillRecPoint()
982 {
983   //
984   // Copy the global array of AliTOFcluster, i.e. fTofClusters (sorted
985   // in Z) in the global TClonesArray of AliTOFcluster,
986   // i.e. fRecPoints.
987   //
988
989   Int_t ii, jj;
990
991   Int_t detectorIndex[5];
992   Int_t parTOF[7];
993   Int_t trackLabels[3];
994   Int_t digitIndex = -1;
995   Bool_t status=kTRUE;
996
997   TClonesArray &lRecPoints = *fRecPoints;
998   
999   for (ii=0; ii<fNumberOfTofClusters; ii++) {
1000
1001     digitIndex = fTofClusters[ii]->GetIndex();
1002     for(jj=0; jj<5; jj++) detectorIndex[jj] = fTofClusters[ii]->GetDetInd(jj);
1003     for(jj=0; jj<3; jj++) trackLabels[jj] = fTofClusters[ii]->GetLabel(jj);
1004     parTOF[0] = fTofClusters[ii]->GetTDC(); // TDC
1005     parTOF[1] = fTofClusters[ii]->GetToT(); // TOT
1006     parTOF[2] = fTofClusters[ii]->GetADC(); // ADC=TOT
1007     parTOF[3] = fTofClusters[ii]->GetTDCND(); // TDCND
1008     parTOF[4] = fTofClusters[ii]->GetTDCRAW();//RAW
1009     parTOF[5] = fTofClusters[ii]->GetDeltaBC();//deltaBC
1010     parTOF[6] = fTofClusters[ii]->GetL0L1Latency();//L0-L1 latency
1011     status=fTofClusters[ii]->GetStatus();
1012     Double_t posClus[3];
1013     Double_t covClus[6];
1014     UShort_t volIdClus=GetClusterVolIndex(detectorIndex);
1015     GetClusterPars(detectorIndex,posClus,covClus);
1016     new(lRecPoints[ii]) AliTOFcluster(volIdClus,posClus[0],posClus[1],posClus[2],covClus[0],covClus[1],covClus[2],covClus[3],covClus[4],covClus[5],trackLabels,detectorIndex, parTOF,status,digitIndex);
1017
1018     AliDebug(2, Form(" %4d  %4d  %f %f %f  %f %f %f %f %f %f  %3d %3d %3d  %2d %1d %2d %1d %2d  %4d %3d %3d %4d %4d  %1d  %4d", 
1019                      ii, volIdClus, posClus[0], posClus[1], posClus[2],
1020                      fTofClusters[ii]->GetSigmaX2(),
1021                      fTofClusters[ii]->GetSigmaXY(),
1022                      fTofClusters[ii]->GetSigmaXZ(),
1023                      fTofClusters[ii]->GetSigmaY2(),
1024                      fTofClusters[ii]->GetSigmaYZ(),
1025                      fTofClusters[ii]->GetSigmaZ2(),
1026                      trackLabels[0], trackLabels[1], trackLabels[2],
1027                      detectorIndex[0], detectorIndex[1], detectorIndex[2], detectorIndex[3], detectorIndex[4],
1028                      parTOF[0], parTOF[1], parTOF[2], parTOF[3], parTOF[4],
1029                      status, digitIndex));
1030
1031   } // loop on clusters
1032
1033 }
1034
1035 //_________________________________________________________________________
1036 void AliTOFClusterFinder::CalibrateRecPoint(UInt_t timestamp)
1037 {
1038   //
1039   // Copy the global array of AliTOFcluster, i.e. fTofClusters (sorted
1040   // in Z) in the global TClonesArray of AliTOFcluster,
1041   // i.e. fRecPoints.
1042   //
1043
1044   Int_t ii, jj;
1045
1046   Int_t detectorIndex[5];
1047   Int_t digitIndex = -1;
1048   Double_t tToT;
1049   Double_t timeCorr;
1050   Int_t   tdcCorr;
1051   Float_t tdcLatencyWindow;
1052   AliDebug(1," Calibrating TOF Clusters");
1053
1054   AliTOFChannelOnlineArray *calDelay = fTOFcalib->GetTOFOnlineDelay();  
1055   AliTOFChannelOnlineStatusArray *calStatus = fTOFcalib->GetTOFOnlineStatus();  
1056   TObjArray *calTOFArrayOffline = fTOFcalib->GetTOFCalArrayOffline();
1057   
1058   AliTOFDeltaBCOffset *deltaBCOffsetObj = fTOFcalib->GetDeltaBCOffset();
1059   Int_t deltaBCOffset = deltaBCOffsetObj->GetDeltaBCOffset();
1060   AliTOFCTPLatency *ctpLatencyObj = fTOFcalib->GetCTPLatency();
1061   Float_t ctpLatency = ctpLatencyObj->GetCTPLatency();
1062   AliTOFRunParams *runParamsObj = fTOFcalib->GetRunParams();
1063   Float_t t0 = runParamsObj->EvalT0(timestamp);
1064
1065   TString validity = (TString)fTOFcalib->GetOfflineValidity();
1066   Int_t calibration = -1;
1067   if (validity.CompareTo("valid")==0) {
1068     //AliInfo(Form(" validity = %s - Using offline calibration parameters",validity.Data()));
1069     calibration = 1;
1070   } else {
1071     //AliInfo(Form(" validity = %s - Using online calibration parameters",validity.Data()));
1072     calibration = 0 ;
1073   }
1074
1075   for (ii=0; ii<fNumberOfTofClusters; ii++) {
1076     digitIndex = fTofClusters[ii]->GetIndex();
1077     for(jj=0; jj<5; jj++) detectorIndex[jj] = fTofClusters[ii]->GetDetInd(jj);
1078
1079     Int_t index = AliTOFGeometry::GetIndex(detectorIndex);
1080      
1081     UChar_t statusPulser=calStatus->GetPulserStatus(index);
1082     UChar_t statusNoise=calStatus->GetNoiseStatus(index);
1083     UChar_t statusHW=calStatus->GetHWStatus(index);
1084     UChar_t status=calStatus->GetStatus(index);
1085     tdcLatencyWindow = calStatus->GetLatencyWindow(index) * 1.e3; /* ns -> ps */
1086     
1087     //check the status, also unknown is fine!!!!!!!
1088
1089     AliDebug(2, Form(" Status for channel %d = %d",index, (Int_t)status));
1090     if((statusPulser & AliTOFChannelOnlineStatusArray::kTOFPulserBad)==(AliTOFChannelOnlineStatusArray::kTOFPulserBad)||(statusNoise & AliTOFChannelOnlineStatusArray::kTOFNoiseBad)==(AliTOFChannelOnlineStatusArray::kTOFNoiseBad)||(statusHW & AliTOFChannelOnlineStatusArray::kTOFHWBad)==(AliTOFChannelOnlineStatusArray::kTOFHWBad)){
1091       AliDebug(2, Form(" Bad Status for channel %d",index));
1092       fTofClusters[ii]->SetStatus(kFALSE); //odd convention, to avoid conflict with calibration objects currently in the db (temporary solution).
1093     }
1094     else {
1095       AliDebug(2, Form(" Good Status for channel %d",index));
1096     }
1097     // Get Rough channel online equalization 
1098     Double_t roughDelay=(Double_t)calDelay->GetDelay(index);  // in ns
1099     AliDebug(2,Form(" channel delay (ns) = %f", roughDelay));
1100     // Get Refined channel offline calibration parameters
1101     if (calibration ==1){
1102       AliTOFChannelOffline * calChannelOffline = (AliTOFChannelOffline*)calTOFArrayOffline->At(index);
1103       Double_t par[6];
1104       for (Int_t j = 0; j<6; j++){
1105         par[j]=(Double_t)calChannelOffline->GetSlewPar(j);
1106      } 
1107       AliDebug(2,Form(" Calib Pars = %f, %f, %f, %f, %f, %f ",par[0],par[1],par[2],par[3],par[4],par[5]));
1108       AliDebug(2,Form(" The ToT and Time, uncorr (counts) = %d , %d", fTofClusters[ii]->GetToT(),fTofClusters[ii]->GetTDC()));
1109       tToT = (Double_t)(fTofClusters[ii]->GetToT()*AliTOFGeometry::ToTBinWidth());    
1110       tToT*=1.E-3; //ToT in ns
1111
1112       /* check TOT limits and set new TOT in case */
1113       if (tToT < AliTOFGeometry::SlewTOTMin()) tToT = AliTOFGeometry::SlewTOTMin();
1114       if (tToT > AliTOFGeometry::SlewTOTMax()) tToT = AliTOFGeometry::SlewTOTMax();
1115
1116       AliDebug(2,Form(" The ToT and Time, uncorr (ns)= %e, %e",fTofClusters[ii]->GetTDC()*AliTOFGeometry::TdcBinWidth()*1.E-3,tToT));
1117       timeCorr=par[0]+par[1]*tToT+par[2]*tToT*tToT+par[3]*tToT*tToT*tToT+par[4]*tToT*tToT*tToT*tToT+par[5]*tToT*tToT*tToT*tToT*tToT; // the time correction (ns)
1118     }
1119     else {
1120       timeCorr = roughDelay; // correction in ns
1121     }
1122     AliDebug(2,Form(" The ToT and Time, uncorr (ns)= %e, %e",fTofClusters[ii]->GetTDC()*AliTOFGeometry::TdcBinWidth()*1.E-3,fTofClusters[ii]->GetToT()*AliTOFGeometry::ToTBinWidth()));
1123     AliDebug(2,Form(" The time correction (ns) = %f", timeCorr));
1124     timeCorr=(Double_t)(fTofClusters[ii]->GetTDC())*AliTOFGeometry::TdcBinWidth()*1.E-3-timeCorr;//redefine the time
1125     timeCorr*=1.E3;
1126     AliDebug(2,Form(" The channel time, corr (ps)= %e",timeCorr ));
1127
1128     /* here timeCorr should be already corrected for calibration. 
1129      * we now go into further corrections keeping in mind that timeCorr
1130      * is in ps.
1131      *
1132      * the following corrections are performed in this way:
1133      *
1134      *    time = timeRaw - deltaBC + L0L1Latency + CTPLatency - TDCLatencyWindow - T0
1135      *
1136      */
1137
1138     AliDebug(2, Form("applying further corrections (DeltaBC): DeltaBC=%d (BC bins), DeltaBCoffset=%d (BC bins)", fTofClusters[ii]->GetDeltaBC(), deltaBCOffset));
1139     AliDebug(2, Form("applying further corrections (L0L1Latency): L0L1Latency=%d (BC bins)", fTofClusters[ii]->GetL0L1Latency()));
1140     AliDebug(2, Form("applying further corrections (CTPLatency): CTPLatency=%f (ps)", ctpLatency));
1141     AliDebug(2, Form("applying further corrections (TDCLatencyWindow): TDCLatencyWindow=%f (ps)", tdcLatencyWindow));
1142     AliDebug(2, Form("applying further corrections (T0): T0=%f (ps)", t0));
1143
1144     /* deltaBC correction (inhibited for the time being) */
1145     //    timeCorr -= (fTofClusters[ii]->GetDeltaBC() - deltaBCOffset) * AliTOFGeometry::BunchCrossingBinWidth();
1146     /* L0L1-latency correction */
1147     timeCorr += fTofClusters[ii]->GetL0L1Latency() * AliTOFGeometry::BunchCrossingBinWidth();
1148     /* CTP-latency correction (from OCDB) */
1149     timeCorr += ctpLatency;
1150     /* TDC latency-window correction (from OCDB) */
1151     timeCorr -= tdcLatencyWindow;
1152     /* T0 correction (from OCDB) */
1153     timeCorr -= t0;
1154
1155     /*
1156      * end of furhter corrections
1157      */
1158
1159     tdcCorr=(Int_t)(timeCorr/AliTOFGeometry::TdcBinWidth()); //the corrected time (tdc counts)
1160     fTofClusters[ii]->SetTDC(tdcCorr);
1161   } // loop on clusters
1162
1163 }
1164 //______________________________________________________________________________
1165
1166 void AliTOFClusterFinder::ResetRecpoint()
1167 {
1168   //
1169   // Clear the list of reconstructed points
1170   //
1171
1172   fNumberOfTofClusters = 0;
1173   if (fRecPoints) fRecPoints->Clear();
1174
1175 }
1176 //______________________________________________________________________________
1177
1178 void AliTOFClusterFinder::Load()
1179 {
1180   //
1181   // Load TOF.Digits.root and TOF.RecPoints.root files
1182   //
1183
1184   fTOFLoader->LoadDigits("READ");
1185   fTOFLoader->LoadRecPoints("recreate");
1186
1187 }
1188 //______________________________________________________________________________
1189
1190 void AliTOFClusterFinder::LoadClusters()
1191 {
1192   //
1193   // Load TOF.RecPoints.root file
1194   //
1195
1196   fTOFLoader->LoadRecPoints("recreate");
1197
1198 }
1199 //______________________________________________________________________________
1200
1201 void AliTOFClusterFinder::UnLoad()
1202 {
1203   //
1204   // Unload TOF.Digits.root and TOF.RecPoints.root files
1205   //
1206
1207   fTOFLoader->UnloadDigits();
1208   fTOFLoader->UnloadRecPoints();
1209
1210 }
1211 //______________________________________________________________________________
1212
1213 void AliTOFClusterFinder::UnLoadClusters()
1214 {
1215   //
1216   // Unload TOF.RecPoints.root file
1217   //
1218
1219   fTOFLoader->UnloadRecPoints();
1220
1221 }
1222 //-------------------------------------------------------------------------
1223 UShort_t AliTOFClusterFinder::GetClusterVolIndex(const Int_t * const ind) const {
1224
1225   //First of all get the volume ID to retrieve the l2t transformation...
1226   //
1227   // Detector numbering scheme
1228   Int_t nSector = 18;
1229   Int_t nPlate  = 5;
1230   Int_t nStripA = 15;
1231   Int_t nStripB = 19;
1232   Int_t nStripC = 19;
1233
1234   Int_t isector =ind[0];
1235   if (isector >= nSector)
1236     AliError(Form("Wrong sector number in TOF (%d) !",isector));
1237   Int_t iplate = ind[1];
1238   if (iplate >= nPlate)
1239     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
1240   Int_t istrip = ind[2];
1241
1242   Int_t stripOffset = 0;
1243   switch (iplate) {
1244   case 0:
1245     stripOffset = 0;
1246     break;
1247   case 1:
1248     stripOffset = nStripC;
1249     break;
1250   case 2:
1251     stripOffset = nStripC+nStripB;
1252     break;
1253   case 3:
1254     stripOffset = nStripC+nStripB+nStripA;
1255     break;
1256   case 4:
1257     stripOffset = nStripC+nStripB+nStripA+nStripB;
1258     break;
1259   default:
1260     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
1261     break;
1262   };
1263
1264   Int_t index= (2*(nStripC+nStripB)+nStripA)*isector +
1265                stripOffset +
1266                istrip;
1267
1268   UShort_t volIndex = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,index);
1269   return volIndex;
1270 }
1271 //
1272 //-------------------------------------------------------------------------
1273 void AliTOFClusterFinder::GetClusterPars(Int_t *ind, Double_t* pos,Double_t* cov) const {
1274
1275   //First of all get the volume ID to retrieve the l2t transformation...
1276   //
1277   UShort_t volIndex = GetClusterVolIndex(ind);
1278   //
1279   //
1280   //we now go in the system of the strip: determine the local coordinates
1281   //
1282   //
1283   // 47---------------------------------------------------0  ^ z
1284   // | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 |
1285   // -----------------------------------------------------   | y going outwards
1286   // | | | | | | | | | | | | | | | | | | | | | | | | | | | 0 |  par[0]=0;
1287
1288   // -----------------------------------------------------   |
1289   // x <-----------------------------------------------------
1290
1291   /*
1292   Float_t localX = (ind[4]-23.5)*AliTOFGeometry::XPad();
1293   Float_t localY = 0;
1294   Float_t localZ = (ind[3]- 0.5)*AliTOFGeometry::ZPad();
1295   */
1296   Float_t localX = (ind[4]-AliTOFGeometry::NpadX()/2)*AliTOFGeometry::XPad()+AliTOFGeometry::XPad()/2.;
1297   Float_t localY = 0;
1298   Float_t localZ = (ind[3]-AliTOFGeometry::NpadZ()/2)*AliTOFGeometry::ZPad()+AliTOFGeometry::ZPad()/2.;
1299   //move to the tracking ref system
1300
1301   Double_t lpos[3];
1302   lpos[0] = localX;
1303   lpos[1] = localY;
1304   lpos[2] = localZ; 
1305
1306   const TGeoHMatrix *l2t= AliGeomManager::GetTracking2LocalMatrix(volIndex);
1307   // Get The position in the track ref system
1308   Double_t tpos[3];
1309   l2t->MasterToLocal(lpos,tpos);
1310   pos[0] = tpos[0];
1311   pos[1] = tpos[1];
1312   pos[2] = tpos[2];
1313
1314   //Get The cluster covariance in the track ref system
1315   Double_t lcov[9];
1316
1317   //cluster covariance in the local system:
1318   // sx2   0   0
1319   // 0     0   0
1320   // 0     0   sz2
1321
1322   lcov[0] = AliTOFGeometry::XPad()*AliTOFGeometry::XPad()/12.;
1323   lcov[1] = 0;
1324   lcov[2] = 0;
1325   lcov[3] = 0;
1326   lcov[4] = 0;
1327   lcov[5] = 0;
1328   lcov[6] = 0;
1329   lcov[7] = 0;
1330   lcov[8] = AliTOFGeometry::ZPad()*AliTOFGeometry::ZPad()/12.;
1331
1332   //cluster covariance in the tracking system:
1333   TGeoHMatrix m;
1334   m.SetRotation(lcov);
1335   m.Multiply(l2t);
1336   m.MultiplyLeft(&l2t->Inverse());
1337   Double_t *tcov = m.GetRotationMatrix();
1338   cov[0] = tcov[0]; cov[1] = tcov[1]; cov[2] = tcov[2];
1339   cov[3] = tcov[4]; cov[4] = tcov[5];
1340   cov[5] = tcov[8];
1341
1342   return;
1343
1344 }