]>
Commit | Line | Data |
---|---|---|
b12fe461 | 1 | /************************************************************************** |
960d54ad | 2 | * This file is property of and copyright by the ALICE HLT Project * |
3 | * All rights reserved. * | |
b12fe461 | 4 | * * |
960d54ad | 5 | * Primary Authors: * |
6 | * Indranil Das <indra.das@saha.ac.in> * | |
b12fe461 | 7 | * * |
8 | * Permission to use, copy, modify and distribute this software and its * | |
9 | * documentation strictly for non-commercial purposes is hereby granted * | |
10 | * without fee, provided that the above copyright notice appears in all * | |
11 | * copies and that both the copyright notice and this permission notice * | |
12 | * appear in the supporting documentation. The authors make no claims * | |
960d54ad | 13 | * about the suitability of this software for any purpose. It is * |
b12fe461 | 14 | * provided "as is" without express or implied warranty. * |
15 | **************************************************************************/ | |
16 | ||
1d8ae082 | 17 | // $Id$ |
b12fe461 | 18 | |
19 | /////////////////////////////////////////////// | |
20 | //Author : Indranil Das, SINP, INDIA | |
21 | // Sukalyan Chattopadhyay, SINP, INDIA | |
22 | // | |
b12fe461 | 23 | //Email : indra.das@saha.ac.in |
24 | // sukalyan.chattopadhyay@saha.ac.in | |
baff881d | 25 | // |
26 | // This class implements a hit reconstruction algorithm for the dimuon | |
27 | // high level trigger. | |
28 | // The algorithm finds 3 pad clusters by looking for unique pads with a charge | |
29 | // above a certain threshold. A centre of gravity type calculation is applied | |
30 | // to the three pads forming the cluster to find the hit's X or Y coordinate | |
31 | // along the non-bending and bending planes individually. | |
32 | // The sepperate X and Y coordinates are then merged to give the full coordinate | |
33 | // of the hit. | |
34 | ///////////////////////////////////////////////// | |
b12fe461 | 35 | |
5c561c5b | 36 | #include "AliHLTMUONHitReconstructor.h" |
baff881d | 37 | #include "AliHLTMUONRecHitsBlockStruct.h" |
83d66053 | 38 | #include "AliHLTMUONClustersBlockStruct.h" |
39 | #include "AliHLTMUONChannelsBlockStruct.h" | |
a090ff22 | 40 | #include "AliHLTMUONUtils.h" |
13f09bc1 | 41 | #include <cstring> |
84ab1541 | 42 | #include <strings.h> |
b12fe461 | 43 | |
44 | ||
ee3678d3 | 45 | const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDetectorId = 0xA00; |
46 | const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLOffSet = 12; | |
47 | const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkNofDDL = 8; | |
48 | const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLHeaderSize = 8; | |
49 | const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkLutLine = 59648 + 1; | |
50 | ||
51 | ||
52 | AliHLTMUONHitReconstructor::AliHLTMUONHitReconstructor() : | |
53 | AliHLTLogging(), | |
54 | fHLTMUONDecoder(), | |
55 | fkBlockHeaderSize(8), | |
56 | fkDspHeaderSize(8), | |
57 | fkBuspatchHeaderSize(4), | |
ffc1a6f6 | 58 | fDCCut(-1), |
ee3678d3 | 59 | fPadData(NULL), |
60 | fLookUpTableData(NULL), | |
61 | fRecPoints(NULL), | |
62 | fRecPointsCount(NULL), | |
63 | fMaxRecPointsCount(0), | |
83d66053 | 64 | fClusters(NULL), |
65 | fClusterCount(0), | |
66 | fMaxClusters(0), | |
67 | fGenerateClusterInfo(false), | |
68 | fNewClusterId(0), | |
69 | fDDL(0), | |
70 | fChannels(NULL), | |
71 | fChannelCount(0), | |
72 | fMaxChannels(0), | |
73 | fGenerateChannelInfo(false), | |
74 | fMaxChannelMult(6), | |
ee3678d3 | 75 | fCentralCountB(0), |
76 | fCentralCountNB(0), | |
ee3678d3 | 77 | fDigitPerDDL(0), |
78 | fCentralChargeB(NULL), | |
79 | fCentralChargeNB(NULL), | |
80 | fRecX(NULL), | |
81 | fRecY(NULL), | |
82 | fAvgChargeX(NULL), | |
83 | fAvgChargeY(NULL), | |
83d66053 | 84 | fTotChargeX(NULL), |
85 | fTotChargeY(NULL), | |
ee3678d3 | 86 | fNofBChannel(NULL), |
87 | fNofNBChannel(NULL), | |
aa1eea98 | 88 | fNofYNeighbour(NULL), |
ee3678d3 | 89 | fNofFiredDetElem(0), |
a9afae73 | 90 | fIdToEntry(), |
83d66053 | 91 | fMaxEntryPerBusPatch(0), |
a9afae73 | 92 | fRecoveryMode(kDontTryRecover) |
b12fe461 | 93 | { |
ee3678d3 | 94 | /// Default constructor |
95 | ||
96 | fkBlockHeaderSize = 8; | |
97 | fkDspHeaderSize = 8; | |
98 | fkBuspatchHeaderSize = 4; | |
99 | ||
100 | try | |
101 | { | |
102 | fPadData = new AliHLTMUONPad[fgkLutLine]; | |
103 | } | |
104 | catch (const std::bad_alloc&) | |
105 | { | |
878cb83d | 106 | HLTError("Dynamic memory allocation failed for fPadData in constructor."); |
ee3678d3 | 107 | throw; |
108 | } | |
109 | ||
110 | fPadData[0].fDetElemId = 0; | |
111 | fPadData[0].fIX = 0 ; | |
112 | fPadData[0].fIY = 0 ; | |
113 | fPadData[0].fRealX = 0.0 ; | |
114 | fPadData[0].fRealY = 0.0 ; | |
115 | fPadData[0].fRealZ = 0.0 ; | |
116 | fPadData[0].fHalfPadSize = 0.0 ; | |
117 | fPadData[0].fPlane = -1 ; | |
118 | fPadData[0].fCharge = 0 ; | |
66622a82 | 119 | fPadData[0].fBusPatch = -1; |
120 | fPadData[0].fRawData = 0 ; | |
ee3678d3 | 121 | |
122 | bzero(fGetIdTotalData, 336*237*2*sizeof(int)); | |
b12fe461 | 123 | } |
124 | ||
125 | ||
b12fe461 | 126 | AliHLTMUONHitReconstructor::~AliHLTMUONHitReconstructor() |
127 | { | |
ee3678d3 | 128 | /// Default destructor |
129 | ||
93a75941 | 130 | if (fPadData) |
ee3678d3 | 131 | { |
132 | delete [] fPadData; | |
133 | fPadData = NULL; | |
134 | } | |
83d66053 | 135 | |
136 | if (fClusters != NULL) | |
137 | { | |
138 | delete [] fClusters; | |
139 | } | |
140 | if (fChannels != NULL) | |
141 | { | |
142 | delete [] fChannels; | |
143 | } | |
b12fe461 | 144 | } |
145 | ||
b12fe461 | 146 | |
93a75941 | 147 | void AliHLTMUONHitReconstructor::SetLookUpTable( |
148 | const AliHLTMUONHitRecoLutRow* lookupTable, | |
83d66053 | 149 | const IdManuChannelToEntry* idToEntry, |
150 | const MaxEntryPerBusPatch* maxEntryPerBP | |
93a75941 | 151 | ) |
b12fe461 | 152 | { |
93a75941 | 153 | /// Sets the Lookup table (LUT) containing the position of each pad with |
154 | /// electronic channel associated with it. Also the appropriate manu | |
155 | /// channel ID mapping to LUT row is also set. | |
b12fe461 | 156 | |
93a75941 | 157 | assert( lookupTable != NULL ); |
158 | assert( idToEntry != NULL ); | |
83d66053 | 159 | assert( maxEntryPerBP != NULL ); |
93a75941 | 160 | |
93a75941 | 161 | fLookUpTableData = lookupTable; |
83d66053 | 162 | fIdToEntry = idToEntry; |
163 | fMaxEntryPerBusPatch = maxEntryPerBP; | |
b12fe461 | 164 | } |
165 | ||
166 | ||
a9afae73 | 167 | void AliHLTMUONHitReconstructor::TryRecover(ERecoveryMode mode) |
a5d4696f | 168 | { |
169 | /// Sets if the decoder should enable the error recovery logic. | |
170 | ||
a9afae73 | 171 | // Here we setup the various flags to control exactly how the DDL raw data |
172 | // decoder will behave and what output is generated during errors. | |
173 | fRecoveryMode = mode; | |
174 | switch (mode) | |
175 | { | |
176 | case kRecoverFull: | |
177 | fHLTMUONDecoder.TryRecover(true); | |
178 | fHLTMUONDecoder.ExitOnError(false); | |
179 | fHLTMUONDecoder.GetHandler().WarnOnly(true); | |
180 | fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true); | |
181 | break; | |
182 | case kRecoverJustSkip: | |
183 | fHLTMUONDecoder.TryRecover(false); | |
184 | fHLTMUONDecoder.ExitOnError(false); | |
185 | fHLTMUONDecoder.GetHandler().WarnOnly(true); | |
186 | fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true); | |
187 | break; | |
188 | case kRecoverFromParityErrorsOnly: | |
189 | fHLTMUONDecoder.TryRecover(false); | |
190 | fHLTMUONDecoder.ExitOnError(false); | |
191 | fHLTMUONDecoder.GetHandler().WarnOnly(false); | |
192 | fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true); | |
193 | break; | |
194 | default: | |
195 | fRecoveryMode = kDontTryRecover; | |
196 | fHLTMUONDecoder.TryRecover(false); | |
197 | fHLTMUONDecoder.ExitOnError(true); | |
198 | fHLTMUONDecoder.GetHandler().WarnOnly(false); | |
199 | fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(false); | |
200 | break; | |
201 | } | |
a5d4696f | 202 | } |
203 | ||
204 | ||
29486e5a | 205 | bool AliHLTMUONHitReconstructor::Run( |
206 | const AliHLTUInt32_t* rawData, | |
207 | AliHLTUInt32_t rawDataSize, | |
208 | AliHLTMUONRecHitStruct* recHit, | |
209 | AliHLTUInt32_t& nofHit | |
210 | ) | |
211 | { | |
b12fe461 | 212 | // main function called by HLTReconstructor to perform DHLT Hitreconstruction |
213 | ||
29486e5a | 214 | fRecPoints = recHit; |
215 | fMaxRecPointsCount = nofHit; | |
216 | fRecPointsCount = &nofHit; | |
b12fe461 | 217 | *fRecPointsCount = 0; |
ee3678d3 | 218 | fDigitPerDDL = 0; |
83d66053 | 219 | fClusterCount = 0; |
220 | fChannelCount = 0; | |
b12fe461 | 221 | |
ee3678d3 | 222 | if (not DecodeDDL(rawData, rawDataSize)) { |
223 | // Dont need to log any message again. Already done so in DecodeDDL. | |
b12fe461 | 224 | return false; |
225 | } | |
ee3678d3 | 226 | |
227 | if (fDigitPerDDL == 1) | |
13f09bc1 | 228 | { |
229 | // There are no digits to process so stop here. | |
230 | return true; | |
231 | } | |
83d66053 | 232 | |
233 | // Allocate fClusters and fChannels if required to do so and only if the allocated | |
234 | // size of the arrays is too small. | |
235 | try | |
236 | { | |
237 | if (fGenerateClusterInfo and fMaxClusters < fMaxRecPointsCount) | |
238 | { | |
239 | if (fClusters != NULL) | |
240 | { | |
241 | delete [] fClusters; | |
242 | fMaxClusters = 0; | |
243 | } | |
244 | fClusters = new AliHLTMUONClusterStruct[fMaxRecPointsCount]; | |
245 | fMaxClusters = fMaxRecPointsCount; | |
246 | } | |
247 | if (fGenerateChannelInfo and fMaxChannels < fMaxRecPointsCount*fMaxChannelMult) | |
248 | { | |
249 | if (fChannels != NULL) | |
250 | { | |
251 | delete [] fChannels; | |
252 | fMaxChannels = 0; | |
253 | } | |
254 | fChannels = new AliHLTMUONChannelStruct[fMaxRecPointsCount*fMaxChannelMult]; | |
255 | fMaxChannels = fMaxRecPointsCount*fMaxChannelMult; | |
256 | } | |
257 | } | |
258 | catch(const std::bad_alloc&) | |
259 | { | |
260 | HLTError("Could not allocate memory for the extra cluster and channel information."); | |
261 | return false; | |
262 | } | |
b12fe461 | 263 | |
13f09bc1 | 264 | if (not FindRecHits()) { |
960d54ad | 265 | HLTError("Failed to generate RecHits"); |
b12fe461 | 266 | return false; |
267 | } | |
ee3678d3 | 268 | |
b12fe461 | 269 | return true; |
270 | } | |
271 | ||
272 | ||
83d66053 | 273 | bool AliHLTMUONHitReconstructor::FillClusterData( |
274 | AliHLTMUONClusterStruct* clusters, AliHLTUInt32_t& nofClusters | |
275 | ) | |
276 | { | |
277 | /// Fills the output clusters array with extra cluster information. | |
278 | ||
279 | bool sizeOk = fClusterCount <= nofClusters; | |
280 | AliHLTUInt32_t n = sizeOk ? fClusterCount : nofClusters; | |
281 | memcpy(clusters, fClusters, sizeof(AliHLTMUONClusterStruct)*n); | |
282 | nofClusters = n; | |
283 | return sizeOk; | |
284 | } | |
285 | ||
286 | ||
287 | bool AliHLTMUONHitReconstructor::FillChannelData( | |
288 | AliHLTMUONChannelStruct* channels, AliHLTUInt32_t& nofChannels | |
289 | ) | |
290 | { | |
291 | /// Fills the output channels array with extra channel information for each cluster. | |
292 | ||
293 | bool sizeOk = fChannelCount <= nofChannels; | |
294 | AliHLTUInt32_t n = sizeOk ? fChannelCount : nofChannels; | |
295 | memcpy(channels, fChannels, sizeof(AliHLTMUONChannelStruct)*n); | |
296 | nofChannels = n; | |
297 | return sizeOk; | |
298 | } | |
299 | ||
300 | ||
ee3678d3 | 301 | bool AliHLTMUONHitReconstructor::DecodeDDL(const AliHLTUInt32_t* rawData,AliHLTUInt32_t rawDataSize) |
b12fe461 | 302 | { |
ee3678d3 | 303 | //function to decode Raw Data |
304 | ||
305 | AliHLTMUONRawDecoder& handler = reinterpret_cast<AliHLTMUONRawDecoder&>(fHLTMUONDecoder.GetHandler()); | |
306 | UInt_t bufferSize = UInt_t(rawDataSize*sizeof(AliHLTUInt32_t)); | |
307 | ||
308 | handler.SetDCCut(fDCCut); | |
309 | handler.SetPadData(fPadData); | |
310 | handler.SetLookUpTable(fLookUpTableData); | |
311 | handler.SetIdManuChannelToEntry(fIdToEntry); | |
312 | handler.SetNofFiredDetElemId(fNofFiredDetElem); | |
313 | handler.SetMaxFiredPerDetElem(fMaxFiredPerDetElem); | |
83d66053 | 314 | handler.SetMaxEntryPerBusPatch(fMaxEntryPerBusPatch); |
ee3678d3 | 315 | |
316 | if(!fHLTMUONDecoder.Decode(rawData,bufferSize)) | |
a5d4696f | 317 | { |
a9afae73 | 318 | switch (TryRecover()) |
a5d4696f | 319 | { |
a9afae73 | 320 | case kRecoverFull: |
a5d4696f | 321 | HLTWarning("There was a problem with the raw data." |
322 | " Recovered as much data as possible." | |
a9afae73 | 323 | " Will continue processing the next event." |
a5d4696f | 324 | ); |
a9afae73 | 325 | break; |
326 | case kRecoverJustSkip: | |
327 | HLTWarning("There was a problem with the raw data." | |
328 | " Skipped corrupted data structures." | |
329 | " Will continue processing the next event." | |
330 | ); | |
331 | break; | |
332 | case kRecoverFromParityErrorsOnly: | |
333 | if (fHLTMUONDecoder.GetHandler().NonParityErrorFound()) | |
334 | { | |
335 | HLTError("Failed to decode the tracker DDL raw data."); | |
336 | return false; | |
337 | } | |
338 | HLTWarning("Found parity errors in the raw data," | |
339 | " but will continue processing." | |
340 | ); | |
341 | break; | |
342 | default: | |
343 | HLTError("Failed to decode the tracker DDL raw data."); | |
a5d4696f | 344 | return false; |
345 | } | |
346 | } | |
960d54ad | 347 | |
ee3678d3 | 348 | fDigitPerDDL = handler.GetDataCount(); |
349 | fMaxFiredPerDetElem[fNofFiredDetElem-1] = handler.GetDataCount(); | |
90af8855 | 350 | |
351 | HLTDebug("fNofFiredDetElem : %d, NofDigits %d and max reco point limit is : %d, nofDetElems : %d", | |
352 | fNofFiredDetElem,fDigitPerDDL,fMaxRecPointsCount,fNofFiredDetElem); | |
353 | ||
354 | for(int iDet=0; iDet<TMath::Max(fNofFiredDetElem,130); iDet++) | |
355 | HLTDebug("NofCount (fMaxFiredPerDetElem) in iDet %d is : %d", iDet, fMaxFiredPerDetElem[iDet]); | |
356 | ||
357 | if(fNofFiredDetElem>129){ | |
358 | HLTError("Number of fired detection elements is %d, which is more than 129.", fNofFiredDetElem); | |
359 | return false; | |
360 | } | |
361 | ||
ee3678d3 | 362 | if(fDigitPerDDL == 1){ |
90af8855 | 363 | HLTDebug("An Empty DDL file was found."); |
13f09bc1 | 364 | } |
90af8855 | 365 | |
b12fe461 | 366 | return true; |
b12fe461 | 367 | } |
368 | ||
960d54ad | 369 | |
ee3678d3 | 370 | bool AliHLTMUONHitReconstructor::FindRecHits() |
b12fe461 | 371 | { |
878cb83d | 372 | // fuction that calls hit reconstruction detector element-wise. |
373 | ||
374 | assert( fCentralChargeB == NULL ); | |
375 | assert( fCentralChargeNB == NULL ); | |
376 | assert( fRecX == NULL ); | |
377 | assert( fRecY == NULL ); | |
378 | assert( fAvgChargeX == NULL ); | |
379 | assert( fAvgChargeY == NULL ); | |
83d66053 | 380 | assert( fTotChargeX == NULL ); |
381 | assert( fTotChargeY == NULL ); | |
878cb83d | 382 | assert( fNofBChannel == NULL ); |
383 | assert( fNofNBChannel == NULL ); | |
aa1eea98 | 384 | assert( fNofYNeighbour == NULL ); |
878cb83d | 385 | |
386 | bool resultOk = false; | |
90af8855 | 387 | |
388 | HLTDebug("Number of fired detection elements = %d.", fNofFiredDetElem); | |
b12fe461 | 389 | |
878cb83d | 390 | for(int iDet=0; iDet<fNofFiredDetElem ; iDet++) |
391 | { | |
392 | fCentralCountB = 0; | |
393 | fCentralCountNB = 0; | |
ee3678d3 | 394 | |
878cb83d | 395 | try |
396 | { | |
ee3678d3 | 397 | fCentralChargeB = new int[fMaxFiredPerDetElem[iDet]]; |
878cb83d | 398 | HLTDebug("Allocated fCentralChargeB with %d elements.", fMaxFiredPerDetElem[iDet]); |
ee3678d3 | 399 | fCentralChargeNB = new int[fMaxFiredPerDetElem[iDet]]; |
878cb83d | 400 | HLTDebug("Allocated fCentralChargeNB with %d elements.", fMaxFiredPerDetElem[iDet]); |
401 | resultOk = true; | |
ee3678d3 | 402 | } |
878cb83d | 403 | catch(const std::bad_alloc&) |
404 | { | |
405 | HLTError("Dynamic memory allocation failed for fCentralChargeNB and fCentralChargeB"); | |
406 | resultOk = false; | |
90af8855 | 407 | //break; Do not break. Might have smaller memory requirements in the next iteration. |
ee3678d3 | 408 | } |
409 | ||
878cb83d | 410 | // Continue processing, but check if everything is OK as we do, otherwise |
411 | // do not execute the next steps. | |
412 | if (resultOk) | |
413 | { | |
414 | if(iDet>0) | |
90af8855 | 415 | { |
416 | HLTDebug("Finding central hists from fMaxFiredPerDetElem[%d] : %d, to fMaxFiredPerDetElem[%d] : %d.", | |
417 | iDet-1, fMaxFiredPerDetElem[iDet-1], iDet, fMaxFiredPerDetElem[iDet] | |
418 | ); | |
878cb83d | 419 | FindCentralHits(fMaxFiredPerDetElem[iDet-1],fMaxFiredPerDetElem[iDet]); |
90af8855 | 420 | } |
878cb83d | 421 | else |
90af8855 | 422 | { |
423 | HLTDebug("Finding central hists from fMaxFiredPerDetElem[1] : %d, to fMaxFiredPerDetElem[%d] : %d.", | |
424 | fMaxFiredPerDetElem[1], iDet, fMaxFiredPerDetElem[iDet] | |
425 | ); | |
878cb83d | 426 | // minimum value is 1 because dataCount in ReadDDL starts from 1 instead of 0; |
427 | FindCentralHits(1,fMaxFiredPerDetElem[iDet]); | |
90af8855 | 428 | } |
429 | ||
430 | HLTDebug("Found fCentralCountB : %d, fCentralCountNB : %d",fCentralCountB,fCentralCountNB); | |
431 | if(fCentralCountB==0 or fCentralCountNB==0) | |
432 | { | |
433 | HLTDebug("There is no fired pad in bending/nonbending plane...skipping this detection element"); | |
434 | if (fCentralChargeB != NULL) | |
435 | { | |
436 | delete [] fCentralChargeB; | |
437 | HLTDebug("Released fCentralChargeB array."); | |
438 | fCentralChargeB = NULL; | |
439 | } | |
440 | if (fCentralChargeNB != NULL) | |
441 | { | |
442 | delete [] fCentralChargeNB; | |
443 | HLTDebug("Released fCentralChargeNB array."); | |
444 | fCentralChargeNB = NULL; | |
445 | } | |
446 | continue; | |
447 | } | |
448 | } | |
878cb83d | 449 | |
90af8855 | 450 | if (resultOk) |
451 | { | |
878cb83d | 452 | try |
453 | { | |
454 | fRecY = new float[fCentralCountB]; | |
455 | HLTDebug("Allocated fRecY with %d elements.", fCentralCountB); | |
456 | fRecX = new float[fCentralCountNB]; | |
457 | HLTDebug("Allocated fRecX with %d elements.", fCentralCountNB); | |
458 | fAvgChargeY = new float[fCentralCountB]; | |
459 | HLTDebug("Allocated fAvgChargeY with %d elements.", fCentralCountB); | |
460 | fAvgChargeX = new float[fCentralCountNB]; | |
461 | HLTDebug("Allocated fAvgChargeX with %d elements.", fCentralCountNB); | |
83d66053 | 462 | fTotChargeY = new float[fCentralCountB]; |
463 | HLTDebug("Allocated fTotChargeY with %d elements.", fCentralCountB); | |
464 | fTotChargeX = new float[fCentralCountNB]; | |
465 | HLTDebug("Allocated fTotChargeX with %d elements.", fCentralCountNB); | |
878cb83d | 466 | fNofBChannel = new int[fCentralCountB]; |
467 | HLTDebug("Allocated fNofBChannel with %d elements.", fCentralCountB); | |
468 | fNofNBChannel = new int[fCentralCountNB]; | |
469 | HLTDebug("Allocated fNofNBChannel with %d elements.", fCentralCountNB); | |
aa1eea98 | 470 | fNofYNeighbour = new int[fCentralCountB]; |
471 | HLTDebug("Allocated fNofBChannel with %d elements.", fCentralCountB); | |
878cb83d | 472 | resultOk = true; |
473 | } | |
474 | catch(const std::bad_alloc&){ | |
475 | HLTError("Dynamic memory allocation failed for internal arrays."); | |
476 | resultOk = false; | |
90af8855 | 477 | //break; Must not break, this will prevent calling delete and memory cleanup, i.e. memory leak. |
878cb83d | 478 | } |
ee3678d3 | 479 | } |
480 | ||
878cb83d | 481 | if (resultOk) RecXRecY(); |
482 | if (resultOk) | |
483 | { | |
484 | resultOk = MergeRecHits(); | |
485 | } | |
90af8855 | 486 | |
487 | if(iDet==0) | |
878cb83d | 488 | { |
90af8855 | 489 | // minimum value in loop is 1 because dataCount in ReadDDL starts from 1 instead of 0; |
490 | for(int i=1;i<fMaxFiredPerDetElem[iDet];i++) | |
491 | fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0; | |
492 | } | |
493 | else | |
494 | { | |
495 | for(int i=fMaxFiredPerDetElem[iDet-1];i<fMaxFiredPerDetElem[iDet];i++) | |
496 | fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0; | |
b12fe461 | 497 | } |
ee3678d3 | 498 | |
878cb83d | 499 | // Make sure to release any memory that was allocated. |
500 | if (fCentralChargeB != NULL) | |
501 | { | |
502 | delete [] fCentralChargeB; | |
503 | HLTDebug("Released fCentralChargeB array."); | |
13f09bc1 | 504 | fCentralChargeB = NULL; |
505 | } | |
878cb83d | 506 | if (fCentralChargeNB != NULL) |
507 | { | |
508 | delete [] fCentralChargeNB; | |
509 | HLTDebug("Released fCentralChargeNB array."); | |
13f09bc1 | 510 | fCentralChargeNB = NULL; |
511 | } | |
878cb83d | 512 | if (fRecX != NULL) |
513 | { | |
514 | delete [] fRecX; | |
515 | HLTDebug("Released fRecX array."); | |
516 | fRecX = NULL; | |
517 | } | |
518 | if (fRecY != NULL) | |
519 | { | |
520 | delete [] fRecY; | |
521 | HLTDebug("Released fRecY array."); | |
522 | fRecY = NULL; | |
523 | } | |
524 | if (fAvgChargeX != NULL) | |
525 | { | |
526 | delete [] fAvgChargeX; | |
527 | HLTDebug("Released fAvgChargeX array."); | |
528 | fAvgChargeX = NULL; | |
529 | } | |
530 | if (fAvgChargeY != NULL) | |
531 | { | |
532 | delete [] fAvgChargeY; | |
533 | HLTDebug("Released fAvgChargeY array."); | |
534 | fAvgChargeY = NULL; | |
535 | } | |
83d66053 | 536 | if (fTotChargeX != NULL) |
537 | { | |
538 | delete [] fTotChargeX; | |
539 | HLTDebug("Released fTotChargeX array."); | |
540 | fTotChargeX = NULL; | |
541 | } | |
542 | if (fTotChargeY != NULL) | |
543 | { | |
544 | delete [] fTotChargeY; | |
545 | HLTDebug("Released fTotChargeY array."); | |
546 | fTotChargeY = NULL; | |
547 | } | |
878cb83d | 548 | if (fNofBChannel != NULL) |
549 | { | |
550 | delete [] fNofBChannel; | |
551 | HLTDebug("Released fNofBChannel array."); | |
552 | fNofBChannel = NULL; | |
553 | } | |
554 | if (fNofNBChannel != NULL) | |
555 | { | |
556 | delete [] fNofNBChannel; | |
557 | HLTDebug("Released fNofNBChannel array."); | |
558 | fNofNBChannel = NULL; | |
559 | } | |
aa1eea98 | 560 | if (fNofYNeighbour != NULL) |
561 | { | |
562 | delete [] fNofYNeighbour; | |
563 | HLTDebug("Released fNofYNeighbour array."); | |
564 | fNofYNeighbour = NULL; | |
565 | } | |
b12fe461 | 566 | } |
ee3678d3 | 567 | |
878cb83d | 568 | Clear(); // clear internal arrays. |
b12fe461 | 569 | |
878cb83d | 570 | return resultOk; |
b12fe461 | 571 | } |
572 | ||
960d54ad | 573 | |
b12fe461 | 574 | void AliHLTMUONHitReconstructor::FindCentralHits(int minPadId, int maxPadId) |
575 | { | |
576 | // to find central hit associated with each cluster | |
577 | ||
878cb83d | 578 | assert( fCentralChargeB != NULL ); |
579 | assert( fCentralChargeNB != NULL ); | |
580 | ||
b12fe461 | 581 | int b,nb; |
582 | int idManuChannelCentral; | |
583 | bool hasFind; | |
ee3678d3 | 584 | |
b12fe461 | 585 | for(int iPad=minPadId;iPad<maxPadId;iPad++){ |
ee3678d3 | 586 | |
587 | fGetIdTotalData[fPadData[iPad].fIX] | |
588 | [fPadData[iPad].fIY] | |
589 | [fPadData[iPad].fPlane] = iPad ; | |
83d66053 | 590 | |
591 | if(fPadData[iPad].fCharge <= fDCCut ) continue; | |
b12fe461 | 592 | |
ee3678d3 | 593 | if(fPadData[iPad].fPlane == 0 ){//&& fPadData[iPad].fIY > (0+1) && fPadData[iPad].fIY < (79 - 1)){ |
594 | //if(fPadData[iPad].fIY > 0){ | |
b12fe461 | 595 | if(fCentralCountB>0){ |
596 | hasFind = false; | |
597 | for(b = 0;b<fCentralCountB;b++){ | |
598 | idManuChannelCentral = fCentralChargeB[b]; | |
ee3678d3 | 599 | if(fPadData[iPad].fIX == fPadData[idManuChannelCentral].fIX |
b12fe461 | 600 | && |
ee3678d3 | 601 | (fPadData[iPad].fIY |
b12fe461 | 602 | == fPadData[idManuChannelCentral].fIY + 1 |
603 | || | |
ee3678d3 | 604 | fPadData[iPad].fIY |
b12fe461 | 605 | == fPadData[idManuChannelCentral].fIY + 2 |
606 | || | |
ee3678d3 | 607 | fPadData[iPad].fIY |
b12fe461 | 608 | == fPadData[idManuChannelCentral].fIY - 2 |
609 | || | |
ee3678d3 | 610 | fPadData[iPad].fIY |
b12fe461 | 611 | == fPadData[idManuChannelCentral].fIY - 1)){ |
612 | ||
613 | hasFind = true; | |
ee3678d3 | 614 | if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){ |
615 | fCentralChargeB[b] = iPad; | |
b12fe461 | 616 | }// if condn on pad charge |
617 | }// if condon on pad position | |
618 | }// for loop over b | |
619 | if(!hasFind){ | |
ee3678d3 | 620 | fCentralChargeB[fCentralCountB] = iPad; |
b12fe461 | 621 | fCentralCountB++; |
622 | } | |
623 | } | |
624 | else{ | |
ee3678d3 | 625 | fCentralChargeB[fCentralCountB] = iPad; |
b12fe461 | 626 | fCentralCountB++; |
627 | }// check the size of centralHitB | |
628 | for(b = 0;b<fCentralCountB;b++){ | |
629 | idManuChannelCentral = fCentralChargeB[b]; | |
630 | } | |
631 | //}// if cond on iY > 2 (to avoid edge value pb) | |
632 | }// B/Nb checking | |
633 | else{ | |
634 | if(fCentralCountNB>0){ | |
635 | hasFind = false; | |
636 | for(nb = 0;nb<fCentralCountNB;nb++){ | |
637 | idManuChannelCentral = fCentralChargeNB[nb]; | |
ee3678d3 | 638 | if(fPadData[iPad].fIY == fPadData[idManuChannelCentral].fIY |
b12fe461 | 639 | && |
ee3678d3 | 640 | (fPadData[iPad].fIX |
b12fe461 | 641 | == fPadData[idManuChannelCentral].fIX + 1 |
642 | || | |
ee3678d3 | 643 | fPadData[iPad].fIX |
b12fe461 | 644 | == fPadData[idManuChannelCentral].fIX + 2 |
645 | || | |
ee3678d3 | 646 | fPadData[iPad].fIX |
b12fe461 | 647 | == fPadData[idManuChannelCentral].fIX - 2 |
648 | || | |
ee3678d3 | 649 | fPadData[iPad].fIX |
b12fe461 | 650 | == fPadData[idManuChannelCentral].fIX - 1)){ |
651 | ||
652 | hasFind = true; | |
ee3678d3 | 653 | if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){ |
654 | fCentralChargeNB[nb] = iPad; | |
b12fe461 | 655 | }// if condn over to find higher charge |
656 | }// if condn over to find position | |
657 | }// for loop over presently all nb values | |
658 | if(!hasFind){ | |
ee3678d3 | 659 | fCentralChargeNB[fCentralCountNB] = iPad; |
b12fe461 | 660 | fCentralCountNB++; |
661 | } | |
662 | }// centralHitNB size test | |
663 | else{ | |
ee3678d3 | 664 | fCentralChargeNB[fCentralCountNB] = iPad; |
b12fe461 | 665 | fCentralCountNB++; |
666 | }// centralHitNB size test | |
667 | ||
668 | }// fill for bending and nonbending hit | |
669 | }// detElemId loop | |
ee3678d3 | 670 | |
b12fe461 | 671 | } |
672 | ||
878cb83d | 673 | void AliHLTMUONHitReconstructor::RecXRecY() |
b12fe461 | 674 | { |
675 | // find reconstructed X and Y for each plane separately | |
878cb83d | 676 | |
677 | assert( fRecX != NULL ); | |
678 | assert( fRecY != NULL ); | |
679 | assert( fAvgChargeX != NULL ); | |
680 | assert( fAvgChargeY != NULL ); | |
83d66053 | 681 | assert( fTotChargeX != NULL ); |
682 | assert( fTotChargeY != NULL ); | |
878cb83d | 683 | assert( fNofBChannel != NULL ); |
684 | assert( fNofNBChannel != NULL ); | |
aa1eea98 | 685 | assert( fNofYNeighbour != NULL ); |
878cb83d | 686 | |
b12fe461 | 687 | int b,nb; |
688 | int idCentral; | |
689 | int idLower = 0; | |
690 | int idUpper = 0; | |
691 | int idRight = 0; | |
692 | int idLeft = 0; | |
ee3678d3 | 693 | |
b12fe461 | 694 | for(b=0;b<fCentralCountB;b++){ |
695 | idCentral = fCentralChargeB[b]; | |
ee3678d3 | 696 | |
b12fe461 | 697 | if(fPadData[idCentral].fIY==0) |
698 | idLower = 0; | |
699 | else | |
700 | idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][0]; | |
83d66053 | 701 | |
702 | if(fPadData[idCentral].fIY==236) | |
b12fe461 | 703 | idUpper = 0; |
704 | else | |
705 | idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][0]; | |
706 | ||
707 | fRecY[b] = (fPadData[idCentral].fRealY*fPadData[idCentral].fCharge | |
708 | + | |
ee3678d3 | 709 | fPadData[idUpper].fRealY*fPadData[idUpper].fCharge |
b12fe461 | 710 | + |
ee3678d3 | 711 | fPadData[idLower].fRealY*fPadData[idLower].fCharge |
712 | )/(fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge) ; | |
713 | ||
714 | fAvgChargeY[b] = (fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge)/3.0 ; | |
83d66053 | 715 | fTotChargeY[b] = (fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge); |
83d66053 | 716 | |
ee3678d3 | 717 | fNofBChannel[b] = 0; |
aa1eea98 | 718 | fNofYNeighbour[b] = 0; |
719 | if(fPadData[idLower].fCharge>0){ | |
ee3678d3 | 720 | fNofBChannel[b]++ ; |
aa1eea98 | 721 | fNofYNeighbour[b]++; |
722 | } | |
ee3678d3 | 723 | if(fPadData[idCentral].fCharge>0) |
724 | fNofBChannel[b]++ ; | |
aa1eea98 | 725 | if(fPadData[idUpper].fCharge>0){ |
ee3678d3 | 726 | fNofBChannel[b]++ ; |
aa1eea98 | 727 | fNofYNeighbour[b]++; |
728 | } | |
83d66053 | 729 | |
730 | //collect left coloumn | |
731 | if((fPadData[idCentral].fIX-1)>=0){ | |
732 | ||
733 | idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][0]; | |
734 | ||
735 | if(fPadData[idLeft].fIY==0) | |
736 | idLower = 0; | |
737 | else | |
738 | idLower = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0]; | |
739 | ||
740 | if(fPadData[idLeft].fIY==236) | |
741 | idUpper = 0; | |
742 | else | |
743 | idUpper = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0]; | |
ee3678d3 | 744 | |
83d66053 | 745 | fTotChargeY[b] += (fPadData[idLeft].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge); |
83d66053 | 746 | |
747 | if(fPadData[idLower].fCharge>0) | |
748 | fNofBChannel[b]++ ; | |
749 | if(fPadData[idLeft].fCharge>0) | |
750 | fNofBChannel[b]++ ; | |
751 | if(fPadData[idUpper].fCharge>0) | |
752 | fNofBChannel[b]++ ; | |
753 | ||
754 | } | |
755 | //////////////////////////////////////////////////// | |
756 | ||
757 | //collect right coloumn | |
758 | if((fPadData[idCentral].fIX+1)<=335){ | |
759 | ||
760 | idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][0]; | |
761 | ||
762 | if(fPadData[idRight].fIY==0) | |
763 | idLower = 0; | |
764 | else | |
765 | idLower = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0]; | |
766 | ||
767 | if(fPadData[idRight].fIY==236) | |
768 | idUpper = 0; | |
769 | else | |
770 | idUpper = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0]; | |
771 | ||
83d66053 | 772 | fTotChargeY[b] += (fPadData[idRight].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge); |
83d66053 | 773 | |
774 | if(fPadData[idLower].fCharge>0) | |
775 | fNofBChannel[b]++ ; | |
776 | if(fPadData[idRight].fCharge>0) | |
777 | fNofBChannel[b]++ ; | |
778 | if(fPadData[idUpper].fCharge>0) | |
779 | fNofBChannel[b]++ ; | |
780 | ||
781 | } | |
782 | ////////////////////////////////////////////////////////////////////////////////// | |
783 | ||
784 | ||
785 | HLTDebug("lower : %d, middle : %d, upper : %d, nofChannel : %d",fPadData[idLower].fCharge, | |
786 | fPadData[idCentral].fCharge,fPadData[idUpper].fCharge,fNofBChannel[b]); | |
ee3678d3 | 787 | |
788 | HLTDebug("RecY[%d] : %f",b,fRecY[b]); | |
b12fe461 | 789 | } |
790 | ||
791 | for(nb=0;nb<fCentralCountNB;nb++){ | |
792 | idCentral = fCentralChargeNB[nb]; | |
793 | ||
794 | if(fPadData[idCentral].fIX==0) | |
795 | idLeft = 0; | |
796 | else | |
797 | idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][1]; | |
798 | ||
799 | if(fPadData[idCentral].fIX==335) | |
800 | idRight = 0 ; | |
801 | else | |
802 | idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][1]; | |
803 | ||
804 | fRecX[nb] = (fPadData[idCentral].fRealX*fPadData[idCentral].fCharge | |
805 | + | |
806 | fPadData[idRight].fRealX*fPadData[idRight].fCharge | |
807 | + | |
808 | fPadData[idLeft].fRealX*fPadData[idLeft].fCharge | |
809 | )/(fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge); | |
810 | ||
811 | ||
ee3678d3 | 812 | fAvgChargeX[nb] = (fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge)/3.0 ; |
83d66053 | 813 | fTotChargeX[nb] = (fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge); |
66622a82 | 814 | |
ee3678d3 | 815 | fNofNBChannel[nb] = 0; |
816 | if(fPadData[idLeft].fCharge>0) | |
817 | fNofNBChannel[nb]++ ; | |
818 | if(fPadData[idCentral].fCharge>0) | |
819 | fNofNBChannel[nb]++ ; | |
820 | if(fPadData[idRight].fCharge>0) | |
821 | fNofNBChannel[nb]++ ; | |
822 | ||
83d66053 | 823 | // lower row |
824 | if((fPadData[idCentral].fIY-1)>=0){ | |
825 | ||
826 | idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][1]; | |
827 | ||
828 | if(fPadData[idLower].fIX==0) | |
829 | idLeft = 0; | |
830 | else | |
831 | idLeft = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1]; | |
832 | ||
833 | if(fPadData[idLower].fIX==335) | |
834 | idRight = 0 ; | |
835 | else | |
836 | idRight = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1]; | |
837 | ||
83d66053 | 838 | fTotChargeX[nb] += (fPadData[idLower].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge); |
83d66053 | 839 | |
840 | if(fPadData[idLeft].fCharge>0) | |
841 | fNofNBChannel[nb]++ ; | |
842 | if(fPadData[idLower].fCharge>0) | |
843 | fNofNBChannel[nb]++ ; | |
844 | if(fPadData[idRight].fCharge>0) | |
845 | fNofNBChannel[nb]++ ; | |
846 | ||
847 | } | |
848 | //////////////////////////////////////////////////////////// | |
849 | ||
850 | // Upper row | |
851 | if((fPadData[idCentral].fIY+1)<=236){ | |
852 | ||
853 | idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][1]; | |
854 | ||
855 | if(fPadData[idUpper].fIX==0) | |
856 | idLeft = 0; | |
857 | else | |
858 | idLeft = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1]; | |
859 | ||
860 | if(fPadData[idUpper].fIX==335) | |
861 | idRight = 0 ; | |
862 | else | |
863 | idRight = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1]; | |
864 | ||
83d66053 | 865 | fTotChargeX[nb] += (fPadData[idUpper].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge); |
83d66053 | 866 | |
867 | if(fPadData[idLeft].fCharge>0) | |
868 | fNofNBChannel[nb]++ ; | |
869 | if(fPadData[idRight].fCharge>0) | |
870 | fNofNBChannel[nb]++ ; | |
871 | if(fPadData[idRight].fCharge>0) | |
872 | fNofNBChannel[nb]++ ; | |
873 | ||
874 | } | |
875 | //////////////////////////////////////////////////////////// | |
876 | ||
877 | ||
878 | HLTDebug("left : %d, middle : %d, right : %d, nofChannel : %d",fPadData[idLeft].fCharge, | |
879 | fPadData[idCentral].fCharge,fPadData[idRight].fCharge,fNofNBChannel[nb]); | |
ee3678d3 | 880 | |
881 | HLTDebug("RecX[%d] : %f",nb,fRecX[nb]); | |
66622a82 | 882 | |
ee3678d3 | 883 | |
b12fe461 | 884 | } |
b12fe461 | 885 | } |
886 | ||
960d54ad | 887 | |
b12fe461 | 888 | bool AliHLTMUONHitReconstructor::MergeRecHits() |
889 | { | |
890 | // Merge reconstructed hits first over same plane then bending plane with non-bending plane | |
891 | ||
878cb83d | 892 | assert( fRecX != NULL ); |
893 | assert( fRecY != NULL ); | |
894 | assert( fAvgChargeX != NULL ); | |
895 | assert( fAvgChargeY != NULL ); | |
83d66053 | 896 | assert( fTotChargeX != NULL ); |
897 | assert( fTotChargeY != NULL ); | |
878cb83d | 898 | assert( fNofBChannel != NULL ); |
899 | assert( fNofNBChannel != NULL ); | |
aa1eea98 | 900 | assert( fNofYNeighbour != NULL ); |
878cb83d | 901 | |
b12fe461 | 902 | int idCentralB,idCentralNB ; |
903 | float padCenterXB; | |
904 | float padCenterYNB; | |
905 | float diffX,diffY; | |
906 | float halfPadLengthX,halfPadLengthY; | |
907 | ||
908 | // MERGE Bending Plane hits, which are placed side by side | |
909 | for(int i=0;i<fCentralCountB-1;i++){ | |
910 | if(fRecY[i] != 0.0){ | |
911 | for(int j=i+1;j<fCentralCountB;j++){ | |
912 | ||
913 | if(fCentralChargeB[i]==fCentralChargeB[j]){ | |
914 | fRecY[j] = 0.0; | |
915 | continue; | |
916 | } | |
917 | else if( | |
918 | ( | |
919 | fPadData[fCentralChargeB[i]].fIY == fPadData[fCentralChargeB[j]].fIY | |
920 | ) | |
921 | && | |
922 | ( | |
923 | fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX + 1 | |
924 | || | |
925 | fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX - 1 | |
926 | ) | |
927 | && | |
928 | fRecY[j] != 0.0 | |
929 | && | |
930 | fRecY[i] != 0.0 | |
931 | ){ | |
932 | ||
933 | if(fAvgChargeY[i] > fAvgChargeY[j]){ | |
934 | fRecY[i] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j] | |
935 | )/(fAvgChargeY[i] + fAvgChargeY[j]); | |
936 | fRecY[j] = 0.0; | |
937 | } | |
938 | else{ | |
939 | fRecY[j] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j] | |
940 | )/(fAvgChargeY[i] + fAvgChargeY[j]); | |
941 | fRecY[i] = 0.0; | |
942 | ||
943 | }// search for higher charge | |
944 | }//pad position | |
945 | }//j for loop | |
946 | }//if fRecY[i] != 0.0 | |
947 | }// i for loop | |
b12fe461 | 948 | |
66622a82 | 949 | // MERGE Non Bending Plane hits, which are placed side by side |
b12fe461 | 950 | for(int i=0;i<fCentralCountNB-1;i++){ |
951 | if(fRecX[i] != 0.0){ | |
952 | for(int j=i+1;j<fCentralCountNB;j++){ | |
953 | ||
954 | if(fCentralChargeNB[i]==fCentralChargeNB[j]){ | |
955 | fRecX[j] = 0.0; | |
956 | continue; | |
957 | } | |
958 | else if( | |
959 | ( | |
960 | fPadData[fCentralChargeNB[i]].fIX == fPadData[fCentralChargeNB[j]].fIX | |
961 | ) | |
962 | && | |
963 | ( | |
964 | fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY + 1 | |
965 | || | |
966 | fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY - 1 | |
967 | ) | |
968 | && | |
969 | fRecX[j] != 0.0 | |
970 | && | |
971 | fRecX[i] != 0.0 | |
972 | ){ | |
973 | ||
974 | if(fAvgChargeX[i] > fAvgChargeX[j]){ | |
975 | fRecX[i] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j] | |
976 | )/(fAvgChargeX[i] + fAvgChargeX[j]); | |
977 | fRecX[j] = 0.0; | |
978 | } | |
979 | else{ | |
980 | fRecX[j] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j] | |
981 | )/(fAvgChargeX[i] + fAvgChargeX[j]); | |
982 | fRecX[i] = 0.0; | |
983 | }// search for higher charge | |
984 | }//pad position | |
985 | }//j for loop | |
986 | }//if fRecX[i] != 0.0 | |
987 | }// i for loop | |
988 | ||
b12fe461 | 989 | // Merge bending Plane hits with Non Bending |
b12fe461 | 990 | for(int b=0;b<fCentralCountB;b++){ |
991 | if(fRecY[b]!=0.0){ | |
992 | idCentralB = fCentralChargeB[b]; | |
993 | padCenterXB = fPadData[idCentralB].fRealX; | |
994 | ||
ee3678d3 | 995 | halfPadLengthX = fPadData[idCentralB].fIY ; |
b12fe461 | 996 | |
997 | for(int nb=0;nb<fCentralCountNB;nb++){ | |
998 | if(fRecX[nb]!=0.0){ | |
999 | idCentralNB = fCentralChargeNB[nb]; | |
1000 | ||
1001 | padCenterYNB = fPadData[idCentralNB].fRealY; | |
1002 | ||
ee3678d3 | 1003 | halfPadLengthY = fPadData[idCentralNB].fHalfPadSize ; |
b12fe461 | 1004 | |
1005 | if(fabsf(fRecX[nb]) > fabsf(padCenterXB)) | |
1006 | diffX = fabsf(fRecX[nb]) - fabsf(padCenterXB); | |
1007 | else | |
1008 | diffX = fabsf(padCenterXB) - fabsf(fRecX[nb]); | |
1009 | ||
1010 | if(fabsf(padCenterYNB)>fabsf(fRecY[b])) | |
1011 | diffY = fabsf(padCenterYNB) - fabsf(fRecY[b]); | |
1012 | else | |
1013 | diffY = fabsf(fRecY[b]) - fabsf(padCenterYNB); | |
1014 | ||
1015 | if(diffX < halfPadLengthX && diffY < halfPadLengthY ){//&& fPadData[idCentralB].fIY != 0){ | |
1016 | ||
aa1eea98 | 1017 | if(fNofYNeighbour[b]==2){ |
1018 | if(fPadData[idCentralB].fDetElemId<104) | |
1019 | fRecY[b] += 0.02*sin(14.5*(fRecY[b] - fPadData[idCentralB].fRealY)) ; | |
1020 | else if(fPadData[idCentralB].fDetElemId>=200 && fPadData[idCentralB].fDetElemId<204) | |
1021 | fRecY[b] += 0.02*sin(14.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ; | |
1022 | else | |
1023 | fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ; | |
1024 | } | |
1025 | ||
1026 | if(fPadData[idCentralNB].fDetElemId<204) | |
1027 | fRecX[nb] += 0.095*sin(10.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ; | |
1028 | else if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404) | |
1029 | fRecX[nb] += 0.085*sin(9.0*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ; | |
1030 | else | |
1031 | fRecX[nb] += 0.075*sin(9.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ; | |
ee3678d3 | 1032 | |
ee3678d3 | 1033 | |
29486e5a | 1034 | // First check that we have not overflowed the buffer. |
1035 | if((*fRecPointsCount) == fMaxRecPointsCount){ | |
90af8855 | 1036 | HLTError("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d." |
1037 | " Output buffer is too small.", | |
1038 | (*fRecPointsCount),fMaxRecPointsCount | |
1039 | ); | |
29486e5a | 1040 | return false; |
1041 | } | |
a090ff22 | 1042 | |
1043 | AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags( | |
1044 | (fPadData[idCentralB].fDetElemId / 100) - 1, | |
1045 | fPadData[idCentralB].fDetElemId | |
1046 | ); | |
1047 | fRecPoints[(*fRecPointsCount)].fFlags = idflags; | |
b12fe461 | 1048 | fRecPoints[(*fRecPointsCount)].fX = fRecX[nb]; |
1049 | fRecPoints[(*fRecPointsCount)].fY = fRecY[b]; | |
1050 | fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ; | |
83d66053 | 1051 | |
1052 | if (fGenerateClusterInfo) | |
1053 | { | |
1054 | if (fClusterCount >= fMaxClusters) | |
1055 | { | |
1056 | HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters); | |
1057 | return false; | |
1058 | } | |
1059 | ||
1060 | fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL; | |
1061 | ||
1062 | // Increment the cluster ID and warp it around at 0x03FFFFFF since | |
1063 | // the bottom 5 bits are filled with the source DDL number and the | |
1064 | // sign bit in fClusters[fClusterCount].fId must be positive. | |
1065 | fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF; | |
1066 | ||
1067 | fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)]; | |
1068 | fClusters[fClusterCount].fDetElemId = fPadData[idCentralB].fDetElemId; | |
66622a82 | 1069 | fClusters[fClusterCount].fNchannelsB = fNofBChannel[b]; |
1070 | fClusters[fClusterCount].fNchannelsNB = fNofNBChannel[nb]; | |
1071 | fClusters[fClusterCount].fChargeB = fTotChargeY[b]; | |
1072 | fClusters[fClusterCount].fChargeNB = fTotChargeX[nb]; | |
83d66053 | 1073 | fClusterCount++; |
1074 | } | |
1075 | ||
1076 | if (fGenerateChannelInfo) | |
1077 | { | |
66622a82 | 1078 | // 3 by 3 pad structure around the central pad for the 2 planes. |
1079 | int pad[2][3][3] = {{ | |
1080 | {0, 0, 0}, | |
1081 | {0, idCentralB, 0}, | |
1082 | {0, 0, 0} | |
1083 | },{ | |
1084 | {0, 0, 0}, | |
1085 | {0, idCentralNB, 0}, | |
1086 | {0, 0, 0} | |
1087 | }}; | |
1088 | ||
1089 | // Find the pad index numbers for the central pads and the pads surrounding them. | |
1090 | // All these pads would have contributed to the cluster as long as their charge is != 0. | |
1091 | if (fPadData[idCentralB].fIY > 0) | |
1092 | pad[0][0][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY-1][0]; | |
1093 | if (fPadData[idCentralB].fIY < 236) | |
1094 | pad[0][2][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY+1][0]; | |
1095 | if (fPadData[idCentralB].fIX > 0) | |
1096 | { | |
1097 | int idLeft = fGetIdTotalData[fPadData[idCentralB].fIX-1][fPadData[idCentralB].fIY][0]; | |
1098 | pad[0][1][0] = idLeft; | |
1099 | if (fPadData[idLeft].fIY > 0) | |
1100 | pad[0][0][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0]; | |
1101 | if (fPadData[idLeft].fIY < 236) | |
1102 | pad[0][2][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0]; | |
1103 | } | |
1104 | if (fPadData[idCentralB].fIX < 335) | |
1105 | { | |
1106 | int idRight = fGetIdTotalData[fPadData[idCentralB].fIX+1][fPadData[idCentralB].fIY][0]; | |
1107 | pad[0][1][2] = idRight; | |
1108 | if (fPadData[idRight].fIY > 0) | |
1109 | pad[0][0][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0]; | |
1110 | if (fPadData[idRight].fIY < 236) | |
1111 | pad[0][2][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0]; | |
1112 | } | |
1113 | ||
1114 | if (fPadData[idCentralNB].fIX > 0) | |
1115 | pad[1][1][0] = fGetIdTotalData[fPadData[idCentralNB].fIX-1][fPadData[idCentralNB].fIY][1]; | |
1116 | if (fPadData[idCentralNB].fIX < 335) | |
1117 | pad[1][1][2] = fGetIdTotalData[fPadData[idCentralNB].fIX+1][fPadData[idCentralNB].fIY][1]; | |
1118 | if (fPadData[idCentralNB].fIY > 0) | |
1119 | { | |
1120 | int idLower = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY-1][1]; | |
1121 | pad[1][0][1] = idLower; | |
1122 | if (fPadData[idLower].fIX > 0) | |
1123 | pad[1][0][0] = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1]; | |
1124 | if (fPadData[idLower].fIX < 335) | |
1125 | pad[1][0][2] = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1]; | |
1126 | } | |
1127 | if (fPadData[idCentralNB].fIY < 236) | |
1128 | { | |
1129 | int idUpper = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY+1][1]; | |
1130 | pad[1][2][1] = idUpper; | |
1131 | if (fPadData[idUpper].fIX > 0) | |
1132 | pad[1][2][0] = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1]; | |
1133 | if (fPadData[idUpper].fIX < 335) | |
1134 | pad[1][2][2] = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1]; | |
1135 | } | |
1136 | ||
1137 | AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1; | |
1138 | ||
1139 | // Now generate the pad structures from all the pad indices found above. | |
1140 | for (int i = 0; i < 2; i++) | |
1141 | for (int j = 0; j < 3; j++) | |
1142 | for (int k = 0; k < 3; k++) | |
1143 | { | |
1144 | AliHLTMUONPad& p = fPadData[pad[i][j][k]]; | |
1145 | // Skip pads that have zero charge because they would not have | |
1146 | // contributed to the cluster. | |
1147 | if (p.fCharge <= 0) continue; | |
1148 | ||
1149 | UShort_t manuId; UChar_t channelId; UShort_t adc; | |
1150 | AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc); | |
1151 | ||
1152 | fChannels[fChannelCount].fClusterId = clusterId; | |
1153 | fChannels[fChannelCount].fBusPatch = p.fBusPatch; | |
1154 | fChannels[fChannelCount].fManu = manuId; | |
1155 | fChannels[fChannelCount].fChannelAddress = channelId; | |
1156 | fChannels[fChannelCount].fSignal = adc; | |
1157 | fChannels[fChannelCount].fRawDataWord = p.fRawData; | |
1158 | fChannelCount++; | |
1159 | } | |
83d66053 | 1160 | } |
1161 | ||
90af8855 | 1162 | HLTDebug("Reconstructed hit (X,Y,Z) : (%f,%f,%f)", |
1163 | fRecPoints[(*fRecPointsCount)].fX, | |
1164 | fRecPoints[(*fRecPointsCount)].fY, | |
1165 | fRecPoints[(*fRecPointsCount)].fZ | |
1166 | ); | |
b12fe461 | 1167 | (*fRecPointsCount)++; |
b12fe461 | 1168 | }//if lies wihtin 5.0 mm |
1169 | }// condn over fRecX ! = 0.0 | |
1170 | }// loop over NB side | |
1171 | }// condn on fRecY[b] != 0.0 | |
1172 | }// loop over B side; | |
1173 | ||
b12fe461 | 1174 | return true; |
1175 | } | |
13f09bc1 | 1176 | |
1177 | ||
1178 | void AliHLTMUONHitReconstructor::Clear() | |
1179 | { | |
878cb83d | 1180 | // function to clear internal arrays. |
ee3678d3 | 1181 | |
90af8855 | 1182 | HLTDebug("Clearing fPadData and fMaxFiredPerDetElem buffers."); |
1183 | ||
ee3678d3 | 1184 | for(int iPad=1;iPad<fDigitPerDDL;iPad++){ |
1185 | fGetIdTotalData[fPadData[iPad].fIX][fPadData[iPad].fIY][fPadData[iPad].fPlane] = 0; | |
1186 | fPadData[iPad].fDetElemId = 0; | |
1187 | fPadData[iPad].fIX = 0 ; | |
1188 | fPadData[iPad].fIY = 0 ; | |
1189 | fPadData[iPad].fRealX = 0.0 ; | |
1190 | fPadData[iPad].fRealY = 0.0 ; | |
1191 | fPadData[iPad].fRealZ = 0.0 ; | |
1192 | fPadData[iPad].fHalfPadSize = -1 ; | |
1193 | fPadData[iPad].fPlane = -1 ; | |
1194 | fPadData[iPad].fCharge = 0 ; | |
66622a82 | 1195 | fPadData[iPad].fBusPatch = -1; |
1196 | fPadData[iPad].fRawData = 0; | |
13f09bc1 | 1197 | } |
1198 | ||
90af8855 | 1199 | for(int i=0;i<130;i++) |
13f09bc1 | 1200 | fMaxFiredPerDetElem[i] = 0; |
ee3678d3 | 1201 | } |
1202 | ||
1203 | ||
1204 | AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::AliHLTMUONRawDecoder() : | |
1205 | fBufferStart(NULL), | |
a6b16447 | 1206 | fBusPatchId(0), |
ffc1a6f6 | 1207 | fDCCut(-1), |
a6b16447 | 1208 | fPadData(NULL), |
1209 | fLookUpTableData(NULL), | |
1210 | fNofFiredDetElem(NULL), | |
1211 | fMaxFiredPerDetElem(NULL), | |
1212 | fIdToEntry(), | |
83d66053 | 1213 | fMaxEntryPerBusPatch(), |
a6b16447 | 1214 | fDataCount(1), |
1215 | fPrevDetElemId(0), | |
1216 | fPadCharge(0), | |
1217 | fCharge(0.0), | |
1218 | fIdManuChannel(0x0), | |
a5d4696f | 1219 | fLutEntry(0), |
a9afae73 | 1220 | fWarnOnly(false), |
1221 | fSkipParityErrors(false), | |
1222 | fDontPrintParityErrors(false), | |
1223 | fPrintParityErrorAsWarning(false), | |
83d66053 | 1224 | fNonParityErrorFound(false), |
1225 | fIsMuchNoisy(false) | |
ee3678d3 | 1226 | { |
1227 | // ctor | |
1228 | } | |
1229 | ||
1230 | ||
1231 | AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::~AliHLTMUONRawDecoder() | |
1232 | { | |
1233 | // dtor | |
1234 | } | |
1235 | ||
93a75941 | 1236 | |
878cb83d | 1237 | void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/) |
1238 | { | |
1239 | /// Called for every new raw DDL data payload being processed. | |
1240 | /// Just clears internal counters. | |
1241 | /// \param buffer The pointer to the raw data buffer. | |
1242 | ||
1243 | assert( buffer != NULL ); | |
1244 | fBufferStart = buffer; | |
1245 | // dataCount starts from 1 because the 0-th element of fPadData is used as null value. | |
1246 | fDataCount = 1; | |
1247 | *fNofFiredDetElem = 0; | |
1248 | fPrevDetElemId = 0 ; | |
a9afae73 | 1249 | fNonParityErrorFound = false; |
878cb83d | 1250 | }; |
1251 | ||
1252 | ||
1253 | void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnError(ErrorCode code, const void* location) | |
1254 | { | |
1255 | /// Called if there was an error detected in the raw DDL data. | |
1256 | /// Logs an error message. | |
1257 | /// \param code The error code describing the problem. | |
1258 | /// \param location A pointer to the location in the raw data buffer | |
1259 | /// where the problem was found. | |
1260 | ||
a9afae73 | 1261 | if (code != kParityError) fNonParityErrorFound = true; |
1262 | if (fDontPrintParityErrors and code == kParityError) return; | |
1263 | ||
878cb83d | 1264 | long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader); |
a9afae73 | 1265 | if (fWarnOnly or (fPrintParityErrorAsWarning and code == kParityError)) |
1266 | { | |
1267 | HLTWarning("There is a problem with decoding the raw data." | |
1268 | " %s (Error code: %d, at byte %d). Trying to recover from corrupt data.", | |
1269 | ErrorCodeToMessage(code), code, bytepos | |
1270 | ); | |
1271 | } | |
1272 | else | |
1273 | { | |
1274 | HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)", | |
1275 | ErrorCodeToMessage(code), code, bytepos | |
1276 | ); | |
1277 | } | |
878cb83d | 1278 | }; |
1279 | ||
1280 | ||
a9afae73 | 1281 | void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnData(UInt_t dataWord, bool parityError) |
ee3678d3 | 1282 | { |
1283 | //function to arrange the decoded Raw Data | |
1284 | ||
a9afae73 | 1285 | if (fSkipParityErrors and parityError) return; |
1286 | ||
83d66053 | 1287 | if(fIsMuchNoisy) return; |
1288 | ||
ee3678d3 | 1289 | fIdManuChannel = 0x0; |
1290 | fIdManuChannel = (fIdManuChannel|fBusPatchId)<<17; | |
1291 | fIdManuChannel |= (dataWord >> 12) & 0x1FFFF; | |
1292 | ||
93a75941 | 1293 | IdManuChannelToEntry& idToEntry = * const_cast<IdManuChannelToEntry*>(fIdToEntry); |
1294 | fLutEntry = idToEntry[fIdManuChannel]; | |
90af8855 | 1295 | if(fLutEntry==0) |
1296 | { | |
1297 | HLTDebug("Failed to find a valid LUT entry."); | |
1298 | return; | |
1299 | } | |
ee3678d3 | 1300 | fPadCharge = int(((unsigned short)(dataWord & 0xFFF)) - fLookUpTableData[fLutEntry].fPed); |
1301 | ||
1302 | fCharge = 0; | |
83d66053 | 1303 | if(fPadCharge > 5.0*fLookUpTableData[fLutEntry].fSigma){ // (charge > 4) is due cut out the noise level |
ee3678d3 | 1304 | |
1305 | fPadData[fDataCount].fDetElemId = fLookUpTableData[fLutEntry].fDetElemId; | |
1306 | fPadData[fDataCount].fIX = fLookUpTableData[fLutEntry].fIX; | |
1307 | fPadData[fDataCount].fIY = fLookUpTableData[fLutEntry].fIY; | |
1308 | fPadData[fDataCount].fRealX = fLookUpTableData[fLutEntry].fRealX; | |
1309 | fPadData[fDataCount].fRealY = fLookUpTableData[fLutEntry].fRealY; | |
1310 | fPadData[fDataCount].fRealZ = fLookUpTableData[fLutEntry].fRealZ; | |
1311 | fPadData[fDataCount].fHalfPadSize = fLookUpTableData[fLutEntry].fHalfPadSize; | |
1312 | fPadData[fDataCount].fPlane = fLookUpTableData[fLutEntry].fPlane; | |
66622a82 | 1313 | fPadData[fDataCount].fBusPatch = fBusPatchId; |
1314 | fPadData[fDataCount].fRawData = dataWord; | |
ee3678d3 | 1315 | |
1316 | if ( fPadCharge < fLookUpTableData[fLutEntry].fThres ) { | |
1317 | fCharge = (fLookUpTableData[fLutEntry].fA0)*fPadCharge; | |
1318 | }else{ | |
1319 | fCharge = (fLookUpTableData[fLutEntry].fA0)*(fLookUpTableData[fLutEntry].fThres) | |
1320 | + (fLookUpTableData[fLutEntry].fA0)*(fPadCharge-fLookUpTableData[fLutEntry].fThres) | |
1321 | + (fLookUpTableData[fLutEntry].fA1)*(fPadCharge-fLookUpTableData[fLutEntry].fThres)*(fPadCharge-fLookUpTableData[fLutEntry].fThres); | |
1322 | } | |
1323 | ||
1324 | fPadData[fDataCount].fCharge = fCharge; | |
1325 | ||
1326 | if(fLookUpTableData[fLutEntry].fDetElemId != fPrevDetElemId){ | |
1327 | if((*fNofFiredDetElem)>0){ | |
1328 | fMaxFiredPerDetElem[(*fNofFiredDetElem)-1] = fDataCount; | |
1329 | } | |
90af8855 | 1330 | |
1331 | HLTDebug("detElem : %d, prevDetElem : %d, datacount : %d, maxFiredPerDetElem[%d] : %d", | |
1332 | fLookUpTableData[fLutEntry].fDetElemId,fPrevDetElemId,fDataCount, | |
1333 | ((*fNofFiredDetElem)-1),fMaxFiredPerDetElem[(*fNofFiredDetElem)-1] | |
1334 | ); | |
1335 | ||
ee3678d3 | 1336 | (*fNofFiredDetElem)++; |
1337 | fPrevDetElemId = fLookUpTableData[fLutEntry].fDetElemId ; | |
1338 | } | |
1339 | ||
83d66053 | 1340 | HLTDebug("%x, fLutEntry : %d, buspatch : %d, detele : %d, id : %d, manu : %d, channel : %d, iX : %d, iY: %d, (X,Y) : (%f, %f, %f), charge : %f, padsize : %f, plane : %d, ped : %f, sigma : %f", |
1341 | fLookUpTableData,fLutEntry,fBusPatchId,fPadData[fDataCount].fDetElemId, | |
1342 | fIdManuChannel,((dataWord >> 18) & 0x7FF),((dataWord >> 12) & 0x3F), | |
1343 | fPadData[fDataCount].fIX,fPadData[fDataCount].fIY, | |
1344 | fPadData[fDataCount].fRealX,fPadData[fDataCount].fRealY,fPadData[fDataCount].fRealZ, | |
1345 | fPadData[fDataCount].fCharge,fLookUpTableData[fLutEntry].fHalfPadSize,fPadData[fDataCount].fPlane,fLookUpTableData[fLutEntry].fPed,fLookUpTableData[fLutEntry].fSigma); | |
ee3678d3 | 1346 | |
90af8855 | 1347 | fDataCount++; |
ee3678d3 | 1348 | }// if charge is more than DC Cut limit condition |
1349 | ||
13f09bc1 | 1350 | } |