Changes needed on HP and Alpha
[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
f65ac70b 187#if defined(__HP_aCC) || defined(__DECCXX)
188 if(!f.rdbuf()->is_open()){f.clear(); continue;}
189#else
0421c3d1 190 if(!f.is_open()){f.clear(); continue;}
f65ac70b 191#endif
c9bd9d3d 192 if (fVerbose)
0421c3d1 193 Info("RawDataCompDecompress", "&s -> dest.ddl", filename);
2e9f335b 194 ofstream fdest;
30c1018e 195#ifndef __DECCXX
0421c3d1 196 fdest.open("dest.ddl",ios::binary);
30c1018e 197#else
0421c3d1 198 fdest.open("dest.ddl");
30c1018e 199#endif
2e9f335b 200 //loop over the DDL block
0421c3d1 201 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
2e9f335b 202 //The number of block is ceil(216/LDCsNumber)
0421c3d1 203 AliRawDataHeader header;
204 //here the Data Header is read
205 while( f.read((char*)(&header),sizeof(header)) ){
206 size=header.fSize-sizeof(header);
9f992f70 207 // cout<<"Data size:"<<size<<endl;
0b3c7dfc 208 //Int_t dim=sizeof(UInt_t)+sizeof(Int_t)*5;
a79660fb 209 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
0421c3d1 210 Bool_t compressed = header.TestAttribute(1);
211 if ((compressed && compress) ||
212 (!compressed && !compress)) continue;
2e9f335b 213 //open the temporay File
214 ofstream fo;
215 char temp[15]="TempFile";
30c1018e 216#ifndef __DECCXX
2e9f335b 217 fo.open(temp,ios::binary);
30c1018e 218#else
219 fo.open(temp);
220#endif
2e9f335b 221 Int_t car=0;
0b3c7dfc 222 for(UInt_t j=0;j<size;j++){
2e9f335b 223 f.read((char*)(&car),1);
224 fo.write((char*)(&car),1);
225 }//end for
226 fo.close();
227 //The temp file is compressed or decompressed
0421c3d1 228 Int_t result=0;
229 if(compress){
230 result=util.CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
9f992f70 231 }
2e9f335b 232 else
0421c3d1 233 result=util.DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
234 if (result != 0) break;
2e9f335b 235 //the temp compressed file is open and copied to the final file fdest
236 ifstream fi;
30c1018e 237#ifndef __DECCXX
2e9f335b 238 fi.open("TempCompDecomp",ios::binary);
30c1018e 239#else
240 fi.open("TempCompDecomp");
241#endif
2e9f335b 242 fi.seekg(0,ios::end);
a79660fb 243 size=fi.tellg();
2e9f335b 244 fi.seekg(0);
0421c3d1 245 //The Data Header is updated (size and Compressed flag)
2e9f335b 246 //and written into the output file
0421c3d1 247 header.fSize=size+sizeof(header);
248 if (compress) header.SetAttribute(1);
249 else header.ResetAttribute(1);
250 fdest.write((char*)(&header),sizeof(header));
2e9f335b 251 //The compressem temp file is copied into the output file fdest
0b3c7dfc 252 for(UInt_t j=0;j<size;j++){
2e9f335b 253 fi.read((char*)(&car),1);
254 fdest.write((char*)(&car),1);
255 }//end for
256 fi.close();
257 }//end while
cd43b5e1 258 f.clear();
2e9f335b 259 f.close();
260 fdest.close();
261 remove("TempFile");
262 remove("TempCompDecomp");
0421c3d1 263 rename("dest.ddl",filename);
2e9f335b 264 }//end for
265 return 0;
266}
267
268/////////////////////////////////////////////////////////////////////////////////
0421c3d1 269void AliTPCDDLRawData::RawDataAltro(const char* inputFileName, const char* outputFileName)const{
a79660fb 270 //This method is used to build the Altro format from AliTPCDDL.dat
9f992f70 271 //It is used to debug the code and creates the tables used in the compresseion phase
2e9f335b 272 Int_t offset=1;
273 ifstream f;
30c1018e 274#ifndef __DECCXX
0421c3d1 275 f.open(inputFileName,ios::binary);
30c1018e 276#else
0421c3d1 277 f.open(inputFileName);
30c1018e 278#endif
0421c3d1 279 if(!f){
280 Error("RawDataAltro", "File doesn't exist !!");
281 return;
282 }
2e9f335b 283 struct DataPad{
284 Int_t Sec;
285 Int_t SubSec;
286 Int_t Row;
287 Int_t Pad;
288 Int_t Dig;
289 Int_t Time;
290 };
291 DataPad data;
292
293 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
0421c3d1 294 Info("RawDataAltro", "Creating &s", outputFileName);
295 AliTPCBuffer160 *buffer=new AliTPCBuffer160(outputFileName,1);
2e9f335b 296
0b3c7dfc 297 UInt_t count=0;
a79660fb 298 Int_t pSecNumber=-1; //Previous Sector number
299 Int_t pRowNumber=-1; //Previous Row number
300 Int_t pPadNumber=-1; //Previous Pad number
301 Int_t pTimeBin=-1; //Previous Time-Bin
302 Int_t bunchLength=0;
2e9f335b 303 Int_t nwords=0;
0b3c7dfc 304 UInt_t numPackets=0;
2e9f335b 305 while (f.read((char*)(&data),sizeof(data))){
a79660fb 306 count++;
307 if (pPadNumber==-1){
308 pSecNumber=data.Sec;
309 pRowNumber=data.Row;
310 pPadNumber=data.Pad;
311 pTimeBin=data.Time;
312 bunchLength=1;
313 buffer->FillBuffer(data.Dig-offset);
2e9f335b 314 nwords++;
315 }//end if
316 else{
a79660fb 317 if ( (data.Time==(pTimeBin+1)) &&
318 (pPadNumber==data.Pad) &&
319 (pRowNumber==data.Row) &&
320 (pSecNumber==data.Sec)){
321 bunchLength++;
2e9f335b 322 }//end if
323 else{
a79660fb 324 buffer->FillBuffer(pTimeBin);
325 buffer->FillBuffer(bunchLength+2);
2e9f335b 326 nwords+=2;
a79660fb 327 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
2e9f335b 328 //Trailer is formatted and inserted!!
a79660fb 329 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
2e9f335b 330 numPackets++;
331 nwords=0;
332 }//end if
333
a79660fb 334 bunchLength=1;
335 pPadNumber=data.Pad;
336 pRowNumber=data.Row;
337 pSecNumber=data.Sec;
2e9f335b 338 }//end else
a79660fb 339 pTimeBin=data.Time;
340 buffer->FillBuffer(data.Dig-offset);
2e9f335b 341 nwords++;
342 }//end else
343 }//end while
a79660fb 344 buffer->FillBuffer(pTimeBin);
345 buffer->FillBuffer(bunchLength+2);
2e9f335b 346 nwords+=2;
a79660fb 347 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
348 delete buffer;
0421c3d1 349 Info("RawDataAltro", "Number of digits: %d", count);
2e9f335b 350 f.close();
351 return;
352}
353
a79660fb 354/////////////////////////////////////////////////////////////////////////
0421c3d1 355void AliTPCDDLRawData::RawDataAltroDecode(const char* outputFileName){
a79660fb 356 //This method merges the slides in only one file removing at the same
0421c3d1 357 //time all the data headers. The file so obtained must be Altro format
a79660fb 358 //complaiant.
359 //It is used mainly in the debugging phase
2e9f335b 360 char filename[15];
2e9f335b 361 fstream f;
2e9f335b 362 ofstream fdest;
cd43b5e1 363
30c1018e 364#ifndef __DECCXX
0421c3d1 365 fdest.open(outputFileName,ios::binary);
30c1018e 366#else
0421c3d1 367 fdest.open(outputFileName);
30c1018e 368#endif
0b3c7dfc 369 UInt_t size=0;
0421c3d1 370 AliRawDataHeader header;
371 for(Int_t i=0;i<216;i++){
372 sprintf(filename,"TPC_%d.ddl",i+kDDLOffset);
30c1018e 373#ifndef __DECCXX
2e9f335b 374 f.open(filename,ios::binary|ios::in);
30c1018e 375#else
376 f.open(filename,ios::in);
377#endif
0421c3d1 378 if(!f)continue;
2e9f335b 379 //loop over the DDL block
0421c3d1 380 //Each block contains a Data Header followed by raw data (ALTRO FORMAT)
381 while( (f.read((char*)(&header),sizeof(header))) ){
2e9f335b 382 Int_t car=0;
0421c3d1 383 size=header.fSize-sizeof(header);
0b3c7dfc 384 for(UInt_t j=0;j<size;j++){
2e9f335b 385 f.read((char*)(&car),1);
386 fdest.write((char*)(&car),1);
387 }//end for
388 }//end while
cd43b5e1 389 f.clear();
2e9f335b 390 f.close();
391 }//end for
392 fdest.close();
393 return;
394}
395