Moving the generation of the LUTs to the component class and adding default loading...
[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 //
33 //  The trigger reconstructor class is designed to deal the rawdata inputfiles
34 //  to findout the the reconstructed hits at the trigger DDL. The output is send
35 //  to the output block for further processing.
36 //
37 //  Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
38 // 
39 //*/
40
41 #include "AliHLTMUONTriggerReconstructor.h"
42 #include "AliHLTMUONTriggerRecordsBlockStruct.h"
43 #include "AliHLTMUONUtils.h"
44 #include "AliHLTMUONConstants.h"
45 #include "AliHLTMUONCalculations.h"
46 #include <vector>
47 #include <cassert>
48
49
50 AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor() :
51         fMaxRecPointsCount(0),
52         fTrigRecId(0),
53         fLookupTable()
54 {
55         // ctor
56         
57         for (Int_t i = 0; i < 8; i++)
58         for (Int_t j = 0; j < 16; j++)
59         for (Int_t k = 0; k < 4; k++)
60         for (Int_t n = 0; n < 2; n++)
61         for (Int_t m = 0; m < 16; m++)
62         {
63                 fLookupTable.fRow[i][j][k][n][m].fX = 0;
64                 fLookupTable.fRow[i][j][k][n][m].fY = 0;
65                 fLookupTable.fRow[i][j][k][n][m].fZ = 0;
66         }
67 }
68
69
70 AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
71 {
72         // dtor
73 }
74
75
76 bool AliHLTMUONTriggerReconstructor::Run(
77                 const AliHLTUInt32_t* rawData,
78                 // TODO: if we are not checking rawDataSize then it means we are
79                 // not parsing the raw data safely or checking for corruption carefully.
80                 // This must be fixed at some point.
81                 AliHLTUInt32_t /*rawDataSize*/,
82                 AliHLTMUONTriggerRecordStruct* trigRecord,
83                 AliHLTUInt32_t& nofTrigRec,
84                 bool suppressPartialTrigs
85         )
86 {
87         fMaxRecPointsCount = nofTrigRec;
88         
89         // nofTrigRec now becomes the output of how many trigger records were found.
90         nofTrigRec = 0;
91         
92         int index = 0;
93         int reg_output, reg_phys_trig_occur;
94         int iLocIndex,loc,locDec,triggY,sign,loDev,triggX;
95         short pattern[2][4]; // 2 stands for two cathode planes and 4 stands for 4 chambers
96         
97         int phys_trig_occur = (rawData[index]>>30)&0x1; // 1 for physics trigger, 0 for software trigger
98         
99         if (not phys_trig_occur) // for software trigger
100                 index += 8 ;// corresponding to scalar words
101         
102         index += 1 ; // To skip the separator 0xDEADFACE
103         
104         index += 4 ; // corresponding to global input
105         
106         index += 1 ; // reaches to global output
107         
108         if (not phys_trig_occur) index += 10; // corresponds to scalar words
109         
110         index += 1; // separator 0xDEADBEEF 
111         
112         for (int iReg = 0; iReg < 8; iReg++)
113         {
114                 index += 1; // DARC Status Word
115                 index += 1; // Regeional Word
116                 reg_output = rawData[index] & 0xFF;
117                 reg_phys_trig_occur = ( rawData[index] >> 31) & 0x1;
118                 
119                 index += 2; // 2 words for regional input
120                 
121                 index += 1; // L0 counter
122                 
123                 if (not reg_phys_trig_occur) index += 10;
124                 
125                 index += 1; // end of Regeonal header 0xBEEFFACE
126                 
127                 for(int iLoc = 0; iLoc < 16 ; iLoc++)
128                 {
129                         iLocIndex = index;
130                         
131                         loc = (rawData[index+5] >> 19) &  0xF ;
132                         
133                         locDec = (rawData[index+5] >> 15) & 0xF;
134                         triggY = (rawData[index+5] >> 14) & 0x1;
135                         sign = (rawData[index+5] >> 9) & 0x1;
136                         loDev = (rawData[index+5] >> 5) & 0xF ;
137                         triggX = (loDev >> 4 & 0x1 ) && !(loDev & 0xF);
138                         
139                         if( locDec != 0x9 )
140                         { // check for Dec
141                         
142                                 index += 1;
143                                 pattern[0][0] = rawData[index] & 0xFFFF; // x-strip pattern for chamber 0 
144                                 pattern[0][1] = (rawData[index] >> 16) & 0xFFFF; // x-strip pattern for chamber 1
145                                 index += 1; 
146                                 pattern[0][2] = rawData[index] & 0xFFFF; 
147                                 pattern[0][3] = (rawData[index] >> 16) & 0xFFFF; 
148                                 
149                                 index += 1;
150                                 pattern[1][0] = rawData[index] & 0xFFFF; // y-strip pattern for chamber 0
151                                 pattern[1][1] = (rawData[index] >> 16) & 0xFFFF; // y-strip pattern for chamber 0 
152                                 index += 1; 
153                                 pattern[1][2] = rawData[index] & 0xFFFF; 
154                                 pattern[1][3] = (rawData[index] >> 16) & 0xFFFF; 
155                         
156                                 if (pattern[0][0] || pattern[0][1] || pattern[0][2] || pattern[0][3]
157                                    || pattern[1][0] || pattern[1][1] || pattern[1][2] || pattern[1][3]
158                                 )
159                                 {
160                                         if (nofTrigRec == fMaxRecPointsCount)
161                                         {
162                                                 HLTError("Output buffer is overflowed maximum assiged arraysize : %d, present array index : %d",
163                                                         fMaxRecPointsCount, nofTrigRec
164                                                 );
165                                                 return false;
166                                         }
167                                 
168                                         bool Xset[4] = {false, false, false, false};
169                                         bool Yset[4] = {false, false, false, false};
170                                 
171                                         for (int iChamber = 0; iChamber < 4 ; iChamber++) //4 chambers per DDL 
172                                         for (int iPlane = 0; iPlane < 2 ; iPlane++) // 2 cathode plane
173                                         {
174                                                 for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy)
175                                                 {
176                                                         if (((pattern[iPlane][iChamber] >> ibitxy) & 0x1) != 0x1)
177                                                                 continue;
178                                                         
179                                                         if (iPlane == 1)
180                                                         {
181                                                                 trigRecord[nofTrigRec].fHit[iChamber].fX =
182                                                                         fLookupTable.fRow[iReg][iLoc][iChamber][iPlane][ibitxy].fX;
183                                                                 Xset[iChamber] = true;
184                                                         }
185                                                         else
186                                                         {
187                                                                 trigRecord[nofTrigRec].fHit[iChamber].fY =
188                                                                         fLookupTable.fRow[iReg][iLoc][iChamber][iPlane][ibitxy].fY;
189                                                                 trigRecord[nofTrigRec].fHit[iChamber].fZ =
190                                                                         fLookupTable.fRow[iReg][iLoc][iChamber][iPlane][ibitxy].fZ;
191                                                                 Yset[iChamber] = true;
192                                                         }
193                                                         
194                                                 }// loop of ibitxy
195                                         }// ichamber, iplane
196                                 
197                                         // hitset indicates which hits on chambers 7 to 10 have been found and filled.
198                                         bool hitset[4] = {false, false, false, false};
199                                         
200                                         // Fill the hitset flags and make sure the hit structures that were not
201                                         // filled (set) get set to a nil value.
202                                         for (int i = 0; i < 4; i++)
203                                         {
204                                                 hitset[i] = Xset[i] and Yset[i];
205                                                 
206                                                 if (not hitset[i])
207                                                 {
208                                                         trigRecord[nofTrigRec].fHit[i]
209                                                                 = AliHLTMUONConstants::NilRecHitStruct();
210                                                 }
211                                         }
212                         
213                                         trigRecord[nofTrigRec].fId = fTrigRecId;
214                                 
215                                         // Increment trigger record Id and keep it positive.
216                                         //TODO: handle the wrapparound better.
217                                         if (fTrigRecId < 0x7FFFFFFF)
218                                                 fTrigRecId++;
219                                         else
220                                                 fTrigRecId = 0;
221                                         
222                                         AliHLTMUONRecHitStruct* hit1 = NULL;
223                                         if (hitset[0])
224                                                 hit1 = &trigRecord[nofTrigRec].fHit[0];
225                                         else if (hitset[1])
226                                                 hit1 = &trigRecord[nofTrigRec].fHit[1];
227                                         AliHLTMUONRecHitStruct* hit2 = NULL;
228                                         if (hitset[2])
229                                                 hit2 = &trigRecord[nofTrigRec].fHit[2];
230                                         else if (hitset[3])
231                                                 hit2 = &trigRecord[nofTrigRec].fHit[3];
232                                         
233                                         if (hit1 != NULL and hit2 != NULL)
234                                         {
235                                                 // Calculate the momentum and fill in the flags and momentum fields.
236                                                 AliHLTMUONCalculations::ComputeMomentum(
237                                                                 hit1->fX,
238                                                                 hit1->fY, hit2->fY,
239                                                                 hit1->fZ, hit2->fZ
240                                                         );
241                                                 trigRecord[nofTrigRec].fPx = AliHLTMUONCalculations::Px();
242                                                 trigRecord[nofTrigRec].fPy = AliHLTMUONCalculations::Py();
243                                                 trigRecord[nofTrigRec].fPz = AliHLTMUONCalculations::Pz();
244                         
245                                                 trigRecord[nofTrigRec].fFlags =
246                                                         AliHLTMUONUtils::PackTriggerRecordFlags(
247                                                                 AliHLTMUONCalculations::Sign(),
248                                                                 hitset
249                                                         );
250                                                 
251                                                 nofTrigRec++;
252                                         }
253                                         else if ((hit1 != NULL or hit2 != NULL) and not suppressPartialTrigs)
254                                         {
255                                                 trigRecord[nofTrigRec].fPx = 0;
256                                                 trigRecord[nofTrigRec].fPy = 0;
257                                                 trigRecord[nofTrigRec].fPz = 0;
258                         
259                                                 trigRecord[nofTrigRec].fFlags =
260                                                         AliHLTMUONUtils::PackTriggerRecordFlags(
261                                                                 kSignUnknown,
262                                                                 hitset
263                                                         );
264                                                 
265                                                 nofTrigRec++;
266                                         }
267                                 
268                                 }// if any non zero pattern found
269                         
270                                 index += 1 ; // the last word, important one
271                         }// Dec Condn
272                         
273                         if (not reg_phys_trig_occur)
274                                 index += 45;
275                                 
276                         index += 1; // end of local Data 0xCAFEFADE
277                         
278                         index = iLocIndex + 6; //important to reset the index counter for fake locids like 235 
279                 }// iLoc loop
280         }// iReg Loop
281         
282         return true;
283 }