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