1 /**************************************************************************
2 * Copyright(c) 1998-2003, 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 //This class conteins all the methods to create raw data
20 //It produces DDL with both compressed and uncompressed format.
21 //For compression we use the optimized table wich needs
24 #include <TObjArray.h>
25 #include <Riostream.h>
28 #include "AliTPCCompression.h"
29 #include "AliTPCBuffer160.h"
30 #include "AliTPCDDLRawData.h"
31 #include "AliRawDataHeader.h"
33 ClassImp(AliTPCDDLRawData)
34 ////////////////////////////////////////////////////////////////////////////////////////
36 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source):
40 fVerbose=source.fVerbose;
44 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
46 fVerbose=source.fVerbose;
51 ////////////////////////////////////////////////////////////////////////////
52 void AliTPCDDLRawData::RawData(const char* inputFileName){
54 //Number of DDL=2*36+4*36=216
55 //2 DDL for each inner sector
56 //4 DDL for each outer sector
60 f.open(inputFileName,ios::binary);
62 f.open(inputFileName);
64 if(!f){Error("RawData", "File doesn't exist !!");return;}
75 //AliTPCBuffer160 is used in write mode to generate raw data file
78 AliTPCBuffer160 *buffer=NULL;
79 Int_t pSecNumber=-1; //Previous Sector number
80 Int_t pRowNumber=-1; //Previous Row number
81 Int_t pPadNumber=-1; //Previous Pad number
82 Int_t pTimeBin=-1; //Previous Time-Bin
83 Int_t pSubSector=-1; //Previous Sub Sector
88 while (f.read((char*)(&data),sizeof(data))){
94 pSubSector=data.SubSec;
97 ddlNumber=data.Sec*2+data.SubSec;
99 ddlNumber=72+(data.Sec-36)*4+data.SubSec;
100 sprintf(filename,"TPC_%d.ddl",ddlNumber+kDDLOffset);
101 buffer=new AliTPCBuffer160(filename,1);
102 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
103 buffer->WriteDataHeader(kTRUE,kFALSE);//Dummy;
105 buffer->FillBuffer(data.Dig-offset);
109 if ( (data.Time==(pTimeBin+1)) &&
110 (pPadNumber==data.Pad) &&
111 (pRowNumber==data.Row) &&
112 (pSecNumber==data.Sec)){
116 buffer->FillBuffer(pTimeBin);
117 buffer->FillBuffer(bunchLength+2);
119 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
120 //Trailer is formatted and inserted!!
121 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
125 if(pSubSector!=data.SubSec){
126 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
128 buffer->WriteDataHeader(kFALSE,kFALSE);
129 //cout<<"Data header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
133 ddlNumber=data.Sec*2+data.SubSec;
135 ddlNumber=72+(data.Sec-36)*4+data.SubSec;
136 sprintf(filename,"TPC_%d.ddl",ddlNumber+kDDLOffset);
137 buffer=new AliTPCBuffer160(filename,1);
138 buffer->WriteDataHeader(kTRUE,kFALSE);//Dummy;
139 pSubSector=data.SubSec;
149 buffer->FillBuffer(data.Dig-offset);
154 buffer->FillBuffer(pTimeBin);
155 buffer->FillBuffer(bunchLength+2);
157 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
160 buffer->WriteDataHeader(kFALSE,kFALSE);
161 //cout<<"Data header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
167 ////////////////////////////////////////////////////////////////////////////
168 ////////////////////////////////////////////////////////////////////////////
171 Int_t AliTPCDDLRawData::RawDataCompDecompress(Bool_t compress){
172 //This method is used to compress and decompress the slides
173 static const Int_t kNumTables=5;
177 AliTPCCompression util;
180 for(Int_t i=0;i<216;i++){
181 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
183 f.open(filename,ios::binary|ios::in);
185 f.open(filename,ios::in);
187 #if defined(__HP_aCC) || defined(__DECCXX)
188 if(!f.rdbuf()->is_open()){f.clear(); continue;}
190 if(!f.is_open()){f.clear(); continue;}
193 Info("RawDataCompDecompress", "&s -> dest.ddl", filename);
196 fdest.open("dest.ddl",ios::binary);
198 fdest.open("dest.ddl");
200 //loop over the DDL block
201 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
202 //The number of block is ceil(216/LDCsNumber)
203 AliRawDataHeader header;
204 //here the Data Header is read
205 while( f.read((char*)(&header),sizeof(header)) ){
206 size=header.fSize-sizeof(header);
207 // cout<<"Data size:"<<size<<endl;
208 //Int_t dim=sizeof(UInt_t)+sizeof(Int_t)*5;
209 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
210 Bool_t compressed = header.TestAttribute(1);
211 if ((compressed && compress) ||
212 (!compressed && !compress)) continue;
213 //open the temporay File
215 char temp[15]="TempFile";
217 fo.open(temp,ios::binary);
222 for(UInt_t j=0;j<size;j++){
223 f.read((char*)(&car),1);
224 fo.write((char*)(&car),1);
227 //The temp file is compressed or decompressed
230 result=util.CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
233 result=util.DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
234 if (result != 0) break;
235 //the temp compressed file is open and copied to the final file fdest
238 fi.open("TempCompDecomp",ios::binary);
240 fi.open("TempCompDecomp");
242 fi.seekg(0,ios::end);
245 //The Data Header is updated (size and Compressed flag)
246 //and written into the output file
247 header.fSize=size+sizeof(header);
248 if (compress) header.SetAttribute(1);
249 else header.ResetAttribute(1);
250 fdest.write((char*)(&header),sizeof(header));
251 //The compressem temp file is copied into the output file fdest
252 for(UInt_t j=0;j<size;j++){
253 fi.read((char*)(&car),1);
254 fdest.write((char*)(&car),1);
262 remove("TempCompDecomp");
263 rename("dest.ddl",filename);
268 /////////////////////////////////////////////////////////////////////////////////
269 void AliTPCDDLRawData::RawDataAltro(const char* inputFileName, const char* outputFileName)const{
270 //This method is used to build the Altro format from AliTPCDDL.dat
271 //It is used to debug the code and creates the tables used in the compresseion phase
275 f.open(inputFileName,ios::binary);
277 f.open(inputFileName);
280 Error("RawDataAltro", "File doesn't exist !!");
293 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
294 Info("RawDataAltro", "Creating &s", outputFileName);
295 AliTPCBuffer160 *buffer=new AliTPCBuffer160(outputFileName,1);
298 Int_t pSecNumber=-1; //Previous Sector number
299 Int_t pRowNumber=-1; //Previous Row number
300 Int_t pPadNumber=-1; //Previous Pad number
301 Int_t pTimeBin=-1; //Previous Time-Bin
305 while (f.read((char*)(&data),sizeof(data))){
313 buffer->FillBuffer(data.Dig-offset);
317 if ( (data.Time==(pTimeBin+1)) &&
318 (pPadNumber==data.Pad) &&
319 (pRowNumber==data.Row) &&
320 (pSecNumber==data.Sec)){
324 buffer->FillBuffer(pTimeBin);
325 buffer->FillBuffer(bunchLength+2);
327 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
328 //Trailer is formatted and inserted!!
329 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
340 buffer->FillBuffer(data.Dig-offset);
344 buffer->FillBuffer(pTimeBin);
345 buffer->FillBuffer(bunchLength+2);
347 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
349 Info("RawDataAltro", "Number of digits: %d", count);
354 /////////////////////////////////////////////////////////////////////////
355 void AliTPCDDLRawData::RawDataAltroDecode(const char* outputFileName){
356 //This method merges the slides in only one file removing at the same
357 //time all the data headers. The file so obtained must be Altro format
359 //It is used mainly in the debugging phase
365 fdest.open(outputFileName,ios::binary);
367 fdest.open(outputFileName);
370 AliRawDataHeader header;
371 for(Int_t i=0;i<216;i++){
372 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
374 f.open(filename,ios::binary|ios::in);
376 f.open(filename,ios::in);
379 //loop over the DDL block
380 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
381 while( (f.read((char*)(&header),sizeof(header))) ){
383 size=header.fSize-sizeof(header);
384 for(UInt_t j=0;j<size;j++){
385 f.read((char*)(&car),1);
386 fdest.write((char*)(&car),1);