1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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
24 #include "AliTPCBuffer160.h"
25 #include "AliRawDataHeader.h"
26 #include <TObjArray.h>
27 #include <Riostream.h>
32 ClassImp(AliTPCBuffer160)
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
45 //the buffer is cleaned
46 for (Int_t i=0;i<5;i++)fBuffer[i]=0;
47 //open the output file
49 f = new fstream(fileName,ios::binary|ios::out);
51 f = new fstream(fileName,ios::out);
57 f = new fstream(fileName,ios::binary|ios::in);
59 f = new fstream(fileName,ios::in);
62 Error("AliTPCBuffer160", "File doesn't exist: %s", fileName);
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;
75 AliTPCBuffer160::AliTPCBuffer160(fstream* file, Int_t size){
76 //constructor for reading a file
84 fDataHeaderPos=f->tellg();
85 f->seekg(fDataHeaderPos+size);
86 fFilePosition=f->tellg();
87 fFileEnd=fFilePosition;
88 f->seekg(fDataHeaderPos);
92 AliTPCBuffer160::~AliTPCBuffer160(){
95 //Flush out the Buffer content at the end only if Buffer wasn't completely filled
98 Info("~AliTPCBuffer160", "File Created");
107 AliTPCBuffer160::AliTPCBuffer160(const AliTPCBuffer160 &source)
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];
123 AliTPCBuffer160& AliTPCBuffer160::operator=(const AliTPCBuffer160 &source){
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];
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;
147 if (f->tellg()>=(Int_t)fFileEnd) return -1;
148 if ( f->read((char*)fBuffer,sizeof(UInt_t)*5) ){
151 value=fBuffer[fCurrentCell]&mask;
153 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
160 value=fBuffer[fCurrentCell]&mask;
163 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
166 value=fBuffer[fCurrentCell]&mask;
168 temp=fBuffer[fCurrentCell];
173 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<(10-fShift);
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
189 if (fFilePosition>fDataHeaderPos){
190 fFilePosition-=sizeof(UInt_t)*5;
191 f->seekg(fFilePosition);
192 f->read((char*)fBuffer,sizeof(UInt_t)*5);
194 //cout<<"Buffer letto"<<endl;
196 char* tt=(char*)fBuffer;
197 for(Int_t ii=0;ii<20;ii++){
199 cout<<ii<<"==> "<<(Int_t)*tt<<endl;
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;
213 value=fBuffer[fCurrentCell]&mask;
214 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
218 // f->seekg(fFileEnd);
219 f->seekg(fDataHeaderPos);
225 value=fBuffer[fCurrentCell]&mask;
227 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
230 value=fBuffer[fCurrentCell];
232 temp=fBuffer[fCurrentCell]&mask;
233 temp=temp&fMaskBackward;
234 fMaskBackward=fMaskBackward>>2;
237 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>(10-fShift);
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++){
254 void AliTPCBuffer160::FillBuffer(Int_t Val){
255 //Fills the Buffer with 16 ten bits words and write into a file
259 Val=Val>>(10-fShift);
260 fBuffer[fCurrentCell]|=Val;
267 fBuffer[fCurrentCell]|=Val;
269 //Buffer is written into a file
270 f->write((char*)fBuffer,sizeof(UInt_t)*5);
272 for(Int_t j=0;j<5;j++)fBuffer[j]=0;
278 for(Int_t jj=0;jj<5;jj++){
279 cout.flags(ios::hex);
280 cout<<fBuffer[jj]<<endl;
281 cout.flags(ios::dec);
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++){
294 FillBuffer(WordsNumber);
295 FillBuffer(PadNumber);
296 FillBuffer(RowNumber);
297 FillBuffer(SecNumber);
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();
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
314 temp=GetNextBackWord();
316 if (temp==-1)return -1;
317 }while (temp==0x2AA);
320 RowNumber=GetNextBackWord();
321 PadNumber=GetNextBackWord();
322 WordsNumber=GetNextBackWord();
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;
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));
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);
350 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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;
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;
361 Error("PackWord", "Word to be filled is not within desired length");
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;
372 dummyWord<<=StartBit;
374 BaseWord=BaseWord&dummyWord;
378 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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
385 length=StopBit-StartBit+1;
386 offSet=(UInt_t)TMath::Power(2,length)-1;
388 Word=PackedWord&offSet;
393 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////