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