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(!f.is_open()){f.clear(); continue;}
189 Info("RawDataCompDecompress", "&s -> dest.ddl", filename);
192 fdest.open("dest.ddl",ios::binary);
194 fdest.open("dest.ddl");
196 //loop over the DDL block
197 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
198 //The number of block is ceil(216/LDCsNumber)
199 AliRawDataHeader header;
200 //here the Data Header is read
201 while( f.read((char*)(&header),sizeof(header)) ){
202 size=header.fSize-sizeof(header);
203 // cout<<"Data size:"<<size<<endl;
204 //Int_t dim=sizeof(UInt_t)+sizeof(Int_t)*5;
205 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
206 Bool_t compressed = header.TestAttribute(1);
207 if ((compressed && compress) ||
208 (!compressed && !compress)) continue;
209 //open the temporay File
211 char temp[15]="TempFile";
213 fo.open(temp,ios::binary);
218 for(UInt_t j=0;j<size;j++){
219 f.read((char*)(&car),1);
220 fo.write((char*)(&car),1);
223 //The temp file is compressed or decompressed
226 result=util.CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
229 result=util.DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
230 if (result != 0) break;
231 //the temp compressed file is open and copied to the final file fdest
234 fi.open("TempCompDecomp",ios::binary);
236 fi.open("TempCompDecomp");
238 fi.seekg(0,ios::end);
241 //The Data Header is updated (size and Compressed flag)
242 //and written into the output file
243 header.fSize=size+sizeof(header);
244 if (compress) header.SetAttribute(1);
245 else header.ResetAttribute(1);
246 fdest.write((char*)(&header),sizeof(header));
247 //The compressem temp file is copied into the output file fdest
248 for(UInt_t j=0;j<size;j++){
249 fi.read((char*)(&car),1);
250 fdest.write((char*)(&car),1);
258 remove("TempCompDecomp");
259 rename("dest.ddl",filename);
264 /////////////////////////////////////////////////////////////////////////////////
265 void AliTPCDDLRawData::RawDataAltro(const char* inputFileName, const char* outputFileName)const{
266 //This method is used to build the Altro format from AliTPCDDL.dat
267 //It is used to debug the code and creates the tables used in the compresseion phase
271 f.open(inputFileName,ios::binary);
273 f.open(inputFileName);
276 Error("RawDataAltro", "File doesn't exist !!");
289 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
290 Info("RawDataAltro", "Creating &s", outputFileName);
291 AliTPCBuffer160 *buffer=new AliTPCBuffer160(outputFileName,1);
294 Int_t pSecNumber=-1; //Previous Sector number
295 Int_t pRowNumber=-1; //Previous Row number
296 Int_t pPadNumber=-1; //Previous Pad number
297 Int_t pTimeBin=-1; //Previous Time-Bin
301 while (f.read((char*)(&data),sizeof(data))){
309 buffer->FillBuffer(data.Dig-offset);
313 if ( (data.Time==(pTimeBin+1)) &&
314 (pPadNumber==data.Pad) &&
315 (pRowNumber==data.Row) &&
316 (pSecNumber==data.Sec)){
320 buffer->FillBuffer(pTimeBin);
321 buffer->FillBuffer(bunchLength+2);
323 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
324 //Trailer is formatted and inserted!!
325 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
336 buffer->FillBuffer(data.Dig-offset);
340 buffer->FillBuffer(pTimeBin);
341 buffer->FillBuffer(bunchLength+2);
343 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
345 Info("RawDataAltro", "Number of digits: %d", count);
350 /////////////////////////////////////////////////////////////////////////
351 void AliTPCDDLRawData::RawDataAltroDecode(const char* outputFileName){
352 //This method merges the slides in only one file removing at the same
353 //time all the data headers. The file so obtained must be Altro format
355 //It is used mainly in the debugging phase
361 fdest.open(outputFileName,ios::binary);
363 fdest.open(outputFileName);
366 AliRawDataHeader header;
367 for(Int_t i=0;i<216;i++){
368 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
370 f.open(filename,ios::binary|ios::in);
372 f.open(filename,ios::in);
375 //loop over the DDL block
376 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
377 while( (f.read((char*)(&header),sizeof(header))) ){
379 size=header.fSize-sizeof(header);
380 for(UInt_t j=0;j<size;j++){
381 f.read((char*)(&car),1);
382 fdest.write((char*)(&car),1);