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