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