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