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