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 **************************************************************************/
18 // Interface to the Altro format
19 // to read and write digits
20 // To be used in Alice Data Challenges
21 // and in the compression of the RAW data
24 #include "TObjArray.h"
25 #include "Riostream.h"
27 #include "AliTPCBuffer160.h"
30 ClassImp(AliTPCBuffer160)
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
43 //the buffer is cleaned
44 for (Int_t i=0;i<5;i++)fBuffer[i]=0;
45 //open the output file
47 f.open(fileName,ios::binary|ios::out);
49 f.open(fileName,ios::out);
55 f.open(fileName,ios::binary|ios::in);
57 f.open(fileName,ios::in);
59 if(!f){cout<<"File doesn't exist\n";exit(-1);}
61 //To get the file dimension (position of the last element in term of bytes)
63 fFilePosition= f.tellg();
64 fFileEnd=fFilePosition;
69 AliTPCBuffer160::~AliTPCBuffer160(){
72 //Flush out the Buffer content at the end only if Buffer wasn't completely filled
75 cout<<"File Created\n";
81 AliTPCBuffer160::AliTPCBuffer160(const AliTPCBuffer160 &source){
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];
96 AliTPCBuffer160& AliTPCBuffer160::operator=(const AliTPCBuffer160 &source){
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];
111 Int_t AliTPCBuffer160::GetNext(){
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.
114 //If there aren't elements anymore -1 is returned otherwise
115 //the next element is returned
116 ULong_t mask=0xFFC00000;
120 if ( f.read((char*)fBuffer,sizeof(ULong_t)*5) ){
123 value=fBuffer[fCurrentCell]&mask;
125 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
132 value=fBuffer[fCurrentCell]&mask;
135 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
138 value=fBuffer[fCurrentCell]&mask;
140 temp=fBuffer[fCurrentCell];
145 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<(10-fShift);
152 Int_t AliTPCBuffer160::GetNextBackWord(){
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.
155 //If there aren't elements anymore -1 is returned otherwise
156 //the next element is returned
162 fFilePosition-=sizeof(ULong_t)*5;
163 f.seekg(fFilePosition);
164 f.read((char*)fBuffer,sizeof(ULong_t)*5);
168 value=fBuffer[fCurrentCell]&mask;
169 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
176 value=fBuffer[fCurrentCell]&mask;
178 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
181 value=fBuffer[fCurrentCell];
183 temp=fBuffer[fCurrentCell]&mask;
184 temp=temp&fMaskBackward;
185 fMaskBackward=fMaskBackward>>2;
188 fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>(10-fShift);
195 void AliTPCBuffer160::Flush(){
196 // Flushes the Buffer content
197 if(fFreeCellBuffer!=16){
198 Int_t temp=fFreeCellBuffer;
199 for(Int_t i=0;i<temp;i++){
205 void AliTPCBuffer160::FillBuffer(Int_t Val){
206 //Fills the Buffer with 16 ten bits words and write into a file
210 Val=Val>>(10-fShift);
211 fBuffer[fCurrentCell]|=Val;
218 fBuffer[fCurrentCell]|=Val;
220 //Buffer is written into a file
221 f.write((char*)fBuffer,sizeof(ULong_t)*5);
223 for(Int_t j=0;j<5;j++)fBuffer[j]=0;
229 for(Int_t jj=0;jj<5;jj++){
230 cout.flags(ios::hex);
231 cout<<fBuffer[jj]<<endl;
232 cout.flags(ios::dec);
239 void AliTPCBuffer160::WriteTrailer(Int_t WordsNumber,Int_t PadNumber,Int_t RowNumber,Int_t SecNumber){
240 //Writes a trailer of 40 bits
241 Int_t num=fFreeCellBuffer%4;
242 for(Int_t i=0;i<num;i++){
245 FillBuffer(WordsNumber);
246 FillBuffer(PadNumber);
247 FillBuffer(RowNumber);
248 FillBuffer(SecNumber);
251 void AliTPCBuffer160::ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
252 //Read a trailer of 40 bits in the forward reading mode
253 WordsNumber=GetNext();
260 Int_t AliTPCBuffer160::ReadTrailerBackward(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
261 //Read a trailer of 40 bits in the backward reading mode
265 temp=GetNextBackWord();
267 if (temp==-1)return -1;
268 }while (temp==0x2AA);
271 RowNumber=GetNextBackWord();
272 PadNumber=GetNextBackWord();
273 WordsNumber=GetNextBackWord();
277 void AliTPCBuffer160::WriteMiniHeader(ULong_t Size,Int_t SecNumber,Int_t SubSector,Int_t Detector,Int_t Flag ){
278 //Size msg errore sector number sub-sector number 0 for TPC 0 for uncompressed
280 ULong_t miniHeader[3];
283 ddlNumber=SecNumber*2+SubSector;
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);
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;
299 f.write((char*)(miniHeader),miniHeaderSize);
302 ULong_t currentFilePos=f.tellp();
303 f.seekp(fMiniHeaderPos);
304 Size=currentFilePos-fMiniHeaderPos-miniHeaderSize;
305 //cout<<"Current Position (Next MH) "<<currentFilePos<<" Position of the MH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl;
307 //cout<<"Mini Header Size:"<<miniHeader[0]<<endl;
308 f.write((char*)(miniHeader),miniHeaderSize);
309 f.seekp(currentFilePos);
315 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
317 void AliTPCBuffer160::PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit){
318 //Packs a word into the BaseWord buffer from StartBit bit up to StopBit bit
319 ULong_t dummyWord,offSet;
322 //The BaseWord is being filled with 1 from StartBit to StopBit
323 length=StopBit-StartBit+1;
324 sum=(ULong_t)TMath::Power(2,length)-1;
326 cout<<"WARNING::Word to be filled is not within desired length"<<endl;
331 BaseWord=BaseWord|offSet;
332 //The Word to be filled is shifted to the position StartBit
333 //and the remaining Left and Right bits are filled with 1
334 sum=(ULong_t)TMath::Power(2,StartBit)-1;
335 dummyWord=0xFFFFFFFF<<length;
337 dummyWord<<=StartBit;
339 BaseWord=BaseWord&dummyWord;
343 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
345 void AliTPCBuffer160::UnpackWord(ULong_t PackedWord, Int_t StartBit, Int_t StopBit, ULong_t &Word){
346 //Unpacks a word of StopBit-StartBit+1 bits from PackedWord buffer starting from the position
347 //indicated by StartBit
350 length=StopBit-StartBit+1;
351 offSet=(ULong_t)TMath::Power(2,length)-1;
353 Word=PackedWord&offSet;
358 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////