]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/TOFbase/AliTOFRawStream.cxx
Fixing small memory leaks (Hans)
[u/mrichter/AliRoot.git] / TOF / TOFbase / AliTOFRawStream.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
19 Added lookup tables for
20          TRM number 3 in the left crates (TOF OR signals)
21          and detector elements (A.Silenzi)
22
23 Revision 1.19.1  2008/09/19  preghenella
24   Decode method updated:
25   it reads the CDH from the rawReader and sends it to the decoder;
26  LoadRawDataBuffers modified:
27      it corrects tof hit infos per ddlBC and deltaBC offsets
28      (in case of the static member fgApplyBCCorrections
29       has been setted to kTRUE);
30  Added static member fgApplyBCCorrections (kTRUE by default)
31  and the related static method ApplyBCCorrections;
32
33 Revision 1.19  2007/05/18 13:07:53  decaro
34 Error messages stored in the global raw-reader error log (Cvetan, Chiara)
35
36 Revision 1.18  2007/05/08 11:53:29  arcelli
37 Improved class flexibility for further use (R.Preghenella)
38
39 Revision 1.17  2007/05/03 08:53:50  decaro
40 Coding convention: RS3 violation -> suppression
41
42 Revision 1.16  2007/05/03 08:22:22  decaro
43 Coding convention: RN17 violation -> suppression
44
45 Revision 1.15  2007/04/30 15:22:06  arcelli
46 Change TOF digit Time, Tot etc to int type
47
48 Revision 1.14  2007/04/27 11:11:53  arcelli
49 updates for the new decoder
50
51 Revision 1.13  2007/03/16 11:46:35  decaro
52 Coding convention: RN17 rule violation -> suppression
53
54 Revision 1.12  2007/02/22 09:43:45  decaro
55 Added AliTOFRawStream::GetIndex method for online calibration (C.Zampolli)
56
57 Revision 1.11  2007/02/20 15:57:00  decaro
58 Raw data update: to read the TOF raw data defined in UNPACKED mode
59
60 Revision 1.10  2006/12/15 14:01:38  cvetan
61 Memory leak fixed
62
63 Revision 1.9  2006/10/13 11:22:27  arcelli
64 remove warnings due to uninitialized AliTOFtdcDigit data members
65
66 Revision 1.8  2006/08/22 13:30:17  arcelli
67 removal of effective c++ warnings (C.Zampolli)
68
69 Revision 1.7  2006/08/10 14:46:54  decaro
70 TOF raw data format: updated version
71
72 Revision 1.6.1  2006/06/28 A. De Caro, R. Preghenella:
73         Update TOF raw data format
74         according to the final version
75         (see the ALICE internal note in preparation
76          'ALICE TOF raw data format')
77         Added the methods for the correspoonding numbering
78          between the equipment IDs and the volume IDs:
79            Equip2VolNPlate(...)
80            Equip2VolNStrip(...)
81            Equip2VolNPad(...)
82
83 Revision 0.02  2005/07/28 A. De Caro:
84         Update format TOF raw data
85                (temporary solution) 
86         Correction of few wrong corrispondences
87                between 'software' and 'hardware' numberings
88
89 Revision 0.01  2005/07/22 A. De Caro
90         Implement methods Next()
91                           GetSector(),
92                           GetPlate(),
93                           GetStrip(),
94                           GetPadZ(),
95                           GetPadX()
96 */
97
98 ////////////////////////////////////////////////////////////////////////
99 //                                                                    //
100 //     This class provides access to TOF raw data in DDL files.       //
101 //                                                                    //
102 //      It loops over all TOF raw data given by the AliRawReader.     //
103 //                                                                    //
104 ////////////////////////////////////////////////////////////////////////
105
106
107 #include "Riostream.h"
108
109 #include "TClonesArray.h"
110 #include "TStopwatch.h"
111
112 #include "AliDAQ.h"
113 #include "AliLog.h"
114 #include "AliRawReader.h"
115
116 #include "AliTOFGeometry.h"
117 #include "AliTOFrawData.h"
118 #include "AliTOFRawMap.h"
119 #include "AliTOFRawStream.h"
120 #include "AliTOFdigit.h"
121 #include "AliTOFSDigit.h"
122 //#include "AliTOFCableLengthMap.h"
123
124 #include "AliTOFHitData.h"
125
126 #include "AliRawEventHeaderBase.h"
127 #include "AliRawDataHeader.h"
128 #include "AliRawDataHeaderV3.h"
129
130 #include "AliTOFDecoderV2.h"
131 #include "AliTOFTDCHit.h"
132 #include "AliTOFDecoderSummaryData.h"
133 #include "AliTOFDRMSummaryData.h"
134 #include "AliTOFLTMSummaryData.h"
135 #include "AliTOFTRMSummaryData.h"
136 #include "AliTOFChainSummaryData.h"
137 #include "AliTOFTDCHitBuffer.h"
138 #include "AliTOFTDCErrorBuffer.h"
139
140 ClassImp(AliTOFRawStream)
141
142 const Int_t AliTOFRawStream::fgkddlBCshift[72] = 
143 {
144   0, 0, 0, 0,
145   0, 0, 0, 0,
146   0, 0, 0, 0,
147   0, 0, 0, 0,
148   0, 0, 0, 0,
149   0, 0, 0, 0,
150   0, 0, 0, 0,
151   0, 0, 0, 0,
152   0, 0, 0, 0,
153   0, 0, 0, 0,
154   0, 0, 0, 0,
155   0, 0, 0, 0,
156   0, 0, 0, 0,
157   0, 0, 0, 0,
158   0, 0, 0, 0,
159   0, 0, 0, 0,
160   0, 0, 0, 0,
161   0, 0, 0, 0
162 };
163
164 const Int_t AliTOFRawStream::fgkStrip0MapCrate0[]=
165   {1,3,5,7,9,11,13,15,17,0,2,4,6,8,10,12,14,16,18,1,3,5,7,-1};
166 const Int_t AliTOFRawStream::fgkStrip1MapCrate0[]=
167   {0,2,4,6,8,10,12,14,16,18,1,3,5,7,9,11,13,15,17,0,2,4,6,-1};
168 const Int_t AliTOFRawStream::fgkStrip0MapCrate1[]=
169   {1,3,5,7,9,11,13,15,17,0,2,4,6,8,10,12,14,16,18,1,3,5,7,-1};
170 const Int_t AliTOFRawStream::fgkStrip1MapCrate1[]=
171   {0,2,4,6,8,10,12,14,16,18,1,3,5,7,9,11,13,15,17,0,2,4,6,-1};
172 const Int_t AliTOFRawStream::fgkStrip0MapCrate2[]=
173   {17,15,13,11, 9,7,5,3,1,18,16,14,12,10,8,6,4,2, 0,13,11, 9,7,-1};
174 const Int_t AliTOFRawStream::fgkStrip1MapCrate2[]=
175   {18,16,14,12,10,8,6,4,2, 0,17,15,13,11,9,7,5,3, 1,14,12,10,8,-1};
176 const Int_t AliTOFRawStream::fgkStrip0MapCrate3[]=
177   {17,15,13,11, 9,7,5,3,1,18,16,14,12,10,8,6,4,2, 0,13,11, 9,7,-1};
178 const Int_t AliTOFRawStream::fgkStrip1MapCrate3[]=
179   {18,16,14,12,10,8,6,4,2, 0,17,15,13,11,9,7,5,3, 1,14,12,10,8,-1};
180
181
182 const Int_t AliTOFRawStream::fgkModule0MapCrate0[]=
183   {0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,-1};
184 const Int_t AliTOFRawStream::fgkModule1MapCrate0[]=
185   {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,-1};
186 const Int_t AliTOFRawStream::fgkModule0MapCrate1[]=
187   {0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,-1};
188 const Int_t AliTOFRawStream::fgkModule1MapCrate1[]=
189   {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,-1};
190
191 const Int_t AliTOFRawStream::fgkModule0MapCrate2[]=
192   {4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,-1};
193 const Int_t AliTOFRawStream::fgkModule1MapCrate2[]=
194   {4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,-1};
195 const Int_t AliTOFRawStream::fgkModule0MapCrate3[]=
196   {4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,-1};
197 const Int_t AliTOFRawStream::fgkModule1MapCrate3[]=
198   {4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,-1};
199
200 const Int_t AliTOFRawStream::fgkChannelMap0[5][19]=
201   {{0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9},
202    {9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18},
203    {19,19,20,20,21,21,22,22,22,21,21,20,20,19,19,-1,-1,-1,-1},
204    {18,18,17,17,16,16,15,15,14,14,13,13,12,12,11,11,10,10,9},
205    {9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1,0,0}
206   };
207
208 const Int_t AliTOFRawStream::fgkChainMap0[5][19]=
209   {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
210    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
211    {0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,-1,-1,-1,-1},
212    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
213    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
214   };
215
216 const Int_t AliTOFRawStream::fgkChannelMap24[5][19]=
217   {{0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9},
218    {9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18},
219    {19,19,20,20,21,21,22,22,22,21,21,20,20,19,19,-1,-1,-1,-1},
220    {18,18,17,17,16,16,15,15,14,14,13,13,12,12,11,11,10,10,9},
221    {9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1,0,0}
222   };
223
224 const Int_t AliTOFRawStream::fgkChainMap24[5][19]=
225   {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
226    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
227    {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,-1,-1,-1,-1},
228    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
229    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
230   };
231
232 Bool_t AliTOFRawStream::fgApplyBCCorrections = kTRUE;
233 //_____________________________________________________________________________
234 AliTOFRawStream::AliTOFRawStream(AliRawReader* rawReader):
235   fRawReader(rawReader),
236   fTOFrawData(new TClonesArray("AliTOFrawData",1000)),
237   fDecoder(new AliTOFDecoder()),
238   fDecoderV2(new AliTOFDecoderV2()),
239   fDDL(-1),
240   fTRM(-1),
241   fTRMchain(-1),
242   fTDC(-1),
243   fTDCchannel(-1),
244   fTime(-1),
245   fToT(-1),
246   fLeadingEdge(-1),
247   fTrailingEdge(-1),
248   fErrorFlag(-1),
249   fSector(-1),
250   fPlate(-1),
251   fStrip(-1),
252   fPadX(-1),
253   fPadZ(-1),
254   fPackedDigits(0),
255   fWordType(-1),
256   fSlotID(-1),
257   fACQ(-1),
258   fPSbit(-1),
259   fTDCerrorFlag(-1),
260   fInsideDRM(kFALSE),
261   fInsideTRM(kFALSE),
262   fInsideLTM(kFALSE),
263   fInsideTRMchain0(kFALSE),
264   fInsideTRMchain1(kFALSE),
265   //fDataBuffer(),
266   //fPackedDataBuffer(),
267   fLocalEventCounterDRM(-1),
268   fLocalEventCounterLTM(-1),
269   //fLocalEventCounterTRM(),
270   //fLocalEventCounterChain(),
271   //fChainBunchID(),
272   //fCableLengthMap(new AliTOFCableLengthMap()),
273   fEventID(0),
274   fNewDecoderVersion(0)
275 {
276   //
277   // create an object to read TOF raw digits
278   //
279
280   for (Int_t i=0;i<AliDAQ::NumberOfDdls("TOF");i++){
281     ResetDataBuffer(i);
282     ResetPackedDataBuffer(i);
283   }
284
285   //fTOFrawData = new TClonesArray("AliTOFrawData",1000);
286   fTOFrawData->SetOwner();
287
288   fRawReader->Reset();
289   fRawReader->Select("TOF");
290
291   for (Int_t jj=0;jj<13;jj++) {
292     fLocalEventCounterTRM[jj] = -1;
293     for (Int_t ii=0;ii<2;ii++) {
294       fLocalEventCounterChain[jj][ii] = -1;
295       fChainBunchID[jj][ii] = -1;
296     }
297   }
298
299 }
300
301 //_____________________________________________________________________________
302 AliTOFRawStream::AliTOFRawStream():
303   fRawReader(0x0),
304   fTOFrawData(new TClonesArray("AliTOFrawData",1000)),
305   fDecoder(new AliTOFDecoder()),
306   fDecoderV2(new AliTOFDecoderV2()),
307   fDDL(-1),
308   fTRM(-1),
309   fTRMchain(-1),
310   fTDC(-1),
311   fTDCchannel(-1),
312   fTime(-1),
313   fToT(-1),
314   fLeadingEdge(-1),
315   fTrailingEdge(-1),
316   fErrorFlag(-1),
317   fSector(-1),
318   fPlate(-1),
319   fStrip(-1),
320   fPadX(-1),
321   fPadZ(-1),
322   fPackedDigits(0),
323   fWordType(-1),
324   fSlotID(-1),
325   fACQ(-1),
326   fPSbit(-1),
327   fTDCerrorFlag(-1),
328   fInsideDRM(kFALSE),
329   fInsideTRM(kFALSE),
330   fInsideLTM(kFALSE),
331   fInsideTRMchain0(kFALSE),
332   fInsideTRMchain1(kFALSE),
333   //fDataBuffer(),
334   //fPackedDataBuffer(),
335   fLocalEventCounterDRM(-1),
336   fLocalEventCounterLTM(-1),
337   //fLocalEventCounterTRM(),
338   //fLocalEventCounterChain(),
339   //fChainBunchID(),
340   //fCableLengthMap(new AliTOFCableLengthMap()),
341   fEventID(0),
342   fNewDecoderVersion(0)
343 {
344   //
345   // default ctr
346   //
347   for (Int_t i=0;i<AliDAQ::NumberOfDdls("TOF");i++){
348     ResetDataBuffer(i);
349     ResetPackedDataBuffer(i);
350   }
351
352   //fTOFrawData = new TClonesArray("AliTOFrawData",1000);
353   fTOFrawData->SetOwner();
354
355   for (Int_t j=0;j<13;j++){
356     fLocalEventCounterTRM[j] = -1;
357     for (Int_t k=0;k<2;k++){
358       fLocalEventCounterChain[j][k] = -1;
359       fChainBunchID[j][k] = -1;
360     }
361   }
362
363 }
364
365 //_____________________________________________________________________________
366 AliTOFRawStream::AliTOFRawStream(const AliTOFRawStream& stream) :
367   TObject(stream),
368   fRawReader(stream.fRawReader),
369   fTOFrawData(stream.fTOFrawData),
370   fDecoder(new AliTOFDecoder()),
371   fDecoderV2(new AliTOFDecoderV2()),
372   fDDL(stream.fDDL),
373   fTRM(stream.fTRM),
374   fTRMchain(stream.fTRMchain),
375   fTDC(stream.fTDC),
376   fTDCchannel(stream.fTDCchannel),
377   fTime(stream.fTime),
378   fToT(-stream.fToT),
379   fLeadingEdge(stream.fLeadingEdge),
380   fTrailingEdge(stream.fTrailingEdge),
381   fErrorFlag(stream.fErrorFlag),
382   fSector(stream.fSector),
383   fPlate(stream.fPlate),
384   fStrip(stream.fStrip),
385   fPadX(stream.fPadX),
386   fPadZ(stream.fPadZ),
387   fPackedDigits(stream.fPackedDigits),
388   fWordType(stream.fWordType),
389   fSlotID(stream.fSlotID),
390   fACQ(stream.fACQ),
391   fPSbit(stream.fPSbit),
392   fTDCerrorFlag(stream.fTDCerrorFlag),
393   fInsideDRM(stream.fInsideDRM),
394   fInsideTRM(stream.fInsideTRM),
395   fInsideLTM(stream.fInsideLTM),
396   fInsideTRMchain0(stream.fInsideTRMchain0),
397   fInsideTRMchain1(stream.fInsideTRMchain1),
398   //fDataBuffer(),
399   //fPackedDataBuffer(),
400   fLocalEventCounterDRM(stream.fLocalEventCounterDRM),
401   fLocalEventCounterLTM(stream.fLocalEventCounterLTM),
402   //fLocalEventCounterTRM(),
403   //fLocalEventCounterChain(),
404   //fChainBunchID(),
405   //fCableLengthMap(stream.fCableLengthMap),
406   fEventID(stream.fEventID),
407   fNewDecoderVersion(stream.fNewDecoderVersion)
408 {
409   //
410   // copy constructor
411   //
412
413   for (Int_t i=0;i<AliDAQ::NumberOfDdls("TOF");i++){
414     fDataBuffer[i] = stream.fDataBuffer[i];
415     fPackedDataBuffer[i] = stream.fPackedDataBuffer[i];
416   }
417
418   fTOFrawData = new TClonesArray(*stream.fTOFrawData);
419
420   for (Int_t j=0;j<13;j++){
421     fLocalEventCounterTRM[j] = stream.fLocalEventCounterTRM[j];
422     for (Int_t k=0;k<2;k++){
423       fLocalEventCounterChain[j][k] = stream.fLocalEventCounterChain[j][k];
424       fChainBunchID[j][k] = stream.fChainBunchID[j][k];
425     }
426   }
427
428 }
429
430 //_____________________________________________________________________________
431 AliTOFRawStream& AliTOFRawStream::operator = (const AliTOFRawStream& stream)
432 {
433   //
434   // assignment operator
435   //
436
437   if (this == &stream)
438     return *this;
439
440   TObject::operator=(stream);
441
442   fRawReader = stream.fRawReader;
443
444   fTOFrawData = stream.fTOFrawData;
445
446   fDDL = stream.fDDL;
447   fTRM = stream.fTRM;
448   fTRMchain = stream.fTRMchain;
449   fTDC = stream.fTDC;
450   fTDCchannel = stream.fTDCchannel;
451   fTime = stream.fTime;
452   fToT = stream.fToT;
453   fLeadingEdge = stream.fLeadingEdge;
454   fTrailingEdge = stream.fTrailingEdge;
455   fErrorFlag = stream.fErrorFlag;
456
457   fSector = stream.fSector;
458   fPlate = stream.fPlate;
459   fStrip = stream.fStrip;
460   fPadX = stream.fPadX;
461   fPadZ = stream.fPadZ;
462
463   fPackedDigits = stream.fPackedDigits;
464
465   fWordType = stream.fWordType;
466   fSlotID = stream.fSlotID;
467   fACQ = stream.fACQ;
468   fPSbit = stream.fPSbit;
469   fTDCerrorFlag = stream.fTDCerrorFlag;
470   fInsideDRM = stream.fInsideDRM;
471   fInsideTRM = stream.fInsideTRM;
472   fInsideLTM = stream.fInsideLTM;
473   fInsideTRMchain0 = stream.fInsideTRMchain0;
474   fInsideTRMchain1 = stream.fInsideTRMchain1;
475
476   for (Int_t i=0;i<AliDAQ::NumberOfDdls("TOF");i++){ 
477     fDataBuffer[i] = stream.fDataBuffer[i];
478     fPackedDataBuffer[i] = stream.fPackedDataBuffer[i];
479   }
480   
481   fTOFrawData = stream.fTOFrawData;
482
483   fLocalEventCounterDRM = stream.fLocalEventCounterDRM;
484   fLocalEventCounterLTM = stream.fLocalEventCounterLTM;
485   for (Int_t j=0;j<13;j++){
486     fLocalEventCounterTRM[j] = stream.fLocalEventCounterTRM[j];
487     for (Int_t k=0;k<2;k++){
488       fLocalEventCounterChain[j][k] = stream.fLocalEventCounterChain[j][k];
489       fChainBunchID[j][k] = stream.fChainBunchID[j][k];
490     }
491   }
492
493   //fCableLengthMap = stream.fCableLengthMap;
494
495   fEventID = stream.fEventID;
496   fNewDecoderVersion = stream.fNewDecoderVersion;
497
498   return *this;
499
500 }
501
502 //_____________________________________________________________________________
503 AliTOFRawStream::~AliTOFRawStream()
504 {
505   // destructor
506
507   fPackedDigits = 0;
508   delete fDecoder;
509   delete fDecoderV2;
510   
511   if (fTOFrawData) {
512     fTOFrawData->Clear("C");
513     delete fTOFrawData;
514   }
515
516   //delete fCableLengthMap;
517
518 }
519
520
521 //_____________________________________________________________________________
522
523 void AliTOFRawStream::LoadRawData(Int_t indexDDL)
524 {
525   //
526   // To load raw data
527   //
528
529   fEventID = (Int_t)fRawReader->GetBCID(); //bunch crossing
530
531   fTOFrawData->Clear();
532
533   TClonesArray &arrayTofRawData =  *fTOFrawData;
534
535   fPackedDigits = 0;
536
537   // create raw data map
538   AliTOFRawMap rawMap(fTOFrawData);
539   rawMap.Clear();
540
541   Int_t slot[4] = {-1, -1, -1, -1};
542
543   fLocalEventCounterDRM = -1;
544   fLocalEventCounterLTM = -1;
545   for (Int_t ii=0; ii<13; ii++)
546     fLocalEventCounterTRM[ii] = -1;
547   for (Int_t ii=0; ii<13; ii++)
548     for (Int_t jj=0; jj<2; jj++) {
549       fLocalEventCounterChain[ii][jj] = -1;
550       fChainBunchID[ii][jj] = -1;
551     }
552
553   fRawReader->Reset();
554   fRawReader->Select("TOF", indexDDL, indexDDL);
555     
556   Bool_t signal = kFALSE;
557
558   AliTOFrawData *rawDigit = NULL;
559
560   while(Next()) {
561
562     signal = (fSector!=-1 && fPlate!=-1 && fStrip!=-1 && fPadZ!=-1 && fPadX!=-1);
563     if (signal) {
564       AliDebug(2,Form("  %2i  %1i  %2i  %1i  %2i", fSector, fPlate, fStrip, fPadZ, fPadX));
565
566       slot[0] = fTRM;
567       slot[1] = fTRMchain;
568       slot[2] = fTDC;
569       slot[3] = fTDCchannel;
570
571       if (rawMap.TestHit(slot) != kEmpty) {
572
573         rawDigit = static_cast<AliTOFrawData*>(rawMap.GetHit(slot));
574
575         if (rawDigit->GetLeading()!=-1 && rawDigit->GetTrailing()==-1 &&
576             fLeadingEdge==-1 && fTrailingEdge!=-1) {
577
578           rawDigit->Update(fTime, fToT, fLeadingEdge, fTrailingEdge, fPSbit, fACQ, fErrorFlag);
579         }
580         else if ( ((rawDigit->GetTOF()!=-1 || rawDigit->GetLeading()!=-1 || rawDigit->GetTrailing()!=-1) &&
581                    (fLeadingEdge!=-1 || fTrailingEdge!=-1 || fTime!=-1) )
582
583                   )
584           {
585
586             new (arrayTofRawData[fPackedDigits++]) AliTOFrawData(fTRM, fTRMchain, fTDC, fTDCchannel, fTime, fToT, fLeadingEdge, fTrailingEdge, fPSbit, fACQ, fErrorFlag);
587
588             rawMap.SetHit(slot);
589
590           }
591
592
593       }
594       else {
595
596         new (arrayTofRawData[fPackedDigits++]) AliTOFrawData(fTRM, fTRMchain, fTDC, fTDCchannel, fTime, fToT, fLeadingEdge, fTrailingEdge, fPSbit, fACQ, fErrorFlag);
597
598         rawMap.SetHit(slot);
599
600       } // else if (rawMap.TestHit(slot) == kEmpty)
601
602     } // if (signal)
603
604   } // closed -> while (Next())
605
606 }
607
608 //_____________________________________________________________________________
609 Bool_t AliTOFRawStream::Next()
610 {
611   //
612   // Read next 32-bit word in TOF raw data files
613   // returns kFALSE if there is no word left
614   //
615
616   UInt_t data;
617
618   Int_t dummy = 0;
619
620   if (!fRawReader->ReadNextInt(data)) return kFALSE;
621
622   if (fSector!=-1 && fPlate!=-1 && fStrip!=-1 && fPadZ!=-1 && fPadX!=-1) {
623     fSector = -1;
624     fPlate  = -1;
625     fStrip  = -1;
626     fPadZ   = -1;
627     fPadX   = -1;
628     fTime   = -1;
629     fToT    = -1;
630     fLeadingEdge  = -1;
631     fTrailingEdge = -1;
632   }
633
634   fDDL  = fRawReader->GetDDLID();
635   if (fDDL==-1) {
636     fRawReader->AddMajorErrorLog(kDDLdataReading);
637     AliWarning("Error when load DDL. Go to next DDL");
638     return kFALSE;
639   }
640
641   fWordType = GetField(data,WORD_TYPE_MASK,WORD_TYPE_POSITION);
642
643   switch (fWordType) { // switch word type
644
645   case GLOBAL_HEADER_TYPE: // global header
646     fSlotID = GetField(data, HEADER_SLOT_ID_MASK, HEADER_SLOT_ID_POSITION);
647     fTRM = fSlotID;
648
649
650     switch (fSlotID) { // switch global header slot ID
651
652     case DRM_ID_NUMBER: //DRM global header
653       if (fInsideDRM) { // unexpected DRM global headers -> exit
654         break;
655       }
656       fInsideDRM = kTRUE; // DRM global header accepted
657       break;
658
659     case LTM_ID_NUMBER: // LTM global header
660       if (fInsideLTM) { // unexpected LTM global headers -> exit
661         break;
662       }
663       fInsideLTM = kTRUE; // LTM global header accepted
664       break;
665
666     case  3: //TRM header
667     case  4: //TRM header
668     case  5: //TRM header
669     case  6: //TRM header
670     case  7: //TRM header
671     case  8: //TRM header
672     case  9: //TRM header
673     case 10: //TRM header
674     case 11: //TRM header
675     case 12: //TRM header
676       if (fInsideTRM) { // unexpected TRM global headers -> exit
677         break;
678       }
679       fInsideTRM = kTRUE; // TRM global header accepted
680       fACQ =  GetField(data,TRM_ACQ_BITS_MASK,TRM_ACQ_BITS_POSITION);
681       break;
682
683     default: // unexpected global header slot ID
684       break;
685
686     } //end switch global header slot id
687
688     break;
689
690
691   case GLOBAL_TRAILER_TYPE: // global trailer
692     fSlotID = GetField(data,HEADER_SLOT_ID_MASK,HEADER_SLOT_ID_POSITION);
693
694     switch (fSlotID) { // switch global trailer slot ID
695
696     case DRM_ID_NUMBER: // DRM global trailer
697       if (!fInsideDRM) { // unexpected DRM global trailers -> exit
698         break;
699       }
700       dummy = 0x0000fff0;
701       //AliInfo(Form("  DRM local event counter = %i", GetField(data,dummy,4)));
702       fLocalEventCounterDRM = GetField(data,dummy,4);
703       fInsideDRM = kFALSE; // DRM global trailer accepted
704       fInsideTRM = kFALSE;
705       fInsideLTM = kFALSE;
706       fInsideTRMchain0 = kFALSE;
707       fInsideTRMchain1 = kFALSE;
708       fSector = -1;
709       fPlate  = -1;
710       fStrip  = -1;
711       fPadZ   = -1;
712       fPadX   = -1;
713       fDDL        = -1;
714       fTRM        = -1;
715       fTDC        = -1;
716       fTRMchain   = -1;
717       fTDCchannel = -1;
718       fTime = -1;
719       fToT  = -1;
720       fLeadingEdge  = -1;
721       fTrailingEdge = -1;
722       fErrorFlag = -1;
723       fACQ   = -1;
724       fPSbit = -1;
725       fTDCerrorFlag = -1;
726       break;
727     case LTM_ID_NUMBER: // LTM global trailer
728       if (!fInsideLTM) { // unexpected LTM global trailer -> exit
729         break;
730       }
731       dummy = 0x0fff0000;
732       //AliInfo(Form("  LTM local event counter = %i", GetField(data,dummy,16)));
733       fLocalEventCounterLTM = GetField(data,dummy,16);
734       fInsideLTM = kFALSE; // LTM global trailer accepted
735       break;
736     case 15: //TRM global trailer
737       if (!fInsideTRM) { // unexpected TRM global trailers -> exit
738         break;
739       }
740       dummy = 0x0fff0000;
741       //AliInfo(Form("  TRM local event counter = %i", GetField(data,dummy,16)));
742       fLocalEventCounterTRM[fTRM] = GetField(data,dummy,16);
743       fInsideTRM = kFALSE; // TRM global trailer accepted
744       break;
745     default: // unexpected global trailer slot ID
746       break;
747     } //end switch global trailer slot id
748
749
750     break;
751
752
753   case ERROR_TYPE: // TDC error
754     fTDC          = GetField(data,TRM_TDC_ERROR_TDC_ID_MASK,TRM_TDC_ERROR_TDC_ID_POSITION);
755     fTDCerrorFlag = GetField(data,TRM_TDC_ERROR_FLAGS_MASK,TRM_TDC_ERROR_FLAGS_POSITION);
756     break;
757
758
759   case FILLER_TYPE: // filler
760     break;
761
762
763   default: // other word types
764
765     if (fInsideTRM) { // inside TRM
766
767       switch (fWordType) { // switch word type inside TRM
768       case TRM_CHAIN0_HEADER_TYPE: // TRM chain0 header
769         if (fInsideTRMchain0) { // unexpected TRM chain0 header
770           break;
771         }
772         fInsideTRMchain0 = kTRUE;
773         fTRMchain = 0;
774         dummy = 0x0000fff0;
775         //AliInfo(Form("  chain bunch ID = %i", GetField(data,dummy,4)));
776         fChainBunchID[fTRM][fTRMchain] = GetField(data,dummy,4);
777         break;
778       case TRM_CHAIN0_TRAILER_TYPE: // TRM chain0 trailer
779         if (!fInsideTRMchain0) { // unexpected TRM chain0 trailer
780           break;
781         }
782         dummy = 0x0fff0000;
783         //AliInfo(Form("  chain local event counter = %i", GetField(data,dummy,16)));
784         fLocalEventCounterChain[fTRM][fTRMchain] = GetField(data,dummy,16);
785         fInsideTRMchain0 = kFALSE;
786         fTRMchain = -1;
787         break;
788       case TRM_CHAIN1_HEADER_TYPE: // TRM chain1 header
789         if (fInsideTRMchain1) { // unexpected TRM chain1 header
790           break;
791         }
792         fInsideTRMchain1 = kTRUE;
793         fTRMchain = 1;
794         dummy = 0x0000fff0;
795         //AliInfo(Form("  chain bunch ID = %i", GetField(data,dummy,4)));
796         fChainBunchID[fTRM][fTRMchain] = GetField(data,dummy,4);
797         break;
798       case TRM_CHAIN1_TRAILER_TYPE: // TRM chain1 trailer
799         if (!fInsideTRMchain1) { // unexpected TRM chain1 trailer
800           break;
801         }
802         dummy = 0x0fff0000;
803         //AliInfo(Form("  chain local event counter = %i", GetField(data,dummy,16)));
804         fLocalEventCounterChain[fTRM][fTRMchain] = GetField(data,dummy,16);
805         fInsideTRMchain1 = kFALSE;
806         fTRMchain = -1;
807         break;
808       } // end switch word type inside TRM
809
810     } // end if (fInsideTRM)
811
812       
813     if (
814         ((fInsideTRMchain0&&!fInsideTRMchain1) || (!fInsideTRMchain0&&fInsideTRMchain1)) 
815         && fWordType!=TRM_CHAIN0_HEADER_TYPE && fWordType!=TRM_CHAIN0_TRAILER_TYPE
816         && fWordType!=TRM_CHAIN1_HEADER_TYPE && fWordType!=TRM_CHAIN1_TRAILER_TYPE
817         ){ // inside TRM chains
818
819       fPSbit      = GetField(data,TRM_PS_BITS_MASK,TRM_PS_BITS_POSITION);
820       fTDC        = GetField(data,TRM_TDC_ID_MASK,TRM_TDC_ID_POSITION);
821       fTDCchannel = GetField(data,TRM_CHAN_MASK,TRM_CHAN_POSITION);
822       fErrorFlag  = GetField(data,TRM_E_BIT_MASK,TRM_E_BIT_POSITION);
823
824       SetSector();
825       SetPlate();
826       SetStrip();
827       SetPadZ();
828       SetPadX();
829
830
831       switch (fPSbit) { // switch fPSbit bits inside TRM chains
832
833       case 0: // packing ok, digit time and TOT
834         fToT  = GetField(data,TRM_TOT_WIDTH_MASK, TRM_TOT_WIDTH_POSITION);
835         fTime = GetField(data,TRM_DIGIT_TIME_MASK,TRM_DIGIT_TIME_POSITION)
836           /*-
837           fCableLengthMap->GetCableTimeShiftBin(fDDL, fTRM, fTRMchain, fTDC)*/
838           ;
839         if (fgApplyBCCorrections) {
840           AliDebug(2,"Apply nominal DDL BC time-shift correction");
841           AliDebug(2,"Apply deltaBC time-shift correction");
842           AliDebug(2,Form(" fChainBunchID[%d][%d] = %d ,fEventID = %d",fTRM,fTRMchain,fChainBunchID[fTRM][fTRMchain],fEventID));
843           fTime += fgkddlBCshift[fDDL] * 1024 + (fChainBunchID[fTRM][fTRMchain] - fEventID) * 1024;
844         }
845         break;
846
847       case 1: // leading edge digit, long digit time, no TOT
848         //fToT  = -1;
849         //fTime  = -1;
850         fLeadingEdge = GetField(data,TRM_LONG_DIGIT_TIME_MASK,TRM_LONG_DIGIT_TIME_POSITION)
851           /*-
852           fCableLengthMap->GetCableTimeShiftBin(fDDL, fTRM, fTRMchain, fTDC)*/
853           ;
854         if (fgApplyBCCorrections) {
855           AliDebug(2,"Apply nominal DDL BC time-shift correction");
856           AliDebug(2,"Apply deltaBC time-shift correction");
857           AliDebug(2,Form(" fChainBunchID[%d][%d] = %d ,fEventID = %d",fTRM,fTRMchain,fChainBunchID[fTRM][fTRMchain],fEventID));
858           fLeadingEdge += fgkddlBCshift[fDDL] * 1024 + (fChainBunchID[fTRM][fTRMchain] - fEventID) * 1024;
859         }
860         break;
861
862       case 2: // trailing edge digit, long digit time, no TOT
863         //fToT  = -1;
864         //fTime  = -1;
865         fTrailingEdge = GetField(data,TRM_LONG_DIGIT_TIME_MASK,TRM_LONG_DIGIT_TIME_POSITION)
866           /*-
867           fCableLengthMap->GetCableTimeShiftBin(fDDL, fTRM, fTRMchain, fTDC)*/
868           ;
869         if (fgApplyBCCorrections) {
870           AliDebug(2,"Apply nominal DDL BC time-shift correction");
871           AliDebug(2,"Apply deltaBC time-shift correction");
872           AliDebug(2,Form(" fChainBunchID[%d][%d] = %d ,fEventID = %d",fTRM,fTRMchain,fChainBunchID[fTRM][fTRMchain],fEventID));
873           fTrailingEdge += fgkddlBCshift[fDDL] * 1024 + (fChainBunchID[fTRM][fTRMchain] - fEventID) * 1024;
874         }
875         break;
876
877       case 3: // TOT overflow
878         fToT  = GetField(data,TRM_TOT_WIDTH_MASK, TRM_TOT_WIDTH_POSITION);
879         fTime = GetField(data,TRM_DIGIT_TIME_MASK,TRM_DIGIT_TIME_POSITION)
880           /*-
881           fCableLengthMap->GetCableTimeShiftBin(fDDL, fTRM, fTRMchain, fTDC)*/
882           ;
883         if (fgApplyBCCorrections) {
884           AliDebug(2,"Apply nominal DDL BC time-shift correction");
885           AliDebug(2,"Apply deltaBC time-shift correction");
886           AliDebug(2,Form(" fChainBunchID[%d][%d] = %d ,fEventID = %d",fTRM,fTRMchain,fChainBunchID[fTRM][fTRMchain],fEventID));
887           fTime += fgkddlBCshift[fDDL] * 1024 + (fChainBunchID[fTRM][fTRMchain] - fEventID) * 1024;
888         }
889         break;
890
891       } // end switch PS bits inside TRM chains
892
893     } // end if is inside TRM chains
894
895   } // end switch on fWordType
896
897
898   return kTRUE;
899   
900 }
901 //_____________________________________________________________________________
902
903 void AliTOFRawStream::SetSector()
904 {
905   //
906   // Evaluate the TOF sector number -> [ 0;17]
907   // corresponding to the TOF equipment IDs:
908   //                                  fDDL        -> [ 0;71]
909   //                                  fTRM        -> [ 3;12]
910   //                                  fTRMchain   -> [ 0; 1]
911   //                                  fTDC        -> [ 0;14]
912   //                                  fTDCchannel -> [ 0; 7]
913   //
914
915   Int_t iSector = -1;
916
917   if (!(fDDL==-1)) iSector = Int_t((Float_t)(fDDL)/AliTOFGeometry::NDDL());
918
919   fSector = iSector;
920
921 }
922 //_____________________________________________________________________________
923
924
925 void AliTOFRawStream::SetPlate()
926 {
927   //
928   // Evaluate the TOF plate number ->[ 0; 4]
929   // corresponding to the TOF equipment IDs:
930   //                                  fDDL        -> [ 0;71]
931   //                                  fTRM        -> [ 3;12]
932   //                                  fTRMchain   -> [ 0; 1]
933   //                                  fTDC        -> [ 0;14]
934   //                                  fTDCchannel -> [ 0; 7]
935   //
936
937   Int_t iPlate = -1;
938   if (!(fDDL==-1 || fTRM==-1 || fTDC==-1
939         || fSector==-1))
940     iPlate = Equip2VolNplate(GetDDLnumberPerSector(fDDL), fTRM, fTDC);
941
942   fPlate = iPlate;
943
944 }
945 //_____________________________________________________________________________
946
947 void AliTOFRawStream::SetStrip()
948 {
949   //
950   // Evaluate the TOF strip number per module -> [ 0; 14/18]
951   // corresponding to the TOF equipment IDs:
952   //                                  fDDL        -> [ 0;71]
953   //                                  fTRM        -> [ 3;12]
954   //                                  fTRMchain   -> [ 0; 1]
955   //                                  fTDC        -> [ 0;14]
956   //                                  fTDCchannel -> [ 0; 7]
957   //
958
959   Int_t iStrip = -1;
960
961   if (!(fDDL==-1 || fTRM==-1 || fTDC==-1
962         || fSector==-1 || fPlate==-1))
963     iStrip = Equip2VolNstrip(GetDDLnumberPerSector(fDDL), fTRM, fTDC);
964
965   fStrip = iStrip;
966
967 }
968 //_____________________________________________________________________________
969
970 void AliTOFRawStream::SetPadZ()
971 {
972   //
973   // Evaluate the TOF padRow number per strip -> [ 0; 1]
974   // corresponding to the TOF equipment IDs:
975   //                                  fDDL        -> [ 0;71]
976   //                                  fTRM        -> [ 3;12]
977   //                                  fTRMchain   -> [ 0; 1]
978   //                                  fTDC        -> [ 0;14]
979   //                                  fTDCchannel -> [ 0; 7]
980   //
981
982   Int_t iPadZ = -1;
983
984   if (!(fDDL==-1 || fTRM==-1 || fTRMchain==-1 || fTDC==-1 || fTDCchannel==-1
985         || fSector==-1 || fPlate==-1 || fStrip==-1))
986     {
987       Int_t iPadAlongTheStrip = Equip2VolNpad(GetDDLnumberPerSector(fDDL), fTRMchain, fTDC, fTDCchannel);
988       if (iPadAlongTheStrip!=-1)
989         iPadZ  = iPadAlongTheStrip%AliTOFGeometry::NpadZ();
990     }
991
992   //iPadZ = Equip2VolNpad(GetDDLnumberPerSector(fDDL), fTRMchain, fTDC, fTDCchannel)%AliTOFGeometry::NpadZ();
993   //iPadZ = Equip2VolNpadZ(GetDDLnumberPerSector(fDDL), fTRMchain, fTDC, fTDCchannel);
994
995   fPadZ = iPadZ;
996
997 }
998 //_____________________________________________________________________________
999
1000 void AliTOFRawStream::SetPadX()
1001 {
1002   //
1003   // Evaluate the TOF pad number per strip padRow -> [ 0;47]
1004   // corresponding to the TOF equipment IDs:
1005   //                                  fDDL        -> [ 0;71]
1006   //                                  fTRM        -> [ 3;12]
1007   //                                  fTRMchain   -> [ 0; 1]
1008   //                                  fTDC        -> [ 0;14]
1009   //                                  fTDCchannel -> [ 0; 7]
1010   //
1011
1012   Int_t iPadX = -1;
1013
1014   if (!(fDDL==-1 || fTRM==-1 || fTRMchain==-1 || fTDC==-1 || fTDCchannel==-1
1015         || fSector==-1 || fPlate==-1 || fStrip==-1))
1016     {
1017       Int_t iPadAlongTheStrip = Equip2VolNpad(GetDDLnumberPerSector(fDDL), fTRMchain, fTDC, fTDCchannel);
1018       if (iPadAlongTheStrip!=-1)
1019         iPadX  = (Int_t)(iPadAlongTheStrip/(Float_t(AliTOFGeometry::NpadZ())));
1020     }
1021
1022   //iPadX = (Int_t)(Equip2VolNpad(GetDDLnumberPerSector(fDDL), fTRMchain, fTDC, fTDCchannel)/(Float_t(AliTOFGeometry::NpadZ())));
1023   //iPadX = Equip2VolNpadX(GetDDLnumberPerSector(fDDL), fTRMchain, fTDC, fTDCchannel);
1024
1025   fPadX = iPadX;
1026
1027 }
1028
1029 //----------------------------------------------------------------------------
1030 Int_t AliTOFRawStream::GetField(UInt_t word, Int_t fieldMask, Int_t fieldPosition) const
1031 {
1032   // 
1033   // Returns 'word' masked by 'fieldMask' and shifted by 'fieldPosition'
1034   // 
1035
1036   return ((word & fieldMask) >> fieldPosition);
1037 }
1038
1039 //----------------------------------------------------------------------------
1040 Int_t AliTOFRawStream::Equip2VolNplate(Int_t iDDL, Int_t nTRM, Int_t nTDC)
1041 {
1042   //
1043   // Returns the TOF plate number [0;4]
1044   // corresponding to the TOF equipment ID numbers:
1045   //                          iDDL -> DDL number per sector [0;3]
1046   //                          nTRM -> TRM number [3;12]
1047   //                          nTDC -> TDC number [0;14]
1048   //
1049
1050   Int_t iPlate = -1;
1051
1052   if (iDDL==0) {
1053
1054     if (nTRM>=4 && nTRM<7) {
1055       iPlate = 0;
1056     } else if (nTRM==7) {
1057       if (nTDC<12) iPlate = 0;
1058       else iPlate = 1;
1059     } else if (nTRM>=8 && nTRM<11) {
1060       iPlate = 1;
1061     } else if (nTRM==11) {
1062       if (nTDC<9) iPlate = 1;
1063       else iPlate = 2;
1064     }else if (nTRM==12) {
1065       iPlate = 2;
1066     } 
1067
1068   } else if (iDDL==1) {
1069
1070     if (nTRM==3) {
1071       if (nTDC<3) iPlate = 0;
1072     } else if (nTRM>=4 && nTRM<7) {
1073       iPlate = 0;
1074     } else if (nTRM==7) {
1075       if (nTDC<6) iPlate = 1;
1076       else iPlate = 0;
1077     } else if (nTRM>=8 && nTRM<11) {
1078       iPlate = 1;
1079     } else if (nTRM==11) {
1080       if (nTDC<9) iPlate = 2;
1081       else iPlate = 1;
1082     } else if (nTRM==12) {
1083       iPlate = 2;
1084     } 
1085
1086   } else if (iDDL==2) {
1087
1088     if (nTRM>=4 && nTRM<7) {
1089       iPlate = 4;
1090     } else if (nTRM==7) {
1091       if (nTDC<12) iPlate = 4;
1092       else iPlate = 3;
1093     } else if (nTRM>=8 && nTRM<11) {
1094       iPlate = 3;
1095     } else if (nTRM==11) {
1096       if (nTDC<9) iPlate = 3;
1097       else iPlate = 2;
1098     }else if (nTRM==12) {
1099       iPlate = 2;
1100     } 
1101
1102   }  else if (iDDL==3) {
1103
1104     if (nTRM==3) {
1105       if (nTDC<3) iPlate = 4;
1106     } else if (nTRM>=4 && nTRM<7) {
1107       iPlate = 4;
1108     } else if (nTRM==7) {
1109       if (nTDC<6) iPlate = 3;
1110       else iPlate = 4;
1111     } else if (nTRM>=8 && nTRM<11) {
1112       iPlate = 3;
1113     } else if (nTRM==11) {
1114       if (nTDC<9) iPlate = 2;
1115       else iPlate = 3;
1116     } else if (nTRM==12) {
1117       iPlate = 2;
1118     } 
1119
1120   }
1121
1122   return iPlate;
1123
1124 }
1125
1126 //----------------------------------------------------------------------------
1127 Int_t AliTOFRawStream::Equip2VolNstrip(Int_t iDDL, Int_t nTRM, Int_t nTDC)
1128 {
1129   //
1130   // Returns the TOF strip number per module:
1131   //                                [0;14], in the central plates,
1132   //                                [0;18], in the intermediate and external plates
1133   // corresponding to the TOF equipment ID numbers:
1134   //                                iDDL -> DDL number per sector [0;3]
1135   //                                nTRM -> TRM number [3;12]
1136   //                                nTDC -> TDC number [0;14]
1137   //
1138
1139   Int_t iStrip = -1;
1140
1141   if (iDDL==0) {
1142
1143     if (nTRM== 4) iStrip =  (Int_t)(nTDC/3.);
1144     else if (nTRM== 5) iStrip =  5 + (Int_t)(nTDC/3.);
1145     else if (nTRM== 6) iStrip = 10 + (Int_t)(nTDC/3.);
1146     else if (nTRM== 7) {
1147       if (nTDC<12) iStrip =  15 + (Int_t)(nTDC/3.);
1148       else iStrip = (Int_t)(nTDC/3.) -  4;
1149     }
1150     else if (nTRM== 8) iStrip =  1 + (Int_t)(nTDC/3.);
1151     else if (nTRM== 9) iStrip =  6 + (Int_t)(nTDC/3.);
1152     else if (nTRM==10) iStrip = 11 + (Int_t)(nTDC/3.);
1153     else if (nTRM==11) {
1154       if (nTDC<9) iStrip = 16 + (Int_t)(nTDC/3.);
1155       else iStrip = (Int_t)(nTDC/3.) -  3;
1156     }
1157     else if (nTRM==12) iStrip =  2 + (Int_t)(nTDC/3.);
1158
1159   } else if (iDDL==1) {
1160
1161     if (nTRM==3 && nTDC<3) iStrip = (Int_t)(nTDC/3.);
1162     else if (nTRM== 4) iStrip =  5 - (Int_t)(nTDC/3.);
1163     else if (nTRM== 5) iStrip = 10 - (Int_t)(nTDC/3.);
1164     else if (nTRM== 6) iStrip = 15 - (Int_t)(nTDC/3.);
1165     else if (nTRM== 7) {
1166       if (nTDC<6) iStrip =  1 - (Int_t)(nTDC/3.);
1167       else iStrip = 20 - (Int_t)(nTDC/3.);
1168     }
1169     else if (nTRM== 8) iStrip =  6 - (Int_t)(nTDC/3.);
1170     else if (nTRM== 9) iStrip = 11 - (Int_t)(nTDC/3.);
1171     else if (nTRM==10) iStrip = 16 - (Int_t)(nTDC/3.);
1172     else if (nTRM==11) {
1173       if (nTDC<9) iStrip =  2 - (Int_t)(nTDC/3.);
1174       else iStrip = 21 - (Int_t)(nTDC/3.);
1175     }
1176     else if (nTRM==12) iStrip =  7 - (Int_t)(nTDC/3.);
1177
1178   } else if (iDDL==2) {
1179
1180     if (nTRM== 4) iStrip =  18 - (Int_t)(nTDC/3.);
1181     else if (nTRM== 5) iStrip = 18 - ( 5 + (Int_t)(nTDC/3.));
1182     else if (nTRM== 6) iStrip = 18 - (10 + (Int_t)(nTDC/3.));
1183     else if (nTRM== 7) {
1184       if (nTDC<12) iStrip =  18 - (15 + (Int_t)(nTDC/3.));
1185       else iStrip = 18 - ((Int_t)(nTDC/3.) -  4);
1186     }
1187     else if (nTRM== 8) iStrip = 18 - ( 1 + (Int_t)(nTDC/3.));
1188     else if (nTRM== 9) iStrip = 18 - ( 6 + (Int_t)(nTDC/3.));
1189     else if (nTRM==10) iStrip = 18 - (11 + (Int_t)(nTDC/3.));
1190     else if (nTRM==11) {
1191       if (nTDC<9) iStrip = 18 - (16 + (Int_t)(nTDC/3.));
1192       else iStrip = 14 - ((Int_t)(nTDC/3.) -  3);
1193     }
1194     else if (nTRM==12) iStrip = 14 - ( 2 + (Int_t)(nTDC/3.));
1195
1196   } else if (iDDL==3) {
1197
1198     if (nTRM==3 && nTDC<3) iStrip = 18 - (Int_t)(nTDC/3.);
1199     else if (nTRM== 4) iStrip = 18 - ( 5 - (Int_t)(nTDC/3.));
1200     else if (nTRM== 5) iStrip = 18 - (10 - (Int_t)(nTDC/3.));
1201     else if (nTRM== 6) iStrip = 18 - (15 - (Int_t)(nTDC/3.));
1202     else if (nTRM== 7) {
1203       if (nTDC<6) iStrip =  18 - (1 - (Int_t)(nTDC/3.));
1204       else iStrip = 18 - (20 - (Int_t)(nTDC/3.));
1205     }
1206     else if (nTRM== 8) iStrip = 18 - ( 6 - (Int_t)(nTDC/3.));
1207     else if (nTRM== 9) iStrip = 18 - (11 - (Int_t)(nTDC/3.));
1208     else if (nTRM==10) iStrip = 18 - (16 - (Int_t)(nTDC/3.));
1209     else if (nTRM==11) {
1210       if (nTDC<9) iStrip = 14 - ( 2 - (Int_t)(nTDC/3.));
1211       else iStrip = 18 - (21 - (Int_t)(nTDC/3.));
1212     }
1213     else if (nTRM==12) iStrip = 14 - ( 7 - (Int_t)(nTDC/3.));
1214
1215   } 
1216
1217   return iStrip;
1218
1219 }
1220
1221 //----------------------------------------------------------------------------
1222 Int_t AliTOFRawStream::Equip2VolNpad(Int_t iDDL, Int_t iChain, Int_t nTDC,
1223                                      Int_t iCH)
1224 {
1225   //
1226   // Returns the TOF pad number per strip [0;95]
1227   // corresponding to the TOF equipment ID numbers:
1228   //                          iDDL -> DDL number per sector [0;3]
1229   //                        iChain -> TRM chain number [0;1]
1230   //                          nTDC -> TDC number [0;14]
1231   //                           iCH -> TDC channel number [0;7]
1232   //
1233
1234   Int_t iPadAlongTheStrip = -1;
1235
1236   // wrong
1237   //Int_t iTDClocal = nTDC%3 + (1-iChain)*3;
1238   //if (iDDL==0 || iDDL==3) iTDClocal = 5 - iTDClocal;
1239   //else if (iDDL==1 || iDDL==2) iTDClocal = 6 + (5 - iTDClocal);
1240
1241   // right
1242   Int_t iTDClocal = -1;
1243   Int_t iTDClocal03 = nTDC%3 + (1-iChain)*3;
1244   Int_t iTDClocal12 = 2-nTDC%3 + iChain*3;
1245   if (iDDL==0 || iDDL==3) iTDClocal = 5 - iTDClocal03;
1246   else if (iDDL==1 || iDDL==2) iTDClocal = 6 + (5 - iTDClocal12);
1247
1248   Int_t iCHlocal = iCH;
1249   if (iDDL==0 || iDDL==3) iCHlocal = 7 - iCH;
1250
1251   iPadAlongTheStrip = iTDClocal*AliTOFGeometry::NCh() + iCHlocal;
1252
1253   if (((iDDL==1 || iDDL==2) && iPadAlongTheStrip< AliTOFGeometry::NpadX()) ||
1254       ((iDDL==0 || iDDL==3) && iPadAlongTheStrip>=AliTOFGeometry::NpadX())) {
1255     std::cerr << "Warning -> AliTOFRawStream::Equip2VolNpad: Problems with the padX number!\n";
1256     //AliWarning("Problems with the padX number!");
1257   }
1258   return iPadAlongTheStrip;
1259
1260 }
1261
1262 //----------------------------------------------------------------------------
1263 Int_t AliTOFRawStream::Equip2VolNpadX(Int_t iDDL, Int_t iChain, Int_t nTDC,
1264                                       Int_t iCH)
1265 {
1266   //
1267   // Returns the TOF padX number [0;47]
1268   // corresponding to the TOF equipment ID numbers:
1269   //                          iDDL -> DDL number per sector [0;3]
1270   //                        iChain -> TRM chain number [0;1]
1271   //                          nTDC -> TDC number [0;14]
1272   //                           iCH -> TDC channel number [0;7]
1273   //
1274
1275   Int_t iPadX = (Int_t)(AliTOFRawStream::Equip2VolNpad(iDDL, iChain, nTDC, iCH)/
1276                         (Float_t(AliTOFGeometry::NpadZ())));
1277
1278   return iPadX;
1279
1280 }
1281
1282 //----------------------------------------------------------------------------
1283 Int_t AliTOFRawStream::Equip2VolNpadZ(Int_t iDDL, Int_t iChain, Int_t nTDC,
1284                                       Int_t iCH)
1285 {
1286   //
1287   // Returns the TOF padZ number [0;1]
1288   // corresponding to the TOF equipment ID numbers:
1289   //                          iDDL -> DDL number per sector [0;3]
1290   //                        iChain -> TRM chain number [0;1]
1291   //                          nTDC -> TDC number [0;14]
1292   //                           iCH -> TDC channel number [0;7]
1293   //
1294
1295   Int_t iPadZ  = AliTOFRawStream::Equip2VolNpad(iDDL, iChain, nTDC, iCH)%AliTOFGeometry::NpadZ();
1296
1297   return iPadZ;
1298
1299 }
1300
1301 //----------------------------------------------------------------------------
1302 Int_t AliTOFRawStream::GetSectorNumber(Int_t nDDL)
1303 {
1304   //
1305   // Returns the sector number [0;17]
1306   // corresponing to the assigned DRM/DDL number [0;71]
1307   //
1308
1309   Int_t iSector = Int_t((Float_t)(nDDL)/AliTOFGeometry::NDDL());
1310
1311   return iSector;
1312
1313 }
1314 //----------------------------------------------------------------------------
1315 Int_t AliTOFRawStream::GetDDLnumberPerSector(Int_t nDDL)
1316 {
1317   //
1318   // Return the DRM/DDL number per sector [0;3]
1319   // corresponing to the assigned DRM/DDL number [0;71]
1320   //
1321
1322   Int_t iDDL = nDDL%AliTOFGeometry::NDDL();
1323
1324   return iDDL;
1325
1326 }
1327
1328 //----------------------------------------------------------------------------
1329 void AliTOFRawStream::EquipmentId2VolumeId(AliTOFHitData *hitData, Int_t *volume) const
1330 {
1331   EquipmentId2VolumeId(hitData->GetDDLID(),hitData->GetSlotID(),hitData->GetChain(),hitData->GetTDC(),hitData->GetChan(),volume);
1332 }
1333 //----------------------------------------------------------------------------
1334 void AliTOFRawStream::EquipmentId2VolumeId(Int_t nDDL, Int_t nTRM, Int_t iChain,
1335                                            Int_t nTDC, Int_t iCH,
1336                                            Int_t *volume)
1337 {
1338   //
1339   // To convert:
1340   //            nDDL   (variable in [0;71]) -> number of the DDL file 
1341   //            nTRM   (variable in [3;12]) -> number of the TRM slot
1342   //            iChain (variable in [0; 1]) -> number of the TRM chain
1343   //            nTDC   (variable in [0;14]) -> number of the TDC
1344   //            iCH    (variable in [0; 7]) -> number of the TDC channel
1345   //
1346   // in:
1347   //      sector number, i.e. volume[0] (variable in [0,17])
1348   //      plate  number, i.e. volume[1] (variable in [0, 5])
1349   //      strip  number, i.e. volume[2] (variable in [0,14/18])
1350   //      padX   number, i.e. volume[3] (variable in [0,47])
1351   //      padZ   number, i.e. volume[4] (variable in [0, 1])
1352   //
1353
1354   for (Int_t ii=0; ii<5; ii++) volume[ii] = -1;
1355
1356   Int_t iDDL = GetDDLnumberPerSector(nDDL);
1357
1358   if (iDDL%2==1 && nTRM==3 && nTDC/3>0) { // Signal not coming from a TOF pad but -probably- from a TOF OR signal
1359     //printf("Info -> AliTOFRawStream::EquipmentId2VolumeId: Signal not coming from a TOF pad but -probably- from a TOF OR signal (%2d %2d %2d)\n", nDDL, nTRM, nTDC);
1360     return;
1361   }
1362
1363   Int_t iSector = GetSectorNumber(nDDL);
1364
1365   Int_t iPlate = Equip2VolNplate(iDDL, nTRM, nTDC);
1366   if (iPlate==-1) {
1367     /*if (fRawReader)
1368       fRawReader->AddMajorErrorLog(kPlateError,"plate = -1");*/
1369     AliWarningGeneral("AliTOFRawStream", Form("Warning -> AliTOFRawStream::EquipmentId2VolumeId: Problems with the plate number (%2d %2d %2d)!\n",
1370                          nDDL, nTRM, nTDC));
1371   }
1372
1373   Int_t iStrip = Equip2VolNstrip(iDDL, nTRM, nTDC);
1374   if (iStrip==-1) {
1375     /*if (fRawReader)
1376       fRawReader->AddMajorErrorLog(kStripError,"strip = -1");*/
1377     AliWarningGeneral("AliTOFRawStream", Form("Warning -> AliTOFRawStream::EquipmentId2VolumeId: Problems with the strip number (%2d %2d %2d)!\n",
1378                          nDDL, nTRM, nTDC));
1379   }
1380
1381   Int_t iPadAlongTheStrip  = Equip2VolNpad(iDDL, iChain, nTDC, iCH);
1382   if (iPadAlongTheStrip==-1) {
1383     /*if (fRawReader)
1384       fRawReader->AddMajorErrorLog(kPadAlongStripError,"pad = -1");*/
1385     AliWarningGeneral("AliTOFRawStream", Form("Warning -> AliTOFRawStream::EquipmentId2VolumeId: Problems with the pad number along the strip (%2d %1d %2d %1d)!\n",
1386                          nDDL, iChain, nTDC, iCH));
1387   }
1388   
1389   Int_t iPadX  = (Int_t)(iPadAlongTheStrip/(Float_t(AliTOFGeometry::NpadZ())));
1390   Int_t iPadZ  = iPadAlongTheStrip%AliTOFGeometry::NpadZ();
1391
1392   //Int_t iPadX  = (Int_t)(Equip2VolNpad(iDDL, iChain, nTDC, iCH)/(Float_t(AliTOFGeometry::NpadZ())));
1393   //Int_t iPadZ  = Equip2VolNpad(iDDL, iChain, nTDC, iCH)%AliTOFGeometry::NpadZ();
1394
1395   //Int_t iPadX  = Equip2VolNpadX(iDDL, iChain, nTDC, iCH);
1396   //Int_t iPadZ  = Equip2VolNpadZ(iDDL, iChain, nTDC, iCH);
1397
1398   volume[0] = iSector;
1399   volume[1] = iPlate;
1400   volume[2] = iStrip;
1401   volume[3] = iPadX;
1402   volume[4] = iPadZ;
1403
1404 }
1405 //-----------------------------------------------------------------------------
1406 Bool_t AliTOFRawStream::DecodeDDL(Int_t nDDLMin, Int_t nDDLMax, Int_t verbose = 0) {
1407   //
1408   // To decode raw data for DDL number in [nDDLmin; nDDLmax]
1409   //
1410
1411   //check and fix valid DDL range
1412   if (nDDLMin < 0){
1413     nDDLMin = 0;
1414     fRawReader->AddMinorErrorLog(kDDLMinError);
1415     AliWarning("Wrong DDL range: setting first DDL ID to 0");
1416   }
1417   if (nDDLMax > 71){
1418     nDDLMax = 71;
1419     fRawReader->AddMinorErrorLog(kDDLMaxError);
1420     AliWarning("Wrong DDL range: setting last DDL ID to 71");
1421   }  
1422
1423   //select required DDLs
1424   fRawReader->Reset();
1425   fRawReader->Select("TOF", nDDLMin, nDDLMax);
1426
1427   if (verbose)
1428     AliInfo(Form("Selected TOF DDL range: %d-%d", nDDLMin, nDDLMax));
1429
1430   return(Decode(verbose));
1431 }
1432 //-----------------------------------------------------------------------------
1433 Bool_t AliTOFRawStream::Decode(Int_t verbose = 0) {
1434   //
1435   // New decoder method
1436   //
1437
1438   Int_t currentEquipment;
1439   Int_t currentDDL;
1440   const AliRawDataHeader *currentCDH = 0x0;
1441   const AliRawDataHeaderV3 *currentCDHV3 = 0x0;
1442
1443   //pointers
1444   UChar_t *data = 0x0;
1445   
1446   //loop and read DDL headers 
1447   while(fRawReader->ReadHeader()){
1448
1449     //get equipment infos
1450     currentEquipment = fRawReader->GetEquipmentId();
1451
1452     currentDDL = fRawReader->GetDDLID();
1453     if (currentDDL==-1) {
1454       fRawReader->AddMajorErrorLog(kDDLdataReading);
1455       if (verbose)
1456         AliWarning("Error when load DDL. Go to next DDL");
1457       continue;
1458     }
1459
1460     currentCDH = fRawReader->GetDataHeader();
1461     if (!currentCDH) currentCDHV3 = fRawReader->GetDataHeaderV3();
1462     const Int_t kDataSize = fRawReader->GetDataSize();
1463     const Int_t kDataWords = kDataSize / 4;
1464     data = new UChar_t[kDataSize];
1465     
1466     if (verbose)
1467       AliInfo(Form("Found equipment # %d header (DDL # %d): %d bytes (%d words)", currentEquipment, currentDDL, kDataSize, kDataWords));
1468     
1469     if (verbose)
1470       AliInfo(Form("Reading equipment #%d (DDL # %d) data...", currentEquipment, currentDDL));
1471     
1472     //read equipment payload
1473     if (!fRawReader->ReadNext(data, kDataSize))
1474       {
1475         fRawReader->AddMajorErrorLog(kDDLdataReading);
1476         if (verbose)
1477           AliWarning("Error while reading DDL data. Go to next equipment");
1478         delete [] data;
1479         data = 0x0;
1480         continue;
1481       }
1482     
1483     if (verbose)
1484       AliInfo(Form("Equipment # %d (DDL # %d) data has been readed", currentEquipment, currentDDL));
1485     
1486     
1487     //set up the decoder
1488     fDecoder->SetVerbose(verbose);
1489     fDecoder->SetDataBuffer(&fDataBuffer[currentDDL]);
1490     fDecoder->SetPackedDataBuffer(&fPackedDataBuffer[currentDDL]);
1491     
1492     //start decoding
1493     if (fDecoder->Decode((UInt_t *)data, kDataWords, currentCDH, currentCDHV3) == kTRUE) {
1494       fRawReader->AddMajorErrorLog(kDDLDecoder,Form("DDL # = %d",currentDDL));
1495       if (verbose) AliWarning(Form("Error while decoding DDL # %d: decoder returned with errors", currentDDL));
1496       ResetDataBuffer(currentDDL);
1497       ResetPackedDataBuffer(currentDDL);
1498     }
1499     
1500     delete [] data;
1501     data = 0x0;
1502   }
1503   
1504   //reset reader
1505   fRawReader->Reset();
1506
1507   if (verbose)
1508     AliInfo("All done");
1509     
1510   return kFALSE;
1511   
1512 }
1513 //-----------------------------------------------------------------------------
1514 Bool_t AliTOFRawStream::DecodeV2(Int_t verbose = 0) {
1515   //
1516   // Enhanced decoder method
1517   //
1518
1519   Int_t currentEquipment;
1520   Int_t currentDDL;
1521   //const AliRawDataHeader *currentCDH;
1522
1523   //pointers
1524   UChar_t *data = 0x0;
1525   
1526   // read header
1527   if (!fRawReader->ReadHeader()) return kTRUE;
1528   
1529   //get equipment infos
1530   currentEquipment = fRawReader->GetEquipmentId();
1531   currentDDL = fRawReader->GetDDLID();
1532   //currentCDH = fRawReader->GetDataHeader();
1533   const Int_t kDataSize = fRawReader->GetDataSize();
1534   const Int_t kDataWords = kDataSize / 4;
1535   data = new UChar_t[kDataSize];
1536   
1537   if (verbose)
1538     AliInfo(Form("Found equipment # %d header (DDL # %d): %d bytes (%d words)", currentEquipment, currentDDL, kDataSize, kDataWords));
1539   
1540   if (verbose)
1541     AliInfo(Form("Reading equipment #%d (DDL # %d) data...", currentEquipment, currentDDL));
1542   
1543   //read equipment payload
1544   if (!fRawReader->ReadNext(data, kDataSize))
1545     {
1546       fRawReader->AddMajorErrorLog(kDDLdataReading);
1547       if (verbose)
1548         AliWarning("Error while reading DDL data. Go to next equipment");
1549       delete [] data;
1550       data = 0x0;
1551       return kTRUE;
1552     }
1553   
1554   if (verbose)
1555     AliInfo(Form("Equipment # %d (DDL # %d) data has been read", currentEquipment, currentDDL));
1556   
1557   
1558   //set up the decoder
1559   fDecoderV2->SetVerbose(verbose);
1560   
1561   //start decoding
1562   if (fDecoderV2->Decode((UInt_t *)data, kDataWords) == kTRUE) {
1563     fRawReader->AddMajorErrorLog(kDDLDecoder,Form("DDL # = %d",currentDDL));
1564     if (verbose) AliWarning(Form("Error while decoding DDL # %d: decoder returned with errors", currentDDL));
1565   }
1566   
1567   delete [] data;
1568   
1569   if (verbose)
1570     AliInfo("All done");
1571     
1572   return kFALSE;
1573   
1574 }
1575 //---------------------------------------------------------------------------
1576 void
1577 AliTOFRawStream::ResetBuffers()
1578 {
1579   //
1580   // To reset the buffers
1581   //
1582
1583   for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls("TOF"); iDDL++){
1584     ResetDataBuffer(iDDL);
1585     ResetPackedDataBuffer(iDDL);
1586   }
1587 }
1588   
1589 //---------------------------------------------------------------------------
1590 Bool_t
1591 AliTOFRawStream::LoadRawDataBuffers(Int_t indexDDL, Int_t verbose)
1592 {
1593   //
1594   // To load the buffers
1595   //
1596
1597   fTOFrawData->Clear();
1598   fPackedDigits = 0;
1599   
1600   if (verbose > 0)
1601     AliInfo(Form("Decoding raw data for DDL # %d ...", indexDDL));
1602
1603   if (DecodeDDL(indexDDL, indexDDL, verbose) != 0){ //decode DDL
1604     fRawReader->AddMajorErrorLog(kDDLDecoder,Form("DDL # = %d",indexDDL));
1605     AliWarning(Form("Error while decoding DDL # %d", indexDDL));
1606     return kTRUE;
1607   }
1608   
1609   if (verbose > 0)
1610     AliInfo(Form("Done. %d packed %s been found.", fPackedDataBuffer[indexDDL].GetEntries(), fPackedDataBuffer[indexDDL].GetEntries() > 1 ? "hits have" : "hit has"));
1611   
1612   AliTOFHitData *hitData; //hit data pointer
1613   
1614   if (verbose > 0)
1615     AliInfo("Filling TClonesArray ...");
1616
1617   if (verbose > 0)
1618     if (fgApplyBCCorrections) {
1619       AliInfo("Apply nominal DDL BC time-shift correction");
1620       AliInfo("Apply deltaBC time-shift correction");
1621     }
1622
1623   //loop over DDL packed hits
1624   for (Int_t iHit = 0; iHit < fPackedDataBuffer[indexDDL].GetEntries(); iHit++){
1625     hitData = fPackedDataBuffer[indexDDL].GetHit(iHit); //get hit data
1626     Int_t   hitACQ = hitData->GetACQ();
1627     Int_t   hitPS = hitData->GetPS();
1628     Int_t   hitSlotID = hitData->GetSlotID();
1629     Int_t   hitChain = hitData->GetChain();
1630     Int_t   hitTDC = hitData->GetTDC();
1631     Int_t   hitChan = hitData->GetChan();
1632     Int_t   hitTimeBin = hitData->GetTimeBin();
1633     Int_t   hitTOTBin = hitData->GetTOTBin();
1634     Int_t   hitDeltaBC = hitData->GetDeltaBunchID();
1635     Int_t   hitL0L1Latency = hitData->GetL0L1Latency();
1636
1637     Int_t hitLeading = hitData->GetTimeBin();
1638     Int_t hitTrailing = -1;
1639     Int_t hitError = -1;
1640     
1641     TClonesArray &arrayTofRawData =  *fTOFrawData;
1642     new (arrayTofRawData[fPackedDigits++]) AliTOFrawData(hitSlotID, hitChain, hitTDC, hitChan, hitTimeBin, hitTOTBin, hitLeading, hitTrailing, hitPS, hitACQ, hitError, hitDeltaBC, hitL0L1Latency);
1643   }
1644
1645   if (verbose > 0)
1646     AliInfo("Done.");
1647
1648   if (verbose > 0)
1649     AliInfo("Resetting buffers ...");
1650
1651   fDataBuffer[indexDDL].Reset();
1652   fPackedDataBuffer[indexDDL].Reset();
1653
1654   if (verbose > 0)
1655     AliInfo("Done.");
1656
1657   return kFALSE;
1658 }
1659
1660 //---------------------------------------------------------------------------
1661 Bool_t
1662 AliTOFRawStream::LoadRawDataBuffersV2(Int_t indexDDL, Int_t verbose)
1663 {
1664   //
1665   // To load the buffers
1666   //
1667
1668   /*
1669    * decode raw data and fill output array with TOF hits.
1670    * decode algorithm may return with errors due to inconsistent
1671    * raw data format detected during decoding process.
1672    * decoder algorithm has internal recover procedure to deal with
1673    * errors in a safe condition.
1674    * 
1675    * the following conditions will cause total hit rejection from
1676    * specific boards where the condition is detected:
1677    *
1678    * --- within DRM payload (full DRM skipped) ---
1679    * - no header/trailer detected
1680    *
1681    * --- within TRM payload (full TRM skippped) ---
1682    * - no header/trailer detected
1683    * - empty event inserted
1684    * - bad event counter
1685    * - bad CRC
1686    * - ACQ mode off
1687    *
1688    * --- within chain payload (full chain skipped) ---
1689    * - no header/trailer detected
1690    * - bad status
1691    * - bad event counter
1692    *
1693    * --- HPTDC (ful TDC skipped) ---
1694    * - error detected
1695    *
1696    */
1697
1698   fTOFrawData->Clear();
1699   fPackedDigits = 0;
1700   
1701   if (verbose > 0)
1702     AliInfo(Form("Decoding raw data for DDL # %d ...", indexDDL));
1703
1704   //check and fix valid DDL range
1705   if (indexDDL < 0){
1706     indexDDL = 0;
1707     fRawReader->AddMinorErrorLog(kDDLMinError);
1708     AliWarning("Wrong DDL range: setting first DDL ID to 0");
1709   }
1710   if (indexDDL > 71){
1711     indexDDL = 71;
1712     fRawReader->AddMinorErrorLog(kDDLMaxError);
1713     AliWarning("Wrong DDL range: setting last DDL ID to 71");
1714   }  
1715
1716   //select required DDLs
1717   fRawReader->Reset();
1718   fRawReader->Select("TOF", indexDDL, indexDDL);
1719
1720   /* decode */
1721   if (DecodeV2(verbose)) return kTRUE;
1722
1723   /* read and check CDH info */
1724   const AliRawDataHeader *currentCDH = fRawReader->GetDataHeader();
1725   const AliRawDataHeaderV3 *currentCDHV3 = fRawReader->GetDataHeaderV3();
1726   Int_t currentMiniEventID = currentCDH ? currentCDH->GetMiniEventID(): -1;
1727   currentMiniEventID = currentCDHV3 ? currentCDHV3->GetMiniEventID(): currentMiniEventID;
1728   Int_t currentEventID1 = currentCDH? currentCDH->GetEventID1() : -1;
1729   currentEventID1 = currentCDHV3? currentCDHV3->GetEventID1() : currentEventID1;
1730
1731   /* read decoder summary data */
1732   AliTOFDecoderSummaryData *decodersd;
1733   AliTOFDRMSummaryData *drmsd;
1734   //  AliTOFLTMSummaryData *ltmsd;
1735   AliTOFTRMSummaryData *trmsd;  
1736   AliTOFChainSummaryData *chainsd;
1737   AliTOFTDCHitBuffer *hitBuffer;
1738   AliTOFTDCHit *hit;
1739   AliTOFTDCErrorBuffer *errorBuffer;
1740   AliTOFTDCError *error;
1741   Bool_t tdcErrorFlag[15];
1742   decodersd = fDecoderV2->GetDecoderSummaryData();
1743
1744   /* check error detected/recovered */
1745   if (decodersd->GetErrorDetected()) {
1746       AliDebug(2, Form("Error detected while decoding DDL %d (errorSlotID mask = %04x)", indexDDL, decodersd->GetErrorSlotID()));
1747     if (decodersd->GetRecoveringError()) {
1748       AliDebug(2, "Couldn't recover from error");
1749     }
1750     else {
1751       AliDebug(2, "Error recovered, anyway something is probably lost");
1752     }
1753   }
1754   /* check DRM header/trailer */
1755   drmsd = decodersd->GetDRMSummaryData();
1756   if (!drmsd->GetHeader() || !drmsd->GetTrailer()) {
1757     AliWarning("DRM header/trailer missing, skip DDL");
1758     return kTRUE;
1759   }
1760   /* check partecipating mask */
1761   if (drmsd->GetPartecipatingSlotID() != drmsd->GetDecoderSlotEnableMask()) {
1762       AliDebug(2, Form("DRM slot enable mask differs from decoder slot enable mask (%08x != %08x) in DDL %d", drmsd->GetSlotEnableMask(), drmsd->GetDecoderSlotEnableMask(), indexDDL));
1763     for (Int_t ibit = 0; ibit < 11; ibit++)
1764       if ((drmsd->GetPartecipatingSlotID() & (0x1 << ibit)) && !(drmsd->GetDecoderSlotEnableMask() & (0x1 << ibit)))
1765          AliDebug(2, Form("readout slot %d data is missing in decoder", ibit + 2));
1766   }
1767   
1768   /* get DRM data */
1769   Int_t currentL0BCID = drmsd->GetL0BCID();
1770
1771   /* loop over TRM to get hits */
1772   Int_t hitACQ, hitPS, hitSlotID, hitChain, hitTDC, hitChan, hitTimeBin, hitTOTBin, hitDeltaBC, hitL0L1Latency, hitLeading, hitTrailing, hitError;
1773   Int_t currentBunchID;
1774
1775   /* loop over TRMs */
1776   for (Int_t itrm = 0; itrm < 10; itrm++) {
1777     trmsd = drmsd->GetTRMSummaryData(itrm);
1778     /* check header/trailer */
1779     if (!trmsd->GetHeader() || !trmsd->GetTrailer()) continue;
1780     /* skip if TRM empty event detected */
1781     if (trmsd->GetEBit() != 0) continue;
1782     /* skip if bad TRM event counter detected */
1783     if (trmsd->GetEventCounter() != drmsd->GetLocalEventCounter()) continue;
1784     /* skip if bad TRM CRC detected */
1785     AliDebug(2,Form("~~~~~~ %02d %02d --- TRM CRC: as written in raw data =%d and as computed =%d ~~~~~~",indexDDL,itrm,trmsd->GetEventCRC(), trmsd->GetDecoderCRC()));
1786     if (trmsd->GetEventCRC() != trmsd->GetDecoderCRC()) continue;
1787
1788     /* loop over chains */
1789     for (Int_t ichain = 0; ichain < 2; ichain++) {
1790       chainsd = trmsd->GetChainSummaryData(ichain);
1791     /* check header/trailer */
1792       if (!chainsd->GetHeader() || !chainsd->GetTrailer()) continue;
1793       /* skip if chain bad status detected */
1794       if (chainsd->GetStatus() != 0) continue;
1795       /* skip if bad chain event counter detected */
1796       if (chainsd->GetEventCounter() != drmsd->GetLocalEventCounter()) continue;
1797
1798       currentBunchID = chainsd->GetBunchID();
1799       hitBuffer = chainsd->GetTDCPackedHitBuffer();
1800       errorBuffer = chainsd->GetTDCErrorBuffer();
1801
1802       /* check TDC errors and set TDC error flag */
1803       for (Int_t itdc = 0; itdc < 15; itdc++) tdcErrorFlag[itdc] = kFALSE;
1804       for (Int_t ierr = 0; ierr < errorBuffer->GetEntries(); ierr++) {
1805         error = errorBuffer->GetError(ierr);
1806         tdcErrorFlag[error->GetTDCID()] = kTRUE;
1807       }
1808
1809       /* loop over hits */
1810       for (Int_t ihit = 0; ihit < hitBuffer->GetEntries(); ihit++) {
1811
1812         /* get hit */
1813         hit = hitBuffer->GetHit(ihit);
1814         /* skip hit if coming from a TDC with error detected */
1815         if (tdcErrorFlag[hit->GetTDCID()]) continue;
1816
1817         /* set info */
1818         hitACQ = trmsd->GetACQBits();
1819         hitPS = hit->GetPSBits();
1820         hitSlotID = trmsd->GetSlotID();
1821         hitChain = chainsd->GetChain();
1822         hitTDC = hit->GetTDCID();
1823         hitChan = hit->GetChan();
1824         hitTimeBin = hit->GetHitTime();
1825         hitTOTBin = hit->GetTOTWidth();
1826         hitDeltaBC = currentBunchID - currentEventID1;
1827         hitL0L1Latency = currentMiniEventID - currentL0BCID;
1828         
1829         hitLeading = hitTimeBin;
1830         hitTrailing = -1;
1831         hitError = -1;
1832         
1833         /* add hit */
1834         TClonesArray &arrayTofRawData =  *fTOFrawData;
1835         new (arrayTofRawData[fPackedDigits++]) AliTOFrawData(hitSlotID, hitChain, hitTDC, hitChan, hitTimeBin, hitTOTBin, hitLeading, hitTrailing, hitPS, hitACQ, hitError, hitDeltaBC, hitL0L1Latency);
1836       }
1837     }
1838   }
1839
1840   return kFALSE;
1841 }
1842
1843 //---------------------------------------------------------------------------
1844 void AliTOFRawStream::Geant2EquipmentId(Int_t vol[], Int_t eqId[])
1845 {
1846   //
1847   // To convert:
1848   //      nSector number -vol[0]- (variable in [0,17])
1849   //      nPlate  number -vol[1]- (variable in [0, 5])
1850   //      nStrip  number -vol[2]- (variable in [0,14/18])
1851   //      nPadZ   number -vol[3]- (variable in [0, 1])
1852   //      nPadX   number -vol[4]- (variable in [0,47])
1853   // in:
1854   //      nDDL     -eqId[0]- (variable in [0;71]) -> number of the DDL
1855   //      nTRM     -eqId[1]- (variable in [3;12]) -> number of the TRM
1856   //      nTDC     -eqId[2]- (variable in [0;14]) -> number of the TDC
1857   //      nChain   -eqId[3]- (variable in [0; 1]) -> number of the chain
1858   //      nChannel -eqId[4]- (variable in [0; 8]) -> number of the channel
1859   //
1860
1861   eqId[0] = Geant2DDL(vol);
1862   eqId[1] = Geant2TRM(vol);
1863   eqId[2] = Geant2TDC(vol);
1864   eqId[3] = Geant2Chain(vol);
1865   eqId[4] = Geant2Channel(vol);
1866
1867 }
1868
1869 //---------------------------------------------------------------------------
1870 Int_t AliTOFRawStream::Geant2DDL(Int_t vol[])
1871 {
1872   //
1873   // To convert:
1874   //      nSector number -vol[0]- (variable in [0,17])
1875   //      nPlate  number -vol[1]- (variable in [0, 5])
1876   //      nStrip  number -vol[2]- (variable in [0,14/18])
1877   //      nPadZ   number -vol[3]- (variable in [0, 1])
1878   //      nPadX   number -vol[4]- (variable in [0,47])
1879   // in:
1880   //      nDDL   (variable in [0;71]) -> number of the DDL
1881   //
1882
1883
1884   Int_t iDDL = -1;
1885
1886   if (vol[0]<0 || vol[0]>=AliTOFGeometry::NSectors()) {
1887     printf(" AliTOFRawStream - Error: the sector number (%i) is out of the range: [0,17]\n", vol[0]);
1888     return iDDL;
1889   }
1890   if (vol[1]<0 || vol[1]>=AliTOFGeometry::NPlates()) {
1891     printf(" AliTOFRawStream - Error: the module number (%i) is out of the range: [0,4]\n", vol[1]);
1892     return iDDL;
1893   }
1894   if (vol[2]<0 || vol[2]>=AliTOFGeometry::NStrip(vol[1])) {
1895     printf(" AliTOFRawStream - Error: the strip number (%i) is out of the range: [0,%i]\n", vol[2], AliTOFGeometry::NStrip(vol[1]));
1896     return iDDL;
1897   }
1898   if (vol[3]<0 || vol[3]>=AliTOFGeometry::NpadZ())
1899     printf(" AliTOFRawStream - Error: the padz number (%i) is out of the range: [0,1]\n", vol[3]);
1900   if (vol[4]<0 || vol[4]>=AliTOFGeometry::NpadX())
1901     printf(" AliTOFRawStream - Error: the padx number (%i) is out of the range: [0,47]\n", vol[4]);
1902   if ( vol[3]>=AliTOFGeometry::NpadZ() ) {
1903     printf("Maybe you have to invert the order between vol[3](=%i) and vol[4](=%i)\n", vol[3], vol[4]);
1904     return iDDL;
1905   }
1906
1907   Int_t nSector = vol[0];
1908   Int_t nPlate  = vol[1];
1909   Int_t nStrip  = vol[2];
1910   Int_t nPadX   = vol[4];
1911
1912   if ( nPadX<24 && ( nPlate==0 || nPlate==1 || (nPlate==2 && nStrip<7) ) )
1913     iDDL = 0;
1914   else if ( nPadX>=24 && ( nPlate==0 || nPlate==1 || (nPlate==2 && nStrip<8) ) )
1915     iDDL = 1;
1916   else if ( nPadX>=24 && ( nPlate==3 || nPlate==4 || (nPlate==2 && nStrip>7) ) )
1917     iDDL = 2;
1918   else if ( nPadX<24 && ( nPlate==3 || nPlate==4 || (nPlate==2 && nStrip>6) ) )
1919     iDDL = 3;
1920
1921   return 4*nSector+iDDL;
1922
1923 }
1924
1925 //---------------------------------------------------------------------------
1926 Int_t AliTOFRawStream::Geant2TRM(Int_t vol[])
1927 {
1928   //
1929   // To convert:
1930   //      nSector number -vol[0]- (variable in [0,17])
1931   //      nPlate  number -vol[1]- (variable in [0, 5])
1932   //      nStrip  number -vol[2]- (variable in [0,14/18])
1933   //      nPadZ   number -vol[3]- (variable in [0, 1])
1934   //      nPadX   number -vol[4]- (variable in [0,47])
1935   // in:
1936   //      nTRM   (variable in [3;12]) -> number of the TRM slot
1937   //
1938
1939   Int_t nTRM = -1;
1940
1941   if (vol[0]<0 || vol[0]>=AliTOFGeometry::NSectors()) {
1942     printf(" AliTOFRawStream - Error: the sector number (%i) is out of the range: [0,17]\n", vol[0]);
1943     return nTRM;
1944   }
1945   if (vol[1]<0 || vol[1]>=AliTOFGeometry::NPlates()) {
1946     printf(" AliTOFRawStream - Error: the module number (%i) is out of the range: [0,4]\n", vol[1]);
1947     return nTRM;
1948   }
1949   if (vol[2]<0 || vol[2]>=AliTOFGeometry::NStrip(vol[1])) {
1950     printf(" AliTOFRawStream - Error: the strip number (%i) is out of the range: [0,%i]\n", vol[2], AliTOFGeometry::NStrip(vol[1]));
1951     return nTRM;
1952   }
1953   if (vol[3]<0 || vol[3]>=AliTOFGeometry::NpadZ()) {
1954     printf(" AliTOFRawStream - Error: the padz number (%i) is out of the range: [0,1]\n", vol[3]);
1955     return nTRM;
1956   }
1957   if (vol[4]<0 || vol[4]>=AliTOFGeometry::NpadX()) {
1958     printf(" AliTOFRawStream - Error: the padx number (%i) is out of the range: [0,47]\n", vol[4]);
1959     return nTRM;
1960   }
1961
1962   if ( vol[3]>=AliTOFGeometry::NpadZ() )
1963     {
1964       printf("Maybe you have to invert the order between vol[3](=%i) and vol[4](=%i)\n", vol[3], vol[4]);
1965       return nTRM;
1966     }
1967
1968   Int_t nPlate  = vol[1];
1969   Int_t nStrip  = vol[2];
1970
1971   Int_t iDDL = Geant2DDL(vol)%4;
1972
1973   switch (iDDL) {
1974
1975   case 0:
1976
1977     if (nPlate==0) {
1978       if (nStrip<= 4) nTRM =  4;
1979       else if (nStrip> 4 && nStrip<= 9) nTRM =  5;
1980       else if (nStrip> 9 && nStrip<=14) nTRM =  6;
1981       else if (nStrip>14) nTRM =  7;
1982     }
1983     else if (nPlate==1) {
1984       if (nStrip== 0) nTRM =  7;
1985       else if (nStrip> 0 && nStrip<= 5) nTRM =  8;
1986       else if (nStrip> 5 && nStrip<=10) nTRM =  9;
1987       else if (nStrip>10 && nStrip<=15) nTRM = 10;
1988       else if (nStrip>15) nTRM = 11;
1989     }
1990     else if (nPlate==2) {
1991       if (nStrip<= 1) nTRM = 11;
1992       else if (nStrip> 1 && nStrip< 7) nTRM = 12;
1993     }
1994
1995     break;
1996   case 1:
1997
1998     if (nPlate==0) {
1999       if (nStrip== 0) nTRM =  3;
2000       else if (nStrip> 0 && nStrip<= 5) nTRM =  4;
2001       else if (nStrip> 5 && nStrip<=10) nTRM =  5;
2002       else if (nStrip>10 && nStrip<=15) nTRM =  6;
2003       else if (nStrip>15) nTRM =  7;
2004     }
2005     else if (nPlate==1) {
2006       if (nStrip<=1) nTRM = 7;
2007       else if (nStrip> 1 && nStrip<= 6) nTRM =  8;
2008       else if (nStrip> 6 && nStrip<=11) nTRM =  9;
2009       else if (nStrip>11 && nStrip<=16) nTRM = 10;
2010       else if (nStrip>16) nTRM = 11;
2011     }
2012     else if (nPlate==2) {
2013       if (nStrip<= 2) nTRM = 11;
2014       else if (nStrip> 2 && nStrip<= 7) nTRM = 12;
2015     }
2016
2017     break;
2018   case 2:
2019
2020     if (nPlate==4) {
2021       if (nStrip>=14) nTRM =  4;
2022       else if (nStrip<14 && nStrip>= 9) nTRM =  5;
2023       else if (nStrip< 9 && nStrip>= 4) nTRM =  6;
2024       else if (nStrip< 4) nTRM =  7;
2025     }
2026     else if (nPlate==3) {
2027       if (nStrip==18) nTRM =  7;
2028       else if (nStrip<18 && nStrip>=13) nTRM =  8;
2029       else if (nStrip<13 && nStrip>= 8) nTRM =  9;
2030       else if (nStrip< 8 && nStrip>= 3) nTRM = 10;
2031       else if (nStrip< 3) nTRM = 11;
2032     }
2033     else if (nPlate==2) {
2034       if (nStrip>=13) nTRM = 11;
2035       else if (nStrip<13 && nStrip>= 8) nTRM = 12;
2036     }
2037
2038     break;
2039   case 3:
2040
2041     if (nPlate==4) {
2042       if (nStrip==18) nTRM =  3;
2043       else if (nStrip<18 && nStrip>=13) nTRM =  4;
2044       else if (nStrip<13 && nStrip>= 8) nTRM =  5;
2045       else if (nStrip< 8 && nStrip>= 3) nTRM =  6;
2046       else if (nStrip< 3) nTRM =  7;
2047     }
2048     else if (nPlate==3) {
2049       if (nStrip>=17) nTRM = 7;
2050       else if (nStrip<17 && nStrip>=12) nTRM =  8;
2051       else if (nStrip<12 && nStrip>= 7) nTRM =  9;
2052       else if (nStrip< 7 && nStrip>= 2) nTRM = 10;
2053       else if (nStrip< 2) nTRM = 11;
2054     }
2055     else if (nPlate==2) {
2056       if (nStrip>=12) nTRM = 11;
2057       else if (nStrip <12 && nStrip>= 7) nTRM = 12;
2058     }
2059
2060     break;
2061
2062   }
2063
2064   return nTRM;
2065
2066 }
2067
2068 //---------------------------------------------------------------------------
2069 Int_t AliTOFRawStream::Geant2TDC(Int_t vol[])
2070 {
2071   //
2072   // To convert:
2073   //      nSector number -vol[0]- (variable in [0,17])
2074   //      nPlate  number -vol[1]- (variable in [0, 5])
2075   //      nStrip  number -vol[2]- (variable in [0,14/18])
2076   //      nPadZ   number -vol[3]- (variable in [0, 1])
2077   //      nPadX   number -vol[4]- (variable in [0,47])
2078   // in:
2079   //      nTDC   (variable in [0;14]) -> number of the TDC
2080   //
2081
2082   Int_t nTDC = -1;
2083
2084   if (vol[0]<0 || vol[0]>=AliTOFGeometry::NSectors()) {
2085     printf(" AliTOFRawStream - Error: the sector number (%i) is out of the range: [0,17]\n", vol[0]);
2086     return nTDC;
2087   }
2088   if (vol[1]<0 || vol[1]>=AliTOFGeometry::NPlates()) {
2089     printf(" AliTOFRawStream - Error: the module number (%i) is out of the range: [0,4]\n", vol[1]);
2090     return nTDC;
2091   }
2092   if (vol[2]<0 || vol[2]>=AliTOFGeometry::NStrip(vol[1])) {
2093     printf(" AliTOFRawStream - Error: the strip number (%i) is out of the range: [0,%i]\n", vol[2], AliTOFGeometry::NStrip(vol[1]));
2094     return nTDC;
2095   }
2096   if (vol[3]<0 || vol[3]>=AliTOFGeometry::NpadZ())
2097     printf(" AliTOFRawStream - Error: the padz number (%i) is out of the range: [0,1]\n", vol[3]);
2098   if (vol[4]<0 || vol[4]>=AliTOFGeometry::NpadX())
2099     printf(" AliTOFRawStream - Error: the padx number (%i) is out of the range: [0,47]\n", vol[4]);
2100   if ( vol[3]>=AliTOFGeometry::NpadZ() ) {
2101     printf("Maybe you have to invert the order between vol[3](=%i) and vol[4](=%i)\n", vol[3], vol[4]);
2102     return nTDC;
2103   }
2104
2105   Int_t nPlate  = vol[1];
2106   Int_t nStrip  = vol[2];
2107   Int_t iPadX   = vol[4];
2108
2109   Int_t iDDL = Geant2DDL(vol)%4;
2110
2111   switch (iDDL) {
2112
2113   case 0:
2114
2115     if (nPlate==0) {
2116       if (nStrip<= 4) nTDC = (3*(nStrip)+2-(iPadX/4)%3);
2117       else if (nStrip> 4 && nStrip<= 9) nTDC = (3*(nStrip- 5)+2-(iPadX/4)%3);
2118       else if (nStrip> 9 && nStrip<=14) nTDC = (3*(nStrip-10)+2-(iPadX/4)%3);
2119       else if (nStrip>14) nTDC =  (3*(nStrip-15)+2-(iPadX/4)%3);
2120     }
2121     else if (nPlate==1) {
2122       if (nStrip== 0) nTDC =  (3*(nStrip+ 4)+2-(iPadX/4)%3);
2123       else if (nStrip> 0 && nStrip<= 5) nTDC = (3*(nStrip- 1)+2-(iPadX/4)%3);
2124       else if (nStrip> 5 && nStrip<=10) nTDC = (3*(nStrip- 6)+2-(iPadX/4)%3);
2125       else if (nStrip>10 && nStrip<=15) nTDC = (3*(nStrip-11)+2-(iPadX/4)%3);
2126       else if (nStrip>15) nTDC = (3*(nStrip-16)+2-(iPadX/4)%3);
2127     }
2128     else if (nPlate==2) {
2129       if (nStrip<= 1) nTDC = (3*(nStrip+ 3)+2-(iPadX/4)%3);
2130       else if (nStrip> 1 && nStrip< 7) nTDC = (3*(nStrip- 2)+2-(iPadX/4)%3);
2131     }
2132
2133     break;
2134   case 1:
2135
2136     if (nPlate==0) {
2137       if (nStrip== 0) nTDC = (3*(nStrip)+(iPadX/4)%3);
2138       else if (nStrip> 0 && nStrip<= 5) nTDC = (3*( 5-nStrip)+(iPadX/4)%3);
2139       else if (nStrip> 5 && nStrip<=10) nTDC = (3*(10-nStrip)+(iPadX/4)%3);
2140       else if (nStrip>10 && nStrip<=15) nTDC = (3*(15-nStrip)+(iPadX/4)%3);
2141       else if (nStrip>15) nTDC = (3*(20-nStrip)+(iPadX/4)%3);
2142     }
2143     else if (nPlate==1) {
2144       if (nStrip<= 1) nTDC = (3*( 1-nStrip)+(iPadX/4)%3);
2145       else if (nStrip> 1 && nStrip<= 6) nTDC = (3*( 6-nStrip)+(iPadX/4)%3);
2146       else if (nStrip> 6 && nStrip<=11) nTDC = (3*(11-nStrip)+(iPadX/4)%3);
2147       else if (nStrip>11 && nStrip<=16) nTDC = (3*(16-nStrip)+(iPadX/4)%3);
2148       else if (nStrip>16) nTDC = (3*(21-nStrip)+(iPadX/4)%3);
2149     }
2150     else if (nPlate==2) {
2151       if (nStrip<= 2) nTDC = (3*( 2-nStrip)+(iPadX/4)%3);
2152       else if (nStrip> 2 && nStrip<= 7) nTDC = (3*( 7-nStrip)+(iPadX/4)%3);
2153     }
2154
2155     break;
2156   case 2:
2157
2158     if (nPlate==4) {
2159       if (nStrip>=14) nTDC = (3*(18-nStrip)+((iPadX/4)%3));
2160       else if (nStrip<14 && nStrip>= 9) nTDC = (3*(13-nStrip)+((iPadX/4)%3));
2161       else if (nStrip< 9 && nStrip>= 4) nTDC = (3*( 8-nStrip)+((iPadX/4)%3));
2162       else if (nStrip< 4) nTDC = (3*( 3-nStrip)+((iPadX/4)%3));
2163     }
2164     else if (nPlate==3) {
2165       if (nStrip==18) nTDC = (3*(22-nStrip)+((iPadX/4)%3));
2166       else if (nStrip<18 && nStrip>=13) nTDC = (3*(17-nStrip)+((iPadX/4)%3));
2167       else if (nStrip<13 && nStrip>= 8) nTDC = (3*(12-nStrip)+((iPadX/4)%3));
2168       else if (nStrip< 8 && nStrip>= 3) nTDC = (3*( 7-nStrip)+((iPadX/4)%3));
2169       else if (nStrip< 3) nTDC = (3*( 2-nStrip)+((iPadX/4)%3));
2170     }
2171     else if (nPlate==2) {
2172       if (nStrip>=13) nTDC = (3*(17-nStrip)+((iPadX/4)%3));
2173       else if (nStrip<13 && nStrip>= 8) nTDC = (3*(12-nStrip)+((iPadX/4)%3));
2174     }
2175
2176     break;
2177   case 3:
2178
2179     if (nPlate==4) {
2180       if (nStrip==18) nTDC = (3*(nStrip-18)+2-(iPadX/4)%3);
2181       else if (nStrip<18 && nStrip>=13) nTDC = (3*(nStrip-13)+2-(iPadX/4)%3);
2182       else if (nStrip<13 && nStrip>= 8) nTDC = (3*(nStrip- 8)+2-(iPadX/4)%3);
2183       else if (nStrip< 8 && nStrip>= 3) nTDC = (3*(nStrip- 3)+2-(iPadX/4)%3);
2184       else if (nStrip< 3) nTDC = (3*(nStrip+ 2)+2-(iPadX/4)%3);
2185     }
2186     else if (nPlate==3) {
2187       if (nStrip>=17) nTDC = (3*(nStrip-17)+2-(iPadX/4)%3);
2188       else if (nStrip<17 && nStrip>=12) nTDC = (3*(nStrip-12)+2-(iPadX/4)%3);
2189       else if (nStrip<12 && nStrip>= 7) nTDC = (3*(nStrip- 7)+2-(iPadX/4)%3);
2190       else if (nStrip< 7 && nStrip>= 2) nTDC = (3*(nStrip- 2)+2-(iPadX/4)%3);
2191       else if (nStrip< 2) nTDC = (3*(nStrip+ 3)+2-(iPadX/4)%3);
2192     }
2193     else if (nPlate==2) {
2194       if (nStrip>=12) nTDC = (3*(nStrip-12)+2-(iPadX/4)%3);
2195       else if (nStrip <12 && nStrip>= 7) nTDC = (3*(nStrip- 7)+2-(iPadX/4)%3);
2196     }
2197
2198     break;
2199
2200   }
2201
2202   return nTDC;
2203
2204 }
2205
2206 //---------------------------------------------------------------------------
2207 Int_t AliTOFRawStream::Geant2Chain(Int_t vol[])
2208 {
2209   //
2210   // To convert:
2211   //      nSector number -vol[0]- (variable in [0,17])
2212   //      nPlate  number -vol[1]- (variable in [0, 5])
2213   //      nStrip  number -vol[2]- (variable in [0,14/18])
2214   //      nPadZ   number -vol[3]- (variable in [0, 1])
2215   //      nPadX   number -vol[4]- variable in [0,47])
2216   // in:
2217   //      nChain (variable in [0; 1]) -> number of the TRM chain
2218   //
2219
2220   Int_t nChain = -1;
2221
2222   if (vol[0]<0 || vol[0]>=AliTOFGeometry::NSectors()) {
2223     printf(" AliTOFRawStream - Error: the sector number (%i) is out of the range: [0,17]\n", vol[0]);
2224     return nChain;
2225   }
2226   if (vol[1]<0 || vol[1]>=AliTOFGeometry::NPlates()) {
2227     printf(" AliTOFRawStream - Error: the module number (%i) is out of the range: [0,4]\n", vol[1]);
2228     return nChain;
2229   }
2230   if (vol[2]<0 || vol[2]>=AliTOFGeometry::NStrip(vol[1])) {
2231     printf(" AliTOFRawStream - Error: the strip number (%i) is out of the range: [0,%i]\n", vol[2], AliTOFGeometry::NStrip(vol[1]));
2232     return nChain;
2233   }
2234   if (vol[3]<0 || vol[3]>=AliTOFGeometry::NpadZ())
2235     printf(" AliTOFRawStream - Error: the padz number (%i) is out of the range: [0,1]\n", vol[3]);
2236   if (vol[4]<0 || vol[4]>=AliTOFGeometry::NpadX())
2237     printf(" AliTOFRawStream - Error: the padx number (%i) is out of the range: [0,47]\n", vol[4]);
2238   if ( vol[3]>=AliTOFGeometry::NpadZ() ) {
2239     printf("Maybe you have to invert the order between vol[3](=%i) and vol[4](=%i)\n", vol[3], vol[4]);
2240     return nChain;
2241   }
2242
2243   Int_t iPadX = vol[4];
2244
2245   if (iPadX<12 || iPadX>=36) nChain = 0;
2246   else nChain = 1;
2247
2248   return nChain;
2249
2250 }
2251
2252 //---------------------------------------------------------------------------
2253 Int_t AliTOFRawStream::Geant2Channel(Int_t vol[])
2254 {
2255   //
2256   // To convert:
2257   //      nSector number -vol[0]- (variable in [0,17])
2258   //      nPlate  number -vol[1]- (variable in [0, 5])
2259   //      nStrip  number -vol[2]- (variable in [0,14/18])
2260   //      nPadZ   number -vol[3]- (variable in [0, 1])
2261   //      nPadX   number -vol[4]- (variable in [0,47])
2262   // in:
2263   //      nChannel (variable in [0; 7]) -> number of the TDC channel
2264   //
2265
2266   Int_t nChannel = -1;
2267
2268   if (vol[0]<0 || vol[0]>=AliTOFGeometry::NSectors()) {
2269     printf(" AliTOFRawStream - Error: the sector number (%i) is out of the range: [0,17]\n", vol[0]);
2270     return nChannel;
2271   }
2272   if (vol[1]<0 || vol[1]>=AliTOFGeometry::NPlates()) {
2273     printf(" AliTOFRawStream - Error: the module number (%i) is out of the range: [0,4]\n", vol[1]);
2274     return nChannel;
2275   }
2276   if (vol[2]<0 || vol[2]>=AliTOFGeometry::NStrip(vol[1])) {
2277     printf(" AliTOFRawStream - Error: the strip number (%i) is out of the range: [0,%i]\n", vol[2], AliTOFGeometry::NStrip(vol[1]));
2278     return nChannel;
2279   }
2280   if (vol[3]<0 || vol[3]>=AliTOFGeometry::NpadZ())
2281     printf(" AliTOFRawStream - Error: the padz number (%i) is out of the range: [0,1]\n", vol[3]);
2282   if (vol[4]<0 || vol[4]>=AliTOFGeometry::NpadX())
2283     printf(" AliTOFRawStream - Error: the padx number (%i) is out of the range: [0,47]\n", vol[4]);
2284   if ( vol[3]>=AliTOFGeometry::NpadZ() ) {
2285     printf("Maybe you have to invert the order between vol[3](=%i) and vol[4](=%i)\n", vol[3], vol[4]);
2286     return nChannel;
2287   }
2288
2289   Int_t iPadZ   = vol[3];
2290   Int_t iPadX   = vol[4];
2291
2292   Int_t iDDL = Geant2DDL(vol)%4;
2293
2294   switch (iDDL) {
2295
2296   case 0:
2297     nChannel = ((2*(23-iPadX) + (1-iPadZ)))%8;
2298     break;
2299   case 1:
2300     nChannel = ((2*(iPadX-24) + (iPadZ)))%8;
2301     break;
2302   case 2:
2303     nChannel = ((2*(iPadX-24) + (iPadZ)))%8;
2304     break;
2305   case 3:
2306     nChannel = ((2*(23-iPadX) + (1-iPadZ)))%8;
2307     break;
2308   }
2309
2310   return nChannel;
2311
2312 }
2313
2314 //____________________________________________________________________________
2315 void AliTOFRawStream::Raw2Digits(AliRawReader* rawReader, TClonesArray * const digitsArray)
2316 {
2317   //
2318   // Converts raw data to digits for TOF
2319   //
2320
2321   TStopwatch stopwatch;
2322   stopwatch.Start();
2323
2324   //TClonesArray *fDigits = new TClonesArray("AliTOFdigit", 4000);
2325   //digitsTree->Branch("TOF", &fDigits);
2326   TClonesArray &aDigits = *digitsArray;
2327
2328   Int_t inholes = 0;
2329
2330   Clear();
2331   SetRawReader(rawReader);
2332
2333   //ofstream ftxt;
2334   //if (fVerbose==2) ftxt.open("TOFdigitsRead.txt",ios::app);
2335
2336   TClonesArray staticRawData("AliTOFrawData",10000);
2337   staticRawData.Clear();
2338   TClonesArray * clonesRawData = &staticRawData;
2339
2340   Int_t dummy = -1;
2341   Int_t detectorIndex[5] = {-1, -1, -1, -1, -1};
2342   Int_t digit[4];
2343
2344   const Int_t kMaxNumberOfTracksPerDigit = 3;
2345   Int_t tracks[kMaxNumberOfTracksPerDigit];
2346   for (Int_t ii=0; ii<kMaxNumberOfTracksPerDigit; ii++)
2347     tracks[ii] = -1;
2348   Int_t last = -1;
2349
2350   Int_t indexDDL = 0;
2351   Int_t iRawData = 0;
2352   AliTOFrawData *tofRawDatum = 0;
2353   for (indexDDL=0; indexDDL<AliDAQ::NumberOfDdls("TOF"); indexDDL++) {
2354
2355     rawReader->Reset();
2356     if (fNewDecoderVersion) {
2357       AliInfo("Using New Decoder \n"); 
2358       LoadRawDataBuffers(indexDDL, 0);
2359     }
2360     else
2361       LoadRawData(indexDDL);
2362
2363     clonesRawData = GetRawData();
2364     if (clonesRawData->GetEntriesFast()!=0) AliInfo(Form(" TOF raw data number = %3d", clonesRawData->GetEntriesFast()));
2365     for (iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
2366
2367       tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
2368
2369       //if (tofRawDatum->GetTOT()==-1 || tofRawDatum->GetTOF()==-1) continue;
2370       if (tofRawDatum->GetTOF()==-1) continue;
2371
2372       EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
2373                            tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
2374
2375       dummy = detectorIndex[3];
2376       detectorIndex[3] = detectorIndex[4];//padz
2377       detectorIndex[4] = dummy;//padx
2378
2379       digit[0] = tofRawDatum->GetTOF();
2380       digit[1] = tofRawDatum->GetTOT();
2381       digit[2] = tofRawDatum->GetTOT();
2382       digit[3] = -1;//tofRawDatum->GetTOF(); //tofND
2383
2384       dummy = detectorIndex[3];
2385       detectorIndex[3] = detectorIndex[4];//padx
2386       detectorIndex[4] = dummy;//padz
2387
2388       // Do not reconstruct anything in the holes
2389       if (detectorIndex[0]==13 || detectorIndex[0]==14 || detectorIndex[0]==15 ) { // sectors with holes
2390         if (detectorIndex[1]==2) { // plate with holes
2391           inholes++;
2392           continue;
2393         }
2394       }
2395
2396       last = digitsArray->GetEntriesFast();
2397       new (aDigits[last]) AliTOFdigit(tracks, detectorIndex, digit);
2398       /*
2399       if (fVerbose==2) {
2400         if (indexDDL<10) ftxt << "  " << indexDDL;
2401         else         ftxt << " " << indexDDL;
2402         if (tofRawDatum->GetTRM()<10) ftxt << "  " << tofRawDatum->GetTRM();
2403         else         ftxt << " " << tofRawDatum->GetTRM();
2404         ftxt << "  " << tofRawDatum->GetTRMchain();
2405         if (tofRawDatum->GetTDC()<10) ftxt << "  " << tofRawDatum->GetTDC();
2406         else         ftxt << " " << tofRawDatum->GetTDC();
2407         ftxt << "  " << tofRawDatum->GetTDCchannel();
2408
2409         if (detectorIndex[0]<10) ftxt  << "  ->  " << detectorIndex[0];
2410         else              ftxt  << "  -> " << detectorIndex[0];
2411         ftxt << "  " << detectorIndex[1];
2412         if (detectorIndex[2]<10) ftxt << "  " << detectorIndex[2];
2413         else              ftxt << " " << detectorIndex[2];
2414         ftxt << "  " << detectorIndex[4];
2415         if (detectorIndex[4]<10) ftxt << "  " << detectorIndex[3];
2416         else              ftxt << " " << detectorIndex[3];
2417
2418         if (digit[1]<10)ftxt << "        " << digit[1];
2419         else if (digit[1]>=10 && digit[1]<100) ftxt << "      " << digit[1];
2420         else ftxt << "      " << digit[1];
2421         if (digit[0]<10) ftxt << "      " << digit[0] << endl;
2422         else if (digit[0]>=10 && digit[0]<100)   ftxt << "    " << digit[0] << endl;
2423         else if (digit[0]>=100 && digit[0]<1000) ftxt << "    " << digit[0] << endl;
2424         else ftxt << "   " << digit[3] << endl;
2425       }
2426       */
2427       AliDebug(2, Form(" Raw data reading %2d -> %2d %1d %2d %1d %2d (%d, %d, %d)",
2428                        last,
2429                        detectorIndex[0], detectorIndex[1], detectorIndex[2], detectorIndex[4], detectorIndex[3],
2430                        digit[0], digit[1], digit[3]));
2431
2432       tofRawDatum = 0;
2433     } // loop on tofRawData array
2434
2435     clonesRawData->Clear();
2436
2437   } // DDL Loop
2438
2439   //if (fVerbose==2) ftxt.close();
2440
2441
2442   if (inholes) AliWarning(Form("Raw data in the TOF holes: %d",inholes));
2443
2444   Int_t nDigits = digitsArray->GetEntries();
2445   AliDebug(1, Form("Got %d TOF digits", nDigits));
2446   AliDebug(1, Form("Execution time to read TOF raw data and fill TOF digit tree : R:%.2fs C:%.2fs",
2447                    stopwatch.RealTime(),stopwatch.CpuTime()));
2448
2449 }
2450
2451 //____________________________________________________________________________
2452 void AliTOFRawStream::Raw2SDigits(AliRawReader* rawReader, TClonesArray * const sdigitsArray)
2453 {
2454   //
2455   // Converts raw data to sdigits for TOF
2456   //
2457
2458   TStopwatch stopwatch;
2459   stopwatch.Start();
2460
2461   Int_t inholes = 0;
2462
2463   //if(!GetLoader()->TreeS()) {MakeTree("S");  MakeBranch("S");}
2464   TClonesArray &aSDigits = *sdigitsArray;
2465
2466   Clear();
2467   SetRawReader(rawReader);
2468
2469   //ofstream ftxt;
2470   //if (fVerbose==2) ftxt.open("TOFsdigitsRead.txt",ios::app);
2471
2472   TClonesArray staticRawData("AliTOFrawData",10000);
2473   staticRawData.Clear();
2474   TClonesArray * clonesRawData = &staticRawData;
2475
2476   Int_t dummy = -1;
2477   Int_t detectorIndex[5] = {-1, -1, -1, -1, -1};
2478   Int_t digit[2];
2479   Int_t track = -1;
2480   Int_t last = -1;
2481
2482   Int_t indexDDL = 0;
2483   Int_t iRawData = 0;
2484   AliTOFrawData *tofRawDatum = 0;
2485   for (indexDDL=0; indexDDL<AliDAQ::NumberOfDdls("TOF"); indexDDL++) {
2486
2487     rawReader->Reset();
2488     if (fNewDecoderVersion) {
2489       AliInfo("Using New Decoder \n"); 
2490       LoadRawDataBuffers(indexDDL, 0);
2491     }
2492     else
2493       LoadRawData(indexDDL);
2494
2495     clonesRawData = GetRawData();
2496     if (clonesRawData->GetEntriesFast()!=0) AliInfo(Form(" TOF raw data number = %3d", clonesRawData->GetEntriesFast()));
2497     for (iRawData = 0; iRawData<clonesRawData->GetEntriesFast(); iRawData++) {
2498
2499       tofRawDatum = (AliTOFrawData*)clonesRawData->UncheckedAt(iRawData);
2500
2501       //if (tofRawDatum->GetTOT()==-1 || tofRawDatum->GetTOF()==-1) continue;
2502       if (tofRawDatum->GetTOF()==-1) continue;
2503
2504       EquipmentId2VolumeId(indexDDL, tofRawDatum->GetTRM(), tofRawDatum->GetTRMchain(),
2505                            tofRawDatum->GetTDC(), tofRawDatum->GetTDCchannel(), detectorIndex);
2506
2507       dummy = detectorIndex[3];
2508       detectorIndex[3] = detectorIndex[4];//padz
2509       detectorIndex[4] = dummy;//padx
2510
2511       digit[0] = tofRawDatum->GetTOF();
2512       digit[1] = tofRawDatum->GetTOT();
2513
2514       dummy = detectorIndex[3];
2515       detectorIndex[3] = detectorIndex[4];//padx
2516       detectorIndex[4] = dummy;//padz
2517
2518       // Do not reconstruct anything in the holes
2519       if (detectorIndex[0]==13 || detectorIndex[0]==14 || detectorIndex[0]==15 ) { // sectors with holes
2520         if (detectorIndex[1]==2) { // plate with holes
2521           inholes++;
2522           continue;
2523         }
2524       }
2525
2526       last = sdigitsArray->GetEntriesFast();
2527       new (aSDigits[last]) AliTOFSDigit(track, detectorIndex, digit);
2528       /*
2529       if (fVerbose==2) {
2530         if (indexDDL<10) ftxt << "  " << indexDDL;
2531         else         ftxt << " " << indexDDL;
2532         if (tofRawDatum->GetTRM()<10) ftxt << "  " << tofRawDatum->GetTRM();
2533         else         ftxt << " " << tofRawDatum->GetTRM();
2534         ftxt << "  " << tofRawDatum->GetTRMchain();
2535         if (tofRawDatum->GetTDC()<10) ftxt << "  " << tofRawDatum->GetTDC();
2536         else         ftxt << " " << tofRawDatum->GetTDC();
2537         ftxt << "  " << tofRawDatum->GetTDCchannel();
2538
2539         if (detectorIndex[0]<10) ftxt  << "  ->  " << detectorIndex[0];
2540         else              ftxt  << "  -> " << detectorIndex[0];
2541         ftxt << "  " << detectorIndex[1];
2542         if (detectorIndex[2]<10) ftxt << "  " << detectorIndex[2];
2543         else              ftxt << " " << detectorIndex[2];
2544         ftxt << "  " << detectorIndex[4];
2545         if (detectorIndex[4]<10) ftxt << "  " << detectorIndex[3];
2546         else              ftxt << " " << detectorIndex[3];
2547
2548         if (digit[1]<10)ftxt << "        " << digit[1];
2549         else if (digit[1]>=10 && digit[1]<100) ftxt << "      " << digit[1];
2550         else ftxt << "      " << digit[1];
2551         if (digit[0]<10) ftxt << "      " << digit[0] << endl;
2552         else if (digit[0]>=10 && digit[0]<100)   ftxt << "    " << digit[0] << endl;
2553         else if (digit[0]>=100 && digit[0]<1000) ftxt << "    " << digit[0] << endl;
2554         else ftxt << "   " << digit[3] << endl;
2555       }
2556       */
2557       AliDebug(2, Form(" Raw data reading %2d -> %2d %1d %2d %1d %2d (%d, %d)",
2558                        last,
2559                        detectorIndex[0], detectorIndex[1], detectorIndex[2], detectorIndex[4], detectorIndex[3],
2560                        digit[0], digit[1]));
2561
2562       tofRawDatum = 0;
2563     } // while loop
2564
2565     clonesRawData->Clear();
2566
2567   } // DDL Loop
2568
2569   //if (fVerbose==2) ftxt.close();
2570
2571   if (inholes) AliWarning(Form("Clusters in the TOF holes: %d",inholes));
2572
2573   Int_t nSDigits = sdigitsArray->GetEntries();
2574   AliDebug(1, Form("Got %d TOF sdigits", nSDigits));
2575   AliDebug(1, Form("Execution time to read TOF raw data and fill TOF sdigit tree : R:%.2fs C:%.2fs",
2576                    stopwatch.RealTime(),stopwatch.CpuTime()));
2577
2578 }
2579
2580 void AliTOFRawStream::VolumeID2LTM(Int_t detind[],
2581                                    Int_t &iDDL,
2582                                    Int_t &iTRM,
2583                                    Int_t &iChain,
2584                                    Int_t &iTDC,
2585                                    Int_t &iChannel) const {
2586   //
2587   // To convert the TOF trigger macropad ID (i.e. detind)
2588   // into TOF OR signals equipment ID (i.e. iDDL, iTRM, iChain, iTDC, iChannel)
2589   //
2590
2591   const Int_t kFirstTDCnumber = 12;
2592
2593   iDDL=-1, iTRM = 3 , iChain=-1, iTDC=-1, iChannel=-1;
2594   if (detind[1]==0 || detind[1]==1 || (detind[1]==2 && detind[2]<=7)) {
2595     if (detind[4]<24)
2596       iDDL = detind[0]*4;
2597     else
2598       iDDL = detind[0]*4;
2599   }
2600   else {
2601     if (detind[4]<24)
2602       iDDL = detind[0]*4+2;
2603     else
2604       iDDL = detind[0]*4+2;
2605   }
2606
2607   iChain=fgkChainMap24[detind[1]][detind[2]];
2608   iTDC=(Int_t)(fgkChannelMap24[detind[1]][detind[2]]/8)+kFirstTDCnumber;
2609   iChannel=fgkChannelMap24[detind[1]][detind[2]]%8;
2610   
2611 }
2612
2613 void AliTOFRawStream::LTM2VolumeID(Int_t iDDL,
2614                                    Int_t iTRM,
2615                                    Int_t iChain,
2616                                    Int_t iTDC,
2617                                    Int_t iChannel,
2618                                    Int_t detind0[], Int_t detind1[]) const {
2619   //
2620   // To convert the TOF OR signals equipment ID (i.e. iDDL, iTRM, iChain, iTDC, iChannel)
2621   // into TOF trigger macropad IDs (i.e. detind0 and detind1).
2622   // In general, a couple of neighbouring TOF semi-strip represents a TOF trigger macropad.
2623   //
2624
2625   const Int_t kFirstTDCnumber = 12;
2626
2627   Int_t iSector0=-1, iModule0=-1, iStrip0=-1, iPadX0=-1; // Le variabili del Volume ID
2628   Int_t iSector1=-1, iModule1=-1, iStrip1=-1, iPadX1=-1; // Le variabili del Volume ID
2629
2630   if( iDDL%2==1 && iTRM==3 && iTDC-kFirstTDCnumber>=0 && iTDC-kFirstTDCnumber<3 ) {
2631     iSector0 = (Int_t)(iDDL/4);
2632     iSector1 = (Int_t)(iDDL/4);
2633     Int_t iChan= iChannel+(iTDC-kFirstTDCnumber)*8;
2634     if( iDDL%4 == 1 ){
2635       if(iChain==0){      //CRATE 0
2636         iPadX0=0;
2637         iPadX1=0;
2638         iStrip0=fgkStrip0MapCrate0[iChan];
2639         iStrip1=fgkStrip1MapCrate0[iChan];
2640         iModule0=fgkModule0MapCrate0[iChan];
2641         iModule1=fgkModule1MapCrate0[iChan];
2642       }
2643       if(iChain==1){// CRATE 1
2644         iPadX0=24;
2645         iPadX1=24;
2646         iStrip0=fgkStrip0MapCrate1[iChan];
2647         iStrip1=fgkStrip1MapCrate1[iChan];
2648         iModule0=fgkModule0MapCrate1[iChan];
2649         iModule1=fgkModule1MapCrate1[iChan];
2650       }
2651
2652     }
2653     if( iDDL%4 == 3 ){
2654       if(iChain==1){// CRATE 3
2655         iPadX0=0;
2656         iPadX1=0;
2657         iStrip0=fgkStrip0MapCrate3[iChan];
2658         iStrip1=fgkStrip1MapCrate3[iChan];
2659         iModule0=fgkModule0MapCrate3[iChan];
2660         iModule1=fgkModule1MapCrate3[iChan];
2661       }
2662       if(iChain==0){// CRATE 2
2663         iPadX0=24;
2664         iPadX1=24;
2665         iStrip0=fgkStrip0MapCrate2[iChan];
2666         iStrip1=fgkStrip1MapCrate2[iChan];
2667         iModule0=fgkModule0MapCrate2[iChan];
2668         iModule1=fgkModule1MapCrate2[iChan];
2669       }
2670     }
2671   }
2672
2673   if(iStrip1==-1 || iModule1==-1){
2674     detind1[0]=-1;
2675     detind1[1]=-1;
2676     detind1[2]=-1;
2677     detind1[3]=-1;
2678     detind1[4]=-1;
2679   }
2680   else{
2681     detind1[0]=iSector1;
2682     detind1[1]=iModule1;
2683     detind1[2]=iStrip1;
2684     detind1[3]=iPadX1;
2685     detind1[4]=0;
2686   }
2687
2688   if(iStrip0==-1 || iModule0==-1){
2689     detind0[0]=-1;
2690     detind0[1]=-1;
2691     detind0[2]=-1;
2692     detind0[3]=-1;
2693     detind0[4]=-1;
2694   }
2695   else{
2696     detind0[0]=iSector0;
2697     detind0[1]=iModule0;
2698     detind0[2]=iStrip0;
2699     detind0[3]=iPadX0;
2700     detind0[4]=0;
2701   }
2702 }