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