Removing the tasks from the digitization (Ruben)
[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
133 #include "AliTOFDeltaBCOffset.h"
134 #include "AliTOFCTPLatency.h"
135 #include "AliTOFRunParams.h"
136
137 //extern TFile *gFile;
138
139 ClassImp(AliTOFClusterFinder)
140
141 AliTOFClusterFinder::AliTOFClusterFinder(AliTOFcalib *calib):
142   TNamed("AliTOFClusterFinder",""),
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   for (Int_t ii=0; ii<kTofMaxCluster; ii++) fTofClusters[ii]=0x0;
160
161   TString validity = (TString)fTOFcalib->GetOfflineValidity();
162   if (validity.CompareTo("valid")==0) {
163     AliInfo(Form(" validity = %s - Using offline calibration parameters",validity.Data()));
164   } else {
165     AliInfo(Form(" validity = %s - Using online calibration parameters",validity.Data()));
166   }
167
168 }
169
170 //______________________________________________________________________________
171
172 AliTOFClusterFinder::AliTOFClusterFinder(AliRunLoader* runLoader, AliTOFcalib *calib):
173   TNamed("AliTOFClusterFinder",""),
174   fRunLoader(runLoader),
175   fTOFLoader(runLoader->GetLoader("TOFLoader")),
176   fTreeD(0),
177   fTreeR(0),
178   fDigits(new TClonesArray("AliTOFdigit", 4000)),
179   fRecPoints(new TClonesArray("AliTOFcluster", 4000)),
180   fNumberOfTofClusters(0),
181   fVerbose(0),
182   fDecoderVersion(0),
183   fTOFcalib(calib),
184   fTOFRawStream(AliTOFRawStream())
185 {
186 //
187 // Constructor
188 //
189
190   for (Int_t ii=0; ii<kTofMaxCluster; ii++) fTofClusters[ii]=0x0;
191
192   TString validity = (TString)fTOFcalib->GetOfflineValidity();
193   if (validity.CompareTo("valid")==0) {
194     AliInfo(Form(" validity = %s - Using offline calibration parameters",validity.Data()));
195   } else {
196     AliInfo(Form(" validity = %s - Using online calibration parameters",validity.Data()));
197   }
198
199 }
200
201 //------------------------------------------------------------------------
202 AliTOFClusterFinder::AliTOFClusterFinder(const AliTOFClusterFinder &source) :
203   TNamed(source),
204   fRunLoader(0),
205   fTOFLoader(0),
206   fTreeD(0),
207   fTreeR(0),
208   fDigits(source.fDigits),
209   fRecPoints(source.fRecPoints),
210   fNumberOfTofClusters(0),
211   fVerbose(0),
212   fDecoderVersion(source.fDecoderVersion),
213   fTOFcalib(source.fTOFcalib),
214   fTOFRawStream(source.fTOFRawStream)
215 {
216   // copy constructor
217
218   for (Int_t ii=0; ii<kTofMaxCluster; ii++) fTofClusters[ii]=source.fTofClusters[ii];
219
220 }
221
222 //------------------------------------------------------------------------
223 AliTOFClusterFinder& AliTOFClusterFinder::operator=(const AliTOFClusterFinder &source)
224 {
225   // ass. op.
226
227   if (this == &source)
228     return *this;
229
230   TNamed::operator=(source);  
231   fDigits=source.fDigits;
232   fRecPoints=source.fRecPoints;
233   fVerbose=source.fVerbose;
234   fDecoderVersion=source.fDecoderVersion;
235   fTOFcalib=source.fTOFcalib;
236   fTOFRawStream=source.fTOFRawStream;
237   for (Int_t ii=0; ii<kTofMaxCluster; ii++) fTofClusters[ii]=source.fTofClusters[ii];
238
239   return *this;
240
241 }
242 //______________________________________________________________________________
243
244 AliTOFClusterFinder::~AliTOFClusterFinder()
245 {
246
247   //
248   // Destructor
249   //
250
251   if (fDigits)
252     {
253       fDigits->Delete();
254       delete fDigits;
255       fDigits=0;
256     }
257   if (fRecPoints)
258     {
259       fRecPoints->Delete();
260       delete fRecPoints;
261       fRecPoints=0;
262     }
263
264   //if (fTofClusters || fNumberOfTofClusters) {
265   if (fNumberOfTofClusters) {
266     for (Int_t ii=0; ii<kTofMaxCluster; ii++) {
267       if (fTofClusters[ii]) fTofClusters[ii]->Delete();
268       delete fTofClusters[ii];
269     }
270     fNumberOfTofClusters=0;
271    }
272
273 }
274 //______________________________________________________________________________
275
276 void AliTOFClusterFinder::Digits2RecPoints(Int_t iEvent)
277 {
278   //
279   // Converts digits to recpoints for TOF
280   //
281
282   TStopwatch stopwatch;
283   stopwatch.Start();
284
285   Int_t inholes = 0;
286
287   fRunLoader->GetEvent(iEvent);
288
289   fTreeD = fTOFLoader->TreeD();
290   if (fTreeD == 0x0) {
291     AliFatal("AliTOFClusterFinder: Can not get TreeD");
292     return;
293   }
294
295   fDigits->Clear();
296   fTreeD->GetBranch("TOF")->SetAutoDelete(kFALSE);
297   fTreeD->SetBranchAddress("TOF",&fDigits);
298
299   ResetRecpoint();
300
301   fTreeR = fTOFLoader->TreeR();
302   if (fTreeR == 0x0)
303     {
304       fTOFLoader->MakeTree("R");
305       fTreeR = fTOFLoader->TreeR();
306     }
307
308   Int_t bufsize = 32000;
309   fTreeR->Branch("TOF", &fRecPoints, bufsize);
310
311   fTreeD->GetEvent(0);
312   Int_t nDigits = fDigits->GetEntriesFast();
313   AliDebug(2,Form("Number of TOF digits: %d",nDigits));
314
315   Int_t ii;
316   Int_t dig[5]={-1,-1,-1,-1,-1}; //cluster detector indeces
317   Int_t parTOF[7]={0,0,0,0,0,0,0}; //The TOF signal parameters
318   Bool_t status=kTRUE; // assume all sim channels ok in the beginning...
319   for (ii=0; ii<nDigits; ii++) {
320     AliTOFdigit *d = (AliTOFdigit*)fDigits->UncheckedAt(ii);
321     dig[0]=d->GetSector();
322     dig[1]=d->GetPlate();
323     dig[2]=d->GetStrip();
324     dig[3]=d->GetPadz();
325     dig[4]=d->GetPadx();
326
327     /* check valid index */
328     if (dig[0]==-1||dig[1]==-1||dig[2]==-1||dig[3]==-1||dig[4]==-1) continue;
329
330     // Do not reconstruct anything in the holes
331     if (dig[0]==13 || dig[0]==14 || dig[0]==15 ) { // sectors with holes
332       if (dig[1]==2) { // plate with holes
333         inholes++;
334         continue;
335       }
336     }
337
338     AliDebug(2,Form(" %2d  %1d  %2d  %1d  %2d ",dig[0],dig[1],dig[2],dig[3],dig[4]));
339
340     parTOF[0] = d->GetTdc(); //the TDC signal
341     parTOF[1] = d->GetToT(); //the ToT signal
342     parTOF[2] = d->GetAdc(); // the adc charge
343     parTOF[3] = d->GetTdcND(); // non decalibrated sim time
344     parTOF[4] = d->GetTdc(); // raw time, == Tdc time for the moment
345     parTOF[5] = 0; // deltaBC
346     parTOF[6] = 0; // L0-L1 latency
347     Double_t posClus[3];
348     Double_t covClus[6];
349     UShort_t volIdClus=GetClusterVolIndex(dig);
350     GetClusterPars(dig, posClus,covClus);
351     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);
352     InsertCluster(tofCluster);
353
354   }
355
356   AliDebug(1,Form("Number of found clusters: %d for event: %d", fNumberOfTofClusters, iEvent));
357
358   CalibrateRecPoint();
359   FillRecPoint();
360
361   fTreeR->Fill();
362   ResetRecpoint();
363
364   fTOFLoader = fRunLoader->GetLoader("TOFLoader");  
365   fTOFLoader->WriteRecPoints("OVERWRITE");
366
367   AliDebug(1,Form("Execution time to read TOF digits and to write TOF clusters : R:%.4fs C:%.4fs",
368                   stopwatch.RealTime(),stopwatch.CpuTime()));
369   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
370
371 }
372
373 //______________________________________________________________________________
374
375 void AliTOFClusterFinder::Digits2RecPoints(TTree* digitsTree, TTree* clusterTree)
376 {
377   //
378   // Converts digits to recpoints for TOF
379   //
380
381   TStopwatch stopwatch;
382   stopwatch.Start();
383
384   Int_t inholes = 0;
385
386   if (digitsTree == 0x0) {
387     AliFatal("AliTOFClusterFinder: Can not get TreeD");
388     return;
389   }
390
391   fDigits->Clear();
392   digitsTree->GetBranch("TOF")->SetAutoDelete(kFALSE);
393   digitsTree->SetBranchAddress("TOF",&fDigits);
394
395   ResetRecpoint();
396   Int_t bufsize = 32000;
397   clusterTree->Branch("TOF", &fRecPoints, bufsize);
398
399   digitsTree->GetEvent(0);
400   Int_t nDigits = fDigits->GetEntriesFast();
401   AliDebug(2,Form("Number of TOF digits: %d",nDigits));
402
403   Int_t ii;
404   Int_t dig[5]={-1,-1,-1,-1,-1}; //cluster detector indeces
405   Int_t parTOF[7]={0,0,0,0,0,0,0}; //The TOF signal parameters
406   Bool_t status=kTRUE; // assume all sim channels ok in the beginning...
407   for (ii=0; ii<nDigits; ii++) {
408     AliTOFdigit *d = (AliTOFdigit*)fDigits->UncheckedAt(ii);
409     dig[0]=d->GetSector();
410     dig[1]=d->GetPlate();
411     dig[2]=d->GetStrip();
412     dig[3]=d->GetPadz();
413     dig[4]=d->GetPadx();
414
415     /* check valid index */
416     if (dig[0]==-1||dig[1]==-1||dig[2]==-1||dig[3]==-1||dig[4]==-1) continue;
417
418     // Do not reconstruct anything in the holes
419     if (dig[0]==13 || dig[0]==14 || dig[0]==15 ) { // sectors with holes
420       if (dig[1]==2) { // plate with holes
421         inholes++;
422         continue;
423       }
424     }
425
426     //    AliDebug(2,Form(" %2d  %1d  %2d  %1d  %2d ",dig[0],dig[1],dig[2],dig[3],dig[4]));
427
428     parTOF[0] = d->GetTdc(); //the TDC signal
429     parTOF[1] = d->GetToT(); //the ToT signal
430     parTOF[2] = d->GetAdc(); // the adc charge
431     parTOF[3] = d->GetTdcND(); // non decalibrated sim time
432     parTOF[4] = d->GetTdc(); // raw time, == Tdc time for the moment
433     parTOF[5] = 0; // deltaBC
434     parTOF[6] = 0; // L0-L1 latency
435     
436     Double_t posClus[3];
437     Double_t covClus[6];
438     UShort_t volIdClus=GetClusterVolIndex(dig);
439     GetClusterPars(dig,posClus,covClus);
440     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);
441     InsertCluster(tofCluster);
442
443   }
444
445   AliDebug(1,Form("Number of found clusters: %d", fNumberOfTofClusters));
446
447   CalibrateRecPoint();
448   FillRecPoint();
449
450   clusterTree->Fill();
451   ResetRecpoint();
452
453   AliDebug(1,Form("Execution time to read TOF digits and to write TOF clusters : R:%.4fs C:%.4fs",
454                   stopwatch.RealTime(),stopwatch.CpuTime()));
455   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
456
457 }
458 //______________________________________________________________________________
459
460 void AliTOFClusterFinder::Digits2RecPoints(AliRawReader *rawReader,
461                                            TTree *clustersTree)
462 {
463   //
464   // Converts RAW data to recpoints for TOF
465   //
466
467   TStopwatch stopwatch;
468   stopwatch.Start();
469
470   Int_t inholes = 0;
471
472   const Int_t kDDL = AliDAQ::NumberOfDdls("TOF");
473
474   ResetRecpoint();
475
476   Int_t bufsize = 32000;
477   clustersTree->Branch("TOF", &fRecPoints, bufsize);
478
479   TClonesArray * clonesRawData;
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   fTOFRawStream.Clear();
489   fTOFRawStream.SetRawReader(rawReader);
490
491   if (fDecoderVersion == 1) {
492     AliInfo("Using New Decoder");
493   }
494   else if (fDecoderVersion == 2) {
495     AliInfo("Using Enhanced Decoder");
496   }
497   else {
498     AliInfo("Using Old Decoder");
499   }
500
501   Int_t indexDDL = 0;
502   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
503
504     rawReader->Reset();
505     if (fDecoderVersion == 1) {
506       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
507     }
508     else if (fDecoderVersion == 2) {
509       fTOFRawStream.LoadRawDataBuffersV2(indexDDL,fVerbose);
510     }
511     else  {
512       fTOFRawStream.LoadRawData(indexDDL);
513     }
514     
515     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
516
517     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
518
519       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
520
521       //if (tofRawDatum->GetTOT()==-1 || tofRawDatum->GetTOF()==-1) continue;
522       if (tofRawDatum->GetTOF()==-1) continue;
523
524       if (fVerbose==2) {
525         if (indexDDL<10) ftxt << "  " << indexDDL;
526         else         ftxt << " " << indexDDL;
527         if (tofRawDatum->GetTRM()<10) ftxt << "  " << tofRawDatum->GetTRM();
528         else         ftxt << " " << tofRawDatum->GetTRM();
529         ftxt << "  " << tofRawDatum->GetTRMchain();
530         if (tofRawDatum->GetTDC()<10) ftxt << "  " << tofRawDatum->GetTDC();
531         else         ftxt << " " << tofRawDatum->GetTDC();
532         ftxt << "  " << tofRawDatum->GetTDCchannel();
533       }
534
535       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
536                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
537       dummy = detectorIndex[3];
538       detectorIndex[3] = detectorIndex[4];
539       detectorIndex[4] = dummy;
540
541       if (fVerbose==2) {
542         if (detectorIndex[0]<10) ftxt  << "  ->  " << detectorIndex[0];
543         else              ftxt  << "  -> " << detectorIndex[0];
544         ftxt << "  " << detectorIndex[1];
545         if (detectorIndex[2]<10) ftxt << "  " << detectorIndex[2];
546         else              ftxt << " " << detectorIndex[2];
547         ftxt << "  " << detectorIndex[3];
548         if (detectorIndex[4]<10) ftxt << "  " << detectorIndex[4];
549         else              ftxt << " " << detectorIndex[4];
550       }
551
552     /* check valid index */
553     if (detectorIndex[0]==-1||detectorIndex[1]==-1||detectorIndex[2]==-1||detectorIndex[3]==-1||detectorIndex[4]==-1) continue;
554
555       // Do not reconstruct anything in the holes
556       if (detectorIndex[0]==13 || detectorIndex[0]==14 || detectorIndex[0]==15 ) { // sectors with holes
557         if (detectorIndex[1]==2) { // plate with holes
558           inholes++;
559           continue;
560         }
561       }
562
563       parTOF[0] = tofRawDatum->GetTOF(); //TDC
564       parTOF[1] = tofRawDatum->GetTOT(); // TOT
565       parTOF[2] = tofRawDatum->GetTOT(); //ADC==TOF
566       parTOF[3] = 0;//raw data: no track of undecalib sim time
567       parTOF[4] = tofRawDatum->GetTOF(); // RAW time
568       parTOF[5] = tofRawDatum->GetDeltaBC(); // deltaBC
569       parTOF[6] = tofRawDatum->GetL0L1Latency(); // L0-L1 latency
570       Double_t posClus[3];
571       Double_t covClus[6];
572       UShort_t volIdClus=GetClusterVolIndex(detectorIndex);
573       Int_t lab[3]={-1,-1,-1};
574       Bool_t status=kTRUE;
575       GetClusterPars(detectorIndex,posClus,covClus);
576       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);
577       InsertCluster(tofCluster);
578
579       if (fVerbose==2) {
580         if (parTOF[1]<10)ftxt << "        " << parTOF[1];
581         else if (parTOF[1]>=10 && parTOF[1]<100) ftxt << "      " << parTOF[1];
582         else ftxt << "      " << parTOF[1];
583         if (parTOF[0]<10) ftxt << "      " << parTOF[0] << endl;
584         else if (parTOF[0]>=10 && parTOF[0]<100)   ftxt << "    " << parTOF[0] << endl;
585         else if (parTOF[0]>=100 && parTOF[0]<1000) ftxt << "    " << parTOF[0] << endl;
586         else ftxt << "   " << parTOF[0] << endl;
587       }
588
589     } // closed loop on TOF raw data per current DDL file
590
591     clonesRawData->Clear("C");
592
593   } // closed loop on DDL index
594
595   if (fVerbose==2) ftxt.close();
596
597   AliDebug(1,Form("Number of found clusters: %d", fNumberOfTofClusters));
598
599   CalibrateRecPoint(rawReader->GetTimestamp());
600   FillRecPoint();
601
602   clustersTree->Fill();
603
604   ResetRecpoint();
605
606   AliDebug(1, Form("Execution time to read TOF raw data and to write TOF clusters : R:%.4fs C:%.4fs",
607                    stopwatch.RealTime(),stopwatch.CpuTime()));
608   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
609
610 }
611 //______________________________________________________________________________
612
613 void AliTOFClusterFinder::Digits2RecPoints(Int_t iEvent, AliRawReader *rawReader)
614 {
615   //
616   // Converts RAW data to recpoints for TOF
617   //
618
619   TStopwatch stopwatch;
620   stopwatch.Start();
621
622   Int_t inholes = 0;
623
624   const Int_t kDDL = AliDAQ::NumberOfDdls("TOF");
625
626   fRunLoader->GetEvent(iEvent);
627
628   AliDebug(2,Form(" Event number %2d ", iEvent));
629
630   fTreeR = fTOFLoader->TreeR();
631
632   if (fTreeR == 0x0){
633     fTOFLoader->MakeTree("R");
634     fTreeR = fTOFLoader->TreeR();
635   }
636
637   Int_t bufsize = 32000;
638   fTreeR->Branch("TOF", &fRecPoints, bufsize);
639
640   TClonesArray * clonesRawData;
641
642   Int_t dummy = -1;
643
644   Int_t detectorIndex[5] = {-1, -1, -1, -1, -1};
645   Int_t parTOF[7];
646   ofstream ftxt;
647   if (fVerbose==2) ftxt.open("TOFdigitsRead.txt",ios::app);
648
649   fTOFRawStream.Clear();
650   fTOFRawStream.SetRawReader(rawReader);
651
652   if (fDecoderVersion == 1) {
653     AliInfo("Using New Decoder");
654   }
655   else if (fDecoderVersion == 2) {
656     AliInfo("Using Enhanced Decoder");
657   }
658   else {
659     AliInfo("Using Old Decoder");
660   }
661
662   Int_t indexDDL = 0;
663   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
664
665     rawReader->Reset();
666     if (fDecoderVersion == 1) {
667       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
668     }
669     else if (fDecoderVersion == 2) {
670       fTOFRawStream.LoadRawDataBuffersV2(indexDDL,fVerbose);
671     }
672     else {
673       fTOFRawStream.LoadRawData(indexDDL);
674     }
675
676     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
677
678     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
679
680       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
681
682       //if (tofRawDatum->GetTOT()==-1 || tofRawDatum->GetTOF()==-1) continue;
683       if (tofRawDatum->GetTOF()==-1) continue;
684
685       if (fVerbose==2) {
686         if (indexDDL<10) ftxt << "  " << indexDDL;
687         else         ftxt << " " << indexDDL;
688         if (tofRawDatum->GetTRM()<10) ftxt << "  " << tofRawDatum->GetTRM();
689         else         ftxt << " " << tofRawDatum->GetTRM();
690         ftxt << "  " << tofRawDatum->GetTRMchain();
691         if (tofRawDatum->GetTDC()<10) ftxt << "  " << tofRawDatum->GetTDC();
692         else         ftxt << " " << tofRawDatum->GetTDC();
693         ftxt << "  " << tofRawDatum->GetTDCchannel();
694       }
695
696       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
697                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
698       dummy = detectorIndex[3];
699       detectorIndex[3] = detectorIndex[4];
700       detectorIndex[4] = dummy;
701
702       if (fVerbose==2) {
703         if (detectorIndex[0]<10) ftxt  << "  ->  " << detectorIndex[0];
704         else              ftxt  << "  -> " << detectorIndex[0];
705         ftxt << "  " << detectorIndex[1];
706         if (detectorIndex[2]<10) ftxt << "  " << detectorIndex[2];
707         else              ftxt << " " << detectorIndex[2];
708         ftxt << "  " << detectorIndex[3];
709         if (detectorIndex[4]<10) ftxt << "  " << detectorIndex[4];
710         else              ftxt << " " << detectorIndex[4];
711       }
712
713     /* check valid index */
714     if (detectorIndex[0]==-1||detectorIndex[1]==-1||detectorIndex[2]==-1||detectorIndex[3]==-1||detectorIndex[4]==-1) continue;
715
716       // Do not reconstruct anything in the holes
717       if (detectorIndex[0]==13 || detectorIndex[0]==14 || detectorIndex[0]==15 ) { // sectors with holes
718         if (detectorIndex[1]==2) { // plate with holes
719           inholes++;
720           continue;
721         }
722       }
723
724       parTOF[0] = tofRawDatum->GetTOF(); // TDC
725       parTOF[1] = tofRawDatum->GetTOT(); // TOT
726       parTOF[2] = tofRawDatum->GetTOT(); // raw data have ADC=TOT
727       parTOF[3] = 0; //raw data: no track of the undecalib sim time
728       parTOF[4] = tofRawDatum->GetTOF(); // Raw time == TDC
729       parTOF[5] = tofRawDatum->GetDeltaBC(); // deltaBC
730       parTOF[6] = tofRawDatum->GetL0L1Latency(); // L0-L1 latency
731       Double_t posClus[3];
732       Double_t covClus[6];
733       UShort_t volIdClus=GetClusterVolIndex(detectorIndex);
734       Int_t lab[3]={-1,-1,-1};
735       Bool_t status=kTRUE;
736       GetClusterPars(detectorIndex,posClus,covClus);
737       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);
738       InsertCluster(tofCluster);
739
740       if (fVerbose==2) {
741         if (parTOF[1]<10)ftxt << "        " << parTOF[1];
742         else if (parTOF[1]>=10 && parTOF[1]<100) ftxt << "      " << parTOF[1];
743         else ftxt << "      " << parTOF[1];
744         if (parTOF[0]<10) ftxt << "      " << parTOF[0] << endl;
745         else if (parTOF[0]>=10 && parTOF[0]<100)   ftxt << "    " << parTOF[0] << endl;
746         else if (parTOF[0]>=100 && parTOF[0]<1000) ftxt << "    " << parTOF[0] << endl;
747         else ftxt << "   " << parTOF[0] << endl;
748       }
749
750     } // closed loop on TOF raw data per current DDL file
751
752     clonesRawData->Clear("C");
753
754   } // closed loop on DDL index
755
756   if (fVerbose==2) ftxt.close();
757
758   AliDebug(1,Form("Number of found clusters: %d for event: %d", fNumberOfTofClusters, iEvent));
759
760   CalibrateRecPoint(rawReader->GetTimestamp());
761   FillRecPoint();
762
763   fTreeR->Fill();
764   ResetRecpoint();
765
766   fTOFLoader = fRunLoader->GetLoader("TOFLoader");
767   fTOFLoader->WriteRecPoints("OVERWRITE");
768   
769   AliDebug(1, Form("Execution time to read TOF raw data and to write TOF clusters : R:%.4fs C:%.4fs",
770                stopwatch.RealTime(),stopwatch.CpuTime()));
771   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
772
773 }
774 //______________________________________________________________________________
775
776 void AliTOFClusterFinder::Raw2Digits(Int_t iEvent, AliRawReader *rawReader)
777 {
778   //
779   // Converts RAW data to MC digits for TOF
780   //
781   //             (temporary solution)
782   //
783
784   TStopwatch stopwatch;
785   stopwatch.Start();
786
787   const Int_t kDDL = AliTOFGeometry::NDDL()*AliTOFGeometry::NSectors();
788
789   fRunLoader->GetEvent(iEvent);
790
791   fTreeD = fTOFLoader->TreeD();
792   if (fTreeD)
793     {
794     AliInfo("TreeD re-creation");
795     fTreeD = 0x0;
796     fTOFLoader->MakeTree("D");
797     fTreeD = fTOFLoader->TreeD();
798     }
799   else {
800     AliFatal("Can not get TreeD");
801     return;
802   }
803
804   Int_t bufsize = 32000;
805   fDigits->Clear();
806   fTreeD->Branch("TOF", &fDigits, bufsize);
807
808   fRunLoader->GetEvent(iEvent);
809
810   AliDebug(2,Form(" Event number %2d ", iEvent));
811
812   TClonesArray * clonesRawData;
813
814   Int_t dummy = -1;
815
816   Int_t detectorIndex[5];
817   Int_t digit[4];
818
819   fTOFRawStream.Clear();
820   fTOFRawStream.SetRawReader(rawReader);
821
822   if (fDecoderVersion == 1) {
823     AliInfo("Using New Decoder");
824   }
825   else if (fDecoderVersion == 2) {
826     AliInfo("Using Enhanced Decoder");
827   }
828   else {
829     AliInfo("Using Old Decoder");
830   }
831
832   Int_t indexDDL = 0;
833   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
834
835     rawReader->Reset();
836     if (fDecoderVersion == 1) {
837       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
838     }
839     else if (fDecoderVersion == 2) {
840       fTOFRawStream.LoadRawDataBuffersV2(indexDDL,fVerbose);
841     }
842     else {
843       fTOFRawStream.LoadRawData(indexDDL);
844     }
845
846     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
847
848     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
849
850       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
851
852       //if (!tofRawDatum->GetTOT() || !tofRawDatum->GetTOF()) continue;
853       if (tofRawDatum->GetTOF()==-1) continue;
854
855       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
856                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
857       dummy = detectorIndex[3];
858       detectorIndex[3] = detectorIndex[4];
859       detectorIndex[4] = dummy;
860
861       digit[0] = fTOFRawStream.GetTofBin();
862       digit[1] = fTOFRawStream.GetToTbin();
863       digit[2] = fTOFRawStream.GetToTbin();
864       digit[3] = 0;
865
866       Int_t tracknum[3]={-1,-1,-1};
867
868       TClonesArray &aDigits = *fDigits;
869       Int_t last=fDigits->GetEntriesFast();
870       new (aDigits[last]) AliTOFdigit(tracknum, detectorIndex, digit);
871
872     } // while loop
873
874     clonesRawData->Clear("C");
875
876   } // DDL Loop
877
878   fTreeD->Fill();
879
880   fTOFLoader = fRunLoader->GetLoader("TOFLoader");
881   fTOFLoader->WriteDigits("OVERWRITE");
882
883   AliDebug(1, Form("Execution time to read TOF raw data and to write TOF clusters : R:%.2fs C:%.2fs",
884                    stopwatch.RealTime(),stopwatch.CpuTime()));
885
886 }
887
888 //______________________________________________________________________________
889
890 void AliTOFClusterFinder::Raw2Digits(AliRawReader *rawReader, TTree* digitsTree)
891 {
892   //
893   // Converts RAW data to MC digits for TOF for the current event
894   //
895   //
896
897   TStopwatch stopwatch;
898   stopwatch.Start();
899
900   const Int_t kDDL = AliTOFGeometry::NDDL()*AliTOFGeometry::NSectors();
901
902   if (!digitsTree)
903     {
904     AliError("No input digits Tree");
905     return;
906     }
907
908   Int_t bufsize = 32000;
909   digitsTree->Branch("TOF", &fDigits, bufsize);
910
911   TClonesArray * clonesRawData;
912   Int_t dummy = -1;
913
914   Int_t detectorIndex[5];
915   Int_t digit[4];
916
917   fTOFRawStream.Clear();
918   fTOFRawStream.SetRawReader(rawReader);
919
920   if (fDecoderVersion == 1) {
921     AliInfo("Using New Decoder");
922   }
923   else if (fDecoderVersion == 2) {
924     AliInfo("Using Enhanced Decoder");
925   }
926   else {
927     AliInfo("Using Old Decoder");
928   }
929
930   Int_t indexDDL = 0;
931   for (indexDDL = 0; indexDDL < kDDL; indexDDL++) {
932
933     rawReader->Reset();
934     if (fDecoderVersion == 1) {
935       fTOFRawStream.LoadRawDataBuffers(indexDDL,fVerbose);
936     }
937     else if (fDecoderVersion == 2) {
938       fTOFRawStream.LoadRawDataBuffersV2(indexDDL,fVerbose);
939     }
940     else {
941       fTOFRawStream.LoadRawData(indexDDL);
942     }
943
944     clonesRawData = (TClonesArray*)fTOFRawStream.GetRawData();
945
946     for (Int_t iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
947
948       AliTOFrawData *tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
949
950       //if (!tofRawDatum->GetTOT() || !tofRawDatum->GetTOF()) continue;
951       if (tofRawDatum->GetTOF()==-1) continue;
952
953       fTOFRawStream.EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
954                                          tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
955       dummy = detectorIndex[3];
956       detectorIndex[3] = detectorIndex[4];
957       detectorIndex[4] = dummy;
958
959       digit[0] = fTOFRawStream.GetTofBin();
960       digit[1] = fTOFRawStream.GetToTbin();
961       digit[2] = fTOFRawStream.GetToTbin();
962       digit[3] = 0;
963
964       Int_t tracknum[3]={-1,-1,-1};
965
966       TClonesArray &aDigits = *fDigits;
967       Int_t last=fDigits->GetEntriesFast();
968       new (aDigits[last]) AliTOFdigit(tracknum, detectorIndex, digit);
969
970     } // while loop
971
972     clonesRawData->Clear("C");
973
974   } // DDL Loop
975
976   digitsTree->Fill();
977
978   AliDebug(1, Form("Got %d digits: ", fDigits->GetEntries()));
979   AliDebug(1, Form("Execution time to read TOF raw data and fill TOF digit tree : R:%.2fs C:%.2fs",
980                    stopwatch.RealTime(),stopwatch.CpuTime()));
981
982 }
983 //______________________________________________________________________________
984
985 Int_t AliTOFClusterFinder::InsertCluster(AliTOFcluster *tofCluster) {
986   //---------------------------------------------------------------------------//
987   // This function adds a TOF cluster to the array of TOF clusters sorted in Z //
988   //---------------------------------------------------------------------------//
989   if (fNumberOfTofClusters==kTofMaxCluster) {
990     AliError("Too many clusters !");
991     return 1;
992   }
993
994   if (fNumberOfTofClusters==0) {
995     fTofClusters[fNumberOfTofClusters++] = tofCluster;
996     return 0;
997   }
998
999   Int_t ii = FindClusterIndex(tofCluster->GetZ());
1000   memmove(fTofClusters+ii+1 ,fTofClusters+ii,(fNumberOfTofClusters-ii)*sizeof(AliTOFcluster*));
1001   fTofClusters[ii] = tofCluster;
1002   fNumberOfTofClusters++;
1003   
1004   return 0;
1005
1006 }
1007 //_________________________________________________________________________
1008
1009 Int_t AliTOFClusterFinder::FindClusterIndex(Double_t z) const {
1010   //--------------------------------------------------------------------
1011   // This function returns the index of the nearest cluster in z
1012   //--------------------------------------------------------------------
1013   if (fNumberOfTofClusters==0) return 0;
1014   if (z <= fTofClusters[0]->GetZ()) return 0;
1015   if (z > fTofClusters[fNumberOfTofClusters-1]->GetZ()) return fNumberOfTofClusters;
1016   Int_t b = 0, e = fNumberOfTofClusters-1, m = (b+e)/2;
1017   for (; b<e; m=(b+e)/2) {
1018     if (z > fTofClusters[m]->GetZ()) b=m+1;
1019     else e=m;
1020   }
1021
1022   return m;
1023
1024 }
1025 //_________________________________________________________________________
1026
1027 void AliTOFClusterFinder::FillRecPoint()
1028 {
1029   //
1030   // Copy the global array of AliTOFcluster, i.e. fTofClusters (sorted
1031   // in Z) in the global TClonesArray of AliTOFcluster,
1032   // i.e. fRecPoints.
1033   //
1034
1035   Int_t ii, jj;
1036
1037   Int_t detectorIndex[5];
1038   Int_t parTOF[7];
1039   Int_t trackLabels[3];
1040   Int_t digitIndex = -1;
1041   Bool_t status=kTRUE;
1042
1043   TClonesArray &lRecPoints = *fRecPoints;
1044   
1045   for (ii=0; ii<fNumberOfTofClusters; ii++) {
1046
1047     digitIndex = fTofClusters[ii]->GetIndex();
1048     for(jj=0; jj<5; jj++) detectorIndex[jj] = fTofClusters[ii]->GetDetInd(jj);
1049     for(jj=0; jj<3; jj++) trackLabels[jj] = fTofClusters[ii]->GetLabel(jj);
1050     parTOF[0] = fTofClusters[ii]->GetTDC(); // TDC
1051     parTOF[1] = fTofClusters[ii]->GetToT(); // TOT
1052     parTOF[2] = fTofClusters[ii]->GetADC(); // ADC=TOT
1053     parTOF[3] = fTofClusters[ii]->GetTDCND(); // TDCND
1054     parTOF[4] = fTofClusters[ii]->GetTDCRAW();//RAW
1055     parTOF[5] = fTofClusters[ii]->GetDeltaBC();//deltaBC
1056     parTOF[6] = fTofClusters[ii]->GetL0L1Latency();//L0-L1 latency
1057     status=fTofClusters[ii]->GetStatus();
1058     Double_t posClus[3];
1059     Double_t covClus[6];
1060     UShort_t volIdClus=GetClusterVolIndex(detectorIndex);
1061     GetClusterPars(detectorIndex,posClus,covClus);
1062     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);
1063
1064     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", 
1065                      ii, volIdClus, posClus[0], posClus[1], posClus[2],
1066                      fTofClusters[ii]->GetSigmaX2(),
1067                      fTofClusters[ii]->GetSigmaXY(),
1068                      fTofClusters[ii]->GetSigmaXZ(),
1069                      fTofClusters[ii]->GetSigmaY2(),
1070                      fTofClusters[ii]->GetSigmaYZ(),
1071                      fTofClusters[ii]->GetSigmaZ2(),
1072                      trackLabels[0], trackLabels[1], trackLabels[2],
1073                      detectorIndex[0], detectorIndex[1], detectorIndex[2], detectorIndex[3], detectorIndex[4],
1074                      parTOF[0], parTOF[1], parTOF[2], parTOF[3], parTOF[4],
1075                      status, digitIndex));
1076
1077   } // loop on clusters
1078
1079 }
1080
1081 //_________________________________________________________________________
1082
1083 /*
1084  * OLD CALIBRATE REC POINTS FUNCTION
1085  */
1086
1087 #if 0
1088 void AliTOFClusterFinder::CalibrateRecPoint(UInt_t timestamp)
1089 {
1090   //
1091   // Copy the global array of AliTOFcluster, i.e. fTofClusters (sorted
1092   // in Z) in the global TClonesArray of AliTOFcluster,
1093   // i.e. fRecPoints.
1094   //
1095
1096   Int_t ii, jj;
1097
1098   Int_t detectorIndex[5];
1099   Int_t digitIndex = -1;
1100   Double_t tToT;
1101   Double_t timeCorr;
1102   Int_t   tdcCorr;
1103   Float_t tdcLatencyWindow;
1104   AliDebug(1," Calibrating TOF Clusters");
1105
1106   AliTOFChannelOnlineArray *calDelay = fTOFcalib->GetTOFOnlineDelay();  
1107   AliTOFChannelOnlineStatusArray *calStatus = fTOFcalib->GetTOFOnlineStatus();  
1108   TObjArray *calTOFArrayOffline = fTOFcalib->GetTOFCalArrayOffline();
1109   
1110   AliTOFDeltaBCOffset *deltaBCOffsetObj = fTOFcalib->GetDeltaBCOffset();
1111   Int_t deltaBCOffset = deltaBCOffsetObj->GetDeltaBCOffset();
1112   AliTOFCTPLatency *ctpLatencyObj = fTOFcalib->GetCTPLatency();
1113   Float_t ctpLatency = ctpLatencyObj->GetCTPLatency();
1114   AliTOFRunParams *runParamsObj = fTOFcalib->GetRunParams();
1115   Float_t t0 = runParamsObj->EvalT0(timestamp);
1116
1117   TString validity = (TString)fTOFcalib->GetOfflineValidity();
1118   Int_t calibration = -1;
1119   if (validity.CompareTo("valid")==0) {
1120     //AliInfo(Form(" validity = %s - Using offline calibration parameters",validity.Data()));
1121     calibration = 1;
1122   } else {
1123     //AliInfo(Form(" validity = %s - Using online calibration parameters",validity.Data()));
1124     calibration = 0 ;
1125   }
1126
1127   for (ii=0; ii<fNumberOfTofClusters; ii++) {
1128     digitIndex = fTofClusters[ii]->GetIndex();
1129     for(jj=0; jj<5; jj++) detectorIndex[jj] = fTofClusters[ii]->GetDetInd(jj);
1130
1131     Int_t index = AliTOFGeometry::GetIndex(detectorIndex);
1132      
1133     UChar_t statusPulser=calStatus->GetPulserStatus(index);
1134     UChar_t statusNoise=calStatus->GetNoiseStatus(index);
1135     UChar_t statusHW=calStatus->GetHWStatus(index);
1136     UChar_t status=calStatus->GetStatus(index);
1137     tdcLatencyWindow = calStatus->GetLatencyWindow(index) * 1.e3; /* ns -> ps */
1138     
1139     //check the status, also unknown is fine!!!!!!!
1140
1141     AliDebug(2, Form(" Status for channel %d = %d",index, (Int_t)status));
1142     if((statusPulser & AliTOFChannelOnlineStatusArray::kTOFPulserBad)==(AliTOFChannelOnlineStatusArray::kTOFPulserBad)||(statusNoise & AliTOFChannelOnlineStatusArray::kTOFNoiseBad)==(AliTOFChannelOnlineStatusArray::kTOFNoiseBad)||(statusHW & AliTOFChannelOnlineStatusArray::kTOFHWBad)==(AliTOFChannelOnlineStatusArray::kTOFHWBad)){
1143       AliDebug(2, Form(" Bad Status for channel %d",index));
1144       fTofClusters[ii]->SetStatus(kFALSE); //odd convention, to avoid conflict with calibration objects currently in the db (temporary solution).
1145     }
1146     else {
1147       AliDebug(2, Form(" Good Status for channel %d",index));
1148     }
1149     // Get Rough channel online equalization 
1150     Double_t roughDelay=(Double_t)calDelay->GetDelay(index);  // in ns
1151     AliDebug(2,Form(" channel delay (ns) = %f", roughDelay));
1152     // Get Refined channel offline calibration parameters
1153     if (calibration ==1){
1154       AliTOFChannelOffline * calChannelOffline = (AliTOFChannelOffline*)calTOFArrayOffline->At(index);
1155       Double_t par[6];
1156       for (Int_t j = 0; j<6; j++){
1157         par[j]=(Double_t)calChannelOffline->GetSlewPar(j);
1158      } 
1159       AliDebug(2,Form(" Calib Pars = %f, %f, %f, %f, %f, %f ",par[0],par[1],par[2],par[3],par[4],par[5]));
1160       AliDebug(2,Form(" The ToT and Time, uncorr (counts) = %d , %d", fTofClusters[ii]->GetToT(),fTofClusters[ii]->GetTDC()));
1161       tToT = (Double_t)(fTofClusters[ii]->GetToT()*AliTOFGeometry::ToTBinWidth());
1162       tToT*=1.E-3; //ToT in ns
1163
1164       /* check TOT limits and set new TOT in case */
1165       if (tToT < AliTOFGeometry::SlewTOTMin()) tToT = AliTOFGeometry::SlewTOTMin();
1166       if (tToT > AliTOFGeometry::SlewTOTMax()) tToT = AliTOFGeometry::SlewTOTMax();
1167
1168       AliDebug(2,Form(" The ToT and Time, uncorr (ns)= %e, %e",fTofClusters[ii]->GetTDC()*AliTOFGeometry::TdcBinWidth()*1.E-3,tToT));
1169       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)
1170     }
1171     else {
1172       timeCorr = roughDelay; // correction in ns
1173     }
1174     AliDebug(2,Form(" The ToT and Time, uncorr (ns)= %e, %e",fTofClusters[ii]->GetTDC()*AliTOFGeometry::TdcBinWidth()*1.E-3,fTofClusters[ii]->GetToT()*AliTOFGeometry::ToTBinWidth()));
1175     AliDebug(2,Form(" The time correction (ns) = %f", timeCorr));
1176     timeCorr=(Double_t)(fTofClusters[ii]->GetTDC())*AliTOFGeometry::TdcBinWidth()*1.E-3-timeCorr;//redefine the time
1177     timeCorr*=1.E3;
1178     AliDebug(2,Form(" The channel time, corr (ps)= %e",timeCorr ));
1179
1180     /* here timeCorr should be already corrected for calibration. 
1181      * we now go into further corrections keeping in mind that timeCorr
1182      * is in ps.
1183      *
1184      * the following corrections are performed in this way:
1185      *
1186      *    time = timeRaw - deltaBC + L0L1Latency + CTPLatency - TDCLatencyWindow - T0
1187      *
1188      */
1189
1190     AliDebug(2, Form("applying further corrections (DeltaBC): DeltaBC=%d (BC bins), DeltaBCoffset=%d (BC bins)", fTofClusters[ii]->GetDeltaBC(), deltaBCOffset));
1191     AliDebug(2, Form("applying further corrections (L0L1Latency): L0L1Latency=%d (BC bins)", fTofClusters[ii]->GetL0L1Latency()));
1192     AliDebug(2, Form("applying further corrections (CTPLatency): CTPLatency=%f (ps)", ctpLatency));
1193     AliDebug(2, Form("applying further corrections (TDCLatencyWindow): TDCLatencyWindow=%f (ps)", tdcLatencyWindow));
1194     AliDebug(2, Form("applying further corrections (T0): T0=%f (ps)", t0));
1195
1196     /* deltaBC correction (inhibited for the time being) */
1197     //    timeCorr -= (fTofClusters[ii]->GetDeltaBC() - deltaBCOffset) * AliTOFGeometry::BunchCrossingBinWidth();
1198     /* L0L1-latency correction */
1199     timeCorr += fTofClusters[ii]->GetL0L1Latency() * AliTOFGeometry::BunchCrossingBinWidth();
1200     /* CTP-latency correction (from OCDB) */
1201     timeCorr += ctpLatency;
1202     /* TDC latency-window correction (from OCDB) */
1203     timeCorr -= tdcLatencyWindow;
1204     /* T0 correction (from OCDB) */
1205     timeCorr -= t0;
1206
1207     /*
1208      * end of furhter corrections
1209      */
1210
1211     tdcCorr=(Int_t)(timeCorr/AliTOFGeometry::TdcBinWidth()); //the corrected time (tdc counts)
1212     fTofClusters[ii]->SetTDC(tdcCorr);
1213   } // loop on clusters
1214
1215 }
1216 #endif
1217
1218 //_________________________________________________________________________
1219
1220 void AliTOFClusterFinder::CalibrateRecPoint(UInt_t timestamp)
1221 {
1222   //
1223   // Copy the global array of AliTOFcluster, i.e. fTofClusters (sorted
1224   // in Z) in the global TClonesArray of AliTOFcluster,
1225   // i.e. fRecPoints.
1226   //
1227
1228   Int_t detectorIndex[5];
1229   Double_t time, tot, corr;
1230   Int_t deltaBC, l0l1, tdcBin;
1231   for (Int_t ii = 0; ii < fNumberOfTofClusters; ii++) {
1232     for(Int_t jj = 0; jj < 5; jj++) detectorIndex[jj] = fTofClusters[ii]->GetDetInd(jj);
1233
1234     Int_t index = AliTOFGeometry::GetIndex(detectorIndex);
1235
1236     /* check channel enabled */
1237     if (!fTOFcalib->IsChannelEnabled(index)) fTofClusters[ii]->SetStatus(kFALSE);
1238     
1239     /* get cluster info */
1240     time = fTofClusters[ii]->GetTDC() * AliTOFGeometry::TdcBinWidth(); /* ps */
1241     tot = fTofClusters[ii]->GetToT() * AliTOFGeometry::ToTBinWidth() * 1.e-3; /* ns */
1242     deltaBC = fTofClusters[ii]->GetDeltaBC();
1243     l0l1 = fTofClusters[ii]->GetL0L1Latency();
1244
1245     /* get correction */
1246     corr = fTOFcalib->GetTimeCorrection(index, tot, deltaBC, l0l1, timestamp); /* ps */
1247     AliDebug(2, Form("calibrate index %d: time=%f (ps) tot=%f (ns) deltaBC=%d l0l1=%d timestamp=%d corr=%f (ps)", index, time, tot, deltaBC, l0l1, timestamp, corr));
1248
1249     /* apply time correction */
1250     time -= corr;
1251
1252     /* convert in TDC bins and set cluster */
1253     //tdcBin = (Int_t)(time / AliTOFGeometry::TdcBinWidth()); //the corrected time (tdc counts)
1254     tdcBin = TMath::Nint(time / AliTOFGeometry::TdcBinWidth()); //the corrected time (tdc counts)
1255     fTofClusters[ii]->SetTDC(tdcBin);
1256
1257   } // loop on clusters
1258
1259 }
1260
1261 //______________________________________________________________________________
1262
1263 void AliTOFClusterFinder::ResetRecpoint()
1264 {
1265   //
1266   // Clear the list of reconstructed points
1267   //
1268
1269   fNumberOfTofClusters = 0;
1270   if (fRecPoints) fRecPoints->Clear();
1271
1272 }
1273 //______________________________________________________________________________
1274
1275 void AliTOFClusterFinder::Load()
1276 {
1277   //
1278   // Load TOF.Digits.root and TOF.RecPoints.root files
1279   //
1280
1281   fTOFLoader->LoadDigits("READ");
1282   fTOFLoader->LoadRecPoints("recreate");
1283
1284 }
1285 //______________________________________________________________________________
1286
1287 void AliTOFClusterFinder::LoadClusters()
1288 {
1289   //
1290   // Load TOF.RecPoints.root file
1291   //
1292
1293   fTOFLoader->LoadRecPoints("recreate");
1294
1295 }
1296 //______________________________________________________________________________
1297
1298 void AliTOFClusterFinder::UnLoad()
1299 {
1300   //
1301   // Unload TOF.Digits.root and TOF.RecPoints.root files
1302   //
1303
1304   fTOFLoader->UnloadDigits();
1305   fTOFLoader->UnloadRecPoints();
1306
1307 }
1308 //______________________________________________________________________________
1309
1310 void AliTOFClusterFinder::UnLoadClusters()
1311 {
1312   //
1313   // Unload TOF.RecPoints.root file
1314   //
1315
1316   fTOFLoader->UnloadRecPoints();
1317
1318 }
1319 //-------------------------------------------------------------------------
1320 UShort_t AliTOFClusterFinder::GetClusterVolIndex(const Int_t * const ind) const {
1321
1322   //First of all get the volume ID to retrieve the l2t transformation...
1323   //
1324   // Detector numbering scheme
1325   Int_t nSector = 18;
1326   Int_t nPlate  = 5;
1327   Int_t nStripA = 15;
1328   Int_t nStripB = 19;
1329   Int_t nStripC = 19;
1330
1331   Int_t isector =ind[0];
1332   if (isector >= nSector)
1333     AliError(Form("Wrong sector number in TOF (%d) !",isector));
1334   Int_t iplate = ind[1];
1335   if (iplate >= nPlate)
1336     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
1337   Int_t istrip = ind[2];
1338
1339   Int_t stripOffset = 0;
1340   switch (iplate) {
1341   case 0:
1342     stripOffset = 0;
1343     break;
1344   case 1:
1345     stripOffset = nStripC;
1346     break;
1347   case 2:
1348     stripOffset = nStripC+nStripB;
1349     break;
1350   case 3:
1351     stripOffset = nStripC+nStripB+nStripA;
1352     break;
1353   case 4:
1354     stripOffset = nStripC+nStripB+nStripA+nStripB;
1355     break;
1356   default:
1357     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
1358     break;
1359   };
1360
1361   Int_t index= (2*(nStripC+nStripB)+nStripA)*isector +
1362                stripOffset +
1363                istrip;
1364
1365   UShort_t volIndex = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,index);
1366   return volIndex;
1367 }
1368 //
1369 //-------------------------------------------------------------------------
1370 void AliTOFClusterFinder::GetClusterPars(Int_t *ind, Double_t* pos,Double_t* cov) const {
1371
1372   //First of all get the volume ID to retrieve the l2t transformation...
1373   //
1374   UShort_t volIndex = GetClusterVolIndex(ind);
1375   //
1376   //
1377   //we now go in the system of the strip: determine the local coordinates
1378   //
1379   //
1380   // 47---------------------------------------------------0  ^ z
1381   // | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 |
1382   // -----------------------------------------------------   | y going outwards
1383   // | | | | | | | | | | | | | | | | | | | | | | | | | | | 0 |  par[0]=0;
1384
1385   // -----------------------------------------------------   |
1386   // x <-----------------------------------------------------
1387
1388   /*
1389   Float_t localX = (ind[4]-23.5)*AliTOFGeometry::XPad();
1390   Float_t localY = 0;
1391   Float_t localZ = (ind[3]- 0.5)*AliTOFGeometry::ZPad();
1392   */
1393   Float_t localX = (ind[4]-AliTOFGeometry::NpadX()/2)*AliTOFGeometry::XPad()+AliTOFGeometry::XPad()/2.;
1394   Float_t localY = 0;
1395   Float_t localZ = (ind[3]-AliTOFGeometry::NpadZ()/2)*AliTOFGeometry::ZPad()+AliTOFGeometry::ZPad()/2.;
1396   //move to the tracking ref system
1397
1398   Double_t lpos[3];
1399   lpos[0] = localX;
1400   lpos[1] = localY;
1401   lpos[2] = localZ; 
1402
1403   const TGeoHMatrix *l2t= AliGeomManager::GetTracking2LocalMatrix(volIndex);
1404   // Get The position in the track ref system
1405   Double_t tpos[3];
1406   l2t->MasterToLocal(lpos,tpos);
1407   pos[0] = tpos[0];
1408   pos[1] = tpos[1];
1409   pos[2] = tpos[2];
1410
1411   //Get The cluster covariance in the track ref system
1412   Double_t lcov[9];
1413
1414   //cluster covariance in the local system:
1415   // sx2   0   0
1416   // 0     0   0
1417   // 0     0   sz2
1418
1419   lcov[0] = AliTOFGeometry::XPad()*AliTOFGeometry::XPad()/12.;
1420   lcov[1] = 0;
1421   lcov[2] = 0;
1422   lcov[3] = 0;
1423   lcov[4] = 0;
1424   lcov[5] = 0;
1425   lcov[6] = 0;
1426   lcov[7] = 0;
1427   lcov[8] = AliTOFGeometry::ZPad()*AliTOFGeometry::ZPad()/12.;
1428
1429   //cluster covariance in the tracking system:
1430   TGeoHMatrix m;
1431   m.SetRotation(lcov);
1432   m.Multiply(l2t);
1433   m.MultiplyLeft(&l2t->Inverse());
1434   Double_t *tcov = m.GetRotationMatrix();
1435   cov[0] = tcov[0]; cov[1] = tcov[1]; cov[2] = tcov[2];
1436   cov[3] = tcov[4]; cov[4] = tcov[5];
1437   cov[5] = tcov[8];
1438
1439   return;
1440
1441 }