]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDrawData.cxx
Remove AliTRDRawStreamV2
[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 "AliTRDarrayDictionary.h"
37 #include "AliTRDarrayADC.h"
38 #include "AliTRDrawStreamBase.h"
39 #include "AliTRDrawOldStream.h"
40 #include "AliTRDcalibDB.h"
41 #include "AliTRDSignalIndex.h"
42 #include "AliTRDfeeParam.h"
43 #include "AliTRDmcmSim.h"
44
45 ClassImp(AliTRDrawData)
46
47 Int_t AliTRDrawData::fgRawFormatVersion = AliTRDrawData::kRawNewFormat;
48 Int_t AliTRDrawData::fgDataSuppressionLevel = 1;
49
50 //_____________________________________________________________________________
51 AliTRDrawData::AliTRDrawData()
52   :TObject()
53   ,fGeo(NULL)
54   ,fFee(NULL)
55   ,fNumberOfDDLs(0)
56   ,fSMindexPos(0)
57   ,fStackindexPos(0)
58   ,fEventCounter(0)
59 {
60   //
61   // Default constructor
62   //
63
64   fFee = AliTRDfeeParam::Instance();
65   fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
66
67 }
68
69 //_____________________________________________________________________________
70 AliTRDrawData::AliTRDrawData(const AliTRDrawData &r)
71   :TObject(r)
72   ,fGeo(NULL)
73   ,fFee(NULL)
74   ,fNumberOfDDLs(0)
75   ,fSMindexPos(0)
76   ,fStackindexPos(0)
77   ,fEventCounter(0)
78 {
79   //
80   // Copy constructor
81   //
82
83   fFee = AliTRDfeeParam::Instance();
84   fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
85
86 }
87
88 //_____________________________________________________________________________
89 AliTRDrawData::~AliTRDrawData()
90 {
91   //
92   // Destructor
93   //
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   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
109
110   if (!digitsManager->ReadDigits(digitsTree)) {
111     delete digitsManager;
112     return kFALSE;
113   }
114
115   if (tracks != NULL) {
116     delete digitsManager;
117     AliError("Tracklet input is not supported yet.");
118     return kFALSE;
119   }
120
121   fGeo = new AliTRDgeometry();
122
123   if (!AliTRDcalibDB::Instance()) {
124     AliError("Could not get calibration object");
125     delete fGeo;
126     delete digitsManager;
127     return kFALSE;
128   }
129
130   Int_t retval = kTRUE;
131   Int_t rv     = fFee->GetRAWversion();
132
133   // Call appropriate Raw Simulator
134   if ( rv > 0 && rv <= 3 ) retval = Digits2Raw(digitsManager); 
135   else {
136     retval = kFALSE;
137     AliWarning(Form("Unsupported raw version (%d).", rv));
138   }
139
140   // Cleanup
141   delete fGeo;
142   delete digitsManager;
143
144   return retval;
145
146 }
147
148 //_____________________________________________________________________________
149 Bool_t AliTRDrawData::Digits2Raw(AliTRDdigitsManager *digitsManager)
150 {
151   //
152   // Raw data simulator for all versions > 0. This is prepared for real data.
153   // This version simulate only raw data with ADC data and not with tracklet.
154   //
155
156   const Int_t kMaxHcWords = (fGeo->TBmax()/3)
157                           * fGeo->ADCmax()
158                           * fGeo->MCMmax()
159                           * fGeo->ROBmaxC1()/2 
160                           + 100 + 20;
161
162   // Buffer to temporary store half chamber data
163   UInt_t     *hcBuffer    = new UInt_t[kMaxHcWords];
164   
165   Bool_t newEvent = kFALSE;  // only for correct readout tree
166   Bool_t newSM    = kFALSE;  // new SM flag, for writing SM index words
167   Bool_t newStack = kFALSE;  // new stack flag, for writing stack index words
168
169   // sect is same as iDDL, so I use only sect here.
170   for (Int_t sect = 0; sect < fGeo->Nsector(); sect++) { 
171
172     char name[1024];
173     sprintf(name,"TRD_%d.ddl",sect + AliTRDrawOldStream::kDDLOffset);
174
175     AliFstream* of = new AliFstream(name);
176
177             // Write a dummy data header
178     AliRawDataHeaderSim  header;  // the event header
179     UInt_t hpos = of->Tellp();
180     of->WriteBuffer((char *) (& header), sizeof(header));
181
182     // Reset payload byte size (payload does not include header).
183     Int_t npayloadbyte = 0;
184
185
186     if ( fgRawFormatVersion == 0 ){
187     // GTU common data header (5x4 bytes per super module, shows link mask)
188     for( Int_t stack = 0; stack < fGeo->Nstack(); stack++ ) {
189       UInt_t gtuCdh = (UInt_t)(0xe << 28);
190       for( Int_t layer = 0; layer < fGeo->Nlayer(); layer++) {
191     Int_t iDet = fGeo->GetDetector(layer, stack, sect);
192
193     // If chamber status is ok, we assume that the optical link is also OK.
194         // This is shown in the GTU link mask.
195     if ( AliTRDcalibDB::Instance()->GetChamberStatus(iDet) )
196       gtuCdh = gtuCdh | (3 << (2*layer));
197       }
198       of->WriteBuffer((char *) (& gtuCdh), sizeof(gtuCdh));
199       npayloadbyte += 4;
200     }
201     }
202
203
204     // check the existance of the data
205     // SM index word and Stack index word
206    if ( fgRawFormatVersion == 1 ){
207     UInt_t *iwbuffer = new UInt_t[42]; // index word buffer; max 42 = 2 SM headers + 5*8 stack headers
208     Int_t nheader = 0;
209     UInt_t StackMask = 0x0;
210     Bool_t StackHasData = kFALSE;
211     Bool_t SMHasData = kFALSE;
212     iwbuffer[nheader++] = 0x0001a020;   // SM index words 
213     iwbuffer[nheader++] = 0x10404071;   // SM header
214
215     for ( Int_t stack= 0; stack < fGeo->Nstack(); stack++) {
216         UInt_t LinkMask = 0x0;
217         for( Int_t layer = 0; layer < fGeo->Nlayer(); layer++) {
218             Int_t iDet = fGeo->GetDetector(layer,stack,sect);
219                         AliTRDarrayADC *digits = (AliTRDarrayADC *) digitsManager->GetDigits(iDet);
220             if ( digits->HasData() ) {
221                 StackMask = StackMask | ( 1 << stack ); // active stack mask for new stack
222                 LinkMask = LinkMask | ( 3 << (2*layer) );    // 3 = 0011
223                 StackHasData = kTRUE;
224                 SMHasData = kTRUE;
225             } // has data
226         } // loop over layer
227
228         if ( fgDataSuppressionLevel==0 || StackHasData ){
229         //if ( StackHasData ){
230             iwbuffer[nheader++] = 0x0007a000 | LinkMask;    // stack index word + link masks
231             //if (fgDataSuppressionLevel==0) iwbuffer[nheader-1] = 0x0007afff;  // no suppression
232             iwbuffer[nheader++] = 0x04045b01;               // stack header
233             for (Int_t i=0;i<6;i++) iwbuffer[nheader++] = 0x00000000; // 6 dummy words
234             StackHasData = kFALSE;
235         }
236     } // loop over stack
237
238     if ( fgDataSuppressionLevel==0 || SMHasData ){
239         iwbuffer[0] = iwbuffer[0] | StackMask;  // add stack masks to SM index word
240         if (fgDataSuppressionLevel==0) iwbuffer[0] = 0x0001a03f;    // no suppression
241         of->WriteBuffer((char *) iwbuffer, nheader*4);
242         AliDebug(11, Form("SM %d index word: %08x", iwbuffer[0]));
243         AliDebug(11, Form("SM %d header: %08x", iwbuffer[1]));
244     }
245    }
246     // end of SM & stack header ------------------------------------------------------------------------
247     // -------------------------------------------------------------------------------------------------
248
249     // Prepare chamber data
250     for( Int_t stack = 0; stack < fGeo->Nstack(); stack++) {
251       for( Int_t layer = 0; layer < fGeo->Nlayer(); layer++) {
252
253         Int_t iDet = fGeo->GetDetector(layer,stack,sect);
254         if (iDet == 0){
255             newEvent = kTRUE; // it is expected that each event has at least one tracklet; 
256                                          // this is only needed for correct readout tree
257             fEventCounter++;
258             AliDebug(11, Form("New event!! Event counter: %d",fEventCounter));
259         }
260
261         if ( stack==0 && layer==0 ) newSM = kTRUE;  // new SM flag
262         if ( layer==0 ) newStack = kTRUE;           // new stack flag
263         AliDebug(15, Form("stack : %d, layer : %d, iDec : %d\n",stack,layer,iDet));
264         // Get the digits array
265                 AliTRDarrayADC *digits = (AliTRDarrayADC *) digitsManager->GetDigits(iDet);
266         if (fgDataSuppressionLevel==0 || digits->HasData() ) {  // second part is new!! and is for indicating a new event
267
268                 if (digits->HasData()) digits->Expand();
269
270                         Int_t hcwords = 0;
271                         Int_t rv = fFee->GetRAWversion();
272
273
274         if ( fgRawFormatVersion == 0 ){
275       // Process A side of the chamber
276           if ( rv >= 1 && rv <= 2 ) {
277             hcwords = ProduceHcDataV1andV2(digits,0,iDet,hcBuffer,kMaxHcWords);
278           }
279           if ( rv == 3 ) { 
280    
281               hcwords = ProduceHcDataV3     (digits,0,iDet,hcBuffer,kMaxHcWords,newEvent);
282               //hcwords = ProduceHcDataV3     (digits,0,iDet,hcBuffer,kMaxHcWords);
283             if(newEvent == kTRUE) newEvent = kFALSE;
284           }
285
286           of->WriteBuffer((char *) hcBuffer, hcwords*4);
287           npayloadbyte += hcwords*4;
288
289       // Process B side of the chamber
290           if ( rv >= 1 && rv <= 2 ) {
291             hcwords = ProduceHcDataV1andV2(digits,1,iDet,hcBuffer,kMaxHcWords);
292           }
293           if ( rv >= 3 ) {
294            
295               hcwords = ProduceHcDataV3     (digits,1,iDet,hcBuffer,kMaxHcWords,newEvent);
296               //hcwords = ProduceHcDataV3     (digits,1,iDet,hcBuffer,kMaxHcWords);
297           }
298
299           of->WriteBuffer((char *) hcBuffer, hcwords*4);
300           npayloadbyte += hcwords*4;
301
302     } else { // real data format
303
304        if (digits->HasData()){
305         // Process A side of the chamber
306         hcwords = ProduceHcData(digits,0,iDet,hcBuffer,kMaxHcWords,newEvent,newSM);
307         //if ( newStack ){
308         //  AssignStackMask(hcBuffer, stack);   // active stack mask for this stack
309         //  hcwords += AddStackIndexWords(hcBuffer, stack, hcwords);
310         //  newStack = kFALSE;
311         //}
312         //if ( newSM ) newSM = kFALSE;
313         if ( newEvent ) newEvent = kFALSE;
314         //AssignLinkMask(hcBuffer, layer);  // active link mask for this layer(2*HC)
315         of->WriteBuffer((char *) hcBuffer, hcwords*4);
316         npayloadbyte += hcwords*4;
317         //for ( Int_t i=0; i<hcwords; i++ ) AliInfo(Form("Buf : %X",hcBuffer[i]));
318
319         // Process B side of the chamber
320         hcwords = ProduceHcData(digits,1,iDet,hcBuffer,kMaxHcWords,newEvent,newSM);
321         of->WriteBuffer((char *) hcBuffer, hcwords*4);
322         npayloadbyte += hcwords*4;
323        } else {
324         hcBuffer[hcwords++] = fgkEndOfTrackletMarker;
325         hcBuffer[hcwords++] = fgkEndOfTrackletMarker;
326         hcBuffer[hcwords++] = (1<<31) | (0<<24) | (0<<17) | (1<<14) | (sect<<9) | (layer<<6) | (stack<<3) | (0<<2) | 1;
327         hcBuffer[hcwords++] = (24<<26) | (99<<10) | (15<<6) | (11<<2) | 1;
328         hcBuffer[hcwords++] = kEndofrawdatamarker;
329         hcBuffer[hcwords++] = kEndofrawdatamarker;
330         hcBuffer[hcwords++] = kEndofrawdatamarker;
331         hcBuffer[hcwords++] = kEndofrawdatamarker;
332         npayloadbyte += hcwords*4;
333
334         hcBuffer[hcwords++] = fgkEndOfTrackletMarker;
335         hcBuffer[hcwords++] = fgkEndOfTrackletMarker;
336         hcBuffer[hcwords++] = (1<<31) | (0<<24) | (0<<17) | (1<<14) | (sect<<9) | (layer<<6) | (stack<<3) | (1<<2) | 1;
337         hcBuffer[hcwords++] = (24<<26) | (99<<10) | (15<<6) | (11<<2) | 1;
338         hcBuffer[hcwords++] = kEndofrawdatamarker;
339         hcBuffer[hcwords++] = kEndofrawdatamarker;
340         hcBuffer[hcwords++] = kEndofrawdatamarker;
341         hcBuffer[hcwords++] = kEndofrawdatamarker;
342         npayloadbyte += hcwords*4;
343
344         of->WriteBuffer((char *) hcBuffer, hcwords*4);
345        }
346     }
347
348     } // has data
349
350       } // loop over layer
351     } // loop over stack
352
353     // Complete header
354     header.fSize = UInt_t(of->Tellp()) - hpos;
355     header.SetAttribute(0);  // Valid data
356     of->Seekp(hpos);         // Rewind to header position
357     of->WriteBuffer((char *) (& header), sizeof(header));
358     delete of;
359   }
360
361   delete [] hcBuffer;
362
363   return kTRUE;
364
365 }
366
367 //_____________________________________________________________________________
368 void AliTRDrawData::ProduceSMIndexData(UInt_t *buf, Int_t& nw){
369         // 
370         // This function generates 
371         //       1) SM index words : ssssssss ssssssss vvvv rrrr r d t mmmmm
372         //          - s : size of SM header (number of header, default = 0x0001)
373         //          - v : SM header version (default = 0xa)
374         //          - r : reserved for future use (default = 00000)
375         //          - d : track data enabled bit (default = 0)
376         //          - t : tracklet data enabled bit (default = 1)
377         //          - m : stack mask (each bit corresponds a stack, default = 11111)
378         //
379         //       2) SM header : rrr c vvvv vvvvvvvv vvvv rrrr bbbbbbbb
380         //          - r : reserved for future use (default = 000)
381         //          - c : clean check out flag (default = 1)
382         //          - v : hardware design revision (default = 0x0404)
383         //          - r : reserved for future use (default = 0x0)
384         //          - b : physical board ID (default = 0x71)
385         //
386         //       3) stack index words : ssssssss ssssssss vvvv mmmm mmmmmmmm
387         //          - s : size of stack header (number of header, (default = 0x0007)
388         //          - v : header version (default = 0xa)
389         //          - m : link mask (default = 0xfff)
390         //
391         //       4) stack header : vvvvvvvv vvvvvvvv bbbbbbbb rrrr rrr c
392         //          - v : hardware design revision (default = 0x0404)
393         //          - b : physical board ID (default = 0x5b)
394         //          - r : reserved for future use (default = 0000 000)
395         //          - c : clean checkout flag (default = 1)
396         //      
397         //       and 6 dummy words(0x00000000)
398         //
399         
400     //buf[nw++] = 0x0001a03f;   // SM index words
401     fSMindexPos = nw;       // memorize position of the SM index word for re-allocating stack mask
402     buf[nw++] = 0x0001a020; // SM index words
403     buf[nw++] = 0x10404071; // SM header
404
405     fStackindexPos = nw;    // memorize position of the stack index word for future adding
406         /*  
407     for (Int_t istack=0; istack<5; istack++){
408         buf[nw++] = 0x0007afff; // stack index words
409         buf[nw++] = 0x04045b01; // stack header
410         for (Int_t i=0;i<6;i++) buf[nw++] = 0x00000000; // 6 dummy words
411     } // loop over 5 stacks
412         */
413 }
414
415 //_____________________________________________________________________________
416 void AliTRDrawData::AssignStackMask(UInt_t *buf, Int_t nStack){
417     //
418     // This function re-assign stack mask active(from 0 to 1) in the SM index word
419     //   
420     buf[fSMindexPos] = buf[fSMindexPos] | ( 1 << nStack );
421 }
422
423 //_____________________________________________________________________________  
424 Int_t AliTRDrawData::AddStackIndexWords(UInt_t *buf, Int_t /*nStack*/, Int_t nMax){
425     // 
426     // This function add stack index words and stack header when there is data for the stack
427     //
428     //   1) stack index words : ssssssss ssssssss vvvv mmmm mmmmmmmm 
429     //      - s : size of stack header (number of header, (default = 0x0007)       
430     //      - v : header version (default = 0xa)
431     //      - m : link mask (default = 0xfff)
432     //      - m : link mask (starting value = 0x000)
433     //
434     //   2) stack header : vvvvvvvv vvvvvvvv bbbbbbbb rrrr rrr c
435     //      - v : hardware design revision (default = 0x0404)
436     //      - b : physical board ID (default = 0x5b)
437     //      - r : reserved for future use (default = 0000 000)
438     //      - c : clean checkout flag (default = 1)
439     //  
440     //   and 6 dummy words(0x00000000)
441     //
442
443     Int_t nAddedWords = 0;  // Number of added words
444     if ( ShiftWords(buf, fStackindexPos, 8, nMax)== kFALSE ){
445         AliError("Adding stack header failed.");
446         return 0;
447     }
448
449     buf[fStackindexPos++] = 0x0007a000; // stack index words
450     buf[fStackindexPos++] = 0x04045b01; // stack header
451     for (Int_t i=0;i<6;i++) buf[fStackindexPos++] = 0x00000000; // 6 dummy words 
452     nAddedWords += 8;
453
454     return nAddedWords;
455 }
456
457 //_____________________________________________________________________________
458 void AliTRDrawData::AssignLinkMask(UInt_t *buf, Int_t nLayer){
459     //
460     // This function re-assign link mask active(from 0 to 1) in the stack index word
461     //   
462     buf[fStackindexPos-8] = buf[fStackindexPos-8] | ( 3 << (2*nLayer) );    // 3 = 0011 
463 }
464
465 //_____________________________________________________________________________ 
466 Bool_t AliTRDrawData::ShiftWords(UInt_t *buf, Int_t nStart, Int_t nWords, Int_t nMax){
467     //  
468     // This function shifts n words
469     //
470     //if ( nStart+nWords > sizeof(buf)/sizeof(UInt_t) ){
471     //  AliError("Words shift failed. No more buffer space.");
472     //  return kFALSE;
473     //}
474
475     for ( Int_t iw=nMax; iw>nStart-1; iw--){
476         buf[iw+nWords] = buf[iw];
477     }
478     return kTRUE;
479 }
480
481 //_____________________________________________________________________________
482 Int_t AliTRDrawData::ProduceHcData(AliTRDarrayADC *digits, Int_t side, Int_t det, UInt_t *buf, Int_t maxSize, Bool_t newEvent = kFALSE, Bool_t newSM = kFALSE){
483         //
484         // This function can be used for both ZS and NZS data
485         //
486
487         Int_t           nw = 0;                       // Number of written    words
488         Int_t           of = 0;                       // Number of overflowed words
489         Int_t      *tempnw = 0x0;                     // Number of written    words for temp. buffer
490         Int_t      *tempof = 0x0;                     // Number of overflowed words for temp. buffer
491         Int_t        layer = fGeo->GetLayer( det );   // Layer
492         Int_t        stack = fGeo->GetStack( det );   // Stack
493         Int_t         sect = fGeo->GetSector( det );  // Sector (=iDDL)
494         const Int_t kCtype = fGeo->GetStack(det) == 2 ? 0 : 1;                       // Chamber type (0:C0, 1:C1)
495
496         Bool_t tracklet_on = fFee->GetTracklet();     // tracklet simulation active?
497
498         AliDebug(1,Form("Producing raw data for sect=%d layer=%d stack=%d side=%d",sect,layer,stack,side));
499         
500         AliTRDmcmSim* mcm = new AliTRDmcmSim();
501
502         UInt_t *tempBuffer = buf; // tempBuffer used to write ADC data
503                                   // different in case of tracklet writing
504         
505         if (tracklet_on) {
506           tempBuffer = new UInt_t[maxSize];
507           tempnw = new Int_t(0);
508           tempof = new Int_t(0);
509         }
510         else {
511           tempnw = &nw;
512           tempof = &of;
513         }
514
515         WriteIntermediateWordsV2(tempBuffer,*tempnw,*tempof,maxSize,det,side);  //??? no tracklet or NZS
516
517         // scanning direction such, that tracklet-words are sorted in ascending z and then in ascending y order
518         // ROB numbering on chamber and MCM numbering on ROB increase with decreasing z and increasing y
519         for (Int_t iRobRow = 0; iRobRow <= (kCtype + 3)-1; iRobRow++ ) {        // ROB number should be increasing
520           Int_t iRob = iRobRow * 2 + side;
521           // MCM on one ROB
522           for (Int_t iMcmRB = 0; iMcmRB < fGeo->MCMmax(); iMcmRB++ ) {
523             Int_t iMcm = 16 - 4*(iMcmRB/4 + 1) + (iMcmRB%4);
524             
525             mcm->Init(det, iRob, iMcm);
526             mcm->SetData(digits);     // no filtering done here (already done in digitizer)
527             if (tracklet_on) {
528               mcm->Tracklet();
529               Int_t tempNw = mcm->ProduceTrackletStream(&buf[nw], maxSize - nw);
530               if(  tempNw < 0 ) {
531                 of += tempNw;
532                 nw += maxSize - nw;
533                 AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile."));
534               } else {
535                 nw += tempNw;
536               }
537             }
538             mcm->ZSMapping();  // Calculate zero suppression mapping
539                                // at the moment it has to be rerun here
540             // Write MCM data to temp. buffer
541             Int_t tempNw = mcm->ProduceRawStream( &tempBuffer[*tempnw], maxSize - *tempnw, fEventCounter );
542             if ( tempNw < 0 ) {
543               *tempof += tempNw;
544               *tempnw += maxSize - nw;
545               AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile."));
546             } else {
547               *tempnw += tempNw;
548             }
549           }
550         }
551
552         delete mcm;
553
554
555         // in case of tracklet writing copy temp data to final buffer
556         if (tracklet_on) {
557           if (nw + *tempnw < maxSize) {
558             memcpy(&buf[nw], tempBuffer, *tempnw * sizeof(UInt_t));
559             nw += *tempnw;
560           }
561           else {
562             AliError("Buffer overflow detected");
563           }
564         }
565
566         // Write end of raw data marker
567         if (nw+3 < maxSize) {
568           buf[nw++] = 0x00000000; // fFee->GetRawDataEndmarker(); 
569           buf[nw++] = 0x00000000; // fFee->GetRawDataEndmarker(); 
570           buf[nw++] = 0x00000000; // fFee->GetRawDataEndmarker(); 
571           buf[nw++] = 0x00000000; // fFee->GetRawDataEndmarker(); 
572         } else {
573           of++;
574         }
575         
576         if (tracklet_on) {
577           delete [] tempBuffer;
578           delete tempof;
579           delete tempnw;
580         }
581
582         if (of != 0) {
583           AliError("Buffer overflow. Data is truncated. Please increase buffer size and recompile.");
584         }
585
586         return nw;
587 }
588
589 //_____________________________________________________________________________
590 Int_t AliTRDrawData::ProduceHcDataV1andV2(AliTRDarrayADC *digits, Int_t side
591                                         , Int_t det, UInt_t *buf, Int_t maxSize)
592 {
593   //
594   // This function simulates: 1) SM-I commissiong data Oct. 06 (Raw Version == 1).
595   //                          2) Full Raw Production Version   (Raw Version == 2)
596   //
597   // Produce half chamber data (= an ORI data) for the given chamber (det) and side (side)
598   // where
599   //
600   //   side=0 means A side with ROB positions 0, 2, 4, 6.
601   //   side=1 means B side with ROB positions 1, 3, 5, 7.
602   //
603   // Chamber type (C0 orC1) is determined by "det" automatically.
604   // Appropriate size of buffer (*buf) must be prepared prior to calling this function.
605   // Pointer to the buffer and its size must be given to "buf" and "maxSize".
606   // Return value is the number of valid data filled in the buffer in unit of 32 bits
607   // UInt_t words.
608   // If buffer size if too small, the data is truncated with the buffer size however
609   // the function will finish without crash (this behaviour is similar to the MCM).
610   //
611
612   Int_t           nw = 0;                       // Number of written    words
613   Int_t           of = 0;                       // Number of overflowed words
614   Int_t        layer = fGeo->GetLayer( det );   // Layer
615   Int_t        stack = fGeo->GetStack( det );   // Stack
616   Int_t         sect = fGeo->GetSector( det );  // Sector (=iDDL)
617   Int_t         nRow = fGeo->GetRowMax( layer, stack, sect );
618   Int_t         nCol = fGeo->GetColMax( layer );
619   const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
620   Int_t       kCtype = 0;                       // Chamber type (0:C0, 1:C1)
621   Int_t          iEv = 0xA;                     // Event ID. Now fixed to 10, how do I get event id?
622   UInt_t           x = 0;                       // General used number
623   Int_t           rv = fFee->GetRAWversion();
624
625   // Check the nCol and nRow.
626   if ((nCol == 144) && 
627       (nRow == 16 || nRow == 12)) {
628     kCtype = (nRow-12) / 4;
629   } 
630   else {
631     AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)."
632                  ,nRow,nCol));
633     return 0;
634   }
635
636   AliDebug(1,Form("Producing raw data for sect=%d layer=%d stack=%d side=%d"
637                  ,sect,layer,stack,side));
638
639   // Tracklet should be processed here but not implemented yet
640
641   // Write end of tracklet marker
642   if (nw < maxSize) {
643     buf[nw++] = kEndoftrackletmarker;
644   } 
645   else {
646     of++;
647   }
648
649   // Half Chamber header
650   if      ( rv == 1 ) {
651     // Now it is the same version as used in SM-I commissioning.
652     Int_t  dcs = det+100;      // DCS Serial (in simulation, it is meaningless
653     x = (dcs<<20) | (sect<<15) | (layer<<12) | (stack<<9) | (side<<8) | 1;
654     if (nw < maxSize) {
655       buf[nw++] = x; 
656     }
657     else {
658       of++;
659     }
660   } 
661   else if ( rv == 2 ) {
662     // h[0] (there are 3 HC header)
663     Int_t minorv = 0;      // The minor version number
664     Int_t add    = 2;      // The number of additional header words to follow
665     x = (1<<31) | (rv<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (layer<<6) | (stack<<3) | (side<<2) | 1;
666     if (nw < maxSize) {
667       buf[nw++] = x; 
668     }
669     else {
670       of++;
671     }
672     // h[1]
673     Int_t bcCtr   = 99; // bunch crossing counter. Here it is set to 99 always for no reason
674     Int_t ptCtr   = 15; // pretrigger counter. Here it is set to 15 always for no reason
675     Int_t ptPhase = 11; // pretrigger phase. Here it is set to 11 always for no reason
676     x = (bcCtr<<16) | (ptCtr<<12) | (ptPhase<<8) | ((kNTBin-1)<<2) | 1;
677     if (nw < maxSize) {
678       buf[nw++] = x; 
679     }
680     else {
681       of++;
682     }
683     // h[2]
684     Int_t pedSetup       = 1;    // Pedestal filter setup (0:1). Here it is always 1 for no reason
685     Int_t gainSetup      = 1;    // Gain filter setup (0:1). Here it is always 1 for no reason
686     Int_t tailSetup      = 1;    // Tail filter setup (0:1). Here it is always 1 for no reason
687     Int_t xtSetup        = 0;    // Cross talk filter setup (0:1). Here it is always 0 for no reason
688     Int_t nonlinSetup    = 0;    // Nonlinearity filter setup (0:1). Here it is always 0 for no reason
689     Int_t bypassSetup    = 0;    // Filter bypass (for raw data) setup (0:1). Here it is always 0 for no reason
690     Int_t commonAdditive = 10;   // Digital filter common additive (0:63). Here it is always 10 for no reason
691     x = (pedSetup<<31) | (gainSetup<<30) | (tailSetup<<29) | (xtSetup<<28) | (nonlinSetup<<27)
692       | (bypassSetup<<26) | (commonAdditive<<20) | 1;
693     if (nw < maxSize) {
694       buf[nw++] = x; 
695     }
696     else {
697       of++;
698     }
699   }
700
701   // Scan for ROB and MCM
702   for (Int_t iRobRow = 0; iRobRow < (kCtype + 3); iRobRow++ ) {
703     Int_t iRob = iRobRow * 2 + side;
704     for (Int_t iMcm = 0; iMcm < fGeo->MCMmax(); iMcm++ ) {
705       Int_t padrow = iRobRow * 4 + iMcm / 4;
706
707       // MCM header
708       x = ((iRob * fGeo->MCMmax() + iMcm) << 24) | ((iEv % 0x100000) << 4) | 0xC;
709       if (nw < maxSize) {
710         buf[nw++] = x; 
711       }
712       else {
713         of++;
714       }
715
716       // ADC data
717       for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) {
718         Int_t padcol = fFee->GetPadColFromADC(iRob, iMcm, iAdc);
719         UInt_t aa = !(iAdc & 1) + 2;    // 3 for the even ADC channel , 2 for the odd ADC channel
720         UInt_t *a = new UInt_t[kNTBin+2];
721         // 3 timebins are packed into one 32 bits word
722         for (Int_t iT = 0; iT < kNTBin; iT+=3) { 
723           if ((padcol >=    0) && (padcol <  nCol)) {
724             a[iT  ] = ((iT    ) < kNTBin ) ? digits->GetData(padrow,padcol,iT    ) : 0;
725             a[iT+1] = ((iT + 1) < kNTBin ) ? digits->GetData(padrow,padcol,iT + 1) : 0;
726             a[iT+2] = ((iT + 2) < kNTBin ) ? digits->GetData(padrow,padcol,iT + 2) : 0; 
727           } 
728           else {
729             a[iT] = a[iT+1] = a[iT+2] = 0; // This happenes at the edge of chamber (should be pedestal! How?)
730           }
731           x = (a[iT+2] << 22) | (a[iT+1] << 12) | (a[iT] << 2) | aa;
732           if (nw < maxSize) {
733             buf[nw++] = x; 
734           }
735           else {
736             of++;
737           }
738         }
739         // Diagnostics
740         Float_t avg = 0;
741         Float_t rms = 0;
742         for (Int_t iT = 0; iT < kNTBin; iT++) {
743           avg += (Float_t) (a[iT]);
744         }
745         avg /= (Float_t) kNTBin;
746         for (Int_t iT = 0; iT < kNTBin; iT++) {
747           rms += ((Float_t) (a[iT]) - avg) * ((Float_t) (a[iT]) - avg);
748         }
749         rms = TMath::Sqrt(rms / (Float_t) kNTBin);
750         if (rms > 1.7) {
751           AliDebug(2,Form("Large RMS (>1.7)  (ROB,MCM,ADC)=(%02d,%02d,%02d), avg=%03.1f, rms=%03.1f"
752                           ,iRob,iMcm,iAdc,avg,rms));
753         }
754         delete [] a;
755       }
756     }
757   }
758
759   // Write end of raw data marker
760   if (nw < maxSize) {
761     buf[nw++] = kEndofrawdatamarker; 
762   }
763   else {
764     of++;
765   }
766   if (of != 0) {
767     AliWarning("Buffer overflow. Data is truncated. Please increase buffer size and recompile.");
768   }
769
770   return nw;
771
772 }
773
774 //_____________________________________________________________________________
775
776 //Int_t AliTRDrawData::ProduceHcDataV3(AliTRDarrayADC *digits, Int_t side , Int_t det, UInt_t *buf, Int_t maxSize)
777 Int_t AliTRDrawData::ProduceHcDataV3(AliTRDarrayADC *digits, Int_t side , Int_t det, UInt_t *buf, Int_t maxSize, Bool_t newEvent = kFALSE)
778 {
779   //
780   // This function simulates: Raw Version == 3 (Zero Suppression Prototype)
781   //
782
783   Int_t           nw = 0;                       // Number of written    words
784   Int_t           of = 0;                       // Number of overflowed words
785   Int_t        layer = fGeo->GetLayer( det );   // Layer
786   Int_t        stack = fGeo->GetStack( det );   // Stack
787   Int_t         sect = fGeo->GetSector( det );  // Sector (=iDDL)
788   Int_t         nRow = fGeo->GetRowMax( layer, stack, sect );
789   Int_t         nCol = fGeo->GetColMax( layer );
790   const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
791   Int_t       kCtype = 0;                       // Chamber type (0:C0, 1:C1)
792   //Int_t          iEv = 0xA;                     // Event ID. Now fixed to 10, how do I get event id?
793
794  
795
796   Bool_t tracklet_on = fFee->GetTracklet();     // **new**
797
798   // Check the nCol and nRow.
799   if ((nCol == 144) && 
800       (nRow == 16 || nRow == 12)) {
801     kCtype = (nRow-12) / 4;
802   } 
803   else {
804     AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)."
805                  ,nRow,nCol));
806     return 0;
807   }
808
809   AliDebug(1,Form("Producing raw data for sect=%d layer=%d stack=%d side=%d"
810                  ,sect,layer,stack,side));
811
812   AliTRDmcmSim** mcm = new AliTRDmcmSim*[(kCtype + 3)*(fGeo->MCMmax())];
813
814   // in case no tracklet-words are processed: write the tracklet-endmarker as well as all additional words immediately and write 
815   // raw-data in one go; if tracklet-processing is enabled, first all tracklet-words of a half-chamber have to be processed before the
816   // additional words (tracklet-endmarker,headers,...)are written. Raw-data is written in a second loop;
817   
818   if (!tracklet_on) {
819       WriteIntermediateWords(buf,nw,of,maxSize,det,side); 
820   }
821   
822   // Scan for ROB and MCM
823   // scanning direction such, that tracklet-words are sorted in ascending z and then in ascending y order
824   // ROB numbering on chamber and MCM numbering on ROB increase with decreasing z and increasing y
825   for (Int_t iRobRow =  (kCtype + 3)-1; iRobRow >= 0; iRobRow-- ) {
826     Int_t iRob = iRobRow * 2 + side;
827     // MCM on one ROB
828     for (Int_t iMcmRB = 0; iMcmRB < fGeo->MCMmax(); iMcmRB++ ) {
829         Int_t iMcm = 16 - 4*(iMcmRB/4 + 1) + (iMcmRB%4);
830         Int_t entry = iRobRow*(fGeo->MCMmax()) + iMcm;
831         
832         mcm[entry] = new AliTRDmcmSim();
833         mcm[entry]->Init( det, iRob, iMcm , newEvent);
834         //mcm[entry]->Init( det, iRob, iMcm);
835         if (newEvent == kTRUE) newEvent = kFALSE; // only one mcm is concerned with new event
836         Int_t padrow = mcm[entry]->GetRow();
837
838         // Copy ADC data to MCM simulator
839         for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) {
840             Int_t padcol = mcm[entry]->GetCol( iAdc );
841             if ((padcol >=    0) && (padcol <  nCol)) {
842                 for (Int_t iT = 0; iT < kNTBin; iT++) { 
843                   mcm[entry]->SetData( iAdc, iT, digits->GetData( padrow, padcol, iT) );
844                 } 
845             } 
846             else {  // this means it is out of chamber, and masked ADC
847                 mcm[entry]->SetDataPedestal( iAdc );
848             }
849         }
850
851         // Simulate process in MCM
852         mcm[entry]->Filter();     // Apply filter
853         mcm[entry]->ZSMapping();  // Calculate zero suppression mapping
854 //jkl   mcm[entry]->CopyArrays();
855 //jkl   mcm[entry]->GeneratefZSM1Dim();
856 //jkl   mcm[entry]->RestoreZeros();
857
858         if (tracklet_on) {
859             mcm[entry]->Tracklet(); 
860             Int_t tempNw =  mcm[entry]->ProduceTrackletStream( &buf[nw], maxSize - nw );
861             //Int_t tempNw = 0;
862             if( tempNw < 0 ) {
863                 of += tempNw;
864                 nw += maxSize - nw;
865                 AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile."));
866             } else {
867                 nw += tempNw;
868             }
869         }
870         // no tracklets: write raw-data already in this loop
871         else {
872              // Write MCM data to buffer
873             Int_t tempNw =  mcm[entry]->ProduceRawStream( &buf[nw], maxSize - nw );
874             if( tempNw < 0 ) {
875                 of += tempNw;
876                 nw += maxSize - nw;
877                 AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile."));
878             } else {
879                 nw += tempNw;
880             }
881             
882             delete mcm[entry];
883         }
884             
885         
886
887
888         //mcm->DumpData( "trdmcmdata.txt", "RFZS" ); // debugging purpose
889     }
890   }
891
892   // if tracklets are switched on, raw-data can be written only after all tracklets
893   if (tracklet_on) {
894       WriteIntermediateWords(buf,nw,of,maxSize,det,side); 
895   
896   
897       // Scan for ROB and MCM
898       for (Int_t iRobRow =  (kCtype + 3)-1; iRobRow >= 0; iRobRow-- ) {
899           //Int_t iRob = iRobRow * 2 + side;
900           // MCM on one ROB
901           for (Int_t iMcmRB = 0; iMcmRB < fGeo->MCMmax(); iMcmRB++ ) {
902               Int_t iMcm = 16 - 4*(iMcmRB/4 + 1) + (iMcmRB%4);
903               
904               Int_t entry = iRobRow*(fGeo->MCMmax()) + iMcm; 
905               
906               // Write MCM data to buffer
907               Int_t tempNw =  mcm[entry]->ProduceRawStream( &buf[nw], maxSize - nw );
908               if( tempNw < 0 ) {
909                   of += tempNw;
910                   nw += maxSize - nw;
911                   AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile."));
912               } else {
913                   nw += tempNw;
914               }
915               
916               delete mcm[entry];
917           
918           }
919       }
920   }
921
922   delete [] mcm;
923   
924   // Write end of raw data marker
925   if (nw < maxSize) {
926     buf[nw++] = kEndofrawdatamarker; 
927   }
928   else {
929     of++;
930   }
931   if (of != 0) {
932     AliError("Buffer overflow. Data is truncated. Please increase buffer size and recompile.");
933   }
934
935
936   return nw;
937
938 }
939
940 //_____________________________________________________________________________
941 AliTRDdigitsManager *AliTRDrawData::Raw2Digits(AliRawReader *rawReader)
942 {
943   //
944   // Vx of the raw data reading
945   //
946
947   AliTRDarrayADC *digits = 0;
948   AliTRDarrayDictionary *track0 = 0;
949   AliTRDarrayDictionary *track1 = 0;
950   AliTRDarrayDictionary *track2 = 0;  
951
952   //AliTRDSignalIndex *indexes = 0;
953   // Create the digits manager
954   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
955   digitsManager->CreateArrays();
956
957   AliTRDrawStreamBase *pinput = AliTRDrawStreamBase::GetRawStream(rawReader);
958   AliTRDrawStreamBase &input = *pinput;
959   input.SetRawVersion( fFee->GetRAWversion() ); //<= ADDED by MinJung
960
961   AliInfo(Form("Stream version: %s", input.IsA()->GetName()));
962
963   // Loop through the digits
964   Int_t det    = 0;
965
966   while (det >= 0)
967     {
968       det = input.NextChamber(digitsManager);
969       if (det >= 0)
970         {
971           // get...
972           digits = (AliTRDarrayADC *) digitsManager->GetDigits(det);
973           track0 = (AliTRDarrayDictionary *) digitsManager->GetDictionary(det,0);
974           track1 = (AliTRDarrayDictionary *) digitsManager->GetDictionary(det,1);
975           track2 = (AliTRDarrayDictionary *) digitsManager->GetDictionary(det,2);
976           // and compress
977           if (digits) digits->Compress();  
978           if (track0) track0->Compress();   
979           if (track1) track1->Compress();     
980           if (track2) track2->Compress();
981         }
982     }
983
984   delete pinput;
985   pinput = NULL;
986
987   return digitsManager;
988 }
989
990
991 //_____________________________________________________________________________
992 void AliTRDrawData::WriteIntermediateWords(UInt_t* buf, Int_t& nw, Int_t& of, const Int_t& maxSize, const Int_t& det, const Int_t& side) {
993     
994     Int_t        layer = fGeo->GetLayer( det );   // Layer
995     Int_t        stack = fGeo->GetStack( det );   // Stack
996     Int_t         sect = fGeo->GetSector( det );  // Sector (=iDDL)
997     Int_t           rv = fFee->GetRAWversion();
998     const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
999     UInt_t           x = 0;
1000
1001     // Write end of tracklet marker
1002     if (nw < maxSize) {
1003         buf[nw++] = kEndoftrackletmarker;
1004     } 
1005     else {
1006         of++;
1007     }
1008     
1009   // Half Chamber header
1010   // h[0] (there are 3 HC header)
1011     Int_t minorv = 0;    // The minor version number
1012     Int_t add    = 2;    // The number of additional header words to follow
1013     x = (1<<31) | (rv<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (layer<<6) | (stack<<3) | (side<<2) | 1;
1014     if (nw < maxSize) {
1015         buf[nw++] = x; 
1016     }
1017     else {
1018         of++;
1019     }
1020     // h[1]
1021     Int_t bcCtr   = 99; // bunch crossing counter. Here it is set to 99 always for no reason
1022     Int_t ptCtr   = 15; // pretrigger counter. Here it is set to 15 always for no reason
1023     Int_t ptPhase = 11; // pretrigger phase. Here it is set to 11 always for no reason
1024     x = (bcCtr<<16) | (ptCtr<<12) | (ptPhase<<8) | ((kNTBin-1)<<2) | 1;
1025     if (nw < maxSize) {
1026         buf[nw++] = x; 
1027     }
1028     else {
1029         of++;
1030     }
1031     // h[2]
1032     Int_t pedSetup       = 1;  // Pedestal filter setup (0:1). Here it is always 1 for no reason
1033     Int_t gainSetup      = 1;  // Gain filter setup (0:1). Here it is always 1 for no reason
1034     Int_t tailSetup      = 1;  // Tail filter setup (0:1). Here it is always 1 for no reason
1035     Int_t xtSetup        = 0;  // Cross talk filter setup (0:1). Here it is always 0 for no reason
1036     Int_t nonlinSetup    = 0;  // Nonlinearity filter setup (0:1). Here it is always 0 for no reason
1037     Int_t bypassSetup    = 0;  // Filter bypass (for raw data) setup (0:1). Here it is always 0 for no reason
1038     Int_t commonAdditive = 10; // Digital filter common additive (0:63). Here it is always 10 for no reason
1039     x = (pedSetup<<31) | (gainSetup<<30) | (tailSetup<<29) | (xtSetup<<28) | (nonlinSetup<<27)
1040         | (bypassSetup<<26) | (commonAdditive<<20) | 1;
1041     if (nw < maxSize) {
1042         buf[nw++] = x; 
1043     }
1044     else {
1045         of++;
1046     } 
1047 }
1048
1049 //_____________________________________________________________________________
1050 void AliTRDrawData::WriteIntermediateWordsV2(UInt_t* buf, Int_t& nw, Int_t& of, const Int_t& maxSize, const Int_t& det, const Int_t& side) {
1051     
1052     Int_t        layer = fGeo->GetLayer( det );   // Layer
1053     Int_t        stack = fGeo->GetStack( det );   // Stack
1054     Int_t         sect = fGeo->GetSector( det );  // Sector (=iDDL)
1055     Int_t           rv = fFee->GetRAWversion();
1056     const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
1057         Bool_t tracklet_on = fFee->GetTracklet();
1058     UInt_t           x = 0;
1059
1060     // Write end of tracklet marker
1061         if (nw < maxSize){
1062         buf[nw++] = fgkEndOfTrackletMarker;
1063         buf[nw++] = fgkEndOfTrackletMarker;     // the number of tracklet end marker should be more than 2
1064     }
1065     else {
1066         of++;
1067     }
1068
1069    
1070         // Half Chamber header
1071         // h[0] (there are 2 HC headers) xmmm mmmm nnnn nnnq qqss sssp ppcc ci01
1072         //      , where  x : Raw version speacial number (=1)
1073         //                   m : Raw version major number (test pattern, ZS, disable tracklet, 0, options)
1074         //                   n : Raw version minor number
1075         //                   q : number of addtional header words (default = 1)
1076         //                   s : SM sector number (ALICE numbering)
1077         //                   p : plane(layer) number
1078         //                       c : chamber(stack) number
1079         //                       i : side number (0:A, 1:B)
1080         Int_t majorv = 0;       // The major version number 
1081     Int_t minorv = 0;   // The minor version number
1082     Int_t add    = 1;   // The number of additional header words to follow : now 1, previous 2
1083         Int_t TP         = 0;   // test pattern (default=0)
1084         Int_t ZS         = (rv==3) ? 1 : 0;                     // zero suppression
1085         Int_t DT         = (tracklet_on) ? 0 : 1;       // disable tracklet 
1086
1087         majorv = (TP<<6) | (ZS<<5) | (DT<<4) | 1;       // major version
1088
1089     x = (1<<31) | (majorv<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (layer<<6) | (stack<<3) | (side<<2) | 1;
1090     if (nw < maxSize) buf[nw++] = x; else of++;
1091    
1092     // h[1]             tttt ttbb bbbb bbbb bbbb bbpp pphh hh01
1093         // , where  t : number of time bins
1094         //          b : bunch crossing number
1095         //          p : pretrigger counter
1096         //          h : pretrigger phase
1097     Int_t bcCtr   = 99; // bunch crossing counter. Here it is set to 99 always for no reason
1098     Int_t ptCtr   = 15; // pretrigger counter. Here it is set to 15 always for no reason
1099     Int_t ptPhase = 11; // pretrigger phase. Here it is set to 11 always for no reason
1100     //x = (bcCtr<<16) | (ptCtr<<12) | (ptPhase<<8) | ((kNTBin-1)<<2) | 1;       // old format
1101     x = ((kNTBin)<<26) | (bcCtr<<10) | (ptCtr<<6) | (ptPhase<<2) | 1;
1102     if (nw < maxSize) buf[nw++] = x; else of++;
1103   
1104 }
1105
1106 //_____________________________________________________________________________
1107 AliTRDdigitsManager *AliTRDrawData::Raw2DigitsOLD(AliRawReader *rawReader)
1108 {
1109   //
1110   // Vx of the raw data reading
1111   //
1112
1113   AliTRDarrayADC *digits = 0;
1114   AliTRDarrayDictionary *track0 = 0;
1115   AliTRDarrayDictionary *track1 = 0;
1116   AliTRDarrayDictionary *track2 = 0; 
1117
1118   AliTRDSignalIndex *indexes = 0;
1119   // Create the digits manager
1120   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
1121   digitsManager->CreateArrays();
1122
1123   AliTRDrawOldStream input(rawReader);
1124   input.SetRawVersion( fFee->GetRAWversion() );
1125   input.Init();
1126
1127   AliInfo(Form("Stream version: %s", input.IsA()->GetName()));
1128
1129   // Loop through the digits
1130   Int_t lastdet = -1;
1131   Int_t det    = 0;
1132   Int_t it = 0;
1133   while (input.Next()) {
1134
1135       det    = input.GetDet();
1136
1137       if (det != lastdet) { // If new detector found
1138         
1139           lastdet = det;
1140
1141           if (digits) digits->Compress();
1142           if (track0) track0->Compress();       
1143           if (track1) track1->Compress();       
1144           if (track2) track2->Compress();
1145         
1146           // Add a container for the digits of this detector
1147           digits = (AliTRDarrayADC *) digitsManager->GetDigits(det);
1148           track0 = (AliTRDarrayDictionary *) digitsManager->GetDictionary(det,0);
1149           track1 = (AliTRDarrayDictionary *) digitsManager->GetDictionary(det,1);
1150           track2 = (AliTRDarrayDictionary *) digitsManager->GetDictionary(det,2);
1151
1152           // Allocate memory space for the digits buffer
1153           if (digits->GetNtime() == 0) 
1154             {
1155               digits->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
1156               track0->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
1157               track1->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
1158               track2->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
1159             }
1160
1161           indexes = digitsManager->GetIndexes(det);
1162           indexes->SetSM(input.GetSM());
1163           indexes->SetStack(input.GetStack());
1164           indexes->SetLayer(input.GetLayer());
1165           indexes->SetDetNumber(det);
1166           if (indexes->IsAllocated() == kFALSE)
1167             indexes->Allocate(input.GetMaxRow(), input.GetMaxCol(), input.GetNumberOfTimeBins());
1168         }
1169     
1170       // 3 timebin data are stored per word
1171       for (it = 0; it < 3; it++)
1172         {
1173           if ( input.GetTimeBin() + it < input.GetNumberOfTimeBins() )
1174             {
1175               if (input.GetSignals()[it] > 0)
1176                 {
1177                   digits->SetData(input.GetRow(), input.GetCol(),input.GetTimeBin() + it, input.GetSignals()[it]);
1178
1179                   indexes->AddIndexRC(input.GetRow(), input.GetCol());
1180                   track0->SetData(input.GetRow(), input.GetCol(), input.GetTimeBin() + it, 0);
1181                   track1->SetData(input.GetRow(), input.GetCol(), input.GetTimeBin() + it, 0);
1182                   track2->SetData(input.GetRow(), input.GetCol(), input.GetTimeBin() + it, 0);
1183                 }
1184             }
1185         }
1186   }
1187
1188   if (digits) digits->Compress();
1189   if (track0) track0->Compress();        
1190   if (track1) track1->Compress();       
1191   if (track2) track2->Compress();
1192
1193   return digitsManager;
1194
1195 }
1196
1197