]>
Commit | Line | Data |
---|---|---|
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 | |
32 | ClassImp(AliTPCBuffer160) | |
33 | ||
34 | AliTPCBuffer160::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 | ||
75 | AliTPCBuffer160::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 | ||
92 | AliTPCBuffer160::~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 | 107 | AliTPCBuffer160::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 | ||
123 | AliTPCBuffer160& 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 | ||
138 | Int_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 | ||
180 | Int_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 | ||
244 | void 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 | ||
254 | void 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 | ||
288 | void 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 | ||
300 | void 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 | ||
309 | Int_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 | 326 | void 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 | 352 | void 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 | 380 | void 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 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |