Line data Source code
1 : /**************************************************************************
2 : * This file is property of and copyright by the ALICE HLT Project *
3 : * All rights reserved. *
4 : * *
5 : * Primary Authors: *
6 : * Indranil Das <indra.das@saha.ac.in> *
7 : * Artur Szostak <artursz@iafrica.com> *
8 : * *
9 : * Permission to use, copy, modify and distribute this software and its *
10 : * documentation strictly for non-commercial purposes is hereby granted *
11 : * without fee, provided that the above copyright notice appears in all *
12 : * copies and that both the copyright notice and this permission notice *
13 : * appear in the supporting documentation. The authors make no claims *
14 : * about the suitability of this software for any purpose. It is *
15 : * provided "as is" without express or implied warranty. *
16 : **************************************************************************/
17 :
18 : // $Id$
19 :
20 : /**********************************************************************
21 : Created on : 16/05/2007
22 : Purpose : This class reads the tracker DDL files and gives the output
23 : as AliMUONTriggerRecordStruct structures.
24 : Author : Indranil Das, HEP Division, SINP
25 : Email : indra.das@saha.ac.in | indra.ehep@gmail.com
26 :
27 : Artur Szostak <artursz@iafrica.com>:
28 : Completely reimplemented the lookup table to a simplified format.
29 : **********************************************************************/
30 :
31 : ///
32 : /// @file AliHLTMUONTriggerReconstructor.cxx
33 : /// @author Indranil Das <indra.das@saha.ac.in>,
34 : /// Artur Szostak <artursz@iafrica.com>
35 : /// @date 16 May 2007
36 : /// @brief Implementation of the AliHLTMUONTriggerReconstructor class.
37 : ///
38 : /// The trigger reconstructor class is designed to deal the rawdata inputfiles
39 : /// to findout the the reconstructed hits at the trigger DDL. The output is send
40 : /// to the output block for further processing.
41 : ///
42 :
43 : #include "AliHLTMUONTriggerReconstructor.h"
44 : #include "AliHLTMUONTriggerRecordsBlockStruct.h"
45 : #include "AliHLTMUONTrigRecsDebugBlockStruct.h"
46 : #include "AliHLTMUONUtils.h"
47 : #include "AliHLTMUONConstants.h"
48 : #include "AliHLTMUONCalculations.h"
49 : #include "AliMUONConstants.h"
50 : #include <vector>
51 : #include <cassert>
52 :
53 :
54 : const AliMUONLocalInfoStruct AliHLTMUONTriggerReconstructor::AliDecoderHandler::fgkNullStruct =
55 : {
56 : 0x0, 0x0, 0x0, 0x0, 0x0
57 : };
58 :
59 :
60 : AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor() :
61 0 : AliHLTLogging(),
62 0 : fDecoder()
63 0 : {
64 : /// Default constructor.
65 :
66 0 : fDecoder.MaxRegionals(8);
67 0 : fDecoder.MaxLocals(16);
68 0 : }
69 :
70 :
71 : AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
72 0 : {
73 : /// Default destructor.
74 0 : }
75 :
76 :
77 : bool AliHLTMUONTriggerReconstructor::Run(
78 : const AliHLTUInt8_t* rawData,
79 : AliHLTUInt32_t rawDataSize,
80 : bool scalarEvent,
81 : AliHLTMUONTriggerRecordStruct* trigRecord,
82 : AliHLTUInt32_t& nofTrigRec
83 : )
84 : {
85 : /// Runs the trigger reconstruction algorithm on the raw data.
86 : /// \param [in] rawData Pointer to the raw data DDL payload.
87 : /// \param [in] rawDataSize Size of the raw data DDL payload in bytes.
88 : /// \param [in] scalarEvent Indicates if the raw data should contain
89 : /// scalar data also.
90 : /// \param [out] trigRecord Pointer to output buffer for reconstructed
91 : /// trigger records.
92 : /// \param [in,out] nofTrigRec Initialy should indicate the number of
93 : /// elements that can be stored in the trigRecord array. It will
94 : /// contain the number of elements filled after this method has returned.
95 : /// \return true if raw data was decoded and false if there was a problem
96 : /// with the raw data or we overflowed the output buffer.
97 : ///
98 : /// \note OverflowedOutputBuffer() can be used to check if the output
99 : /// buffer 'trigRecord' was overflowed during this method call.
100 :
101 : // Reset and initialise some variables in the decoder.
102 0 : fDecoder.GetHandler().MaxOutputTrigRecs(nofTrigRec);
103 0 : fDecoder.GetHandler().OutputTrigRecs(trigRecord);
104 :
105 0 : if (not fDecoder.Decode(rawData, rawDataSize, scalarEvent))
106 : {
107 0 : if (TryRecover())
108 : {
109 : /// Fix as long as the DARC header problem is not fixed in hardware by trigger colleagues
110 0 : if (fDecoder.GetHandler().HadNonWrongEventTypeError() or
111 0 : (fDecoder.GetHandler().HadWrongEventTypeError() and not fDecoder.GetHandler().DontPrintWrongEventError())
112 : )
113 : {
114 0 : HLTWarning("There was a problem with the raw data."
115 : " Recovered as much data as possible."
116 : " Will continue processing the next event."
117 : );
118 : }
119 : }
120 : else
121 : {
122 0 : HLTError("Failed to decode the trigger DDL raw data.");
123 0 : return false;
124 : }
125 : }
126 :
127 : // nofTrigRec now becomes the output of how many trigger records were found.
128 0 : nofTrigRec = fDecoder.GetHandler().OutputTrigRecsCount();
129 :
130 0 : return not fDecoder.GetHandler().OverflowedOutputBuffer();
131 0 : }
132 :
133 :
134 : void AliHLTMUONTriggerReconstructor::TryRecover(bool value)
135 : {
136 : /// Sets the flag indicating if the decoder should enable the error
137 : /// recovery logic.
138 :
139 0 : fDecoder.TryRecover(value);
140 0 : fDecoder.ExitOnError(not value);
141 0 : fDecoder.GetHandler().WarnOnly(value);
142 0 : }
143 :
144 :
145 : AliHLTMUONTriggerReconstructor::AliDecoderHandler::AliDecoderHandler() :
146 0 : AliMUONTriggerDDLDecoderEventHandler(),
147 0 : AliHLTLogging(),
148 0 : fLookupTable(),
149 0 : fBufferStart(NULL),
150 0 : fMaxOutputTrigRecs(0),
151 0 : fOutputTrigRecsCount(0),
152 0 : fOutputTrigRecs(NULL),
153 0 : fTrigRecId(0),
154 0 : fDDLBit(0),
155 0 : fSuppressPartialTriggers(false),
156 0 : fOverflowed(false),
157 0 : fWarnOnly(false),
158 0 : fUseLocalId(true),
159 0 : fUseCrateId(true),
160 0 : fCurrentCrateId(0),
161 0 : fCurrentRegional(0),
162 0 : fNextLocalIndex(0),
163 0 : fPrevStruct(&fgkNullStruct),
164 0 : fCurrentStruct(&fgkNullStruct),
165 0 : fNextStruct(&fgkNullStruct),
166 0 : fStoreInfo(false),
167 0 : fInfoBufferSize(0),
168 0 : fInfoBufferCount(0),
169 0 : fInfoBuffer(NULL),
170 0 : fDontPrintWrongEventError(false),
171 0 : fHadWrongEventTypeError(false),
172 0 : fHadNonWrongEventTypeError(false)
173 0 : {
174 : /// Default constructor just resets the lookup table to zero and local
175 : /// structure marker pointers to NULL.
176 :
177 0 : for (AliHLTInt32_t i = 0; i < 16; i++)
178 0 : for (AliHLTInt32_t j = 0; j < 16; j++)
179 0 : for (AliHLTInt32_t k = 0; k < 4; k++)
180 0 : for (AliHLTInt32_t n = 0; n < 2; n++)
181 0 : for (AliHLTInt32_t m = 0; m < 16; m++)
182 : {
183 0 : fLookupTable.fRow[i][j][k][n][m].fIdFlags = 0x0;
184 0 : fLookupTable.fRow[i][j][k][n][m].fX = 0;
185 0 : fLookupTable.fRow[i][j][k][n][m].fY = 0;
186 0 : fLookupTable.fRow[i][j][k][n][m].fZ = 0;
187 : }
188 0 : }
189 :
190 :
191 0 : AliHLTMUONTriggerReconstructor::AliDecoderHandler::~AliDecoderHandler()
192 0 : {
193 : // Default destructor deletes allocated array.
194 :
195 0 : if (fInfoBuffer != NULL) delete [] fInfoBuffer;
196 0 : }
197 :
198 :
199 : bool AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindStripsOnMT1(
200 : AliHLTInt32_t& xPos, AliHLTInt32_t& yPos
201 : )
202 : {
203 : /// This method will find the X and Y strip positions on stations MT1 of the
204 : /// trigger system which were fired for the current L0 local trigger decision.
205 : /// \param [out] xPos The X strip that was fired.
206 : /// \param [out] yPos The Y strip that was fired.
207 : /// \return true is returned if a strip was fired, otherwise a warning is
208 : /// generated and false is returned.
209 : /// \note Values for xPos and yPos are in the range [0..15].
210 :
211 : // Try to identify the strips on MT1 (chambers 11 or 12) that fired
212 : // the trigger and set yPos and xPos to the correct values.
213 : // For the Y strips the yPos value might or might not have to be divided
214 : // by 2. This depends on the switches in the trigger electronics and how
215 : // they were configured. To avoid having to try to track this info we
216 : // just use a trial and error method.
217 0 : yPos = GetLocalYPos(fCurrentStruct);
218 0 : AliHLTUInt32_t yStrips1 = GetLocalY1(fCurrentStruct);
219 0 : AliHLTUInt32_t yStrips2 = GetLocalY2(fCurrentStruct);
220 0 : if (((yStrips1 >> yPos) & 0x1) != 0x1 and ((yStrips2 >> yPos) & 0x1) != 0x1)
221 : {
222 0 : if (((yStrips1 >> (yPos / 2)) & 0x1) == 0x1 or ((yStrips2 >> (yPos / 2)) & 0x1) == 0x1)
223 : {
224 0 : yPos = yPos / 2;
225 0 : }
226 : else
227 : {
228 0 : for (AliHLTInt32_t i = 1; i < 16; ++i)
229 : {
230 0 : if (yPos + i < 16 and (((yStrips1 >> (yPos + i)) & 0x1) == 0x1 or
231 0 : ((yStrips2 >> (yPos + i)) & 0x1) == 0x1)
232 : )
233 : {
234 0 : yPos = yPos + i;
235 0 : break;
236 : }
237 0 : else if (yPos / 2 + i < 16 and (((yStrips1 >> (yPos / 2 + i)) & 0x1) == 0x1 or
238 0 : ((yStrips2 >> (yPos / 2 + i)) & 0x1) == 0x1)
239 : )
240 : {
241 0 : yPos = yPos / 2 + i;
242 0 : break;
243 : }
244 0 : else if (yPos - i >= 0 and (((yStrips1 >> (yPos - i)) & 0x1) == 0x1 or
245 0 : ((yStrips2 >> (yPos - i)) & 0x1) == 0x1)
246 : )
247 : {
248 0 : yPos = yPos - i;
249 0 : break;
250 : }
251 0 : else if (yPos / 2 - i >= 0 and (((yStrips1 >> (yPos / 2 - i)) & 0x1) == 0x1 or
252 0 : ((yStrips2 >> (yPos / 2 - i)) & 0x1) == 0x1)
253 : )
254 : {
255 0 : yPos = yPos / 2 - i;
256 0 : break;
257 : }
258 : }
259 0 : if (((yStrips1 >> yPos) & 0x1) != 0x1 and ((yStrips2 >> yPos) & 0x1) != 0x1)
260 : {
261 : // No y strip found in MT1 so this local trigger circuit does not
262 : // pass the 3/4 coincidence requirement, so ignore it and continue.
263 0 : HLTWarning("Could not find fired Y strip for local trigger"
264 : " structure (regional structure = %d, crate ID = %d, ID = %d),"
265 : " which corresponds to triggered strip YPos = %d.",
266 : fCurrentRegional, fCurrentCrateId, GetLocalId(fCurrentStruct),
267 : GetLocalYPos(fCurrentStruct)
268 : );
269 0 : return false;
270 : }
271 : }
272 : }
273 :
274 : // Now find the X strip on MT1 that fired the trigger.
275 0 : xPos = GetLocalXPos(fCurrentStruct) / 2;
276 0 : AliHLTUInt32_t xStrips1 = GetLocalX1(fCurrentStruct);
277 0 : AliHLTUInt32_t xStrips2 = GetLocalX2(fCurrentStruct);
278 0 : if (((xStrips1 >> xPos) & 0x1) != 0x1 and ((xStrips2 >> xPos) & 0x1) != 0x1)
279 : {
280 0 : for (AliHLTInt32_t i = 1; i < 16; ++i)
281 : {
282 0 : if (xPos + i < 16 and (((xStrips1 >> (xPos + i)) & 0x1) == 0x1 or
283 0 : ((xStrips2 >> (xPos + i)) & 0x1) == 0x1)
284 : )
285 : {
286 0 : xPos = xPos + i;
287 0 : break;
288 : }
289 0 : else if (xPos - i >= 0 and (((xStrips1 >> (xPos - i)) & 0x1) == 0x1 or
290 0 : ((xStrips2 >> (xPos - i)) & 0x1) == 0x1)
291 : )
292 : {
293 0 : xPos = xPos - i;
294 0 : break;
295 : }
296 : }
297 0 : if (((xStrips1 >> xPos) & 0x1) != 0x1 and ((xStrips2 >> xPos) & 0x1) != 0x1)
298 : {
299 : // No x strip found in MT1 so this local trigger circuit does not
300 : // pass the 3/4 coincidence requirement, so ignore it and continue.
301 0 : HLTWarning("Could not find fired X strip for local trigger"
302 : " structure (regional structure = %d, crate ID = %d, ID = %d),"
303 : " which corresponds to triggered strip XPos = %d.",
304 : fCurrentRegional, fCurrentCrateId, GetLocalId(fCurrentStruct),
305 : GetLocalXPos(fCurrentStruct)
306 : );
307 0 : return false;
308 : }
309 : }
310 :
311 0 : return true;
312 0 : }
313 :
314 :
315 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::SelectXPatterns(
316 : AliHLTUInt64_t strips[4]
317 : )
318 : {
319 : // Select the correct X strips to use.
320 :
321 0 : assert( fCurrentStruct != NULL );
322 :
323 0 : strips[0] = AliHLTUInt64_t(GetLocalX1(fPrevStruct)) |
324 0 : (AliHLTUInt64_t(GetLocalX1(fCurrentStruct)) << 16) |
325 0 : (AliHLTUInt64_t(GetLocalX1(fNextStruct)) << 32);
326 :
327 0 : strips[1] = AliHLTUInt64_t(GetLocalX2(fPrevStruct)) |
328 0 : (AliHLTUInt64_t(GetLocalX2(fCurrentStruct)) << 16) |
329 0 : (AliHLTUInt64_t(GetLocalX2(fNextStruct)) << 32);
330 :
331 0 : strips[2] = AliHLTUInt64_t(GetLocalX3(fPrevStruct)) |
332 0 : (AliHLTUInt64_t(GetLocalX3(fCurrentStruct)) << 16) |
333 0 : (AliHLTUInt64_t(GetLocalX3(fNextStruct)) << 32);
334 :
335 0 : strips[3] = AliHLTUInt64_t(GetLocalX4(fPrevStruct)) |
336 0 : (AliHLTUInt64_t(GetLocalX4(fCurrentStruct)) << 16) |
337 0 : (AliHLTUInt64_t(GetLocalX4(fNextStruct)) << 32);
338 0 : }
339 :
340 :
341 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::SelectYPatterns(
342 : AliHLTInt32_t xpos[4], AliHLTUInt32_t strips[4], AliHLTUInt8_t locId[4]
343 : )
344 : {
345 : // Select the correct Y strip patterns and local IDs based on the X strip positions found.
346 :
347 0 : AliHLTUInt8_t locIdnext = fUseLocalId ? GetLocalId(fNextStruct) : AliHLTUInt8_t(fNextLocalIndex);
348 0 : if (locIdnext >= 16) locIdnext = 0;
349 0 : AliHLTUInt8_t locIdcurr = fUseLocalId ? GetLocalId(fCurrentStruct) : AliHLTUInt8_t(fNextLocalIndex-1);
350 0 : if (locIdcurr >= 16) locIdcurr = 0;
351 0 : AliHLTUInt8_t locIdprev = fUseLocalId ? GetLocalId(fPrevStruct) : AliHLTUInt8_t(fNextLocalIndex-2);
352 0 : if (locIdprev >= 16) locIdprev = 0;
353 :
354 0 : UShort_t patterns[4][3] = {
355 0 : {GetLocalY1(fPrevStruct), GetLocalY1(fCurrentStruct), GetLocalY1(fNextStruct)},
356 0 : {GetLocalY2(fPrevStruct), GetLocalY2(fCurrentStruct), GetLocalY2(fNextStruct)},
357 0 : {GetLocalY3(fPrevStruct), GetLocalY3(fCurrentStruct), GetLocalY3(fNextStruct)},
358 0 : {GetLocalY4(fPrevStruct), GetLocalY4(fCurrentStruct), GetLocalY4(fNextStruct)}
359 : };
360 :
361 0 : for (int i = 0; i < 4; i++)
362 : {
363 : // Check if the Y strips for the different local structures are the
364 : // same physical strip. If they are then performs a bit or between the
365 : // patterns. This is necessary because the signal sometimes does not
366 : // propagate in time (in particular for cosmic runs). This has to do with
367 : // the calibration of the timings in the trigger electronics. The solution
368 : // here is to perform the bitwise or to form the correct strip pattern.
369 0 : UShort_t mergedPattern[3] = {patterns[i][0], patterns[i][1], patterns[i][2]};
370 0 : const AliHLTMUONTriggerRecoLutRow& lutnext = fLookupTable.fRow[fCurrentCrateId][locIdnext][i][1][0];
371 0 : const AliHLTMUONTriggerRecoLutRow& lutcurr = fLookupTable.fRow[fCurrentCrateId][locIdcurr][i][1][0];
372 0 : const AliHLTMUONTriggerRecoLutRow& lutprev = fLookupTable.fRow[fCurrentCrateId][locIdprev][i][1][0];
373 0 : if (lutprev.fX == lutcurr.fX and lutprev.fY == lutcurr.fY and lutprev.fZ == lutcurr.fZ)
374 : {
375 0 : mergedPattern[0] |= patterns[i][1];
376 : mergedPattern[1] |= patterns[i][0];
377 0 : }
378 0 : if (lutnext.fX == lutcurr.fX and lutnext.fY == lutcurr.fY and lutnext.fZ == lutcurr.fZ)
379 : {
380 0 : mergedPattern[1] |= patterns[i][2];
381 0 : mergedPattern[2] |= patterns[i][1];
382 0 : }
383 :
384 0 : if (xpos[i] >= 32)
385 : {
386 0 : strips[i] = mergedPattern[2];
387 0 : locId[i] = locIdnext;
388 0 : }
389 0 : else if (xpos[i] >= 16)
390 : {
391 0 : strips[i] = mergedPattern[1];
392 0 : locId[i] = locIdcurr;
393 0 : }
394 0 : else if (xpos[i] >= 0)
395 : {
396 0 : strips[i] = mergedPattern[0];
397 0 : locId[i] = locIdprev;
398 0 : }
399 : else
400 : {
401 : // If the X strip could not be found then just look on the
402 : // current local board strips.
403 0 : strips[i] = mergedPattern[1];
404 0 : locId[i] = locIdcurr;
405 : }
406 : }
407 0 : }
408 :
409 :
410 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindXStrips(
411 : AliHLTInt32_t startPos, AliHLTUInt64_t strips[4], AliHLTInt32_t pos[4]
412 : )
413 : {
414 : /// Finds the X strips that were fired in the local trigger structures.
415 : /// \param [in] startPos The first X strip location to start looking from.
416 : /// \param [in] strips The X strip patterns for chambers 11 to 14 to use.
417 : /// \param [out] pos Array of X strip positions on chambers 11 to 14. pos[0]
418 : /// is for chamber 11, pos[1] for chamber 12 and so on.
419 : /// The elements of the array will contain -1 if no valid strip position
420 : /// was found for that chamber.
421 : /// \note Values for startPos and pos are in the range [0..47], where 0..15 is
422 : /// for strip positions in the fPrevStruct patterns, 16..31 for fCurrentStruct
423 : /// and 32..47 for fNextStruct.
424 :
425 0 : assert( startPos >= 0 );
426 0 : assert( fCurrentStruct != NULL );
427 :
428 0 : if (GetLocalSXDev(fCurrentStruct)) // check the direction of the deviation.
429 : {
430 0 : for (int i = 0; i < 2; ++i)
431 : {
432 0 : if (((strips[i] >> startPos) & 0x1) == 0x1)
433 : {
434 0 : pos[i] = startPos;
435 0 : continue;
436 : }
437 0 : for (AliHLTInt32_t j = 1; j < 16; ++j)
438 : {
439 : // We first check the straighter tracklet option, i.e higher momentum.
440 0 : if (startPos - j >= 0 and ((strips[i] >> (startPos - j)) & 0x1) == 0x1)
441 : {
442 0 : pos[i] = startPos - j;
443 0 : break;
444 : }
445 0 : else if (startPos + j < 48 and ((strips[i] >> (startPos + j)) & 0x1) == 0x1)
446 : {
447 0 : pos[i] = startPos + j;
448 0 : break;
449 : }
450 : }
451 0 : if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
452 : }
453 :
454 : // Given the MT1 coordinate 'startPos' and the deviation information we can
455 : // identify the X strip on MT2 that corresponds to the L0 trigger.
456 : // We find fired strips on MT2 by looking for strips around the position
457 : // endPos = (posX + deviation) / 2, where posX = GetLocalXPos(fCurrentStruct);
458 : // deviation = GetLocalXDev(fCurrentStruct)
459 0 : AliHLTInt32_t endPos = (GetLocalXPos(fCurrentStruct) + GetLocalXDev(fCurrentStruct)) / 2;
460 0 : endPos += 16; // fCurrentStruct strips start at bit 16.
461 :
462 0 : for (int i = 2; i < 4; ++i)
463 : {
464 0 : if (((strips[i] >> endPos) & 0x1) == 0x1)
465 : {
466 0 : pos[i] = endPos;
467 0 : continue;
468 : }
469 0 : for (AliHLTInt32_t j = 1; j < 16; ++j)
470 : {
471 0 : if (endPos - j >= 0 and ((strips[i] >> (endPos - j)) & 0x1) == 0x1)
472 : {
473 0 : pos[i] = endPos - j;
474 0 : break;
475 : }
476 0 : else if (endPos + j < 48 and ((strips[i] >> (endPos + j)) & 0x1) == 0x1)
477 : {
478 0 : pos[i] = endPos + j;
479 0 : break;
480 : }
481 : }
482 0 : if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
483 : }
484 0 : }
485 : else
486 : {
487 : // Similar logic to the positive deviation case above, but with the
488 : // arithmetic inversed.
489 0 : for (int i = 0; i < 2; ++i)
490 : {
491 0 : if (((strips[i] >> startPos) & 0x1) == 0x1)
492 : {
493 0 : pos[i] = startPos;
494 0 : continue;
495 : }
496 0 : for (AliHLTInt32_t j = 1; j < 16; ++j)
497 : {
498 : // We first check the straighter tracklet option, i.e higher momentum.
499 0 : if (startPos + j < 48 and ((strips[i] >> (startPos + j)) & 0x1) == 0x1)
500 : {
501 0 : pos[i] = startPos + j;
502 0 : break;
503 : }
504 0 : else if (startPos - j >= 0 and ((strips[i] >> (startPos - j)) & 0x1) == 0x1)
505 : {
506 0 : pos[i] = startPos - j;
507 0 : break;
508 : }
509 : }
510 0 : if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
511 : }
512 :
513 0 : AliHLTInt32_t endPos = (GetLocalXPos(fCurrentStruct) - GetLocalXDev(fCurrentStruct)) / 2;
514 0 : endPos += 16; // fCurrentStruct strips start at bit 16.
515 :
516 0 : for (int i = 2; i < 4; ++i)
517 : {
518 0 : if (((strips[i] >> endPos) & 0x1) == 0x1)
519 : {
520 0 : pos[i] = endPos;
521 0 : continue;
522 : }
523 0 : for (AliHLTInt32_t j = 1; j < 16; ++j)
524 : {
525 0 : if (endPos + j < 48 and ((strips[i] >> (endPos + j)) & 0x1) == 0x1)
526 : {
527 0 : pos[i] = endPos + j;
528 0 : break;
529 : }
530 0 : else if (endPos - j >= 0 and ((strips[i] >> (endPos - j)) & 0x1) == 0x1)
531 : {
532 0 : pos[i] = endPos - j;
533 0 : break;
534 : }
535 : }
536 0 : if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
537 : }
538 : }
539 0 : }
540 :
541 :
542 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindYStrips(
543 : AliHLTInt32_t startPos, AliHLTUInt32_t strips[4], AliHLTInt32_t pos[4]
544 : )
545 : {
546 : /// Finds the Y strips that were fired in the local trigger structures.
547 : /// \param [in] startPos The first Y strip location to start looking from.
548 : /// \param [in] strips Array of Y strip patterns to look in for chamber 11 to 14.
549 : /// \param [out] pos Array of Y strip positions on chambers 11 to 14. pos[0]
550 : /// is for chamber 11, pos[1] for chamber 12 and so on.
551 : /// The elements of the array will contain -1 if no valid strip position
552 : /// was found for that chamber.
553 : /// \note Values for startPos and pos are in the range [0..15].
554 :
555 0 : assert( startPos >= 0 );
556 :
557 : // First we scan from the i'th = startPos strip upwards (i.e. i-1, i, i+1, i+2 etc..)
558 : // to find the first fired strip. Then we similarly scan downwards
559 : // (i.e. i+1, i, i-1, i-2 etc..) to find the first fired strip.
560 : // Ideally we should have all of posUp[i] == posDown[i] == startPos, but this
561 : // need not be the case due to multiple scattering or if dealing with cosmic tracks.
562 : AliHLTUInt8_t posUpCount = 0, posDownCount = 0, posNearestCount = 0;
563 0 : AliHLTInt32_t posUp[4] = {-1, -1, -1, -1};
564 0 : AliHLTInt32_t posDown[4] = {-1, -1, -1, -1};
565 0 : AliHLTInt32_t posNearest[4] = {-1, -1, -1, -1};
566 0 : for (AliHLTInt32_t n = 0; n < 4; n++)
567 : {
568 0 : for (AliHLTInt32_t i = (startPos >= 1 ? startPos-1 : 0); i <= 15; i++)
569 : {
570 0 : if (((strips[n] >> i) & 0x1) == 0x1)
571 : {
572 0 : posUp[n] = i;
573 0 : posUpCount++;
574 0 : break;
575 : }
576 : }
577 0 : for (AliHLTInt32_t i = startPos+1; i >= 0; i--)
578 : {
579 0 : if (((strips[n] >> i) & 0x1) == 0x1)
580 : {
581 0 : posDown[n] = i;
582 0 : posDownCount++;
583 0 : break;
584 : }
585 : }
586 :
587 : // 20 Nov 2009: Added scanning on either side of startPos to find the
588 : // nearest strip to startPos for pathological cases, where there is
589 : // a larger angle or scatter in Y strips than +/- 1 strip, eg. cosmics.
590 0 : if (((strips[n] >> startPos) & 0x1) == 0x1)
591 : {
592 0 : posNearest[n] = startPos;
593 0 : posNearestCount++;
594 0 : }
595 : else
596 : {
597 0 : for (AliHLTInt32_t i = 1; i < 16; ++i)
598 : {
599 0 : if (((strips[n] >> (startPos + i)) & 0x1) == 0x1)
600 : {
601 0 : posNearest[n] = startPos + i;
602 0 : posNearestCount++;
603 0 : break;
604 : }
605 0 : else if (((strips[n] >> (startPos - i)) & 0x1) == 0x1)
606 : {
607 0 : posNearest[n] = startPos - i;
608 0 : posNearestCount++;
609 0 : break;
610 : }
611 : }
612 : }
613 : }
614 :
615 : // Now select either posUp or posDown, whichever has the most found strips.
616 0 : if (posUpCount >= posDownCount and posUpCount >= posNearestCount)
617 : {
618 0 : for (AliHLTInt32_t n = 0; n < 4; n++)
619 0 : pos[n] = posUp[n];
620 0 : }
621 0 : else if (posDownCount >= posUpCount and posDownCount >= posNearestCount)
622 : {
623 0 : for (AliHLTInt32_t n = 0; n < 4; n++)
624 0 : pos[n] = posDown[n];
625 0 : }
626 : else
627 : {
628 0 : for (AliHLTInt32_t n = 0; n < 4; n++)
629 0 : pos[n] = posNearest[n];
630 : }
631 0 : }
632 :
633 :
634 : const AliHLTMUONTriggerRecoLutRow& AliHLTMUONTriggerReconstructor::AliDecoderHandler::GetLutRowX(
635 : AliHLTInt32_t xPos, AliHLTUInt8_t chamber
636 : )
637 : {
638 : // Fetches the appropriate LUT row for a given strip X and Y position.
639 :
640 0 : assert( chamber <= 3 );
641 0 : assert( fCurrentCrateId < 16 );
642 :
643 : int locId = 0;
644 : int pos = 0;
645 0 : if (xPos >= 32)
646 : {
647 0 : locId = fUseLocalId ? GetLocalId(fNextStruct) : fNextLocalIndex;
648 0 : pos = xPos - 32;
649 0 : }
650 0 : else if (xPos >= 16)
651 : {
652 0 : locId = fUseLocalId ? GetLocalId(fCurrentStruct) : fNextLocalIndex-1;
653 0 : pos = xPos - 16;
654 0 : }
655 0 : else if (xPos >= 0)
656 : {
657 0 : locId = fUseLocalId ? GetLocalId(fPrevStruct) : fNextLocalIndex-2;
658 : pos = xPos;
659 0 : }
660 0 : if (locId < 0 or locId >= 16) locId = 0;
661 0 : if (pos < 0 or pos >= 16) pos = 0;
662 :
663 0 : return fLookupTable.fRow[fCurrentCrateId][locId][chamber][0][pos];
664 : }
665 :
666 :
667 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ReconstructHit(
668 : AliHLTUInt64_t xStrips, AliHLTUInt32_t yStrips,
669 : AliHLTInt32_t xPos, AliHLTInt32_t yPos, AliHLTUInt8_t yLocId,
670 : AliHLTUInt8_t chamber, AliHLTMUONRecHitStruct& hit
671 : )
672 : {
673 : /// Reconstructs the hit coordinates for the given chamber from the
674 : /// strip and fired strip information provided.
675 : /// \param [in] xStrips The X strip pattern for the given chamber.
676 : /// \param [in] yStrips The Y strip pattern for the given chamber.
677 : /// \param [in] xPos The position of the X strip that was fired.
678 : /// \param [in] yPos The position of the Y strip that was fired.
679 : /// \param [in] chamber The chamber on which the strips were found.
680 : /// Valid range [0..3].
681 : /// \param [out] hit This will be filled with the reconstructed hit.
682 :
683 0 : assert( 0 <= xPos and xPos < 48 );
684 0 : assert( 0 <= yPos and yPos < 16 );
685 0 : assert( ((xStrips >> xPos) & 0x1) == 0x1 );
686 0 : assert( ((yStrips >> yPos) & 0x1) == 0x1 );
687 0 : assert( chamber <= 3 );
688 0 : assert( fCurrentCrateId < 16 );
689 0 : assert( yLocId < 16 );
690 :
691 0 : const AliHLTMUONTriggerRecoLutRow& lut = GetLutRowX(xPos, chamber);
692 :
693 : // Decode the Y position of the hit from the strip position information.
694 : // If two neighbouring strips were fired then we decluster the strips like
695 : // the L0 electronics does by taking the middle position of the two strips.
696 0 : if (xPos > 0 and ((xStrips >> (xPos-1)) & 0x1) == 0x1)
697 : {
698 0 : if (((xStrips >> (xPos+1)) & 0x1) == 0x1)
699 : {
700 : // Strips fired on both sides of strip at xPos so just use the middle one.
701 0 : hit.fFlags = lut.fIdFlags;
702 0 : hit.fY = lut.fY;
703 0 : hit.fZ = lut.fZ;
704 0 : }
705 : else
706 : {
707 : // Second strip fired below the one at xPos, so decluster.
708 0 : assert(xPos-1 < 48);
709 0 : const AliHLTMUONTriggerRecoLutRow& lut2 = GetLutRowX(xPos-1, chamber);
710 0 : hit.fFlags = lut.fIdFlags;
711 0 : hit.fY = (lut2.fY + lut.fY) * 0.5;
712 0 : hit.fZ = (lut2.fZ + lut.fZ) * 0.5;
713 : }
714 : }
715 : else
716 : {
717 0 : if (((xStrips >> (xPos+1)) & 0x1) == 0x1)
718 : {
719 : // Second strip fired above the one at xPos, so decluster.
720 0 : assert(xPos+1 < 48);
721 0 : const AliHLTMUONTriggerRecoLutRow& lut2 = GetLutRowX(xPos+1, chamber);
722 0 : hit.fFlags = lut.fIdFlags;
723 0 : hit.fY = (lut2.fY + lut.fY) * 0.5;
724 0 : hit.fZ = (lut2.fZ + lut.fZ) * 0.5;
725 0 : }
726 : else
727 : {
728 : // Only strip at xPos fired and neither of its two neighbours.
729 0 : hit.fFlags = lut.fIdFlags;
730 0 : hit.fY = lut.fY;
731 0 : hit.fZ = lut.fZ;
732 : }
733 : }
734 :
735 : // Similarly decode the X position of the hit from the strip position information.
736 : // Also decluster like for the Y strips.
737 0 : if (yPos > 0 and ((yStrips >> (yPos-1)) & 0x1) == 0x1)
738 : {
739 0 : if (((yStrips >> (yPos+1)) & 0x1) == 0x1)
740 : {
741 : // Strips fired on both sides of strip at yPos so just use the middle one.
742 0 : hit.fX = fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX;
743 0 : }
744 : else
745 : {
746 : // Second strip fired below the one at yPos, so decluster.
747 0 : assert(yPos-1 < 16);
748 0 : hit.fX = (fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos-1].fX
749 0 : + fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX) * 0.5;
750 : }
751 : }
752 : else
753 : {
754 0 : if (((yStrips >> (yPos+1)) & 0x1) == 0x1)
755 : {
756 : // Second strip fired above the one at yPos, so decluster.
757 0 : assert(yPos+1 < 16);
758 0 : hit.fX = (fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos+1].fX
759 0 : + fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX) * 0.5;
760 0 : }
761 : else
762 : {
763 : // Only strip at yPos fired and neither of its two neighbours.
764 0 : hit.fX = fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX;
765 : }
766 : }
767 0 : }
768 :
769 :
770 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnNewRegionalStructV2(
771 : UInt_t num,
772 : const AliMUONRegionalHeaderStruct* regionalStruct,
773 : const AliMUONRegionalScalarsStruct* /*scalars*/,
774 : const void* /*data*/
775 : )
776 : {
777 : // Reset the local trigger structure pointers, and mark the current regional
778 : // structure number and Crate ID.
779 :
780 0 : fCurrentRegional = num;
781 0 : fCurrentCrateId = (fUseCrateId ? GetRegionalId(regionalStruct) : num);
782 0 : fPrevStruct = fCurrentStruct = fNextStruct = &fgkNullStruct;
783 0 : }
784 :
785 :
786 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnEndOfRegionalStructV2(
787 : UInt_t /*num*/,
788 : const AliMUONRegionalHeaderStruct* /*regionalStruct*/,
789 : const AliMUONRegionalScalarsStruct* /*scalars*/,
790 : const void* /*data*/
791 : )
792 : {
793 : // Process the last local trigger structure.
794 :
795 0 : fPrevStruct = fCurrentStruct;
796 0 : fCurrentStruct = fNextStruct;
797 0 : fNextStruct = &fgkNullStruct;
798 :
799 : // The index numbers for fPrevStruct and fCurrentStruct are calculated from
800 : // fNextLocalIndex in ProcessLocalStruct so we need to increment it correctly.
801 0 : ++fNextLocalIndex;
802 :
803 0 : ProcessLocalStruct();
804 0 : }
805 :
806 :
807 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnLocalStructV2(
808 : UInt_t iloc,
809 : const AliMUONLocalInfoStruct* localStruct,
810 : const AliMUONLocalScalarsStruct* /*scalars*/
811 : )
812 : {
813 : // Update pointers and process the current local trigger structure.
814 :
815 0 : assert(iloc < 16);
816 0 : assert(localStruct != NULL);
817 :
818 0 : fPrevStruct = fCurrentStruct;
819 0 : fCurrentStruct = fNextStruct;
820 0 : fNextStruct = localStruct;
821 0 : fNextLocalIndex = iloc;
822 0 : ProcessLocalStruct();
823 0 : }
824 :
825 :
826 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ProcessLocalStruct()
827 : {
828 : /// Converts the fCurrentStruct local trigger structure from the L0 into a trigger record.
829 : /// The dHLT trigger records is then used as a seed for tracking algorithms.
830 : /// \note fOutputTrigRecs must be set before calling the decoder to decode
831 : /// a new raw data buffer.
832 :
833 0 : assert(fOutputTrigRecs != NULL);
834 :
835 : // If the current local trigger structure does not have a decision then skip it.
836 0 : if (GetLocalDec(fCurrentStruct) == 0) return;
837 :
838 : // First try to identify the X and Y strips on MT1 that fired the trigger.
839 : // Note: X strips are for the Y axis in ALICE coordinate system,
840 : // i.e. bending plane. and Y strips for the X axis.
841 0 : AliHLTInt32_t xPos, yPos;
842 0 : if (not FindStripsOnMT1(xPos, yPos)) return;
843 :
844 : // Check that we will not overflow the output buffer.
845 0 : if (fOutputTrigRecsCount >= fMaxOutputTrigRecs)
846 : {
847 0 : HLTError("Output buffer has overflowed maximum element count of %d.",
848 : fMaxOutputTrigRecs
849 : );
850 0 : fOverflowed = true;
851 0 : return;
852 : }
853 :
854 0 : AliHLTMUONTriggerRecordStruct& trigger = fOutputTrigRecs[fOutputTrigRecsCount];
855 :
856 : // Now try find all the fired X and Y strips on all 4 trigger chambers.
857 :
858 0 : AliHLTUInt64_t xStrips[4];
859 0 : SelectXPatterns(xStrips);
860 0 : AliHLTInt32_t stripPosX[4];
861 : // Note: the +16 is because FindStripsOnMT1 returns value in the range [0..15]
862 : // for fCurrentStruct, but we need the value in the range [0..47].
863 0 : FindXStrips(xPos+16, xStrips, stripPosX);
864 0 : AliHLTUInt32_t yStrips[4]; AliHLTUInt8_t locId[4];
865 0 : SelectYPatterns(stripPosX, yStrips, locId);
866 0 : AliHLTInt32_t stripPosY[4];
867 0 : FindYStrips(yPos, yStrips, stripPosY);
868 :
869 : // hitset indicates which hits on chambers 7 to 10 have been found and filled.
870 0 : bool hitset[4] = {false, false, false, false};
871 :
872 : // Reconstruct the hits from the found strips. Also, fill the hitset
873 : // flags and make sure the hits for which no valid strips were found get
874 : // set to a nil value.
875 : int hitCount = 0;
876 0 : for (int i = 0; i < 4; i++)
877 : {
878 0 : if (stripPosX[i] != -1 and stripPosY[i] != -1)
879 : {
880 0 : ReconstructHit(
881 0 : xStrips[i], yStrips[i],
882 : stripPosX[i], stripPosY[i],
883 0 : locId[i], i, trigger.fHit[i]
884 : );
885 0 : hitset[i] = true;
886 0 : hitCount++;
887 0 : }
888 : else
889 : {
890 0 : trigger.fHit[i] = AliHLTMUONConstants::NilRecHitStruct();
891 0 : hitset[i] = false;
892 : }
893 : }
894 :
895 0 : if (hitCount < 3)
896 : {
897 : // If we could not find at least 3 hits, but the trigger fired, then
898 : // maybe we have a pathalogical case where 3 X strips and 3 Y strips
899 : // fired but one chamber has an X, one a Y and only the other 2 have both
900 : // X and Y strips fired.
901 : // In such a case we need to try fit a line to X and Y independantly
902 : // and form the hits from the best line fit.
903 :
904 0 : AliHLTFloat32_t x[4], zx[4], y[4], zy[4];
905 : AliHLTUInt32_t nx = 0, ny = 0;
906 0 : for (int i = 0; i < 4; i++)
907 : {
908 0 : if (stripPosX[i] != -1)
909 : {
910 0 : const AliHLTMUONTriggerRecoLutRow& lut = GetLutRowX(stripPosX[i], i);
911 0 : y[ny] = lut.fY;
912 0 : zy[ny] = lut.fZ;
913 0 : ++ny;
914 0 : }
915 0 : if (stripPosY[i] != -1)
916 : {
917 : const AliHLTMUONTriggerRecoLutRow& lut =
918 0 : fLookupTable.fRow[fCurrentCrateId][locId[i]][i][1][stripPosY[i]];
919 0 : x[nx] = lut.fX;
920 0 : zx[nx] = lut.fZ;
921 0 : ++nx;
922 0 : }
923 : }
924 :
925 : AliHLTFloat32_t mx = 0, cx = 0, my = 0, cy = 0;
926 0 : bool xfitted = AliHLTMUONCalculations::FitLineToData(x, zx, nx);
927 0 : mx = AliHLTMUONCalculations::Mzx();
928 0 : cx = AliHLTMUONCalculations::Czx();
929 0 : bool yfitted = AliHLTMUONCalculations::FitLineToData(y, zy, ny);
930 0 : my = AliHLTMUONCalculations::Mzx();
931 0 : cy = AliHLTMUONCalculations::Czx();
932 0 : if (xfitted and yfitted)
933 : {
934 0 : for (int i = 0; i < 4; i++)
935 : {
936 0 : if (hitset[i]) continue; // Leave the found hits alone.
937 0 : if (stripPosX[i] != -1)
938 : {
939 : // Got X strip but no hit, so Y strip is missing.
940 : // Thus we have a good Y coordinate but poor X.
941 0 : const AliHLTMUONTriggerRecoLutRow& lut = GetLutRowX(stripPosX[i], i);
942 0 : trigger.fHit[i].fFlags = lut.fIdFlags;
943 0 : trigger.fHit[i].fX = mx * lut.fZ + cx;
944 0 : trigger.fHit[i].fY = lut.fY;
945 0 : trigger.fHit[i].fZ = lut.fZ;
946 0 : hitset[i] = true;
947 0 : hitCount++;
948 0 : }
949 0 : else if (stripPosY[i] != -1)
950 : {
951 : // Got Y strip but no hit, so X strip is missing.
952 : // Thus we have a good X coordinate but poor Y.
953 : const AliHLTMUONTriggerRecoLutRow& lut =
954 0 : fLookupTable.fRow[fCurrentCrateId][locId[i]][i][1][stripPosY[i]];
955 0 : trigger.fHit[i].fFlags = lut.fIdFlags;
956 0 : trigger.fHit[i].fX = lut.fX;
957 0 : trigger.fHit[i].fY = my * lut.fZ + cy;
958 0 : trigger.fHit[i].fZ = lut.fZ;
959 0 : hitset[i] = true;
960 0 : hitCount++;
961 0 : }
962 : }
963 0 : }
964 0 : }
965 :
966 : // If 4 hits found then check if they are all good, otherwise find the 3
967 : // best fitting ones.
968 0 : if (hitCount > 3)
969 : {
970 0 : AliHLTFloat32_t dx = AliMUONConstants::TriggerNonBendingReso();
971 0 : AliHLTFloat32_t dy = AliMUONConstants::TriggerBendingReso();
972 0 : AliHLTMUONCalculations::SigmaX2(dx*dx);
973 0 : AliHLTMUONCalculations::SigmaY2(dy*dy);
974 :
975 0 : AliHLTFloat32_t chi2 = AliHLTMUONCalculations::ComputeChi2(trigger, hitset);
976 0 : if (chi2 != -1 and chi2 > 5.*4) // check 5 sigma cut.
977 : {
978 : // Poor fit so look for best 3 points.
979 : int worstHit = -1;
980 : AliHLTFloat32_t bestchi2 = 1e38;
981 0 : for (int j = 0; j < 4; j++)
982 : {
983 0 : bool tmphitset[4] = {true, true, true, true};
984 0 : tmphitset[j] = false;
985 0 : AliHLTFloat32_t tmpchi2 = AliHLTMUONCalculations::ComputeChi2(trigger, tmphitset);
986 0 : if (tmpchi2 * 4 < chi2 * 3 and tmpchi2 < bestchi2)
987 : {
988 : bestchi2 = tmpchi2;
989 : worstHit = j;
990 0 : }
991 0 : }
992 0 : if (worstHit != -1)
993 : {
994 0 : for (int j = 0; j < 4; j++) hitset[j] = true;
995 0 : hitset[worstHit] = false;
996 0 : trigger.fHit[worstHit] = AliHLTMUONConstants::NilRecHitStruct();
997 0 : }
998 0 : }
999 0 : }
1000 :
1001 : // Construct the ID from the running counter fTrigRecId and use the
1002 : // regional counter, local counter and DDL id for the bottom 8 bits.
1003 0 : AliHLTUInt8_t iloc = fNextLocalIndex-1;
1004 0 : trigger.fId = (fTrigRecId << 8) | fDDLBit | ((fCurrentRegional & 0x7) << 4) | (iloc & 0xF);
1005 :
1006 : // Increment the trigger record ID and warp it around at 0x7FFFFF since
1007 : // the bottom 8 bits are filled with the regional + local counters and the
1008 : // sign bit in fOutputTrigRecs[fOutputTrigRecsCount].fId must be positive.
1009 0 : fTrigRecId = (fTrigRecId + 1) & 0x007FFFFF;
1010 :
1011 : // Set the ideal Z coordinate used in line fit for trigger record to
1012 : // the same as the Z coordinate for the hits that were found, otherwise
1013 : // use nominal coordinates.
1014 : AliHLTFloat32_t chamberZ11 = -1603.5f;
1015 0 : if (hitset[0]) chamberZ11 = trigger.fHit[0].fZ;
1016 0 : if (hitset[1]) chamberZ11 = trigger.fHit[1].fZ;
1017 : AliHLTFloat32_t chamberZ13 = -1703.5f;
1018 0 : if (hitset[2]) chamberZ13 = trigger.fHit[2].fZ;
1019 0 : if (hitset[3]) chamberZ13 = trigger.fHit[3].fZ;
1020 0 : AliHLTMUONCalculations::IdealZ1(chamberZ11);
1021 0 : AliHLTMUONCalculations::IdealZ2(chamberZ13);
1022 :
1023 : bool trigAdded = false;
1024 :
1025 0 : if (hitCount >= 3 and
1026 0 : AliHLTMUONCalculations::FitLineToTriggerRecord(trigger, hitset)
1027 : )
1028 : {
1029 : // Calculate the momentum and fill in the flags and momentum fields.
1030 0 : AliHLTMUONCalculations::ComputeMomentum(
1031 0 : AliHLTMUONCalculations::IdealX1(),
1032 0 : AliHLTMUONCalculations::IdealY1(),
1033 0 : AliHLTMUONCalculations::IdealY2(),
1034 0 : AliHLTMUONCalculations::IdealZ1(),
1035 0 : AliHLTMUONCalculations::IdealZ2()
1036 : );
1037 :
1038 0 : trigger.fPx = AliHLTMUONCalculations::Px();
1039 0 : trigger.fPy = AliHLTMUONCalculations::Py();
1040 0 : trigger.fPz = AliHLTMUONCalculations::Pz();
1041 :
1042 0 : trigger.fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
1043 0 : AliHLTMUONCalculations::Sign(),
1044 : hitset
1045 : );
1046 :
1047 0 : fOutputTrigRecsCount++;
1048 : trigAdded = true;
1049 0 : }
1050 0 : else if ((hitset[0] or hitset[1] or hitset[2] or hitset[3])
1051 0 : and not fSuppressPartialTriggers
1052 : )
1053 : {
1054 0 : trigger.fPx = trigger.fPy = trigger.fPz = 0;
1055 :
1056 0 : trigger.fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
1057 : kSignUnknown,
1058 0 : hitset
1059 : );
1060 :
1061 0 : fOutputTrigRecsCount++;
1062 : trigAdded = true;
1063 0 : }
1064 :
1065 0 : if (trigAdded and fStoreInfo)
1066 : {
1067 : // Allocate or reallocate buffer.
1068 0 : if (fInfoBuffer == NULL)
1069 : {
1070 : try
1071 : {
1072 0 : fInfoBuffer = new AliHLTMUONTrigRecInfoStruct[256];
1073 0 : }
1074 : catch (...)
1075 : {
1076 0 : HLTError("Could not allocate buffer space for debug information.");
1077 : return;
1078 0 : }
1079 0 : fInfoBufferSize = 256;
1080 0 : }
1081 0 : else if (fInfoBufferCount >= fInfoBufferSize)
1082 : {
1083 : AliHLTMUONTrigRecInfoStruct* newbuf = NULL;
1084 : try
1085 : {
1086 0 : newbuf = new AliHLTMUONTrigRecInfoStruct[fInfoBufferSize*2];
1087 0 : }
1088 : catch (...)
1089 : {
1090 0 : HLTError("Could not allocate more buffer space for debug information.");
1091 : return;
1092 0 : }
1093 0 : for (AliHLTUInt32_t i = 0; i < fInfoBufferSize; ++i) newbuf[i] = fInfoBuffer[i];
1094 0 : delete [] fInfoBuffer;
1095 0 : fInfoBuffer = newbuf;
1096 0 : fInfoBufferSize = fInfoBufferSize*2;
1097 0 : }
1098 :
1099 0 : fInfoBuffer[fInfoBufferCount].fTrigRecId = trigger.fId;
1100 0 : for (int i = 0; i < 4; ++i)
1101 : {
1102 0 : if (trigger.fHit[i] != AliHLTMUONConstants::NilRecHitStruct())
1103 : {
1104 0 : fInfoBuffer[fInfoBufferCount].fDetElemId[i] =
1105 0 : AliHLTMUONUtils::GetDetElemIdFromFlags(trigger.fHit[i].fFlags);
1106 0 : }
1107 : else
1108 : {
1109 0 : fInfoBuffer[fInfoBufferCount].fDetElemId[i] = -1;
1110 : }
1111 : }
1112 0 : fInfoBuffer[fInfoBufferCount].fZmiddle = AliHLTMUONCalculations::Zf();
1113 0 : fInfoBuffer[fInfoBufferCount].fBl = AliHLTMUONCalculations::QBL();
1114 0 : fInfoBuffer[fInfoBufferCount].fL0Struct = *fCurrentStruct;
1115 0 : fInfoBuffer[fInfoBufferCount].fL0StructPrev = *fPrevStruct;
1116 0 : fInfoBuffer[fInfoBufferCount].fL0StructNext = *fNextStruct;
1117 0 : ++fInfoBufferCount;
1118 0 : }
1119 0 : }
1120 :
1121 :
1122 : void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnError(
1123 : ErrorCode code, const void* location
1124 : )
1125 : {
1126 : /// Logs an error message if there was a decoding problem with the DDL payload.
1127 :
1128 0 : long bytepos = long(location) - long(fBufferStart);
1129 0 : if (code == kWrongEventType)
1130 : {
1131 0 : fHadWrongEventTypeError = true;
1132 :
1133 : /// Do not generate an error message if the fDontPrintWrongEventError option is set.
1134 0 : if (fDontPrintWrongEventError) return;
1135 : }
1136 : else
1137 : {
1138 0 : fHadNonWrongEventTypeError = true;
1139 : }
1140 0 : if (fWarnOnly)
1141 : {
1142 0 : HLTWarning("There is a problem with decoding the raw data."
1143 : " %s (Error code: %d, at byte %d). Trying to recover from corrupt data.",
1144 : ErrorCodeToMessage(code), code, bytepos
1145 : );
1146 : }
1147 : else
1148 : {
1149 0 : HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)",
1150 : ErrorCodeToMessage(code), code, bytepos
1151 : );
1152 : }
1153 0 : }
1154 :
|