Revised version of raw data v1 (bug fix and coding vios)
[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 <Riostream.h>
25 #include <TMath.h>
26
27 #include "AliDAQ.h"
28 #include "AliRawDataHeader.h"
29 #include "AliRawReader.h"
30 #include "AliLog.h"
31
32 #include "AliTRDrawData.h"
33 #include "AliTRDdigitsManager.h"
34 #include "AliTRDgeometry.h"
35 #include "AliTRDdataArrayI.h"
36 #include "AliTRDRawStream.h"
37 #include "AliTRDCommonParam.h"
38 #include "AliTRDcalibDB.h"
39
40 ClassImp(AliTRDrawData)
41
42 //_____________________________________________________________________________
43 AliTRDrawData::AliTRDrawData()
44   :TObject()
45   ,fRawVersion(1)    // Default Raw Data version set here
46   ,fCommonParam(0)
47   ,fCalibration(0)
48   ,fGeo(0)
49   ,fNumberOfDDLs(0)
50 {
51   //
52   // Default constructor
53   //
54
55 }
56
57 //_____________________________________________________________________________
58 AliTRDrawData::AliTRDrawData(const AliTRDrawData &r)
59   :TObject(r)
60   ,fRawVersion(1)    // Default Raw Data version set here
61   ,fCommonParam(0)
62   ,fCalibration(0)
63   ,fGeo(0)
64   ,fNumberOfDDLs(0)
65 {
66   //
67   // Copy constructor
68   //
69
70 }
71
72 //_____________________________________________________________________________
73 AliTRDrawData::~AliTRDrawData()
74 {
75   //
76   // Destructor
77   //
78
79 }
80
81 //_____________________________________________________________________________
82 Bool_t AliTRDrawData::SetRawVersion(Int_t v)
83 {
84   //
85   // Set the raw data version (Currently only version 0, 1 and 2 are available)
86   //
87
88   if ( (v >= 0) && (v <= 2) ) {
89     fRawVersion = v;
90     return kTRUE;
91   }
92
93   return kFALSE;
94
95 }
96
97 //_____________________________________________________________________________
98 Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree, TTree *tracks )
99 {
100   //
101   // Initialize necessary parameters and call one
102   // of the raw data simulator selected by SetRawVersion.
103   //
104   // Currently tracklet output is not spported yet and it
105   // will be supported in higher version simulator.
106   //
107
108   fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
109
110   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
111
112   if (!digitsManager->ReadDigits(digitsTree)) {
113     delete digitsManager;
114     return kFALSE;
115   }
116
117   if (tracks != NULL) {
118     delete digitsManager;
119     AliError("Tracklet input is not supported yet.");
120     return kFALSE;
121   }
122
123   fGeo = new AliTRDgeometry();
124
125   fCommonParam = AliTRDCommonParam::Instance();
126   if (!fCommonParam) {
127     AliError("Could not get common params");
128     delete fGeo;
129     delete digitsManager;
130     return kFALSE;
131   }
132
133   fCalibration = AliTRDcalibDB::Instance();
134   if (!fCalibration) {
135     AliError("Could not get calibration object");
136     delete fGeo;
137     delete digitsManager;
138     return kFALSE;
139   }
140
141   Int_t retval = kTRUE;
142
143   // Call appropriate Raw Simulator
144   if      ( fRawVersion == 0 )                    retval = Digits2RawV0(digitsManager); 
145   else if ( fRawVersion > 0 && fRawVersion <= 2 ) retval = Digits2RawVx(digitsManager); 
146   else {
147     retval = kFALSE;
148     AliWarning(Form("Unsupported raw version (fRawVersion=%d).",fRawVersion));
149   }
150
151   // Cleanup
152   delete fGeo;
153   delete digitsManager;
154
155   return retval;
156
157 }
158
159 //_____________________________________________________________________________
160 Bool_t AliTRDrawData::Digits2RawV0(AliTRDdigitsManager* digitsManager)
161 {
162   //
163   // Bogdan's raw simulator (offline use only)
164   //
165   // Convert the digits to raw data byte stream. The output is written
166   // into the the binary files TRD_<DDL number>.ddl.
167   //
168   // The pseudo raw data format is currently defined like this:
169   //
170   //          DDL data header
171   //
172   //          Subevent (= single chamber) header (8 bytes)
173   //                  FLAG
174   //                  Detector number (2 bytes)
175   //                  Number of data bytes (2 bytes)
176   //                  Number of pads with data (2 bytes)
177   //                  1 empty byte
178   //
179   //          Data bank
180   //
181
182   const Int_t kSubeventHeaderLength = 8;
183   const Int_t kSubeventDummyFlag    = 0xBB;
184   Int_t       headerSubevent[3];
185
186   ofstream     **outputFile = new ofstream* [fNumberOfDDLs];
187   UInt_t        *bHPosition = new UInt_t    [fNumberOfDDLs];
188   Int_t         *ntotalbyte = new Int_t     [fNumberOfDDLs];
189   Int_t          nbyte = 0;
190   Int_t          npads = 0;
191   unsigned char *bytePtr;
192   unsigned char *headerPtr;
193
194   AliTRDdataArrayI *digits;
195   AliRawDataHeader  header;   // The event header
196
197   // Open the output files
198   for (Int_t iDDL = 0; iDDL < fNumberOfDDLs; iDDL++) {
199
200     char name[20];
201     sprintf(name, "TRD_%d.ddl", iDDL + AliTRDRawStream::kDDLOffset);
202 #ifndef __DECCXX
203     outputFile[iDDL] = new ofstream(name, ios::binary);
204 #else
205     outputFile[iDDL] = new ofstream(name);
206 #endif
207
208     // Write a dummy data header
209     bHPosition[iDDL] = outputFile[iDDL]->tellp();
210     outputFile[iDDL]->write((char *) (& header),sizeof(header));
211     ntotalbyte[iDDL] = 0;
212
213   }
214
215   // Loop through all detectors
216   for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
217
218     Int_t cham      = fGeo->GetChamber(det);
219     Int_t plan      = fGeo->GetPlane(det);
220     Int_t sect      = fGeo->GetSector(det);
221     Int_t rowMax    = fCommonParam->GetRowMax(plan,cham,sect);
222     Int_t colMax    = fCommonParam->GetColMax(plan);
223     Int_t timeTotal = fCalibration->GetNumberOfTimeBins();
224     Int_t bufferMax = rowMax * colMax * timeTotal;
225     Int_t *buffer   = new Int_t[bufferMax];
226
227     npads   = 0;
228     nbyte   = 0;
229     bytePtr = (unsigned char *) buffer;
230
231     Int_t iDDL = sect;
232
233     // Get the digits array
234     digits = digitsManager->GetDigits(det);
235     digits->Expand();
236     // This is to take care of switched off super modules
237     if (digits->GetNtime() == 0) {
238       continue;
239     }
240
241     // Loop through the detector pixel
242     for (Int_t col = 0; col < colMax; col++) {
243       for (Int_t row = 0; row < rowMax; row++) {
244
245         // Check whether data exists for this pad
246         Bool_t dataflag = kFALSE;
247         for (Int_t time = 0; time < timeTotal; time++) {
248           Int_t data = digits->GetDataUnchecked(row,col,time);
249           if (data) {
250             dataflag = kTRUE;
251             break;
252           }
253         }
254
255         if (dataflag) {
256
257           npads++;
258
259           // The pad row number
260           *bytePtr++ = row + 1;
261           // The pad column number
262           *bytePtr++ = col + 1;
263           nbyte += 2;
264
265           Int_t nzero = 0;
266           for (Int_t time = 0; time < timeTotal; time++) {
267
268             Int_t data = digits->GetDataUnchecked(row,col,time);
269
270             if (!data) {
271               nzero++;
272               if ((nzero ==       256) || 
273                   (time  == timeTotal-1)) {
274                 *bytePtr++ = 0;
275                 *bytePtr++ = nzero-1;
276                 nbyte += 2;
277                 nzero  = 0;
278               }
279             }
280             else {
281               if (nzero) {
282                 *bytePtr++ = 0;
283                 *bytePtr++ = nzero-1;
284                 nbyte += 2;
285                 nzero  = 0;
286               }
287               // High byte (MSB always set)
288               *bytePtr++ = ((data >> 8) | 128);
289               // Low byte
290               *bytePtr++ = (data & 0xff);
291               nbyte += 2;
292             }
293
294           }
295
296         }
297
298       }
299
300     }
301
302     // Fill the end of the buffer with zeros
303     while (nbyte % 4) {  
304       *bytePtr++ = 0;
305       nbyte++;
306     }
307
308     AliDebug(1,Form("det = %d, nbyte = %d (%d)",det,nbyte,bufferMax));
309
310     // Write the subevent header
311     bytePtr    = (unsigned char *) headerSubevent;
312     headerPtr  = bytePtr;
313     *bytePtr++ = kSubeventDummyFlag;
314     *bytePtr++ = (det   & 0xff);
315     *bytePtr++ = (det   >> 8);
316     *bytePtr++ = (nbyte & 0xff);
317     *bytePtr++ = (nbyte >> 8);
318     *bytePtr++ = (nbyte >> 16);
319     *bytePtr++ = (npads & 0xff);
320     *bytePtr++ = (npads >> 8);
321     outputFile[iDDL]->write((char *) headerPtr,kSubeventHeaderLength);
322
323     // Write the buffer to the file
324     bytePtr = (unsigned char *) buffer;
325     outputFile[iDDL]->write((char *) bytePtr,nbyte);
326
327     ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength;
328
329     delete buffer;
330
331   }
332
333   // Update the data headers and close the output files
334   for (Int_t iDDL = 0; iDDL < fNumberOfDDLs; iDDL++) {
335
336     header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL];
337     header.SetAttribute(0);  // valid data
338     outputFile[iDDL]->seekp(bHPosition[iDDL]);
339     outputFile[iDDL]->write((char *) (&header),sizeof(header));
340
341     outputFile[iDDL]->close();
342     delete outputFile[iDDL];
343
344   }
345
346   delete [] outputFile;
347   delete [] bHPosition;
348   delete [] ntotalbyte;
349
350   return kTRUE;
351 }
352
353 //_____________________________________________________________________________
354 Bool_t AliTRDrawData::Digits2RawVx(AliTRDdigitsManager *digitsManager)
355 {
356   //
357   // Raw data simulator for all versions > 0. This is prepared for real data.
358   // This version simulate only raw data with ADC data and not with tracklet.
359   //
360
361   const Int_t kMaxHcWords = (fGeo->TBmax()/3)*fGeo->ADCmax()*fGeo->MCMmax()*fGeo->ROBmaxC1()/2 + 100 + 20;
362
363   // Buffer to temporary store half chamber data
364   UInt_t     *hc_buffer   = new UInt_t[kMaxHcWords];
365
366   // sect is same as iDDL, so I use only sect here.
367   for (Int_t sect = 0; sect < fGeo->Nsect(); sect++) { 
368
369     char name[1024];
370     sprintf(name,"TRD_%d.ddl",sect + AliTRDRawStream::kDDLOffset);
371
372 #ifndef __DECCXX
373     ofstream *of = new ofstream(name, ios::binary);
374 #else
375     ofstream *of = new ofstream(name);
376 #endif
377
378     // Write a dummy data header
379     AliRawDataHeader  header;  // the event header
380     UInt_t hpos = of->tellp();
381     of->write((char *) (& header), sizeof(header));
382
383     // Reset payload byte size (payload does not include header).
384     Int_t npayloadbyte = 0;
385
386     // GTU common data header (5x4 bytes per super module, shows link mask)
387     for( Int_t cham = 0; cham < fGeo->Ncham(); cham++ ) {
388       UInt_t GtuCdh = (0xe << 28);
389       for( Int_t plan = 0; plan < fGeo->Nplan(); plan++) {
390         Int_t iDet = fGeo->GetDetector(plan, cham, sect);
391         // If chamber status is ok, we assume that the optical link is also OK.
392         // This is shown in the GTU link mask.
393         if ( fCalibration->GetChamberStatus(iDet) )
394           GtuCdh = GtuCdh | (3 << (2*plan));
395       }
396       of->write((char *) (& GtuCdh), sizeof(GtuCdh));
397       npayloadbyte += 4;
398     }
399
400     // Prepare chamber data
401     for( Int_t cham = 0; cham < fGeo->Ncham(); cham++) {
402       for( Int_t plan = 0; plan < fGeo->Nplan(); plan++) {
403
404         Int_t iDet = fGeo->GetDetector(plan,cham,sect);
405
406         // Get the digits array
407         AliTRDdataArrayI *digits = digitsManager->GetDigits(iDet);
408         digits->Expand();
409
410         Int_t hcwords = 0;
411
412         // Process A side of the chamber
413         if ( fRawVersion >= 1 && fRawVersion <= 2 ) hcwords = ProduceHcDataV1andV2(digits,0,iDet,hc_buffer,kMaxHcWords);
414         of->write((char *) hc_buffer, hcwords*4);
415         npayloadbyte += hcwords*4;
416
417         // Process B side of the chamber
418         if ( fRawVersion >= 1 && fRawVersion <= 2 ) hcwords = ProduceHcDataV1andV2(digits,1,iDet,hc_buffer,kMaxHcWords);
419         of->write((char *) hc_buffer, hcwords*4);
420         npayloadbyte += hcwords*4;
421
422       }
423     }
424
425     // Complete header
426     header.fSize = UInt_t(of->tellp()) - hpos;
427     header.SetAttribute(0);  // Valid data
428     of->seekp(hpos);         // Rewind to header position
429     of->write((char *) (& header), sizeof(header));
430     of->close();
431     delete of;
432
433   }
434
435   delete hc_buffer;
436   return kTRUE;
437
438 }
439
440 //_____________________________________________________________________________
441 Int_t AliTRDrawData::ProduceHcDataV1andV2(AliTRDdataArrayI *digits, Int_t side
442                                         , Int_t det, UInt_t *buf, Int_t maxSize)
443 {
444   //
445   // This function simulates: 1) SM-I commissiong data Oct. 06 (fRawVersion == 1).
446   //                          2) Full Raw Production Version   (fRawVersion == 2)
447   //
448   // Produce half chamber data (= an ORI data) for the given chamber (det) and side (side)
449   // where
450   //
451   //   side=0 means A side with ROB positions 0, 2, 4, 6.
452   //   side=1 means B side with ROB positions 1, 3, 5, 7.
453   //
454   // Chamber type (C0 orC1) is determined by "det" automatically.
455   // Appropriate size of buffer (*buf) must be prepared prior to calling this function.
456   // Pointer to the buffer and its size must be given to "buf" and "maxSize".
457   // Return value is the number of valid data filled in the buffer in unit of 32 bits
458   // UInt_t words.
459   // If buffer size if too small, the data is truncated with the buffer size however
460   // the function will finish without crash (this behaviour is similar to the MCM).
461   //
462
463   Int_t          nw = 0;                       // Number of written    words
464   Int_t          of = 0;                       // Number of overflowed words
465   Int_t        plan = fGeo->GetPlane( det );   // Plane
466   Int_t        cham = fGeo->GetChamber( det ); // Chamber
467   Int_t        sect = fGeo->GetSector( det );  // Sector (=iDDL)
468   Int_t        nRow = fCommonParam->GetRowMax( plan, cham, sect );
469   Int_t        nCol = fCommonParam->GetColMax( plan );
470   const Int_t nTBin = fCalibration->GetNumberOfTimeBins();
471   Int_t      kCtype = 0;                       // Chamber type (0:C0, 1:C1)
472   Int_t         iEv = 0xA;                     // Event ID. Now fixed to 10, how do I get event id?
473   UInt_t          x = 0;                       // General used number
474
475   // Check the nCol and nRow.
476   if ((nCol == 144) && 
477       (nRow == 16 || nRow == 12)) {
478     kCtype = (nRow-12) / 4;
479   } 
480   else {
481     AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)."
482                  ,nRow,nCol));
483     return 0;
484   }
485
486   AliDebug(1,Form("Producing raw data for sect=%d plan=%d cham=%d side=%d"
487                  ,sect,plan,cham,side));
488
489   // Tracklet should be processed here but not implemented yet
490
491   // Write end of tracklet marker
492   if (nw < maxSize) {
493     buf[nw++] = endoftrackletmarker;
494   } 
495   else {
496     of++;
497   }
498
499   // Half Chamber header
500   if      ( fRawVersion == 1 ) {
501     // Now it is the same version as used in SM-I commissioning.
502     Int_t  dcs = det+100;      // DCS Serial (in simulation, it is meaningless
503     x = (dcs<<20) | (sect<<15) | (plan<<12) | (cham<<9) | (side<<8) | 1;
504     if (nw < maxSize) {
505       buf[nw++] = x; 
506     }
507     else {
508       of++;
509     }
510   } 
511   else if ( fRawVersion == 2 ) {
512     // h[0] (there are 2 HC header)
513     Int_t minorv = 0;      // The minor version number
514     Int_t add    = 1;      // The number of additional header words to follow
515     x = (1<<31) | (fRawVersion<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (plan<<6) | (cham<<3) | (side<<2) | 1;
516     if (nw < maxSize) {
517       buf[nw++] = x; 
518     }
519     else {
520       of++;
521     }
522     // h[1]
523     Int_t bc_ctr   = 99; // bunch crossing counter. Here it is set to 99 always for no reason
524     Int_t pt_ctr   = 15; // pretrigger counter. Here it is set to 15 always for no reason
525     Int_t pt_phase = 11; // pretrigger phase. Here it is set to 11 always for no reason
526     x = (bc_ctr<<16) | (pt_ctr<<12) | (pt_phase<<8) | ((nTBin-1)<<2) | 1;
527     if (nw < maxSize) {
528       buf[nw++] = x; 
529     }
530     else {
531       of++;
532     }
533   }
534
535   // Scan for ROB and MCM
536   for (Int_t iRobRow = 0; iRobRow < (kCtype + 3); iRobRow++ ) {
537     Int_t iRob = iRobRow * 2 + side;
538     for (Int_t iMcm = 0; iMcm < fGeo->MCMmax(); iMcm++ ) {
539       Int_t padrow = iRobRow * 4 + iMcm / 4;
540
541       // MCM header
542       x = ((iRob * fGeo->MCMmax() + iMcm) << 24) | ((iEv % 0x100000) << 4) | 0xC;
543       if (nw < maxSize) {
544         buf[nw++] = x; 
545       }
546       else {
547         of++;
548       }
549
550       // ADC data
551       for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) {
552         Int_t padcol = fGeo->GetPadCol(iRob, iMcm, iAdc);
553         UInt_t aa = !(iAdc & 1) + 2;
554         UInt_t *a = new UInt_t[nTBin+2];
555         // 3 timebins are packed into one 32 bits word
556         for (Int_t iT = 0; iT < nTBin; iT+=3) { 
557           if ((padcol >=    0) && (padcol <  nCol)) {
558             a[iT  ] = ((iT    ) < nTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT    ) : 0;
559             a[iT+1] = ((iT + 1) < nTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 1) : 0;
560             a[iT+2] = ((iT + 2) < nTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 2) : 0; 
561           } 
562           else {
563             a[iT] = a[iT+1] = a[iT+2] = 0; // This happenes at the edge of chamber (should be pedestal! How?)
564           }
565           x = (a[iT+2] << 22) | (a[iT+1] << 12) | (a[iT] << 2) | aa;
566           if (nw < maxSize) {
567             buf[nw++] = x; 
568           }
569           else {
570             of++;
571           }
572         }
573         // Diagnostics
574         Float_t avg = 0;
575         Float_t rms = 0;
576         for (Int_t iT = 0; iT < nTBin; iT++) {
577           avg += (Float_t) (a[iT]);
578         }
579         avg /= (Float_t) nTBin;
580         for (Int_t iT = 0; iT < nTBin; iT++) {
581           rms += ((Float_t) (a[iT]) - avg) * ((Float_t) (a[iT]) - avg);
582         }
583         rms = TMath::Sqrt(rms / (Float_t) nTBin);
584         if (rms > 1.7) {
585           AliDebug(2,Form("Large RMS (>1.7)  (ROB,MCM,ADC)=(%02d,%02d,%02d), avg=%03.1f, rms=%03.1f"
586                           ,iRob,iMcm,iAdc,avg,rms));
587         }
588         delete a;
589       }
590     }
591   }
592
593   // Write end of raw data marker
594   if (nw < maxSize) {
595     buf[nw++] = endofeventmarker; 
596   }
597   else {
598     of++;
599   }
600   if (of != 0) {
601     AliWarning("Buffer overflow. Data is truncated. Please increase buffer size and recompile.");
602   }
603
604   return nw;
605
606 }
607
608 //_____________________________________________________________________________
609 AliTRDdigitsManager *AliTRDrawData::Raw2Digits(AliRawReader *rawReader)
610 {
611   //
612   // Read raw data and convert to digits
613   //
614
615   if ( fRawVersion == 0 ) {
616     return Raw2DigitsV0(rawReader);  // fRawVersion == 0
617   }
618   else {
619     return Raw2DigitsVx(rawReader);  // fRawVersion > 0
620   }
621
622 }
623
624 //_____________________________________________________________________________
625 AliTRDdigitsManager *AliTRDrawData::Raw2DigitsV0(AliRawReader *rawReader)
626 {
627   //
628   // Bogdan's raw data reader (for offline only).
629   //
630
631   AliTRDdataArrayI *digits = 0;
632   AliTRDdataArrayI *track0 = 0;
633   AliTRDdataArrayI *track1 = 0;
634   AliTRDdataArrayI *track2 = 0; 
635
636   AliTRDgeometry *geo = new AliTRDgeometry();
637
638   AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
639   if (!commonParam) {
640     AliError("Could not get common parameters");
641     return 0;
642   }
643
644   AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
645   if (!calibration) {
646     AliError("Could not get calibration object");
647     return 0;
648   }
649
650   // Create the digits manager
651   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
652   digitsManager->CreateArrays();
653
654   AliTRDRawStream input(rawReader);
655
656   // Loop through the digits
657   while (input.Next()) {
658
659     Int_t det    = input.GetDetector();
660     Int_t npads  = input.GetNPads();
661
662     if (input.IsNewDetector()) {
663
664       if (digits) digits->Compress(1,0);
665       if (track0) track0->Compress(1,0);
666       if (track1) track1->Compress(1,0);
667       if (track2) track2->Compress(1,0);
668
669       AliDebug(2,"Subevent header:");
670       AliDebug(2,Form("\tdet   = %d",det));
671       AliDebug(2,Form("\tnpads = %d",npads));
672
673       // Create the data buffer
674       Int_t cham      = geo->GetChamber(det);
675       Int_t plan      = geo->GetPlane(det);
676       Int_t sect      = geo->GetSector(det);
677       Int_t rowMax    = commonParam->GetRowMax(plan,cham,sect);
678       Int_t colMax    = commonParam->GetColMax(plan);
679       Int_t timeTotal = calibration->GetNumberOfTimeBins();
680
681       // Add a container for the digits of this detector
682       digits = digitsManager->GetDigits(det);
683       track0 = digitsManager->GetDictionary(det,0);
684       track1 = digitsManager->GetDictionary(det,1);
685       track2 = digitsManager->GetDictionary(det,2);
686       // Allocate memory space for the digits buffer
687       if (digits->GetNtime() == 0) {
688         digits->Allocate(rowMax,colMax,timeTotal);
689         track0->Allocate(rowMax,colMax,timeTotal);
690         track1->Allocate(rowMax,colMax,timeTotal);
691         track2->Allocate(rowMax,colMax,timeTotal);
692       }
693
694     }
695
696     digits->SetDataUnchecked(input.GetRow(),input.GetColumn(),
697                              input.GetTime(),input.GetSignal());
698     track0->SetDataUnchecked(input.GetRow(),input.GetColumn(),
699                              input.GetTime(),                0);
700     track1->SetDataUnchecked(input.GetRow(),input.GetColumn(),
701                              input.GetTime(),                0);
702     track2->SetDataUnchecked(input.GetRow(),input.GetColumn(),
703                              input.GetTime(),                0);
704
705   }
706
707   if (digits) digits->Compress(1,0);
708   if (track0) track0->Compress(1,0);
709   if (track1) track1->Compress(1,0);
710   if (track2) track2->Compress(1,0);
711
712   delete geo;
713
714   return digitsManager;
715
716 }
717
718 //_____________________________________________________________________________
719 AliTRDdigitsManager *AliTRDrawData::Raw2DigitsVx(AliRawReader *rawReader)
720 {
721
722   //
723   // This is executed for all Raw Data Versions > 0. Raw data is read and filled
724   // into digits array. Next function is not used.
725   //
726
727   AliTRDdataArrayI  *digits      = 0;
728
729   AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
730   if (!commonParam) {
731     AliError("Could not get common params");
732     return 0;
733   }
734
735   AliTRDcalibDB     *calibration = AliTRDcalibDB::Instance();
736   if (!calibration) {
737     AliError("Could not get calibration object");
738     return 0;
739   }
740
741   // Create the digits manager
742   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
743   digitsManager->CreateArrays();
744
745   AliTRDRawStream input(rawReader, digitsManager, digits);
746   input.SetRawVersion( fRawVersion );
747   input.ReadAll();     // Loop through the digits
748
749   delete digits;
750
751   return digitsManager;
752
753 }