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