]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx
Deleted old deprecated macros.
[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
18/* $Id$ */
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"
7af42d4d 45#include "AliHLTMUONUtils.h"
46#include "AliHLTMUONConstants.h"
47#include "AliHLTMUONCalculations.h"
69c14678 48#include "AliRawDataHeader.h"
7af42d4d 49#include <vector>
547f15d6 50#include <cassert>
6efe69e7 51
960d54ad 52
80590aa1 53AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor() :
69c14678 54 AliHLTLogging(),
55 fDecoder()
56{
57 /// Default constructor.
58}
59
60
61AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
62{
63 /// Default destructor.
64}
65
66
67bool AliHLTMUONTriggerReconstructor::Run(
68 const AliHLTUInt8_t* rawData,
69 AliHLTUInt32_t rawDataSize,
a5d4696f 70 bool scalarEvent,
69c14678 71 AliHLTMUONTriggerRecordStruct* trigRecord,
a3d4b6ba 72 AliHLTUInt32_t& nofTrigRec
69c14678 73 )
74{
75 /// Runs the trigger reconstruction algorithm on the raw data.
a3d4b6ba 76 /// [in] \param rawData Pointer to the raw data DDL payload.
77 /// [in] \param rawDataSize Size of the raw data DDL payload in bytes.
78 /// [in] \param scalarEvent Indicates if the raw data should contain
79 /// scalar data also.
80 /// [out] \param trigRecord Pointer to output buffer for reconstructed
81 /// trigger records.
82 /// [in/out] \param nofTrigRec Initialy should indicate the number of
83 /// elements that can be stored in the trigRecord array. It will
84 /// contain the number of elements filled after this method has returned.
85 /// \return true if raw data was decoded and false if there was a problem
86 /// with the raw data or we overflowed the output buffer.
87 ///
88 /// \note OverflowedOutputBuffer() can be used to check if the output
89 /// buffer 'trigRecord' was overflowed during this method call.
69c14678 90
91 // Reset and initialise some variables in the decoder.
92 fDecoder.GetHandler().MaxOutputTrigRecs(nofTrigRec);
93 fDecoder.GetHandler().OutputTrigRecs(trigRecord);
69c14678 94
a5d4696f 95 if (not fDecoder.Decode(rawData, rawDataSize, scalarEvent))
96 {
97 if (TryRecover())
98 {
99 HLTWarning("There was a problem with the raw data."
100 " Recovered as much data as possible."
101 " Will continue processing next event."
102 );
103 }
104 else
105 {
106 return false;
107 }
108 }
69c14678 109
110 // nofTrigRec now becomes the output of how many trigger records were found.
111 nofTrigRec = fDecoder.GetHandler().OutputTrigRecsCount();
112
113 return not fDecoder.GetHandler().OverflowedOutputBuffer();
114}
115
116
a5d4696f 117void AliHLTMUONTriggerReconstructor::TryRecover(bool value)
118{
a3d4b6ba 119 /// Sets the flag indicating if the decoder should enable the error
120 /// recovery logic.
a5d4696f 121
122 fDecoder.TryRecover(value);
123 fDecoder.ExitOnError(not value);
124 fDecoder.GetHandler().WarnOnly(value);
125}
126
127
69c14678 128AliHLTMUONTriggerReconstructor::AliDecoderHandler::AliDecoderHandler() :
129 AliMUONTriggerDDLDecoderEventHandler(),
130 AliHLTLogging(),
131 fLookupTable(),
132 fBufferStart(NULL),
133 fMaxOutputTrigRecs(0),
134 fOutputTrigRecsCount(0),
135 fOutputTrigRecs(NULL),
c95cf30c 136 fTrigRecId(0),
406c5bc3 137 fDDLBit(0),
69c14678 138 fSuppressPartialTriggers(false),
a5d4696f 139 fOverflowed(false),
a3d4b6ba 140 fWarnOnly(false),
2b7af22a 141 fUseLocalId(true),
a3d4b6ba 142 fUseCrateId(true),
143 fCurrentCrateId(0),
144 fCurrentRegional(0)
6efe69e7 145{
a3d4b6ba 146 /// Default constructor just resets the lookup table to zero and local
147 /// structure marker pointers to NULL.
b39b98c8 148
a3d4b6ba 149 for (AliHLTInt32_t i = 0; i < 16; i++)
150 for (AliHLTInt32_t j = 0; j < 16; j++)
151 for (AliHLTInt32_t k = 0; k < 4; k++)
152 for (AliHLTInt32_t n = 0; n < 2; n++)
153 for (AliHLTInt32_t m = 0; m < 16; m++)
b39b98c8 154 {
a090ff22 155 fLookupTable.fRow[i][j][k][n][m].fIdFlags = 0x0;
c95cf30c 156 fLookupTable.fRow[i][j][k][n][m].fX = 0;
157 fLookupTable.fRow[i][j][k][n][m].fY = 0;
158 fLookupTable.fRow[i][j][k][n][m].fZ = 0;
b39b98c8 159 }
6efe69e7 160}
161
162
a3d4b6ba 163bool AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindStripsOnMT1(
164 const AliMUONLocalInfoStruct* localStruct,
165 AliHLTInt32_t& xPos, AliHLTInt32_t& yPos
166 )
167{
168 /// This method will find the X and Y strip positions on stations MT1
169 /// of the trigger system which were fired for the corresponding
170 /// L0 local trigger decision.
171 /// [in] \param localStruct The local trigger structure as found in the DDL payload.
172 /// [out] \param xPos The X strip that was fired.
173 /// [out] \param yPos The Y strip that was fired.
174 /// \return true is returned if a strip was fired, otherwise a warning is
175 /// generated and false is returned.
176
177 // Try to identify the strips on MT1 (chambers 11 or 12) that fired
178 // the trigger and set yPos and xPos to the correct values.
179 // For the Y strips the yPos value might or might not have to be divided
180 // by 2. This depends on the switches in the trigger electronics and how
181 // they were configured. To avoid having to try to track this info we
182 // just use a trial and error method.
183 yPos = GetLocalYPos(localStruct);
184 AliHLTUInt32_t yStrips = GetLocalY1(localStruct);
185 if (((yStrips >> yPos) & 0x1) == 0x1)
186 {
187 // nothing to do, yPos is already correct.
188 }
189 else if (((yStrips >> (yPos + 1)) & 0x1) == 0x1)
190 {
191 yPos = yPos + 1;
192 }
193 else if (((yStrips >> (yPos / 2)) & 0x1) == 0x1)
194 {
195 yPos = yPos / 2;
196 }
197 else if (((yStrips >> (yPos / 2 + 1)) & 0x1) == 0x1)
198 {
199 yPos = yPos / 2 + 1;
200 }
201 else
202 {
203 // OK, move onto chamber 12.
204 yStrips = GetLocalY2(localStruct);
205 if (((yStrips >> (yPos)) & 0x1) == 0x1)
206 {
207 // nothing to do, yPos is already correct.
208 }
209 else if (((yStrips >> (yPos + 1)) & 0x1) == 0x1)
210 {
211 yPos = yPos + 1;
212 }
213 else if (((yStrips >> (yPos / 2)) & 0x1) == 0x1)
214 {
215 yPos = yPos / 2;
216 }
217 else if (((yStrips >> (yPos / 2 + 1)) & 0x1) == 0x1)
218 {
219 yPos = yPos / 2 + 1;
220 }
221 else
222 {
223 // At this point give up on the value of yPos and just
224 // try find the first strip that was fired.
225 yStrips = GetLocalY1(localStruct);
226 for (AliHLTInt32_t i = 0; i < 16; i++)
227 {
228 if (((yStrips >> i) & 0x1) == 0x1)
229 {
230 yPos = i;
231 goto foundYstrip;
232 }
233 }
234
235 yStrips = GetLocalY2(localStruct);
236 for (AliHLTInt32_t i = 0; i < 16; i++)
237 {
238 if (((yStrips >> i) & 0x1) == 0x1)
239 {
240 yPos = i;
241 goto foundYstrip;
242 }
243 }
244
245 // No y strip found in MT1 so this local trigger circuit
246 // does not pass the 3/4 coincidence requirement,
247 // so ignore it and continue.
248 HLTWarning("Could not find fired Y strip for local trigger"
249 " structure (regional structure = %d, crate ID = %d, ID = %d),"
250 " which corresponds to triggered strip YPos = %d.",
251 fCurrentRegional, fCurrentCrateId, GetLocalId(localStruct),
252 GetLocalYPos(localStruct)
253 );
254 return false;
255
256 foundYstrip: ;
257 }
258 }
259
260 // Now find the X strip on MT1 that fired the trigger.
261 xPos = GetLocalXPos(localStruct);
262 AliHLTUInt32_t xStrips = GetLocalX1(localStruct);
263 if (((xStrips >> (xPos / 2)) & 0x1) == 0x1)
264 {
265 xPos = xPos / 2;
266 }
267 else if (((xStrips >> (xPos / 2 + 1)) & 0x1) == 0x1)
268 {
269 xPos = xPos / 2 + 1;
270 }
271 else
272 {
273 // OK, move onto chamber 12.
274 xStrips = GetLocalX2(localStruct);
275 if (((xStrips >> (xPos / 2)) & 0x1) == 0x1)
276 {
277 xPos = xPos / 2;
278 }
279 else if (((xStrips >> (xPos / 2 + 1)) & 0x1) == 0x1)
280 {
281 xPos = xPos / 2 + 1;
282 }
283 else
284 {
285 // At this point give up on the value of xPos and just
286 // try find the first strip that was fired.
287 xStrips = GetLocalX1(localStruct);
288 for (AliHLTInt32_t i = 0; i < 16; i++)
289 {
290 if (((xStrips >> i) & 0x1) == 0x1)
291 {
292 xPos = i;
293 goto foundXstrip;
294 }
295 }
296
297 xStrips = GetLocalX2(localStruct);
298 for (AliHLTInt32_t i = 0; i < 16; i++)
299 {
300 if (((xStrips >> i) & 0x1) == 0x1)
301 {
302 xPos = i;
303 goto foundXstrip;
304 }
305 }
306
307 // No x strip found in MT1 so this local trigger circuit
308 // does not pass the 3/4 coincidence requirement,
309 // so ignore it and continue.
310 HLTWarning("Could not find fired X strip for local trigger"
311 " structure (regional structure = %d, crate ID = %d, ID = %d),"
312 " which corresponds to triggered strip XPos = %d.",
313 fCurrentRegional, fCurrentCrateId, GetLocalId(localStruct),
314 GetLocalXPos(localStruct)
315 );
316 return false;
317
318 foundXstrip: ;
319 }
320 }
321
322 return true;
323}
324
325
326void AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindXStrips(
327 const AliMUONLocalInfoStruct* localStruct, AliHLTInt32_t startPos,
328 AliHLTInt32_t pos[4]
329 )
330{
331 /// Finds the X strips that were fired in the local trigger structure.
332 /// [in] \param localStruct The local trigger structure as found in the DDL payload.
333 /// [in] \param startPos The first X strip location to start looking from.
334 /// [out] \param pos Array of X strip positions on chambers 11 to 14. pos[0]
335 /// is for chamber 11, pos[1] for chamber 12 and so on.
336 /// The elements of the array will contain -1 if no valid strip position
337 /// was found for that chamber.
338
339 assert( startPos >= 0 );
340
341 if (((GetLocalX1(localStruct) >> startPos) & 0x1) == 0x1)
342 {
343 pos[0] = startPos;
344 }
345 else
346 {
347 pos[0] = -1;
348 }
349
350 AliHLTUInt32_t xStrips = GetLocalX2(localStruct);
351 if (GetLocalSXDev(localStruct)) // check the direction of the deviation.
352 {
353 // For hits on chamber 12 we have to look for fired strips
354 // within 1 strip of startPos. Where startPos is the X position
355 // as found by FindStripsOnMT1.
356 if (((xStrips >> startPos) & 0x1) == 0x1)
357 {
358 pos[1] = startPos;
359 }
360 else if (((xStrips >> (startPos + 1)) & 0x1) == 0x1)
361 {
362 pos[1] = startPos + 1;
363 }
364 else
365 {
366 pos[1] = -1;
367 }
368
369 // Given the MT1 coordinate and the deviation information we can
370 // identify the X strip on MT2 that corresponds to the L0 trigger.
371 // For fired strips on MT2 we look for strips that are within 2
372 // strips of the position endPos = (posX + deviation) / 2, where
373 // posX = GetLocalXPos(localStruct);
374 // deviation = GetLocalXDev(localStruct)
375 // We use the 2 strip tollerance because there is a truncation of 1
376 // bit when we apply integer divide by 2.
377 // This procedure should thus apply the same constraints and
378 // tollerance as the L0 electronics for the X strip 'mini-roads',
379 // ref. section 3.4.2.2, "Technical Design Report of the Dimuon
380 // Forward Spectrometer".
381 AliHLTInt32_t endPos = (GetLocalXPos(localStruct) + GetLocalXDev(localStruct)) / 2;
382
383 // Note the order of the checks are such that we choose the strip with
384 // giving the smallest deviation.
385 xStrips = GetLocalX3(localStruct);
386 if (endPos >= 0 and ((xStrips >> endPos) & 0x1) == 0x1)
387 {
388 pos[2] = endPos;
389 }
390 else if (endPos - 1 >= 0 and ((xStrips >> (endPos - 1)) & 0x1) == 0x1)
391 {
392 pos[2] = endPos - 1;
393 }
394 else if (endPos + 1 >= 0 and ((xStrips >> (endPos + 1)) & 0x1) == 0x1)
395 {
396 pos[2] = endPos + 1;
397 }
398 else if (endPos - 2 >= 0 and ((xStrips >> (endPos - 2)) & 0x1) == 0x1)
399 {
400 pos[2] = endPos - 2;
401 }
402 else if (endPos + 2 >= 0 and ((xStrips >> (endPos + 2)) & 0x1) == 0x1)
403 {
404 pos[2] = endPos + 2;
405 }
406 else
407 {
408 pos[2] = -1;
409 }
410
411 xStrips = GetLocalX4(localStruct);
412 if (endPos >= 0 and ((xStrips >> endPos) & 0x1) == 0x1)
413 {
414 pos[3] = endPos;
415 }
416 else if (endPos - 1 >= 0 and ((xStrips >> (endPos - 1)) & 0x1) == 0x1)
417 {
418 pos[3] = endPos - 1;
419 }
420 else if (endPos + 1 >= 0 and ((xStrips >> (endPos + 1)) & 0x1) == 0x1)
421 {
422 pos[3] = endPos + 1;
423 }
424 else if (endPos - 2 >= 0 and ((xStrips >> (endPos - 2)) & 0x1) == 0x1)
425 {
426 pos[3] = endPos - 2;
427 }
428 else if (endPos + 2 >= 0 and ((xStrips >> (endPos + 2)) & 0x1) == 0x1)
429 {
430 pos[3] = endPos + 2;
431 }
432 else
433 {
434 pos[3] = -1;
435 }
436 }
437 else
438 {
439 // The following code is the same as for the
440 // GetLocalSXDev(localStruct) == true case above, but with the
441 // arithmetic changing sign.
442 if (((xStrips >> startPos) & 0x1) == 0x1)
443 {
444 pos[1] = startPos;
445 }
446 else if (startPos - 1 >= 0 and ((xStrips >> (startPos - 1)) & 0x1) == 0x1)
447 {
448 pos[1] = startPos + 1;
449 }
450 else
451 {
452 pos[1] = -1;
453 }
454
455 AliHLTInt32_t endPos = (GetLocalXPos(localStruct) - GetLocalXDev(localStruct)) / 2;
456
457 xStrips = GetLocalX3(localStruct);
458 if (endPos >= 0 and ((xStrips >> endPos) & 0x1) == 0x1)
459 {
460 pos[2] = endPos;
461 }
462 else if (endPos + 1 >= 0 and ((xStrips >> (endPos + 1)) & 0x1) == 0x1)
463 {
464 pos[2] = endPos + 1;
465 }
466 else if (endPos - 1 >= 0 and ((xStrips >> (endPos - 1)) & 0x1) == 0x1)
467 {
468 pos[2] = endPos - 1;
469 }
470 else if (endPos + 2 >= 0 and ((xStrips >> (endPos + 2)) & 0x1) == 0x1)
471 {
472 pos[2] = endPos + 2;
473 }
474 else if (endPos - 2 >= 0 and ((xStrips >> (endPos - 2)) & 0x1) == 0x1)
475 {
476 pos[2] = endPos - 2;
477 }
478 else
479 {
480 pos[2] = -1;
481 }
482
483 xStrips = GetLocalX4(localStruct);
484 if (endPos >= 0 and ((xStrips >> endPos) & 0x1) == 0x1)
485 {
486 pos[3] = endPos;
487 }
488 else if (endPos + 1 >= 0 and ((xStrips >> (endPos + 1)) & 0x1) == 0x1)
489 {
490 pos[3] = endPos + 1;
491 }
492 else if (endPos - 1 >= 0 and ((xStrips >> (endPos - 1)) & 0x1) == 0x1)
493 {
494 pos[3] = endPos - 1;
495 }
496 else if (endPos + 2 >= 0 and ((xStrips >> (endPos + 2)) & 0x1) == 0x1)
497 {
498 pos[3] = endPos + 2;
499 }
500 else if (endPos - 2 >= 0 and ((xStrips >> (endPos - 2)) & 0x1) == 0x1)
501 {
502 pos[3] = endPos - 2;
503 }
504 else
505 {
506 pos[3] = -1;
507 }
508 }
509}
510
511
512void AliHLTMUONTriggerReconstructor::AliDecoderHandler::FindYStrips(
513 const AliMUONLocalInfoStruct* localStruct, AliHLTInt32_t startPos,
514 AliHLTInt32_t pos[4]
69c14678 515 )
6efe69e7 516{
a3d4b6ba 517 /// Finds the Y strips that were fired in the local trigger structure.
518 /// [in] \param localStruct The local trigger structure as found in the DDL payload.
519 /// [in] \param startPos The first Y strip location to start looking from.
520 /// [out] \param pos Array of Y strip positions on chambers 11 to 14. pos[0]
521 /// is for chamber 11, pos[1] for chamber 12 and so on.
522 /// The elements of the array will contain -1 if no valid strip position
523 /// was found for that chamber.
69c14678 524
a3d4b6ba 525 assert( startPos >= 0 );
69c14678 526
a3d4b6ba 527 // First we scan from the i'th = startPos strip upwards (i.e. i+1, i+2 etc..)
528 // to find the first fired strip. Then we similarly scan downwards
529 // (i.e. i-1, i-2 etc..) to find the first fired strip. We actually only need
530 // to check in the range [i-1 .. i+1] due to the constraint that valid tracks
531 // only have a +/- 1 Y strip deviation on consecutive chambers.
532 // Ideally we should have all of posUp[i] == posDown[i] == startPos, but this
533 // need not be the case due to multiple scattering.
534 // This procedure should thus apply the same constraints and tollerance
535 // as the L0 electronics for the Y strip 'roads',
536 // ref. section 3.4.2.2, "Technical Design Report of the Dimuon Forward Spectrometer".
537 AliHLTUInt32_t strips[4] = {
538 GetLocalY1(localStruct), GetLocalY2(localStruct),
539 GetLocalY3(localStruct), GetLocalY4(localStruct)
540 };
541 AliHLTUInt8_t posUpCount = 0, posDownCount = 0;
542 AliHLTInt32_t posUp[4] = {-1, -1, -1, -1};
543 AliHLTInt32_t posDown[4] = {-1, -1, -1, -1};
544 for (AliHLTInt32_t n = 0; n < 4; n++)
545 {
546 for (AliHLTInt32_t i = startPos; i <= startPos+1; i++)
547 {
548 if (((strips[n] >> i) & 0x1) == 0x1)
549 {
550 posUp[n] = i;
551 posUpCount++;
552 break;
553 }
554 }
555 for (AliHLTInt32_t i = startPos; i >= 0; i--)
556 {
557 if (((strips[n] >> i) & 0x1) == 0x1)
558 {
559 posDown[n] = i;
560 posDownCount++;
561 break;
562 }
563 }
564 }
565
566 // Now select either posUp or posDown, whichever has the most found strips.
567 if (posUpCount > posDownCount)
568 {
569 for (AliHLTInt32_t n = 0; n < 4; n++)
570 pos[n] = posUp[n];
571 }
572 else
573 {
574 for (AliHLTInt32_t n = 0; n < 4; n++)
575 pos[n] = posDown[n];
576 }
6efe69e7 577}
578
6efe69e7 579
a3d4b6ba 580void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ReconstructHit(
581 AliHLTUInt32_t xStrips, AliHLTUInt32_t yStrips,
582 AliHLTInt32_t xPos, AliHLTInt32_t yPos,
583 AliHLTUInt8_t crateId, AliHLTUInt8_t locId, AliHLTUInt8_t chamber,
584 AliHLTMUONRecHitStruct& hit
585 )
586{
587 /// Reconstructs the hit coordinates for the given chamber from the
588 /// strip and fired strip information provided.
589 /// [in] \param xStrips The X strip pattern for the given chamber.
590 /// [in] \param yStrips The Y strip pattern for the given chamber.
591 /// [in] \param xPos The position of the X strip that was fired.
592 /// [in] \param yPos The position of the Y strip that was fired.
593 /// [in] \param chamber The chamber on which the strips were found.
594 /// Valid range [0..3].
595 /// [out] \param hit This will be filled with the reconstructed hit.
596
597 assert( 0 <= xPos and xPos < 16 );
598 assert( 0 <= yPos and yPos < 16 );
599 assert( ((xStrips >> xPos) & 0x1) == 0x1 );
600 assert( ((yStrips >> yPos) & 0x1) == 0x1 );
601 assert( chamber <= 3 );
602 assert( crateId < 16 );
603 assert( locId < 16 );
604
605 // Decode the Y position of the hit from the strip position information.
606 // If two neighbouring strips were fired then we decluster the strips like
607 // the L0 electronics does by taking the middle position of the two strips.
608 if (xPos > 0 and ((xStrips >> (xPos-1)) & 0x1) == 0x1)
609 {
610 if (((xStrips >> (xPos+1)) & 0x1) == 0x1)
611 {
612 // Strips fired on both sides of strip at xPos so just use the middle one.
613 hit.fFlags = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fIdFlags;
614 hit.fY = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fY;
615 hit.fZ = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fZ;
616 }
617 else
618 {
619 // Second strip fired below the one at xPos, so decluster.
620 assert(xPos-1 < 16);
621 hit.fFlags = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fIdFlags;
622 hit.fY = (fLookupTable.fRow[crateId][locId][chamber][0][xPos-1].fY
623 + fLookupTable.fRow[crateId][locId][chamber][0][xPos].fY) * 0.5;
624 hit.fZ = (fLookupTable.fRow[crateId][locId][chamber][0][xPos-1].fZ
625 + fLookupTable.fRow[crateId][locId][chamber][0][xPos].fZ) * 0.5;
626 }
627 }
628 else
629 {
630 if (((xStrips >> (xPos+1)) & 0x1) == 0x1)
631 {
632 // Second strip fired above the one at xPos, so decluster.
633 assert(xPos+1 < 16);
634 hit.fFlags = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fIdFlags;
635 hit.fY = (fLookupTable.fRow[crateId][locId][chamber][0][xPos+1].fY
636 + fLookupTable.fRow[crateId][locId][chamber][0][xPos].fY) * 0.5;
637 hit.fZ = (fLookupTable.fRow[crateId][locId][chamber][0][xPos+1].fZ
638 + fLookupTable.fRow[crateId][locId][chamber][0][xPos].fZ) * 0.5;
639 }
640 else
641 {
642 // Only strip at xPos fired and neither of its two neighbours.
643 hit.fFlags = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fIdFlags;
644 hit.fY = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fY;
645 hit.fZ = fLookupTable.fRow[crateId][locId][chamber][0][xPos].fZ;
646 }
647 }
648
649 // Similarly decode the X position of the hit from the strip position information.
650 // Also decluster like for the Y strips.
651 if (yPos > 0 and ((yStrips >> (yPos-1)) & 0x1) == 0x1)
652 {
653 if (((yStrips >> (yPos+1)) & 0x1) == 0x1)
654 {
655 // Strips fired on both sides of strip at yPos so just use the middle one.
656 hit.fX = fLookupTable.fRow[crateId][locId][chamber][1][yPos].fX;
657 }
658 else
659 {
660 // Second strip fired below the one at yPos, so decluster.
661 assert(yPos-1 < 16);
662 hit.fX = (fLookupTable.fRow[crateId][locId][chamber][1][yPos-1].fX
663 + fLookupTable.fRow[crateId][locId][chamber][1][yPos].fX) * 0.5;
664 }
665 }
666 else
667 {
668 if (((yStrips >> (yPos+1)) & 0x1) == 0x1)
669 {
670 // Second strip fired above the one at yPos, so decluster.
671 assert(yPos+1 < 16);
672 hit.fX = (fLookupTable.fRow[crateId][locId][chamber][1][yPos+1].fX
673 + fLookupTable.fRow[crateId][locId][chamber][1][yPos].fX) * 0.5;
674 }
675 else
676 {
677 // Only strip at yPos fired and neither of its two neighbours.
678 hit.fX = fLookupTable.fRow[crateId][locId][chamber][1][yPos].fX;
679 }
680 }
681}
682
683
684void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnLocalStructV2(
685 UInt_t iloc,
69c14678 686 const AliMUONLocalInfoStruct* localStruct,
687 const AliMUONLocalScalarsStruct* /*scalars*/
227e7192 688 )
6efe69e7 689{
69c14678 690 /// Converts a local trigger structure from the L0 into a trigger record.
691 /// The dHLT trigger records is then used as a seed for tracking algorithms.
692 /// \note fOutputTrigRecs must be set before calling the decoder to decode
693 /// a new raw data buffer.
694 /// \param localStruct This is a pointer to the local L0 trigger structure data.
695
ffc1a6f6 696 assert(iloc < 16);
69c14678 697 assert(localStruct != NULL);
698 assert(fOutputTrigRecs != NULL);
a3d4b6ba 699
700 // We must have at least one bit in each of the 4 strip words otherwise
701 // if one of the words is zero it means we only have X or Y coordinate
702 // information for a station or no coordinate on one of the stations at all.
703 if (localStruct->fX2X1 == 0 or localStruct->fX4X3 == 0 or
704 localStruct->fY2Y1 == 0 or localStruct->fY4Y3 == 0
69c14678 705 )
706 {
707 return;
708 }
b39b98c8 709
a3d4b6ba 710 // First try to identify the X and Y strips on MT1 that fired the trigger.
711 // Note: X strips are for the Y axis in ALICE coordinate system,
712 // i.e. bending plane. and Y strips for the X axis.
713 AliHLTInt32_t xPos, yPos;
714 if (not FindStripsOnMT1(localStruct, xPos, yPos)) return;
715
69c14678 716 // Check that we will not overflow the output buffer.
717 if (fOutputTrigRecsCount >= fMaxOutputTrigRecs)
718 {
719 HLTError("Output buffer has overflowed maximum element count of %d.",
720 fMaxOutputTrigRecs
721 );
722 fOverflowed = true;
723 return;
724 }
b39b98c8 725
a3d4b6ba 726 AliHLTMUONTriggerRecordStruct& trigger = fOutputTrigRecs[fOutputTrigRecsCount];
727
728 // Now try find all the X and Y strips on all 4 trigger chambers.
729 AliHLTInt32_t stripPosX[4];
730 FindXStrips(localStruct, xPos, stripPosX);
731 AliHLTInt32_t stripPosY[4];
732 FindYStrips(localStruct, yPos, stripPosY);
406c5bc3 733
69c14678 734 // hitset indicates which hits on chambers 7 to 10 have been found and filled.
735 bool hitset[4] = {false, false, false, false};
b39b98c8 736
a3d4b6ba 737 // Reconstruct the hits from the found strips. Also, fill the hitset
738 // flags and make sure the hits for which no valid strips were found get
739 // set to a nil value.
740 AliHLTUInt32_t xStrips[4] = {
741 GetLocalX1(localStruct), GetLocalX2(localStruct),
742 GetLocalX3(localStruct), GetLocalX4(localStruct)
743 };
744 AliHLTUInt32_t yStrips[4] = {
745 GetLocalY1(localStruct), GetLocalY2(localStruct),
746 GetLocalY3(localStruct), GetLocalY4(localStruct)
747 };
748 int hitCount = 0;
749 AliHLTUInt8_t locId = GetLocalId(localStruct);
69c14678 750 for (int i = 0; i < 4; i++)
751 {
a3d4b6ba 752 if (stripPosX[i] != -1 and stripPosY[i] != -1)
69c14678 753 {
a3d4b6ba 754 ReconstructHit(
755 xStrips[i], yStrips[i],
756 stripPosX[i], stripPosY[i],
757 fCurrentCrateId, locId, i,
758 trigger.fHit[i]
759 );
760 hitset[i] = true;
761 hitCount++;
762 }
763 else
764 {
765 trigger.fHit[i] = AliHLTMUONConstants::NilRecHitStruct();
766 hitset[i] = false;
69c14678 767 }
768 }
769
406c5bc3 770 // Construct the ID from the running counter fTrigRecId and use the
771 // regional counter, local counter and DDL id for the bottom 8 bits.
a3d4b6ba 772 trigger.fId = (fTrigRecId << 8) | fDDLBit | ((fCurrentRegional & 0x7) << 4) | (iloc & 0xF);
69c14678 773
406c5bc3 774 // Increment the trigger record ID and warp it around at 0x7FFFFF since
775 // the bottom 8 bits are filled with the regional + local counters and the
776 // sign bit in fOutputTrigRecs[fOutputTrigRecsCount].fId must be positive.
777 fTrigRecId = (fTrigRecId + 1) & 0x007FFFFF;
b39b98c8 778
a3d4b6ba 779 // Set the ideal Z coordinate used in line fit for trigger record to
780 // the same as the Z coordinate for the hits that were found, otherwise
781 // use nominal coordinates.
782 AliHLTFloat32_t chamberZ11 = -1603.5f;
783 if (hitset[0]) chamberZ11 = trigger.fHit[0].fZ;
784 if (hitset[1]) chamberZ11 = trigger.fHit[1].fZ;
785 AliHLTFloat32_t chamberZ13 = -1703.5f;
786 if (hitset[2]) chamberZ13 = trigger.fHit[2].fZ;
787 if (hitset[3]) chamberZ13 = trigger.fHit[3].fZ;
788 AliHLTMUONCalculations::IdealZ1(chamberZ11);
789 AliHLTMUONCalculations::IdealZ2(chamberZ13);
b39b98c8 790
a3d4b6ba 791 if (hitCount >= 3 and
792 AliHLTMUONCalculations::FitLineToTriggerRecord(trigger, hitset)
793 )
b39b98c8 794 {
69c14678 795 // Calculate the momentum and fill in the flags and momentum fields.
796 AliHLTMUONCalculations::ComputeMomentum(
a3d4b6ba 797 AliHLTMUONCalculations::IdealX1(),
798 AliHLTMUONCalculations::IdealY1(),
799 AliHLTMUONCalculations::IdealY2(),
800 AliHLTMUONCalculations::IdealZ1(),
801 AliHLTMUONCalculations::IdealZ2()
69c14678 802 );
a3d4b6ba 803
804 trigger.fPx = AliHLTMUONCalculations::Px();
805 trigger.fPy = AliHLTMUONCalculations::Py();
806 trigger.fPz = AliHLTMUONCalculations::Pz();
69c14678 807
a3d4b6ba 808 trigger.fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
69c14678 809 AliHLTMUONCalculations::Sign(),
810 hitset
811 );
80590aa1 812
69c14678 813 fOutputTrigRecsCount++;
814 }
a3d4b6ba 815 else if ((hitset[0] or hitset[1] or hitset[2] or hitset[3])
816 and not fSuppressPartialTriggers
817 )
69c14678 818 {
a3d4b6ba 819 trigger.fPx = trigger.fPy = trigger.fPz = 0;
820
821 trigger.fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
69c14678 822 kSignUnknown,
823 hitset
824 );
80590aa1 825
69c14678 826 fOutputTrigRecsCount++;
827 }
828}
829
830
831void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnError(
832 ErrorCode code, const void* location
833 )
834{
835 /// Logs an error message if there was a decoding problem with the DDL payload.
960d54ad 836
69c14678 837 long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader);
a5d4696f 838 if (fWarnOnly)
839 {
840 HLTWarning("There is a problem with decoding the raw data."
841 " %s (Error code: %d, at byte %d). Trying to recover from corrupt data.",
842 ErrorCodeToMessage(code), code, bytepos
843 );
844 }
845 else
846 {
847 HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)",
848 ErrorCodeToMessage(code), code, bytepos
849 );
850 }
6efe69e7 851}
69c14678 852