]>
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 | ||
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 | |
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 |
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 | ||
70 | AliTPCBuffer160::~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 | ||
82 | AliTPCBuffer160::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 | ||
97 | AliTPCBuffer160& 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 | ||
112 | Int_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 | ||
153 | Int_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 | ||
213 | void 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 | ||
223 | void 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 | ||
257 | void 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 | ||
269 | void 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 | ||
278 | Int_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 | ||
295 | void 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 | ||
335 | void 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 | ||
363 | void 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 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |