ALIROOT-5433 Transition to CDHv3 in HLT
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONTriggerReconstructor.cxx
CommitLineData
6efe69e7 1/**************************************************************************
b39b98c8 2 * This file is property of and copyright by the ALICE HLT Project *
6efe69e7 3 * All rights reserved. *
4 * *
5 * Primary Authors: *
6 * Indranil Das <indra.das@saha.ac.in> *
b39b98c8 7 * Artur Szostak <artursz@iafrica.com> *
6efe69e7 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 *
b39b98c8 14 * about the suitability of this software for any purpose. It is *
6efe69e7 15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
1d8ae082 18// $Id$
6efe69e7 19
20/**********************************************************************
21 Created on : 16/05/2007
b39b98c8 22 Purpose : This class reads the tracker DDL files and gives the output
23 as AliMUONTriggerRecordStruct structures.
6efe69e7 24 Author : Indranil Das, HEP Division, SINP
25 Email : indra.das@saha.ac.in | indra.ehep@gmail.com
b39b98c8 26
27 Artur Szostak <artursz@iafrica.com>:
28 Completely reimplemented the lookup table to a simplified format.
6efe69e7 29**********************************************************************/
30
69c14678 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///
6efe69e7 42
6efe69e7 43#include "AliHLTMUONTriggerReconstructor.h"
c95cf30c 44#include "AliHLTMUONTriggerRecordsBlockStruct.h"
462e3880 45#include "AliHLTMUONTrigRecsDebugBlockStruct.h"
7af42d4d 46#include "AliHLTMUONUtils.h"
47#include "AliHLTMUONConstants.h"
48#include "AliHLTMUONCalculations.h"
bc5cb6d6 49#include "AliMUONConstants.h"
7af42d4d 50#include <vector>
547f15d6 51#include <cassert>
6efe69e7 52
960d54ad 53
462e3880 54const AliMUONLocalInfoStruct AliHLTMUONTriggerReconstructor::AliDecoderHandler::fgkNullStruct =
55{
56 0x0, 0x0, 0x0, 0x0, 0x0
57};
58
59
80590aa1 60AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor() :
69c14678 61 AliHLTLogging(),
62 fDecoder()
63{
64 /// Default constructor.
462e3880 65
66 fDecoder.MaxRegionals(8);
67 fDecoder.MaxLocals(16);
69c14678 68}
69
70
71AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
72{
73 /// Default destructor.
74}
75
76
77bool AliHLTMUONTriggerReconstructor::Run(
78 const AliHLTUInt8_t* rawData,
79 AliHLTUInt32_t rawDataSize,
a5d4696f 80 bool scalarEvent,
69c14678 81 AliHLTMUONTriggerRecordStruct* trigRecord,
a3d4b6ba 82 AliHLTUInt32_t& nofTrigRec
69c14678 83 )
84{
85 /// Runs the trigger reconstruction algorithm on the raw data.
8984a6aa 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
a3d4b6ba 89 /// scalar data also.
8984a6aa 90 /// \param [out] trigRecord Pointer to output buffer for reconstructed
a3d4b6ba 91 /// trigger records.
8984a6aa 92 /// \param [in,out] nofTrigRec Initialy should indicate the number of
a3d4b6ba 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.
69c14678 100
101 // Reset and initialise some variables in the decoder.
102 fDecoder.GetHandler().MaxOutputTrigRecs(nofTrigRec);
103 fDecoder.GetHandler().OutputTrigRecs(trigRecord);
69c14678 104
a5d4696f 105 if (not fDecoder.Decode(rawData, rawDataSize, scalarEvent))
106 {
107 if (TryRecover())
108 {
aae30cc5 109 /// Fix as long as the DARC header problem is not fixed in hardware by trigger colleagues
110 if (fDecoder.GetHandler().HadNonWrongEventTypeError() or
111 (fDecoder.GetHandler().HadWrongEventTypeError() and not fDecoder.GetHandler().DontPrintWrongEventError())
112 )
113 {
114 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 }
a5d4696f 119 }
120 else
121 {
a9afae73 122 HLTError("Failed to decode the trigger DDL raw data.");
a5d4696f 123 return false;
124 }
125 }
69c14678 126
127 // nofTrigRec now becomes the output of how many trigger records were found.
128 nofTrigRec = fDecoder.GetHandler().OutputTrigRecsCount();
129
130 return not fDecoder.GetHandler().OverflowedOutputBuffer();
131}
132
133
a5d4696f 134void AliHLTMUONTriggerReconstructor::TryRecover(bool value)
135{
a3d4b6ba 136 /// Sets the flag indicating if the decoder should enable the error
137 /// recovery logic.
a5d4696f 138
139 fDecoder.TryRecover(value);
140 fDecoder.ExitOnError(not value);
141 fDecoder.GetHandler().WarnOnly(value);
142}
143
144
69c14678 145AliHLTMUONTriggerReconstructor::AliDecoderHandler::AliDecoderHandler() :
146 AliMUONTriggerDDLDecoderEventHandler(),
147 AliHLTLogging(),
148 fLookupTable(),
149 fBufferStart(NULL),
150 fMaxOutputTrigRecs(0),
151 fOutputTrigRecsCount(0),
152 fOutputTrigRecs(NULL),
c95cf30c 153 fTrigRecId(0),
406c5bc3 154 fDDLBit(0),
69c14678 155 fSuppressPartialTriggers(false),
a5d4696f 156 fOverflowed(false),
a3d4b6ba 157 fWarnOnly(false),
2b7af22a 158 fUseLocalId(true),
a3d4b6ba 159 fUseCrateId(true),
160 fCurrentCrateId(0),
462e3880 161 fCurrentRegional(0),
162 fNextLocalIndex(0),
163 fPrevStruct(&fgkNullStruct),
164 fCurrentStruct(&fgkNullStruct),
165 fNextStruct(&fgkNullStruct),
166 fStoreInfo(false),
167 fInfoBufferSize(0),
168 fInfoBufferCount(0),
aae30cc5 169 fInfoBuffer(NULL),
170 fDontPrintWrongEventError(false),
171 fHadWrongEventTypeError(false),
172 fHadNonWrongEventTypeError(false)
6efe69e7 173{
a3d4b6ba 174 /// Default constructor just resets the lookup table to zero and local
175 /// structure marker pointers to NULL.
b39b98c8 176
a3d4b6ba 177 for (AliHLTInt32_t i = 0; i < 16; i++)
178 for (AliHLTInt32_t j = 0; j < 16; j++)
179 for (AliHLTInt32_t k = 0; k < 4; k++)
180 for (AliHLTInt32_t n = 0; n < 2; n++)
181 for (AliHLTInt32_t m = 0; m < 16; m++)
b39b98c8 182 {
a090ff22 183 fLookupTable.fRow[i][j][k][n][m].fIdFlags = 0x0;
c95cf30c 184 fLookupTable.fRow[i][j][k][n][m].fX = 0;
185 fLookupTable.fRow[i][j][k][n][m].fY = 0;
186 fLookupTable.fRow[i][j][k][n][m].fZ = 0;
b39b98c8 187 }
6efe69e7 188}
189
190
462e3880 191AliHLTMUONTriggerReconstructor::AliDecoderHandler::~AliDecoderHandler()
192{
193 // Default destructor deletes allocated array.
194
195 if (fInfoBuffer != NULL) delete [] fInfoBuffer;
196}
197
198
a3d4b6ba 199bool AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindStripsOnMT1(
a3d4b6ba 200 AliHLTInt32_t& xPos, AliHLTInt32_t& yPos
201 )
202{
462e3880 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.
8984a6aa 205 /// \param [out] xPos The X strip that was fired.
206 /// \param [out] yPos The Y strip that was fired.
a3d4b6ba 207 /// \return true is returned if a strip was fired, otherwise a warning is
208 /// generated and false is returned.
462e3880 209 /// \note Values for xPos and yPos are in the range [0..15].
a3d4b6ba 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.
462e3880 217 yPos = GetLocalYPos(fCurrentStruct);
218 AliHLTUInt32_t yStrips1 = GetLocalY1(fCurrentStruct);
219 AliHLTUInt32_t yStrips2 = GetLocalY2(fCurrentStruct);
220 if (((yStrips1 >> yPos) & 0x1) != 0x1 and ((yStrips2 >> yPos) & 0x1) != 0x1)
a3d4b6ba 221 {
462e3880 222 if (((yStrips1 >> (yPos / 2)) & 0x1) == 0x1 or ((yStrips2 >> (yPos / 2)) & 0x1) == 0x1)
a3d4b6ba 223 {
224 yPos = yPos / 2;
225 }
a3d4b6ba 226 else
227 {
462e3880 228 for (AliHLTInt32_t i = 1; i < 16; ++i)
a3d4b6ba 229 {
462e3880 230 if (yPos + i < 16 and (((yStrips1 >> (yPos + i)) & 0x1) == 0x1 or
231 ((yStrips2 >> (yPos + i)) & 0x1) == 0x1)
232 )
a3d4b6ba 233 {
462e3880 234 yPos = yPos + i;
235 break;
a3d4b6ba 236 }
462e3880 237 else if (yPos / 2 + i < 16 and (((yStrips1 >> (yPos / 2 + i)) & 0x1) == 0x1 or
238 ((yStrips2 >> (yPos / 2 + i)) & 0x1) == 0x1)
239 )
a3d4b6ba 240 {
462e3880 241 yPos = yPos / 2 + i;
242 break;
243 }
244 else if (yPos - i >= 0 and (((yStrips1 >> (yPos - i)) & 0x1) == 0x1 or
245 ((yStrips2 >> (yPos - i)) & 0x1) == 0x1)
246 )
247 {
248 yPos = yPos - i;
249 break;
250 }
251 else if (yPos / 2 - i >= 0 and (((yStrips1 >> (yPos / 2 - i)) & 0x1) == 0x1 or
252 ((yStrips2 >> (yPos / 2 - i)) & 0x1) == 0x1)
253 )
254 {
255 yPos = yPos / 2 - i;
256 break;
a3d4b6ba 257 }
258 }
462e3880 259 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 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 return false;
270 }
a3d4b6ba 271 }
272 }
273
274 // Now find the X strip on MT1 that fired the trigger.
462e3880 275 xPos = GetLocalXPos(fCurrentStruct) / 2;
276 AliHLTUInt32_t xStrips1 = GetLocalX1(fCurrentStruct);
277 AliHLTUInt32_t xStrips2 = GetLocalX2(fCurrentStruct);
278 if (((xStrips1 >> xPos) & 0x1) != 0x1 and ((xStrips2 >> xPos) & 0x1) != 0x1)
a3d4b6ba 279 {
462e3880 280 for (AliHLTInt32_t i = 1; i < 16; ++i)
a3d4b6ba 281 {
462e3880 282 if (xPos + i < 16 and (((xStrips1 >> (xPos + i)) & 0x1) == 0x1 or
283 ((xStrips2 >> (xPos + i)) & 0x1) == 0x1)
284 )
a3d4b6ba 285 {
462e3880 286 xPos = xPos + i;
287 break;
a3d4b6ba 288 }
462e3880 289 else if (xPos - i >= 0 and (((xStrips1 >> (xPos - i)) & 0x1) == 0x1 or
290 ((xStrips2 >> (xPos - i)) & 0x1) == 0x1)
291 )
a3d4b6ba 292 {
462e3880 293 xPos = xPos - i;
294 break;
a3d4b6ba 295 }
462e3880 296 }
297 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.
a3d4b6ba 301 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.",
462e3880 304 fCurrentRegional, fCurrentCrateId, GetLocalId(fCurrentStruct),
305 GetLocalXPos(fCurrentStruct)
a3d4b6ba 306 );
307 return false;
a3d4b6ba 308 }
309 }
310
311 return true;
312}
313
314
462e3880 315void AliHLTMUONTriggerReconstructor::AliDecoderHandler::SelectXPatterns(
316 AliHLTUInt64_t strips[4]
a3d4b6ba 317 )
318{
462e3880 319 // Select the correct X strips to use.
a3d4b6ba 320
462e3880 321 assert( fCurrentStruct != NULL );
a3d4b6ba 322
462e3880 323 strips[0] = AliHLTUInt64_t(GetLocalX1(fPrevStruct)) |
324 (AliHLTUInt64_t(GetLocalX1(fCurrentStruct)) << 16) |
325 (AliHLTUInt64_t(GetLocalX1(fNextStruct)) << 32);
a3d4b6ba 326
462e3880 327 strips[1] = AliHLTUInt64_t(GetLocalX2(fPrevStruct)) |
328 (AliHLTUInt64_t(GetLocalX2(fCurrentStruct)) << 16) |
329 (AliHLTUInt64_t(GetLocalX2(fNextStruct)) << 32);
a3d4b6ba 330
462e3880 331 strips[2] = AliHLTUInt64_t(GetLocalX3(fPrevStruct)) |
332 (AliHLTUInt64_t(GetLocalX3(fCurrentStruct)) << 16) |
333 (AliHLTUInt64_t(GetLocalX3(fNextStruct)) << 32);
a3d4b6ba 334
462e3880 335 strips[3] = AliHLTUInt64_t(GetLocalX4(fPrevStruct)) |
336 (AliHLTUInt64_t(GetLocalX4(fCurrentStruct)) << 16) |
337 (AliHLTUInt64_t(GetLocalX4(fNextStruct)) << 32);
338}
339
340
341void 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 AliHLTUInt8_t locIdnext = fUseLocalId ? GetLocalId(fNextStruct) : AliHLTUInt8_t(fNextLocalIndex);
348 if (locIdnext >= 16) locIdnext = 0;
349 AliHLTUInt8_t locIdcurr = fUseLocalId ? GetLocalId(fCurrentStruct) : AliHLTUInt8_t(fNextLocalIndex-1);
350 if (locIdcurr >= 16) locIdcurr = 0;
351 AliHLTUInt8_t locIdprev = fUseLocalId ? GetLocalId(fPrevStruct) : AliHLTUInt8_t(fNextLocalIndex-2);
352 if (locIdprev >= 16) locIdprev = 0;
353
354 UShort_t patterns[4][3] = {
355 {GetLocalY1(fPrevStruct), GetLocalY1(fCurrentStruct), GetLocalY1(fNextStruct)},
356 {GetLocalY2(fPrevStruct), GetLocalY2(fCurrentStruct), GetLocalY2(fNextStruct)},
357 {GetLocalY3(fPrevStruct), GetLocalY3(fCurrentStruct), GetLocalY3(fNextStruct)},
358 {GetLocalY4(fPrevStruct), GetLocalY4(fCurrentStruct), GetLocalY4(fNextStruct)}
359 };
360
361 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 UShort_t mergedPattern[3] = {patterns[i][0], patterns[i][1], patterns[i][2]};
370 const AliHLTMUONTriggerRecoLutRow& lutnext = fLookupTable.fRow[fCurrentCrateId][locIdnext][i][1][0];
bc5cb6d6 371 const AliHLTMUONTriggerRecoLutRow& lutcurr = fLookupTable.fRow[fCurrentCrateId][locIdcurr][i][1][0];
372 const AliHLTMUONTriggerRecoLutRow& lutprev = fLookupTable.fRow[fCurrentCrateId][locIdprev][i][1][0];
462e3880 373 if (lutprev.fX == lutcurr.fX and lutprev.fY == lutcurr.fY and lutprev.fZ == lutcurr.fZ)
a3d4b6ba 374 {
462e3880 375 mergedPattern[0] |= patterns[i][1];
376 mergedPattern[1] |= patterns[i][0];
a3d4b6ba 377 }
462e3880 378 if (lutnext.fX == lutcurr.fX and lutnext.fY == lutcurr.fY and lutnext.fZ == lutcurr.fZ)
a3d4b6ba 379 {
462e3880 380 mergedPattern[1] |= patterns[i][2];
381 mergedPattern[2] |= patterns[i][1];
a3d4b6ba 382 }
462e3880 383
384 if (xpos[i] >= 32)
a3d4b6ba 385 {
462e3880 386 strips[i] = mergedPattern[2];
387 locId[i] = locIdnext;
a3d4b6ba 388 }
462e3880 389 else if (xpos[i] >= 16)
a3d4b6ba 390 {
462e3880 391 strips[i] = mergedPattern[1];
392 locId[i] = locIdcurr;
a3d4b6ba 393 }
462e3880 394 else if (xpos[i] >= 0)
a3d4b6ba 395 {
462e3880 396 strips[i] = mergedPattern[0];
bc5cb6d6 397 locId[i] = locIdprev;
a3d4b6ba 398 }
399 else
400 {
462e3880 401 // If the X strip could not be found then just look on the
402 // current local board strips.
403 strips[i] = mergedPattern[1];
404 locId[i] = locIdcurr;
a3d4b6ba 405 }
406 }
462e3880 407}
408
409
410void 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.
8984a6aa 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]
462e3880 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 assert( startPos >= 0 );
426 assert( fCurrentStruct != NULL );
427
428 if (GetLocalSXDev(fCurrentStruct)) // check the direction of the deviation.
a3d4b6ba 429 {
462e3880 430 for (int i = 0; i < 2; ++i)
a3d4b6ba 431 {
462e3880 432 if (((strips[i] >> startPos) & 0x1) == 0x1)
433 {
434 pos[i] = startPos;
435 continue;
436 }
437 for (AliHLTInt32_t j = 1; j < 16; ++j)
438 {
439 // We first check the straighter tracklet option, i.e higher momentum.
440 if (startPos - j >= 0 and ((strips[i] >> (startPos - j)) & 0x1) == 0x1)
441 {
442 pos[i] = startPos - j;
443 break;
444 }
445 else if (startPos + j < 48 and ((strips[i] >> (startPos + j)) & 0x1) == 0x1)
446 {
447 pos[i] = startPos + j;
448 break;
449 }
450 }
451 if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
a3d4b6ba 452 }
453
462e3880 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 AliHLTInt32_t endPos = (GetLocalXPos(fCurrentStruct) + GetLocalXDev(fCurrentStruct)) / 2;
460 endPos += 16; // fCurrentStruct strips start at bit 16.
a3d4b6ba 461
462e3880 462 for (int i = 2; i < 4; ++i)
a3d4b6ba 463 {
462e3880 464 if (((strips[i] >> endPos) & 0x1) == 0x1)
465 {
466 pos[i] = endPos;
467 continue;
468 }
469 for (AliHLTInt32_t j = 1; j < 16; ++j)
470 {
471 if (endPos - j >= 0 and ((strips[i] >> (endPos - j)) & 0x1) == 0x1)
472 {
473 pos[i] = endPos - j;
474 break;
475 }
476 else if (endPos + j < 48 and ((strips[i] >> (endPos + j)) & 0x1) == 0x1)
477 {
478 pos[i] = endPos + j;
479 break;
480 }
481 }
482 if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
a3d4b6ba 483 }
462e3880 484 }
485 else
486 {
487 // Similar logic to the positive deviation case above, but with the
488 // arithmetic inversed.
489 for (int i = 0; i < 2; ++i)
a3d4b6ba 490 {
462e3880 491 if (((strips[i] >> startPos) & 0x1) == 0x1)
492 {
493 pos[i] = startPos;
494 continue;
495 }
496 for (AliHLTInt32_t j = 1; j < 16; ++j)
497 {
498 // We first check the straighter tracklet option, i.e higher momentum.
499 if (startPos + j < 48 and ((strips[i] >> (startPos + j)) & 0x1) == 0x1)
500 {
501 pos[i] = startPos + j;
502 break;
503 }
504 else if (startPos - j >= 0 and ((strips[i] >> (startPos - j)) & 0x1) == 0x1)
505 {
506 pos[i] = startPos - j;
507 break;
508 }
509 }
510 if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
a3d4b6ba 511 }
512
462e3880 513 AliHLTInt32_t endPos = (GetLocalXPos(fCurrentStruct) - GetLocalXDev(fCurrentStruct)) / 2;
514 endPos += 16; // fCurrentStruct strips start at bit 16.
515
516 for (int i = 2; i < 4; ++i)
a3d4b6ba 517 {
462e3880 518 if (((strips[i] >> endPos) & 0x1) == 0x1)
519 {
520 pos[i] = endPos;
521 continue;
522 }
523 for (AliHLTInt32_t j = 1; j < 16; ++j)
524 {
525 if (endPos + j < 48 and ((strips[i] >> (endPos + j)) & 0x1) == 0x1)
526 {
527 pos[i] = endPos + j;
528 break;
529 }
530 else if (endPos - j >= 0 and ((strips[i] >> (endPos - j)) & 0x1) == 0x1)
531 {
532 pos[i] = endPos - j;
533 break;
534 }
535 }
536 if (((strips[i] >> pos[i]) & 0x1) != 0x1) pos[i] = -1;
a3d4b6ba 537 }
538 }
539}
540
541
542void AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindYStrips(
462e3880 543 AliHLTInt32_t startPos, AliHLTUInt32_t strips[4], AliHLTInt32_t pos[4]
69c14678 544 )
6efe69e7 545{
462e3880 546 /// Finds the Y strips that were fired in the local trigger structures.
8984a6aa 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]
a3d4b6ba 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.
462e3880 553 /// \note Values for startPos and pos are in the range [0..15].
69c14678 554
a3d4b6ba 555 assert( startPos >= 0 );
69c14678 556
462e3880 557 // First we scan from the i'th = startPos strip upwards (i.e. i-1, i, i+1, i+2 etc..)
a3d4b6ba 558 // to find the first fired strip. Then we similarly scan downwards
462e3880 559 // (i.e. i+1, i, i-1, i-2 etc..) to find the first fired strip.
a3d4b6ba 560 // Ideally we should have all of posUp[i] == posDown[i] == startPos, but this
462e3880 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;
a3d4b6ba 563 AliHLTInt32_t posUp[4] = {-1, -1, -1, -1};
564 AliHLTInt32_t posDown[4] = {-1, -1, -1, -1};
462e3880 565 AliHLTInt32_t posNearest[4] = {-1, -1, -1, -1};
a3d4b6ba 566 for (AliHLTInt32_t n = 0; n < 4; n++)
567 {
462e3880 568 for (AliHLTInt32_t i = (startPos >= 1 ? startPos-1 : 0); i <= 15; i++)
a3d4b6ba 569 {
570 if (((strips[n] >> i) & 0x1) == 0x1)
571 {
572 posUp[n] = i;
573 posUpCount++;
574 break;
575 }
576 }
462e3880 577 for (AliHLTInt32_t i = startPos+1; i >= 0; i--)
a3d4b6ba 578 {
579 if (((strips[n] >> i) & 0x1) == 0x1)
580 {
581 posDown[n] = i;
582 posDownCount++;
583 break;
584 }
585 }
462e3880 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 if (((strips[n] >> startPos) & 0x1) == 0x1)
591 {
592 posNearest[n] = startPos;
593 posNearestCount++;
594 }
595 else
596 {
597 for (AliHLTInt32_t i = 1; i < 16; ++i)
598 {
599 if (((strips[n] >> (startPos + i)) & 0x1) == 0x1)
600 {
601 posNearest[n] = startPos + i;
602 posNearestCount++;
603 break;
604 }
605 else if (((strips[n] >> (startPos - i)) & 0x1) == 0x1)
606 {
607 posNearest[n] = startPos - i;
608 posNearestCount++;
609 break;
610 }
611 }
612 }
a3d4b6ba 613 }
614
615 // Now select either posUp or posDown, whichever has the most found strips.
462e3880 616 if (posUpCount >= posDownCount and posUpCount >= posNearestCount)
a3d4b6ba 617 {
618 for (AliHLTInt32_t n = 0; n < 4; n++)
619 pos[n] = posUp[n];
620 }
462e3880 621 else if (posDownCount >= posUpCount and posDownCount >= posNearestCount)
a3d4b6ba 622 {
623 for (AliHLTInt32_t n = 0; n < 4; n++)
624 pos[n] = posDown[n];
625 }
462e3880 626 else
627 {
628 for (AliHLTInt32_t n = 0; n < 4; n++)
629 pos[n] = posNearest[n];
630 }
631}
632
633
634const 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 assert( chamber <= 3 );
641 assert( fCurrentCrateId < 16 );
642
643 int locId = 0;
644 int pos = 0;
645 if (xPos >= 32)
646 {
647 locId = fUseLocalId ? GetLocalId(fNextStruct) : fNextLocalIndex;
648 pos = xPos - 32;
649 }
650 else if (xPos >= 16)
651 {
652 locId = fUseLocalId ? GetLocalId(fCurrentStruct) : fNextLocalIndex-1;
653 pos = xPos - 16;
654 }
655 else if (xPos >= 0)
656 {
657 locId = fUseLocalId ? GetLocalId(fPrevStruct) : fNextLocalIndex-2;
658 pos = xPos;
659 }
660 if (locId < 0 or locId >= 16) locId = 0;
661 if (pos < 0 or pos >= 16) pos = 0;
662
663 return fLookupTable.fRow[fCurrentCrateId][locId][chamber][0][pos];
6efe69e7 664}
665
6efe69e7 666
a3d4b6ba 667void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ReconstructHit(
462e3880 668 AliHLTUInt64_t xStrips, AliHLTUInt32_t yStrips,
669 AliHLTInt32_t xPos, AliHLTInt32_t yPos, AliHLTUInt8_t yLocId,
670 AliHLTUInt8_t chamber, AliHLTMUONRecHitStruct& hit
a3d4b6ba 671 )
672{
673 /// Reconstructs the hit coordinates for the given chamber from the
674 /// strip and fired strip information provided.
8984a6aa 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.
a3d4b6ba 680 /// Valid range [0..3].
8984a6aa 681 /// \param [out] hit This will be filled with the reconstructed hit.
a3d4b6ba 682
462e3880 683 assert( 0 <= xPos and xPos < 48 );
a3d4b6ba 684 assert( 0 <= yPos and yPos < 16 );
685 assert( ((xStrips >> xPos) & 0x1) == 0x1 );
686 assert( ((yStrips >> yPos) & 0x1) == 0x1 );
687 assert( chamber <= 3 );
462e3880 688 assert( fCurrentCrateId < 16 );
689 assert( yLocId < 16 );
690
691 const AliHLTMUONTriggerRecoLutRow& lut = GetLutRowX(xPos, chamber);
a3d4b6ba 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 if (xPos > 0 and ((xStrips >> (xPos-1)) & 0x1) == 0x1)
697 {
698 if (((xStrips >> (xPos+1)) & 0x1) == 0x1)
699 {
700 // Strips fired on both sides of strip at xPos so just use the middle one.
462e3880 701 hit.fFlags = lut.fIdFlags;
702 hit.fY = lut.fY;
703 hit.fZ = lut.fZ;
a3d4b6ba 704 }
705 else
706 {
707 // Second strip fired below the one at xPos, so decluster.
462e3880 708 assert(xPos-1 < 48);
709 const AliHLTMUONTriggerRecoLutRow& lut2 = GetLutRowX(xPos-1, chamber);
710 hit.fFlags = lut.fIdFlags;
711 hit.fY = (lut2.fY + lut.fY) * 0.5;
712 hit.fZ = (lut2.fZ + lut.fZ) * 0.5;
a3d4b6ba 713 }
714 }
715 else
716 {
717 if (((xStrips >> (xPos+1)) & 0x1) == 0x1)
718 {
719 // Second strip fired above the one at xPos, so decluster.
462e3880 720 assert(xPos+1 < 48);
721 const AliHLTMUONTriggerRecoLutRow& lut2 = GetLutRowX(xPos+1, chamber);
722 hit.fFlags = lut.fIdFlags;
723 hit.fY = (lut2.fY + lut.fY) * 0.5;
724 hit.fZ = (lut2.fZ + lut.fZ) * 0.5;
a3d4b6ba 725 }
726 else
727 {
728 // Only strip at xPos fired and neither of its two neighbours.
462e3880 729 hit.fFlags = lut.fIdFlags;
730 hit.fY = lut.fY;
731 hit.fZ = lut.fZ;
a3d4b6ba 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 if (yPos > 0 and ((yStrips >> (yPos-1)) & 0x1) == 0x1)
738 {
739 if (((yStrips >> (yPos+1)) & 0x1) == 0x1)
740 {
741 // Strips fired on both sides of strip at yPos so just use the middle one.
462e3880 742 hit.fX = fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX;
a3d4b6ba 743 }
744 else
745 {
746 // Second strip fired below the one at yPos, so decluster.
747 assert(yPos-1 < 16);
462e3880 748 hit.fX = (fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos-1].fX
749 + fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX) * 0.5;
a3d4b6ba 750 }
751 }
752 else
753 {
754 if (((yStrips >> (yPos+1)) & 0x1) == 0x1)
755 {
756 // Second strip fired above the one at yPos, so decluster.
757 assert(yPos+1 < 16);
462e3880 758 hit.fX = (fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos+1].fX
759 + fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX) * 0.5;
a3d4b6ba 760 }
761 else
762 {
763 // Only strip at yPos fired and neither of its two neighbours.
462e3880 764 hit.fX = fLookupTable.fRow[fCurrentCrateId][yLocId][chamber][1][yPos].fX;
a3d4b6ba 765 }
766 }
767}
768
769
462e3880 770void 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 fCurrentRegional = num;
781 fCurrentCrateId = (fUseCrateId ? GetRegionalId(regionalStruct) : num);
782 fPrevStruct = fCurrentStruct = fNextStruct = &fgkNullStruct;
783}
784
785
786void 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 fPrevStruct = fCurrentStruct;
796 fCurrentStruct = fNextStruct;
797 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 ++fNextLocalIndex;
802
803 ProcessLocalStruct();
804}
805
806
a3d4b6ba 807void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnLocalStructV2(
808 UInt_t iloc,
69c14678 809 const AliMUONLocalInfoStruct* localStruct,
810 const AliMUONLocalScalarsStruct* /*scalars*/
227e7192 811 )
6efe69e7 812{
462e3880 813 // Update pointers and process the current local trigger structure.
814
815 assert(iloc < 16);
816 assert(localStruct != NULL);
817
818 fPrevStruct = fCurrentStruct;
819 fCurrentStruct = fNextStruct;
820 fNextStruct = localStruct;
821 fNextLocalIndex = iloc;
822 ProcessLocalStruct();
823}
824
825
826void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ProcessLocalStruct()
827{
828 /// Converts the fCurrentStruct local trigger structure from the L0 into a trigger record.
69c14678 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.
69c14678 832
69c14678 833 assert(fOutputTrigRecs != NULL);
a3d4b6ba 834
462e3880 835 // If the current local trigger structure does not have a decision then skip it.
836 if (GetLocalDec(fCurrentStruct) == 0) return;
b39b98c8 837
a3d4b6ba 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 AliHLTInt32_t xPos, yPos;
462e3880 842 if (not FindStripsOnMT1(xPos, yPos)) return;
a3d4b6ba 843
69c14678 844 // Check that we will not overflow the output buffer.
845 if (fOutputTrigRecsCount >= fMaxOutputTrigRecs)
846 {
847 HLTError("Output buffer has overflowed maximum element count of %d.",
848 fMaxOutputTrigRecs
849 );
850 fOverflowed = true;
851 return;
852 }
b39b98c8 853
a3d4b6ba 854 AliHLTMUONTriggerRecordStruct& trigger = fOutputTrigRecs[fOutputTrigRecsCount];
855
462e3880 856 // Now try find all the fired X and Y strips on all 4 trigger chambers.
857
858 AliHLTUInt64_t xStrips[4];
859 SelectXPatterns(xStrips);
a3d4b6ba 860 AliHLTInt32_t stripPosX[4];
462e3880 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 FindXStrips(xPos+16, xStrips, stripPosX);
864 AliHLTUInt32_t yStrips[4]; AliHLTUInt8_t locId[4];
865 SelectYPatterns(stripPosX, yStrips, locId);
a3d4b6ba 866 AliHLTInt32_t stripPosY[4];
462e3880 867 FindYStrips(yPos, yStrips, stripPosY);
406c5bc3 868
69c14678 869 // hitset indicates which hits on chambers 7 to 10 have been found and filled.
870 bool hitset[4] = {false, false, false, false};
b39b98c8 871
a3d4b6ba 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.
a3d4b6ba 875 int hitCount = 0;
69c14678 876 for (int i = 0; i < 4; i++)
877 {
a3d4b6ba 878 if (stripPosX[i] != -1 and stripPosY[i] != -1)
69c14678 879 {
a3d4b6ba 880 ReconstructHit(
881 xStrips[i], yStrips[i],
882 stripPosX[i], stripPosY[i],
462e3880 883 locId[i], i, trigger.fHit[i]
a3d4b6ba 884 );
885 hitset[i] = true;
886 hitCount++;
887 }
888 else
889 {
890 trigger.fHit[i] = AliHLTMUONConstants::NilRecHitStruct();
891 hitset[i] = false;
69c14678 892 }
893 }
462e3880 894
895 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 AliHLTFloat32_t x[4], zx[4], y[4], zy[4];
905 AliHLTUInt32_t nx = 0, ny = 0;
906 for (int i = 0; i < 4; i++)
907 {
908 if (stripPosX[i] != -1)
909 {
910 const AliHLTMUONTriggerRecoLutRow& lut = GetLutRowX(stripPosX[i], i);
911 y[ny] = lut.fY;
912 zy[ny] = lut.fZ;
913 ++ny;
914 }
915 if (stripPosY[i] != -1)
916 {
917 const AliHLTMUONTriggerRecoLutRow& lut =
918 fLookupTable.fRow[fCurrentCrateId][locId[i]][i][1][stripPosY[i]];
919 x[nx] = lut.fX;
920 zx[nx] = lut.fZ;
921 ++nx;
922 }
923 }
924
925 AliHLTFloat32_t mx = 0, cx = 0, my = 0, cy = 0;
926 bool xfitted = AliHLTMUONCalculations::FitLineToData(x, zx, nx);
927 mx = AliHLTMUONCalculations::Mzx();
928 cx = AliHLTMUONCalculations::Czx();
929 bool yfitted = AliHLTMUONCalculations::FitLineToData(y, zy, ny);
930 my = AliHLTMUONCalculations::Mzx();
931 cy = AliHLTMUONCalculations::Czx();
932 if (xfitted and yfitted)
933 {
934 for (int i = 0; i < 4; i++)
935 {
936 if (hitset[i]) continue; // Leave the found hits alone.
937 if (stripPosX[i] != -1)
938 {
bc5cb6d6 939 // Got X strip but no hit, so Y strip is missing.
462e3880 940 // Thus we have a good Y coordinate but poor X.
941 const AliHLTMUONTriggerRecoLutRow& lut = GetLutRowX(stripPosX[i], i);
942 trigger.fHit[i].fFlags = lut.fIdFlags;
943 trigger.fHit[i].fX = mx * lut.fZ + cx;
944 trigger.fHit[i].fY = lut.fY;
945 trigger.fHit[i].fZ = lut.fZ;
946 hitset[i] = true;
947 hitCount++;
948 }
949 else if (stripPosY[i] != -1)
950 {
bc5cb6d6 951 // Got Y strip but no hit, so X strip is missing.
462e3880 952 // Thus we have a good X coordinate but poor Y.
953 const AliHLTMUONTriggerRecoLutRow& lut =
954 fLookupTable.fRow[fCurrentCrateId][locId[i]][i][1][stripPosY[i]];
955 trigger.fHit[i].fFlags = lut.fIdFlags;
956 trigger.fHit[i].fX = lut.fX;
957 trigger.fHit[i].fY = my * lut.fZ + cy;
958 trigger.fHit[i].fZ = lut.fZ;
959 hitset[i] = true;
960 hitCount++;
961 }
962 }
963 }
964 }
bc5cb6d6 965
966 // If 4 hits found then check if they are all good, otherwise find the 3
967 // best fitting ones.
968 if (hitCount > 3)
969 {
970 AliHLTFloat32_t dx = AliMUONConstants::TriggerNonBendingReso();
971 AliHLTFloat32_t dy = AliMUONConstants::TriggerBendingReso();
972 AliHLTMUONCalculations::SigmaX2(dx*dx);
973 AliHLTMUONCalculations::SigmaY2(dy*dy);
974
975 AliHLTFloat32_t chi2 = AliHLTMUONCalculations::ComputeChi2(trigger, hitset);
976 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 for (int j = 0; j < 4; j++)
982 {
983 bool tmphitset[4] = {true, true, true, true};
984 tmphitset[j] = false;
985 AliHLTFloat32_t tmpchi2 = AliHLTMUONCalculations::ComputeChi2(trigger, tmphitset);
986 if (tmpchi2 * 4 < chi2 * 3 and tmpchi2 < bestchi2)
987 {
988 bestchi2 = tmpchi2;
989 worstHit = j;
990 }
991 }
992 if (worstHit != -1)
993 {
994 for (int j = 0; j < 4; j++) hitset[j] = true;
995 hitset[worstHit] = false;
996 trigger.fHit[worstHit] = AliHLTMUONConstants::NilRecHitStruct();
997 }
998 }
999 }
69c14678 1000
406c5bc3 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.
462e3880 1003 AliHLTUInt8_t iloc = fNextLocalIndex-1;
a3d4b6ba 1004 trigger.fId = (fTrigRecId << 8) | fDDLBit | ((fCurrentRegional & 0x7) << 4) | (iloc & 0xF);
69c14678 1005
406c5bc3 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 fTrigRecId = (fTrigRecId + 1) & 0x007FFFFF;
b39b98c8 1010
a3d4b6ba 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 if (hitset[0]) chamberZ11 = trigger.fHit[0].fZ;
1016 if (hitset[1]) chamberZ11 = trigger.fHit[1].fZ;
1017 AliHLTFloat32_t chamberZ13 = -1703.5f;
1018 if (hitset[2]) chamberZ13 = trigger.fHit[2].fZ;
1019 if (hitset[3]) chamberZ13 = trigger.fHit[3].fZ;
1020 AliHLTMUONCalculations::IdealZ1(chamberZ11);
1021 AliHLTMUONCalculations::IdealZ2(chamberZ13);
b39b98c8 1022
462e3880 1023 bool trigAdded = false;
1024
a3d4b6ba 1025 if (hitCount >= 3 and
1026 AliHLTMUONCalculations::FitLineToTriggerRecord(trigger, hitset)
1027 )
b39b98c8 1028 {
69c14678 1029 // Calculate the momentum and fill in the flags and momentum fields.
1030 AliHLTMUONCalculations::ComputeMomentum(
a3d4b6ba 1031 AliHLTMUONCalculations::IdealX1(),
1032 AliHLTMUONCalculations::IdealY1(),
1033 AliHLTMUONCalculations::IdealY2(),
1034 AliHLTMUONCalculations::IdealZ1(),
1035 AliHLTMUONCalculations::IdealZ2()
69c14678 1036 );
a3d4b6ba 1037
1038 trigger.fPx = AliHLTMUONCalculations::Px();
1039 trigger.fPy = AliHLTMUONCalculations::Py();
1040 trigger.fPz = AliHLTMUONCalculations::Pz();
69c14678 1041
a3d4b6ba 1042 trigger.fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
69c14678 1043 AliHLTMUONCalculations::Sign(),
1044 hitset
1045 );
80590aa1 1046
69c14678 1047 fOutputTrigRecsCount++;
462e3880 1048 trigAdded = true;
69c14678 1049 }
a3d4b6ba 1050 else if ((hitset[0] or hitset[1] or hitset[2] or hitset[3])
1051 and not fSuppressPartialTriggers
1052 )
69c14678 1053 {
a3d4b6ba 1054 trigger.fPx = trigger.fPy = trigger.fPz = 0;
1055
1056 trigger.fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
69c14678 1057 kSignUnknown,
1058 hitset
1059 );
80590aa1 1060
69c14678 1061 fOutputTrigRecsCount++;
462e3880 1062 trigAdded = true;
1063 }
1064
1065 if (trigAdded and fStoreInfo)
1066 {
1067 // Allocate or reallocate buffer.
1068 if (fInfoBuffer == NULL)
1069 {
1070 try
1071 {
1072 fInfoBuffer = new AliHLTMUONTrigRecInfoStruct[256];
1073 }
1074 catch (...)
1075 {
1076 HLTError("Could not allocate buffer space for debug information.");
1077 return;
1078 }
1079 fInfoBufferSize = 256;
1080 }
1081 else if (fInfoBufferCount >= fInfoBufferSize)
1082 {
1083 AliHLTMUONTrigRecInfoStruct* newbuf = NULL;
1084 try
1085 {
1086 newbuf = new AliHLTMUONTrigRecInfoStruct[fInfoBufferSize*2];
1087 }
1088 catch (...)
1089 {
bc5cb6d6 1090 HLTError("Could not allocate more buffer space for debug information.");
462e3880 1091 return;
1092 }
1093 for (AliHLTUInt32_t i = 0; i < fInfoBufferSize; ++i) newbuf[i] = fInfoBuffer[i];
1094 delete [] fInfoBuffer;
1095 fInfoBuffer = newbuf;
1096 fInfoBufferSize = fInfoBufferSize*2;
1097 }
1098
1099 fInfoBuffer[fInfoBufferCount].fTrigRecId = trigger.fId;
1100 for (int i = 0; i < 4; ++i)
1101 {
1102 if (trigger.fHit[i] != AliHLTMUONConstants::NilRecHitStruct())
1103 {
1104 fInfoBuffer[fInfoBufferCount].fDetElemId[i] =
1105 AliHLTMUONUtils::GetDetElemIdFromFlags(trigger.fHit[i].fFlags);
1106 }
1107 else
1108 {
1109 fInfoBuffer[fInfoBufferCount].fDetElemId[i] = -1;
1110 }
1111 }
1112 fInfoBuffer[fInfoBufferCount].fZmiddle = AliHLTMUONCalculations::Zf();
1113 fInfoBuffer[fInfoBufferCount].fBl = AliHLTMUONCalculations::QBL();
1114 fInfoBuffer[fInfoBufferCount].fL0Struct = *fCurrentStruct;
1115 fInfoBuffer[fInfoBufferCount].fL0StructPrev = *fPrevStruct;
1116 fInfoBuffer[fInfoBufferCount].fL0StructNext = *fNextStruct;
1117 ++fInfoBufferCount;
69c14678 1118 }
1119}
1120
1121
1122void 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.
960d54ad 1127
16e6f752 1128 long bytepos = long(location) - long(fBufferStart);
aae30cc5 1129 if (code == kWrongEventType)
1130 {
1131 fHadWrongEventTypeError = true;
1132
1133 /// Do not generate an error message if the fDontPrintWrongEventError option is set.
1134 if (fDontPrintWrongEventError) return;
1135 }
1136 else
1137 {
1138 fHadNonWrongEventTypeError = true;
1139 }
a5d4696f 1140 if (fWarnOnly)
1141 {
1142 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 HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)",
1150 ErrorCodeToMessage(code), code, bytepos
1151 );
1152 }
6efe69e7 1153}
69c14678 1154