ef44ec64 |
1 | // $Id$\r |
2 | \r |
3 | /**************************************************************************\r |
31b89da4 |
4 | * This file is property of and copyright by the ALICE HLT Project *\r |
ef44ec64 |
5 | * All rights reserved. *\r |
6 | * *\r |
7 | * Primary Authors: Oystein Djuvsland *\r |
8 | * *\r |
9 | * Permission to use, copy, modify and distribute this software and its *\r |
10 | * documentation strictly for non-commercial purposes is hereby granted *\r |
11 | * without fee, provided that the above copyright notice appears in all *\r |
12 | * copies and that both the copyright notice and this permission notice *\r |
13 | * appear in the supporting documentation. The authors make no claims *\r |
31b89da4 |
14 | * about the suitability of this software for any purpose. It is *\r |
ef44ec64 |
15 | * provided "as is" without express or implied warranty. *\r |
16 | **************************************************************************/\r |
17 | \r |
31b89da4 |
18 | /**\r |
ef44ec64 |
19 | * @file AliHLTCaloClusterizer.cxx\r |
20 | * @author Oystein Djuvsland\r |
31b89da4 |
21 | * @date\r |
22 | * @brief Clusterizer for PHOS HLT\r |
ef44ec64 |
23 | */\r |
24 | \r |
25 | // see header file for class documentation\r |
26 | // or\r |
27 | // refer to README to build package\r |
28 | // or\r |
29 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt\r |
30 | \r |
31 | #include "AliHLTCaloClusterizer.h"\r |
ef44ec64 |
32 | #include "AliHLTLogging.h"\r |
33 | #include "TMath.h"\r |
ef44ec64 |
34 | #include "AliHLTCaloRecPointDataStruct.h"\r |
35 | #include "AliHLTCaloDigitDataStruct.h"\r |
36 | #include "AliHLTCaloDigitContainerDataStruct.h"\r |
4f4b7ba4 |
37 | #include "AliHLTCaloConstantsHandler.h"\r |
ef44ec64 |
38 | \r |
39 | ClassImp(AliHLTCaloClusterizer);\r |
40 | \r |
41 | AliHLTCaloClusterizer::AliHLTCaloClusterizer(TString det):\r |
31b89da4 |
42 | AliHLTCaloConstantsHandler(det),\r |
43 | fCompareFunction(CompareDigitsByPosition),\r |
44 | fRecPointArray(0),\r |
45 | fRecPointDataPtr(0),\r |
46 | fFirstRecPointPtr(0),\r |
47 | fArraySize(0),\r |
48 | fAvailableSize(0),\r |
49 | fUsedSize(0),\r |
50 | fNRecPoints(0),\r |
51 | fDigitIndexPtr(0),\r |
52 | fEmcClusteringThreshold(0),\r |
53 | fEmcMinEnergyThreshold(0),\r |
54 | fEmcTimeGate(0),\r |
55 | fDigitsInCluster(0),\r |
56 | fDigitsPointerArray(0),\r |
57 | fDigitContainerPtr(0),\r |
58 | fMaxDigitIndexDiff(0),\r |
59 | fNDigits(0),\r |
60 | fSortedByPosition(false),\r |
61 | fSortedByEnergy(false),\r |
62 | fSortDigits(false)\r |
ef44ec64 |
63 | {\r |
31b89da4 |
64 | //See header file for documentation\r |
65 | //fEmcClusteringThreshold = 0.2;\r |
66 | //fEmcMinEnergyThreshold = 0.03;\r |
67 | \r |
68 | fEmcClusteringThreshold = 0.1;\r |
69 | fEmcMinEnergyThreshold = 0.01;\r |
70 | fEmcTimeGate = 1.e-6 ;\r |
71 | \r |
72 | fMaxDigitIndexDiff = 2*fCaloConstants->GetNZROWSMOD();\r |
73 | \r |
74 | \r |
75 | fArraySize = 10;\r |
76 | fRecPointArray = new AliHLTCaloRecPointDataStruct*[fArraySize];\r |
77 | \r |
78 | fAvailableSize = sizeof(AliHLTCaloRecPointDataStruct) * 20;\r |
79 | fFirstRecPointPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(new UChar_t[fAvailableSize]);\r |
80 | fRecPointDataPtr = fFirstRecPointPtr;\r |
c375e15d |
81 | \r |
c375e15d |
82 | }//end\r |
83 | \r |
31b89da4 |
84 | AliHLTCaloClusterizer::~AliHLTCaloClusterizer()\r |
ef44ec64 |
85 | {\r |
31b89da4 |
86 | //See header file for documentation\r |
ef44ec64 |
87 | }\r |
88 | \r |
31b89da4 |
89 | void\r |
ef44ec64 |
90 | AliHLTCaloClusterizer::SetRecPointDataPtr(AliHLTCaloRecPointDataStruct* recPointDataPtr)\r |
91 | {\r |
31b89da4 |
92 | // See header file for documentation\r |
93 | fRecPointDataPtr = recPointDataPtr;\r |
ef44ec64 |
94 | }\r |
95 | \r |
31b89da4 |
96 | Int_t\r |
7c80a370 |
97 | AliHLTCaloClusterizer::ClusterizeEvent(Int_t nDigits)\r |
ef44ec64 |
98 | {\r |
31b89da4 |
99 | //see header file for documentation\r |
100 | Int_t nRecPoints = 0;\r |
101 | fNRecPoints = 0;\r |
102 | fUsedSize = 0;\r |
103 | fNDigits = nDigits;\r |
104 | fRecPointDataPtr = fFirstRecPointPtr;\r |
105 | \r |
106 | // Sort our digits\r |
107 | SortDigits();\r |
108 | \r |
109 | //Clusterization starts\r |
110 | for (Int_t i = 0; i < nDigits; i++)\r |
111 | {\r |
112 | fDigitsInCluster = 0;\r |
113 | \r |
114 | if (fDigitsPointerArray[i]->fEnergy < fEmcClusteringThreshold)\r |
115 | {\r |
116 | continue;\r |
117 | }\r |
118 | \r |
119 | CheckArray();\r |
120 | CheckBuffer();\r |
121 | \r |
122 | // First digit is placed at the fDigits member variable in the recpoint\r |
123 | fDigitIndexPtr = &(fRecPointDataPtr->fDigits);\r |
124 | \r |
125 | fRecPointDataPtr->fAmp = 0;\r |
126 | fRecPointDataPtr->fModule = fDigitsPointerArray[i]->fModule;\r |
127 | \r |
128 | // Assigning the digit to this rec point\r |
129 | fRecPointDataPtr->fDigits = i;\r |
130 | fUsedSize += sizeof(AliHLTCaloRecPointDataStruct);\r |
131 | \r |
132 | // Incrementing the pointer to be ready for new entry\r |
133 | fDigitIndexPtr++;\r |
134 | \r |
135 | fRecPointDataPtr->fAmp += fDigitsPointerArray[i]->fEnergy;\r |
136 | fDigitsPointerArray[i]->fEnergy = 0;\r |
137 | fDigitsInCluster++;\r |
138 | nRecPoints++;\r |
139 | \r |
140 | // Scanning for the neighbours\r |
141 | if (ScanForNeighbourDigits(i, fRecPointDataPtr) != 0)\r |
142 | {\r |
143 | return -1;\r |
144 | }\r |
145 | \r |
146 | //fUsedSize += sizeof(AliHLTCaloRecPointDataStruct) + (fDigitsInCluster-1)*sizeof(AliHLTCaloDigitDataStruct);\r |
147 | \r |
148 | fRecPointDataPtr->fMultiplicity = fDigitsInCluster;\r |
149 | fRecPointArray[fNRecPoints] = fRecPointDataPtr;\r |
150 | \r |
151 | fRecPointDataPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(fDigitIndexPtr);\r |
152 | \r |
153 | fNRecPoints++;\r |
154 | \r |
ef44ec64 |
155 | }//end of clusterization\r |
70c86cde |
156 | \r |
157 | return nRecPoints;\r |
ef44ec64 |
158 | }\r |
159 | \r |
9bd6f29b |
160 | Int_t\r |
ef44ec64 |
161 | AliHLTCaloClusterizer::ScanForNeighbourDigits(Int_t index, AliHLTCaloRecPointDataStruct* recPoint)\r |
162 | {\r |
31b89da4 |
163 | //see header file for documentation\r |
ef44ec64 |
164 | \r |
31b89da4 |
165 | // The following cuts can be used if we sort by posisiton. Not tested, but it should be fine...\r |
166 | Int_t max = TMath::Min(fNDigits, (Int_t)fMaxDigitIndexDiff+index);\r |
167 | Int_t min = TMath::Max(0, (Int_t)(index - (Int_t)fMaxDigitIndexDiff));\r |
168 | \r |
169 | // All digits for now\r |
170 | max = fNDigits;\r |
171 | min = 0;\r |
172 | \r |
173 | for (Int_t j = min; j < max; j++)\r |
ef44ec64 |
174 | {\r |
31b89da4 |
175 | if (fDigitsPointerArray[j]->fEnergy > fEmcMinEnergyThreshold)\r |
176 | {\r |
177 | if (j != index)\r |
178 | {\r |
179 | if (AreNeighbours(fDigitsPointerArray[index],\r |
180 | fDigitsPointerArray[j]))\r |
181 | {\r |
182 | // Check that the buffer is large enough for adding a digit (can be heavily improved wrt performance)\r |
183 | CheckBuffer();\r |
184 | \r |
185 | // Assigning index to digit\r |
186 | *fDigitIndexPtr = j;\r |
187 | fUsedSize += sizeof(Int_t);\r |
188 | \r |
189 | // Incrementing digit pointer to be ready for new entry\r |
190 | fDigitIndexPtr++;\r |
191 | \r |
192 | // Adding the digit energy to the rec point\r |
193 | fRecPointDataPtr->fAmp += fDigitsPointerArray[j]->fEnergy;\r |
194 | \r |
195 | // Setting the digit energy to 0 (not included in clusterisation anymore)\r |
196 | fDigitsPointerArray[j]->fEnergy = 0;\r |
197 | \r |
198 | fDigitsInCluster++;\r |
199 | \r |
200 | // Scan for neighbours of this digit\r |
201 | ScanForNeighbourDigits(j, recPoint);\r |
202 | }\r |
203 | }\r |
204 | }\r |
ef44ec64 |
205 | }\r |
31b89da4 |
206 | return 0;\r |
ef44ec64 |
207 | }\r |
208 | \r |
31b89da4 |
209 | Int_t\r |
210 | AliHLTCaloClusterizer::AreNeighbours(AliHLTCaloDigitDataStruct* digit1,\r |
211 | AliHLTCaloDigitDataStruct* digit2)\r |
ef44ec64 |
212 | {\r |
31b89da4 |
213 | //see header file for documentation\r |
214 | if ( (digit1->fModule == digit2->fModule) /*&& (coord1[1]==coord2[1])*/ ) // inside the same PHOS module\r |
215 | {\r |
216 | Int_t rowdiff = TMath::Abs( digit1->fZ - digit2->fZ );\r |
217 | Int_t coldiff = TMath::Abs( digit1->fX - digit2->fX );\r |
218 | \r |
219 | // As in the offline code we define neighbours as cells that share an edge, a corner is not enough\r |
220 | if (( coldiff <= 1 && rowdiff == 0 ) || ( coldiff == 0 && rowdiff <= 1 ))\r |
221 | {\r |
222 | // Check also for time\r |
223 | if (TMath::Abs(digit1->fTime - digit2->fTime ) < fEmcTimeGate)\r |
224 | {\r |
225 | return 1;\r |
226 | }\r |
227 | }\r |
ef44ec64 |
228 | }\r |
31b89da4 |
229 | return 0;\r |
ef44ec64 |
230 | }\r |
7c80a370 |
231 | \r |
232 | \r |
233 | \r |
234 | Int_t AliHLTCaloClusterizer::CheckArray()\r |
235 | {\r |
31b89da4 |
236 | // See header file for class documentation\r |
237 | if (fArraySize == fNRecPoints)\r |
238 | {\r |
239 | fArraySize *= 2;\r |
240 | AliHLTCaloRecPointDataStruct **tmp = new AliHLTCaloRecPointDataStruct*[fArraySize];\r |
241 | memcpy(tmp, fRecPointArray, fArraySize/2 * sizeof(AliHLTCaloRecPointDataStruct*));\r |
242 | delete [] fRecPointArray;\r |
243 | fRecPointArray = tmp;\r |
244 | }\r |
245 | return 0;\r |
7c80a370 |
246 | }\r |
247 | \r |
248 | Int_t AliHLTCaloClusterizer::CheckBuffer()\r |
249 | {\r |
31b89da4 |
250 | // See header file for class documentation\r |
251 | if ((fAvailableSize - fUsedSize) < (Int_t)sizeof(AliHLTCaloRecPointDataStruct))\r |
252 | {\r |
253 | Int_t recPointOffset = reinterpret_cast<UChar_t*>(fRecPointDataPtr) - reinterpret_cast<UChar_t*>(fFirstRecPointPtr);\r |
254 | Int_t digitIndexOffset = reinterpret_cast<UChar_t*>(fDigitIndexPtr) - reinterpret_cast<UChar_t*>(fRecPointDataPtr);\r |
255 | UChar_t *tmp = new UChar_t[fAvailableSize*2];\r |
256 | \r |
257 | memcpy(tmp, fFirstRecPointPtr, fUsedSize);\r |
258 | fAvailableSize *= 2;\r |
259 | for (Int_t n = 0; n < fNRecPoints; n++)\r |
260 | {\r |
261 | fRecPointArray[n] = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(reinterpret_cast<UChar_t*>(fRecPointArray[n]) - reinterpret_cast<UChar_t*>(fFirstRecPointPtr) + reinterpret_cast<UChar_t*>(tmp));\r |
262 | }\r |
263 | delete [] fFirstRecPointPtr;\r |
264 | fFirstRecPointPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(tmp);\r |
265 | fRecPointDataPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(tmp + recPointOffset);\r |
266 | fDigitIndexPtr = reinterpret_cast<Int_t*>(reinterpret_cast<UChar_t*>(fRecPointDataPtr) + digitIndexOffset);\r |
267 | //fUsedSize = 0;\r |
268 | }\r |
269 | return 0;\r |
7c80a370 |
270 | }\r |
271 | \r |
31b89da4 |
272 | void AliHLTCaloClusterizer::SetSortDigitsByPosition()\r |
7c80a370 |
273 | {\r |
31b89da4 |
274 | // Sort the digit pointers by position\r |
275 | fCompareFunction = &CompareDigitsByPosition;\r |
276 | fSortDigits = true;\r |
277 | fSortedByPosition = true;\r |
7c80a370 |
278 | }\r |
279 | \r |
31b89da4 |
280 | void AliHLTCaloClusterizer::SetSortDigitsByEnergy()\r |
281 | {\r |
282 | // See header file for class documentation\r |
283 | fCompareFunction = &CompareDigitsByEnergy;\r |
284 | fSortDigits = true;\r |
285 | fSortedByEnergy = true;\r |
286 | }\r |
287 | \r |
288 | void AliHLTCaloClusterizer::SortDigits()\r |
289 | {\r |
290 | // See header file for class documentation\r |
291 | if (fSortDigits) qsort(fDigitsPointerArray, fNDigits, sizeof(AliHLTCaloDigitDataStruct*), fCompareFunction);\r |
292 | }\r |
293 | \r |
294 | Int_t\r |
295 | AliHLTCaloClusterizer::CompareDigitsByPosition(const void *dig0, const void *dig1)\r |
296 | {\r |
297 | // See header file for documentation\r |
298 | return (*((AliHLTCaloDigitDataStruct**)(dig0)))->fID - (*((AliHLTCaloDigitDataStruct**)(dig1)))->fID;\r |
299 | }\r |
300 | \r |
301 | Int_t\r |
302 | AliHLTCaloClusterizer::CompareDigitsByEnergy(const void *dig0, const void *dig1)\r |
7c80a370 |
303 | {\r |
31b89da4 |
304 | // See header file for documentation\r |
305 | return (*((AliHLTCaloDigitDataStruct**)(dig1)))->fEnergy - (*((AliHLTCaloDigitDataStruct**)(dig0)))->fEnergy;\r |
2a24cbbe |
306 | }\r |