1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 #include "TObjArray.h"
17 #include "Riostream.h"
19 #include "AliTPCBuffer160.h"
22 ClassImp(AliTPCBuffer160)
24 AliTPCBuffer160::AliTPCBuffer160(const char* fileName,Int_t flag){
25 //if flag = 1 the actual object is used in the write mode
26 //if flag = 0 the actual object is used in the read mode
35 //the buffer is cleaned
36 for (Int_t i=0;i<5;i++)fBuffer[i]=0;
37 //open the output file
38 f.open(fileName,ios::binary|ios::out);
42 f.open(fileName,ios::binary|ios::in);
43 if(!f){cout<<"File doesn't exist\n";exit(-1);}
45 //To get the file dimension (position of the last element in term of bytes)
47 fFilePosition= f.tellg();
48 fFileEnd=fFilePosition;
53 AliTPCBuffer160::~AliTPCBuffer160(){
55 //Last Buffer filled couldn't be full
58 cout<<"File Created\n";
64 AliTPCBuffer160::AliTPCBuffer160(const AliTPCBuffer160 &source){
66 if(&source==this)return;
67 this->fShift=source.fShift;
68 this->fCurrentCell=source.fCurrentCell;
69 this->fFreeCellBuffer=source.fFreeCellBuffer;
70 this->fFlag=source.fFlag;
71 this->fMaskBackward=source.fMaskBackward;
72 this->fFilePosition=source.fFilePosition;
73 this->fMiniHeaderPos=source.fMiniHeaderPos;
74 this->fVerbose=source.fVerbose;
75 for (Int_t i=0;i<5;i++)this->fBuffer[i]=source.fBuffer[i];
79 AliTPCBuffer160& AliTPCBuffer160::operator=(const AliTPCBuffer160 &source){
81 if(&source==this)return *this;
82 this->fShift=source.fShift;
83 this->fCurrentCell=source.fCurrentCell;
84 this->fFreeCellBuffer=source.fFreeCellBuffer;
85 this->fFlag=source.fFlag;
86 this->fMaskBackward=source.fMaskBackward;
87 this->fFilePosition=source.fFilePosition;
88 this->fMiniHeaderPos=source.fMiniHeaderPos;
89 this->fVerbose=source.fVerbose;
90 for (Int_t i=0;i<5;i++)this->fBuffer[i]=source.fBuffer[i];
94 Int_t AliTPCBuffer160::GetNext(){
95 //If there aren't elements anymore -1 is returned otherwise
96 //the next element is returned
97 ULong_t Mask=0xFFC00000;
101 if ( f.read((char*)fBuffer,sizeof(ULong_t)*5) ){
104 Value=fBuffer[fCurrentCell]&Mask;
106 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
113 Value=fBuffer[fCurrentCell]&Mask;
116 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
119 Value=fBuffer[fCurrentCell]&Mask;
121 temp=fBuffer[fCurrentCell];
126 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<(10-fShift);
133 Int_t AliTPCBuffer160::GetNextBackWord(){
134 //If there aren't elements anymore -1 is returned otherwise
135 //the next element is returned
141 fFilePosition-=sizeof(ULong_t)*5;
142 f.seekg(fFilePosition);
143 f.read((char*)fBuffer,sizeof(ULong_t)*5);
147 Value=fBuffer[fCurrentCell]&Mask;
148 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
155 Value=fBuffer[fCurrentCell]&Mask;
157 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
160 Value=fBuffer[fCurrentCell];
162 temp=fBuffer[fCurrentCell]&Mask;
163 temp=temp&fMaskBackward;
164 fMaskBackward=fMaskBackward>>2;
167 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>(10-fShift);
174 void AliTPCBuffer160::Flush(){
175 if(fFreeCellBuffer!=16){
176 Int_t temp=fFreeCellBuffer;
177 for(Int_t i=0;i<temp;i++){
183 void AliTPCBuffer160::FillBuffer(Int_t Val){
184 //each value takes 10 bits
188 Val=Val>>(10-fShift);
189 fBuffer[fCurrentCell]|=Val;
196 fBuffer[fCurrentCell]|=Val;
198 //Buffer is written into a file
199 f.write((char*)fBuffer,sizeof(ULong_t)*5);
201 for(Int_t j=0;j<5;j++)fBuffer[j]=0;
207 for(Int_t jj=0;jj<5;jj++){
208 cout.flags(ios::hex);
209 cout<<fBuffer[jj]<<endl;
210 cout.flags(ios::dec);
217 void AliTPCBuffer160::WriteTrailer(Int_t WordsNumber,Int_t PadNumber,Int_t RowNumber,Int_t SecNumber){
218 Int_t num=fFreeCellBuffer%4;
219 for(Int_t i=0;i<num;i++){
222 FillBuffer(WordsNumber);
223 FillBuffer(PadNumber);
224 FillBuffer(RowNumber);
225 FillBuffer(SecNumber);
228 void AliTPCBuffer160::ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
229 WordsNumber=GetNext();
236 Int_t AliTPCBuffer160::ReadTrailerBackward(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
240 temp=GetNextBackWord();
242 if (temp==-1)return -1;
243 }while (temp==0x2AA);
246 RowNumber=GetNextBackWord();
247 PadNumber=GetNextBackWord();
248 WordsNumber=GetNextBackWord();
252 void AliTPCBuffer160::WriteMiniHeader(ULong_t Size,Int_t SecNumber,Int_t SubSector,Int_t Detector,Int_t Flag ){
253 //size msg errore sector number sub-sector number 0 for TPC 0 for uncompressed
255 ULong_t MiniHeader[3];
258 DDLNumber=SecNumber*2+SubSector;
260 DDLNumber=72+(SecNumber-36)*4+SubSector;
261 // cout<<"DDL number "<<DDLNumber<<endl;
262 for(Int_t i=0;i<3;i++)MiniHeader[i]=0;
263 Int_t MiniHeaderSize=(sizeof(ULong_t))*3;
264 PackWord(MiniHeader[1],Detector,0,7);
265 PackWord(MiniHeader[1],0x123456,8,31);
266 PackWord(MiniHeader[2],Version,0,7);
267 PackWord(MiniHeader[2],Flag,8,15);
268 PackWord(MiniHeader[2],DDLNumber,16,31);
270 //if size=0 it means that this mini header is a dummi mini header
271 fMiniHeaderPos=f.tellp();
272 //cout<<" Position of the DUMMY MH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl;
274 f.write((char*)(MiniHeader),MiniHeaderSize);
277 ULong_t CurrentFilePos=f.tellp();
278 f.seekp(fMiniHeaderPos);
279 Size=CurrentFilePos-fMiniHeaderPos-MiniHeaderSize;
280 //cout<<"Current Position (Next MH) "<<CurrentFilePos<<" Position of the MH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl;
282 //cout<<"Mini Header Size:"<<MiniHeader[0]<<endl;
283 f.write((char*)(MiniHeader),MiniHeaderSize);
284 f.seekp(CurrentFilePos);
290 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
292 void AliTPCBuffer160::PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit){
293 ULong_t DummyWord,OffSet;
296 //The BaseWord is being filled with 1 from StartBit to StopBit
297 Length=StopBit-StartBit+1;
298 Sum=(ULong_t)TMath::Power(2,Length)-1;
300 cout<<"WARNING::Word to be filled is not within desired length"<<endl;
305 BaseWord=BaseWord|OffSet;
306 //The Word to be filled is shifted to the position StartBit
307 //and the remaining Left and Right bits are filled with 1
308 Sum=(ULong_t)TMath::Power(2,StartBit)-1;
309 DummyWord=0xFFFFFFFF<<Length;
311 DummyWord<<=StartBit;
313 BaseWord=BaseWord&DummyWord;
317 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
319 void AliTPCBuffer160::UnpackWord(ULong_t PackedWord, Int_t StartBit, Int_t StopBit, ULong_t &Word){
322 Length=StopBit-StartBit+1;
323 OffSet=(ULong_t)TMath::Power(2,Length)-1;
325 Word=PackedWord&OffSet;
330 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////