]>
Commit | Line | Data |
---|---|---|
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 | ||
28 | ClassImp(AliTPCDDLRawData) | |
29 | //////////////////////////////////////////////////////////////////////////////////////// | |
30 | ||
31 | AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){ | |
32 | // Copy Constructor | |
33 | return; | |
34 | } | |
35 | ||
36 | AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){ | |
37 | //Assigment operator | |
38 | return *this; | |
39 | } | |
40 | ||
41 | ||
42 | //////////////////////////////////////////////////////////////////////////// | |
43 | void 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 | ||
164 | Int_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 | |
249 | void 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 | ||
327 | void 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 |