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"
32 ClassImp(AliTPCDDLRawData)
33 ////////////////////////////////////////////////////////////////////////////////////////
35 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
37 fVerbose=source.fVerbose;
41 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
43 fVerbose=source.fVerbose;
48 ////////////////////////////////////////////////////////////////////////////
49 void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
50 //Raw data slides generation
51 //Number of DDL=2*36+4*36=216
52 //2 DDL for each inner sector
53 //4 DDL for each outer sector
54 Int_t ddlPerFile=216/LDCsNumber;
56 if (216%LDCsNumber) ddlPerFile++;
57 cout<<"Number of DDL per slide: "<<ddlPerFile<<endl;
60 f.open("AliTPCDDL.dat",ios::binary);
62 f.open("AliTPCDDL.dat");
64 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
75 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
78 sprintf(filename,"TPCslice%d",sliceNumber);
79 cout<<" Creating "<<filename<<endl;
80 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
83 Int_t pSecNumber=-1; //Previous Sector number
84 Int_t pRowNumber=-1; //Previous Row number
85 Int_t pPadNumber=-1; //Previous Pad number
86 Int_t pTimeBin=-1; //Previous Time-Bin
87 Int_t pSubSector=-1; //Previous Sub Sector
92 while (f.read((char*)(&data),sizeof(data))){
99 pSubSector=data.SubSec;
100 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
101 buffer->WriteMiniHeader(0,pSecNumber,pSubSector,0,0);//Dummy;
103 buffer->FillBuffer(data.Dig-offset);
107 if ( (data.Time==(pTimeBin+1)) &&
108 (pPadNumber==data.Pad) &&
109 (pRowNumber==data.Row) &&
110 (pSecNumber==data.Sec)){
114 buffer->FillBuffer(pTimeBin);
115 buffer->FillBuffer(bunchLength+2);
117 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
118 //Trailer is formatted and inserted!!
119 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
123 if(pSubSector!=data.SubSec){
125 if(countDDL==ddlPerFile){
126 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
128 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
129 //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
132 sprintf(filename,"TPCslice%d",sliceNumber);
133 cout<<" Creating "<<filename<<endl;
134 buffer=new AliTPCBuffer160(filename,1);
135 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
140 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
141 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
143 pSubSector=data.SubSec;
153 buffer->FillBuffer(data.Dig-offset);
157 buffer->FillBuffer(pTimeBin);
158 buffer->FillBuffer(bunchLength+2);
160 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
163 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
164 //cout<<"Mini header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
166 cout<<"Number of digits: "<<count<<endl;
170 ////////////////////////////////////////////////////////////////////////////
171 ////////////////////////////////////////////////////////////////////////////
174 Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
175 //This method is used to compress and decompress the slides
176 static const Int_t kNumTables=5;
181 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
183 for(Int_t i=1;i<=LDCsNumber;i++){
185 sprintf(filename,"TPCslice%d",i);
186 sprintf(dest,"TPCslice%d.comp",i);
189 sprintf(filename,"TPCslice%d.comp",i);
190 sprintf(dest,"TPCslice%d.decomp",i);
193 f.open(filename,ios::binary|ios::in);
195 f.open(filename,ios::in);
197 if(!f){cout<<"BE CAREFUL!! There isn't enough data to generate "<<LDCsNumber<<" slices"<<endl;break;}
198 cout<<filename<<" "<<dest<<endl;
201 fdest.open(dest,ios::binary);
205 //loop over the DDL block
206 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
207 //The number of block is ceil(216/LDCsNumber)
208 ULong_t miniHeader[3];
209 //here the Mini Header is read
210 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
212 // cout<<"Data size:"<<size<<endl;
213 //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
214 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
215 //open the temporay File
217 char temp[15]="TempFile";
219 fo.open(temp,ios::binary);
224 for(ULong_t j=0;j<size;j++){
225 f.read((char*)(&car),1);
226 fo.write((char*)(&car),1);
229 //The temp file is compressed or decompressed
230 AliTPCCompression *util = new AliTPCCompression();
233 util->CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
236 util->DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
238 //the temp compressed file is open and copied to the final file fdest
241 fi.open("TempCompDecomp",ios::binary);
243 fi.open("TempCompDecomp");
245 fi.seekg(0,ios::end);
248 //The Mini Header is updated (size and Compressed flag)
249 //and written into the output file
258 miniHeader[2]=miniHeader[2]|aux;
259 fdest.write((char*)(miniHeader),sizeof(ULong_t)*3);
260 //The compressem temp file is copied into the output file fdest
261 for(ULong_t j=0;j<size;j++){
262 fi.read((char*)(&car),1);
263 fdest.write((char*)(&car),1);
271 remove("TempCompDecomp");
276 /////////////////////////////////////////////////////////////////////////////////
277 void AliTPCDDLRawData::RawDataAltro()const{
278 //This method is used to build the Altro format from AliTPCDDL.dat
279 //It is used to debug the code and creates the tables used in the compresseion phase
283 f.open("AliTPCDDL.dat",ios::binary);
285 f.open("AliTPCDDL.dat");
287 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
298 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
299 char filename[30]="AltroFormatDDL.dat";
300 cout<<" Creating "<<filename<<endl;
301 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
304 Int_t pSecNumber=-1; //Previous Sector number
305 Int_t pRowNumber=-1; //Previous Row number
306 Int_t pPadNumber=-1; //Previous Pad number
307 Int_t pTimeBin=-1; //Previous Time-Bin
310 ULong_t numPackets=0;
311 while (f.read((char*)(&data),sizeof(data))){
319 buffer->FillBuffer(data.Dig-offset);
323 if ( (data.Time==(pTimeBin+1)) &&
324 (pPadNumber==data.Pad) &&
325 (pRowNumber==data.Row) &&
326 (pSecNumber==data.Sec)){
330 buffer->FillBuffer(pTimeBin);
331 buffer->FillBuffer(bunchLength+2);
333 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
334 //Trailer is formatted and inserted!!
335 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
346 buffer->FillBuffer(data.Dig-offset);
350 buffer->FillBuffer(pTimeBin);
351 buffer->FillBuffer(bunchLength+2);
353 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
355 cout<<"Number of digits: "<<count<<endl;
360 /////////////////////////////////////////////////////////////////////////
361 void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
362 //This method merges the slides in only one file removing at the same
363 //time all the mini headers. The file so obtained must be Altro format
365 //It is used mainly in the debugging phase
370 sprintf(dest,"AltroDDLRecomposed.dat");
372 sprintf(dest,"AltroDDLRecomposedDec.dat");
376 fdest.open(dest,ios::binary);
381 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,flag=0;
382 for(Int_t i=1;i<=LDCsNumber;i++){
384 sprintf(filename,"TPCslice%d",i);
386 sprintf(filename,"TPCslice%d.decomp",i);
388 f.open(filename,ios::binary|ios::in);
390 f.open(filename,ios::in);
392 if(!f){cout<<"BE CAREFUL!! There isn't enough data to generate "<<LDCsNumber<<" slices"<<endl;break;}
393 //loop over the DDL block
394 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
395 //The number of block is ceil(216/LDCsNumber)
396 ULong_t miniHeader[3];
397 //here the Mini Header is read
398 //cout<<filename<<endl;
399 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
402 for(ULong_t j=0;j<size;j++){
403 f.read((char*)(&car),1);
404 fdest.write((char*)(&car),1);