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