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