3 /**************************************************************************
\r
4 * This file is property of and copyright by the ALICE HLT Project *
\r
5 * All rights reserved. *
\r
7 * Primary Authors: Oystein Djuvsland *
\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
14 * about the suitability of this software for any purpose. It is *
\r
15 * provided "as is" without express or implied warranty. *
\r
16 **************************************************************************/
\r
19 * @file AliHLTCaloClusterizer.cxx
\r
20 * @author Oystein Djuvsland
\r
22 * @brief Clusterizer for PHOS HLT
\r
25 // see header file for class documentation
\r
27 // refer to README to build package
\r
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
\r
31 #include "AliHLTCaloClusterizer.h"
\r
32 #include "AliHLTLogging.h"
\r
34 #include "AliHLTCaloRecPointDataStruct.h"
\r
35 #include "AliHLTCaloDigitDataStruct.h"
\r
36 #include "AliHLTCaloDigitContainerDataStruct.h"
\r
37 #include "AliHLTCaloConstantsHandler.h"
\r
39 ClassImp(AliHLTCaloClusterizer);
\r
41 AliHLTCaloClusterizer::AliHLTCaloClusterizer(TString det):
\r
42 AliHLTCaloConstantsHandler(det),
\r
43 fCompareFunction(CompareDigitsByPosition),
\r
45 fRecPointDataPtr(0),
\r
46 fFirstRecPointPtr(0),
\r
52 fEmcClusteringThreshold(0),
\r
53 fEmcMinEnergyThreshold(0),
\r
55 fDigitsInCluster(0),
\r
56 fDigitsPointerArray(0),
\r
57 fDigitContainerPtr(0),
\r
58 fMaxDigitIndexDiff(0),
\r
60 fSortedByPosition(false),
\r
61 fSortedByEnergy(false),
\r
65 //See header file for documentation
\r
66 //fEmcClusteringThreshold = 0.2;
\r
67 //fEmcMinEnergyThreshold = 0.03;
\r
69 fEmcClusteringThreshold = 0.1;
\r
70 fEmcMinEnergyThreshold = 0.01;
\r
71 fEmcTimeGate = 1.e-6 ;
\r
73 fMaxDigitIndexDiff = 2*fCaloConstants->GetNZROWSMOD();
\r
77 fRecPointArray = new AliHLTCaloRecPointDataStruct*[fArraySize];
\r
79 fAvailableSize = sizeof(AliHLTCaloRecPointDataStruct) * 20;
\r
80 fBuffer = new UChar_t[fAvailableSize]; //FR
\r
82 fFirstRecPointPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(fBuffer);
\r
83 fRecPointDataPtr = fFirstRecPointPtr;
\r
87 AliHLTCaloClusterizer::~AliHLTCaloClusterizer()
\r
89 //See header file for documentation
\r
90 delete [] fBuffer; //FR
\r
91 fBuffer = NULL; //FR
\r
92 fAvailableSize = 0; //FR
\r
94 delete [] fRecPointArray;
\r
98 AliHLTCaloClusterizer::SetRecPointDataPtr(AliHLTCaloRecPointDataStruct* recPointDataPtr)
\r
100 // See header file for documentation
\r
101 fRecPointDataPtr = recPointDataPtr;
\r
105 AliHLTCaloClusterizer::ClusterizeEvent(Int_t nDigits)
\r
107 //see header file for documentation
\r
108 Int_t nRecPoints = 0;
\r
111 fNDigits = nDigits;
\r
112 fRecPointDataPtr = fFirstRecPointPtr;
\r
117 //Clusterization starts
\r
118 for (Int_t i = 0; i < nDigits; i++)
\r
120 fDigitsInCluster = 0;
\r
122 HLTDebug("Digit with energy: %f", fDigitsPointerArray[i]->fEnergy);
\r
124 if (fDigitsPointerArray[i]->fEnergy < fEmcClusteringThreshold && fSortedByEnergy)
\r
126 // Since we have sorted by energy the next digit will have even lower energy, so we return
\r
127 return fNRecPoints;
\r
130 if(fDigitsPointerArray[i]->fAssociatedCluster != -1)
\r
132 // The digit is added to a previous cluster, continue
\r
139 // First digit is placed at the fDigits member variable in the recpoint
\r
140 fDigitIndexPtr = &(fRecPointDataPtr->fDigits);
\r
142 fRecPointDataPtr->fAmp = 0;
\r
143 fRecPointDataPtr->fModule = fDigitsPointerArray[i]->fModule;
\r
145 // Assigning the digit to this rec point
\r
146 fRecPointDataPtr->fDigits = i;
\r
147 fUsedSize += sizeof(AliHLTCaloRecPointDataStruct);
\r
149 // Incrementing the pointer to be ready for new entry
\r
152 fRecPointDataPtr->fAmp += fDigitsPointerArray[i]->fEnergy;
\r
155 //fDigitsPointerArray[i]->fEnergy = 0;
\r
156 fDigitsPointerArray[i]->fAssociatedCluster = fNRecPoints;
\r
159 fDigitsInCluster++;
\r
162 // Scanning for the neighbours
\r
163 if (ScanForNeighbourDigits(i, fRecPointDataPtr) != 0)
\r
168 //fUsedSize += sizeof(AliHLTCaloRecPointDataStruct) + (fDigitsInCluster-1)*sizeof(AliHLTCaloDigitDataStruct);
\r
170 fRecPointDataPtr->fMultiplicity = fDigitsInCluster;
\r
171 fRecPointArray[fNRecPoints] = fRecPointDataPtr;
\r
173 fRecPointDataPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(fDigitIndexPtr);
\r
177 }//end of clusterization
\r
183 AliHLTCaloClusterizer::ScanForNeighbourDigits(Int_t index, AliHLTCaloRecPointDataStruct* recPoint)
\r
185 //see header file for documentation
\r
187 // The following cuts can be used if we sort by posisiton. Not tested, but it should be fine...
\r
188 Int_t max = TMath::Min(fNDigits, (Int_t)fMaxDigitIndexDiff+index);
\r
189 Int_t min = TMath::Max(0, (Int_t)(index - (Int_t)fMaxDigitIndexDiff));
\r
191 // All digits for now
\r
195 for (Int_t j = min; j < max; j++)
\r
197 if (fDigitsPointerArray[j]->fAssociatedCluster == -1 && fDigitsPointerArray[j]->fEnergy > fEmcMinEnergyThreshold)
\r
201 if (AreNeighbours(fDigitsPointerArray[index],
\r
202 fDigitsPointerArray[j]))
\r
204 // Check that the buffer is large enough for adding a digit (can be heavily improved wrt performance)
\r
207 // Assigning index to digit
\r
208 *fDigitIndexPtr = j;
\r
209 fUsedSize += sizeof(Int_t);
\r
211 // Incrementing digit pointer to be ready for new entry
\r
214 // Adding the digit energy to the rec point
\r
215 fRecPointDataPtr->fAmp += fDigitsPointerArray[j]->fEnergy;
\r
217 // Setting energy to 0
\r
218 //fDigitsPointerArray[j]->fEnergy = 0;
\r
220 // Setting the associated cluster
\r
221 fDigitsPointerArray[j]->fAssociatedCluster = fNRecPoints;
\r
223 HLTDebug("Added digit with index: %d, energy: %f, to associated cluster: %d", fDigitsPointerArray[j]->fID, fDigitsPointerArray[j]->fEnergy, fDigitsPointerArray[j]->fAssociatedCluster);
\r
225 fDigitsInCluster++;
\r
227 // Scan for neighbours of this digit
\r
228 ScanForNeighbourDigits(j, recPoint);
\r
237 AliHLTCaloClusterizer::AreNeighbours(AliHLTCaloDigitDataStruct* digit1,
\r
238 AliHLTCaloDigitDataStruct* digit2)
\r
240 //see header file for documentation
\r
241 if ( (digit1->fModule == digit2->fModule) /*&& (coord1[1]==coord2[1])*/ ) // inside the same PHOS module
\r
243 Int_t rowdiff = TMath::Abs( digit1->fZ - digit2->fZ );
\r
244 Int_t coldiff = TMath::Abs( digit1->fX - digit2->fX );
\r
246 // As in the offline code we define neighbours as cells that share an edge, a corner is not enough
\r
247 // if (( coldiff <= 1 && rowdiff == 0 ) || ( coldiff == 0 && rowdiff <= 1 ))
\r
248 if (( coldiff <= 1) || ( rowdiff <= 1 ))
\r
250 // Check also for time
\r
251 if (TMath::Abs(digit1->fTime - digit2->fTime ) < fEmcTimeGate)
\r
262 Int_t AliHLTCaloClusterizer::CheckArray()
\r
264 // See header file for class documentation
\r
265 if (fArraySize == fNRecPoints)
\r
268 AliHLTCaloRecPointDataStruct **tmp = new AliHLTCaloRecPointDataStruct*[fArraySize];
\r
269 memcpy(tmp, fRecPointArray, fArraySize/2 * sizeof(AliHLTCaloRecPointDataStruct*));
\r
270 delete [] fRecPointArray;
\r
271 fRecPointArray = tmp;
\r
276 Int_t AliHLTCaloClusterizer::CheckBuffer()
\r
278 // See header file for class documentation
\r
279 if ((fAvailableSize - fUsedSize) < (Int_t)sizeof(AliHLTCaloRecPointDataStruct))
\r
281 Int_t recPointOffset = reinterpret_cast<UChar_t*>(fRecPointDataPtr) - reinterpret_cast<UChar_t*>(fFirstRecPointPtr);
\r
282 Int_t digitIndexOffset = reinterpret_cast<UChar_t*>(fDigitIndexPtr) - reinterpret_cast<UChar_t*>(fRecPointDataPtr);
\r
283 UChar_t *tmp = new UChar_t[fAvailableSize*2];
\r
287 HLTError("Pointer error");
\r
291 memcpy(tmp, fFirstRecPointPtr, fUsedSize);
\r
292 fAvailableSize *= 2;
\r
293 for (Int_t n = 0; n < fNRecPoints; n++)
\r
295 fRecPointArray[n] = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(reinterpret_cast<UChar_t*>(fRecPointArray[n]) - reinterpret_cast<UChar_t*>(fFirstRecPointPtr) + reinterpret_cast<UChar_t*>(tmp));
\r
297 delete [] fBuffer; //FR
\r
298 fBuffer = tmp; //FR
\r
300 fFirstRecPointPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(tmp);
\r
301 fRecPointDataPtr = reinterpret_cast<AliHLTCaloRecPointDataStruct*>(tmp + recPointOffset);
\r
302 fDigitIndexPtr = reinterpret_cast<Int_t*>(reinterpret_cast<UChar_t*>(fRecPointDataPtr) + digitIndexOffset);
\r
308 void AliHLTCaloClusterizer::SetSortDigitsByPosition()
\r
310 // Sort the digit pointers by position
\r
311 fCompareFunction = &CompareDigitsByPosition;
\r
312 fSortDigits = true;
\r
313 fSortedByPosition = true;
\r
316 void AliHLTCaloClusterizer::SetSortDigitsByEnergy()
\r
318 // See header file for class documentation
\r
319 fCompareFunction = &CompareDigitsByEnergy;
\r
320 fSortDigits = true;
\r
321 fSortedByEnergy = true;
\r
324 void AliHLTCaloClusterizer::SortDigits()
\r
326 // See header file for class documentation
\r
327 if (fSortDigits) qsort(fDigitsPointerArray, fNDigits, sizeof(AliHLTCaloDigitDataStruct*), fCompareFunction);
\r
331 AliHLTCaloClusterizer::CompareDigitsByPosition(const void *dig0, const void *dig1)
\r
333 // See header file for documentation
\r
334 return (*((AliHLTCaloDigitDataStruct**)(dig0)))->fID - (*((AliHLTCaloDigitDataStruct**)(dig1)))->fID;
\r
338 AliHLTCaloClusterizer::CompareDigitsByEnergy(const void *dig0, const void *dig1)
\r
340 // See header file for documentation
\r
341 if ( ((*((AliHLTCaloDigitDataStruct**)(dig1)))->fEnergy - (*((AliHLTCaloDigitDataStruct**)(dig0)))->fEnergy) < 0) return -1;
\r