]>
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 | |
2e9f335b | 59 | if(!f){cout<<"File doesn't exist\n";exit(-1);} |
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); | |
165 | fCurrentCell=4; | |
166 | fShift=22; | |
167 | fMaskBackward=0xFF; | |
7c27857f | 168 | value=fBuffer[fCurrentCell]&mask; |
2e9f335b | 169 | fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10; |
7c27857f | 170 | return value; |
2e9f335b | 171 | } |
172 | else return -1; | |
173 | }//end if | |
174 | else{ | |
175 | if (fShift>=10){ | |
7c27857f | 176 | value=fBuffer[fCurrentCell]&mask; |
2e9f335b | 177 | fShift-=10; |
178 | fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10; | |
179 | } | |
180 | else{ | |
7c27857f | 181 | value=fBuffer[fCurrentCell]; |
2e9f335b | 182 | fCurrentCell--; |
7c27857f | 183 | temp=fBuffer[fCurrentCell]&mask; |
2e9f335b | 184 | temp=temp&fMaskBackward; |
185 | fMaskBackward=fMaskBackward>>2; | |
186 | temp=temp<<fShift; | |
7c27857f | 187 | value=value|temp; |
2e9f335b | 188 | fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>(10-fShift); |
189 | fShift=22+fShift; | |
190 | } | |
7c27857f | 191 | return value; |
2e9f335b | 192 | }//end else |
193 | } | |
194 | ||
195 | void AliTPCBuffer160::Flush(){ | |
a79660fb | 196 | // Flushes the Buffer content |
2e9f335b | 197 | if(fFreeCellBuffer!=16){ |
198 | Int_t temp=fFreeCellBuffer; | |
199 | for(Int_t i=0;i<temp;i++){ | |
200 | FillBuffer(0x2AA); | |
201 | }//end for | |
202 | }//end if | |
203 | } | |
204 | ||
205 | void AliTPCBuffer160::FillBuffer(Int_t Val){ | |
a79660fb | 206 | //Fills the Buffer with 16 ten bits words and write into a file |
2e9f335b | 207 | fFreeCellBuffer--; |
208 | if (fShift<10){ | |
209 | Int_t temp=Val; | |
210 | Val=Val>>(10-fShift); | |
211 | fBuffer[fCurrentCell]|=Val; | |
212 | fCurrentCell++; | |
213 | fShift+=32; | |
214 | Val=temp; | |
215 | } | |
216 | fShift-=10; | |
217 | Val=Val<<fShift; | |
218 | fBuffer[fCurrentCell]|=Val; | |
219 | if(!fShift){ | |
220 | //Buffer is written into a file | |
221 | f.write((char*)fBuffer,sizeof(ULong_t)*5); | |
222 | //Buffer is empty | |
223 | for(Int_t j=0;j<5;j++)fBuffer[j]=0; | |
224 | fShift=32; | |
225 | fCurrentCell=0; | |
226 | fFreeCellBuffer=16; | |
227 | } | |
228 | /* | |
229 | for(Int_t jj=0;jj<5;jj++){ | |
230 | cout.flags(ios::hex); | |
231 | cout<<fBuffer[jj]<<endl; | |
232 | cout.flags(ios::dec); | |
233 | } | |
234 | ||
235 | */ | |
236 | return; | |
237 | } | |
238 | ||
239 | void AliTPCBuffer160::WriteTrailer(Int_t WordsNumber,Int_t PadNumber,Int_t RowNumber,Int_t SecNumber){ | |
a79660fb | 240 | //Writes a trailer of 40 bits |
2e9f335b | 241 | Int_t num=fFreeCellBuffer%4; |
242 | for(Int_t i=0;i<num;i++){ | |
243 | FillBuffer(0x2AA); | |
244 | }//end for | |
245 | FillBuffer(WordsNumber); | |
246 | FillBuffer(PadNumber); | |
247 | FillBuffer(RowNumber); | |
248 | FillBuffer(SecNumber); | |
249 | } | |
250 | ||
251 | void AliTPCBuffer160::ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){ | |
a79660fb | 252 | //Read a trailer of 40 bits in the forward reading mode |
2e9f335b | 253 | WordsNumber=GetNext(); |
254 | PadNumber=GetNext(); | |
255 | RowNumber=GetNext(); | |
256 | SecNumber=GetNext(); | |
257 | } | |
258 | ||
259 | ||
260 | Int_t AliTPCBuffer160::ReadTrailerBackward(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){ | |
a79660fb | 261 | //Read a trailer of 40 bits in the backward reading mode |
2e9f335b | 262 | Int_t temp; |
7c27857f | 263 | fEndingFillWords=0; |
2e9f335b | 264 | do{ |
265 | temp=GetNextBackWord(); | |
7c27857f | 266 | fEndingFillWords++; |
2e9f335b | 267 | if (temp==-1)return -1; |
268 | }while (temp==0x2AA); | |
7c27857f | 269 | fEndingFillWords--; |
2e9f335b | 270 | SecNumber=temp; |
271 | RowNumber=GetNextBackWord(); | |
272 | PadNumber=GetNextBackWord(); | |
273 | WordsNumber=GetNextBackWord(); | |
274 | return 0; | |
275 | } | |
276 | ||
277 | void AliTPCBuffer160::WriteMiniHeader(ULong_t Size,Int_t SecNumber,Int_t SubSector,Int_t Detector,Int_t Flag ){ | |
a79660fb | 278 | //Size msg errore sector number sub-sector number 0 for TPC 0 for uncompressed |
7c27857f | 279 | Int_t ddlNumber; |
280 | ULong_t miniHeader[3]; | |
281 | Int_t version=1; | |
2e9f335b | 282 | if(SecNumber<36) |
7c27857f | 283 | ddlNumber=SecNumber*2+SubSector; |
2e9f335b | 284 | else |
7c27857f | 285 | ddlNumber=72+(SecNumber-36)*4+SubSector; |
286 | // cout<<"DDL number "<<ddlNumber<<endl; | |
287 | for(Int_t i=0;i<3;i++)miniHeader[i]=0; | |
288 | Int_t miniHeaderSize=(sizeof(ULong_t))*3; | |
289 | PackWord(miniHeader[1],Detector,0,7); | |
290 | PackWord(miniHeader[1],0x123456,8,31); | |
291 | PackWord(miniHeader[2],version,0,7); | |
292 | PackWord(miniHeader[2],Flag,8,15); | |
293 | PackWord(miniHeader[2],ddlNumber,16,31); | |
2e9f335b | 294 | if (!Size){ |
295 | //if size=0 it means that this mini header is a dummi mini header | |
296 | fMiniHeaderPos=f.tellp(); | |
297 | //cout<<" Position of the DUMMY MH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl; | |
7c27857f | 298 | miniHeader[0]=Size; |
299 | f.write((char*)(miniHeader),miniHeaderSize); | |
2e9f335b | 300 | }//end if |
301 | else{ | |
7c27857f | 302 | ULong_t currentFilePos=f.tellp(); |
2e9f335b | 303 | f.seekp(fMiniHeaderPos); |
7c27857f | 304 | Size=currentFilePos-fMiniHeaderPos-miniHeaderSize; |
305 | //cout<<"Current Position (Next MH) "<<currentFilePos<<" Position of the MH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl; | |
306 | miniHeader[0]=Size; | |
307 | //cout<<"Mini Header Size:"<<miniHeader[0]<<endl; | |
308 | f.write((char*)(miniHeader),miniHeaderSize); | |
309 | f.seekp(currentFilePos); | |
2e9f335b | 310 | } |
311 | return; | |
312 | } | |
313 | ||
314 | ||
315 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
316 | ||
317 | void AliTPCBuffer160::PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit){ | |
a79660fb | 318 | //Packs a word into the BaseWord buffer from StartBit bit up to StopBit bit |
7c27857f | 319 | ULong_t dummyWord,offSet; |
320 | Int_t length; | |
321 | ULong_t sum; | |
2e9f335b | 322 | //The BaseWord is being filled with 1 from StartBit to StopBit |
7c27857f | 323 | length=StopBit-StartBit+1; |
324 | sum=(ULong_t)TMath::Power(2,length)-1; | |
325 | if(Word > sum){ | |
2e9f335b | 326 | cout<<"WARNING::Word to be filled is not within desired length"<<endl; |
327 | exit(-1); | |
328 | } | |
7c27857f | 329 | offSet=sum; |
330 | offSet<<=StartBit; | |
331 | BaseWord=BaseWord|offSet; | |
2e9f335b | 332 | //The Word to be filled is shifted to the position StartBit |
333 | //and the remaining Left and Right bits are filled with 1 | |
7c27857f | 334 | sum=(ULong_t)TMath::Power(2,StartBit)-1; |
335 | dummyWord=0xFFFFFFFF<<length; | |
336 | dummyWord +=Word; | |
337 | dummyWord<<=StartBit; | |
338 | dummyWord+=sum; | |
339 | BaseWord=BaseWord&dummyWord; | |
2e9f335b | 340 | return; |
341 | } | |
342 | ||
343 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
344 | ||
345 | void AliTPCBuffer160::UnpackWord(ULong_t PackedWord, Int_t StartBit, Int_t StopBit, ULong_t &Word){ | |
a79660fb | 346 | //Unpacks a word of StopBit-StartBit+1 bits from PackedWord buffer starting from the position |
347 | //indicated by StartBit | |
7c27857f | 348 | ULong_t offSet; |
349 | Int_t length; | |
350 | length=StopBit-StartBit+1; | |
351 | offSet=(ULong_t)TMath::Power(2,length)-1; | |
352 | offSet<<=StartBit; | |
353 | Word=PackedWord&offSet; | |
2e9f335b | 354 | Word>>=StartBit; |
355 | return; | |
356 | } | |
357 | ||
358 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |