]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx
Fixing problem with duplicated structure IDs per event.
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONTriggerReconstructor.cxx
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 "AliHLTMUONUtils.h"
46 #include "AliHLTMUONConstants.h"
47 #include "AliHLTMUONCalculations.h"
48 #include "AliRawDataHeader.h"
49 #include <vector>
50 #include <cassert>
51
52
53 AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor() :
54         AliHLTLogging(),
55         fDecoder()
56 {
57         /// Default constructor.
58 }
59
60
61 AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
62 {
63         /// Default destructor.
64 }
65
66
67 bool AliHLTMUONTriggerReconstructor::Run(
68                 const AliHLTUInt8_t* rawData,
69                 AliHLTUInt32_t rawDataSize,
70                 bool scalarEvent,
71                 AliHLTMUONTriggerRecordStruct* trigRecord,
72                 AliHLTUInt32_t& nofTrigRec,
73                 bool suppressPartialTrigs
74         )
75 {
76         /// Runs the trigger reconstruction algorithm on the raw data.
77         
78         // Reset and initialise some variables in the decoder.
79         fDecoder.GetHandler().MaxOutputTrigRecs(nofTrigRec);
80         fDecoder.GetHandler().OutputTrigRecs(trigRecord);
81         fDecoder.GetHandler().SuppressPartialTriggers(suppressPartialTrigs);
82         
83         if (not fDecoder.Decode(rawData, rawDataSize, scalarEvent))
84         {
85                 if (TryRecover())
86                 {
87                         HLTWarning("There was a problem with the raw data."
88                                 " Recovered as much data as possible."
89                                 " Will continue processing next event."
90                         );
91                 }
92                 else
93                 {
94                         return false;
95                 }
96         }
97         
98         // nofTrigRec now becomes the output of how many trigger records were found.
99         nofTrigRec = fDecoder.GetHandler().OutputTrigRecsCount();
100         
101         return not fDecoder.GetHandler().OverflowedOutputBuffer();
102 }
103
104
105 void AliHLTMUONTriggerReconstructor::TryRecover(bool value)
106 {
107         /// Sets if the decoder should enable the error recovery logic.
108         
109         fDecoder.TryRecover(value);
110         fDecoder.ExitOnError(not value);
111         fDecoder.GetHandler().WarnOnly(value);
112 }
113
114
115 AliHLTMUONTriggerReconstructor::AliDecoderHandler::AliDecoderHandler() :
116         AliMUONTriggerDDLDecoderEventHandler(),
117         AliHLTLogging(),
118         fLookupTable(),
119         fBufferStart(NULL),
120         fMaxOutputTrigRecs(0),
121         fOutputTrigRecsCount(0),
122         fOutputTrigRecs(NULL),
123         fTrigRecId(0),
124         fDDLBit(0),
125         fCurrentRegional(0),
126         fCurrentLocal(0),
127         fSuppressPartialTriggers(false),
128         fOverflowed(false),
129         fWarnOnly(false)
130 {
131         /// Default constructor just resets the lookup table to zero.
132         
133         for (Int_t i = 0; i < 8; i++)
134         for (Int_t j = 0; j < 16; j++)
135         for (Int_t k = 0; k < 4; k++)
136         for (Int_t n = 0; n < 2; n++)
137         for (Int_t m = 0; m < 16; m++)
138         {
139                 fLookupTable.fRow[i][j][k][n][m].fIdFlags = 0x0;
140                 fLookupTable.fRow[i][j][k][n][m].fX = 0;
141                 fLookupTable.fRow[i][j][k][n][m].fY = 0;
142                 fLookupTable.fRow[i][j][k][n][m].fZ = 0;
143         }
144 }
145
146
147 void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnNewBuffer(
148                 const void* buffer, UInt_t /*bufferSize*/
149         )
150 {
151         /// Called for each new buffer. Sets the buffer and resets the structure
152         /// counters.
153         
154         assert( buffer != NULL );
155         fBufferStart = buffer;
156         
157         // Start from -1 since we increment immediately in OnNewRegionalStruct.
158         fCurrentRegional = fCurrentLocal = -1;
159 }
160
161
162 void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnLocalStruct(
163                 const AliMUONLocalInfoStruct* localStruct,
164                 const AliMUONLocalScalarsStruct* /*scalars*/
165         )
166 {
167         /// Converts a local trigger structure from the L0 into a trigger record.
168         /// The dHLT trigger records is then used as a seed for tracking algorithms.
169         /// \note fOutputTrigRecs must be set before calling the decoder to decode
170         ///    a new raw data buffer.
171         /// \param localStruct  This is a pointer to the local L0 trigger structure data.
172
173         assert(localStruct != NULL);
174         assert(fOutputTrigRecs != NULL);
175
176         fCurrentLocal++;
177         AliHLTInt32_t iReg = fCurrentRegional;
178         AliHLTInt32_t iLoc = fCurrentLocal;
179         assert(iReg >= 0 and iReg < 8);
180         assert(iLoc >= 0 and iLoc < 16);
181
182         // Check if there is anything in the trigger patterns at all.
183         // If nothing then ignore this local L0 trigger.
184         if (localStruct->fX2X1 == 0 and localStruct->fX4X3 == 0 and
185             localStruct->fY2Y1 == 0 and localStruct->fY4Y3 == 0
186            )
187         {
188                 return;
189         }
190         
191         // Check that we will not overflow the output buffer.
192         if (fOutputTrigRecsCount >= fMaxOutputTrigRecs)
193         {
194                 HLTError("Output buffer has overflowed maximum element count of %d.",
195                         fMaxOutputTrigRecs
196                 );
197                 fOverflowed = true;
198                 return;
199         }
200         
201         UShort_t pattern[2][4]; // 2 stands for two cathode planes and the 4 stands for 4 chambers.
202         pattern[0][0] = GetLocalX1(localStruct); // x-strip pattern for chamber 0
203         pattern[0][1] = GetLocalX2(localStruct); // x-strip pattern for chamber 1
204         pattern[0][2] = GetLocalX3(localStruct); // x-strip pattern for chamber 2
205         pattern[0][3] = GetLocalX4(localStruct); // x-strip pattern for chamber 3
206         pattern[1][0] = GetLocalY1(localStruct); // y-strip pattern for chamber 0
207         pattern[1][1] = GetLocalY2(localStruct); // y-strip pattern for chamber 1
208         pattern[1][2] = GetLocalY3(localStruct); // y-strip pattern for chamber 2
209         pattern[1][3] = GetLocalY4(localStruct); // y-strip pattern for chamber 3
210
211         bool setX[4] = {false, false, false, false};
212         bool setY[4] = {false, false, false, false};
213         
214         for (int iChamber = 0; iChamber < 4; iChamber++) //4 chambers
215         for (int iPlane = 0; iPlane < 2; iPlane++) // 2 cathode planes
216         {
217                 for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy)
218                 {
219                         if (((pattern[iPlane][iChamber] >> ibitxy) & 0x1) != 0x1)
220                                 continue;
221                         
222                         if (iPlane == 1)
223                         {
224                                 fOutputTrigRecs[fOutputTrigRecsCount].fHit[iChamber].fX =
225                                         fLookupTable.fRow[iReg][iLoc][iChamber][iPlane][ibitxy].fX;
226                                 fOutputTrigRecs[fOutputTrigRecsCount].fHit[iChamber].fFlags =
227                                         fLookupTable.fRow[iReg][iLoc][iChamber][iPlane][ibitxy].fIdFlags;
228                                 setX[iChamber] = true;
229                         }
230                         else
231                         {
232                                 fOutputTrigRecs[fOutputTrigRecsCount].fHit[iChamber].fY =
233                                         fLookupTable.fRow[iReg][iLoc][iChamber][iPlane][ibitxy].fY;
234                                 fOutputTrigRecs[fOutputTrigRecsCount].fHit[iChamber].fZ =
235                                         fLookupTable.fRow[iReg][iLoc][iChamber][iPlane][ibitxy].fZ;
236                                 setY[iChamber] = true;
237                         }
238                 }
239         }
240
241         // hitset indicates which hits on chambers 7 to 10 have been found and filled.
242         bool hitset[4] = {false, false, false, false};
243         
244         // Fill the hitset flags and make sure the hit structures that were not
245         // filled (set) get set to a nil value.
246         for (int i = 0; i < 4; i++)
247         {
248                 hitset[i] = setX[i] and setY[i];
249                 
250                 if (not hitset[i])
251                 {
252                         fOutputTrigRecs[fOutputTrigRecsCount].fHit[i]
253                                 = AliHLTMUONConstants::NilRecHitStruct();
254                 }
255         }
256
257         // Construct the ID from the running counter fTrigRecId and use the
258         // regional counter, local counter and DDL id for the bottom 8 bits.
259         fOutputTrigRecs[fOutputTrigRecsCount].fId =
260                 (fTrigRecId << 8) | fDDLBit | (iReg << 4) | iLoc;
261
262         // Increment the trigger record ID and warp it around at 0x7FFFFF since
263         // the bottom 8 bits are filled with the regional + local counters and the
264         // sign bit in fOutputTrigRecs[fOutputTrigRecsCount].fId must be positive.
265         fTrigRecId = (fTrigRecId + 1) & 0x007FFFFF;
266         
267         AliHLTMUONRecHitStruct* hit1 = NULL;
268         if (hitset[0])
269                 hit1 = &fOutputTrigRecs[fOutputTrigRecsCount].fHit[0];
270         else if (hitset[1])
271                 hit1 = &fOutputTrigRecs[fOutputTrigRecsCount].fHit[1];
272         AliHLTMUONRecHitStruct* hit2 = NULL;
273         if (hitset[2])
274                 hit2 = &fOutputTrigRecs[fOutputTrigRecsCount].fHit[2];
275         else if (hitset[3])
276                 hit2 = &fOutputTrigRecs[fOutputTrigRecsCount].fHit[3];
277         
278         if (hit1 != NULL and hit2 != NULL)
279         {
280                 // Calculate the momentum and fill in the flags and momentum fields.
281                 AliHLTMUONCalculations::ComputeMomentum(
282                                 hit1->fX,
283                                 hit1->fY, hit2->fY,
284                                 hit1->fZ, hit2->fZ
285                         );
286                 fOutputTrigRecs[fOutputTrigRecsCount].fPx = AliHLTMUONCalculations::Px();
287                 fOutputTrigRecs[fOutputTrigRecsCount].fPy = AliHLTMUONCalculations::Py();
288                 fOutputTrigRecs[fOutputTrigRecsCount].fPz = AliHLTMUONCalculations::Pz();
289
290                 fOutputTrigRecs[fOutputTrigRecsCount].fFlags =
291                         AliHLTMUONUtils::PackTriggerRecordFlags(
292                                 AliHLTMUONCalculations::Sign(),
293                                 hitset
294                         );
295                 
296                 fOutputTrigRecsCount++;
297         }
298         else if ((hit1 != NULL or hit2 != NULL) and not fSuppressPartialTriggers)
299         {
300                 fOutputTrigRecs[fOutputTrigRecsCount].fPx = 0;
301                 fOutputTrigRecs[fOutputTrigRecsCount].fPy = 0;
302                 fOutputTrigRecs[fOutputTrigRecsCount].fPz = 0;
303
304                 fOutputTrigRecs[fOutputTrigRecsCount].fFlags =
305                         AliHLTMUONUtils::PackTriggerRecordFlags(
306                                 kSignUnknown,
307                                 hitset
308                         );
309                 
310                 fOutputTrigRecsCount++;
311         }
312 }
313
314
315 void AliHLTMUONTriggerReconstructor::AliDecoderHandler::OnError(
316                 ErrorCode code, const void* location
317         )
318 {
319         /// Logs an error message if there was a decoding problem with the DDL payload.
320         
321         long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader);
322         if (fWarnOnly)
323         {
324                 HLTWarning("There is a problem with decoding the raw data."
325                         " %s (Error code: %d, at byte %d). Trying to recover from corrupt data.",
326                         ErrorCodeToMessage(code), code, bytepos
327                 );
328         }
329         else
330         {
331                 HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)",
332                         ErrorCodeToMessage(code), code, bytepos
333                 );
334         }
335 }
336