Simulation of RAW data (T.Kuhr)
[u/mrichter/AliRoot.git] / TRD / AliTRDrawData.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  TRD raw data conversion class                                            //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include <Riostream.h>
25
26 #include "AliTRDrawData.h"
27 #include "AliTRDdigitsManager.h"
28 #include "AliTRDgeometryFull.h"
29 #include "AliTRDparameter.h"
30 #include "AliTRDdataArrayI.h"
31 #include "AliTRDRawStream.h"
32 #include "AliRawDataHeader.h"
33
34 ClassImp(AliTRDrawData)
35
36 //_____________________________________________________________________________
37 AliTRDrawData::AliTRDrawData():TObject()
38 {
39   //
40   // Default constructor
41   //
42
43   fDebug         = 0;
44
45 }
46
47 //_____________________________________________________________________________
48 AliTRDrawData::AliTRDrawData(const AliTRDrawData &r):TObject()
49 {
50   //
51   // AliTRDrawData copy constructor
52   //
53
54   ((AliTRDrawData &) r).Copy(*this);
55
56 }
57
58 //_____________________________________________________________________________
59 AliTRDrawData::~AliTRDrawData()
60 {
61   //
62   // Destructor
63   //
64
65 }
66
67 //_____________________________________________________________________________
68 AliTRDrawData &AliTRDrawData::operator=(const AliTRDrawData &r)
69 {
70   //
71   // Assignment operator
72   //
73
74   if (this != &r) ((AliTRDrawData &) r).Copy(*this);
75   return *this;
76
77 }
78
79 //_____________________________________________________________________________
80 void AliTRDrawData::Copy(TObject &r)
81 {
82   //
83   // Copy function
84   //
85
86   ((AliTRDrawData &) r).fDebug         = fDebug;
87
88 }
89
90 //_____________________________________________________________________________
91 Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree)
92 {
93   //
94   // Convert the digits to raw data byte stream. The output is written
95   // into the the binary files TRD_<DDL number>.ddl.
96   //
97   // The pseudo raw data format is currently defined like this:
98   //
99   //          DDL data header
100   //
101   //          Subevent (= single chamber) header (8 bytes)
102   //                  FLAG
103   //                  Detector number (2 bytes)
104   //                  Number of data bytes (2 bytes)
105   //                  Number of pads with data (2 bytes)
106   //                  1 empty byte
107   //
108   //          Data bank
109   //
110
111   const Int_t kNumberOfDDLs         = 18;
112   const Int_t kSubeventHeaderLength = 8;
113   const Int_t kSubeventDummyFlag    = 0xBB;
114   int headerSubevent[2];
115
116   ofstream      *outputFile[kNumberOfDDLs];
117   UInt_t         bHPosition[kNumberOfDDLs];
118   Int_t          ntotalbyte[kNumberOfDDLs];
119   Int_t          nbyte = 0;
120   Int_t          npads = 0;
121   unsigned char *bytePtr;
122   unsigned char *headerPtr;
123
124   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
125   digitsManager->SetDebug(fDebug);
126
127   // Read in the digit arrays
128   if (!digitsManager->ReadDigits(digitsTree)) {
129     delete digitsManager;
130     return kFALSE;
131   }
132
133   AliTRDgeometryFull *geo = new AliTRDgeometryFull();
134   AliTRDparameter    *par = new AliTRDparameter("TRDparameter"
135                                                ,"TRD parameter class");
136   AliTRDdataArrayI   *digits;
137
138   // the event header
139   AliRawDataHeader header;
140
141   if (fDebug) {
142     printf("Event header size: %d \n",sizeof(header));
143   }
144
145   // Open the output files
146   for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
147     char name[20];
148     sprintf(name, "TRD_%d.ddl", iDDL + AliTRDRawStream::kDDLOffset);
149 #ifndef __DECCXX
150     outputFile[iDDL] = new ofstream(name, ios::binary);
151 #else
152     outputFile[iDDL] = new ofstream(name);
153 #endif
154
155     // Write a dummy data header
156     bHPosition[iDDL] = outputFile[iDDL]->tellp();
157     outputFile[iDDL]->write((char*)(&header),sizeof(header));
158     ntotalbyte[iDDL] = 0;
159   }
160
161   // Loop through all detectors
162   for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
163
164     Int_t cham      = geo->GetChamber(det);
165     Int_t plan      = geo->GetPlane(det);
166     Int_t sect      = geo->GetSector(det);
167     Int_t rowMax    = par->GetRowMax(plan,cham,sect);
168     Int_t colMax    = par->GetColMax(plan);
169     Int_t timeMax   = par->GetTimeMax();
170     Int_t bufferMax = rowMax*colMax*timeMax;
171     int  *buffer    = new int[bufferMax];
172
173     npads   = 0;
174     nbyte   = 0;
175     bytePtr = (unsigned char *) buffer;
176
177     Int_t iDDL = sect;
178
179     // Get the digits array
180     digits = digitsManager->GetDigits(det);
181     digits->Expand();
182
183     // Loop through the detector pixel
184     for (Int_t col = 0; col < colMax; col++) {
185       for (Int_t row = 0; row < rowMax; row++) {
186
187         // Check whether data exists for this pad
188         Bool_t dataflag = kFALSE;
189         for (Int_t time = 0; time < timeMax; time++) {
190           Int_t data = digits->GetDataUnchecked(row,col,time);
191           if (data) {
192             dataflag = kTRUE;
193             break;
194           }
195         }
196
197         if (dataflag) {
198
199           npads++;
200
201           // The pad row number
202           *bytePtr++ = row + 1;
203           // The pad column number
204           *bytePtr++ = col + 1;
205           nbyte += 2;
206
207           Int_t nzero = 0;
208           for (Int_t time = 0; time < timeMax; time++) {
209
210             Int_t data = digits->GetDataUnchecked(row,col,time);
211
212             if (!data) {
213               nzero++;
214               if ((nzero ==       256) || 
215                   (time  == timeMax-1)) {
216                 *bytePtr++ = 0;
217                 *bytePtr++ = nzero-1;
218                 nbyte += 2;
219                 nzero  = 0;
220               }
221             }
222             else {
223               if (nzero) {
224                 *bytePtr++ = 0;
225                 *bytePtr++ = nzero-1;
226                 nbyte += 2;
227                 nzero  = 0;
228               }
229               // High byte (MSB always set)
230               *bytePtr++ = ((data >> 8) | 128);
231               // Low byte
232               *bytePtr++ = (data & 0xff);
233               nbyte += 2;
234             }
235
236           }
237
238         }
239
240       }
241
242     }
243
244     // Fill the end of the buffer with zeros
245     while (nbyte % 4) {  
246       *bytePtr++ = 0;
247       nbyte++;
248     }
249
250     if (fDebug > 1) {
251       Info("Digits2Raw","det = %d, nbyte = %d (%d)",det,nbyte,bufferMax);
252     }
253
254     // Write the subevent header
255     bytePtr    = (unsigned char *) headerSubevent;
256     headerPtr  = bytePtr;
257     *bytePtr++ = kSubeventDummyFlag;
258     *bytePtr++ = (det   & 0xff);
259     *bytePtr++ = (det   >> 8);
260     *bytePtr++ = (nbyte & 0xff);
261     *bytePtr++ = (nbyte >> 8);
262     *bytePtr++ = (npads & 0xff);
263     *bytePtr++ = (npads >> 8);
264     *bytePtr++ = 0;
265     outputFile[iDDL]->write((char*)headerPtr,kSubeventHeaderLength);
266
267     // Write the buffer to the file
268     bytePtr = (unsigned char *) buffer;
269     outputFile[iDDL]->write((char*)bytePtr,nbyte);
270
271     ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength;
272
273     delete buffer;
274
275   }
276
277   if (fDebug) {
278     for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
279       Info("Digits2Raw","Total size: DDL %d = %d",iDDL,ntotalbyte[iDDL]);
280     }
281   }
282
283   // Update the data headers and close the output files
284   for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
285     header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL];
286     header.SetAttribute(0);  // valid data
287     outputFile[iDDL]->seekp(bHPosition[iDDL]);
288     outputFile[iDDL]->write((char*)(&header),sizeof(header));
289
290     outputFile[iDDL]->close();
291     delete outputFile[iDDL];
292   }
293
294   delete geo;
295   delete par;
296   delete digitsManager;
297
298   return kTRUE;
299
300 }
301
302 //_____________________________________________________________________________
303 AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader)
304 {
305   //
306   // Read the raw data digits and put them into the returned digits manager
307   //
308
309   AliTRDdataArrayI *digits    = 0;
310
311   AliTRDgeometryFull *geo = new AliTRDgeometryFull();
312   AliTRDparameter    *par = new AliTRDparameter("TRDparameter"
313                                                ,"TRD parameter class");
314
315   // Create the digits manager
316   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
317   digitsManager->SetDebug(fDebug);
318   digitsManager->CreateArrays();
319
320   AliTRDRawStream input(rawReader);
321
322   // Loop through the digits
323   while (input.Next()) {
324
325     Int_t det    = input.GetDetector();
326     Int_t npads  = input.GetNPads();
327
328     if (input.IsNewDetector()) {
329
330       if (digits) digits->Compress(1,0);
331
332       if (fDebug > 2) {
333         Info("Raw2Digits","Subevent header:");
334         Info("Raw2Digits","\tdet   = %d",det);
335         Info("Raw2Digits","\tnpads = %d",npads);
336       }      
337
338       // Create the data buffer
339       Int_t cham      = geo->GetChamber(det);
340       Int_t plan      = geo->GetPlane(det);
341       Int_t sect      = geo->GetSector(det);
342       Int_t rowMax    = par->GetRowMax(plan,cham,sect);
343       Int_t colMax    = par->GetColMax(plan);
344       Int_t timeMax   = par->GetTimeMax();
345
346       // Add a container for the digits of this detector
347       digits = digitsManager->GetDigits(det);
348       // Allocate memory space for the digits buffer
349       if (digits->GetNtime() == 0) {
350         digits->Allocate(rowMax,colMax,timeMax);
351       }
352
353     } 
354     digits->SetDataUnchecked(input.GetRow(),input.GetColumn(),
355                              input.GetTime(),input.GetSignal());
356   }
357
358   if (digits) digits->Compress(1,0);
359
360   delete geo;
361   delete par;
362
363   return digitsManager;
364
365 }