]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCDDLRawData.cxx
New classes and macros for raw data compression and ADC (D.Favretto)
[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 **************************************************************************/
15
16#include "TObjArray.h"
17#include "Riostream.h"
18#include <stdio.h>
19#include <stdlib.h>
20#include "AliTPCCompression.h"
21#include "AliTPCBuffer160.h"
22#include "AliTPCDDLRawData.h"
23#include "TFile.h"
24#include "TTree.h"
25
26
27
28ClassImp(AliTPCDDLRawData)
29////////////////////////////////////////////////////////////////////////////////////////
30
31AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
32 // Copy Constructor
33 return;
34}
35
36AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
37 //Assigment operator
38 return *this;
39}
40
41
42////////////////////////////////////////////////////////////////////////////
43void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
44 //Number of DDL=2*36+4*36=216
45 //2 DDL for each inner sector
46 //4 DDL for each outer sector
47 Int_t DDLPerFile=216/LDCsNumber;
48 Int_t offset=1;
49 if (216%LDCsNumber) DDLPerFile++;
50 cout<<"Number of DDL per slide: "<<DDLPerFile<<endl;
51 ifstream f;
52 f.open("AliTPCDDL.dat",ios::binary);
53 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
54 struct DataPad{
55 Int_t Sec;
56 Int_t SubSec;
57 Int_t Row;
58 Int_t Pad;
59 Int_t Dig;
60 Int_t Time;
61 };
62 DataPad data;
63
64 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
65 Int_t SliceNumber=1;
66 char filename[15];
67 sprintf(filename,"TPCslice%d",SliceNumber);
68 cout<<" Creating "<<filename<<endl;
69 AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
70
71 ULong_t Count=0;
72 Int_t PSecNumber=-1; //Previous Sector number
73 Int_t PRowNumber=-1; //Previous Row number
74 Int_t PPadNumber=-1; //Previous Pad number
75 Int_t PTimeBin=-1; //Previous Time-Bin
76 Int_t PSubSector=-1; //Previous Sub Sector
77 Int_t BunchLength=0;
78 Int_t CountDDL=0;
79 Int_t nwords=0;
80 ULong_t numPackets=0;
81 while (f.read((char*)(&data),sizeof(data))){
82 Count++;
83 if (PPadNumber==-1){
84 PSecNumber=data.Sec;
85 PRowNumber=data.Row;
86 PPadNumber=data.Pad;
87 PTimeBin=data.Time;
88 PSubSector=data.SubSec;
89 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
90 Buffer->WriteMiniHeader(0,PSecNumber,PSubSector,0,0);//Dummy;
91 BunchLength=1;
92 Buffer->FillBuffer(data.Dig-offset);
93 nwords++;
94 }//end if
95 else{
96 if ( (data.Time==(PTimeBin+1)) &&
97 (PPadNumber==data.Pad) &&
98 (PRowNumber==data.Row) &&
99 (PSecNumber==data.Sec)){
100 BunchLength++;
101 }//end if
102 else{
103 Buffer->FillBuffer(PTimeBin);
104 Buffer->FillBuffer(BunchLength+2);
105 nwords+=2;
106 if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
107 //Trailer is formatted and inserted!!
108 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
109 numPackets++;
110 nwords=0;
111
112 if(PSubSector!=data.SubSec){
113 CountDDL++;
114 if(CountDDL==(DDLPerFile+1)){
115 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
116 Buffer->Flush();
117 Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
118 //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
119 delete Buffer;
120 SliceNumber++;
121 sprintf(filename,"TPCslice%d",SliceNumber);
122 cout<<" Creating "<<filename<<endl;
123 Buffer=new AliTPCBuffer160(filename,1);
124 Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
125 CountDDL=1;
126 }//end if
127 else{
128 Buffer->Flush();
129 Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
130 Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
131 }
132 PSubSector=data.SubSec;
133 }//end if
134
135 }//end if
136
137 BunchLength=1;
138 PPadNumber=data.Pad;
139 PRowNumber=data.Row;
140 PSecNumber=data.Sec;
141 }//end else
142 PTimeBin=data.Time;
143 Buffer->FillBuffer(data.Dig-offset);
144 nwords++;
145 }//end else
146 }//end while
147 Buffer->FillBuffer(PTimeBin);
148 Buffer->FillBuffer(BunchLength+2);
149 nwords+=2;
150 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
151 //write the M.H.
152 Buffer->Flush();
153 Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
154 //cout<<"Mini header for D D L:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
155 delete Buffer;
156 cout<<"Number of digits: "<<Count<<endl;
157 f.close();
158 return;
159}
160////////////////////////////////////////////////////////////////////////////
161////////////////////////////////////////////////////////////////////////////
162//This method is used to Compress and decompress the slides
163
164Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
165 static const Int_t NumTable=5;
166 char filename[20];
167 char dest[20];
168 fstream f;
169 ULong_t Size=0;
170 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
171 Int_t Flag=0;
172 for(Int_t i=1;i<=LDCsNumber;i++){
173 if(!Comp){
174 sprintf(filename,"TPCslice%d",i);
175 sprintf(dest,"TPCslice%d.comp",i);
176 }
177 else{
178 sprintf(filename,"TPCslice%d.comp",i);
179 sprintf(dest,"TPCslice%d.decomp",i);
180 }
181 f.open(filename,ios::binary|ios::in);
182 if(!f){cout<<"File doesn't exist \n";exit(1);}
183 cout<<filename<<" "<<dest<<endl;
184 ofstream fdest;
185 fdest.open(dest,ios::binary);
186 //loop over the DDL block
187 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
188 //The number of block is ceil(216/LDCsNumber)
189 ULong_t MiniHeader[3];
190 //here the Mini Header is read
191 while( (f.read((char*)(MiniHeader),sizeof(ULong_t)*3)) ){
192 Size=MiniHeader[0];
193 //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
194 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" Size "<<Size<<endl;
195 //open the temporay File
196 ofstream fo;
197 char temp[15]="TempFile";
198 fo.open(temp,ios::binary);
199 Int_t car=0;
200 for(ULong_t j=0;j<Size;j++){
201 f.read((char*)(&car),1);
202 fo.write((char*)(&car),1);
203 }//end for
204 fo.close();
205 //The temp file is compressed or decompressed
206 AliTPCCompression *util = new AliTPCCompression();
207 if(!Comp)
208 util->CompressDataOptTables(NumTable,temp,"TempCompDecomp");
209 else
210 util->DecompressDataOptTables(NumTable,temp,"TempCompDecomp");
211 delete util;
212 //the temp compressed file is open and copied to the final file fdest
213 ifstream fi;
214 fi.open("TempCompDecomp",ios::binary);
215 fi.seekg(0,ios::end);
216 Size=fi.tellg();
217 fi.seekg(0);
218 //The Mini Header is updated (Size and Compressed flag)
219 //and written into the output file
220 MiniHeader[0]=Size;
221 if(!Comp)
222 Flag=1;
223 else
224 Flag=0;
225 ULong_t aux=0xFFFF;
226 aux<<=16;
227 aux|=Flag;
228 aux|=0xFF;
229 MiniHeader[2]=MiniHeader[2]&aux;
230 fdest.write((char*)(MiniHeader),sizeof(ULong_t)*3);
231 //The compressem temp file is copied into the output file fdest
232 for(ULong_t j=0;j<Size;j++){
233 fi.read((char*)(&car),1);
234 fdest.write((char*)(&car),1);
235 }//end for
236 fi.close();
237 }//end while
238 f.close();
239 fdest.close();
240 remove("TempFile");
241 remove("TempCompDecomp");
242 }//end for
243 return 0;
244}
245
246/////////////////////////////////////////////////////////////////////////////////
247//This method is used to build the Altro format from AliTPCDDL.dat
248//It is used to debug the code and create the tables used in the compresseion phase
249void AliTPCDDLRawData::RawDataAltro(){
250 Int_t offset=1;
251 ifstream f;
252 f.open("AliTPCDDL.dat",ios::binary);
253 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
254 struct DataPad{
255 Int_t Sec;
256 Int_t SubSec;
257 Int_t Row;
258 Int_t Pad;
259 Int_t Dig;
260 Int_t Time;
261 };
262 DataPad data;
263
264 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
265 char filename[30]="AltroFormatDDL.dat";
266 cout<<" Creating "<<filename<<endl;
267 AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
268
269 ULong_t Count=0;
270 Int_t PSecNumber=-1; //Previous Sector number
271 Int_t PRowNumber=-1; //Previous Row number
272 Int_t PPadNumber=-1; //Previous Pad number
273 Int_t PTimeBin=-1; //Previous Time-Bin
274 Int_t BunchLength=0;
275 Int_t nwords=0;
276 ULong_t numPackets=0;
277 while (f.read((char*)(&data),sizeof(data))){
278 Count++;
279 if (PPadNumber==-1){
280 PSecNumber=data.Sec;
281 PRowNumber=data.Row;
282 PPadNumber=data.Pad;
283 PTimeBin=data.Time;
284 BunchLength=1;
285 Buffer->FillBuffer(data.Dig-offset);
286 nwords++;
287 }//end if
288 else{
289 if ( (data.Time==(PTimeBin+1)) &&
290 (PPadNumber==data.Pad) &&
291 (PRowNumber==data.Row) &&
292 (PSecNumber==data.Sec)){
293 BunchLength++;
294 }//end if
295 else{
296 Buffer->FillBuffer(PTimeBin);
297 Buffer->FillBuffer(BunchLength+2);
298 nwords+=2;
299 if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
300 //Trailer is formatted and inserted!!
301 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
302 numPackets++;
303 nwords=0;
304 }//end if
305
306 BunchLength=1;
307 PPadNumber=data.Pad;
308 PRowNumber=data.Row;
309 PSecNumber=data.Sec;
310 }//end else
311 PTimeBin=data.Time;
312 Buffer->FillBuffer(data.Dig-offset);
313 nwords++;
314 }//end else
315 }//end while
316 Buffer->FillBuffer(PTimeBin);
317 Buffer->FillBuffer(BunchLength+2);
318 nwords+=2;
319 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
320 delete Buffer;
321 cout<<"Number of digits: "<<Count<<endl;
322 f.close();
323 return;
324}
325
326
327void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
328 char filename[15];
329 char dest[30];
330 fstream f;
331 if(!Comp)
332 sprintf(dest,"AltroDDLRecomposed.dat");
333 else
334 sprintf(dest,"AltroDDLRecomposedDec.dat");
335 ofstream fdest;
336 fdest.open(dest,ios::binary);
337
338 ULong_t Size=0;
339 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,Flag=0;
340 for(Int_t i=1;i<=LDCsNumber;i++){
341 if(!Comp)
342 sprintf(filename,"TPCslice%d",i);
343 else
344 sprintf(filename,"TPCslice%d.decomp",i);
345
346 f.open(filename,ios::binary|ios::in);
347 if(!f){exit(1);}
348 //loop over the DDL block
349 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
350 //The number of block is ceil(216/LDCsNumber)
351 ULong_t MiniHeader[3];
352 //here the Mini Header is read
353 // for(Int_t j=0;j<3;j++)MiniHeader[j]=0;
354 while( (f.read((char*)(MiniHeader),sizeof(ULong_t)*3)) ){
355 //cout<<"Mini header dimension "<<MiniHeader[0]<<endl;
356 Int_t car=0;
357 Size=MiniHeader[0];
358 for(ULong_t j=0;j<Size;j++){
359 f.read((char*)(&car),1);
360 fdest.write((char*)(&car),1);
361 }//end for
362 }//end while
363 f.close();
364 }//end for
365 fdest.close();
366 return;
367}
368