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 <TObjArray.h>
26 #include <Riostream.h>
31 ClassImp(AliTPCBuffer160)
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
44 //the buffer is cleaned
45 for (Int_t i=0;i<5;i++)fBuffer[i]=0;
46 //open the output file
48 f = new fstream(fileName,ios::binary|ios::out);
50 f = new fstream(fileName,ios::out);
56 f = new fstream(fileName,ios::binary|ios::in);
58 f = new fstream(fileName,ios::in);
60 if(!f){cout<<"File doesn't exist:"<<fileName<<endl;;exit(-1);}
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;
71 AliTPCBuffer160::AliTPCBuffer160(fstream* file, Int_t size){
72 //constructor for reading a file with mini header
80 fMiniHeaderPos=f->tellg();
81 f->seekg(fMiniHeaderPos+size);
82 fFilePosition=f->tellg();
83 fFileEnd=fFilePosition;
84 f->seekg(fMiniHeaderPos);
88 AliTPCBuffer160::~AliTPCBuffer160(){
91 //Flush out the Buffer content at the end only if Buffer wasn't completely filled
94 cout<<"File Created\n";
103 AliTPCBuffer160::AliTPCBuffer160(const AliTPCBuffer160 &source){
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];
118 AliTPCBuffer160& AliTPCBuffer160::operator=(const AliTPCBuffer160 &source){
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];
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;
142 if (f->tellg()>=(Int_t)fFileEnd) return -1;
143 if ( f->read((char*)fBuffer,sizeof(ULong_t)*5) ){
146 value=fBuffer[fCurrentCell]&mask;
148 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
155 value=fBuffer[fCurrentCell]&mask;
158 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
161 value=fBuffer[fCurrentCell]&mask;
163 temp=fBuffer[fCurrentCell];
168 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<(10-fShift);
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
184 if (fFilePosition>fMiniHeaderPos){
185 fFilePosition-=sizeof(ULong_t)*5;
186 f->seekg(fFilePosition);
187 f->read((char*)fBuffer,sizeof(ULong_t)*5);
189 //cout<<"Buffer letto"<<endl;
191 char* tt=(char*)fBuffer;
192 for(Int_t ii=0;ii<20;ii++){
194 cout<<ii<<"==> "<<(Int_t)*tt<<endl;
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;
208 value=fBuffer[fCurrentCell]&mask;
209 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
213 // f->seekg(fFileEnd);
214 f->seekg(fMiniHeaderPos);
220 value=fBuffer[fCurrentCell]&mask;
222 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
225 value=fBuffer[fCurrentCell];
227 temp=fBuffer[fCurrentCell]&mask;
228 temp=temp&fMaskBackward;
229 fMaskBackward=fMaskBackward>>2;
232 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>(10-fShift);
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++){
249 void AliTPCBuffer160::FillBuffer(Int_t Val){
250 //Fills the Buffer with 16 ten bits words and write into a file
254 Val=Val>>(10-fShift);
255 fBuffer[fCurrentCell]|=Val;
262 fBuffer[fCurrentCell]|=Val;
264 //Buffer is written into a file
265 f->write((char*)fBuffer,sizeof(ULong_t)*5);
267 for(Int_t j=0;j<5;j++)fBuffer[j]=0;
273 for(Int_t jj=0;jj<5;jj++){
274 cout.flags(ios::hex);
275 cout<<fBuffer[jj]<<endl;
276 cout.flags(ios::dec);
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++){
289 FillBuffer(WordsNumber);
290 FillBuffer(PadNumber);
291 FillBuffer(RowNumber);
292 FillBuffer(SecNumber);
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();
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
309 temp=GetNextBackWord();
311 if (temp==-1)return -1;
312 }while (temp==0x2AA);
315 RowNumber=GetNextBackWord();
316 PadNumber=GetNextBackWord();
317 WordsNumber=GetNextBackWord();
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
324 ULong_t miniHeader[3];
327 ddlNumber=SecNumber*2+SubSector;
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);
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;
343 f->write((char*)(miniHeader),miniHeaderSize);
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;
351 //cout<<"Mini Header Size:"<<miniHeader[0]<<endl;
352 f->write((char*)(miniHeader),miniHeaderSize);
353 f->seekp(currentFilePos);
359 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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;
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;
370 cout<<"WARNING::Word to be filled is not within desired length"<<endl;
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;
381 dummyWord<<=StartBit;
383 BaseWord=BaseWord&dummyWord;
387 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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
394 length=StopBit-StartBit+1;
395 offSet=(ULong_t)TMath::Power(2,length)-1;
397 Word=PackedWord&offSet;
402 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////