]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EMCAL/AliEMCALClusterizerFixedWindow.cxx
#86069: Fix to prevent crash when missing logger in AliITSQASPDDataMakerRec (seen...
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALClusterizerFixedWindow.cxx
CommitLineData
89504c57 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16// This class derives from AliEMCALClustrerizer but also keeps the API of AliEMCALClusterizerv1
17// Algorithm:
18// 1. peek the most energetic cell
19// 2. assign it as a center of the cluster and add cells surrounding it: 3x3, 5x5...
20// 3. remove the cells contributing to the cluster
21// 4. start from 1 for the remaining clusters
22// 5. cluster splitting (not implemented yet) - use the shape analysis to resolve the energy sharing
23// - for high energy clusters check the surrounding of the 3x3 clusters for extra energy
24// (merge 3x3 clusters and resolve the internal energy sharing - case for 2 clusters merged)
25// Use Case:
26// root [0] AliEMCALClusterizerFixedWindow * cl = new AliEMCALClusterizerFixedWindow("galice.root")
27// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
28// //reads gAlice from header file "..."
29// root [1] cl->ExecuteTask()
30// //finds RecPoints in all events stored in galice.root
31// root [2] cl->SetDigitsBranch("digits2")
32// //sets another title for Digitis (input) branch
33// root [3] cl->SetRecPointsBranch("recp2")
34// //sets another title four output branches
35// root [4] cl->SetTowerLocalMaxCut(0.03)
36// //set clusterization parameters
37// root [5] cl->ExecuteTask("deb all time")
38// //once more finds RecPoints options are
39// // deb - print number of found rec points
40// // deb all - print number of found RecPoints and some their characteristics
41// // time - print benchmarking results
42
43#include "AliEMCALClusterizerFixedWindow.h"
44
45// --- ROOT system ---
46#include <TMath.h>
47#include <TMinuit.h>
48#include <TTree.h>
49#include <TBenchmark.h>
50#include <TBrowser.h>
51#include <TROOT.h>
52#include <TClonesArray.h>
53#include <TH1I.h>
54
55// --- Standard library ---
56#include <cassert>
57//#include <iostream>
58//#include <fstream>
59
60// --- AliRoot header files ---
61#include "AliLog.h"
62#include "AliEMCALRecPoint.h"
63#include "AliEMCALDigit.h"
64#include "AliEMCALGeometry.h"
65#include "AliCaloCalibPedestal.h"
66#include "AliEMCALCalibData.h"
67#include "AliESDCaloCluster.h"
68#include "AliEMCALUnfolding.h"
69#include "AliEMCALFixedWindowClusterInfo.h"
70
71ClassImp(AliEMCALClusterizerFixedWindow)
72
73//____________________________________________________________________________
74AliEMCALClusterizerFixedWindow::AliEMCALClusterizerFixedWindow()
75: AliEMCALClusterizer(),
76nPhi(4),
77nEta(4),
78shiftPhi(2),
79shiftEta(2),
80fTRUshift(0),
81clusters_array(0),
82fClustersInfo(new AliEMCALFixedWindowClusterInfo("clustersInfo"))
83{
84 // ctor with the indication of the file where header Tree and digits Tree are stored
85
86}
87
88//____________________________________________________________________________
89AliEMCALClusterizerFixedWindow::AliEMCALClusterizerFixedWindow(AliEMCALGeometry* geometry)
90: AliEMCALClusterizer(geometry),
91nPhi(4),
92nEta(4),
93shiftPhi(2),
94shiftEta(2),
95fTRUshift(0),
96clusters_array(0),
97fClustersInfo(new AliEMCALFixedWindowClusterInfo("clustersInfo"))
98{
99 // ctor with the indication of the file where header Tree and digits Tree are stored
100 // use this contructor to avoid usage of Init() which uses runloader
101 // change needed by HLT - MP
102}
103
104//____________________________________________________________________________
105AliEMCALClusterizerFixedWindow::AliEMCALClusterizerFixedWindow(AliEMCALGeometry* geometry, AliEMCALCalibData * calib, AliCaloCalibPedestal * caloped)
106: AliEMCALClusterizer(geometry, calib, caloped),
107nPhi(4),
108nEta(4),
109shiftPhi(2),
110shiftEta(2),
111fTRUshift(0),
112clusters_array(0),
113fClustersInfo(new AliEMCALFixedWindowClusterInfo("clustersInfo"))
114{
115 // ctor, geometry and calibration are initialized elsewhere.
116}
117
118//____________________________________________________________________________
119AliEMCALClusterizerFixedWindow::~AliEMCALClusterizerFixedWindow()
120{
121 // dtor
122 delete fClustersInfo;
123}
124
125//____________________________________________________________________________
126void AliEMCALClusterizerFixedWindow::Digits2Clusters(Option_t * option)
127{
128 // Steering method to perform clusterization for the current event
129 // in AliEMCALLoader
130
131 if (strstr(option,"tim"))
132 gBenchmark->Start("EMCALClusterizer");
133
134 if (strstr(option,"print"))
135 Print("");
136
137 //Get calibration parameters from file or digitizer default values.
138 GetCalibrationParameters();
139
140 //Get dead channel map from file or digitizer default values.
141 GetCaloCalibPedestal();
142
143 MakeClusters(); //only the real clusters
144
145 if (fToUnfold) {
146 fClusterUnfolding->SetInput(fNumberOfECAClusters,fRecPoints,fDigitsArr);
147 fClusterUnfolding->MakeUnfolding();
148 }
149
150 //Evaluate position, dispersion and other RecPoint properties for EC section
151 for (Int_t index = 0; index < fRecPoints->GetEntries(); index++) {
152 AliEMCALRecPoint * rp = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(index));
153 if (rp) {
154 rp->EvalAll(fECAW0,fDigitsArr,fJustClusters);
155 AliDebug(5, Form("MAX INDEX %d ", rp->GetMaximalEnergyIndex()));
156 //For each rec.point set the distance to the nearest bad crystal
157 if (fCaloPed)
158 rp->EvalDistanceToBadChannels(fCaloPed);
159 }
160 }
161
162 //fRecPoints->Sort();
163
164 for (Int_t index = 0; index < fRecPoints->GetEntries(); index++) {
165 AliEMCALRecPoint *rp = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(index));
166 if (rp) {
167 rp->SetIndexInList(index);
168 }
169 else AliFatal("RecPoint NULL!!");
170 }
171
172 if (fTreeR)
173 fTreeR->Fill();
174
175 if (strstr(option,"deb") || strstr(option,"all"))
176 PrintRecPoints(option);
177
178 AliDebug(1,Form("EMCAL Clusterizer found %d Rec Points",fRecPoints->GetEntriesFast()));
179
180 if (strstr(option,"tim")) {
181 gBenchmark->Stop("EMCALClusterizer");
182 printf("Exec took %f seconds for Clusterizing",
183 gBenchmark->GetCpuTime("EMCALClusterizer"));
184 }
185}
186
187//____________________________________________________________________________
188void AliEMCALClusterizerFixedWindow::MakeClusters()
189{
190 // Make clusters
191
192 if (fGeom == 0)
193 AliFatal("Did not get geometry from EMCALLoader");
194
195 fNumberOfECAClusters = 0;
196 fRecPoints->Delete();
197
198 if (fClustersInfo->GetLastElementId() > 0)
199 fClustersInfo->Clear();
200
201 Int_t nSupMod=0, nModule=0, nIphi=0, nIeta=0, iphi=0, ieta=0;
202
203 // Defining geometry and clusterization parameter
204 Int_t nEtaDigitsSupMod = fGeom->GetNEta() * fGeom->GetNETAdiv(); // always 48?;
205 Int_t nPhiDigitsSupMod = fGeom->GetNPhi() * fGeom->GetNPHIdiv(); // always 24?;
206
207 Int_t nTRUPhi = 1;
208 Int_t nTRUEta = 1;
209
210 Int_t nEtaDigits = nEtaDigitsSupMod * fGeom->GetNumberOfSuperModules() / fGeom->GetNPhiSuperModule();
211 Int_t nPhiDigits = nPhiDigitsSupMod * fGeom->GetNPhiSuperModule();
212
213 if (fTRUshift)
214 {
215 nTRUPhi = fGeom->GetNPhiSuperModule() * 3;
216 nTRUEta = fGeom->GetNumberOfSuperModules() / fGeom->GetNPhiSuperModule();
217 nEtaDigits /= nTRUEta;
218 nPhiDigits /= nTRUPhi;
219 }
220
221 // Check if clusterizer parameter are compatible with calorimeter geometry
222 if (nEtaDigits < nEta)
223 {
224 AliFatal(Form("Error: nEta = %d is greater than nEtaDigits = %d.",nEta,nEtaDigits));
225 return;
226 }
227 if (nPhiDigits < nPhi)
228 {
229 AliFatal(Form("Error: nPhi = %d is greater than nPhiDigits = %d.",nPhi,nPhiDigits));
230 return;
231 }
232 if (nEtaDigits % shiftEta != 0)
233 {
234 AliFatal(Form("Error: shiftEta = %d is such that clusters cannot slide the whole calorimeter (nEtaDigits = %d).",shiftEta,nEtaDigits));
235 return;
236 }
237 if (nPhiDigits % shiftPhi != 0)
238 {
239 AliFatal(Form("Error: shiftPhi = %d is such that clusters cannot slide the whole calorimeter (nPhiDigits = %d).",shiftPhi,nPhiDigits));
240 return;
241 }
242 if (nEta % shiftEta != 0)
243 {
244 AliFatal(Form("Error: shiftEta = %d is not divisor of nEta = %d.",shiftEta,nEta));
245 return;
246 }
247 if (nPhi % shiftPhi != 0)
248 {
249 AliFatal(Form("Error: shiftPhi = %d is not divisor of nPhi = %d).",shiftPhi,nPhi));
250 return;
251 }
252
253 Int_t maxiShiftPhi = nPhi / shiftPhi;
254 Int_t maxiShiftEta = nEta / shiftEta;
255
256 Int_t nDigitsCluster = nPhi * nEta;
257
258 Int_t nClusEtaNoShift = nEtaDigits / nEta;
259 Int_t nClusPhiNoShift = nPhiDigits / nPhi;
260
261 Int_t nClusters = nClusEtaNoShift * nClusPhiNoShift * nTRUEta * nTRUPhi;
262
263 Int_t nTotalClus = nClusters * maxiShiftEta * maxiShiftPhi;
264
265 if (!clusters_array)
266 {
267 clusters_array = new AliEMCALDigit**[nTotalClus];
268 for (Int_t i = 0; i < nTotalClus; i++)
269 {
270 clusters_array[i] = NULL;
271 }
272 }
273
274 AliEMCALDigit *digit = 0;
275
276 for (Int_t ishiftPhi = 0; ishiftPhi < maxiShiftPhi; ishiftPhi++)
277 {
278 Int_t nClusPhi = (nPhiDigits - shiftPhi * ishiftPhi) / nPhi;
279
280 for (Int_t ishiftEta = 0; ishiftEta < maxiShiftEta; ishiftEta++)
281 {
282
283 Int_t nClusEta = (nEtaDigits - shiftEta * ishiftEta) / nEta;
284
285 Int_t iTotalClus = nClusters * (ishiftPhi * maxiShiftEta + ishiftEta);
286
287 TIter nextdigit(fDigitsArr);
288
289 nextdigit.Reset();
290
291 while (digit = static_cast<AliEMCALDigit*>(nextdigit()))
292 {
293 fGeom->GetCellIndex (digit->GetId(), nSupMod, nModule, nIphi, nIeta);
294 fGeom->GetCellPhiEtaIndexInSModule (nSupMod, nModule, nIphi, nIeta, iphi, ieta);
295
296 Int_t iphi_eff = iphi - shiftPhi * ishiftPhi + nPhiDigitsSupMod * (nSupMod / 2); // N supermodules along phi
297
298 Int_t iTRUphi = iphi_eff / nPhiDigits;
299
300 iphi_eff -= iTRUphi * nPhiDigits;
301
302 Int_t iClusPhi = iphi_eff / nPhi;
303
304 if (iphi_eff < 0 || iClusPhi >= nClusPhi)
305 continue;
306
307 Int_t ieta_eff = ieta - shiftEta * ishiftEta + nEtaDigitsSupMod * (nSupMod % 2); // 2 supermodules along eta
308
309 Int_t iTRUeta = ieta_eff / nEtaDigits;
310
311 ieta_eff -= iTRUeta * nEtaDigits;
312
313 Int_t iClusEta = ieta_eff / nEta;
314
315 if (ieta_eff < 0 || iClusEta >= nClusEta)
316 continue;
317
318 iphi_eff += iTRUphi * nPhiDigits;
319 iClusPhi = iphi_eff / nPhi;
320
321 ieta_eff += iTRUeta * nEtaDigits;
322 iClusEta = ieta_eff / nEta;
323
324 Int_t iCluster = iClusPhi + iClusEta * nClusPhiNoShift * nTRUPhi;
325 Int_t iDigit = iphi_eff % nPhi + (ieta_eff % nEta) * nPhi;
326
327
328 if (iCluster >= nClusters)
329 {
330 AliFatal(Form("ERROR: iCluster out of range! iCluster = %d, nClusters = %d", iCluster, nClusters));
331 return;
332 }
333
334 iCluster += iTotalClus;
335
336 if (clusters_array[iCluster] == NULL)
337 {
338 fNumberOfECAClusters++;
339 clusters_array[iCluster] = new AliEMCALDigit*[nDigitsCluster];
340 for (Int_t i = 0; i < nDigitsCluster; i++)
341 {
342 clusters_array[iCluster][i] = NULL;
343 }
344
345 fClustersInfo->Add(iCluster, -1, iClusEta, iClusPhi);
346 }
347
348 if (clusters_array[iCluster][iDigit] != NULL)
349 {
350 AliFatal("ERROR: digit already added!");
351 return;
352 }
353
354 clusters_array[iCluster][iDigit] = digit;
355
356 } // loop on digit
357
358 } // loop on eta shift
359
360 } // loop on phi shift
361
362 Int_t iRecPoint = 0;
363 for (Int_t iCluster = 0; iCluster < nTotalClus; iCluster++)
364 {
365
366 if (clusters_array[iCluster] == NULL) continue;
367
368 (*fRecPoints)[iRecPoint] = new AliEMCALRecPoint("");
369 AliEMCALRecPoint *recPoint = dynamic_cast<AliEMCALRecPoint*> (fRecPoints->At(iRecPoint));
370
371 if (recPoint)
372 {
373 if (fClustersInfo->ContainsIndex(iRecPoint))
374 AliFatal(Form("ERROR: index present already, %d", iRecPoint));
375
376 fClustersInfo->SetIndexFromId(iCluster, iRecPoint);
377
378 iRecPoint++;
379 recPoint->SetClusterType(AliVCluster::kEMCALClusterv1);
380 // note: this way the sharing info is lost!
381 for (Int_t iDigit = 0; iDigit < nDigitsCluster; iDigit++)
382 {
383 if (clusters_array[iCluster][iDigit] == NULL) continue;
384 digit = clusters_array[iCluster][iDigit];
385 Float_t dEnergyCalibrated = digit->GetAmplitude();
386 Float_t time = digit->GetTime();
387 Calibrate(dEnergyCalibrated,time,digit->GetId());
388 digit->SetCalibAmp(dEnergyCalibrated);
389 recPoint->AddDigit(*digit, dEnergyCalibrated, kFALSE); //Time or TimeR?
390 clusters_array[iCluster][iDigit] = NULL;
391 }
392 }
393
394 delete[] clusters_array[iCluster];
395 clusters_array[iCluster] = NULL;
396 }
397
398 AliDebug(1,Form("MakeClusters: Number of digits %d -> (e %f)\n",
399 fDigitsArr->GetEntries(),fMinECut));
400
401 AliDebug(1,Form("total no of clusters %d from %d digits",fNumberOfECAClusters,fDigitsArr->GetEntriesFast()));
402}