1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Authors: Øystein Djuvsland <oysteind@ift.uib.no> *
6 * Permission to use, copy, modify and distribute this software and its *
7 * documentation strictly for non-commercial purposes is hereby granted *
8 * without fee, provided that the above copyright notice appears in all *
9 * copies and that both the copyright notice and this permission notice *
10 * appear in the supporting documentation. The authors make no claims *
11 * about the suitability of this software for any purpose. It is *
12 * provided "as is" without express or implied warranty. *
13 **************************************************************************/
16 /** @file AliHLTPHOSClusterizer.cxx
17 @author Øystein Djuvsland
19 @brief A temporary clusterizer for PHOS
24 #include "AliHLTPHOSPhysicsDefinitions.h"
25 #include "AliHLTPHOSClusterizer.h"
26 #include "AliHLTPHOSCommonDefs.h"
29 #include "AliHLTPHOSRcuCellEnergyDataStruct.h"
30 #include "AliHLTPHOSRecPointListDataStruct.h"
31 #include "AliHLTPHOSValidCellDataStruct.h"
32 #include "AliHLTPHOSRecPointDataStruct.h"
33 #include "AliHLTPHOSClusterDataStruct.h"
34 #include "AliHLTPHOSConstants.h"
36 using namespace PhosHLTConst;
39 ClassImp(AliHLTPHOSClusterizer);
44 AliHLTPHOSClusterizer::AliHLTPHOSClusterizer():fPHOSModule(0), fThreshold(0), fClusterThreshold(0),
45 fHighGainFactor(0.005), fLowGainFactor(0.08),
46 fArraySize(3), fMultiplicity(fArraySize*fArraySize)
48 //See header file for documentation
52 AliHLTPHOSClusterizer::AliHLTPHOSClusterizer(const AliHLTPHOSClusterizer &):fPHOSModule(0), fThreshold(0), fClusterThreshold(0),
53 fHighGainFactor(0.005), fLowGainFactor(0.08),
54 fArraySize(3), fMultiplicity(fArraySize*fArraySize)
56 //Copy constructor, not implemented
59 AliHLTPHOSClusterizer:: ~AliHLTPHOSClusterizer()
65 * Building a 2D array of cell energies of the PHOS detector
66 * @param cellData object containing the cell energies from one event
67 * @param recPointList list to be filled with coordinates of local maxima in the detector
71 AliHLTPHOSClusterizer::BuildCellEnergyArray(AliHLTPHOSRcuCellEnergyDataStruct* cellData,
72 AliHLTPHOSRecPointListDataStruct* recPointList)
74 //BuildCellEnergyArray
82 Double_t energyCount = 0;
84 for(Int_t cell = 0; cell < cellData->fCnt; cell++)
87 z = (cellData->fValidData[cell]).fZ;
88 x = (cellData->fValidData[cell]).fX;
89 gain = (cellData->fValidData[cell]).fGain;
91 zMod = z + (cellData->fRcuZ)*N_ZROWS_RCU;
92 xMod = x + (cellData->fRcuX)*N_XCOLUMNS_RCU;
94 energyCount = (cellData->fValidData[cell]).fEnergy;
96 if(gain == 0 && energyCount < 1023)
98 fEnergyArray[xMod][zMod] = fHighGainFactor * energyCount;
100 if(fEnergyArray[xMod][zMod] > fClusterThreshold)
102 recPointList[index].fZ = zMod;
103 recPointList[index].fX = xMod;
105 for(Int_t j = 0; j < index; j++)
107 if(recPointList[j].fZ == zMod && recPointList[j].fX == xMod)
108 recPointList[j].fZ = -1;
114 else if(gain == 1 && fEnergyArray[xMod][zMod] == 0)
116 fEnergyArray[xMod][zMod] = fLowGainFactor * energyCount;
117 if(fEnergyArray[xMod][zMod] > fClusterThreshold)
119 recPointList[index].fZ = zMod;
120 recPointList[index].fX = xMod;
121 recPointList[index].fModule = cellData->fModuleID;
128 fPHOSModule = cellData->fModuleID;
131 }//end BuildCellEnergyArray
136 * Creating an array of rec points
137 * @param recPointStructArrayPtr array to store the rec points
138 * @param list list of rec points
139 * @param nPoints number of points
142 AliHLTPHOSClusterizer::CreateRecPointStructArray(AliHLTPHOSRecPointDataStruct* recPointStructArrayPtr,
143 AliHLTPHOSRecPointListDataStruct* list,
147 //CreateRecPointStructArray
150 Int_t edgeFlagRows = 0;
151 Int_t edgeFlagCols = 0;
153 Int_t nRecPoints = 0;
160 Float_t* energiesList = NULL;
162 for(Int_t point = 0; point < nPoints; point++)
166 if(z == -1) continue;
168 if((z-fArraySize/2) < 0/*= - N_ZROWS_MOD/2*/ || (z+fArraySize/2) >= N_ZROWS_MOD/*/2*/)
173 if((x-fArraySize/2) < 0/*= - N_COLUMNS_MOD/2*/ || (x+fArraySize/2) >= N_XCOLUMNS_MOD)
180 if(!flag) energiesList = new Float_t[fMultiplicity];
185 for(i = -fArraySize/2; i <= fArraySize/2; i++)
188 for(j = -fArraySize/2; j <= fArraySize/2; j++)
191 if(fEnergyArray[x+i][z+j] > fEnergyArray[x][z] && abs(i) < 2 && abs(j) < 2)
197 energiesList[k] = fEnergyArray[x+i][z+j];
205 for(a = 0; a < k; a++)
207 (recPointStructArrayPtr[nRecPoints].fEnergiesListPtr)[a] = energiesList[a];
209 recPointStructArrayPtr[nRecPoints].fCoordinatesPtr[0] = x;
210 recPointStructArrayPtr[nRecPoints].fCoordinatesPtr[1] = z;
211 recPointStructArrayPtr[nRecPoints].fX = x;
212 recPointStructArrayPtr[nRecPoints].fZ = z;
213 // recPointStructArrayPtr[nRecPoints].fMultiplicity = fMultiplicity;
214 recPointStructArrayPtr[nRecPoints].fPHOSModule = list[point].fModule;
220 delete [] energiesList;
226 }//end CreateRecPointStructArray
230 * Calculating the center of gravity of a rec point
231 * Not working well at this point!
232 * @param recPointPtr pointer to the rec point
235 AliHLTPHOSClusterizer::CalculateCenterOfGravity(AliHLTPHOSRecPointDataStruct* recPointPtr)
237 //CalculateCenterOfGravity
238 //Copied from offline code, and modified
248 Int_t x = recPointPtr->fCoordinatesPtr[0];
249 Int_t z = recPointPtr->fCoordinatesPtr[1];
251 for(Int_t i = -fArraySize/2; i <= fArraySize/2; i++)
253 for(Int_t j = -fArraySize/2; j <= fArraySize/2; j++)
257 w = TMath::Max( (Float_t)0., (Float_t)(w0 + log( fEnergyArray[x+i][z+j] / fEnergyArray[x][z]) ) ) ;
258 //printf("log in cog: %f\n", log( fEnergyArray[x+i][z+j] / fEnergyArray[x][z]));
267 //printf("wtot cog: %f\n", wtot);
269 recPointPtr->fX = xt;
270 recPointPtr->fZ = zt;
274 }//end CalculateCenterOfGravity
277 AliHLTPHOSClusterizer::CalculateMoments(AliHLTPHOSRecPointDataStruct* recPointPtr, Bool_t axisOnly)
279 //Copied from offline code, and modified
282 // Calculate the shower moments in the eigen reference system
283 // M2x, M2z, M3x, M4z
284 // Calculate the angle between the shower position vector and the eigen vector
292 Double_t lambda0=0, lambda1=0;
293 Float_t logWeight = 4.5;
297 // 1) Find covariance matrix elements:
305 Int_t xc = recPointPtr->fCoordinatesPtr[0];
306 Int_t zc = recPointPtr->fCoordinatesPtr[1];
308 for(Int_t i = -fArraySize/2; i <= fArraySize/2; i++)
311 for(Int_t j = -fArraySize/2; j <= fArraySize/2; j++)
314 if (fEnergyArray[xi][zj] > 0)
316 w = TMath::Max(0.,logWeight + log( fEnergyArray[xi][zj]/fEnergyArray[xc][zc] ) ) ;
317 //printf("log in mom: %f\n", TMath::Log( fEnergyArray[xi][zj] / fEnergyArray[xc][zc]));
327 //printf("wtot: %f\n", wtot);
339 // 2) Find covariance matrix eigen values lambda0 and lambda1
341 lambda0 = 0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
342 lambda1 = 0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
345 recPointPtr->fM2x = lambda0;
346 recPointPtr->fM2z = lambda1;
347 // printf("lambda0 = %f -- lambda1 = %f\n", lambda0, lambda1);
348 // 3) Find covariance matrix eigen vectors e0 and e1
353 e0.Set(1.,(lambda0-dxx)/dxz);
358 e1.Set(-e0.Y(),e0.X());
360 // 4) Rotate cluster tensor from (x,z) to (e0,e1) system
361 // and calculate moments M3x and M4z
363 Float_t cosPhi = e0.X();
364 Float_t sinPhi = e0.Y();
368 Double_t dx3, dz3, dz4;
378 for(Int_t i = -fArraySize/2; i <= fArraySize/2; i++)
380 for(Int_t j = -fArraySize/2; j <= fArraySize/2; j++)
384 xiPHOS = (Float_t)xi*cosPhi + (Float_t)zj*sinPhi;
385 zjPHOS = (Float_t)zj*cosPhi - (Float_t)xi*sinPhi;
386 // xi = (Float_t)xi*cosPhi + (Float_t)zj*sinPhi;
387 // zj = (Float_t)zj*cosPhi - (Float_t)xi*sinPhi;
388 if (fEnergyArray[xi][zj] > 0)
390 w = TMath::Max(0.,logWeight+TMath::Log(fEnergyArray[xi][zj]/fEnergyArray[xc][zc] ) ) ;
391 // printf("log in mom: %f\n", TMath::Log( fEnergyArray[xi][zj] / fEnergyArray[xc][zc]));
398 dx3 += w * xi * xi * xi;
399 dz3 += w * zj * zj * zj ;
400 dz4 += w * zj * zj * zj * zj ;
415 dx3 += -3*dxx*x + 2*x*x*x;
416 dz4 += -4*dz3*z + 6*dzz*z*z -3*z*z*z*z;
422 // 5) Find an angle between cluster center vector and eigen vector e0
426 phi = TMath::ACos ((x*e0.X() + z*e0.Y()) / sqrt(x*x + z*z));
428 recPointPtr->fM3x = dx3;
429 recPointPtr->fM4z = dz4;
430 recPointPtr->fPhixe = phi;
431 // printf("%f\n",phi);
438 * Create a simpler data struct for a rec point, containing
439 * only coordinates, energy and timing
440 * @param recPointPtr pointer to the rec point
441 * @clusterStructPtr pointer to the cluster struct
444 AliHLTPHOSClusterizer::ClusterizeStruct(AliHLTPHOSRecPointDataStruct* recPointPtr, AliHLTPHOSClusterDataStruct* clusterStructPtr)
448 Float_t clusterEnergy = 0;
449 Float_t* energiesListPtr = recPointPtr->fEnergiesListPtr;
451 for(Int_t i = 0; i < recPointPtr->fMultiplicity; i++)
453 clusterEnergy += energiesListPtr[i];
456 clusterStructPtr->fLocalPositionPtr[0] = recPointPtr->fX;
457 clusterStructPtr->fLocalPositionPtr[1] = recPointPtr->fZ;
458 clusterStructPtr->fClusterEnergy = clusterEnergy;
459 clusterStructPtr->fPHOSModule = recPointPtr->fPHOSModule;
463 }//end ClusterizeStruct
469 * Resets the cell energy array
472 AliHLTPHOSClusterizer::ResetCellEnergyArray()
475 //ResetCellEnergyArray
477 for(Int_t x = 0; x < N_ZROWS_MOD; x++)
479 for(Int_t z = 0; z < N_XCOLUMNS_MOD; z++)
481 fEnergyArray[x][z] = 0;
487 }//end ResetCellEnergyArray