377c12705073791b301029ee5ecd1170e1f76bd3
[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 "AliTRDgeometry.h"
29 #include "AliTRDdataArrayI.h"
30 #include "AliTRDRawStream.h"
31 #include "AliRawDataHeader.h"
32 #include "AliRawReader.h"
33 #include "AliTRDCommonParam.h"
34 #include "AliTRDcalibDB.h"
35
36 ClassImp(AliTRDrawData)
37
38 //_____________________________________________________________________________
39 AliTRDrawData::AliTRDrawData():TObject()
40 {
41   //
42   // Default constructor
43   //
44
45   fDebug         = 0;
46
47 }
48
49 //_____________________________________________________________________________
50 AliTRDrawData::AliTRDrawData(const AliTRDrawData &r):TObject()
51 {
52   //
53   // AliTRDrawData copy constructor
54   //
55
56   ((AliTRDrawData &) r).Copy(*this);
57
58 }
59
60 //_____________________________________________________________________________
61 AliTRDrawData::~AliTRDrawData()
62 {
63   //
64   // Destructor
65   //
66
67 }
68
69 //_____________________________________________________________________________
70 AliTRDrawData &AliTRDrawData::operator=(const AliTRDrawData &r)
71 {
72   //
73   // Assignment operator
74   //
75
76   if (this != &r) ((AliTRDrawData &) r).Copy(*this);
77   return *this;
78
79 }
80
81 //_____________________________________________________________________________
82 void AliTRDrawData::Copy(TObject &r) const
83 {
84   //
85   // Copy function
86   //
87
88   ((AliTRDrawData &) r).fDebug         = fDebug;
89
90 }
91
92 //_____________________________________________________________________________
93 Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree)
94 {
95   //
96   // Convert the digits to raw data byte stream. The output is written
97   // into the the binary files TRD_<DDL number>.ddl.
98   //
99   // The pseudo raw data format is currently defined like this:
100   //
101   //          DDL data header
102   //
103   //          Subevent (= single chamber) header (8 bytes)
104   //                  FLAG
105   //                  Detector number (2 bytes)
106   //                  Number of data bytes (2 bytes)
107   //                  Number of pads with data (2 bytes)
108   //                  1 empty byte
109   //
110   //          Data bank
111   //
112
113   const Int_t kNumberOfDDLs         = 18;
114   const Int_t kSubeventHeaderLength = 8;
115   const Int_t kSubeventDummyFlag    = 0xBB;
116   Int_t       headerSubevent[3];
117
118   ofstream      *outputFile[kNumberOfDDLs];
119   UInt_t         bHPosition[kNumberOfDDLs];
120   Int_t          ntotalbyte[kNumberOfDDLs];
121   Int_t          nbyte = 0;
122   Int_t          npads = 0;
123   unsigned char *bytePtr;
124   unsigned char *headerPtr;
125
126   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
127   digitsManager->SetDebug(fDebug);
128
129   // Read in the digit arrays
130   if (!digitsManager->ReadDigits(digitsTree)) {
131     delete digitsManager;
132     return kFALSE;
133   }
134
135   AliTRDgeometry   *geo = new AliTRDgeometry();
136   AliTRDdataArrayI *digits;
137
138   AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
139   if (!commonParam)
140   {
141     printf("<AliTRDrawData::Digits2Raw> ");
142     printf("Could not get common params\n");
143     return 0;
144   }
145   
146   AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
147   if (!calibration)
148   {
149     printf("<AliTRDdigitizer::Digits2Raw> ");
150     printf("Could not get calibration object\n");
151     return kFALSE;
152   }
153     
154   // the event header
155   AliRawDataHeader header;
156
157   // Open the output files
158   for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
159     char name[20];
160     sprintf(name, "TRD_%d.ddl", iDDL + AliTRDRawStream::kDDLOffset);
161 #ifndef __DECCXX
162     outputFile[iDDL] = new ofstream(name, ios::binary);
163 #else
164     outputFile[iDDL] = new ofstream(name);
165 #endif
166
167     // Write a dummy data header
168     bHPosition[iDDL] = outputFile[iDDL]->tellp();
169     outputFile[iDDL]->write((char*)(&header),sizeof(header));
170     ntotalbyte[iDDL] = 0;
171   }
172
173   // Loop through all detectors
174   for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
175
176     Int_t cham      = geo->GetChamber(det);
177     Int_t plan      = geo->GetPlane(det);
178     Int_t sect      = geo->GetSector(det);
179     Int_t rowMax    = commonParam->GetRowMax(plan,cham,sect);
180     Int_t colMax    = commonParam->GetColMax(plan);
181     Int_t timeTotal = calibration->GetNumberOfTimeBins();
182     Int_t bufferMax = rowMax*colMax*timeTotal;
183     Int_t *buffer   = new Int_t[bufferMax];
184
185     npads   = 0;
186     nbyte   = 0;
187     bytePtr = (unsigned char *) buffer;
188
189     Int_t iDDL = sect;
190
191     // Get the digits array
192     digits = digitsManager->GetDigits(det);
193     digits->Expand();
194
195     // Loop through the detector pixel
196     for (Int_t col = 0; col < colMax; col++) {
197       for (Int_t row = 0; row < rowMax; row++) {
198
199         // Check whether data exists for this pad
200         Bool_t dataflag = kFALSE;
201         for (Int_t time = 0; time < timeTotal; time++) {
202           Int_t data = digits->GetDataUnchecked(row,col,time);
203           if (data) {
204             dataflag = kTRUE;
205             break;
206           }
207         }
208
209         if (dataflag) {
210
211           npads++;
212
213           // The pad row number
214           *bytePtr++ = row + 1;
215           // The pad column number
216           *bytePtr++ = col + 1;
217           nbyte += 2;
218
219           Int_t nzero = 0;
220           for (Int_t time = 0; time < timeTotal; time++) {
221
222             Int_t data = digits->GetDataUnchecked(row,col,time);
223
224             if (!data) {
225               nzero++;
226               if ((nzero ==       256) || 
227                   (time  == timeTotal-1)) {
228                 *bytePtr++ = 0;
229                 *bytePtr++ = nzero-1;
230                 nbyte += 2;
231                 nzero  = 0;
232               }
233             }
234             else {
235               if (nzero) {
236                 *bytePtr++ = 0;
237                 *bytePtr++ = nzero-1;
238                 nbyte += 2;
239                 nzero  = 0;
240               }
241               // High byte (MSB always set)
242               *bytePtr++ = ((data >> 8) | 128);
243               // Low byte
244               *bytePtr++ = (data & 0xff);
245               nbyte += 2;
246             }
247
248           }
249
250         }
251
252       }
253
254     }
255
256     // Fill the end of the buffer with zeros
257     while (nbyte % 4) {  
258       *bytePtr++ = 0;
259       nbyte++;
260     }
261
262     if (fDebug > 1) {
263       Info("Digits2Raw","det = %d, nbyte = %d (%d)",det,nbyte,bufferMax);
264     }
265
266     // Write the subevent header
267     bytePtr    = (unsigned char *) headerSubevent;
268     headerPtr  = bytePtr;
269     *bytePtr++ = kSubeventDummyFlag;
270     *bytePtr++ = (det   & 0xff);
271     *bytePtr++ = (det   >> 8);
272     *bytePtr++ = (nbyte & 0xff);
273     *bytePtr++ = (nbyte >> 8);
274     *bytePtr++ = (nbyte >> 16);
275     *bytePtr++ = (npads & 0xff);
276     *bytePtr++ = (npads >> 8);
277     outputFile[iDDL]->write((char*)headerPtr,kSubeventHeaderLength);
278
279     // Write the buffer to the file
280     bytePtr = (unsigned char *) buffer;
281     outputFile[iDDL]->write((char*)bytePtr,nbyte);
282
283     ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength;
284
285     delete buffer;
286
287   }
288
289   if (fDebug) {
290     for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
291       Info("Digits2Raw","Total size: DDL %d = %d",iDDL,ntotalbyte[iDDL]);
292     }
293   }
294
295   // Update the data headers and close the output files
296   for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
297     header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL];
298     header.SetAttribute(0);  // valid data
299     outputFile[iDDL]->seekp(bHPosition[iDDL]);
300     outputFile[iDDL]->write((char*)(&header),sizeof(header));
301
302     outputFile[iDDL]->close();
303     delete outputFile[iDDL];
304   }
305
306   delete geo;
307   delete digitsManager;
308
309   return kTRUE;
310
311 }
312
313 //_____________________________________________________________________________
314 AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader)
315 {
316   //
317   // Read the raw data digits and put them into the returned digits manager
318   //
319
320   AliTRDdataArrayI *digits    = 0;
321   AliTRDdataArrayI *track0    = 0;
322   AliTRDdataArrayI *track1    = 0;
323   AliTRDdataArrayI *track2    = 0; 
324
325   AliTRDgeometry *geo = new AliTRDgeometry();
326
327   AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
328   if (!commonParam)
329   {
330     printf("<AliTRDrawData::Raw2Digits> ");
331     printf("Could not get common params\n");
332     return 0;
333   }
334     
335   AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
336   if (!calibration)
337   {
338     printf("<AliTRDdigitizer::Raw2Digits> ");
339     printf("Could not get calibration object\n");
340     return 0;
341   }
342
343   // Create the digits manager
344   AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
345   digitsManager->SetDebug(fDebug);
346   digitsManager->CreateArrays();
347
348   AliTRDRawStream input(rawReader);
349
350   // Loop through the digits
351   while (input.Next()) {
352
353     Int_t det    = input.GetDetector();
354     Int_t npads  = input.GetNPads();
355
356     if (input.IsNewDetector()) {
357
358       if (digits) digits->Compress(1,0);
359       if (track0) track0->Compress(1,0);
360       if (track1) track1->Compress(1,0);
361       if (track2) track2->Compress(1,0);
362
363       if (fDebug > 2) {
364         Info("Raw2Digits","Subevent header:");
365         Info("Raw2Digits","\tdet   = %d",det);
366         Info("Raw2Digits","\tnpads = %d",npads);
367       }      
368
369       // Create the data buffer
370       Int_t cham      = geo->GetChamber(det);
371       Int_t plan      = geo->GetPlane(det);
372       Int_t sect      = geo->GetSector(det);
373       Int_t rowMax    = commonParam->GetRowMax(plan,cham,sect);
374       Int_t colMax    = commonParam->GetColMax(plan);
375       Int_t timeTotal = calibration->GetNumberOfTimeBins();
376
377       // Add a container for the digits of this detector
378       digits = digitsManager->GetDigits(det);
379       track0 = digitsManager->GetDictionary(det,0);
380       track1 = digitsManager->GetDictionary(det,1);
381       track2 = digitsManager->GetDictionary(det,2);
382       // Allocate memory space for the digits buffer
383       if (digits->GetNtime() == 0) {
384         digits->Allocate(rowMax,colMax,timeTotal);
385         track0->Allocate(rowMax,colMax,timeTotal);
386         track1->Allocate(rowMax,colMax,timeTotal);
387         track2->Allocate(rowMax,colMax,timeTotal);
388       }
389
390     } 
391
392     digits->SetDataUnchecked(input.GetRow(),input.GetColumn(),
393                              input.GetTime(),input.GetSignal());
394     track0->SetDataUnchecked(input.GetRow(),input.GetColumn(),
395                              input.GetTime(),               -1);
396     track1->SetDataUnchecked(input.GetRow(),input.GetColumn(),
397                              input.GetTime(),               -1);
398     track2->SetDataUnchecked(input.GetRow(),input.GetColumn(),
399                              input.GetTime(),               -1);
400   }
401
402   if (digits) digits->Compress(1,0);
403   if (track0) track0->Compress(1,0);
404   if (track1) track1->Compress(1,0);
405   if (track2) track2->Compress(1,0);
406
407   delete geo;
408
409   return digitsManager;
410
411 }