Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / HLT / TRD / AliTRDonlineTrackingDataContainer.cxx
1 #include <cstdlib>
2 #include "TString.h"
3 #include "AliHLTLogging.h"
4 #include "AliTRDonlineTrackingDataContainer.h"
5
6
7 ClassImp(AliTRDonlineTrackingDataContainer)
8
9 const Float_t AliTRDonlineTrackingDataContainer::fgkBinWidthY   = 160e-4; // 160 um
10
11 AliTRDonlineTrackingDataContainer::AliTRDonlineTrackingDataContainer() : AliHLTLogging(),
12   fGtuPtMultiplier(1.),
13   fStoreGtuInfo(kTRUE),
14   fLogPrefix(NULL)
15 {
16   fLogPrefix = new TString("");
17   Clear();
18 }
19
20 AliTRDonlineTrackingDataContainer::AliTRDonlineTrackingDataContainer(const AliTRDonlineTrackingDataContainer& /*cont*/) : AliHLTLogging(),
21   fGtuPtMultiplier(1.),
22   fStoreGtuInfo(kTRUE),
23   fLogPrefix(NULL)
24 {
25   fLogPrefix = new TString("");
26   Clear();
27 }
28
29 AliTRDonlineTrackingDataContainer::~AliTRDonlineTrackingDataContainer(){
30   if (fLogPrefix)
31     delete fLogPrefix;
32   fLogPrefix = NULL;
33 }
34
35 void AliTRDonlineTrackingDataContainer::Clear(const Option_t*) {
36   memset(fNumTracklets, 0, sizeof(UInt_t)*fgkNumChambers);
37   memset(fNumTracks, 0, sizeof(UInt_t)*fgkNumStacks);
38
39   memset(fSectorTrgWords, 0, sizeof(UInt_t)*fgkNumSectors);
40   memset(fStackTrgWords, 0, sizeof(ULong64_t)*fgkNumSectors*fgkNumStacksPerSector);
41
42   //## todo: only for debugging, may be removed without harm
43 //  memset(fTrackletWords, 0, sizeof(UInt_t)*fgkNumChambers*fgkMaxTrackletsPerChamber);
44 //  memset(fTrackletHCId, 0, sizeof(UInt_t)*fgkNumChambers*fgkMaxTrackletsPerChamber);
45 //  memset(fTrackWords, 0, sizeof(ULong64_t)*fgkNumStacks*fgkMaxTracksPerStack);
46 //  memset(fTrackExtWords, 0, sizeof(ULong64_t)*fgkNumStacks*fgkMaxTracksPerStack);
47 //  memset(fTrackTrackletWords, 0, sizeof(UInt_t)*fgkNumStacks*fgkMaxTracksPerStack*fgkNumLayers);
48 }
49
50 Int_t AliTRDonlineTrackingDataContainer::GetNumTracklets() {
51   Int_t count = 0;
52   for (UShort_t det = 0; det < fgkNumChambers; ++det)
53     count += fNumTracklets[det];
54   return count;
55 }
56
57 Int_t AliTRDonlineTrackingDataContainer::GetNumTracklets(UInt_t det) {
58   return fNumTracklets[det];
59 }
60
61 Int_t AliTRDonlineTrackingDataContainer::GetNumTracks() {
62   Int_t count = 0;
63   for (UShort_t stack = 0; stack < fgkNumStacks; ++stack)
64     count += fNumTracks[stack];
65   return count;
66 }
67
68 Int_t AliTRDonlineTrackingDataContainer::GetNumTracks(UShort_t stack){
69   return fNumTracks[stack];
70 }
71
72 Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinY(UInt_t det, UInt_t trackletIndex) {
73   UInt_t trackletWord = fTrackletWords[det][trackletIndex];
74   if (trackletWord & 0x1000) {
75     return -((~(trackletWord - 1)) & 0x1fff);
76   }
77   else {
78     return (trackletWord & 0x1fff);
79   }
80 }
81
82 Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinDy(UInt_t det, UInt_t trackletIndex) {
83   UInt_t trackletWord = fTrackletWords[det][trackletIndex];
84   if (trackletWord & (1 << 19))
85     return -((~((trackletWord >> 13) - 1)) & 0x7f);
86   else
87     return ((trackletWord >> 13) & 0x7f);
88 };
89
90 Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinZ(UInt_t det, UInt_t trackletIndex) {
91   return ((fTrackletWords[det][trackletIndex] >> 20) & 0xf);
92 }
93
94 Int_t AliTRDonlineTrackingDataContainer::GetTrackletPID(UInt_t det, UInt_t trackletIndex) {
95   return ((fTrackletWords[det][trackletIndex] >> 24) & 0xff);
96 };
97
98 Float_t AliTRDonlineTrackingDataContainer::GetTrackletLocalY(UInt_t det, UInt_t trackletIndex) {
99   return GetTrackletBinY(det, trackletIndex) * fgkBinWidthY;
100 }
101
102 AliESDTrdTracklet* AliTRDonlineTrackingDataContainer::GetTracklet(UInt_t det, UInt_t trackletIndex) {
103   AliESDTrdTracklet* trkl = NULL;
104   if ((det < fgkNumChambers) && (trackletIndex < fNumTracklets[det])){
105     trkl = new AliESDTrdTracklet(fTrackletWords[det][trackletIndex], fTrackletHCId[det][trackletIndex], -1);
106   }
107   return trkl;
108 }
109
110 AliESDTrdTrack* AliTRDonlineTrackingDataContainer::GetTrack(UInt_t stack, UInt_t trackIndex, Bool_t constructTracklets){
111   AliESDTrdTrack* trk = NULL;
112   if ((stack < fgkNumStacks) && (trackIndex < fNumTracks[stack])){
113     trk = new AliESDTrdTrack();
114     ULong64_t tw = fTrackWords[stack][trackIndex];
115     ULong64_t etw = fTrackWords[stack][trackIndex];
116     trk->SetLayerMask(GetTrackLayerMask(stack, trackIndex));
117     trk->SetA(GetTrackA(stack, trackIndex));
118     trk->SetB( (((tw >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
119     trk->SetC( (((tw >> 8)  &  0xffff) ^  0x8000) -  0x8000);
120     trk->SetPID(GetTrackPID(stack, trackIndex));
121     trk->SetSector(stack/5);
122     trk->SetStack(stack%5);
123     trk->SetLabel(-3);
124     trk->SetFlags((etw >> 52) & 0x7ff);
125     trk->SetReserved((etw >> 49) & 0x7);
126     trk->SetY((etw >> 36) & 0x1fff);
127     trk->SetTrackletIndex((etw >>  0) & 0x3f, 0);
128     trk->SetTrackletIndex((etw >>  6) & 0x3f, 1);
129     trk->SetTrackletIndex((etw >> 12) & 0x3f, 2);
130     trk->SetTrackletIndex((etw >> 18) & 0x3f, 3);
131     trk->SetTrackletIndex((etw >> 24) & 0x3f, 4);
132     trk->SetTrackletIndex((etw >> 30) & 0x3f, 5);
133
134     if (constructTracklets) {
135       for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
136         AliESDTrdTracklet * trkl = new AliESDTrdTracklet(GetTrackTrackletWord(stack, trackIndex, iLayer), 2*(stack*6 + iLayer));
137         trk->AddTrackletReference(trkl, iLayer);
138       }
139     }
140
141   } else {
142     HLTError("invalid stack (%d) or track index (%d) in GetTrack", stack, trackIndex);
143   }
144   return trk;
145 }
146
147 Double_t AliTRDonlineTrackingDataContainer::GetTrackPt(UInt_t stack, UInt_t trackIndex){
148
149   // calculate pt from a as done in hardware
150   const Int_t maskIdLut[64] = {
151     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,
152     -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1,  2, -1,  3,  4,  5,
153     -1, -1, -1, -1, -1, -1, -1,  6, -1, -1, -1,  7, -1,  8,  9, 10,
154     -1, -1, -1, 11, -1, 12, 13, 14, -1, 15, 16, 17, 18, 19, 20, 21
155   };
156
157   const Int_t c1Lut[32] = {
158     -2371, -2474, -2474, -2474, -2563, -2448, -2578, -2578,
159     -2578, -2670, -2557, -2578, -2578, -2670, -2557, -2578,
160     -2670, -2557, -2763, -2557, -2644, -2523,    -1,    -1,
161     -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1
162   };
163
164   Int_t a = GetTrackA(stack, trackIndex);
165   UShort_t lm = GetTrackLayerMask(stack, trackIndex);
166
167   if (a != 0) {
168     Int_t layerMaskId = maskIdLut[lm];
169     Int_t c1 = c1Lut[layerMaskId];
170     Int_t c1Ext = c1 << 8;
171     Int_t ptRawStage4 = c1Ext / ((a >> 2) != 0 ? (a >> 2) : 1 );
172     Int_t ptRawComb4 = ptRawStage4;
173     Int_t ptExtComb4 = (ptRawComb4 > 0) ? ptRawComb4 + 33 : ptRawComb4 - 30;
174
175     return ((-ptExtComb4/2) / 128.) * fGtuPtMultiplier;
176   }
177   else
178     return 0.;
179
180 }
181
182 UShort_t AliTRDonlineTrackingDataContainer::GetTrackLayerNum(UInt_t stack, UInt_t trackIndex) {
183   UShort_t num = 0;
184   UShort_t layerMask = GetTrackLayerMask(stack, trackIndex);
185   for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer)
186     if ((layerMask >> iLayer) & 1)
187       num++;
188   return num;
189 }
190
191 UInt_t AliTRDonlineTrackingDataContainer::GetTrackTrackletWord(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
192   return fTrackTrackletWords[stack][trackIndex][layer];
193 }
194
195
196 Int_t AliTRDonlineTrackingDataContainer::GetTrackTrackletBinY(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
197   UInt_t trackletWord = fTrackTrackletWords[stack][trackIndex][layer];
198   if (trackletWord & 0x1000) {
199     return -((~(trackletWord - 1)) & 0x1fff);
200   }
201   else {
202     return (trackletWord & 0x1fff);
203   }
204 }
205
206 Int_t AliTRDonlineTrackingDataContainer::GetTrackAddInfo(UShort_t stack, UInt_t trackIndex) {
207   return fTrackAddInfo[stack][trackIndex];
208 }
209
210 Float_t AliTRDonlineTrackingDataContainer::GetTrackTrackletLocalY(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
211   return GetTrackTrackletBinY(stack, trackIndex, layer) * fgkBinWidthY;
212 }
213
214 Int_t AliTRDonlineTrackingDataContainer::GetTrackTrackletBinZ(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
215   return ((fTrackTrackletWords[stack][trackIndex][layer] >> 20) & 0xf);
216 }
217
218 UShort_t AliTRDonlineTrackingDataContainer::GetTrackTrackletPID(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
219   return ((fTrackTrackletWords[stack][trackIndex][layer] >> 24) & 0xff);
220 }
221
222 Int_t AliTRDonlineTrackingDataContainer::AddTracklet(UInt_t HCId, UInt_t trackletWord) {
223   UShort_t det = HCId/2;
224   Int_t pos = fNumTracklets[det]++;
225   fTrackletWords[det][pos] = trackletWord;
226   fTrackletHCId[det][pos] = HCId;
227   return pos;
228 }
229
230 Int_t AliTRDonlineTrackingDataContainer::AddTracklet(const AliESDTrdTracklet* tracklet) {
231   return AddTracklet(tracklet->GetHCId(), tracklet->GetTrackletWord());
232 }
233
234 Int_t AliTRDonlineTrackingDataContainer::AddTrack(UShort_t stack,
235                                                   ULong64_t trackWord, ULong64_t extTrackWord,
236                                                   const UInt_t trackletWords[6], const Int_t addInfo){
237   Int_t pos = fNumTracks[stack]++;
238   fTrackWords[stack][pos] = trackWord;
239   fTrackExtWords[stack][pos] = extTrackWord;
240   fTrackAddInfo[stack][pos] = addInfo;
241   for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
242     fTrackTrackletWords[stack][pos][iLayer] = trackletWords[iLayer];
243   }
244   return pos;
245 }
246
247 Int_t AliTRDonlineTrackingDataContainer::AddTrack(const AliESDTrdTrack* track, Int_t addInfo) {
248
249   UInt_t trackletWords[fgkNumLayers];
250   UShort_t lm = track->GetLayerMask();
251   Bool_t checkOk = kTRUE;
252   for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
253     if ((lm >> iLayer) & 1){
254       if (track->GetTracklet(iLayer))
255         trackletWords[iLayer] = track->GetTracklet(iLayer)->GetTrackletWord();
256       else
257         checkOk = kFALSE;  // inconsistency between layer mask and tracklet pointers: do not use this track
258     } else
259       trackletWords[iLayer] = fgkInvalidTrackletWord;
260   }
261
262   if (checkOk){
263     return AddTrack(track->GetSector()*5 + track->GetStack(),
264                     track->GetTrackWord(0), track->GetExtendedTrackWord(0), trackletWords, addInfo);
265   } else {
266     // DbgLog("ERROR", "Ignoring GTU track with inconsistency between layer mask and tracklet pointers");
267     printf("<ERROR> Ignoring GTU track with inconsistency between layer mask and tracklet pointers\n");
268     return -1;
269   }
270
271 }
272
273 void AliTRDonlineTrackingDataContainer::SetTrackAddInfo(UShort_t stack, UInt_t trackIndex, Int_t addInfo) {
274   fTrackAddInfo[stack][trackIndex] = addInfo;
275 }
276
277 void AliTRDonlineTrackingDataContainer::SetGtuPtMultiplierFromMagField(Double_t magField) {
278   if (magField > 0)
279     fGtuPtMultiplier = -1.;
280   else
281     fGtuPtMultiplier = 1.;
282 }
283
284 void AliTRDonlineTrackingDataContainer::PrintBuffer(const void* buffer, UInt_t sizeInBytes, const char* identifier) {
285
286   UInt_t* buf = (UInt_t*)buffer;
287   UInt_t currPos = 0;
288   TString str("");
289   TString ident(identifier);
290
291   HLTDebug("BUFFER DUMP for <%s>", ident.Data());
292
293   while (currPos < sizeInBytes/4){
294
295     str = Form("%06d: 0x%08x  ", currPos, buf[currPos]);
296
297     if (currPos == 0){  // leading magic constant
298
299       if (buf[currPos++] == fgkLeadingMagicConst)
300         str += "correct leading magic constant";
301       else
302         str += Form("incorrect leading magic constant, should be 0x%08x",
303                     fgkLeadingMagicConst);
304     }
305
306     if (currPos == sizeInBytes/4 - 1){
307
308       if (buf[sizeInBytes/4 - 1] == fgkTrailingMagicConst)
309         str += "correct trailing magic constant";
310       else
311         str += Form("incorrect trailing magic constant, should be 0x%08x",
312                     fgkTrailingMagicConst);
313     }
314
315     currPos++;
316
317     HLTDebug(str.Data());
318
319   }
320
321 }
322
323 void AliTRDonlineTrackingDataContainer::PrintSummary(const char* identifier){
324
325   TString ident(identifier);
326
327   HLTDebug("TRDGM AliTRDonlineTrackingDataContainer <%s> summary: %5d tracklets, %2d tracks, %6ld bytes comp. mem size",
328            ident.Data(), GetNumTracklets(), GetNumTracks(), DataWordsNeeded()*sizeof(UInt_t));
329
330 }
331
332 inline UInt_t AliTRDonlineTrackingDataContainer::MakeDataHeader(){
333   if (fStoreGtuInfo)
334     return (fgkHeaderTypeData << 28) | (1 << 16) | DataWordsNeeded();
335   else
336     return (fgkHeaderTypeData << 28) | DataWordsNeeded();
337 }
338
339 inline UInt_t AliTRDonlineTrackingDataContainer::MakeStackHeader(UShort_t stack,
340                                                                  Bool_t trackletsPresent,
341                                                                  Bool_t tracksPresent,
342                                                                  UInt_t size){
343   return
344     (fgkHeaderTypeStack << 28) |
345     (((tracksPresent) ? 1 : 0) << 27) |
346     (((trackletsPresent) ? 1 : 0) << 26) |
347     ((stack & 0xff) << 16) | (size & 0xffff);
348 }
349
350 inline Int_t AliTRDonlineTrackingDataContainer::StackFromStackHeader(UInt_t stackHeader) {
351   return (stackHeader >> 16) & 0xff;
352 }
353
354 inline UInt_t AliTRDonlineTrackingDataContainer::SizeFromStackHeader(UInt_t stackHeader) {
355   return stackHeader & 0xffff;
356 }
357
358 inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackletHeader(UShort_t halfChamber){
359   return (fgkHeaderTypeTracklet << 28) | ((halfChamber & 0xfff) << 16) | 0x2;
360 }
361
362 inline Int_t AliTRDonlineTrackingDataContainer::HCIdFromTrackletHeader(UInt_t trackletHeader) {
363   return (trackletHeader >> 16) & 0xfff;
364 }
365
366 inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackHeader(UShort_t stack){
367   return (fgkHeaderTypeTrack << 28) | ((stack & 0xff) << 16) | 12;
368 }
369
370 inline UInt_t AliTRDonlineTrackingDataContainer::MakeGtuHeader(Bool_t storeInfo){
371   if (storeInfo)
372     return (fgkHeaderTypeGtu << 28) | (1 << 16) | (1 + 18 + 2*90);
373   else
374     return (fgkHeaderTypeGtu << 28) | 1;
375 }
376
377 inline Bool_t AliTRDonlineTrackingDataContainer::StoreGtuInfoFromDataHeader(UInt_t dataHeader){
378   return ((dataHeader >> 16) & 1);
379 }
380
381 inline Bool_t AliTRDonlineTrackingDataContainer::GtuInfoPresentFromGtuHeader(UInt_t gtuHeader){
382   return ((gtuHeader >> 16) & 1);
383 }
384
385 inline UInt_t AliTRDonlineTrackingDataContainer::DataWordsNeeded() {
386
387   UInt_t size = 0;
388
389   size += 1;                              // leading magic word
390   size += 1;                              // overall data header
391   size += 90;                             // stack headers
392   size += GetNumTracklets()*(1 + 1);      // tracklets (mark + trackword)
393   size += GetNumTracks()*(1 + 4 + 1 + 6); // GTU tracks (mark + trackword[2] + exttrackword[2] + addInfo + 6*trackletword)
394   size += 1;                              // crosscheck word
395   size += 1;                              // trailing magic word
396
397   if (fStoreGtuInfo)
398     size += 1 + 18 + 2*90;                // trigger header + 18 sector trigger words, 90 stack tracking done words[2]
399   else
400     size += 1;                            // trigger header only
401
402   return size;
403 }
404
405 inline UInt_t calcCheck(UInt_t prevCrc, UInt_t c) {
406   // CCITT 16 bit (X^16 + X^12 + X^5 + 1).
407   UInt_t crc = prevCrc;
408   crc  = (unsigned char)(crc >> 8) | (crc << 8);
409   crc ^= c;
410   crc ^= (unsigned char)(crc & 0xff) >> 4;
411   crc ^= (crc << 8) << 4;
412   crc ^= ((crc & 0xff) << 4) << 1;
413   return (crc);
414 }
415
416 Bool_t AliTRDonlineTrackingDataContainer::Compress(void* &buffer, UInt_t &sizeInBytes){
417
418   // TString ptrInfo("COMPRESS CALLED: [");
419
420   UInt_t bufSize = sizeof(UInt_t)*DataWordsNeeded();
421   UInt_t* buf = (UInt_t*)malloc(bufSize);
422   UInt_t crosscheck = fgkCrosscheckSeed;
423   UInt_t lastStackHeaderPos;
424
425   if (!buf){
426     HLTError("Could not allocate %d bytes for buffer", bufSize);
427     return kFALSE;
428   }
429
430   memset(buf, 0, bufSize);
431   // ptrInfo += Form(" memset(%p, 0, %d) -> %p - %p, ", buf, bufSize, buf, (char*)buf + bufSize);
432   UInt_t currPos = 0;
433   UInt_t det;
434
435   // ptrInfo += Form(" lowest write addr: %p, ", &(buf[currPos]));
436   buf[currPos++] = fgkLeadingMagicConst;
437   buf[currPos++] = MakeDataHeader();
438   for (UShort_t iStack = 0; iStack < 90; ++iStack){
439
440     // add stack info
441     lastStackHeaderPos = currPos;
442     buf[currPos++] = MakeStackHeader(iStack, 1, 1, 0);
443
444     // add tracklet infos
445     for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
446       det = iStack*fgkNumLayers + iLayer;
447       for (UInt_t iTrkl = 0; iTrkl < fNumTracklets[det]; ++iTrkl){
448         buf[currPos++] = MakeTrackletHeader(fTrackletHCId[det][iTrkl]);
449         buf[currPos++] = fTrackletWords[det][iTrkl];
450       }
451     }
452
453     // add track infos
454     for (UInt_t iTrk = 0; iTrk < fNumTracks[iStack]; ++iTrk){
455       buf[currPos++] = MakeTrackHeader(iStack);
456       buf[currPos++] = fTrackWords[iStack][iTrk] & 0xffffffff;
457       buf[currPos++] = (fTrackWords[iStack][iTrk] >> 32) & 0xffffffff;
458       buf[currPos++] = fTrackExtWords[iStack][iTrk] & 0xffffffff;
459       buf[currPos++] = (fTrackExtWords[iStack][iTrk] >> 32) & 0xffffffff;
460       buf[currPos++] = fTrackAddInfo[iStack][iTrk];
461       for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer)
462         buf[currPos++] = fTrackTrackletWords[iStack][iTrk][iLayer];
463     }
464
465     buf[lastStackHeaderPos] = MakeStackHeader(iStack,
466                                               ((GetNumTracklets() > 0) ? 1 : 0),
467                                               ((GetNumTracks() > 0) ? 1 : 0),
468                                               currPos - lastStackHeaderPos); // update size  //## todo: check off-by-one issues
469
470   } // loop over all stacks
471
472   // add Gtu header info
473   buf[currPos++] = MakeGtuHeader(fStoreGtuInfo);
474   if (fStoreGtuInfo){
475     // store trigger info from GTU headers
476     for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector)
477       buf[currPos++] = fSectorTrgWords[iSector];
478     for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector){
479       for (UShort_t iStack = 0; iStack < fgkNumStacksPerSector; ++iStack){
480         buf[currPos++] = fStackTrgWords[iSector][iStack] & 0xffffffff;
481         buf[currPos++] = (fStackTrgWords[iSector][iStack] >> 32) & 0xffffffff;
482       }
483     }
484   }
485
486   // calc crosscheck
487   for (UInt_t ofs = 1; ofs < currPos; ++ofs)
488     crosscheck = calcCheck(crosscheck, buf[ofs]);
489
490   buf[currPos++] = crosscheck;
491   buf[currPos++] = fgkTrailingMagicConst;
492   // ptrInfo += Form(" highest write addr: %p, %d]", &(buf[currPos - 1]), (currPos-1)*4);
493
494   if (sizeof(UInt_t)*currPos != bufSize){
495     HLTError("inconsistent memory layout! (%ld %d)", sizeof(UInt_t)*currPos, bufSize);
496   }
497
498 //  for (UInt_t ofs = 0; ofs < bufSize/4; ++ofs)
499 //    printf("%04d: 0x%08x\n", ofs, buf[ofs]);
500
501   buffer = buf;
502   sizeInBytes = bufSize;
503
504   // DbgLog("", ptrInfo.Data());
505
506   return kFALSE;
507 }
508
509 Bool_t AliTRDonlineTrackingDataContainer::Decompress(const void* buffer, UInt_t sizeInBytes, Bool_t cumulative, Bool_t verbose) {
510
511   // TString ptrInfo(Form("DECOMPRESS CALLED: [buf: %p, size: %d - %p - %p, ", buffer, sizeInBytes, buffer, (char*)buffer + sizeInBytes));
512
513   UInt_t* buf = (UInt_t*)buffer;
514   UInt_t currPos = 0;
515   UInt_t crosscheck = fgkCrosscheckSeed;
516   UInt_t stackHeader;
517   UInt_t gtuInfoHeader = 0;
518   Int_t stack = 0;
519   UInt_t size = 0;
520
521   if (!cumulative)
522     Clear();
523
524   if (buf[currPos++] != fgkLeadingMagicConst){
525     HLTError("invalid data: leading mark should be 0x%08x, is 0x%08x", fgkLeadingMagicConst, buf[currPos - 1]);
526     return kFALSE;
527   } else if (verbose)
528     HLTError("0x%05d: 0x%08x  correct leading mark", currPos, buf[currPos - 1]);
529
530   UInt_t overallDataHeader = buf[currPos++];
531   if ((overallDataHeader >> 28) != fgkHeaderTypeData){
532     HLTError("invalid data header: 0x%08x", overallDataHeader);
533     return kFALSE;
534   } else {
535     fStoreGtuInfo = StoreGtuInfoFromDataHeader(overallDataHeader);
536   }
537
538   if (buf[sizeInBytes/4 - 1] != fgkTrailingMagicConst){
539     HLTError("invalid data: trailing mark should be 0x%08x, is 0x%08x", fgkTrailingMagicConst, buf[sizeInBytes/4 - 1]);
540     return kFALSE;
541   } else if (verbose){
542     HLTDebug("0x%05d: 0x%08x  correct trailing mark", sizeInBytes/4 - 1, buf[sizeInBytes/4 - 1]);
543   }
544
545   while (currPos < (sizeInBytes/4) - 2) { // stack-level loop
546
547     stackHeader = buf[currPos++];
548
549     // stack header + encapsulated tracklet and track data
550     if (((stackHeader >> 28) & 0xf) == fgkHeaderTypeStack){
551       stack = StackFromStackHeader(stackHeader);
552       size = SizeFromStackHeader(stackHeader);
553
554       if (verbose){
555         HLTDebug("STACK HEADER: 0x%08x - S%02d-%d, size: %d  [checksum: 0x%08x]", stackHeader, stack/5, stack%5, size, buf[sizeInBytes/4 - 2]);
556       }
557
558       while (currPos < sizeInBytes/4 - 2){
559
560         if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeTracklet){
561           UInt_t trklHdr = buf[currPos++];
562           UInt_t trklWord = buf[currPos++];
563           AddTracklet(HCIdFromTrackletHeader(trklHdr), trklWord);
564           if (verbose){
565             HLTDebug("Tracklet: 0x%08x 0x%08x", trklHdr, trklWord);
566           }
567         } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeTrack){
568           UInt_t trkHdr = buf[currPos++];
569           if (trkHdr == 0)
570             HLTError("ERROR", "invalid track header");
571           ULong64_t trackWord = buf[currPos++];
572           trackWord |= ((ULong64_t)buf[currPos++] << 32);
573           ULong64_t extTrackWord = buf[currPos++];
574           extTrackWord |= ((ULong64_t)buf[currPos++] << 32);
575           UInt_t addInfo = buf[currPos++];
576           UInt_t trackletWords[6];
577           for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
578             trackletWords[iLayer] = buf[currPos++];
579           }
580           AddTrack(stack, trackWord, extTrackWord, trackletWords, addInfo);
581           if (verbose){
582             HLTDebug("GTU track: 0x%016llx 0x%016llx", trackWord, extTrackWord);
583           }
584         } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeStack){
585         //printf("next stack header\n");
586           break;
587         } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeGtu){
588           gtuInfoHeader = buf[currPos];
589           break;
590         } else {
591           HLTError("unknown data block: 0x%08x", buf[currPos]);
592           break;
593         }
594       }
595
596       if (gtuInfoHeader)
597         break;
598
599     } else {
600       HLTError("invalid header while analyzing tracking data block: 0x%08x - S%02d-%d, size: %d",
601                            stackHeader, stack/5, stack%5, size);
602       break;
603     }
604
605   } // stack-level loop
606
607   // GTU header data loop
608   if (((gtuInfoHeader >> 28) & 0xf) == fgkHeaderTypeGtu) {
609     UInt_t gtuHeader = buf[currPos++];
610     HLTInfo("gtu header: 0x%08x", gtuHeader);
611     if (GtuInfoPresentFromGtuHeader(gtuHeader)){
612       for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector)
613         fSectorTrgWords[iSector] = buf[currPos++];
614       for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector){
615         for (UShort_t iStack = 0; iStack < fgkNumStacksPerSector; ++iStack){
616           UInt_t low = buf[currPos++];
617           UInt_t high = buf[currPos++];
618           fStackTrgWords[iSector][iStack] = ((ULong64_t)high << 32) | low;
619         }
620       }
621     }
622   } else {
623     HLTError("expected GtuInfoHeader at position %d, but is 0x%08x",
624                          currPos, buf[currPos]);
625   }
626
627   if (currPos != (sizeInBytes/4) - 2){
628     HLTError("invalid read position after analyzing tracking data block.");
629     return kFALSE;
630   }
631
632   for (UInt_t ofs = 1; ofs < sizeInBytes/4 - 2; ++ofs)
633     crosscheck = calcCheck(crosscheck, buf[ofs]);
634
635   if (crosscheck != buf[sizeInBytes/4 - 2]){  // compare recalculated checksum with the one in the data
636     HLTError("decompress checksum mismatch: should be 0x%08x, is 0x%08x",
637            crosscheck, buf[sizeInBytes/4 - 2]);
638     return kFALSE;
639   }
640
641   // HLTDebug(ptrInfo.Data());
642
643   return kTRUE;
644
645 }
646
647