3 #include "AliHLTLogging.h"
4 #include "AliTRDonlineTrackingDataContainer.h"
7 ClassImp(AliTRDonlineTrackingDataContainer)
9 const Float_t AliTRDonlineTrackingDataContainer::fgkBinWidthY = 160e-4; // 160 um
11 AliTRDonlineTrackingDataContainer::AliTRDonlineTrackingDataContainer() : AliHLTLogging(),
16 fLogPrefix = new TString("");
20 AliTRDonlineTrackingDataContainer::AliTRDonlineTrackingDataContainer(const AliTRDonlineTrackingDataContainer& /*cont*/) : AliHLTLogging(),
25 fLogPrefix = new TString("");
29 AliTRDonlineTrackingDataContainer::~AliTRDonlineTrackingDataContainer(){
35 void AliTRDonlineTrackingDataContainer::Clear(const Option_t*) {
36 memset(fNumTracklets, 0, sizeof(UInt_t)*fgkNumChambers);
37 memset(fNumTracks, 0, sizeof(UInt_t)*fgkNumStacks);
39 memset(fSectorTrgWords, 0, sizeof(UInt_t)*fgkNumSectors);
40 memset(fStackTrgWords, 0, sizeof(ULong64_t)*fgkNumSectors*fgkNumStacksPerSector);
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);
50 Int_t AliTRDonlineTrackingDataContainer::GetNumTracklets() {
52 for (UShort_t det = 0; det < fgkNumChambers; ++det)
53 count += fNumTracklets[det];
57 Int_t AliTRDonlineTrackingDataContainer::GetNumTracklets(UInt_t det) {
58 return fNumTracklets[det];
61 Int_t AliTRDonlineTrackingDataContainer::GetNumTracks() {
63 for (UShort_t stack = 0; stack < fgkNumStacks; ++stack)
64 count += fNumTracks[stack];
68 Int_t AliTRDonlineTrackingDataContainer::GetNumTracks(UShort_t stack){
69 return fNumTracks[stack];
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);
78 return (trackletWord & 0x1fff);
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);
87 return ((trackletWord >> 13) & 0x7f);
90 Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinZ(UInt_t det, UInt_t trackletIndex) {
91 return ((fTrackletWords[det][trackletIndex] >> 20) & 0xf);
94 Int_t AliTRDonlineTrackingDataContainer::GetTrackletPID(UInt_t det, UInt_t trackletIndex) {
95 return ((fTrackletWords[det][trackletIndex] >> 24) & 0xff);
98 Float_t AliTRDonlineTrackingDataContainer::GetTrackletLocalY(UInt_t det, UInt_t trackletIndex) {
99 return GetTrackletBinY(det, trackletIndex) * fgkBinWidthY;
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);
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);
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);
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);
142 HLTError("invalid stack (%d) or track index (%d) in GetTrack", stack, trackIndex);
147 Double_t AliTRDonlineTrackingDataContainer::GetTrackPt(UInt_t stack, UInt_t trackIndex){
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
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
164 Int_t a = GetTrackA(stack, trackIndex);
165 UShort_t lm = GetTrackLayerMask(stack, trackIndex);
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;
175 return ((-ptExtComb4/2) / 128.) * fGtuPtMultiplier;
182 UShort_t AliTRDonlineTrackingDataContainer::GetTrackLayerNum(UInt_t stack, UInt_t trackIndex) {
184 UShort_t layerMask = GetTrackLayerMask(stack, trackIndex);
185 for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer)
186 if ((layerMask >> iLayer) & 1)
191 UInt_t AliTRDonlineTrackingDataContainer::GetTrackTrackletWord(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
192 return fTrackTrackletWords[stack][trackIndex][layer];
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);
202 return (trackletWord & 0x1fff);
206 Int_t AliTRDonlineTrackingDataContainer::GetTrackAddInfo(UShort_t stack, UInt_t trackIndex) {
207 return fTrackAddInfo[stack][trackIndex];
210 Float_t AliTRDonlineTrackingDataContainer::GetTrackTrackletLocalY(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
211 return GetTrackTrackletBinY(stack, trackIndex, layer) * fgkBinWidthY;
214 Int_t AliTRDonlineTrackingDataContainer::GetTrackTrackletBinZ(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
215 return ((fTrackTrackletWords[stack][trackIndex][layer] >> 20) & 0xf);
218 UShort_t AliTRDonlineTrackingDataContainer::GetTrackTrackletPID(UInt_t stack, UInt_t trackIndex, UShort_t layer) {
219 return ((fTrackTrackletWords[stack][trackIndex][layer] >> 24) & 0xff);
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;
230 Int_t AliTRDonlineTrackingDataContainer::AddTracklet(const AliESDTrdTracklet* tracklet) {
231 return AddTracklet(tracklet->GetHCId(), tracklet->GetTrackletWord());
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];
247 Int_t AliTRDonlineTrackingDataContainer::AddTrack(const AliESDTrdTrack* track, Int_t addInfo) {
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();
257 checkOk = kFALSE; // inconsistency between layer mask and tracklet pointers: do not use this track
259 trackletWords[iLayer] = fgkInvalidTrackletWord;
263 return AddTrack(track->GetSector()*5 + track->GetStack(),
264 track->GetTrackWord(0), track->GetExtendedTrackWord(0), trackletWords, addInfo);
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");
273 void AliTRDonlineTrackingDataContainer::SetTrackAddInfo(UShort_t stack, UInt_t trackIndex, Int_t addInfo) {
274 fTrackAddInfo[stack][trackIndex] = addInfo;
277 void AliTRDonlineTrackingDataContainer::SetGtuPtMultiplierFromMagField(Double_t magField) {
279 fGtuPtMultiplier = -1.;
281 fGtuPtMultiplier = 1.;
284 void AliTRDonlineTrackingDataContainer::PrintBuffer(const void* buffer, UInt_t sizeInBytes, const char* identifier) {
286 UInt_t* buf = (UInt_t*)buffer;
289 TString ident(identifier);
291 HLTDebug("BUFFER DUMP for <%s>", ident.Data());
293 while (currPos < sizeInBytes/4){
295 str = Form("%06d: 0x%08x ", currPos, buf[currPos]);
297 if (currPos == 0){ // leading magic constant
299 if (buf[currPos++] == fgkLeadingMagicConst)
300 str += "correct leading magic constant";
302 str += Form("incorrect leading magic constant, should be 0x%08x",
303 fgkLeadingMagicConst);
306 if (currPos == sizeInBytes/4 - 1){
308 if (buf[sizeInBytes/4 - 1] == fgkTrailingMagicConst)
309 str += "correct trailing magic constant";
311 str += Form("incorrect trailing magic constant, should be 0x%08x",
312 fgkTrailingMagicConst);
317 HLTDebug(str.Data());
323 void AliTRDonlineTrackingDataContainer::PrintSummary(const char* identifier){
325 TString ident(identifier);
327 HLTDebug("TRDGM AliTRDonlineTrackingDataContainer <%s> summary: %5d tracklets, %2d tracks, %6ld bytes comp. mem size",
328 ident.Data(), GetNumTracklets(), GetNumTracks(), DataWordsNeeded()*sizeof(UInt_t));
332 inline UInt_t AliTRDonlineTrackingDataContainer::MakeDataHeader(){
334 return (fgkHeaderTypeData << 28) | (1 << 16) | DataWordsNeeded();
336 return (fgkHeaderTypeData << 28) | DataWordsNeeded();
339 inline UInt_t AliTRDonlineTrackingDataContainer::MakeStackHeader(UShort_t stack,
340 Bool_t trackletsPresent,
341 Bool_t tracksPresent,
344 (fgkHeaderTypeStack << 28) |
345 (((tracksPresent) ? 1 : 0) << 27) |
346 (((trackletsPresent) ? 1 : 0) << 26) |
347 ((stack & 0xff) << 16) | (size & 0xffff);
350 inline Int_t AliTRDonlineTrackingDataContainer::StackFromStackHeader(UInt_t stackHeader) {
351 return (stackHeader >> 16) & 0xff;
354 inline UInt_t AliTRDonlineTrackingDataContainer::SizeFromStackHeader(UInt_t stackHeader) {
355 return stackHeader & 0xffff;
358 inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackletHeader(UShort_t halfChamber){
359 return (fgkHeaderTypeTracklet << 28) | ((halfChamber & 0xfff) << 16) | 0x2;
362 inline Int_t AliTRDonlineTrackingDataContainer::HCIdFromTrackletHeader(UInt_t trackletHeader) {
363 return (trackletHeader >> 16) & 0xfff;
366 inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackHeader(UShort_t stack){
367 return (fgkHeaderTypeTrack << 28) | ((stack & 0xff) << 16) | 12;
370 inline UInt_t AliTRDonlineTrackingDataContainer::MakeGtuHeader(Bool_t storeInfo){
372 return (fgkHeaderTypeGtu << 28) | (1 << 16) | (1 + 18 + 2*90);
374 return (fgkHeaderTypeGtu << 28) | 1;
377 inline Bool_t AliTRDonlineTrackingDataContainer::StoreGtuInfoFromDataHeader(UInt_t dataHeader){
378 return ((dataHeader >> 16) & 1);
381 inline Bool_t AliTRDonlineTrackingDataContainer::GtuInfoPresentFromGtuHeader(UInt_t gtuHeader){
382 return ((gtuHeader >> 16) & 1);
385 inline UInt_t AliTRDonlineTrackingDataContainer::DataWordsNeeded() {
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
398 size += 1 + 18 + 2*90; // trigger header + 18 sector trigger words, 90 stack tracking done words[2]
400 size += 1; // trigger header only
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);
410 crc ^= (unsigned char)(crc & 0xff) >> 4;
411 crc ^= (crc << 8) << 4;
412 crc ^= ((crc & 0xff) << 4) << 1;
416 Bool_t AliTRDonlineTrackingDataContainer::Compress(void* &buffer, UInt_t &sizeInBytes){
418 // TString ptrInfo("COMPRESS CALLED: [");
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;
426 HLTError("Could not allocate %d bytes for buffer", bufSize);
430 memset(buf, 0, bufSize);
431 // ptrInfo += Form(" memset(%p, 0, %d) -> %p - %p, ", buf, bufSize, buf, (char*)buf + bufSize);
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){
441 lastStackHeaderPos = currPos;
442 buf[currPos++] = MakeStackHeader(iStack, 1, 1, 0);
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];
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];
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
470 } // loop over all stacks
472 // add Gtu header info
473 buf[currPos++] = MakeGtuHeader(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;
487 for (UInt_t ofs = 1; ofs < currPos; ++ofs)
488 crosscheck = calcCheck(crosscheck, buf[ofs]);
490 buf[currPos++] = crosscheck;
491 buf[currPos++] = fgkTrailingMagicConst;
492 // ptrInfo += Form(" highest write addr: %p, %d]", &(buf[currPos - 1]), (currPos-1)*4);
494 if (sizeof(UInt_t)*currPos != bufSize){
495 HLTError("inconsistent memory layout! (%ld %d)", sizeof(UInt_t)*currPos, bufSize);
498 // for (UInt_t ofs = 0; ofs < bufSize/4; ++ofs)
499 // printf("%04d: 0x%08x\n", ofs, buf[ofs]);
502 sizeInBytes = bufSize;
504 // DbgLog("", ptrInfo.Data());
509 Bool_t AliTRDonlineTrackingDataContainer::Decompress(const void* buffer, UInt_t sizeInBytes, Bool_t cumulative, Bool_t verbose) {
511 // TString ptrInfo(Form("DECOMPRESS CALLED: [buf: %p, size: %d - %p - %p, ", buffer, sizeInBytes, buffer, (char*)buffer + sizeInBytes));
513 UInt_t* buf = (UInt_t*)buffer;
515 UInt_t crosscheck = fgkCrosscheckSeed;
517 UInt_t gtuInfoHeader = 0;
524 if (buf[currPos++] != fgkLeadingMagicConst){
525 HLTError("invalid data: leading mark should be 0x%08x, is 0x%08x", fgkLeadingMagicConst, buf[currPos - 1]);
528 HLTError("0x%05d: 0x%08x correct leading mark", currPos, buf[currPos - 1]);
530 UInt_t overallDataHeader = buf[currPos++];
531 if ((overallDataHeader >> 28) != fgkHeaderTypeData){
532 HLTError("invalid data header: 0x%08x", overallDataHeader);
535 fStoreGtuInfo = StoreGtuInfoFromDataHeader(overallDataHeader);
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]);
542 HLTDebug("0x%05d: 0x%08x correct trailing mark", sizeInBytes/4 - 1, buf[sizeInBytes/4 - 1]);
545 while (currPos < (sizeInBytes/4) - 2) { // stack-level loop
547 stackHeader = buf[currPos++];
549 // stack header + encapsulated tracklet and track data
550 if (((stackHeader >> 28) & 0xf) == fgkHeaderTypeStack){
551 stack = StackFromStackHeader(stackHeader);
552 size = SizeFromStackHeader(stackHeader);
555 HLTDebug("STACK HEADER: 0x%08x - S%02d-%d, size: %d [checksum: 0x%08x]", stackHeader, stack/5, stack%5, size, buf[sizeInBytes/4 - 2]);
558 while (currPos < sizeInBytes/4 - 2){
560 if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeTracklet){
561 UInt_t trklHdr = buf[currPos++];
562 UInt_t trklWord = buf[currPos++];
563 AddTracklet(HCIdFromTrackletHeader(trklHdr), trklWord);
565 HLTDebug("Tracklet: 0x%08x 0x%08x", trklHdr, trklWord);
567 } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeTrack){
568 UInt_t trkHdr = buf[currPos++];
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++];
580 AddTrack(stack, trackWord, extTrackWord, trackletWords, addInfo);
582 HLTDebug("GTU track: 0x%016llx 0x%016llx", trackWord, extTrackWord);
584 } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeStack){
585 //printf("next stack header\n");
587 } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeGtu){
588 gtuInfoHeader = buf[currPos];
591 HLTError("unknown data block: 0x%08x", buf[currPos]);
600 HLTError("invalid header while analyzing tracking data block: 0x%08x - S%02d-%d, size: %d",
601 stackHeader, stack/5, stack%5, size);
605 } // stack-level loop
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;
623 HLTError("expected GtuInfoHeader at position %d, but is 0x%08x",
624 currPos, buf[currPos]);
627 if (currPos != (sizeInBytes/4) - 2){
628 HLTError("invalid read position after analyzing tracking data block.");
632 for (UInt_t ofs = 1; ofs < sizeInBytes/4 - 2; ++ofs)
633 crosscheck = calcCheck(crosscheck, buf[ofs]);
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]);
641 // HLTDebug(ptrInfo.Data());