Simulate TPC raw data with real altro mapping
[u/mrichter/AliRoot.git] / TPC / AliTPCDDLRawData.cxx
CommitLineData
2e9f335b 1/**************************************************************************
2 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
30c1018e 15/* $Id$ */
a79660fb 16
3f1ed77a 17
a79660fb 18//This class conteins all the methods to create raw data
19//as par a given DDL.
20//It produces DDL with both compressed and uncompressed format.
21//For compression we use the optimized table wich needs
22//to be provided.
23
b62e2a95 24#include <TObjArray.h>
0d08c0d0 25#include <TString.h>
26#include <TSystem.h>
b62e2a95 27#include <Riostream.h>
2e9f335b 28#include <stdio.h>
29#include <stdlib.h>
30#include "AliTPCCompression.h"
ba42285c 31#include "AliAltroBuffer.h"
0d08c0d0 32#include "AliTPCAltroMapping.h"
2e9f335b 33#include "AliTPCDDLRawData.h"
0421c3d1 34#include "AliRawDataHeader.h"
2e9f335b 35
36ClassImp(AliTPCDDLRawData)
37////////////////////////////////////////////////////////////////////////////////////////
38
0b3c7dfc 39AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source):
40 TObject(source)
41{
2e9f335b 42 // Copy Constructor
9f992f70 43 fVerbose=source.fVerbose;
2e9f335b 44 return;
45}
46
47AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
48 //Assigment operator
9f992f70 49 fVerbose=source.fVerbose;
2e9f335b 50 return *this;
51}
52
53
54////////////////////////////////////////////////////////////////////////////
0421c3d1 55void AliTPCDDLRawData::RawData(const char* inputFileName){
56 //Raw data generation
2e9f335b 57 //Number of DDL=2*36+4*36=216
58 //2 DDL for each inner sector
59 //4 DDL for each outer sector
2e9f335b 60 Int_t offset=1;
2e9f335b 61 ifstream f;
30c1018e 62#ifndef __DECCXX
0421c3d1 63 f.open(inputFileName,ios::binary);
30c1018e 64#else
0421c3d1 65 f.open(inputFileName);
30c1018e 66#endif
0421c3d1 67 if(!f){Error("RawData", "File doesn't exist !!");return;}
2e9f335b 68 struct DataPad{
69 Int_t Sec;
70 Int_t SubSec;
71 Int_t Row;
72 Int_t Pad;
73 Int_t Dig;
74 Int_t Time;
75 };
76 DataPad data;
77
ba42285c 78 //AliAltroBuffer is used in write mode to generate raw data file
2e9f335b 79 char filename[15];
0421c3d1 80 Int_t ddlNumber=0;
ba42285c 81 AliAltroBuffer *buffer=NULL;
a79660fb 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
87 Int_t bunchLength=0;
2e9f335b 88 Int_t nwords=0;
0b3c7dfc 89 UInt_t numPackets=0;
0421c3d1 90
0d08c0d0 91 TString path = gSystem->Getenv("ALICE_ROOT");
92 path += "/TPC/mapping/Patch";
93 TString path2;
94 AliTPCAltroMapping *mapping[6];
95 for(Int_t i = 0; i < 6; i++) {
96 path2 = path;
97 path2 += i;
98 path2 += ".data";
99 mapping[i] = new AliTPCAltroMapping(path2.Data());
100 }
101
102
2e9f335b 103 while (f.read((char*)(&data),sizeof(data))){
a79660fb 104 if (pPadNumber==-1){
105 pSecNumber=data.Sec;
106 pRowNumber=data.Row;
107 pPadNumber=data.Pad;
108 pTimeBin=data.Time;
109 pSubSector=data.SubSec;
0421c3d1 110
111 if(data.Sec<36)
112 ddlNumber=data.Sec*2+data.SubSec;
113 else
114 ddlNumber=72+(data.Sec-36)*4+data.SubSec;
115 sprintf(filename,"TPC_%d.ddl",ddlNumber+kDDLOffset);
0d08c0d0 116 Int_t patchIndex = data.SubSec;
117 if(data.Sec>=36) patchIndex += 2;
118 buffer=new AliAltroBuffer(filename,1,mapping[patchIndex]);
2e9f335b 119 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
0421c3d1 120 buffer->WriteDataHeader(kTRUE,kFALSE);//Dummy;
a79660fb 121 bunchLength=1;
122 buffer->FillBuffer(data.Dig-offset);
2e9f335b 123 nwords++;
124 }//end if
125 else{
a79660fb 126 if ( (data.Time==(pTimeBin+1)) &&
127 (pPadNumber==data.Pad) &&
128 (pRowNumber==data.Row) &&
129 (pSecNumber==data.Sec)){
130 bunchLength++;
2e9f335b 131 }//end if
132 else{
a79660fb 133 buffer->FillBuffer(pTimeBin);
134 buffer->FillBuffer(bunchLength+2);
2e9f335b 135 nwords+=2;
a79660fb 136 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
2e9f335b 137 //Trailer is formatted and inserted!!
a79660fb 138 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
2e9f335b 139 numPackets++;
140 nwords=0;
141
a79660fb 142 if(pSubSector!=data.SubSec){
0421c3d1 143 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
144 buffer->Flush();
145 buffer->WriteDataHeader(kFALSE,kFALSE);
146 //cout<<"Data header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
147 delete buffer;
148
149 if(data.Sec<36)
150 ddlNumber=data.Sec*2+data.SubSec;
151 else
152 ddlNumber=72+(data.Sec-36)*4+data.SubSec;
153 sprintf(filename,"TPC_%d.ddl",ddlNumber+kDDLOffset);
0d08c0d0 154 Int_t patchIndex = data.SubSec;
155 if(data.Sec>=36) patchIndex += 2;
156 buffer=new AliAltroBuffer(filename,1,mapping[patchIndex]);
0421c3d1 157 buffer->WriteDataHeader(kTRUE,kFALSE);//Dummy;
a79660fb 158 pSubSector=data.SubSec;
2e9f335b 159 }//end if
2e9f335b 160 }//end if
161
a79660fb 162 bunchLength=1;
163 pPadNumber=data.Pad;
164 pRowNumber=data.Row;
165 pSecNumber=data.Sec;
2e9f335b 166 }//end else
a79660fb 167 pTimeBin=data.Time;
168 buffer->FillBuffer(data.Dig-offset);
2e9f335b 169 nwords++;
170 }//end else
171 }//end while
0421c3d1 172 if (buffer) {
173 buffer->FillBuffer(pTimeBin);
174 buffer->FillBuffer(bunchLength+2);
175 nwords+=2;
176 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
177 //write the D.H.
178 buffer->Flush();
179 buffer->WriteDataHeader(kFALSE,kFALSE);
180 //cout<<"Data header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
181 delete buffer;
182 }
0d08c0d0 183
184 for(Int_t i = 0; i < 6; i++) delete mapping[i];
185
2e9f335b 186 f.close();
187 return;
188}
189////////////////////////////////////////////////////////////////////////////
190////////////////////////////////////////////////////////////////////////////
a79660fb 191
2e9f335b 192
0421c3d1 193Int_t AliTPCDDLRawData::RawDataCompDecompress(Bool_t compress){
a79660fb 194 //This method is used to compress and decompress the slides
195 static const Int_t kNumTables=5;
2e9f335b 196 char filename[20];
2e9f335b 197 fstream f;
0b3c7dfc 198 UInt_t size=0;
0421c3d1 199 AliTPCCompression util;
200 util.SetVerbose(0);
201
202 for(Int_t i=0;i<216;i++){
203 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
30c1018e 204#ifndef __DECCXX
2e9f335b 205 f.open(filename,ios::binary|ios::in);
30c1018e 206#else
207 f.open(filename,ios::in);
208#endif
f65ac70b 209#if defined(__HP_aCC) || defined(__DECCXX)
210 if(!f.rdbuf()->is_open()){f.clear(); continue;}
211#else
0421c3d1 212 if(!f.is_open()){f.clear(); continue;}
f65ac70b 213#endif
c9bd9d3d 214 if (fVerbose)
0421c3d1 215 Info("RawDataCompDecompress", "&s -> dest.ddl", filename);
2e9f335b 216 ofstream fdest;
30c1018e 217#ifndef __DECCXX
0421c3d1 218 fdest.open("dest.ddl",ios::binary);
30c1018e 219#else
0421c3d1 220 fdest.open("dest.ddl");
30c1018e 221#endif
2e9f335b 222 //loop over the DDL block
0421c3d1 223 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
2e9f335b 224 //The number of block is ceil(216/LDCsNumber)
0421c3d1 225 AliRawDataHeader header;
226 //here the Data Header is read
227 while( f.read((char*)(&header),sizeof(header)) ){
228 size=header.fSize-sizeof(header);
9f992f70 229 // cout<<"Data size:"<<size<<endl;
0b3c7dfc 230 //Int_t dim=sizeof(UInt_t)+sizeof(Int_t)*5;
a79660fb 231 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
0421c3d1 232 Bool_t compressed = header.TestAttribute(1);
233 if ((compressed && compress) ||
234 (!compressed && !compress)) continue;
2e9f335b 235 //open the temporay File
236 ofstream fo;
237 char temp[15]="TempFile";
30c1018e 238#ifndef __DECCXX
2e9f335b 239 fo.open(temp,ios::binary);
30c1018e 240#else
241 fo.open(temp);
242#endif
2e9f335b 243 Int_t car=0;
0b3c7dfc 244 for(UInt_t j=0;j<size;j++){
2e9f335b 245 f.read((char*)(&car),1);
246 fo.write((char*)(&car),1);
247 }//end for
248 fo.close();
249 //The temp file is compressed or decompressed
0421c3d1 250 Int_t result=0;
251 if(compress){
252 result=util.CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
9f992f70 253 }
2e9f335b 254 else
0421c3d1 255 result=util.DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
256 if (result != 0) break;
2e9f335b 257 //the temp compressed file is open and copied to the final file fdest
258 ifstream fi;
30c1018e 259#ifndef __DECCXX
2e9f335b 260 fi.open("TempCompDecomp",ios::binary);
30c1018e 261#else
262 fi.open("TempCompDecomp");
263#endif
2e9f335b 264 fi.seekg(0,ios::end);
a79660fb 265 size=fi.tellg();
2e9f335b 266 fi.seekg(0);
0421c3d1 267 //The Data Header is updated (size and Compressed flag)
2e9f335b 268 //and written into the output file
0421c3d1 269 header.fSize=size+sizeof(header);
270 if (compress) header.SetAttribute(1);
271 else header.ResetAttribute(1);
272 fdest.write((char*)(&header),sizeof(header));
2e9f335b 273 //The compressem temp file is copied into the output file fdest
0b3c7dfc 274 for(UInt_t j=0;j<size;j++){
2e9f335b 275 fi.read((char*)(&car),1);
276 fdest.write((char*)(&car),1);
277 }//end for
278 fi.close();
279 }//end while
cd43b5e1 280 f.clear();
2e9f335b 281 f.close();
282 fdest.close();
283 remove("TempFile");
284 remove("TempCompDecomp");
0421c3d1 285 rename("dest.ddl",filename);
2e9f335b 286 }//end for
287 return 0;
288}
289
290/////////////////////////////////////////////////////////////////////////////////
0421c3d1 291void AliTPCDDLRawData::RawDataAltro(const char* inputFileName, const char* outputFileName)const{
a79660fb 292 //This method is used to build the Altro format from AliTPCDDL.dat
9f992f70 293 //It is used to debug the code and creates the tables used in the compresseion phase
2e9f335b 294 Int_t offset=1;
295 ifstream f;
30c1018e 296#ifndef __DECCXX
0421c3d1 297 f.open(inputFileName,ios::binary);
30c1018e 298#else
0421c3d1 299 f.open(inputFileName);
30c1018e 300#endif
0421c3d1 301 if(!f){
302 Error("RawDataAltro", "File doesn't exist !!");
303 return;
304 }
2e9f335b 305 struct DataPad{
306 Int_t Sec;
307 Int_t SubSec;
308 Int_t Row;
309 Int_t Pad;
310 Int_t Dig;
311 Int_t Time;
312 };
313 DataPad data;
314
0d08c0d0 315 TString path = gSystem->Getenv("ALICE_ROOT");
316 path += "/TPC/mapping/Patch";
317 TString path2;
318 AliTPCAltroMapping *mapping[6];
319 for(Int_t i = 0; i < 6; i++) {
320 path2 = path;
321 path2 += i;
322 path2 += ".data";
323 mapping[i] = new AliTPCAltroMapping(path2.Data());
324 }
325
ba42285c 326 //AliAltroBuffer is used in write mode to generate AltroFormat.dat file
0421c3d1 327 Info("RawDataAltro", "Creating &s", outputFileName);
ba42285c 328 AliAltroBuffer *buffer=new AliAltroBuffer(outputFileName,1);
2e9f335b 329
0b3c7dfc 330 UInt_t count=0;
a79660fb 331 Int_t pSecNumber=-1; //Previous Sector number
0d08c0d0 332 Int_t pSubSec=-1; //Previous sub Sector
a79660fb 333 Int_t pRowNumber=-1; //Previous Row number
334 Int_t pPadNumber=-1; //Previous Pad number
335 Int_t pTimeBin=-1; //Previous Time-Bin
336 Int_t bunchLength=0;
2e9f335b 337 Int_t nwords=0;
0b3c7dfc 338 UInt_t numPackets=0;
2e9f335b 339 while (f.read((char*)(&data),sizeof(data))){
a79660fb 340 count++;
341 if (pPadNumber==-1){
0d08c0d0 342 pSubSec=data.SubSec;
a79660fb 343 pSecNumber=data.Sec;
344 pRowNumber=data.Row;
345 pPadNumber=data.Pad;
346 pTimeBin=data.Time;
347 bunchLength=1;
348 buffer->FillBuffer(data.Dig-offset);
2e9f335b 349 nwords++;
350 }//end if
351 else{
a79660fb 352 if ( (data.Time==(pTimeBin+1)) &&
353 (pPadNumber==data.Pad) &&
354 (pRowNumber==data.Row) &&
355 (pSecNumber==data.Sec)){
356 bunchLength++;
2e9f335b 357 }//end if
358 else{
a79660fb 359 buffer->FillBuffer(pTimeBin);
360 buffer->FillBuffer(bunchLength+2);
2e9f335b 361 nwords+=2;
a79660fb 362 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
2e9f335b 363 //Trailer is formatted and inserted!!
0d08c0d0 364 Int_t patchIndex = pSubSec;
365 if(pSecNumber >= 36) patchIndex += 2;
366 buffer->SetMapping(mapping[patchIndex]);
a79660fb 367 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
2e9f335b 368 numPackets++;
369 nwords=0;
370 }//end if
371
a79660fb 372 bunchLength=1;
373 pPadNumber=data.Pad;
374 pRowNumber=data.Row;
375 pSecNumber=data.Sec;
2e9f335b 376 }//end else
a79660fb 377 pTimeBin=data.Time;
378 buffer->FillBuffer(data.Dig-offset);
2e9f335b 379 nwords++;
380 }//end else
381 }//end while
a79660fb 382 buffer->FillBuffer(pTimeBin);
383 buffer->FillBuffer(bunchLength+2);
2e9f335b 384 nwords+=2;
0d08c0d0 385 Int_t patchIndex = pSubSec;
386 if(pSecNumber >= 36) patchIndex += 2;
387 buffer->SetMapping(mapping[patchIndex]);
a79660fb 388 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
389 delete buffer;
0421c3d1 390 Info("RawDataAltro", "Number of digits: %d", count);
0d08c0d0 391
392 for(Int_t i = 0; i < 6; i++) delete mapping[i];
393
2e9f335b 394 f.close();
395 return;
396}
397
a79660fb 398/////////////////////////////////////////////////////////////////////////
0421c3d1 399void AliTPCDDLRawData::RawDataAltroDecode(const char* outputFileName){
a79660fb 400 //This method merges the slides in only one file removing at the same
0421c3d1 401 //time all the data headers. The file so obtained must be Altro format
a79660fb 402 //complaiant.
403 //It is used mainly in the debugging phase
2e9f335b 404 char filename[15];
2e9f335b 405 fstream f;
2e9f335b 406 ofstream fdest;
cd43b5e1 407
30c1018e 408#ifndef __DECCXX
0421c3d1 409 fdest.open(outputFileName,ios::binary);
30c1018e 410#else
0421c3d1 411 fdest.open(outputFileName);
30c1018e 412#endif
0b3c7dfc 413 UInt_t size=0;
0421c3d1 414 AliRawDataHeader header;
415 for(Int_t i=0;i<216;i++){
416 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
30c1018e 417#ifndef __DECCXX
2e9f335b 418 f.open(filename,ios::binary|ios::in);
30c1018e 419#else
420 f.open(filename,ios::in);
421#endif
0421c3d1 422 if(!f)continue;
2e9f335b 423 //loop over the DDL block
0421c3d1 424 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
425 while( (f.read((char*)(&header),sizeof(header))) ){
2e9f335b 426 Int_t car=0;
0421c3d1 427 size=header.fSize-sizeof(header);
0b3c7dfc 428 for(UInt_t j=0;j<size;j++){
2e9f335b 429 f.read((char*)(&car),1);
430 fdest.write((char*)(&car),1);
431 }//end for
432 }//end while
cd43b5e1 433 f.clear();
2e9f335b 434 f.close();
435 }//end for
436 fdest.close();
437 return;
438}
439