85bdbe1751fccbd0cbd748efc2fce5f710bd09ab
[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.1.2.1  2002/10/11 07:26:37  hristov
19 Updating VirtualMC to v3-09-02
20
21 Revision 1.1  2002/09/13 14:33:52  cblume
22 Add conversion class to produce fake raw data
23
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
41 ClassImp(AliTRDrawData)
42
43 //_____________________________________________________________________________
44 AliTRDrawData::AliTRDrawData():TObject()
45 {
46
47   fDebug         = 0;
48   fDigitsManager = NULL;
49
50 }
51
52 //_____________________________________________________________________________
53 AliTRDrawData::AliTRDrawData(const AliTRDrawData &r)
54 {
55   //
56   // AliTRDrawData copy constructor
57   //
58
59   ((AliTRDrawData &) r).Copy(*this);
60
61 }
62
63 //_____________________________________________________________________________
64 AliTRDrawData::~AliTRDrawData()
65 {
66   //
67   // Destructor
68   //
69
70   if (fDigitsManager) {
71     delete fDigitsManager;
72     fDigitsManager = NULL;
73   }
74
75 }
76
77 //_____________________________________________________________________________
78 AliTRDrawData &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 //_____________________________________________________________________________
90 void 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 //_____________________________________________________________________________
102 Bool_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 //_____________________________________________________________________________
121 Bool_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 //_____________________________________________________________________________
369 Bool_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 }