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>
27 #include <Riostream.h>
30 #include "AliTPCCompression.h"
31 #include "AliAltroBuffer.h"
32 #include "AliTPCAltroMapping.h"
33 #include "AliTPCDDLRawData.h"
34 #include "AliRawDataHeader.h"
36 ClassImp(AliTPCDDLRawData)
37 ////////////////////////////////////////////////////////////////////////////////////////
39 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source):
43 fVerbose=source.fVerbose;
47 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
49 fVerbose=source.fVerbose;
54 ////////////////////////////////////////////////////////////////////////////
55 void AliTPCDDLRawData::RawData(const char* inputFileName){
57 //Number of DDL=2*36+4*36=216
58 //2 DDL for each inner sector
59 //4 DDL for each outer sector
63 f.open(inputFileName,ios::binary);
65 f.open(inputFileName);
67 if(!f){Error("RawData", "File doesn't exist !!");return;}
78 //AliAltroBuffer is used in write mode to generate raw data file
81 AliAltroBuffer *buffer=NULL;
82 Int_t pSecNumber=-1; //Previous Sector number
83 Int_t pRowNumber=-1; //Previous Row number
84 Int_t pPadNumber=-1; //Previous Pad number
85 Int_t pTimeBin=-1; //Previous Time-Bin
86 Int_t pSubSector=-1; //Previous Sub Sector
91 TString path = gSystem->Getenv("ALICE_ROOT");
92 path += "/TPC/mapping/Patch";
94 AliTPCAltroMapping *mapping[6];
95 for(Int_t i = 0; i < 6; i++) {
99 mapping[i] = new AliTPCAltroMapping(path2.Data());
103 while (f.read((char*)(&data),sizeof(data))){
109 pSubSector=data.SubSec;
112 ddlNumber=data.Sec*2+data.SubSec;
114 ddlNumber=72+(data.Sec-36)*4+data.SubSec;
115 sprintf(filename,"TPC_%d.ddl",ddlNumber+kDDLOffset);
116 Int_t patchIndex = data.SubSec;
117 if(data.Sec>=36) patchIndex += 2;
118 buffer=new AliAltroBuffer(filename,1,mapping[patchIndex]);
119 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
120 buffer->WriteDataHeader(kTRUE,kFALSE);//Dummy;
122 buffer->FillBuffer(data.Dig-offset);
126 if ( (data.Time==(pTimeBin+1)) &&
127 (pPadNumber==data.Pad) &&
128 (pRowNumber==data.Row) &&
129 (pSecNumber==data.Sec)){
133 buffer->FillBuffer(pTimeBin);
134 buffer->FillBuffer(bunchLength+2);
136 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
137 //Trailer is formatted and inserted!!
138 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
142 if(pSubSector!=data.SubSec){
143 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
145 buffer->WriteDataHeader(kFALSE,kFALSE);
146 //cout<<"Data header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
150 ddlNumber=data.Sec*2+data.SubSec;
152 ddlNumber=72+(data.Sec-36)*4+data.SubSec;
153 sprintf(filename,"TPC_%d.ddl",ddlNumber+kDDLOffset);
154 Int_t patchIndex = data.SubSec;
155 if(data.Sec>=36) patchIndex += 2;
156 buffer=new AliAltroBuffer(filename,1,mapping[patchIndex]);
157 buffer->WriteDataHeader(kTRUE,kFALSE);//Dummy;
158 pSubSector=data.SubSec;
168 buffer->FillBuffer(data.Dig-offset);
173 buffer->FillBuffer(pTimeBin);
174 buffer->FillBuffer(bunchLength+2);
176 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
179 buffer->WriteDataHeader(kFALSE,kFALSE);
180 //cout<<"Data header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
184 for(Int_t i = 0; i < 6; i++) delete mapping[i];
189 ////////////////////////////////////////////////////////////////////////////
190 ////////////////////////////////////////////////////////////////////////////
193 Int_t AliTPCDDLRawData::RawDataCompDecompress(Bool_t compress){
194 //This method is used to compress and decompress the slides
195 static const Int_t kNumTables=5;
199 AliTPCCompression util;
202 for(Int_t i=0;i<216;i++){
203 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
205 f.open(filename,ios::binary|ios::in);
207 f.open(filename,ios::in);
209 #if defined(__HP_aCC) || defined(__DECCXX)
210 if(!f.rdbuf()->is_open()){f.clear(); continue;}
212 if(!f.is_open()){f.clear(); continue;}
215 Info("RawDataCompDecompress", "&s -> dest.ddl", filename);
218 fdest.open("dest.ddl",ios::binary);
220 fdest.open("dest.ddl");
222 //loop over the DDL block
223 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
224 //The number of block is ceil(216/LDCsNumber)
225 AliRawDataHeader header;
226 //here the Data Header is read
227 while( f.read((char*)(&header),sizeof(header)) ){
228 size=header.fSize-sizeof(header);
229 // cout<<"Data size:"<<size<<endl;
230 //Int_t dim=sizeof(UInt_t)+sizeof(Int_t)*5;
231 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
232 Bool_t compressed = header.TestAttribute(1);
233 if ((compressed && compress) ||
234 (!compressed && !compress)) continue;
235 //open the temporay File
237 char temp[15]="TempFile";
239 fo.open(temp,ios::binary);
244 for(UInt_t j=0;j<size;j++){
245 f.read((char*)(&car),1);
246 fo.write((char*)(&car),1);
249 //The temp file is compressed or decompressed
252 result=util.CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
255 result=util.DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
256 if (result != 0) break;
257 //the temp compressed file is open and copied to the final file fdest
260 fi.open("TempCompDecomp",ios::binary);
262 fi.open("TempCompDecomp");
264 fi.seekg(0,ios::end);
267 //The Data Header is updated (size and Compressed flag)
268 //and written into the output file
269 header.fSize=size+sizeof(header);
270 if (compress) header.SetAttribute(1);
271 else header.ResetAttribute(1);
272 fdest.write((char*)(&header),sizeof(header));
273 //The compressem temp file is copied into the output file fdest
274 for(UInt_t j=0;j<size;j++){
275 fi.read((char*)(&car),1);
276 fdest.write((char*)(&car),1);
284 remove("TempCompDecomp");
285 rename("dest.ddl",filename);
290 /////////////////////////////////////////////////////////////////////////////////
291 void AliTPCDDLRawData::RawDataAltro(const char* inputFileName, const char* outputFileName)const{
292 //This method is used to build the Altro format from AliTPCDDL.dat
293 //It is used to debug the code and creates the tables used in the compresseion phase
297 f.open(inputFileName,ios::binary);
299 f.open(inputFileName);
302 Error("RawDataAltro", "File doesn't exist !!");
315 TString path = gSystem->Getenv("ALICE_ROOT");
316 path += "/TPC/mapping/Patch";
318 AliTPCAltroMapping *mapping[6];
319 for(Int_t i = 0; i < 6; i++) {
323 mapping[i] = new AliTPCAltroMapping(path2.Data());
326 //AliAltroBuffer is used in write mode to generate AltroFormat.dat file
327 Info("RawDataAltro", "Creating &s", outputFileName);
328 AliAltroBuffer *buffer=new AliAltroBuffer(outputFileName,1);
331 Int_t pSecNumber=-1; //Previous Sector number
332 Int_t pSubSec=-1; //Previous sub Sector
333 Int_t pRowNumber=-1; //Previous Row number
334 Int_t pPadNumber=-1; //Previous Pad number
335 Int_t pTimeBin=-1; //Previous Time-Bin
339 while (f.read((char*)(&data),sizeof(data))){
348 buffer->FillBuffer(data.Dig-offset);
352 if ( (data.Time==(pTimeBin+1)) &&
353 (pPadNumber==data.Pad) &&
354 (pRowNumber==data.Row) &&
355 (pSecNumber==data.Sec)){
359 buffer->FillBuffer(pTimeBin);
360 buffer->FillBuffer(bunchLength+2);
362 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
363 //Trailer is formatted and inserted!!
364 Int_t patchIndex = pSubSec;
365 if(pSecNumber >= 36) patchIndex += 2;
366 buffer->SetMapping(mapping[patchIndex]);
367 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
378 buffer->FillBuffer(data.Dig-offset);
382 buffer->FillBuffer(pTimeBin);
383 buffer->FillBuffer(bunchLength+2);
385 Int_t patchIndex = pSubSec;
386 if(pSecNumber >= 36) patchIndex += 2;
387 buffer->SetMapping(mapping[patchIndex]);
388 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
390 Info("RawDataAltro", "Number of digits: %d", count);
392 for(Int_t i = 0; i < 6; i++) delete mapping[i];
398 /////////////////////////////////////////////////////////////////////////
399 void AliTPCDDLRawData::RawDataAltroDecode(const char* outputFileName){
400 //This method merges the slides in only one file removing at the same
401 //time all the data headers. The file so obtained must be Altro format
403 //It is used mainly in the debugging phase
409 fdest.open(outputFileName,ios::binary);
411 fdest.open(outputFileName);
414 AliRawDataHeader header;
415 for(Int_t i=0;i<216;i++){
416 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
418 f.open(filename,ios::binary|ios::in);
420 f.open(filename,ios::in);
423 //loop over the DDL block
424 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
425 while( (f.read((char*)(&header),sizeof(header))) ){
427 size=header.fSize-sizeof(header);
428 for(UInt_t j=0;j<size;j++){
429 f.read((char*)(&car),1);
430 fdest.write((char*)(&car),1);