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