Bug fix
[u/mrichter/AliRoot.git] / TRD / AliTRDrawData.cxx
CommitLineData
5990c064 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
88cb7938 16/* $Id$ */
5990c064 17
18///////////////////////////////////////////////////////////////////////////////
19// //
20// TRD raw data conversion class //
21// //
22///////////////////////////////////////////////////////////////////////////////
23
a2cb5b3d 24#include <Riostream.h>
5990c064 25
26#include "AliTRDrawData.h"
27#include "AliTRDdigitsManager.h"
bd0f8685 28#include "AliTRDgeometry.h"
5990c064 29#include "AliTRDdataArrayI.h"
b864d801 30#include "AliTRDRawStream.h"
31#include "AliRawDataHeader.h"
928e9fae 32#include "AliRawReader.h"
3551db50 33#include "AliTRDCommonParam.h"
34#include "AliTRDcalibDB.h"
5990c064 35
36ClassImp(AliTRDrawData)
37
38//_____________________________________________________________________________
39AliTRDrawData::AliTRDrawData():TObject()
40{
b864d801 41 //
42 // Default constructor
43 //
5990c064 44
45 fDebug = 0;
5990c064 46
47}
48
49//_____________________________________________________________________________
b864d801 50AliTRDrawData::AliTRDrawData(const AliTRDrawData &r):TObject()
5990c064 51{
52 //
53 // AliTRDrawData copy constructor
54 //
55
56 ((AliTRDrawData &) r).Copy(*this);
57
58}
59
60//_____________________________________________________________________________
61AliTRDrawData::~AliTRDrawData()
62{
63 //
64 // Destructor
65 //
66
5990c064 67}
68
69//_____________________________________________________________________________
70AliTRDrawData &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//_____________________________________________________________________________
e0d47c25 82void AliTRDrawData::Copy(TObject &r) const
5990c064 83{
84 //
85 // Copy function
86 //
87
88 ((AliTRDrawData &) r).fDebug = fDebug;
5990c064 89
90}
91
92//_____________________________________________________________________________
b864d801 93Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree)
5990c064 94{
95 //
96 // Convert the digits to raw data byte stream. The output is written
b864d801 97 // into the the binary files TRD_<DDL number>.ddl.
5990c064 98 //
99 // The pseudo raw data format is currently defined like this:
100 //
b864d801 101 // DDL data header
5990c064 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
b864d801 113 const Int_t kNumberOfDDLs = 18;
5990c064 114 const Int_t kSubeventHeaderLength = 8;
5990c064 115 const Int_t kSubeventDummyFlag = 0xBB;
e3e1266c 116 Int_t headerSubevent[3];
5990c064 117
b864d801 118 ofstream *outputFile[kNumberOfDDLs];
119 UInt_t bHPosition[kNumberOfDDLs];
120 Int_t ntotalbyte[kNumberOfDDLs];
5990c064 121 Int_t nbyte = 0;
122 Int_t npads = 0;
b864d801 123 unsigned char *bytePtr;
124 unsigned char *headerPtr;
5990c064 125
b864d801 126 AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
127 digitsManager->SetDebug(fDebug);
5990c064 128
129 // Read in the digit arrays
b864d801 130 if (!digitsManager->ReadDigits(digitsTree)) {
131 delete digitsManager;
5990c064 132 return kFALSE;
133 }
134
bd0f8685 135 AliTRDgeometry *geo = new AliTRDgeometry();
136 AliTRDdataArrayI *digits;
5990c064 137
3551db50 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
b864d801 154 // the event header
155 AliRawDataHeader header;
5990c064 156
b864d801 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;
5990c064 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);
3551db50 179 Int_t rowMax = commonParam->GetRowMax(plan,cham,sect);
180 Int_t colMax = commonParam->GetColMax(plan);
181 Int_t timeTotal = calibration->GetNumberOfTimeBins();
928e9fae 182 Int_t bufferMax = rowMax*colMax*timeTotal;
e3e1266c 183 Int_t *buffer = new Int_t[bufferMax];
5990c064 184
b864d801 185 npads = 0;
186 nbyte = 0;
187 bytePtr = (unsigned char *) buffer;
5990c064 188
b864d801 189 Int_t iDDL = sect;
5990c064 190
191 // Get the digits array
b864d801 192 digits = digitsManager->GetDigits(det);
5990c064 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;
928e9fae 201 for (Int_t time = 0; time < timeTotal; time++) {
5990c064 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
b864d801 214 *bytePtr++ = row + 1;
5990c064 215 // The pad column number
b864d801 216 *bytePtr++ = col + 1;
5990c064 217 nbyte += 2;
218
219 Int_t nzero = 0;
928e9fae 220 for (Int_t time = 0; time < timeTotal; time++) {
5990c064 221
222 Int_t data = digits->GetDataUnchecked(row,col,time);
223
224 if (!data) {
225 nzero++;
226 if ((nzero == 256) ||
928e9fae 227 (time == timeTotal-1)) {
b864d801 228 *bytePtr++ = 0;
229 *bytePtr++ = nzero-1;
5990c064 230 nbyte += 2;
231 nzero = 0;
232 }
233 }
234 else {
235 if (nzero) {
b864d801 236 *bytePtr++ = 0;
237 *bytePtr++ = nzero-1;
5990c064 238 nbyte += 2;
239 nzero = 0;
240 }
241 // High byte (MSB always set)
b864d801 242 *bytePtr++ = ((data >> 8) | 128);
5990c064 243 // Low byte
b864d801 244 *bytePtr++ = (data & 0xff);
5990c064 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) {
b864d801 258 *bytePtr++ = 0;
5990c064 259 nbyte++;
260 }
261
262 if (fDebug > 1) {
b864d801 263 Info("Digits2Raw","det = %d, nbyte = %d (%d)",det,nbyte,bufferMax);
5990c064 264 }
265
266 // Write the subevent header
b864d801 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);
928e9fae 274 *bytePtr++ = (nbyte >> 16);
b864d801 275 *bytePtr++ = (npads & 0xff);
276 *bytePtr++ = (npads >> 8);
b864d801 277 outputFile[iDDL]->write((char*)headerPtr,kSubeventHeaderLength);
5990c064 278
279 // Write the buffer to the file
b864d801 280 bytePtr = (unsigned char *) buffer;
281 outputFile[iDDL]->write((char*)bytePtr,nbyte);
5990c064 282
b864d801 283 ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength;
5990c064 284
285 delete buffer;
286
287 }
288
289 if (fDebug) {
b864d801 290 for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
291 Info("Digits2Raw","Total size: DDL %d = %d",iDDL,ntotalbyte[iDDL]);
292 }
5990c064 293 }
294
b864d801 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 }
5990c064 305
306 delete geo;
b864d801 307 delete digitsManager;
5990c064 308
309 return kTRUE;
310
311}
312
313//_____________________________________________________________________________
b864d801 314AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader)
5990c064 315{
b864d801 316 //
317 // Read the raw data digits and put them into the returned digits manager
318 //
5990c064 319
5990c064 320 AliTRDdataArrayI *digits = 0;
928e9fae 321 AliTRDdataArrayI *track0 = 0;
322 AliTRDdataArrayI *track1 = 0;
323 AliTRDdataArrayI *track2 = 0;
5990c064 324
bd0f8685 325 AliTRDgeometry *geo = new AliTRDgeometry();
3551db50 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 }
5990c064 342
343 // Create the digits manager
b864d801 344 AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
345 digitsManager->SetDebug(fDebug);
346 digitsManager->CreateArrays();
5990c064 347
3551db50 348 AliTRDRawStream input(rawReader);
5990c064 349
b864d801 350 // Loop through the digits
351 while (input.Next()) {
5990c064 352
b864d801 353 Int_t det = input.GetDetector();
354 Int_t npads = input.GetNPads();
5990c064 355
b864d801 356 if (input.IsNewDetector()) {
357
358 if (digits) digits->Compress(1,0);
928e9fae 359 if (track0) track0->Compress(1,0);
360 if (track1) track1->Compress(1,0);
361 if (track2) track2->Compress(1,0);
5990c064 362
5990c064 363 if (fDebug > 2) {
b864d801 364 Info("Raw2Digits","Subevent header:");
365 Info("Raw2Digits","\tdet = %d",det);
366 Info("Raw2Digits","\tnpads = %d",npads);
5990c064 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);
3551db50 373 Int_t rowMax = commonParam->GetRowMax(plan,cham,sect);
374 Int_t colMax = commonParam->GetColMax(plan);
375 Int_t timeTotal = calibration->GetNumberOfTimeBins();
5990c064 376
377 // Add a container for the digits of this detector
b864d801 378 digits = digitsManager->GetDigits(det);
928e9fae 379 track0 = digitsManager->GetDictionary(det,0);
380 track1 = digitsManager->GetDictionary(det,1);
381 track2 = digitsManager->GetDictionary(det,2);
5990c064 382 // Allocate memory space for the digits buffer
383 if (digits->GetNtime() == 0) {
928e9fae 384 digits->Allocate(rowMax,colMax,timeTotal);
385 track0->Allocate(rowMax,colMax,timeTotal);
386 track1->Allocate(rowMax,colMax,timeTotal);
387 track2->Allocate(rowMax,colMax,timeTotal);
5990c064 388 }
389
5990c064 390 }
928e9fae 391
b864d801 392 digits->SetDataUnchecked(input.GetRow(),input.GetColumn(),
393 input.GetTime(),input.GetSignal());
928e9fae 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);
5990c064 400 }
401
b864d801 402 if (digits) digits->Compress(1,0);
928e9fae 403 if (track0) track0->Compress(1,0);
404 if (track1) track1->Compress(1,0);
405 if (track2) track2->Compress(1,0);
b864d801 406
5990c064 407 delete geo;
5990c064 408
b864d801 409 return digitsManager;
5990c064 410
411}