1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 // This class derives from AliEMCALClustrerizer
22 #include <TBenchmark.h>
25 #include <TClonesArray.h>
30 #include "AliEMCALRecPoint.h"
31 #include "AliEMCALDigit.h"
32 #include "AliEMCALGeometry.h"
33 #include "AliCaloCalibPedestal.h"
34 #include "AliEMCALCalibData.h"
35 #include "AliESDCaloCluster.h"
36 #include "AliEMCALUnfolding.h"
38 #include "AliEMCALClusterizerFixedWindow.h"
40 ClassImp(AliEMCALClusterizerFixedWindow)
42 //__________________________________________________________________________________________
43 AliEMCALClusterizerFixedWindow::AliEMCALClusterizerFixedWindow()
44 : AliEMCALClusterizer(),
55 //__________________________________________________________________________________________
56 AliEMCALClusterizerFixedWindow::AliEMCALClusterizerFixedWindow(AliEMCALGeometry* geometry)
57 : AliEMCALClusterizer(geometry),
68 //__________________________________________________________________________________________
69 AliEMCALClusterizerFixedWindow::AliEMCALClusterizerFixedWindow(AliEMCALGeometry* geometry, AliEMCALCalibData * calib, AliCaloCalibPedestal * caloped)
70 : AliEMCALClusterizer(geometry, calib, caloped),
81 //__________________________________________________________________________________________
82 AliEMCALClusterizerFixedWindow::~AliEMCALClusterizerFixedWindow()
86 delete fClustersArray;
89 //__________________________________________________________________________________________
90 void AliEMCALClusterizerFixedWindow::SetNphi (Int_t n)
92 // Set fNphi; if clusterizer already initialized gives a warning and does nothing
95 AliWarning("Clusterizer already initialized. Unable to change the parameters.");
100 //__________________________________________________________________________________________
101 void AliEMCALClusterizerFixedWindow::SetNeta (Int_t n)
103 // Set fNeta; if clusterizer already initialized gives a warning and does nothing
106 AliWarning("Clusterizer already initialized. Unable to change the parameters.");
111 //__________________________________________________________________________________________
112 void AliEMCALClusterizerFixedWindow::SetShiftPhi (Int_t s)
114 // Set fShiftPhi; if clusterizer already initialized gives a warning and does nothing
117 AliWarning("Clusterizer already initialized. Unable to change the parameters.");
122 //__________________________________________________________________________________________
123 void AliEMCALClusterizerFixedWindow::SetShiftEta (Int_t s)
125 // Set fShiftEta; if clusterizer already initialized gives a warning and does nothing
128 AliWarning("Clusterizer already initialized. Unable to change the parameters.");
133 //__________________________________________________________________________________________
134 void AliEMCALClusterizerFixedWindow::SetTRUshift(Bool_t b)
136 // Set fTRUshift; if clusterizer already initialized gives a warning and does nothing
139 AliWarning("Clusterizer already initialized. Unable to change the parameters.");
145 //__________________________________________________________________________________________
146 void AliEMCALClusterizerFixedWindow::Digits2Clusters(Option_t * option)
148 // Steering method to perform clusterization for the current event
150 if (strstr(option,"tim"))
151 gBenchmark->Start("EMCALClusterizer");
153 if (strstr(option,"print"))
156 //Get calibration parameters from file or digitizer default values.
157 GetCalibrationParameters();
159 //Get dead channel map from file or digitizer default values.
160 GetCaloCalibPedestal();
162 MakeClusters(); //only the real clusters
165 fClusterUnfolding->SetInput(fNumberOfECAClusters,fRecPoints,fDigitsArr);
166 fClusterUnfolding->MakeUnfolding();
169 //Evaluate position, dispersion and other RecPoint properties for EC section
170 for (Int_t index = 0; index < fRecPoints->GetEntries(); index++) {
171 AliEMCALRecPoint * rp = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(index));
173 rp->EvalAll(fECAW0,fDigitsArr,fJustClusters);
174 AliDebug(5, Form("MAX INDEX %d ", rp->GetMaximalEnergyIndex()));
175 //For each rec.point set the distance to the nearest bad crystal
177 rp->EvalDistanceToBadChannels(fCaloPed);
183 for (Int_t index = 0; index < fRecPoints->GetEntries(); index++) {
184 AliEMCALRecPoint *rp = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(index));
186 rp->SetIndexInList(index);
188 else AliFatal("RecPoint NULL!!");
194 if (strstr(option,"deb") || strstr(option,"all"))
195 PrintRecPoints(option);
197 AliDebug(1,Form("EMCAL Clusterizer found %d Rec Points",fRecPoints->GetEntriesFast()));
199 if (strstr(option,"tim")) {
200 gBenchmark->Stop("EMCALClusterizer");
201 printf("Exec took %f seconds for Clusterizing",
202 gBenchmark->GetCpuTime("EMCALClusterizer"));
206 //__________________________________________________________________________________________
207 void AliEMCALClusterizerFixedWindow::MakeClusters()
212 AliFatal("Did not get geometry from EMCALLoader");
214 fNumberOfECAClusters = 0;
215 fRecPoints->Delete();
217 Int_t nSupMod=0, nModule=0, nIphi=0, nIeta=0, iphi=0, ieta=0;
219 // Defining geometry and clusterization parameter
220 Int_t nEtaDigitsSupMod = fGeom->GetNEta() * fGeom->GetNETAdiv(); // always 48?;
221 Int_t nPhiDigitsSupMod = fGeom->GetNPhi() * fGeom->GetNPHIdiv(); // always 24?;
226 Int_t nEtaDigits = nEtaDigitsSupMod * fGeom->GetNumberOfSuperModules() / fGeom->GetNPhiSuperModule();
227 Int_t nPhiDigits = nPhiDigitsSupMod * fGeom->GetNPhiSuperModule();
230 nTRUPhi = fGeom->GetNPhiSuperModule() * 3;
231 nTRUEta = fGeom->GetNumberOfSuperModules() / fGeom->GetNPhiSuperModule();
232 nEtaDigits /= nTRUEta;
233 nPhiDigits /= nTRUPhi;
236 // Check if clusterizer parameter are compatible with calorimeter geometry
237 if (nEtaDigits < fNeta){
238 AliFatal(Form("Error: fNeta = %d is greater than nEtaDigits = %d.",fNeta,nEtaDigits));
241 if (nPhiDigits < fNphi){
242 AliFatal(Form("Error: fNphi = %d is greater than nPhiDigits = %d.",fNphi,nPhiDigits));
245 if (nEtaDigits % fShiftEta != 0){
246 AliFatal(Form("Error: fShiftEta = %d is such that clusters cannot slide the whole calorimeter (nEtaDigits = %d).",fShiftEta,nEtaDigits));
249 if (nPhiDigits % fShiftPhi != 0){
250 AliFatal(Form("Error: fShiftPhi = %d is such that clusters cannot slide the whole calorimeter (nPhiDigits = %d).",fShiftPhi,nPhiDigits));
253 if (fNeta % fShiftEta != 0){
254 AliFatal(Form("Error: fShiftEta = %d is not divisor of fNeta = %d.",fShiftEta,fNeta));
257 if (fNphi % fShiftPhi != 0){
258 AliFatal(Form("Error: fShiftPhi = %d is not divisor of fNphi = %d).",fShiftPhi,fNphi));
262 Int_t maxiShiftPhi = fNphi / fShiftPhi;
263 Int_t maxiShiftEta = fNeta / fShiftEta;
265 Int_t nDigitsCluster = fNphi * fNeta;
267 Int_t nClusEtaNoShift = nEtaDigits / fNeta;
268 Int_t nClusPhiNoShift = nPhiDigits / fNphi;
270 Int_t nClusters = nClusEtaNoShift * nClusPhiNoShift * nTRUEta * nTRUPhi;
272 Int_t nTotalClus = nClusters * maxiShiftEta * maxiShiftPhi;
274 if (!fClustersArray) {
275 fClustersArray = new AliEMCALDigit**[nTotalClus];
276 for (Int_t i = 0; i < nTotalClus; i++)
278 fClustersArray[i] = NULL;
282 // Set up TObjArray with pointers to digits to work on calibrated digits
283 TObjArray *digitsC = new TObjArray();
284 AliEMCALDigit *digit;
285 Float_t dEnergyCalibrated = 0.0, ehs = 0.0, time = 0.0;
286 TIter nextdigit(fDigitsArr);
287 while ((digit = dynamic_cast<AliEMCALDigit*>(nextdigit()))) { // calibrate and clean up digits
288 dEnergyCalibrated = digit->GetAmplitude();
289 time = digit->GetTime();
290 Calibrate(dEnergyCalibrated, time, digit->GetId());
291 digit->SetCalibAmp(dEnergyCalibrated);
292 digit->SetTime(time);
293 if (dEnergyCalibrated < fMinECut) {
296 else if (!fGeom->CheckAbsCellId(digit->GetId())) {
300 ehs += dEnergyCalibrated;
301 digitsC->AddLast(digit);
305 AliDebug(1,Form("MakeClusters: Number of digits %d -> (e %f), ehs %f\n",
306 fDigitsArr->GetEntries(),fMinECut,ehs));
308 for (Int_t ishiftPhi = 0; ishiftPhi < maxiShiftPhi; ishiftPhi++){
309 Int_t nClusPhi = (nPhiDigits - fShiftPhi * ishiftPhi) / fNphi;
311 for (Int_t ishiftEta = 0; ishiftEta < maxiShiftEta; ishiftEta++) {
313 Int_t nClusEta = (nEtaDigits - fShiftEta * ishiftEta) / fNeta;
315 Int_t iTotalClus = nClusters * (ishiftPhi * maxiShiftEta + ishiftEta);
317 TIter nextdigitC(digitsC);
318 while ((digit = dynamic_cast<AliEMCALDigit*>(nextdigitC()))) { // scan over the list of digitsC
320 fGeom->GetCellIndex (digit->GetId(), nSupMod, nModule, nIphi, nIeta);
321 fGeom->GetCellPhiEtaIndexInSModule (nSupMod, nModule, nIphi, nIeta, iphi, ieta);
323 Int_t iphi_eff = iphi - fShiftPhi * ishiftPhi + nPhiDigitsSupMod * (nSupMod / 2); // N supermodules along phi
325 Int_t iTRUphi = iphi_eff / nPhiDigits;
327 iphi_eff -= iTRUphi * nPhiDigits;
329 Int_t iClusPhi = iphi_eff / fNphi;
331 if (iphi_eff < 0 || iClusPhi >= nClusPhi)
334 Int_t ieta_eff = ieta - fShiftEta * ishiftEta + nEtaDigitsSupMod * (nSupMod % 2); // 2 supermodules along eta
336 Int_t iTRUeta = ieta_eff / nEtaDigits;
338 ieta_eff -= iTRUeta * nEtaDigits;
340 Int_t iClusEta = ieta_eff / fNeta;
342 if (ieta_eff < 0 || iClusEta >= nClusEta)
345 iphi_eff += iTRUphi * nPhiDigits;
346 iClusPhi = iphi_eff / fNphi;
348 ieta_eff += iTRUeta * nEtaDigits;
349 iClusEta = ieta_eff / fNeta;
351 Int_t iCluster = iClusPhi + iClusEta * nClusPhiNoShift * nTRUPhi;
352 Int_t iDigit = iphi_eff % fNphi + (ieta_eff % fNeta) * fNphi;
354 if (iCluster >= nClusters){
355 AliWarning(Form("iCluster out of range! iCluster = %d, nClusters = %d", iCluster, nClusters));
359 iCluster += iTotalClus;
361 if (fClustersArray[iCluster] == NULL){
362 fNumberOfECAClusters++;
363 fClustersArray[iCluster] = new AliEMCALDigit*[nDigitsCluster];
364 for (Int_t i = 0; i < nDigitsCluster; i++){
365 fClustersArray[iCluster][i] = NULL;
369 if (fClustersArray[iCluster][iDigit] != NULL){
370 AliWarning("Digit already added!");
374 fClustersArray[iCluster][iDigit] = digit;
378 } // loop on eta shift
380 } // loop on phi shift
383 for (Int_t iCluster = 0; iCluster < nTotalClus; iCluster++){
385 if (fClustersArray[iCluster] == NULL) continue;
387 (*fRecPoints)[iRecPoint] = new AliEMCALRecPoint("");
388 AliEMCALRecPoint *recPoint = dynamic_cast<AliEMCALRecPoint*> (fRecPoints->At(iRecPoint));
392 recPoint->SetClusterType(AliVCluster::kEMCALClusterv1);
393 recPoint->SetUniqueID(iCluster);
395 for (Int_t iDigit = 0; iDigit < nDigitsCluster; iDigit++){
396 if (fClustersArray[iCluster][iDigit] == NULL) continue;
397 digit = fClustersArray[iCluster][iDigit];
398 recPoint->AddDigit(*digit, digit->GetCalibAmp(), kFALSE); //Time or TimeR?
399 fClustersArray[iCluster][iDigit] = NULL;
403 delete[] fClustersArray[iCluster];
404 fClustersArray[iCluster] = NULL;
408 AliDebug(1, Form("MakeClusters: Number of digits %d -> (e %f)\n", fDigitsArr->GetEntries(),fMinECut));
409 AliDebug(1, Form("total no of clusters %d from %d digits", fNumberOfECAClusters, fDigitsArr->GetEntriesFast()));