Transition to NewIO
[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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  TRD raw data conversion class                                            //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include <Riostream.h>
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
33 ClassImp(AliTRDrawData)
34
35 //_____________________________________________________________________________
36 AliTRDrawData::AliTRDrawData():TObject()
37 {
38
39   fDebug         = 0;
40   fDigitsManager = NULL;
41
42 }
43
44 //_____________________________________________________________________________
45 AliTRDrawData::AliTRDrawData(const AliTRDrawData &r)
46 {
47   //
48   // AliTRDrawData copy constructor
49   //
50
51   ((AliTRDrawData &) r).Copy(*this);
52
53 }
54
55 //_____________________________________________________________________________
56 AliTRDrawData::~AliTRDrawData()
57 {
58   //
59   // Destructor
60   //
61
62   if (fDigitsManager) {
63     delete fDigitsManager;
64     fDigitsManager = NULL;
65   }
66
67 }
68
69 //_____________________________________________________________________________
70 AliTRDrawData &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 //_____________________________________________________________________________
82 void 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 //_____________________________________________________________________________
94 Bool_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 //_____________________________________________________________________________
113 Bool_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 //_____________________________________________________________________________
361 Bool_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 }