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