]>
Commit | Line | Data |
---|---|---|
7e914051 | 1 | // $Id$ |
ff2f0f94 | 2 | |
892210c7 | 3 | //************************************************************************** |
4 | //* This file is property of and copyright by the ALICE HLT Project * | |
5 | //* ALICE Experiment at CERN, All rights reserved. * | |
6 | //* * | |
7 | //* Primary Authors: Timm Steinbeck <timm@kip.uni-heidelberg.de> * | |
8 | //* for The ALICE HLT Project. * | |
9 | //* * | |
10 | //* Permission to use, copy, modify and distribute this software and its * | |
11 | //* documentation strictly for non-commercial purposes is hereby granted * | |
12 | //* without fee, provided that the above copyright notice appears in all * | |
13 | //* copies and that both the copyright notice and this permission notice * | |
14 | //* appear in the supporting documentation. The authors make no claims * | |
15 | //* about the suitability of this software for any purpose. It is * | |
16 | //* provided "as is" without express or implied warranty. * | |
17 | //************************************************************************** | |
ff2f0f94 | 18 | |
19 | /** @file AliHLTTPCCompDumpComponent.cxx | |
20 | @author Timm Steinbeck | |
21 | @date 10-08-2006 | |
892210c7 | 22 | @brief A copy processing component for the HLT |
23 | that writes the results of the Vestbo compression | |
24 | components to humanly readable files | |
25 | */ | |
ff2f0f94 | 26 | |
27 | #if __GNUC__ >= 3 | |
28 | using namespace std; | |
29 | #endif | |
30 | ||
31 | #include "AliHLTTPCCompDumpComponent.h" | |
32 | #include "AliHLTTPCDefinitions.h" | |
33 | #include "AliHLTTPCTrackletDataFormat.h" | |
34 | #include "AliHLTTPCClusterDataFormat.h" | |
35 | #include "AliHLTTPCModels.h" | |
36 | #include "AliHLTTPCTransform.h" | |
37 | #include "AliHLTTPCCompDataCompressorHelper.h" | |
38 | #include <stdlib.h> | |
39 | #include <errno.h> | |
40 | ||
41 | // this is a global object used for automatic component registration, do not use this | |
42 | AliHLTTPCCompDumpComponent gAliHLTTPCCompClusterDumpComponent; | |
43 | ||
44 | ClassImp(AliHLTTPCCompDumpComponent) | |
45 | ||
46 | AliHLTTPCCompDumpComponent::AliHLTTPCCompDumpComponent() | |
47 | : | |
48 | fBitDataCurrentWord(0), | |
49 | fBitDataCurrentPosInWord(0), | |
50 | fBitDataCurrentInput(NULL), | |
51 | fBitDataCurrentInputStart(NULL), | |
52 | fBitDataCurrentInputEnd(NULL) | |
53 | { | |
54 | // see header file for class documentation | |
55 | } | |
56 | ||
57 | AliHLTTPCCompDumpComponent::~AliHLTTPCCompDumpComponent() | |
58 | { | |
59 | // see header file for class documentation | |
60 | } | |
61 | ||
892210c7 | 62 | const char* AliHLTTPCCompDumpComponent::GetComponentID() |
ff2f0f94 | 63 | { |
64 | // see header file for class documentation | |
65 | return "TPCCompDump"; // The ID of this component | |
66 | } | |
67 | ||
892210c7 | 68 | void AliHLTTPCCompDumpComponent::GetInputDataTypes( vector<AliHLTComponent_DataType>& list) |
ff2f0f94 | 69 | { |
70 | // see header file for class documentation | |
71 | list.clear(); // We do not have any requirements for our input data type(s). | |
72 | list.push_back( AliHLTTPCDefinitions::fgkClustersDataType ); | |
73 | list.push_back( AliHLTTPCDefinitions::fgkTrackSegmentsDataType ); | |
74 | list.push_back( AliHLTTPCDefinitions::fgkTracksDataType ); | |
75 | list.push_back( AliHLTTPCDefinitions::fgkClusterTracksModelDataType ); | |
76 | list.push_back( AliHLTTPCDefinitions::fgkRemainingClustersModelDataType ); | |
77 | } | |
78 | ||
79 | AliHLTComponent_DataType AliHLTTPCCompDumpComponent::GetOutputDataType() | |
80 | { | |
81 | // see header file for class documentation | |
82 | return AliHLTTPCDefinitions::fgkClusterTracksModelDataType; | |
83 | } | |
84 | ||
892210c7 | 85 | void AliHLTTPCCompDumpComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) |
ff2f0f94 | 86 | { |
87 | // see header file for class documentation | |
88 | constBase = 0; | |
89 | inputMultiplier = 1.; | |
90 | //#warning Adapt input Multiplier to something more realistic | |
91 | } | |
92 | ||
93 | ||
94 | // Spawn function, return new instance of this class | |
95 | AliHLTComponent* AliHLTTPCCompDumpComponent::Spawn() | |
96 | { | |
97 | // see header file for class documentation | |
98 | return new AliHLTTPCCompDumpComponent; | |
99 | }; | |
100 | ||
892210c7 | 101 | void AliHLTTPCCompDumpComponent::InitBitDataInput( AliHLTUInt8_t* input, UInt_t inputSize ) |
102 | { | |
103 | // see header file for class documentation | |
104 | fBitDataCurrentWord = 0; | |
105 | fBitDataCurrentPosInWord = 7; | |
106 | fBitDataCurrentInput = fBitDataCurrentInputStart = input; | |
107 | fBitDataCurrentInputEnd = input+inputSize; | |
108 | fBitDataCurrentWord = *fBitDataCurrentInput; | |
109 | }; | |
110 | ||
111 | bool AliHLTTPCCompDumpComponent::InputBit( AliHLTUInt8_t & value ) | |
112 | { | |
113 | // see header file for class documentation | |
114 | if ( fBitDataCurrentInput>=fBitDataCurrentInputEnd ) | |
115 | return false; | |
116 | value = (fBitDataCurrentWord >> fBitDataCurrentPosInWord) & 1; | |
117 | if ( fBitDataCurrentPosInWord ) | |
118 | fBitDataCurrentPosInWord--; | |
119 | else | |
120 | { | |
121 | fBitDataCurrentInput++; | |
122 | if ( fBitDataCurrentInput<fBitDataCurrentInputEnd ) | |
123 | { | |
124 | fBitDataCurrentWord = *fBitDataCurrentInput; | |
125 | fBitDataCurrentPosInWord = 7; | |
126 | } | |
127 | } | |
128 | return true; | |
129 | }; | |
130 | ||
131 | bool AliHLTTPCCompDumpComponent::InputBits( AliHLTUInt8_t & value, UInt_t const & bitCount ) | |
132 | { | |
133 | // see header file for class documentation | |
134 | if ( bitCount>8 ) | |
135 | { | |
136 | HLTFatal( "Internal error: Attempt to write more than 32 bits (%u)", (unsigned)bitCount ); | |
137 | return false; | |
138 | } | |
139 | AliHLTUInt64_t temp; | |
140 | if ( !InputBits( temp, bitCount ) ) | |
141 | return false; | |
142 | value = (AliHLTUInt8_t)( temp & (AliHLTUInt64_t)0xFFFFFFFFULL ); | |
143 | return true; | |
144 | }; | |
145 | ||
146 | bool AliHLTTPCCompDumpComponent::InputBits( AliHLTUInt16_t & value, UInt_t const & bitCount ) | |
147 | { | |
148 | // see header file for class documentation | |
149 | if ( bitCount>16 ) | |
150 | { | |
151 | HLTFatal( "Internal error: Attempt to write more than 32 bits (%u)", (unsigned)bitCount ); | |
152 | return false; | |
153 | } | |
154 | AliHLTUInt64_t temp; | |
155 | if ( !InputBits( temp, bitCount ) ) | |
156 | return false; | |
157 | value = (AliHLTUInt16_t)( temp & (AliHLTUInt64_t)0xFFFFFFFFULL ); | |
158 | return true; | |
159 | }; | |
160 | ||
161 | bool AliHLTTPCCompDumpComponent::InputBits( Int_t & value, UInt_t const & bitCount ) | |
162 | { | |
163 | // see header file for class documentation | |
164 | if ( bitCount>32 ) | |
165 | { | |
166 | HLTFatal( "Internal error: Attempt to write more than 32 bits (%u)", (unsigned)bitCount ); | |
167 | return false; | |
168 | } | |
169 | AliHLTUInt64_t temp; | |
170 | if ( !InputBits( temp, bitCount ) ) | |
171 | return false; | |
172 | value = (Int_t)( temp & (AliHLTUInt64_t)0xFFFFFFFFULL ); | |
173 | return true; | |
174 | }; | |
175 | ||
176 | bool AliHLTTPCCompDumpComponent::InputBits( AliHLTUInt64_t & value, UInt_t const & bitCount ) | |
177 | { | |
178 | // see header file for class documentation | |
179 | if ( bitCount>64 ) | |
180 | { | |
181 | HLTFatal( "Internal error: Attempt to write more than 64 bits (%u)", (unsigned)bitCount ); | |
182 | return false; | |
183 | } | |
184 | UInt_t bitsToRead=bitCount; | |
185 | UInt_t curBitCount; | |
186 | value = 0; | |
187 | while ( bitsToRead>0 ) | |
188 | { | |
189 | if ( fBitDataCurrentInput>=fBitDataCurrentInputEnd ) | |
190 | return false; | |
191 | if ( bitsToRead >= fBitDataCurrentPosInWord+1 ) | |
192 | curBitCount = fBitDataCurrentPosInWord+1; | |
193 | else | |
194 | curBitCount = bitsToRead; | |
195 | value = (value << curBitCount) | ( (fBitDataCurrentWord >> (fBitDataCurrentPosInWord-curBitCount+1)) & ((1 << curBitCount)-1) ); | |
196 | if ( fBitDataCurrentPosInWord < curBitCount ) | |
197 | { | |
198 | fBitDataCurrentInput++; | |
199 | if ( fBitDataCurrentInput<fBitDataCurrentInputEnd ) | |
200 | { | |
201 | fBitDataCurrentWord = *fBitDataCurrentInput; | |
202 | fBitDataCurrentPosInWord = 7; | |
203 | } | |
204 | } | |
205 | else | |
206 | fBitDataCurrentPosInWord -= curBitCount; | |
207 | bitsToRead -= curBitCount; | |
208 | } | |
209 | return true; | |
210 | }; | |
211 | ||
212 | void AliHLTTPCCompDumpComponent::Pad8Bits() | |
213 | { | |
214 | // see header file for class documentation | |
215 | if ( fBitDataCurrentPosInWord == 7 ) | |
216 | return; | |
217 | fBitDataCurrentInput++; | |
218 | if ( fBitDataCurrentInput<fBitDataCurrentInputEnd ) | |
219 | { | |
220 | fBitDataCurrentWord = *fBitDataCurrentInput; | |
221 | fBitDataCurrentPosInWord = 7; | |
222 | } | |
223 | }; | |
224 | ||
225 | bool AliHLTTPCCompDumpComponent::InputBytes( AliHLTUInt8_t* data, UInt_t const & byteCount ) | |
226 | { | |
227 | // see header file for class documentation | |
228 | Pad8Bits(); | |
229 | if ( fBitDataCurrentInput+byteCount>fBitDataCurrentInputEnd ) | |
230 | return false; | |
231 | memcpy( data, fBitDataCurrentInput, byteCount ); | |
232 | fBitDataCurrentInput += byteCount; | |
233 | if ( fBitDataCurrentInput<fBitDataCurrentInputEnd ) | |
234 | { | |
235 | fBitDataCurrentWord = *fBitDataCurrentInput; | |
236 | fBitDataCurrentPosInWord = 7; | |
237 | } | |
238 | return true; | |
239 | }; | |
240 | ||
ff2f0f94 | 241 | int AliHLTTPCCompDumpComponent::DoInit( int argc, const char** argv ) |
242 | { | |
243 | // see header file for class documentation | |
244 | //char* cpErr; | |
245 | if ( argc ) | |
246 | { | |
247 | Logging( kHLTLogDebug, "HLT::TPCCompDump::DoInit", "Arguments", "argv[0] == %s", argv[0] ); | |
248 | Logging(kHLTLogError, "HLT::TPCCompDump::DoInit", "Unknown Option", "Unknown option '%s'", argv[0] ); | |
249 | return EINVAL; | |
250 | } | |
251 | return 0; | |
252 | } | |
253 | ||
254 | int AliHLTTPCCompDumpComponent::DoDeinit() | |
255 | { | |
256 | // see header file for class documentation | |
257 | return 0; | |
258 | } | |
259 | ||
260 | int AliHLTTPCCompDumpComponent::DoEvent( const AliHLTComponent_EventData& evtData, const AliHLTComponent_BlockData* blocks, | |
261 | AliHLTComponent_TriggerData& /*trigData*/, AliHLTUInt8_t* , | |
262 | AliHLTUInt32_t& size, vector<AliHLTComponent_BlockData>& ) | |
263 | { | |
264 | // see header file for class documentation | |
265 | // Process an event | |
266 | // Loop over all input blocks in the event | |
267 | for ( unsigned long n = 0; n < evtData.fBlockCnt; n++ ) | |
268 | { | |
269 | AliHLTUInt8_t slice, patch; | |
270 | if ( blocks[n].fDataType == AliHLTTPCDefinitions::fgkClustersDataType ) | |
271 | { | |
272 | slice = AliHLTTPCDefinitions::GetMinSliceNr( blocks[n].fSpecification ); | |
273 | patch = AliHLTTPCDefinitions::GetMinPatchNr( blocks[n].fSpecification ); | |
274 | AliHLTTPCClusterData* clusters = (AliHLTTPCClusterData*)blocks[n].fPtr; | |
275 | HLTInfo( "Cluster block slice %u - patch %u - %lu clusters", (unsigned)slice, (unsigned)patch, (unsigned long)clusters->fSpacePointCnt ); | |
276 | for ( unsigned long ii=0; ii<clusters->fSpacePointCnt; ii++ ) | |
277 | { | |
278 | HLTInfo( " Cluster % 5lu: fX: %f - fY: %f - fZ: %f - fZ - fID: %u (0x%08X) - fPadRow: %u - fSigmaY2: %f - fSigmaZ2: %f - fCharge: %u - fUsed: %s - fTrackN: %d", | |
279 | ii, clusters->fSpacePoints[ii].fX, clusters->fSpacePoints[ii].fY, clusters->fSpacePoints[ii].fZ, clusters->fSpacePoints[ii].fID, clusters->fSpacePoints[ii].fID, (unsigned)clusters->fSpacePoints[ii].fPadRow, clusters->fSpacePoints[ii].fSigmaY2, clusters->fSpacePoints[ii].fSigmaZ2, clusters->fSpacePoints[ii].fCharge, (clusters->fSpacePoints[ii].fUsed ? "yes" : "no"), clusters->fSpacePoints[ii].fTrackN ); | |
280 | #if 0 | |
281 | Float_t xyzG[3] = { clusters->fSpacePoints[ii].fX, clusters->fSpacePoints[ii].fY, clusters->fSpacePoints[ii].fZ }; | |
282 | Float_t xyzR[3] = { clusters->fSpacePoints[ii].fX, clusters->fSpacePoints[ii].fY, clusters->fSpacePoints[ii].fZ }; | |
283 | AliHLTTPCTransform::LocHLT2Global( xyzG, slice, clusters->fSpacePoints[ii].fPadRow ); | |
284 | AliHLTTPCTransform::LocHLT2Raw( xyzG, slice, clusters->fSpacePoints[ii].fPadRow ); | |
285 | HLTInfo( " Global: fX: %f - fY: %f - fZ: %f - fZ", | |
286 | xyzG[0], xyzG[1], xyzG[2] ); | |
287 | HLTInfo( " Raw: fX: %f - fY: %f - fZ: %f - fZ", | |
288 | xyzR[0], xyzR[1], xyzR[2] ); | |
289 | #endif | |
290 | } | |
291 | HLTInfo( "" ); | |
292 | } | |
293 | if ( blocks[n].fDataType == AliHLTTPCDefinitions::fgkTrackSegmentsDataType || | |
294 | blocks[n].fDataType == AliHLTTPCDefinitions::fgkTracksDataType) | |
295 | { | |
296 | //fConverter.SetInputTracks( (AliHLTTPCTrackletData*)blocks[n].fPtr ); | |
297 | AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF; | |
298 | minSlice = AliHLTTPCDefinitions::GetMinSliceNr( blocks[n].fSpecification ); | |
299 | maxSlice = AliHLTTPCDefinitions::GetMaxSliceNr( blocks[n].fSpecification ); | |
300 | minPatch = AliHLTTPCDefinitions::GetMinPatchNr( blocks[n].fSpecification ); | |
301 | maxPatch = AliHLTTPCDefinitions::GetMaxPatchNr( blocks[n].fSpecification ); | |
302 | AliHLTTPCTrackletData* tracks = (AliHLTTPCTrackletData*)blocks[n].fPtr; | |
303 | AliHLTTPCTrackSegmentData* tracklet = tracks->fTracklets; | |
304 | HLTInfo( "Track block slices %u-%u - patches %u-%u - %lu tracks", | |
305 | (unsigned)minSlice, (unsigned)maxSlice, (unsigned)minPatch, (unsigned)maxPatch, | |
306 | (unsigned long)tracks->fTrackletCnt ); | |
307 | for ( unsigned long ii=0; ii<tracks->fTrackletCnt; ii++ ) | |
308 | { | |
309 | HLTInfo( " Track % 5lu: fX: %f - fY: %f - fZ: %f - fLastX: %f - fLastY: %f - fLastZ: %f - fPt: %f - fPsi: %f - fTgl: %f - fPterr: %f - fPsierr: %f - fTglerr: %f - fCharge: %d - fNPoints: %u", | |
310 | ii, tracklet->fX, tracklet->fY, tracklet->fZ, tracklet->fLastX, tracklet->fLastY, tracklet->fLastZ, tracklet->fPt, tracklet->fPsi, tracklet->fTgl, tracklet->fPterr, tracklet->fPsierr, tracklet->fTglerr, tracklet->fCharge, tracklet->fNPoints ); | |
311 | for ( unsigned long jj=0; jj<tracklet->fNPoints; jj++ ) | |
312 | { | |
313 | HLTInfo( " Point % 5lu: % 8u / 0x%08X", jj, tracklet->fPointIDs[jj], tracklet->fPointIDs[jj] ); | |
314 | } | |
315 | tracklet = (AliHLTTPCTrackSegmentData*) ( ((AliHLTUInt8_t*)tracklet)+sizeof(AliHLTTPCTrackSegmentData)+tracklet->fNPoints*sizeof(UInt_t) ); | |
316 | } | |
317 | ||
318 | } | |
319 | if ( blocks[n].fDataType == AliHLTTPCDefinitions::fgkClusterTracksModelDataType ) | |
320 | { | |
321 | AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF; | |
322 | minSlice = AliHLTTPCDefinitions::GetMinSliceNr( blocks[n].fSpecification ); | |
323 | maxSlice = AliHLTTPCDefinitions::GetMaxSliceNr( blocks[n].fSpecification ); | |
324 | minPatch = AliHLTTPCDefinitions::GetMinPatchNr( blocks[n].fSpecification ); | |
325 | maxPatch = AliHLTTPCDefinitions::GetMaxPatchNr( blocks[n].fSpecification ); | |
326 | unsigned long trackletCount = (blocks[n].fSize-sizeof(AliHLTUInt32_t)) / (sizeof(AliHLTTPCTrackModel)+AliHLTTPCTransform::GetNRows()*sizeof(AliHLTTPCClusterModel) ); | |
327 | HLTInfo( "Track model block version %u slices %u-%u - patches %u-%u - %lu tracks", | |
328 | (unsigned)*(AliHLTUInt32_t*)blocks[n].fPtr, | |
329 | (unsigned)minSlice, (unsigned)maxSlice, (unsigned)minPatch, (unsigned)maxPatch, | |
330 | (unsigned long)trackletCount ); | |
331 | AliHLTTPCTrackModel* trackModel = (AliHLTTPCTrackModel*)(((AliHLTUInt8_t*)blocks[n].fPtr)+sizeof(AliHLTUInt32_t)); | |
332 | for ( unsigned long ii=0; ii<trackletCount; ii++ ) | |
333 | { | |
334 | unsigned clusterCount=0; | |
335 | AliHLTTPCClusterModel* clusters = (AliHLTTPCClusterModel*) ( ((AliHLTUInt8_t*)trackModel)+sizeof(AliHLTTPCTrackModel) ); | |
336 | for ( unsigned long jj=0; jj<(unsigned long)AliHLTTPCTransform::GetNRows(); jj++ ) | |
337 | { | |
338 | if ( clusters[jj].fPresent ) | |
339 | clusterCount++; | |
340 | } | |
341 | HLTInfo( " Track Model % 5lu fKappa: %f - fPhi: %f - fD: %f - fZ0: %f - fTgl: %f - #clusters: %u", | |
342 | ii, trackModel->fKappa, trackModel->fPhi, trackModel->fD, trackModel->fZ0, trackModel->fTgl, clusterCount ); | |
343 | clusterCount=0; | |
344 | for ( unsigned long jj=0; jj<(unsigned long)AliHLTTPCTransform::GetNRows(); jj++ ) | |
345 | { | |
346 | if ( clusters[jj].fPresent ) | |
347 | { | |
348 | #ifdef MODELDEBUG | |
349 | HLTInfo( " Cluster % 05u: fID: %u (0x%08X) - fDTime: %f - fDPad: %f - fDCharge: %f - fDSigmaY: %f - fDSigmaZ: %f - fNPads: %u - fSlice: %hd - padrow: %lu - fPresent: %u", | |
350 | clusterCount, clusters[jj].fID, clusters[jj].fID, clusters[jj].fDTime, clusters[jj].fDPad, clusters[jj].fDCharge, clusters[jj].fDSigmaY, clusters[jj].fDSigmaZ, clusters[jj].fNPads, clusters[jj].fSlice, jj, (unsigned)clusters[jj].fPresent ); | |
351 | #else | |
352 | HLTInfo( " Cluster % 05u: fDTime: %f - fDPad: %f - fDCharge: %f - fDSigmaY: %f - fDSigmaZ: %f - fNPads: %u - fSlice: %hd - padrow: %lu - fPresent: %u", | |
353 | clusterCount, clusters[jj].fDTime, clusters[jj].fDPad, clusters[jj].fDCharge, clusters[jj].fDSigmaY, clusters[jj].fDSigmaZ, clusters[jj].fNPads, clusters[jj].fSlice, jj, (unsigned)clusters[jj].fPresent ); | |
354 | #endif | |
355 | clusterCount++; | |
356 | } | |
357 | } | |
358 | ||
359 | trackModel = (AliHLTTPCTrackModel*) ( ((AliHLTUInt8_t*)trackModel)+sizeof(AliHLTTPCTrackModel)+AliHLTTPCTransform::GetNRows()*sizeof(AliHLTTPCClusterModel) ); | |
360 | } | |
361 | ||
362 | } | |
363 | if ( blocks[n].fDataType == AliHLTTPCDefinitions::fgkRemainingClustersModelDataType ) | |
364 | { | |
365 | AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF; | |
366 | minSlice = AliHLTTPCDefinitions::GetMinSliceNr( blocks[n].fSpecification ); | |
367 | maxSlice = AliHLTTPCDefinitions::GetMaxSliceNr( blocks[n].fSpecification ); | |
368 | minPatch = AliHLTTPCDefinitions::GetMinPatchNr( blocks[n].fSpecification ); | |
369 | maxPatch = AliHLTTPCDefinitions::GetMaxPatchNr( blocks[n].fSpecification ); | |
370 | unsigned long clusterCount=0; | |
371 | HLTInfo( "Remaining cluster model block version %u", | |
372 | (unsigned)*(AliHLTUInt32_t*)blocks[n].fPtr ); | |
373 | AliHLTUInt8_t* readPtr = (AliHLTUInt8_t*)(((AliHLTUInt8_t*)blocks[n].fPtr)+sizeof(AliHLTUInt32_t)); | |
374 | for(Int_t slice=0; slice<36; slice++) | |
375 | { | |
376 | for(Int_t patch=0; patch < 6; patch++) | |
377 | { | |
378 | if ( !readPtr ) | |
379 | { | |
380 | readPtr++; | |
381 | continue; | |
382 | } | |
383 | unsigned rows = (unsigned)*readPtr; | |
384 | readPtr++; | |
385 | for ( unsigned ii=0; ii<rows; ii++ ) | |
386 | { | |
387 | AliHLTTPCRemainingRow* thisRow = (AliHLTTPCRemainingRow*)readPtr; | |
388 | clusterCount += thisRow->fNClusters; | |
389 | readPtr += sizeof(AliHLTTPCRemainingRow) + thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster); | |
390 | } | |
391 | } | |
392 | } | |
393 | HLTInfo( "Remaining cluster model block slices %u-%u - patches %u-%u - %lu clusters", | |
394 | (unsigned)minSlice, (unsigned)maxSlice, (unsigned)minPatch, (unsigned)maxPatch, | |
395 | clusterCount ); | |
396 | readPtr = (AliHLTUInt8_t*)(((AliHLTUInt8_t*)blocks[n].fPtr)+sizeof(AliHLTUInt32_t)); | |
397 | clusterCount = 0; | |
398 | for(Int_t slice=0; slice<36; slice++) | |
399 | { | |
400 | for(Int_t patch=0; patch < 6; patch++) | |
401 | { | |
402 | if ( !readPtr ) | |
403 | { | |
404 | readPtr++; | |
405 | continue; | |
406 | } | |
407 | unsigned rows = (unsigned)*readPtr; | |
408 | readPtr++; | |
409 | if ( rows ) | |
410 | HLTInfo( " Slice %d - Partition %d", slice, patch ); | |
411 | for ( unsigned ii=0; ii<rows; ii++ ) | |
412 | { | |
413 | AliHLTTPCRemainingRow* thisRow = (AliHLTTPCRemainingRow*)readPtr; | |
414 | for ( unsigned jj=0; jj<thisRow->fNClusters; jj++ ) | |
415 | { | |
416 | #ifdef MODELDEBUG | |
417 | HLTInfo( " Cluster % 5lu: fID: %u (0x%08X) - fPadRow: %u - fPad: %f - fTime: %f - fSigmaY2: %f - fSigmaZ2: %f - fCharge: %hu", | |
418 | clusterCount, thisRow->fClusters[jj].fID, thisRow->fClusters[jj].fID, (unsigned)thisRow->fPadRow, thisRow->fClusters[jj].fPad, thisRow->fClusters[jj].fTime, thisRow->fClusters[jj].fSigmaY2, thisRow->fClusters[jj].fSigmaZ2, thisRow->fClusters[jj].fCharge ); | |
419 | #else | |
420 | HLTInfo( " Cluster % 5lu: fPadRow: %u - fPad: %f - fTime: %f - fSigmaY2: %f - fSigmaZ2: %f - fCharge: %hu", | |
421 | clusterCount, (unsigned)thisRow->fPadRow, thisRow->fClusters[jj].fPad, thisRow->fClusters[jj].fTime, thisRow->fClusters[jj].fSigmaY2, thisRow->fClusters[jj].fSigmaZ2, thisRow->fClusters[jj].fCharge ); | |
422 | #endif | |
423 | } | |
424 | readPtr += sizeof(AliHLTTPCRemainingRow) + thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster); | |
425 | } | |
426 | } | |
427 | } | |
428 | } | |
429 | if ( blocks[n].fDataType == AliHLTTPCDefinitions::fgkClusterTracksCompressedDataType ) | |
430 | { | |
431 | AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF; | |
432 | minSlice = AliHLTTPCDefinitions::GetMinSliceNr( blocks[n].fSpecification ); | |
433 | maxSlice = AliHLTTPCDefinitions::GetMaxSliceNr( blocks[n].fSpecification ); | |
434 | minPatch = AliHLTTPCDefinitions::GetMinPatchNr( blocks[n].fSpecification ); | |
435 | maxPatch = AliHLTTPCDefinitions::GetMaxPatchNr( blocks[n].fSpecification ); | |
436 | HLTInfo( "Track model block slices %u-%u - patches %u-%u", | |
437 | (unsigned)minSlice, (unsigned)maxSlice, (unsigned)minPatch, (unsigned)maxPatch ); | |
438 | InitBitDataInput( (AliHLTUInt8_t*)blocks[n].fPtr, blocks[n].fSize ); | |
439 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
440 | AliHLTUInt8_t version; | |
441 | if ( !InputBits( version, 4 ) ) // Version information | |
442 | { | |
443 | HLTError( "Corrupt input data. Cannot read data version number at position %lu / %u", | |
444 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
445 | continue; | |
446 | } | |
447 | HLTInfo( "Data Format Version: %u", (unsigned)version ); | |
448 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
449 | AliHLTUInt8_t readShape; | |
450 | if ( !InputBit( readShape ) ) // Data format flag | |
451 | { | |
452 | HLTError( "Corrupt input data. Cannot read shape flag at position %lu / %u", | |
453 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
454 | continue; | |
455 | } | |
456 | HLTInfo( "Read shape: %s (%u)", (readShape ? "yes" : "no"), (unsigned)readShape ); | |
457 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
458 | Pad8Bits(); | |
459 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
460 | ||
461 | ||
462 | ||
463 | bool inputError=false; | |
464 | unsigned trackCount=0; | |
465 | ||
466 | while ( !EndOfBitInput() ) | |
467 | { | |
468 | AliHLTTPCTrackModel trackModel; | |
469 | memset( &trackModel, 0, sizeof(trackModel) ); | |
470 | if ( !InputBytes( (AliHLTUInt8_t*)&trackModel, sizeof(AliHLTTPCTrackModel) ) ) | |
471 | { | |
472 | HLTError( "Corrupt input data. Cannot read track model data at position %lu / %u", | |
473 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
474 | inputError = true; | |
475 | break; | |
476 | } | |
477 | HLTInfo( " Track Model % 5lu fKappa: %f - fPhi: %f - fD: %f - fZ0: %f - fTgl: %f", | |
478 | trackCount, trackModel.fKappa, trackModel.fPhi, trackModel.fD, trackModel.fZ0, trackModel.fTgl ); | |
479 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
480 | ||
481 | Int_t clustercount=0; | |
482 | for(Int_t i=0; i<AliHLTTPCTransform::GetNRows(); i++) | |
483 | { | |
484 | AliHLTTPCClusterModel cluster; | |
485 | memset( &cluster, 0, sizeof(cluster) ); | |
486 | AliHLTUInt8_t present; | |
487 | if ( !InputBit( present ) ) | |
488 | { | |
489 | HLTError( "Corrupt input data. Cannot read cluster presence bit at position %lu / %u", | |
490 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
491 | inputError = true; | |
492 | break; | |
493 | } | |
494 | HLTInfo( "Cluster %u present: %s (%u)", (unsigned)i, (present ? "yes" : "no"), (unsigned)present ); | |
495 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
496 | cluster.fPresent = present; | |
497 | if ( !present ) | |
498 | continue; | |
499 | if ( clustercount==0 ) | |
500 | { | |
501 | if ( !InputBits( slice,6 ) ) //Need 6 bits to encode slice number | |
502 | { | |
503 | HLTError( "Corrupt input data. Cannot read cluster slice number at position %lu / %u", | |
504 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
505 | inputError = true; | |
506 | break; | |
507 | } | |
508 | HLTInfo( "First cluster slice: %u", (unsigned)slice ); | |
509 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
510 | } | |
511 | else | |
512 | { | |
513 | AliHLTUInt8_t sliceChange; | |
514 | if ( !InputBit( sliceChange ) ) | |
515 | { | |
516 | HLTError( "Corrupt input data. Cannot read cluster slice change bit at position %lu / %u", | |
517 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
518 | inputError = true; | |
519 | break; | |
520 | } | |
521 | HLTInfo( "Slice change: %s (%u)", (sliceChange ? "yes" : "no"), (unsigned)sliceChange ); | |
522 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
523 | if ( sliceChange ) | |
524 | { //Change of slice | |
525 | if ( !InputBits( slice, 6 ) ) | |
526 | { | |
527 | HLTError( "Corrupt input data. Cannot read cluster slice number at position %lu / %u", | |
528 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
529 | inputError = true; | |
530 | break; | |
531 | } | |
532 | HLTInfo( "Changed cluster slice: %u", (unsigned)slice ); | |
533 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
534 | } | |
535 | } | |
536 | HLTInfo( "Slice. %d", slice ); | |
537 | cluster.fSlice = slice; | |
538 | if ( cluster.fSlice<0 || cluster.fSlice>35 ) | |
539 | { | |
540 | HLTError( "Inconsistent slice number %u (track %u, cluster %d)", cluster.fSlice, trackCount, i ); | |
541 | inputError = true; | |
542 | break; | |
543 | } | |
544 | AliHLTUInt8_t signBit; | |
545 | Int_t sign; | |
546 | AliHLTUInt64_t temp; | |
547 | Int_t val; | |
548 | //Read time information: | |
549 | if ( !InputBit( signBit ) ) | |
550 | { | |
551 | HLTError( "Corrupt input data. Cannot read DTime sign bit at position %lu / %u", | |
552 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
553 | inputError = true; | |
554 | break; | |
555 | } | |
556 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
557 | sign = signBit; | |
558 | sign = -1+sign*2; | |
559 | if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNTimeBits()-1 ) ) | |
560 | { | |
561 | HLTError( "Corrupt input data. Cannot read DTime data at position %lu / %u", | |
562 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
563 | inputError = true; | |
564 | break; | |
565 | } | |
566 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
567 | val = (Int_t)temp; | |
568 | cluster.fDTime = val*sign; | |
569 | ||
570 | ||
571 | //Read pad information: | |
572 | if ( !InputBit( signBit ) ) | |
573 | { | |
574 | HLTError( "Corrupt input data. Cannot read DPad sign bit at position %lu / %u", | |
575 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
576 | inputError = true; | |
577 | break; | |
578 | } | |
579 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
580 | sign = signBit; | |
581 | sign = -1+sign*2; | |
582 | if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNPadBits()-1 ) ) | |
583 | { | |
584 | HLTError( "Corrupt input data. Cannot read DPad data at position %lu / %u", | |
585 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
586 | inputError = true; | |
587 | break; | |
588 | } | |
589 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
590 | val = (Int_t)temp; | |
591 | cluster.fDPad = val*sign; | |
592 | ||
593 | // Read charge information: | |
594 | if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNChargeBits() ) ) | |
595 | { | |
596 | HLTError( "Corrupt input data. Cannot read charge data at position %lu / %u", | |
597 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
598 | inputError = true; | |
599 | break; | |
600 | } | |
601 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
602 | cluster.fDCharge = temp; | |
603 | ||
604 | if ( readShape ) | |
605 | { | |
606 | // Read shape information: | |
607 | if ( !InputBit( signBit ) ) | |
608 | { | |
609 | HLTError( "Corrupt input data. Cannot read DSigmaY sign bit at position %lu / %u", | |
610 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
611 | inputError = true; | |
612 | break; | |
613 | } | |
614 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
615 | sign = signBit; | |
616 | sign = -1+sign*2; | |
617 | if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1 ) ) | |
618 | { | |
619 | HLTError( "Corrupt input data. Cannot read DSigmaY data at position %lu / %u", | |
620 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
621 | inputError = true; | |
622 | break; | |
623 | } | |
624 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
625 | val = (Int_t)temp; | |
626 | cluster.fDSigmaY = val*sign; | |
627 | ||
628 | if ( !InputBit( signBit ) ) | |
629 | { | |
630 | HLTError( "Corrupt input data. Cannot read DSigmaZ sign bit at position %lu / %u", | |
631 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
632 | inputError = true; | |
633 | break; | |
634 | } | |
635 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
636 | sign = signBit; | |
637 | sign = -1+sign*2; | |
638 | if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1 ) ) | |
639 | { | |
640 | HLTError( "Corrupt input data. Cannot read DSigmaZ data at position %lu / %u", | |
641 | GetCurrentByteInputPosition(), GetCurrentBitInputPosition() ); | |
642 | inputError = true; | |
643 | break; | |
644 | } | |
645 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
646 | val = (Int_t)temp; | |
647 | cluster.fDSigmaZ = val*sign; | |
648 | } | |
649 | ||
650 | ||
651 | HLTInfo( " Cluster % 05u: fDTime: %f - fDPad: %f - fDCharge: %f - fDSigmaY: %f - fDSigmaZ: %f - fNPads: %u - fSlice: %hd - padrow: %lu - fPresent: %u", | |
652 | clustercount, cluster.fDTime, cluster.fDPad, cluster.fDCharge, cluster.fDSigmaY, cluster.fDSigmaZ, cluster.fNPads, cluster.fSlice, (unsigned long)i, (unsigned)cluster.fPresent ); | |
653 | ||
654 | ||
655 | clustercount++; | |
656 | ||
657 | ||
658 | } | |
659 | if ( inputError ) | |
660 | break; | |
661 | Pad8Bits(); | |
662 | HLTInfo( "Input position: %lu / %u (0x%02X)", GetCurrentByteInputPosition(), GetCurrentBitInputPosition(), (unsigned)GetCurrentInputByte() ); | |
663 | ||
664 | trackCount++; | |
665 | } | |
666 | if ( inputError ) | |
667 | continue; | |
668 | ||
669 | } | |
670 | if ( blocks[n].fDataType == AliHLTTPCDefinitions::fgkRemainingClustersCompressedDataType ) | |
671 | { | |
672 | AliHLTUInt8_t* inputPtr = (AliHLTUInt8_t*)blocks[n].fPtr; | |
673 | ||
674 | InitBitDataInput( inputPtr, blocks[n].fSize ); | |
675 | AliHLTUInt8_t version; | |
676 | if ( !InputBits( version, 4 ) ) // Version information | |
677 | { | |
678 | HLTError( "Corrupt input data. Cannot read data version number at position %u / %u", | |
679 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
680 | return EIO; | |
681 | } | |
682 | HLTInfo( "Remaining cluster data version: %u", (unsigned)version ); | |
683 | if ( version != 0 ) | |
684 | { | |
685 | HLTError( "Unsupported version %hu. Only version 0 supported currently.", version ); | |
686 | } | |
687 | Pad8Bits(); | |
688 | ||
689 | unsigned long clusterCount=0; | |
690 | for(Int_t slice=0; slice<=35; slice++) | |
691 | { | |
692 | for(Int_t patch=0; patch < 6; patch++) | |
693 | { | |
694 | UInt_t i; | |
695 | //Write number of padrows with clusters | |
696 | UInt_t nRows; | |
697 | if ( !InputBits( nRows, 8 ) ) | |
698 | { | |
699 | HLTError( "Corrupt input data. Cannot read padrow count at position %u / %u", | |
700 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
701 | return EIO; | |
702 | } | |
703 | HLTInfo( "slice %u patch %u: %u padrows", | |
704 | (unsigned)slice, (unsigned)patch, (unsigned)nRows ); | |
705 | if ( !nRows ) | |
706 | { | |
707 | continue; | |
708 | } | |
709 | //HLTInfo( " Slice %d - Partition %d", slice, patch ); | |
710 | for ( UInt_t jj=0; jj<nRows; jj++ ) | |
711 | { | |
712 | ||
713 | UInt_t padrow; | |
714 | if ( !InputBits(padrow,8) ) //Read padrow # | |
715 | { | |
716 | HLTError( "Corrupt input data. Cannot read padrow number at position %u / %u", | |
717 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
718 | return EIO; | |
719 | } | |
720 | HLTInfo( "Padrow: %u", (unsigned)padrow ); | |
721 | UInt_t nClusters; | |
722 | if ( !InputBits(nClusters,10) )//Read number of clusters on this padrow | |
723 | { | |
724 | HLTError( "Corrupt input data. Cannot read cluster count at position %u / %u", | |
725 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
726 | return EIO; | |
727 | } | |
728 | HLTInfo( " #Clusters: %u", (unsigned)nClusters ); | |
729 | for ( i=0; i<nClusters; i++ ) | |
730 | { | |
731 | //Read pad | |
732 | AliHLTTPCRemainingCluster cl; | |
733 | Int_t buff; | |
734 | if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNPadBitsRemaining()) ) | |
735 | { | |
736 | HLTError( "Corrupt input data. Cannot read cluster pad data at position %u / %u", | |
737 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
738 | return EIO; | |
739 | } | |
740 | cl.fPad = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor() ); | |
741 | ||
742 | //Read time | |
743 | if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNTimeBitsRemaining()) ) | |
744 | { | |
745 | HLTError( "Corrupt input data. Cannot read cluster time data at position %u / %u", | |
746 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
747 | return EIO; | |
748 | } | |
749 | cl.fTime = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor() ); | |
750 | ||
751 | //Read widths | |
752 | if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) ) | |
753 | { | |
754 | HLTError( "Corrupt input data. Cannot read cluster pad width data at position %u / %u", | |
755 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
756 | return EIO; | |
757 | } | |
758 | Float_t padw = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor() ); | |
759 | cl.fSigmaY2 = padw*padw; | |
760 | ||
761 | if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) ) | |
762 | { | |
763 | HLTError( "Corrupt input data. Cannot read cluster time width data at position %u / %u", | |
764 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
765 | return EIO; | |
766 | } | |
767 | Float_t timew = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor() ); | |
768 | cl.fSigmaZ2 = timew*timew; | |
769 | ||
770 | //Read charge | |
771 | if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNChargeBits()) ) | |
772 | { | |
773 | HLTError( "Corrupt input data. Cannot read cluster charge data at position %u / %u", | |
774 | (unsigned)GetCurrentByteInputPosition(), (unsigned)GetCurrentBitInputPosition() ); | |
775 | return EIO; | |
776 | } | |
777 | cl.fCharge = buff; | |
778 | ||
779 | HLTInfo( " Cluster % 5lu (% 5u): fPadRow: %u - fPad: %f - fTime: %f - fSigmaY2: %f - fSigmaZ2: %f - fCharge: %hu", | |
780 | clusterCount, (unsigned)i, (unsigned)padrow, cl.fPad, cl.fTime, cl.fSigmaY2, cl.fSigmaZ2, cl.fCharge ); | |
781 | clusterCount++; | |
782 | } | |
783 | } | |
784 | } | |
785 | ||
786 | } | |
787 | ||
788 | ||
789 | } | |
790 | ||
791 | } | |
792 | ||
793 | size = 0; | |
794 | return 0; | |
795 | } |