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