Macro for ITS re-alignment (A. Rossi)
[u/mrichter/AliRoot.git] / TRD / AliTRDrawData.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  TRD raw data conversion class                                            //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include <TMath.h>
25 #include "TClass.h"
26
27 #include "AliDAQ.h"
28 #include "AliRawDataHeaderSim.h"
29 #include "AliRawReader.h"
30 #include "AliLog.h"
31 #include "AliFstream.h"
32
33 #include "AliTRDrawData.h"
34 #include "AliTRDdigitsManager.h"
35 #include "AliTRDgeometry.h"
36 #include "AliTRDdataArrayI.h"
37 #include "AliTRDdataArrayS.h"
38 #include "AliTRDRawStream.h"
39 #include "AliTRDRawStreamV2.h"
40 #include "AliTRDcalibDB.h"
41 #include "AliTRDSignalIndex.h"
42 #include "AliTRDfeeParam.h"
43 #include "AliTRDmcmSim.h"
44
45 ClassImp(AliTRDrawData)
46
47 //_____________________________________________________________________________
48 AliTRDrawData::AliTRDrawData()
49   :TObject()
50   ,fGeo(NULL)
51   ,fFee(NULL)
52   ,fNumberOfDDLs(0)
53 {
54   //
55   // Default constructor
56   //
57
58   fFee = AliTRDfeeParam::Instance();
59   fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
60
61 }
62
63 //_____________________________________________________________________________
64 AliTRDrawData::AliTRDrawData(const AliTRDrawData &r)
65   :TObject(r)
66   ,fGeo(NULL)
67   ,fFee(NULL)
68   ,fNumberOfDDLs(0)
69 {
70   //
71   // Copy constructor
72   //
73
74   fFee = AliTRDfeeParam::Instance();
75   fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
76
77 }
78
79 //_____________________________________________________________________________
80 AliTRDrawData::~AliTRDrawData()
81 {
82   //
83   // Destructor
84   //
85
86 }
87
88 //_____________________________________________________________________________
89 Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree, TTree *tracks )
90 {
91   //
92   // Initialize necessary parameters and call one
93   // of the raw data simulator selected by SetRawVersion.
94   //
95   // Currently tracklet output is not spported yet and it
96   // will be supported in higher version simulator.
97   //
98
99   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
100
101   if (!digitsManager->ReadDigits(digitsTree)) {
102     delete digitsManager;
103     return kFALSE;
104   }
105
106   if (tracks != NULL) {
107     delete digitsManager;
108     AliError("Tracklet input is not supported yet.");
109     return kFALSE;
110   }
111
112   fGeo = new AliTRDgeometry();
113
114   if (!AliTRDcalibDB::Instance()) {
115     AliError("Could not get calibration object");
116     delete fGeo;
117     delete digitsManager;
118     return kFALSE;
119   }
120
121   Int_t retval = kTRUE;
122   Int_t rv     = fFee->GetRAWversion();
123
124   // Call appropriate Raw Simulator
125   if ( rv > 0 && rv <= 3 ) retval = Digits2Raw(digitsManager); 
126   else {
127     retval = kFALSE;
128     AliWarning(Form("Unsupported raw version (%d).", rv));
129   }
130
131   // Cleanup
132   delete fGeo;
133   delete digitsManager;
134
135   return retval;
136
137 }
138
139 //_____________________________________________________________________________
140 Bool_t AliTRDrawData::Digits2Raw(AliTRDdigitsManager *digitsManager)
141 {
142   //
143   // Raw data simulator for all versions > 0. This is prepared for real data.
144   // This version simulate only raw data with ADC data and not with tracklet.
145   //
146
147   const Int_t kMaxHcWords = (fGeo->TBmax()/3)
148                           * fGeo->ADCmax()
149                           * fGeo->MCMmax()
150                           * fGeo->ROBmaxC1()/2 
151                           + 100 + 20;
152
153   // Buffer to temporary store half chamber data
154   UInt_t     *hcBuffer    = new UInt_t[kMaxHcWords];
155
156   // sect is same as iDDL, so I use only sect here.
157   for (Int_t sect = 0; sect < fGeo->Nsect(); sect++) { 
158
159     char name[1024];
160     sprintf(name,"TRD_%d.ddl",sect + AliTRDRawStream::kDDLOffset);
161
162     AliFstream* of = new AliFstream(name);
163
164     // Write a dummy data header
165     AliRawDataHeaderSim  header;  // the event header
166     UInt_t hpos = of->Tellp();
167     of->WriteBuffer((char *) (& header), sizeof(header));
168
169     // Reset payload byte size (payload does not include header).
170     Int_t npayloadbyte = 0;
171
172     // GTU common data header (5x4 bytes per super module, shows link mask)
173     for( Int_t cham = 0; cham < fGeo->Ncham(); cham++ ) {
174       UInt_t gtuCdh = (UInt_t)(0xe << 28);
175       for( Int_t plan = 0; plan < fGeo->Nplan(); plan++) {
176         Int_t iDet = fGeo->GetDetector(plan, cham, sect);
177         // If chamber status is ok, we assume that the optical link is also OK.
178         // This is shown in the GTU link mask.
179         if ( AliTRDcalibDB::Instance()->GetChamberStatus(iDet) )
180           gtuCdh = gtuCdh | (3 << (2*plan));
181       }
182       of->WriteBuffer((char *) (& gtuCdh), sizeof(gtuCdh));
183       npayloadbyte += 4;
184     }
185
186     // Prepare chamber data
187     for( Int_t cham = 0; cham < fGeo->Ncham(); cham++) {
188       for( Int_t plan = 0; plan < fGeo->Nplan(); plan++) {
189
190         Int_t iDet = fGeo->GetDetector(plan,cham,sect);
191
192         // Get the digits array
193         AliTRDdataArrayS *digits = (AliTRDdataArrayS *) digitsManager->GetDigits(iDet);
194         if (digits->HasData()) {
195
196           digits->Expand();
197
198           Int_t hcwords = 0;
199           Int_t rv = fFee->GetRAWversion();
200
201           // Process A side of the chamber
202           if ( rv >= 1 && rv <= 2 ) {
203             hcwords = ProduceHcDataV1andV2(digits,0,iDet,hcBuffer,kMaxHcWords);
204           }
205           if ( rv == 3 ) { 
206             hcwords = ProduceHcDataV3     (digits,0,iDet,hcBuffer,kMaxHcWords);
207           }
208
209           of->WriteBuffer((char *) hcBuffer, hcwords*4);
210           npayloadbyte += hcwords*4;
211
212           // Process B side of the chamber
213           if ( rv >= 1 && rv <= 2 ) {
214             hcwords = ProduceHcDataV1andV2(digits,1,iDet,hcBuffer,kMaxHcWords);
215           }
216           if ( rv >= 3 ) {
217             hcwords = ProduceHcDataV3     (digits,1,iDet,hcBuffer,kMaxHcWords);
218           }
219
220           of->WriteBuffer((char *) hcBuffer, hcwords*4);
221           npayloadbyte += hcwords*4;
222
223         }
224
225       }
226     }
227
228     // Complete header
229     header.fSize = UInt_t(of->Tellp()) - hpos;
230     header.SetAttribute(0);  // Valid data
231     of->Seekp(hpos);         // Rewind to header position
232     of->WriteBuffer((char *) (& header), sizeof(header));
233     delete of;
234   }
235
236   delete [] hcBuffer;
237
238   return kTRUE;
239
240 }
241
242 //_____________________________________________________________________________
243 Int_t AliTRDrawData::ProduceHcDataV1andV2(AliTRDdataArrayS *digits, Int_t side
244                                         , Int_t det, UInt_t *buf, Int_t maxSize)
245 {
246   //
247   // This function simulates: 1) SM-I commissiong data Oct. 06 (Raw Version == 1).
248   //                          2) Full Raw Production Version   (Raw Version == 2)
249   //
250   // Produce half chamber data (= an ORI data) for the given chamber (det) and side (side)
251   // where
252   //
253   //   side=0 means A side with ROB positions 0, 2, 4, 6.
254   //   side=1 means B side with ROB positions 1, 3, 5, 7.
255   //
256   // Chamber type (C0 orC1) is determined by "det" automatically.
257   // Appropriate size of buffer (*buf) must be prepared prior to calling this function.
258   // Pointer to the buffer and its size must be given to "buf" and "maxSize".
259   // Return value is the number of valid data filled in the buffer in unit of 32 bits
260   // UInt_t words.
261   // If buffer size if too small, the data is truncated with the buffer size however
262   // the function will finish without crash (this behaviour is similar to the MCM).
263   //
264
265   Int_t           nw = 0;                       // Number of written    words
266   Int_t           of = 0;                       // Number of overflowed words
267   Int_t         plan = fGeo->GetPlane( det );   // Plane
268   Int_t         cham = fGeo->GetChamber( det ); // Chamber
269   Int_t         sect = fGeo->GetSector( det );  // Sector (=iDDL)
270   Int_t         nRow = fGeo->GetRowMax( plan, cham, sect );
271   Int_t         nCol = fGeo->GetColMax( plan );
272   const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
273   Int_t       kCtype = 0;                       // Chamber type (0:C0, 1:C1)
274   Int_t          iEv = 0xA;                     // Event ID. Now fixed to 10, how do I get event id?
275   UInt_t           x = 0;                       // General used number
276   Int_t           rv = fFee->GetRAWversion();
277
278   // Check the nCol and nRow.
279   if ((nCol == 144) && 
280       (nRow == 16 || nRow == 12)) {
281     kCtype = (nRow-12) / 4;
282   } 
283   else {
284     AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)."
285                  ,nRow,nCol));
286     return 0;
287   }
288
289   AliDebug(1,Form("Producing raw data for sect=%d plan=%d cham=%d side=%d"
290                  ,sect,plan,cham,side));
291
292   // Tracklet should be processed here but not implemented yet
293
294   // Write end of tracklet marker
295   if (nw < maxSize) {
296     buf[nw++] = kEndoftrackletmarker;
297   } 
298   else {
299     of++;
300   }
301
302   // Half Chamber header
303   if      ( rv == 1 ) {
304     // Now it is the same version as used in SM-I commissioning.
305     Int_t  dcs = det+100;      // DCS Serial (in simulation, it is meaningless
306     x = (dcs<<20) | (sect<<15) | (plan<<12) | (cham<<9) | (side<<8) | 1;
307     if (nw < maxSize) {
308       buf[nw++] = x; 
309     }
310     else {
311       of++;
312     }
313   } 
314   else if ( rv == 2 ) {
315     // h[0] (there are 3 HC header)
316     Int_t minorv = 0;      // The minor version number
317     Int_t add    = 2;      // The number of additional header words to follow
318     x = (1<<31) | (rv<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (plan<<6) | (cham<<3) | (side<<2) | 1;
319     if (nw < maxSize) {
320       buf[nw++] = x; 
321     }
322     else {
323       of++;
324     }
325     // h[1]
326     Int_t bcCtr   = 99; // bunch crossing counter. Here it is set to 99 always for no reason
327     Int_t ptCtr   = 15; // pretrigger counter. Here it is set to 15 always for no reason
328     Int_t ptPhase = 11; // pretrigger phase. Here it is set to 11 always for no reason
329     x = (bcCtr<<16) | (ptCtr<<12) | (ptPhase<<8) | ((kNTBin-1)<<2) | 1;
330     if (nw < maxSize) {
331       buf[nw++] = x; 
332     }
333     else {
334       of++;
335     }
336     // h[2]
337     Int_t pedSetup       = 1;    // Pedestal filter setup (0:1). Here it is always 1 for no reason
338     Int_t gainSetup      = 1;    // Gain filter setup (0:1). Here it is always 1 for no reason
339     Int_t tailSetup      = 1;    // Tail filter setup (0:1). Here it is always 1 for no reason
340     Int_t xtSetup        = 0;    // Cross talk filter setup (0:1). Here it is always 0 for no reason
341     Int_t nonlinSetup    = 0;    // Nonlinearity filter setup (0:1). Here it is always 0 for no reason
342     Int_t bypassSetup    = 0;    // Filter bypass (for raw data) setup (0:1). Here it is always 0 for no reason
343     Int_t commonAdditive = 10;   // Digital filter common additive (0:63). Here it is always 10 for no reason
344     x = (pedSetup<<31) | (gainSetup<<30) | (tailSetup<<29) | (xtSetup<<28) | (nonlinSetup<<27)
345       | (bypassSetup<<26) | (commonAdditive<<20) | 1;
346     if (nw < maxSize) {
347       buf[nw++] = x; 
348     }
349     else {
350       of++;
351     }
352   }
353
354   // Scan for ROB and MCM
355   for (Int_t iRobRow = 0; iRobRow < (kCtype + 3); iRobRow++ ) {
356     Int_t iRob = iRobRow * 2 + side;
357     for (Int_t iMcm = 0; iMcm < fGeo->MCMmax(); iMcm++ ) {
358       Int_t padrow = iRobRow * 4 + iMcm / 4;
359
360       // MCM header
361       x = ((iRob * fGeo->MCMmax() + iMcm) << 24) | ((iEv % 0x100000) << 4) | 0xC;
362       if (nw < maxSize) {
363         buf[nw++] = x; 
364       }
365       else {
366         of++;
367       }
368
369       // ADC data
370       for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) {
371         Int_t padcol = fFee->GetPadColFromADC(iRob, iMcm, iAdc);
372         UInt_t aa = !(iAdc & 1) + 2;
373         UInt_t *a = new UInt_t[kNTBin+2];
374         // 3 timebins are packed into one 32 bits word
375         for (Int_t iT = 0; iT < kNTBin; iT+=3) { 
376           if ((padcol >=    0) && (padcol <  nCol)) {
377             a[iT  ] = ((iT    ) < kNTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT    ) : 0;
378             a[iT+1] = ((iT + 1) < kNTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 1) : 0;
379             a[iT+2] = ((iT + 2) < kNTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 2) : 0; 
380           } 
381           else {
382             a[iT] = a[iT+1] = a[iT+2] = 0; // This happenes at the edge of chamber (should be pedestal! How?)
383           }
384           x = (a[iT+2] << 22) | (a[iT+1] << 12) | (a[iT] << 2) | aa;
385           if (nw < maxSize) {
386             buf[nw++] = x; 
387           }
388           else {
389             of++;
390           }
391         }
392         // Diagnostics
393         Float_t avg = 0;
394         Float_t rms = 0;
395         for (Int_t iT = 0; iT < kNTBin; iT++) {
396           avg += (Float_t) (a[iT]);
397         }
398         avg /= (Float_t) kNTBin;
399         for (Int_t iT = 0; iT < kNTBin; iT++) {
400           rms += ((Float_t) (a[iT]) - avg) * ((Float_t) (a[iT]) - avg);
401         }
402         rms = TMath::Sqrt(rms / (Float_t) kNTBin);
403         if (rms > 1.7) {
404           AliDebug(2,Form("Large RMS (>1.7)  (ROB,MCM,ADC)=(%02d,%02d,%02d), avg=%03.1f, rms=%03.1f"
405                           ,iRob,iMcm,iAdc,avg,rms));
406         }
407         delete [] a;
408       }
409     }
410   }
411
412   // Write end of raw data marker
413   if (nw < maxSize) {
414     buf[nw++] = kEndofrawdatamarker; 
415   }
416   else {
417     of++;
418   }
419   if (of != 0) {
420     AliWarning("Buffer overflow. Data is truncated. Please increase buffer size and recompile.");
421   }
422
423   return nw;
424
425 }
426
427 //_____________________________________________________________________________
428 Int_t AliTRDrawData::ProduceHcDataV3(AliTRDdataArrayS *digits, Int_t side
429                                    , Int_t det, UInt_t *buf, Int_t maxSize)
430 {
431   //
432   // This function simulates: Raw Version == 3 (Zero Suppression Prototype)
433   //
434
435   Int_t           nw = 0;                       // Number of written    words
436   Int_t           of = 0;                       // Number of overflowed words
437   Int_t         plan = fGeo->GetPlane( det );   // Plane
438   Int_t         cham = fGeo->GetChamber( det ); // Chamber
439   Int_t         sect = fGeo->GetSector( det );  // Sector (=iDDL)
440   Int_t         nRow = fGeo->GetRowMax( plan, cham, sect );
441   Int_t         nCol = fGeo->GetColMax( plan );
442   const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
443   Int_t       kCtype = 0;                       // Chamber type (0:C0, 1:C1)
444   //Int_t          iEv = 0xA;                     // Event ID. Now fixed to 10, how do I get event id?
445   UInt_t           x = 0;                       // General used number
446   Int_t           rv = fFee->GetRAWversion();
447
448   // Check the nCol and nRow.
449   if ((nCol == 144) && 
450       (nRow == 16 || nRow == 12)) {
451     kCtype = (nRow-12) / 4;
452   } 
453   else {
454     AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)."
455                  ,nRow,nCol));
456     return 0;
457   }
458
459   AliDebug(1,Form("Producing raw data for sect=%d plan=%d cham=%d side=%d"
460                  ,sect,plan,cham,side));
461
462   // Tracklet should be processed here but not implemented yet
463
464   // Write end of tracklet marker
465   if (nw < maxSize) {
466     buf[nw++] = kEndoftrackletmarker;
467   } 
468   else {
469     of++;
470   }
471
472   // Half Chamber header
473   // h[0] (there are 3 HC header)
474   Int_t minorv = 0;    // The minor version number
475   Int_t add    = 2;    // The number of additional header words to follow
476   x = (1<<31) | (rv<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (plan<<6) | (cham<<3) | (side<<2) | 1;
477   if (nw < maxSize) {
478     buf[nw++] = x; 
479   }
480   else {
481     of++;
482   }
483   // h[1]
484   Int_t bcCtr   = 99; // bunch crossing counter. Here it is set to 99 always for no reason
485   Int_t ptCtr   = 15; // pretrigger counter. Here it is set to 15 always for no reason
486   Int_t ptPhase = 11; // pretrigger phase. Here it is set to 11 always for no reason
487   x = (bcCtr<<16) | (ptCtr<<12) | (ptPhase<<8) | ((kNTBin-1)<<2) | 1;
488   if (nw < maxSize) {
489     buf[nw++] = x; 
490   }
491   else {
492     of++;
493   }
494   // h[2]
495   Int_t pedSetup       = 1;  // Pedestal filter setup (0:1). Here it is always 1 for no reason
496   Int_t gainSetup      = 1;  // Gain filter setup (0:1). Here it is always 1 for no reason
497   Int_t tailSetup      = 1;  // Tail filter setup (0:1). Here it is always 1 for no reason
498   Int_t xtSetup        = 0;  // Cross talk filter setup (0:1). Here it is always 0 for no reason
499   Int_t nonlinSetup    = 0;  // Nonlinearity filter setup (0:1). Here it is always 0 for no reason
500   Int_t bypassSetup    = 0;  // Filter bypass (for raw data) setup (0:1). Here it is always 0 for no reason
501   Int_t commonAdditive = 10; // Digital filter common additive (0:63). Here it is always 10 for no reason
502   x = (pedSetup<<31) | (gainSetup<<30) | (tailSetup<<29) | (xtSetup<<28) | (nonlinSetup<<27)
503     | (bypassSetup<<26) | (commonAdditive<<20) | 1;
504   if (nw < maxSize) {
505     buf[nw++] = x; 
506   }
507   else {
508     of++;
509   }
510
511   // Scan for ROB and MCM
512   for (Int_t iRobRow = 0; iRobRow < (kCtype + 3); iRobRow++ ) {
513     Int_t iRob = iRobRow * 2 + side;
514     for (Int_t iMcm = 0; iMcm < fGeo->MCMmax(); iMcm++ ) {
515
516       AliTRDmcmSim *mcm = new AliTRDmcmSim();
517       mcm->Init( det, iRob, iMcm );
518       Int_t padrow = mcm->GetRow();
519
520       // Copy ADC data to MCM simulator
521       for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) {
522         Int_t padcol = mcm->GetCol( iAdc );
523         if ((padcol >=    0) && (padcol <  nCol)) {
524           for (Int_t iT = 0; iT < kNTBin; iT++) { 
525             mcm->SetData( iAdc, iT, digits->GetDataUnchecked( padrow, padcol, iT) );
526           } 
527         } else {  // this means it is out of chamber, and masked ADC
528           mcm->SetDataPedestal( iAdc );
529         }
530       }
531       // Simulate process in MCM
532       mcm->Filter();     // Apply filter
533       mcm->ZSMapping();  // Calculate zero suppression mapping
534       //mcm->DumpData( "trdmcmdata.txt", "RFZS" ); // debugging purpose
535
536       // Write MCM data to buffer
537       Int_t tempNw =  mcm->ProduceRawStream( &buf[nw], maxSize - nw );
538       if( tempNw < 0 ) {
539         of += tempNw;
540         nw += maxSize - nw;
541         AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile."));
542       } else {
543         nw += tempNw;
544       }
545
546       delete mcm;
547
548     }
549   }
550
551   // Write end of raw data marker
552   if (nw < maxSize) {
553     buf[nw++] = kEndofrawdatamarker; 
554   }
555   else {
556     of++;
557   }
558   if (of != 0) {
559     AliError("Buffer overflow. Data is truncated. Please increase buffer size and recompile.");
560   }
561
562   return nw;
563
564 }
565
566 //_____________________________________________________________________________
567 AliTRDdigitsManager *AliTRDrawData::Raw2Digits(AliRawReader *rawReader)
568 {
569   //
570   // Vx of the raw data reading
571   //
572
573   AliTRDdataArrayS *digits = 0;
574   AliTRDdataArrayI *track0 = 0;
575   AliTRDdataArrayI *track1 = 0;
576   AliTRDdataArrayI *track2 = 0; 
577
578   AliTRDSignalIndex *indexes = 0;
579   // Create the digits manager
580   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
581   digitsManager->CreateArrays();
582
583   //AliTRDRawStream input(rawReader);
584   AliTRDRawStreamV2 input(rawReader);
585   input.SetRawVersion( fFee->GetRAWversion() );
586   input.Init();
587
588   AliInfo(Form("Stream version: %s", input.IsA()->GetName()));
589
590   // Loop through the digits
591   Int_t lastdet = -1;
592   Int_t det    = 0;
593   Int_t it = 0;
594   while (input.Next()) {
595
596       det    = input.GetDet();
597
598       if (det != lastdet) { // If new detector found
599         
600           lastdet = det;
601
602           if (digits) digits->Compress(1,0);
603           if (track0) track0->Compress(1,0);
604           if (track1) track1->Compress(1,0);
605           if (track2) track2->Compress(1,0);
606         
607           // Add a container for the digits of this detector
608           digits = (AliTRDdataArrayS *) digitsManager->GetDigits(det);
609           track0 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,0);
610           track1 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,1);
611           track2 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,2);
612
613           // Allocate memory space for the digits buffer
614           if (digits->GetNtime() == 0) 
615             {
616               digits->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
617               track0->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
618               track1->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
619               track2->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
620             }
621
622           indexes = digitsManager->GetIndexes(det);
623           indexes->SetSM(input.GetSM());
624           indexes->SetStack(input.GetStack());
625           indexes->SetLayer(input.GetLayer());
626           indexes->SetDetNumber(det);
627           if (indexes->IsAllocated() == kFALSE)
628             indexes->Allocate(input.GetMaxRow(), input.GetMaxCol(), input.GetNumberOfTimeBins());
629         }
630     
631       // 3 timebin data are stored per word
632       for (it = 0; it < 3; it++)
633         {
634           if ( input.GetTimeBin() + it < input.GetNumberOfTimeBins() )
635             {
636               if (input.GetSignals()[it] > 0)
637                 {
638                   digits->SetDataUnchecked(input.GetRow(), input.GetCol(),
639                                            input.GetTimeBin() + it, input.GetSignals()[it]);
640
641                   indexes->AddIndexTBin(input.GetRow(), input.GetCol(),
642                                         input.GetTimeBin() + it);
643                   track0->SetDataUnchecked(input.GetRow(), input.GetCol(),
644                                            input.GetTimeBin() + it, 0);
645                   track1->SetDataUnchecked(input.GetRow(), input.GetCol(),
646                                            input.GetTimeBin() + it, 0);
647                   track2->SetDataUnchecked(input.GetRow(), input.GetCol(),
648                                            input.GetTimeBin() + it, 0);
649                 }
650             }
651         }
652   }
653
654   if (digits) digits->Compress(1,0);
655   if (track0) track0->Compress(1,0);
656   if (track1) track1->Compress(1,0);
657   if (track2) track2->Compress(1,0);
658
659   return digitsManager;
660
661 }