Add conversion class to produce fake raw data
[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
16/*
17$Log$
18*/
19
20///////////////////////////////////////////////////////////////////////////////
21// //
22// TRD raw data conversion class //
23// //
24///////////////////////////////////////////////////////////////////////////////
25
26#include <fstream.h>
27
28#include "AliTRDrawData.h"
29#include "AliTRDdigitsManager.h"
30#include "AliTRDgeometryFull.h"
31#include "AliTRDparameter.h"
32#include "AliTRDdataArrayI.h"
33#include "AliTRDarrayI.h"
34
35ClassImp(AliTRDrawData)
36
37//_____________________________________________________________________________
38AliTRDrawData::AliTRDrawData():TObject()
39{
40
41 fDebug = 0;
42 fDigitsManager = NULL;
43
44}
45
46//_____________________________________________________________________________
47AliTRDrawData::AliTRDrawData(const AliTRDrawData &r)
48{
49 //
50 // AliTRDrawData copy constructor
51 //
52
53 ((AliTRDrawData &) r).Copy(*this);
54
55}
56
57//_____________________________________________________________________________
58AliTRDrawData::~AliTRDrawData()
59{
60 //
61 // Destructor
62 //
63
64 if (fDigitsManager) {
65 delete fDigitsManager;
66 fDigitsManager = NULL;
67 }
68
69}
70
71//_____________________________________________________________________________
72AliTRDrawData &AliTRDrawData::operator=(const AliTRDrawData &r)
73{
74 //
75 // Assignment operator
76 //
77
78 if (this != &r) ((AliTRDrawData &) r).Copy(*this);
79 return *this;
80
81}
82
83//_____________________________________________________________________________
84void AliTRDrawData::Copy(TObject &r)
85{
86 //
87 // Copy function
88 //
89
90 ((AliTRDrawData &) r).fDebug = fDebug;
91 ((AliTRDrawData &) r).fDigitsManager = NULL;
92
93}
94
95//_____________________________________________________________________________
96Bool_t AliTRDrawData::OpenInput(const Char_t *name)
97{
98 //
99 // Opens a ROOT-file with the TRD digits
100 //
101
102 // Create the digits manager
103 if (fDigitsManager) {
104 delete fDigitsManager;
105 }
106 fDigitsManager = new AliTRDdigitsManager();
107 fDigitsManager->SetDebug(fDebug);
108
109 // Open the input file
110 return fDigitsManager->Open(name);
111
112}
113
114//_____________________________________________________________________________
115Bool_t AliTRDrawData::Digit2Raw(const Char_t *name1, const Char_t *name2)
116{
117 //
118 // Convert the digits to raw data byte stream. The output is written
119 // into the the binary files <name1> and <name2>.
120 //
121 // The pseudo raw data format is currently defined like this:
122 //
123 // LDC header (8 bytes)
124 // FLAG
125 // LDC no.
126 // Number of detectors with data (not yet implemented)
127 // 5 empty bytes
128 //
129 // Subevent (= single chamber) header (8 bytes)
130 // FLAG
131 // Detector number (2 bytes)
132 // Number of data bytes (2 bytes)
133 // Number of pads with data (2 bytes)
134 // 1 empty byte
135 //
136 // Data bank
137 //
138
139 const Int_t kLDCHeaderLength = 8;
140 const Int_t kSubeventHeaderLength = 8;
141
142 const Int_t kLDCDummyFlag = 0xAA;
143 const Int_t kSubeventDummyFlag = 0xBB;
144
145 int headerLDC[2];
146 int headerSubevent[2];
147
148 Int_t ntotalbyte[2] = { 0 };
149 Int_t nbyte = 0;
150 Int_t npads = 0;
151 unsigned char *byte_p;
152 unsigned char *header_p;
153
154 AliTRDgeometryFull *geo = new AliTRDgeometryFull();
155 AliTRDparameter *par = new AliTRDparameter("TRDparameter"
156 ,"TRD parameter class");
157 AliTRDdataArrayI *digits;
158
159 if (fDebug) {
160 Info("Digit2Raw","Open the LDC output files %s, %s"
161 ,name1,name2);
162 }
163 ofstream *outputFile1 = new ofstream(name1, ios::out | ios::binary);
164 ofstream *outputFile2 = new ofstream(name2, ios::out | ios::binary);
165 ofstream *outputFile;
166
167 if (!fDigitsManager) {
168 Error("Digit2Raw","No input file open\n");
169 return kFALSE;
170 }
171
172 // Read in the digit arrays
173 if (!fDigitsManager->ReadDigits()) {
174 return kFALSE;
175 }
176
177 // Count the number of chambers with data
178 Int_t ndetLDC0 = 0;
179 Int_t ndetLDC1 = 0;
180
181 if (fDebug > 1) {
182 Info("Digit2Raw","Write the LDC headers");
183 }
184
185 // Write the LDC header 1
186 byte_p = (unsigned char *) headerLDC;
187 header_p = byte_p;
188 *byte_p++ = kLDCDummyFlag;
189 *byte_p++ = 1;
190 *byte_p++ = ndetLDC0;
191 *byte_p++ = 0;
192 *byte_p++ = 0;
193 *byte_p++ = 0;
194 *byte_p++ = 0;
195 *byte_p++ = 0;
196 outputFile1->write(header_p,kLDCHeaderLength);
197 ntotalbyte[0] += kLDCHeaderLength;
198
199 if (fDebug > 1) {
200 Info("Digit2Raw","LDC header 0 = %d, %d",headerLDC[0],headerLDC[1]);
201 }
202
203 // Write the LDC header 1
204 byte_p = (unsigned char *) headerLDC;
205 header_p = byte_p;
206 *byte_p++ = kLDCDummyFlag;
207 *byte_p++ = 2;
208 *byte_p++ = ndetLDC1;
209 *byte_p++ = 0;
210 *byte_p++ = 0;
211 *byte_p++ = 0;
212 *byte_p++ = 0;
213 *byte_p++ = 0;
214 outputFile2->write(header_p,kLDCHeaderLength);
215 ntotalbyte[1] += kLDCHeaderLength;
216
217 if (fDebug > 1) {
218 Info("Digit2Raw","LDC header 1 = %d, %d",headerLDC[0],headerLDC[1]);
219 }
220
221 // Loop through all detectors
222 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
223
224 Int_t cham = geo->GetChamber(det);
225 Int_t plan = geo->GetPlane(det);
226 Int_t sect = geo->GetSector(det);
227 Int_t rowMax = par->GetRowMax(plan,cham,sect);
228 Int_t colMax = par->GetColMax(plan);
229 Int_t timeMax = par->GetTimeMax();
230 Int_t bufferMax = rowMax*colMax*timeMax;
231 int *buffer = new int[bufferMax];
232
233 npads = 0;
234 nbyte = 0;
235 byte_p = (unsigned char *) buffer;
236
237 // Determine the LDC (resp. output file)
238 Int_t ldc;
239 if (sect < 9) {
240 outputFile = outputFile1;
241 ldc = 0;
242 }
243 else {
244 outputFile = outputFile2;
245 ldc = 1;
246 }
247
248 // Get the digits array
249 digits = fDigitsManager->GetDigits(det);
250 digits->Expand();
251
252 // Loop through the detector pixel
253 for (Int_t col = 0; col < colMax; col++) {
254 for (Int_t row = 0; row < rowMax; row++) {
255
256 // Check whether data exists for this pad
257 Bool_t dataflag = kFALSE;
258 for (Int_t time = 0; time < timeMax; time++) {
259 Int_t data = digits->GetDataUnchecked(row,col,time);
260 if (data) {
261 dataflag = kTRUE;
262 break;
263 }
264 }
265
266 if (dataflag) {
267
268 npads++;
269
270 // The pad row number
271 *byte_p++ = row + 1;
272 // The pad column number
273 *byte_p++ = col + 1;
274 nbyte += 2;
275
276 Int_t nzero = 0;
277 for (Int_t time = 0; time < timeMax; time++) {
278
279 Int_t data = digits->GetDataUnchecked(row,col,time);
280
281 if (!data) {
282 nzero++;
283 if ((nzero == 256) ||
284 (time == timeMax-1)) {
285 *byte_p++ = 0;
286 *byte_p++ = nzero-1;
287 nbyte += 2;
288 nzero = 0;
289 }
290 }
291 else {
292 if (nzero) {
293 *byte_p++ = 0;
294 *byte_p++ = nzero-1;
295 nbyte += 2;
296 nzero = 0;
297 }
298 // High byte (MSB always set)
299 *byte_p++ = ((data >> 8) | 128);
300 // Low byte
301 *byte_p++ = (data & 0xff);
302 nbyte += 2;
303 }
304
305 }
306
307 }
308
309 }
310
311 }
312
313 // Fill the end of the buffer with zeros
314 while (nbyte % 4) {
315 *byte_p++ = 0;
316 nbyte++;
317 }
318
319 if (fDebug > 1) {
320 Info("Digit2Raw","LDC = %d, det = %d, nbyte = %d (%d)",ldc,det,nbyte,bufferMax);
321 }
322
323 // Write the subevent header
324 byte_p = (unsigned char *) headerSubevent;
325 header_p = byte_p;
326 *byte_p++ = kSubeventDummyFlag;
327 *byte_p++ = (det & 0xff);
328 *byte_p++ = (det >> 8);
329 *byte_p++ = (nbyte & 0xff);
330 *byte_p++ = (nbyte >> 8);
331 *byte_p++ = (npads & 0xff);
332 *byte_p++ = (npads >> 8);
333 *byte_p++ = 0;
334 outputFile->write(header_p,kSubeventHeaderLength);
335
336 // Write the buffer to the file
337 byte_p = (unsigned char *) buffer;
338 outputFile->write(byte_p,nbyte);
339
340 ntotalbyte[ldc] += nbyte + kSubeventHeaderLength;
341
342 delete buffer;
343
344 }
345
346 if (fDebug) {
347 Info("Digit2Raw","Total size: LDC0 = %d, LDC1 = %d",ntotalbyte[0],ntotalbyte[1]);
348 }
349
350 outputFile1->close();
351 outputFile2->close();
352
353 delete geo;
354 delete par;
355 delete outputFile1;
356 delete outputFile2;
357
358 return kTRUE;
359
360}
361
362//_____________________________________________________________________________
363Bool_t AliTRDrawData::Raw2Digit(const Char_t *name1, const Char_t *name2)
364{
365
366 const Int_t kLDCHeaderLength = 8;
367 const Int_t kSubeventHeaderLength = 8;
368
369 const Int_t kNldc = 2;
370 const Char_t *name = 0;
371
372 int headerLDC[2];
373 int headerSubevent[2];
374
375 Int_t npads = 0;
376 Int_t nbyte = 0;
377 unsigned char *byte_p;
378 ifstream *inputFile = 0;
379 AliTRDdataArrayI *digits = 0;
380
381 AliTRDgeometryFull *geo = new AliTRDgeometryFull();
382 AliTRDparameter *par = new AliTRDparameter("TRDparameter"
383 ,"TRD parameter class");
384
385 // Create the digits manager
386 if (fDigitsManager) {
387 delete fDigitsManager;
388 }
389 fDigitsManager = new AliTRDdigitsManager();
390 fDigitsManager->SetDebug(fDebug);
391 fDigitsManager->CreateArrays();
392
393 for (Int_t ldc = 0; ldc < kNldc; ldc++) {
394
395 if (ldc == 0) {
396 name = name1;
397 }
398 else if (ldc == 1) {
399 name = name2;
400 }
401 if (fDebug) {
402 Info("Raw2Digit","Open the LDC input file %s",name);
403 }
404 inputFile = new ifstream(name, ios::in | ios::binary);
405
406 // Read the LDC header
407 byte_p = (unsigned char *) headerLDC;
408 inputFile->read(byte_p,kLDCHeaderLength);
409
410 if (fDebug > 1) {
411 Info("Raw2Digit","LDC header no. %d:",ldc);
412 Info("Raw2Digit","\tflag = %d",*byte_p++);
413 Info("Raw2Digit","\tldc no = %d",*byte_p++);
414 Info("Raw2Digit","\tndet = %d",*byte_p++);
415 Info("Raw2Digit","\tempty = %d",*byte_p++);
416 Info("Raw2Digit","\tempty = %d",*byte_p++);
417 Info("Raw2Digit","\tempty = %d",*byte_p++);
418 Info("Raw2Digit","\tempty = %d",*byte_p++);
419 Info("Raw2Digit","\tempty = %d",*byte_p++);
420 }
421
422 // Loop through the subevents
423 byte_p = (unsigned char *) headerSubevent;
424 while (inputFile->read(byte_p,kSubeventHeaderLength)) {
425
426 Int_t flag = *byte_p++;
427 Int_t detl = *byte_p++;
428 Int_t deth = *byte_p++;
429 Int_t det = detl + (deth << 8);
430 Int_t nbytel = *byte_p++;
431 Int_t nbyteh = *byte_p++;
432 nbyte = nbytel + (nbyteh << 8);
433 Int_t npadsl = *byte_p++;
434 Int_t npadsh = *byte_p++;
435 npads = npadsl + (npadsh << 8);
436 if (fDebug > 2) {
437 Info("Raw2Digit","Subevent header:");
438 Info("Raw2Digit","\tflag = %d",flag);
439 Info("Raw2Digit","\tdet = %d",det);
440 Info("Raw2Digit","\tnbyte = %d",nbyte);
441 Info("Raw2Digit","\tnpads = %d",npads);
442 Info("Raw2Digit","\tempty = %d",*byte_p++);
443 }
444
445 // Create the data buffer
446 Int_t cham = geo->GetChamber(det);
447 Int_t plan = geo->GetPlane(det);
448 Int_t sect = geo->GetSector(det);
449 Int_t rowMax = par->GetRowMax(plan,cham,sect);
450 Int_t colMax = par->GetColMax(plan);
451 Int_t timeMax = par->GetTimeMax();
452 Int_t bufferMax = rowMax*colMax*timeMax;
453 int *buffer = new int[bufferMax];
454 byte_p = (unsigned char *) buffer;
455 memset(buffer,0,bufferMax*sizeof(int));
456
457 // Add a container for the digits of this detector
458 digits = fDigitsManager->GetDigits(det);
459 // Allocate memory space for the digits buffer
460 if (digits->GetNtime() == 0) {
461 digits->Allocate(rowMax,colMax,timeMax);
462 }
463
464 // Read the data
465 inputFile->read(byte_p,nbyte);
466
467 Int_t time;
468 Int_t nzero;
469 Int_t data;
470 Int_t low;
471 Int_t high;
472 Int_t signal;
473
474 // Decompress the data
475 while (nbyte > 0) {
476
477 // The pad row number
478 Int_t row = (*byte_p++) - 1;
479 // The pad column number
480 Int_t col = (*byte_p++) - 1;
481 nbyte -= 2;
482
483 time = nzero = 0;
484
485 while ((time < timeMax) &&
486 (nbyte > 0)) {
487
488 data = *byte_p++;
489 nbyte--;
490
491 if (data) {
492 if (!nzero) {
493 // signal for given timebim
494 low = *byte_p++;
495 high = data & 127;
496 signal = low + (high << 8);
497 if ((row < 0) || (col < 0) || (time < 0) ||
498 (row >= rowMax) || (col >= colMax) || (time >= timeMax)) {
499 Error("Raw2Digit"
500 ,"row=%d(%d) col=%d(%d) time=%d(%d)"
501 ,row,rowMax,col,colMax,time,timeMax);
502 }
503 else {
504 digits->SetDataUnchecked(row,col,time,signal);
505 }
506 nbyte--;
507 time++;
508 }
509 else {
510 time += data + 1;
511 nzero = 0;
512 }
513 }
514 else {
515 if (!nzero) {
516 nzero = 1;
517 }
518 else {
519 time++;
520 nzero = 0;
521 }
522 }
523
524 }
525
526 }
527
528 digits->Compress(1,0);
529
530 delete buffer;
531
532 byte_p = (unsigned char *) headerSubevent;
533
534 }
535
536 inputFile->close();
537 delete inputFile;
538 inputFile = 0;
539
540 }
541
542 delete geo;
543 delete par;
544
545 return kTRUE;
546
547}