LCOV - code coverage report
Current view: top level - HLT/MUON/OnlineAnalysis - AliHLTMUONTriggerReconstructor.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 502 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 26 0.0 %

          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             : 

Generated by: LCOV version 1.11