]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliTPCBuffer160.cxx
Quantum efficiency implemented by setting energy deposition to zero to flag inefficiency.
[u/mrichter/AliRoot.git] / RAW / AliTPCBuffer160.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 // Interface to the Altro format
19 // to read and write digits
20 // To be used in Alice Data Challenges 
21 // and in the compression of the RAW data
22 // Author: D.Favretto
23
24 #include "AliTPCBuffer160.h"
25 #include "AliRawDataHeader.h"
26 #include <TObjArray.h>
27 #include <Riostream.h>
28 #include <TMath.h>
29 #include <stdlib.h>
30
31
32 ClassImp(AliTPCBuffer160)
33
34 AliTPCBuffer160::AliTPCBuffer160(const char* fileName,Int_t flag){
35   //if flag = 1 the actual object is used in the write mode
36   //if flag = 0 the actual object is used in the read mode
37   fFlag=flag;
38   fCurrentCell=0;
39   fDataHeaderPos=0;
40   fMaskBackward=0xFF;
41   fVerbose=0;
42   if (flag){
43     fFreeCellBuffer=16;
44     fShift=32; 
45     //the buffer is cleaned 
46     for (Int_t i=0;i<5;i++)fBuffer[i]=0;
47     //open the output file
48 #ifndef __DECCXX
49     f = new fstream(fileName,ios::binary|ios::out);
50 #else
51     f = new fstream(fileName,ios::out);
52 #endif
53   }
54   else{
55     //open the input file
56 #ifndef __DECCXX
57     f = new fstream(fileName,ios::binary|ios::in);
58 #else
59     f = new fstream(fileName,ios::in);
60 #endif
61     if(!f){
62       Error("AliTPCBuffer160", "File doesn't exist: %s", fileName);
63       return;
64     }
65     fShift=0;
66     //To get the file dimension (position of the last element in term of bytes)
67     f->seekg(0, ios::end);
68     fFilePosition= f->tellg();
69     fFileEnd=fFilePosition;
70     f->seekg(0);
71   }
72   fCreated = kTRUE;
73 }
74
75 AliTPCBuffer160::AliTPCBuffer160(fstream* file, Int_t size){
76 //constructor for reading a file
77   fFlag=0;
78   f=file;
79   fCurrentCell=0;
80   fShift=0;
81   fMaskBackward=0xFF;
82   fVerbose=0;
83
84   fDataHeaderPos=f->tellg();
85   f->seekg(fDataHeaderPos+size);
86   fFilePosition=f->tellg();
87   fFileEnd=fFilePosition;
88   f->seekg(fDataHeaderPos);
89   fCreated = kFALSE;
90 }
91
92 AliTPCBuffer160::~AliTPCBuffer160(){
93   // destructor
94   if (fFlag){
95     //Flush out the Buffer content at the end only if Buffer wasn't completely filled
96     Flush();
97     if(fVerbose)
98       Info("~AliTPCBuffer160", "File Created");
99   }//end if
100   if (fCreated) {
101     f->close();
102     delete f;
103   }
104 }
105
106
107 AliTPCBuffer160::AliTPCBuffer160(const AliTPCBuffer160 &source)
108   :TObject(source){
109   // Copy Constructor
110   if(&source==this)return;
111   this->fShift=source.fShift;
112   this->fCurrentCell=source.fCurrentCell;
113   this->fFreeCellBuffer=source.fFreeCellBuffer;
114   this->fFlag=source.fFlag;
115   this->fMaskBackward=source.fMaskBackward;
116   this->fFilePosition=source.fFilePosition;
117   this->fDataHeaderPos=source.fDataHeaderPos;
118   this->fVerbose=source.fVerbose;
119   for (Int_t i=0;i<5;i++)this->fBuffer[i]=source.fBuffer[i];
120   return;
121 }
122
123 AliTPCBuffer160& AliTPCBuffer160::operator=(const AliTPCBuffer160 &source){
124   //Assigment operator
125   if(&source==this)return *this;
126   this->fShift=source.fShift;
127   this->fCurrentCell=source.fCurrentCell;
128   this->fFreeCellBuffer=source.fFreeCellBuffer;
129   this->fFlag=source.fFlag;
130   this->fMaskBackward=source.fMaskBackward;
131   this->fFilePosition=source.fFilePosition;
132   this->fDataHeaderPos=source.fDataHeaderPos;
133   this->fVerbose=source.fVerbose;
134   for (Int_t i=0;i<5;i++)this->fBuffer[i]=source.fBuffer[i];
135   return *this;
136 }
137
138 Int_t AliTPCBuffer160::GetNext(){
139   //It reads a 10 bits word in forward dicection from the Buffer.
140   //A new Buffer is read from the file only when Buffer is empty.
141   //If there aren't elements anymore -1 is returned otherwise 
142   //the next element is returned
143   UInt_t mask=0xFFC00000;
144   UInt_t temp;
145   UInt_t value;
146   if (!fShift){
147     if (f->tellg()>=(Int_t)fFileEnd) return -1;
148     if ( f->read((char*)fBuffer,sizeof(UInt_t)*5) ){
149       fCurrentCell=0;
150       fShift=22;
151       value=fBuffer[fCurrentCell]&mask;
152       value=value>>22;
153       fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
154       return value;      
155     }
156     else return -1;
157   }//end if
158   else{
159     if (fShift>=10){
160       value=fBuffer[fCurrentCell]&mask;
161       value=value>>22;
162       fShift-=10;
163       fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
164     }
165     else{
166       value=fBuffer[fCurrentCell]&mask;
167       fCurrentCell++;
168       temp=fBuffer[fCurrentCell];
169       temp=temp>>fShift;
170       temp=temp&mask;
171       value=value|temp;
172       value=value>>22;
173       fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<(10-fShift);
174       fShift=22+fShift;
175     }
176     return value;
177   }//end else
178 }
179
180 Int_t AliTPCBuffer160::GetNextBackWord(){
181   //It reads a 10 bits word in backward dicection from the Buffer.
182   //A new Buffer is read from the file only when Buffer is empty.
183   //If there aren't elements anymore -1 is returned otherwise 
184   //the next element is returned
185   UInt_t mask=0x3FF;
186   UInt_t temp;
187   UInt_t value;
188   if (!fShift){
189     if (fFilePosition>fDataHeaderPos){
190       fFilePosition-=sizeof(UInt_t)*5;
191       f->seekg(fFilePosition);
192       f->read((char*)fBuffer,sizeof(UInt_t)*5);
193       
194       //cout<<"Buffer letto"<<endl;
195       /*
196       char* tt=(char*)fBuffer;
197       for(Int_t ii=0;ii<20;ii++){
198         cout<<hex;
199         cout<<ii<<"==> "<<(Int_t)*tt<<endl;
200         cout<<dec;
201         tt++;
202       }
203       cout<<0<<" --- "<<hex<<fBuffer[0]<<dec<<endl;
204       cout<<1<<" --- "<<hex<<fBuffer[1]<<dec<<endl;
205       cout<<2<<" --- "<<hex<<fBuffer[2]<<dec<<endl;
206       cout<<3<<" --- "<<hex<<fBuffer[3]<<dec<<endl;
207       cout<<4<<" --- "<<hex<<fBuffer[4]<<dec<<endl;
208       cout<<"Fine UInt_t"<<endl;
209       */
210       fCurrentCell=4;
211       fShift=22;
212       fMaskBackward=0xFF;
213       value=fBuffer[fCurrentCell]&mask;
214       fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
215       return value;      
216     }
217     else {
218 //      f->seekg(fFileEnd);
219       f->seekg(fDataHeaderPos);
220       return -1;
221     }
222   }//end if
223   else{
224     if (fShift>=10){
225       value=fBuffer[fCurrentCell]&mask;
226       fShift-=10;
227       fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
228     }
229     else{
230       value=fBuffer[fCurrentCell];
231       fCurrentCell--;
232       temp=fBuffer[fCurrentCell]&mask;
233       temp=temp&fMaskBackward;
234       fMaskBackward=fMaskBackward>>2;
235       temp=temp<<fShift;
236       value=value|temp;
237       fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>(10-fShift);
238       fShift=22+fShift;
239     }
240     return value;
241   }//end else
242 }
243
244 void AliTPCBuffer160::Flush(){
245   // Flushes the Buffer content 
246   if(fFreeCellBuffer!=16){
247     Int_t temp=fFreeCellBuffer;
248     for(Int_t i=0;i<temp;i++){
249       FillBuffer(0x2AA);
250     }//end for
251   }//end if
252 }
253
254 void AliTPCBuffer160::FillBuffer(Int_t Val){
255   //Fills the Buffer with 16 ten bits words and write into a file 
256   fFreeCellBuffer--;
257   if (fShift<10){
258     Int_t temp=Val;
259     Val=Val>>(10-fShift);
260     fBuffer[fCurrentCell]|=Val;
261     fCurrentCell++;
262     fShift+=32;
263     Val=temp;
264   }
265   fShift-=10;
266   Val=Val<<fShift;
267   fBuffer[fCurrentCell]|=Val;
268   if(!fShift){
269     //Buffer is written into a file
270     f->write((char*)fBuffer,sizeof(UInt_t)*5);
271    //Buffer is empty
272     for(Int_t j=0;j<5;j++)fBuffer[j]=0;
273     fShift=32;
274     fCurrentCell=0;
275     fFreeCellBuffer=16;
276   }
277   /*
278     for(Int_t jj=0;jj<5;jj++){
279     cout.flags(ios::hex);
280     cout<<fBuffer[jj]<<endl;
281     cout.flags(ios::dec);
282     }
283     
284   */
285   return;
286 }
287
288 void   AliTPCBuffer160::WriteTrailer(Int_t WordsNumber,Int_t PadNumber,Int_t RowNumber,Int_t SecNumber){
289   //Writes a trailer of 40 bits
290   Int_t num=fFreeCellBuffer%4;
291   for(Int_t i=0;i<num;i++){
292     FillBuffer(0x2AA);
293   }//end for
294   FillBuffer(WordsNumber);
295   FillBuffer(PadNumber);
296   FillBuffer(RowNumber);
297   FillBuffer(SecNumber);
298 }
299
300 void AliTPCBuffer160::ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
301   //Read a trailer of 40 bits in the forward reading mode
302   WordsNumber=GetNext();
303   PadNumber=GetNext();
304   RowNumber=GetNext();
305   SecNumber=GetNext();
306 }
307
308
309 Int_t AliTPCBuffer160::ReadTrailerBackward(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
310   //Read a trailer of 40 bits in the backward reading mode
311   Int_t temp;
312   fEndingFillWords=0;
313   do{
314     temp=GetNextBackWord();
315     fEndingFillWords++;
316     if (temp==-1)return -1;
317   }while (temp==0x2AA);  
318   fEndingFillWords--;
319   SecNumber=temp;
320   RowNumber=GetNextBackWord();
321   PadNumber=GetNextBackWord();
322   WordsNumber=GetNextBackWord();
323   return 0;
324
325
326 void AliTPCBuffer160::WriteDataHeader(Bool_t dummy, Bool_t compressed){
327   //Size msg errore sector number sub-sector number 0 for TPC 0 for uncompressed
328   AliRawDataHeader header;
329   if (dummy){
330     //if size=0 it means that this mini header is a dummi mini header
331     fDataHeaderPos=f->tellp();
332     //cout<<" Position of the DUMMY DH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl;
333     f->write((char*)(&header),sizeof(header));
334   }//end if
335   else{
336     UInt_t currentFilePos=f->tellp();
337     f->seekp(fDataHeaderPos);
338     header.fSize=currentFilePos-fDataHeaderPos;
339     header.SetAttribute(0);  // valid data
340     if (compressed) header.SetAttribute(1); 
341     //cout<<"Current Position (Next DH) "<<currentFilePos<<" Position of the DH:"<<fDataHeaderPos<<" Size:"<<Size<<endl;
342     //cout<<"Data Header Size:"<<header.fSize<<endl;
343     f->write((char*)(&header),sizeof(header));
344     f->seekp(currentFilePos);
345   }
346   return;
347 }
348
349
350 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
351
352 void AliTPCBuffer160::PackWord(UInt_t &BaseWord, UInt_t Word, Int_t StartBit, Int_t StopBit){
353   //Packs a word into the BaseWord buffer from StartBit bit up to StopBit bit
354   UInt_t dummyWord,offSet;
355   Int_t   length;
356   UInt_t sum;
357   //The BaseWord is being filled with 1 from StartBit to StopBit
358   length=StopBit-StartBit+1;
359   sum=(UInt_t)TMath::Power(2,length)-1;
360   if(Word > sum){
361     Error("PackWord", "Word to be filled is not within desired length");
362     return;
363   }
364   offSet=sum;
365   offSet<<=StartBit;
366   BaseWord=BaseWord|offSet;
367   //The Word to be filled is shifted to the position StartBit
368   //and the remaining  Left and Right bits are filled with 1
369   sum=(UInt_t)TMath::Power(2,StartBit)-1;
370   dummyWord=0xFFFFFFFF<<length;
371   dummyWord +=Word;
372   dummyWord<<=StartBit;
373   dummyWord+=sum;
374   BaseWord=BaseWord&dummyWord;
375   return;
376 }
377
378 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
379
380 void AliTPCBuffer160::UnpackWord(UInt_t PackedWord, Int_t StartBit, Int_t StopBit, UInt_t &Word){       
381   //Unpacks a word of StopBit-StartBit+1 bits from PackedWord buffer starting from the position 
382   //indicated by StartBit
383   UInt_t offSet;
384   Int_t length;
385   length=StopBit-StartBit+1;
386   offSet=(UInt_t)TMath::Power(2,length)-1;
387   offSet<<=StartBit;
388   Word=PackedWord&offSet;
389   Word>>=StartBit;
390   return;
391 }
392
393 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////