]>
Commit | Line | Data |
---|---|---|
c7b7f445 | 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 | ||
6f7c6cc6 | 57 | Int_t AliTRDonlineTrackingDataContainer::GetNumTracklets(UInt_t det) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 68 | Int_t AliTRDonlineTrackingDataContainer::GetNumTracks(UShort_t stack){ |
c7b7f445 | 69 | return fNumTracks[stack]; |
70 | } | |
71 | ||
6f7c6cc6 | 72 | Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinY(UInt_t det, UInt_t trackletIndex) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 82 | Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinDy(UInt_t det, UInt_t trackletIndex) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 90 | Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinZ(UInt_t det, UInt_t trackletIndex) { |
c7b7f445 | 91 | return ((fTrackletWords[det][trackletIndex] >> 20) & 0xf); |
92 | } | |
93 | ||
6f7c6cc6 | 94 | Int_t AliTRDonlineTrackingDataContainer::GetTrackletPID(UInt_t det, UInt_t trackletIndex) { |
c7b7f445 | 95 | return ((fTrackletWords[det][trackletIndex] >> 24) & 0xff); |
96 | }; | |
97 | ||
6f7c6cc6 | 98 | Float_t AliTRDonlineTrackingDataContainer::GetTrackletLocalY(UInt_t det, UInt_t trackletIndex) { |
c7b7f445 | 99 | return GetTrackletBinY(det, trackletIndex) * fgkBinWidthY; |
100 | } | |
101 | ||
6f7c6cc6 | 102 | AliESDTrdTracklet* AliTRDonlineTrackingDataContainer::GetTracklet(UInt_t det, UInt_t trackletIndex) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 110 | AliESDTrdTrack* AliTRDonlineTrackingDataContainer::GetTrack(UInt_t stack, UInt_t trackIndex, Bool_t constructTracklets){ |
c7b7f445 | 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 | ||
6f7c6cc6 | 147 | Double_t AliTRDonlineTrackingDataContainer::GetTrackPt(UInt_t stack, UInt_t trackIndex){ |
c7b7f445 | 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 | ||
6f7c6cc6 | 182 | UShort_t AliTRDonlineTrackingDataContainer::GetTrackLayerNum(UInt_t stack, UInt_t trackIndex) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 191 | UInt_t AliTRDonlineTrackingDataContainer::GetTrackTrackletWord(UInt_t stack, UInt_t trackIndex, UShort_t layer) { |
c7b7f445 | 192 | return fTrackTrackletWords[stack][trackIndex][layer]; |
193 | } | |
194 | ||
195 | ||
6f7c6cc6 | 196 | Int_t AliTRDonlineTrackingDataContainer::GetTrackTrackletBinY(UInt_t stack, UInt_t trackIndex, UShort_t layer) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 206 | Int_t AliTRDonlineTrackingDataContainer::GetTrackAddInfo(UShort_t stack, UInt_t trackIndex) { |
c7b7f445 | 207 | return fTrackAddInfo[stack][trackIndex]; |
208 | } | |
209 | ||
6f7c6cc6 | 210 | Float_t AliTRDonlineTrackingDataContainer::GetTrackTrackletLocalY(UInt_t stack, UInt_t trackIndex, UShort_t layer) { |
c7b7f445 | 211 | return GetTrackTrackletBinY(stack, trackIndex, layer) * fgkBinWidthY; |
212 | } | |
213 | ||
6f7c6cc6 | 214 | Int_t AliTRDonlineTrackingDataContainer::GetTrackTrackletBinZ(UInt_t stack, UInt_t trackIndex, UShort_t layer) { |
c7b7f445 | 215 | return ((fTrackTrackletWords[stack][trackIndex][layer] >> 20) & 0xf); |
216 | } | |
217 | ||
6f7c6cc6 | 218 | UShort_t AliTRDonlineTrackingDataContainer::GetTrackTrackletPID(UInt_t stack, UInt_t trackIndex, UShort_t layer) { |
c7b7f445 | 219 | return ((fTrackTrackletWords[stack][trackIndex][layer] >> 24) & 0xff); |
220 | } | |
221 | ||
6f7c6cc6 | 222 | Int_t AliTRDonlineTrackingDataContainer::AddTracklet(UInt_t HCId, UInt_t trackletWord) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 234 | Int_t AliTRDonlineTrackingDataContainer::AddTrack(UShort_t stack, |
235 | ULong64_t trackWord, ULong64_t extTrackWord, | |
c7b7f445 | 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 | ||
6f7c6cc6 | 247 | Int_t AliTRDonlineTrackingDataContainer::AddTrack(const AliESDTrdTrack* track, Int_t addInfo) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 273 | void AliTRDonlineTrackingDataContainer::SetTrackAddInfo(UShort_t stack, UInt_t trackIndex, Int_t addInfo) { |
c7b7f445 | 274 | fTrackAddInfo[stack][trackIndex] = addInfo; |
275 | } | |
276 | ||
6f7c6cc6 | 277 | void AliTRDonlineTrackingDataContainer::SetGtuPtMultiplierFromMagField(Double_t magField) { |
c7b7f445 | 278 | if (magField > 0) |
279 | fGtuPtMultiplier = -1.; | |
280 | else | |
281 | fGtuPtMultiplier = 1.; | |
282 | } | |
283 | ||
6f7c6cc6 | 284 | void AliTRDonlineTrackingDataContainer::PrintBuffer(const void* buffer, UInt_t sizeInBytes, const char* identifier) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 339 | inline UInt_t AliTRDonlineTrackingDataContainer::MakeStackHeader(UShort_t stack, |
340 | Bool_t trackletsPresent, | |
341 | Bool_t tracksPresent, | |
342 | UInt_t size){ | |
c7b7f445 | 343 | return |
344 | (fgkHeaderTypeStack << 28) | | |
345 | (((tracksPresent) ? 1 : 0) << 27) | | |
346 | (((trackletsPresent) ? 1 : 0) << 26) | | |
347 | ((stack & 0xff) << 16) | (size & 0xffff); | |
348 | } | |
349 | ||
6f7c6cc6 | 350 | inline Int_t AliTRDonlineTrackingDataContainer::StackFromStackHeader(UInt_t stackHeader) { |
c7b7f445 | 351 | return (stackHeader >> 16) & 0xff; |
352 | } | |
353 | ||
6f7c6cc6 | 354 | inline UInt_t AliTRDonlineTrackingDataContainer::SizeFromStackHeader(UInt_t stackHeader) { |
c7b7f445 | 355 | return stackHeader & 0xffff; |
356 | } | |
357 | ||
6f7c6cc6 | 358 | inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackletHeader(UShort_t halfChamber){ |
c7b7f445 | 359 | return (fgkHeaderTypeTracklet << 28) | ((halfChamber & 0xfff) << 16) | 0x2; |
360 | } | |
361 | ||
6f7c6cc6 | 362 | inline Int_t AliTRDonlineTrackingDataContainer::HCIdFromTrackletHeader(UInt_t trackletHeader) { |
c7b7f445 | 363 | return (trackletHeader >> 16) & 0xfff; |
364 | } | |
365 | ||
6f7c6cc6 | 366 | inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackHeader(UShort_t stack){ |
c7b7f445 | 367 | return (fgkHeaderTypeTrack << 28) | ((stack & 0xff) << 16) | 12; |
368 | } | |
369 | ||
6f7c6cc6 | 370 | inline UInt_t AliTRDonlineTrackingDataContainer::MakeGtuHeader(Bool_t storeInfo){ |
c7b7f445 | 371 | if (storeInfo) |
372 | return (fgkHeaderTypeGtu << 28) | (1 << 16) | (1 + 18 + 2*90); | |
373 | else | |
374 | return (fgkHeaderTypeGtu << 28) | 1; | |
375 | } | |
376 | ||
6f7c6cc6 | 377 | inline Bool_t AliTRDonlineTrackingDataContainer::StoreGtuInfoFromDataHeader(UInt_t dataHeader){ |
c7b7f445 | 378 | return ((dataHeader >> 16) & 1); |
379 | } | |
380 | ||
6f7c6cc6 | 381 | inline Bool_t AliTRDonlineTrackingDataContainer::GtuInfoPresentFromGtuHeader(UInt_t gtuHeader){ |
c7b7f445 | 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 | ||
6f7c6cc6 | 405 | inline UInt_t calcCheck(UInt_t prevCrc, UInt_t c) { |
c7b7f445 | 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 | ||
6f7c6cc6 | 509 | Bool_t AliTRDonlineTrackingDataContainer::Decompress(const void* buffer, UInt_t sizeInBytes, Bool_t cumulative, Bool_t verbose) { |
c7b7f445 | 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 | } |