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 "AliHLTPHOSDefinitions.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;
40 ClassImp(AliHLTPHOSClusterizer);
45 AliHLTPHOSClusterizer::AliHLTPHOSClusterizer():AliHLTPHOSBase(),fPHOSModule(0), fThreshold(0), fClusterThreshold(0),
46 fHighGainFactor(0.005), fLowGainFactor(0.08),
47 fArraySize(3), fMultiplicity(fArraySize*fArraySize)
48 //AliHLTPHOSClusterizer::AliHLTPHOSClusterizer():AliHLTPHOSProcessor(),fPHOSModule(0), fThreshold(0), fClusterThreshold(0),
49 // fHighGainFactor(0.005), fLowGainFactor(0.08),
50 // fArraySize(3), fMultiplicity(fArraySize*fArraySize)
52 //See header file for documentation
56 // PTH AliHLTPHOSClusterizer::AliHLTPHOSClusterizer(const AliHLTPHOSClusterizer &):AliHLTPHOSBase(),fPHOSModule(0), fThreshold(0), fClusterThreshold(0),
57 // fHighGainFactor(0.005), fLowGainFactor(0.08),
58 // fArraySize(3), fMultiplicity(fArraySize*fArraySize)
61 //Copy constructor, not implemented
64 AliHLTPHOSClusterizer:: ~AliHLTPHOSClusterizer()
70 * Building a 2D array of cell energies of the PHOS detector
71 * @param cellData object containing the cell energies from one event
72 * @param recPointList list to be filled with coordinates of local maxima in the detector
76 AliHLTPHOSClusterizer::BuildCellEnergyArray(AliHLTPHOSRcuCellEnergyDataStruct* cellData,
77 AliHLTPHOSRecPointListDataStruct* recPointList)
79 //BuildCellEnergyArray
87 Double_t energyCount = 0;
89 for(Int_t cell = 0; cell < cellData->fCnt; cell++)
92 z = (cellData->fValidData[cell]).fZ;
93 x = (cellData->fValidData[cell]).fX;
94 gain = (cellData->fValidData[cell]).fGain;
96 zMod = z + (cellData->fRcuZ)*N_ZROWS_RCU;
97 xMod = x + (cellData->fRcuX)*N_XCOLUMNS_RCU;
99 energyCount = (cellData->fValidData[cell]).fEnergy;
101 if(gain == 0 && energyCount < 1023)
103 fEnergyArray[xMod][zMod] = fHighGainFactor * energyCount;
105 if(fEnergyArray[xMod][zMod] > fClusterThreshold)
107 recPointList[index].fZ = zMod;
108 recPointList[index].fX = xMod;
110 for(Int_t j = 0; j < index; j++)
112 if(recPointList[j].fZ == zMod && recPointList[j].fX == xMod)
113 recPointList[j].fZ = -1;
119 else if(gain == 1 && fEnergyArray[xMod][zMod] == 0)
121 fEnergyArray[xMod][zMod] = fLowGainFactor * energyCount;
122 if(fEnergyArray[xMod][zMod] > fClusterThreshold)
124 recPointList[index].fZ = zMod;
125 recPointList[index].fX = xMod;
126 recPointList[index].fModule = cellData->fModuleID;
133 fPHOSModule = cellData->fModuleID;
136 }//end BuildCellEnergyArray
141 * Creating an array of rec points
142 * @param recPointStructArrayPtr array to store the rec points
143 * @param list list of rec points
144 * @param nPoints number of points
147 AliHLTPHOSClusterizer::CreateRecPointStructArray(AliHLTPHOSRecPointDataStruct* recPointStructArrayPtr,
148 AliHLTPHOSRecPointListDataStruct* list,
152 //CreateRecPointStructArray
155 Int_t edgeFlagRows = 0;
156 Int_t edgeFlagCols = 0;
158 Int_t nRecPoints = 0;
165 Float_t* energiesList = NULL;
167 for(Int_t point = 0; point < nPoints; point++)
171 if(z == -1) continue;
173 if((z-fArraySize/2) < 0/*= - N_ZROWS_MOD/2*/ || (z+fArraySize/2) >= N_ZROWS_MOD/*/2*/)
178 if((x-fArraySize/2) < 0/*= - N_COLUMNS_MOD/2*/ || (x+fArraySize/2) >= N_XCOLUMNS_MOD)
185 if(!flag) energiesList = new Float_t[fMultiplicity];
190 for(i = -fArraySize/2; i <= fArraySize/2; i++)
193 for(j = -fArraySize/2; j <= fArraySize/2; j++)
196 if(fEnergyArray[x+i][z+j] > fEnergyArray[x][z] && abs(i) < 2 && abs(j) < 2)
202 energiesList[k] = fEnergyArray[x+i][z+j];
210 for(a = 0; a < k; a++)
212 (recPointStructArrayPtr[nRecPoints].fEnergiesListPtr)[a] = energiesList[a];
214 recPointStructArrayPtr[nRecPoints].fCoordinatesPtr[0] = x;
215 recPointStructArrayPtr[nRecPoints].fCoordinatesPtr[1] = z;
216 recPointStructArrayPtr[nRecPoints].fX = x;
217 recPointStructArrayPtr[nRecPoints].fZ = z;
218 // recPointStructArrayPtr[nRecPoints].fMultiplicity = fMultiplicity;
219 recPointStructArrayPtr[nRecPoints].fPHOSModule = list[point].fModule;
225 delete [] energiesList;
231 }//end CreateRecPointStructArray
235 * Calculating the center of gravity of a rec point
236 * Not working well at this point!
237 * @param recPointPtr pointer to the rec point
240 AliHLTPHOSClusterizer::CalculateCenterOfGravity(AliHLTPHOSRecPointDataStruct* recPointPtr)
242 //CalculateCenterOfGravity
243 //Copied from offline code, and modified
253 Int_t x = recPointPtr->fCoordinatesPtr[0];
254 Int_t z = recPointPtr->fCoordinatesPtr[1];
256 for(Int_t i = -fArraySize/2; i <= fArraySize/2; i++)
258 for(Int_t j = -fArraySize/2; j <= fArraySize/2; j++)
262 w = TMath::Max( (Float_t)0., (Float_t)(w0 + log( fEnergyArray[x+i][z+j] / fEnergyArray[x][z]) ) ) ;
263 //printf("log in cog: %f\n", log( fEnergyArray[x+i][z+j] / fEnergyArray[x][z]));
272 //printf("wtot cog: %f\n", wtot);
274 recPointPtr->fX = xt;
275 recPointPtr->fZ = zt;
279 }//end CalculateCenterOfGravity
282 AliHLTPHOSClusterizer::CalculateMoments(AliHLTPHOSRecPointDataStruct* recPointPtr, Bool_t axisOnly)
284 //Copied from offline code, and modified
287 // Calculate the shower moments in the eigen reference system
288 // M2x, M2z, M3x, M4z
289 // Calculate the angle between the shower position vector and the eigen vector
297 Double_t lambda0=0, lambda1=0;
298 Float_t logWeight = 4.5;
302 // 1) Find covariance matrix elements:
310 Int_t xc = recPointPtr->fCoordinatesPtr[0];
311 Int_t zc = recPointPtr->fCoordinatesPtr[1];
313 for(Int_t i = -fArraySize/2; i <= fArraySize/2; i++)
316 for(Int_t j = -fArraySize/2; j <= fArraySize/2; j++)
319 if (fEnergyArray[xi][zj] > 0)
322 // w = TMath::Max(0.,logWeight + log( fEnergyArray[xi][zj]/fEnergyArray[xc][zc] ) ) ;
324 //printf("log in mom: %f\n", TMath::Log( fEnergyArray[xi][zj] / fEnergyArray[xc][zc]));
334 //printf("wtot: %f\n", wtot);
346 // 2) Find covariance matrix eigen values lambda0 and lambda1
348 lambda0 = 0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
349 lambda1 = 0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
352 recPointPtr->fM2x = lambda0;
353 recPointPtr->fM2z = lambda1;
354 // printf("lambda0 = %f -- lambda1 = %f\n", lambda0, lambda1);
355 // 3) Find covariance matrix eigen vectors e0 and e1
360 e0.Set(1.,(lambda0-dxx)/dxz);
365 e1.Set(-e0.Y(),e0.X());
367 // 4) Rotate cluster tensor from (x,z) to (e0,e1) system
368 // and calculate moments M3x and M4z
370 Float_t cosPhi = e0.X();
371 Float_t sinPhi = e0.Y();
375 Double_t dx3, dz3, dz4;
385 for(Int_t i = -fArraySize/2; i <= fArraySize/2; i++)
387 for(Int_t j = -fArraySize/2; j <= fArraySize/2; j++)
391 xiPHOS = (Float_t)xi*cosPhi + (Float_t)zj*sinPhi;
392 zjPHOS = (Float_t)zj*cosPhi - (Float_t)xi*sinPhi;
393 // xi = (Float_t)xi*cosPhi + (Float_t)zj*sinPhi;
394 // zj = (Float_t)zj*cosPhi - (Float_t)xi*sinPhi;
395 if (fEnergyArray[xi][zj] > 0)
397 w = TMath::Max(0.,logWeight+TMath::Log(fEnergyArray[xi][zj]/fEnergyArray[xc][zc] ) ) ;
398 // printf("log in mom: %f\n", TMath::Log( fEnergyArray[xi][zj] / fEnergyArray[xc][zc]));
405 dx3 += w * xi * xi * xi;
406 dz3 += w * zj * zj * zj ;
407 dz4 += w * zj * zj * zj * zj ;
422 dx3 += -3*dxx*x + 2*x*x*x;
423 dz4 += -4*dz3*z + 6*dzz*z*z -3*z*z*z*z;
429 // 5) Find an angle between cluster center vector and eigen vector e0
433 phi = TMath::ACos ((x*e0.X() + z*e0.Y()) / sqrt(x*x + z*z));
435 recPointPtr->fM3x = dx3;
436 recPointPtr->fM4z = dz4;
437 recPointPtr->fPhixe = phi;
438 // printf("%f\n",phi);
445 * Create a simpler data struct for a rec point, containing
446 * only coordinates, energy and timing
447 * @param recPointPtr pointer to the rec point
448 * @clusterStructPtr pointer to the cluster struct
451 AliHLTPHOSClusterizer::ClusterizeStruct(AliHLTPHOSRecPointDataStruct* recPointPtr, AliHLTPHOSClusterDataStruct* clusterStructPtr)
455 Float_t clusterEnergy = 0;
456 Float_t* energiesListPtr = recPointPtr->fEnergiesListPtr;
458 for(Int_t i = 0; i < recPointPtr->fMultiplicity; i++)
460 clusterEnergy += energiesListPtr[i];
463 clusterStructPtr->fLocalPositionPtr[0] = recPointPtr->fX;
464 clusterStructPtr->fLocalPositionPtr[1] = recPointPtr->fZ;
465 clusterStructPtr->fClusterEnergy = clusterEnergy;
466 clusterStructPtr->fPHOSModule = recPointPtr->fPHOSModule;
470 }//end ClusterizeStruct
476 * Resets the cell energy array
479 AliHLTPHOSClusterizer::ResetCellEnergyArray()
482 //ResetCellEnergyArray
484 for(Int_t x = 0; x < N_ZROWS_MOD; x++)
486 for(Int_t z = 0; z < N_XCOLUMNS_MOD; z++)
488 fEnergyArray[x][z] = 0;
494 }//end ResetCellEnergyArray