]>
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" |
b62e2a95 | 25 | #include <TObjArray.h> |
26 | #include <Riostream.h> | |
27 | #include <TMath.h> | |
2e9f335b | 28 | #include <stdlib.h> |
b62e2a95 | 29 | |
2e9f335b | 30 | |
31 | ClassImp(AliTPCBuffer160) | |
32 | ||
33 | AliTPCBuffer160::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 | ||
71 | AliTPCBuffer160::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 | ||
88 | AliTPCBuffer160::~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 | 103 | AliTPCBuffer160::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 | ||
119 | AliTPCBuffer160& 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 | ||
134 | Int_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 | ||
176 | Int_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 | ||
240 | void 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 | ||
250 | void 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 | ||
284 | void 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 | ||
296 | void 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 | ||
305 | Int_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 | 322 | void 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 | 362 | void 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 | 390 | void 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 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |