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