]>
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 | ||
2e9f335b | 24 | #include "TObjArray.h" |
25 | #include "Riostream.h" | |
26 | #include <stdlib.h> | |
27 | #include "AliTPCBuffer160.h" | |
0f0615a3 | 28 | #include "TMath.h" |
2e9f335b | 29 | |
30 | ClassImp(AliTPCBuffer160) | |
31 | ||
32 | AliTPCBuffer160::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 | ||
69 | AliTPCBuffer160::~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 | ||
81 | AliTPCBuffer160::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 | ||
96 | AliTPCBuffer160& 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 | ||
111 | Int_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 | ||
152 | Int_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 | ||
212 | void 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 | ||
222 | void 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 | ||
256 | void 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 | ||
268 | void 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 | ||
277 | Int_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 | ||
294 | void 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 | ||
334 | void 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 | ||
362 | void 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 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |