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