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 **************************************************************************/
15 // Class for bad channels & bad runs identification
17 // This class is designed for the following tasks:
18 // 1. find bad (dead/noisy/strange) cells on a per run basis;
19 // 2. find the status/quality of analysed data (e.g. missing RCUs, run quality);
20 // 3. find the extent of problems related to bad cells: required for
21 // systematics estimation for a physical quantity related to a cluster.
23 // See also AliAnalysisTaskCellsQA.
24 // Works for EMCAL and PHOS. Requires initialized geometry.
25 // Class parameters are optimized for EMCAL.
27 // Usage example for EMCAL:
31 // // to check the quality of analysed data and detect most of the problems:
32 // AliEMCALGeometry::GetInstance("EMCAL_COMPLETEV1");
33 // cellsQA = new AliCaloCellsQA(10, AliCaloCellsQA::kEMCAL); // 10 supermodules
35 // // add this line for a full analysis (fills additional histograms):
36 // cellsQA->ActivateFullAnalysis();
38 // b) In UserCreateOutputObjects():
40 // // not required, but suggested
41 // cellsQA->InitSummaryHistograms();
46 // AliVEvent *event = InputEvent();
47 // AliVCaloCells* cells = event->GetEMCALCells();
49 // AliVVertex *vertex = (AliVVertex*) event->GetPrimaryVertex();
50 // Double_t vertexXYZ[3];
51 // vertex->GetXYZ(vertexXYZ);
54 // TObjArray clusArray;
55 // for (Int_t i = 0; i < event->GetNumberOfCaloClusters(); i++) {
56 // AliVCluster *clus = event->GetCaloCluster(i);
58 // // filter clusters here, if necessary
59 // // if (clus->E() < 0.3) continue;
60 // // if (clus->GetNCells() < 2) continue;
62 // clusArray.Add(clus);
65 // // apply afterburners, etc.
68 // cellsQA->Fill(event->GetRunNumber(), &clusArray, cells, vertexXYZ);
70 // d) Do not forget to post data, where necessary:
71 // PostData(1,cellsQA->GetListOfHistos());
72 // See also comments in AliAnalysisTaskCellsQA::Terminate().
74 // TODO: add DCAL (up to 6 supermodules?)
77 // Author: Olga Driga (SUBATECH)
79 // --- ROOT system ---
80 #include <TLorentzVector.h>
82 // --- AliRoot header files ---
83 #include <AliEMCALGeometry.h>
84 #include <AliPHOSGeometry.h>
85 #include <AliCaloCellsQA.h>
87 // ClassImp(AliCaloCellsQA)
89 //_________________________________________________________________________
90 AliCaloCellsQA::AliCaloCellsQA() :
99 fNBinsXNCellsInCluster(0),
100 fNBinsYNCellsInCluster(0),
103 fXMaxNCellsInCluster(0),
110 fhNEventsProcessedPerRun(0),
111 fhCellLocMaxNTimesInClusterElow(),
112 fhCellLocMaxNTimesInClusterEhigh(),
113 fhCellLocMaxETotalClusterElow(),
114 fhCellLocMaxETotalClusterEhigh(),
115 fhCellNonLocMaxNTimesInClusterElow(),
116 fhCellNonLocMaxNTimesInClusterEhigh(),
117 fhCellNonLocMaxETotalClusterElow(),
118 fhCellNonLocMaxETotalClusterEhigh(),
123 fhCellAmplitudeEhigh(0),
124 fhCellAmplitudeNonLocMax(0),
125 fhCellAmplitudeEhighNonLocMax(0),
128 // Use this constructor if unsure.
129 // Defaults: EMCAL, 10 supermodules, fClusElowMin = 0.3 GeV, fClusEhighMin = 1.0 GeV,
130 // fPi0EClusMin = 0.5 GeV, fkFullAnalysis = false.
132 Init(10, kEMCAL, 100000, 200000);
135 //_________________________________________________________________________
136 AliCaloCellsQA::AliCaloCellsQA(Int_t nmods, Int_t det, Int_t startRunNumber, Int_t endRunNumber) :
145 fNBinsXNCellsInCluster(0),
146 fNBinsYNCellsInCluster(0),
149 fXMaxNCellsInCluster(0),
156 fhNEventsProcessedPerRun(0),
157 fhCellLocMaxNTimesInClusterElow(),
158 fhCellLocMaxNTimesInClusterEhigh(),
159 fhCellLocMaxETotalClusterElow(),
160 fhCellLocMaxETotalClusterEhigh(),
161 fhCellNonLocMaxNTimesInClusterElow(),
162 fhCellNonLocMaxNTimesInClusterEhigh(),
163 fhCellNonLocMaxETotalClusterElow(),
164 fhCellNonLocMaxETotalClusterEhigh(),
169 fhCellAmplitudeEhigh(0),
170 fhCellAmplitudeNonLocMax(0),
171 fhCellAmplitudeEhighNonLocMax(0),
174 // Allows to set main class parameters.
176 // nmods -- maximum supermodule number + 1:
177 // use 4 for EMCAL <= 2010;
178 // use 4 for PHOS (PHOS numbers start from 1, not from zero);
179 // use 10 for EMCAL >= 2011.
181 // det -- detector: AliCaloCellsQA::kEMCAL or AliCaloCellsQA::kPHOS.
182 // Note: DCAL not yet implemented.
184 // startRunNumber, endRunNumber -- run range the analysis will run on
185 // (to allow later merging); wide (but reasonable) range can be provided.
187 Init(nmods, det, startRunNumber, endRunNumber);
190 //_________________________________________________________________________
191 AliCaloCellsQA::~AliCaloCellsQA()
193 delete fListOfHistos;
196 //_________________________________________________________________________
197 void AliCaloCellsQA::ActivateFullAnalysis()
199 // Activate initialization and filling of all the designed histograms.
200 // Must be called before InitSummaryHistograms() and Fill() methods, if necessary.
202 fkFullAnalysis = kTRUE;
205 //_________________________________________________________________________
206 void AliCaloCellsQA::InitSummaryHistograms(Int_t nbins, Double_t emax,
207 Int_t nbinsh, Double_t emaxh,
208 Int_t nbinst, Double_t tmin, Double_t tmax)
210 // Initialize summary (not per run) histograms.
211 // Must be called after ActivateFullAnalysis(), before calling Fill() method, if necessary.
213 // nbins, emax -- number of bins and maximum amplitude for fhCellAmplitude and fhCellAmplitudeNonLocMax;
214 // nbinsh, emaxh -- number of bins and maximum amplitude for fhCellAmplitudeEhigh and fhCellAmplitudeEhighNonLocMax;
215 // nbinst, tmin, tmax -- number of bins and minimum/maximum time for fhCellTime.
217 // do not add histograms to the current directory
218 Bool_t ads = TH1::AddDirectoryStatus();
219 TH1::AddDirectory(kFALSE);
221 fhCellAmplitude = new TH2F("hCellAmplitude",
222 "Amplitude distribution per cell", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax, nbins,0,emax);
223 fhCellAmplitude->SetXTitle("AbsId");
224 fhCellAmplitude->SetYTitle("Amplitude, GeV");
225 fhCellAmplitude->SetZTitle("Counts");
227 fhCellAmplitudeEhigh = new TH2F("hCellAmplitudeEhigh",
228 "Amplitude distribution per cell, high energies", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax, nbinsh,0,emaxh);
229 fhCellAmplitudeEhigh->SetXTitle("AbsId");
230 fhCellAmplitudeEhigh->SetYTitle("Amplitude, GeV");
231 fhCellAmplitudeEhigh->SetZTitle("Counts");
233 fhCellTime = new TH2F("hCellTime", "Time distribution per cell",
234 fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax, nbinst,tmin,tmax);
235 fhCellTime->SetXTitle("AbsId");
236 fhCellTime->SetYTitle("Time, microseconds");
237 fhCellTime->SetZTitle("Counts");
239 fListOfHistos->Add(fhCellAmplitude);
240 fListOfHistos->Add(fhCellAmplitudeEhigh);
241 fListOfHistos->Add(fhCellTime);
243 if (fkFullAnalysis) {
244 fhCellAmplitudeNonLocMax = new TH2F("hCellAmplitudeNonLocMax",
245 "Amplitude distribution per cell which is not a local maximum",
246 fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax, nbins,0,emax);
247 fhCellAmplitudeNonLocMax->SetXTitle("AbsId");
248 fhCellAmplitudeNonLocMax->SetYTitle("Amplitude, GeV");
249 fhCellAmplitudeNonLocMax->SetZTitle("Counts");
251 fhCellAmplitudeEhighNonLocMax = new TH2F("hCellAmplitudeEhighNonLocMax",
252 "Amplitude distribution per cell which is not a local maximum, high energies",
253 fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax, nbinsh,0,emaxh);
254 fhCellAmplitudeEhighNonLocMax->SetXTitle("AbsId");
255 fhCellAmplitudeEhighNonLocMax->SetYTitle("Amplitude, GeV");
256 fhCellAmplitudeEhighNonLocMax->SetZTitle("Counts");
258 fListOfHistos->Add(fhCellAmplitudeNonLocMax);
259 fListOfHistos->Add(fhCellAmplitudeEhighNonLocMax);
262 // return to the previous add directory status
263 TH1::AddDirectory(ads);
266 //_________________________________________________________________________
267 void AliCaloCellsQA::Fill(Int_t runNumber, TObjArray *clusArray, AliVCaloCells *cells, Double_t vertexXYZ[3])
269 // Does the job: fills histograms for current event.
271 // runNumber -- current run number;
272 // clusArray -- array of clusters (TObjArray or TClonesArray);
273 // cells -- EMCAL or PHOS cells;
274 // vertexXYZ -- primary vertex position.
276 fhNEventsProcessedPerRun->Fill(runNumber);
277 Int_t ri = FindCurrentRunIndex(runNumber);
279 FillCellsInCluster(ri, clusArray, cells);
280 FillJustCells(ri, cells);
281 FillPi0Mass(ri, clusArray, vertexXYZ);
284 //_________________________________________________________________________
285 void AliCaloCellsQA::SetClusterEnergyCuts(Double_t pi0EClusMin, Double_t elowMin, Double_t ehighMin)
287 // Set cuts for minimum cluster energies.
288 // Must be called before calling Fill() method, if necessary.
290 fClusElowMin = elowMin;
291 fClusEhighMin = ehighMin;
292 fPi0EClusMin = pi0EClusMin;
295 //_________________________________________________________________________
296 void AliCaloCellsQA::SetBinningParameters(Int_t nbins1, Int_t nbins2, Int_t nbins3x, Int_t nbins3y,
297 Double_t xmax1, Double_t xmax2, Double_t xmax3)
299 // Set binning parameters for histograms hECells, hNCellsInCluster and hPi0Mass.
300 // Must be called before Fill() method, if necessary.
302 // nbins1, xmax1 -- number of bins and maximum X axis value for hECells;
303 // nbins2, xmax2 -- number of bins and maximum X axis value for hPi0Mass;
304 // nbins3x, nbins3y, xmax3 -- number of bins in X and Y axes and maximum X axis value for hNCellsInCluster.
306 fNBinsECells = nbins1;
307 fNBinsPi0Mass = nbins2;
308 fNBinsXNCellsInCluster = nbins3x;
309 fNBinsYNCellsInCluster = nbins3y;
311 fXMaxPi0Mass = xmax2;
312 fXMaxNCellsInCluster = xmax3;
315 //_________________________________________________________________________
316 void AliCaloCellsQA::Init(Int_t nmods, Int_t det, Int_t startRunNumber, Int_t endRunNumber)
318 // Class initialization.
319 // Defaults: fClusElowMin = 0.3GeV, fClusEhighMin = 1GeV, fPi0EClusMin = 0.5GeV, fkFullAnalysis = false.
321 // check input (for design limitations only)
322 if (det != kEMCAL && det != kPHOS) {
323 Error("AliCaloCellsQA::Init", "Wrong detector provided");
324 Info("AliCaloCellsQA::Init", "I will use EMCAL");
327 if (nmods < 1 || nmods > 10) {
328 Error("AliCaloCellsQA::Init", "Wrong last supermodule number + 1 provided");
329 Info("AliCaloCellsQA::Init", "I will use nmods = 10");
335 fkFullAnalysis = kFALSE;
336 SetClusterEnergyCuts();
337 SetBinningParameters();
339 // minimum/maximum cell absId;
340 // straightforward solution avoids complications
342 fAbsIdMax = fNMods * 1152;
343 if (fDetector == kPHOS) {
345 fAbsIdMax = 1 + (fNMods-1)*3584;
348 fListOfHistos = new TObjArray;
349 fListOfHistos->SetOwner(kTRUE);
351 fhNEventsProcessedPerRun = new TH1D("hNEventsProcessedPerRun",
352 "Number of processed events vs run number", endRunNumber - startRunNumber, startRunNumber, endRunNumber);
353 fhNEventsProcessedPerRun->SetDirectory(0);
354 fhNEventsProcessedPerRun->SetXTitle("Run number");
355 fhNEventsProcessedPerRun->SetYTitle("Events");
356 fListOfHistos->Add(fhNEventsProcessedPerRun);
358 // will indicate whether InitSummaryHistograms() was called
359 fhCellAmplitude = NULL;
361 // fill with NULLs (will indicate which supermodules can be filled)
362 for (Int_t ri = 0; ri < 1000; ri++)
363 for (Int_t sm = 0; sm < 10; sm++) {
364 fhECells[ri][sm] = NULL;
365 fhNCellsInCluster[ri][sm] = NULL;
367 for (Int_t sm2 = 0; sm2 < 10; sm2++) fhPi0Mass[ri][sm][sm2] = NULL;
371 //_________________________________________________________________________
372 Int_t AliCaloCellsQA::FindCurrentRunIndex(Int_t runNumber)
374 // Return current run index; add a new run if necessary.
376 // try previous value ...
377 if (fRI >= 0 && fRunNumbers[fRI] == runNumber) return fRI;
379 // ... or find current run index ...
380 for (fRI = 0; fRI < fNRuns; fRI++)
381 if (fRunNumbers[fRI] == runNumber) return fRI;
383 // ... or add a new run
385 Fatal("AliCaloCellsQA::FindCurrentRunIndex", "Too many runs, how is this possible?");
388 fRunNumbers[fRI] = runNumber;
389 InitHistosForRun(runNumber, fRI);
395 //_________________________________________________________________________
396 void AliCaloCellsQA::InitHistosForRun(Int_t run, Int_t ri)
398 // Initialize per run histograms for a new run number;
399 // run -- run number; ri -- run index.
401 // do not add histograms to the current directory
402 Bool_t ads = TH1::AddDirectoryStatus();
403 TH1::AddDirectory(kFALSE);
405 fhCellLocMaxNTimesInClusterElow[ri] = new TH1F(Form("run%i_hCellLocMaxNTimesInClusterElow",run),
406 "Number of times cell was local maximum in a low energy cluster", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
407 fhCellLocMaxNTimesInClusterElow[ri]->SetXTitle("AbsId");
408 fhCellLocMaxNTimesInClusterElow[ri]->SetYTitle("Counts");
410 fhCellLocMaxNTimesInClusterEhigh[ri] = new TH1F(Form("run%i_hCellLocMaxNTimesInClusterEhigh",run),
411 "Number of times cell was local maximum in a high energy cluster", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
412 fhCellLocMaxNTimesInClusterEhigh[ri]->SetXTitle("AbsId");
413 fhCellLocMaxNTimesInClusterEhigh[ri]->SetYTitle("Counts");
415 fhCellLocMaxETotalClusterElow[ri] = new TH1F(Form("run%i_hCellLocMaxETotalClusterElow",run),
416 "Total cluster energy for local maximum cell, low energy", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
417 fhCellLocMaxETotalClusterElow[ri]->SetXTitle("AbsId");
418 fhCellLocMaxETotalClusterElow[ri]->SetYTitle("Energy");
420 fhCellLocMaxETotalClusterEhigh[ri] = new TH1F(Form("run%i_hCellLocMaxETotalClusterEhigh",run),
421 "Total cluster energy for local maximum cell, high energy", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
422 fhCellLocMaxETotalClusterEhigh[ri]->SetXTitle("AbsId");
423 fhCellLocMaxETotalClusterEhigh[ri]->SetYTitle("Energy");
425 fListOfHistos->Add(fhCellLocMaxNTimesInClusterElow[ri]);
426 fListOfHistos->Add(fhCellLocMaxNTimesInClusterEhigh[ri]);
427 fListOfHistos->Add(fhCellLocMaxETotalClusterElow[ri]);
428 fListOfHistos->Add(fhCellLocMaxETotalClusterEhigh[ri]);
431 if (fkFullAnalysis) {
432 fhCellNonLocMaxNTimesInClusterElow[ri] = new TH1F(Form("run%i_hCellNonLocMaxNTimesInClusterElow",run),
433 "Number of times cell wasn't local maximum in a low energy cluster", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
434 fhCellNonLocMaxNTimesInClusterElow[ri]->SetXTitle("AbsId");
435 fhCellNonLocMaxNTimesInClusterElow[ri]->SetYTitle("Counts");
437 fhCellNonLocMaxNTimesInClusterEhigh[ri] = new TH1F(Form("run%i_hCellNonLocMaxNTimesInClusterEhigh",run),
438 "Number of times cell wasn't local maximum in a high energy cluster", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
439 fhCellNonLocMaxNTimesInClusterEhigh[ri]->SetXTitle("AbsId");
440 fhCellNonLocMaxNTimesInClusterEhigh[ri]->SetYTitle("Counts");
442 fhCellNonLocMaxETotalClusterElow[ri] = new TH1F(Form("run%i_hCellNonLocMaxETotalClusterElow",run),
443 "Total cluster energy for not local maximum cell, low energy", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
444 fhCellNonLocMaxETotalClusterElow[ri]->SetXTitle("AbsId");
445 fhCellNonLocMaxETotalClusterElow[ri]->SetYTitle("Energy");
447 fhCellNonLocMaxETotalClusterEhigh[ri] = new TH1F(Form("run%i_hCellNonLocMaxETotalClusterEhigh",run),
448 "Total cluster energy for not local maximum cell, high energy", fAbsIdMax-fAbsIdMin,fAbsIdMin,fAbsIdMax);
449 fhCellNonLocMaxETotalClusterEhigh[ri]->SetXTitle("AbsId");
450 fhCellNonLocMaxETotalClusterEhigh[ri]->SetYTitle("Energy");
452 fListOfHistos->Add(fhCellNonLocMaxNTimesInClusterElow[ri]);
453 fListOfHistos->Add(fhCellNonLocMaxNTimesInClusterEhigh[ri]);
454 fListOfHistos->Add(fhCellNonLocMaxETotalClusterElow[ri]);
455 fListOfHistos->Add(fhCellNonLocMaxETotalClusterEhigh[ri]);
460 if (fDetector == kPHOS) minsm = 1;
462 // per supermodule histograms
463 for (Int_t sm = minsm; sm < fNMods; sm++) {
464 fhECells[ri][sm] = new TH1F(Form("run%i_hECellsSM%i",run,sm),
465 "Cell amplitude distribution", fNBinsECells,0,fXMaxECells);
466 fhECells[ri][sm]->SetXTitle("Amplitude, GeV");
467 fhECells[ri][sm]->SetYTitle("Number of cells");
469 fhNCellsInCluster[ri][sm] = new TH2F(Form("run%i_hNCellsInClusterSM%i",run,sm),
470 "Distrubution of number of cells in cluster vs cluster energy",
471 fNBinsXNCellsInCluster,0,fXMaxNCellsInCluster, fNBinsYNCellsInCluster,0,fNBinsYNCellsInCluster);
472 fhNCellsInCluster[ri][sm]->SetXTitle("Energy, GeV");
473 fhNCellsInCluster[ri][sm]->SetYTitle("Number of cells");
474 fhNCellsInCluster[ri][sm]->SetZTitle("Counts");
476 fListOfHistos->Add(fhECells[ri][sm]);
477 fListOfHistos->Add(fhNCellsInCluster[ri][sm]);
481 for (Int_t sm = minsm; sm < fNMods; sm++)
482 for (Int_t sm2 = sm; sm2 < fNMods; sm2++) {
483 fhPi0Mass[ri][sm][sm2] = new TH1F(Form("run%i_hPi0MassSM%iSM%i",run,sm,sm2),
484 "#pi^{0} mass spectrum", fNBinsPi0Mass,0,fXMaxPi0Mass);
485 fhPi0Mass[ri][sm][sm2]->SetXTitle("M_{#gamma#gamma}, GeV");
486 fhPi0Mass[ri][sm][sm2]->SetYTitle("Counts");
488 fListOfHistos->Add(fhPi0Mass[ri][sm][sm2]);
491 // return to the previous add directory status
492 TH1::AddDirectory(ads);
495 //_________________________________________________________________________
496 void AliCaloCellsQA::FillCellsInCluster(Int_t ri, TObjArray *clusArray, AliVCaloCells *cells)
498 // Fill histograms related to a cluster;
503 for (Int_t i = 0; i < clusArray->GetEntriesFast(); i++)
505 AliVCluster *clus = (AliVCluster*) clusArray->At(i);
506 if ((sm = CheckClusterGetSM(clus)) < 0) continue;
508 if (fhNCellsInCluster[ri][sm])
509 fhNCellsInCluster[ri][sm]->Fill(clus->E(), clus->GetNCells());
511 if (clus->E() >= fClusElowMin)
512 for (Int_t c = 0; c < clus->GetNCells(); c++) {
513 Int_t absId = clus->GetCellAbsId(c);
515 if (IsCellLocalMaximum(c, clus, cells)) {// local maximum
516 if (clus->E() < fClusEhighMin) {
517 fhCellLocMaxNTimesInClusterElow[ri]->Fill(absId);
518 fhCellLocMaxETotalClusterElow[ri]->Fill(absId, clus->E());
520 fhCellLocMaxNTimesInClusterEhigh[ri]->Fill(absId);
521 fhCellLocMaxETotalClusterEhigh[ri]->Fill(absId, clus->E());
524 else if (fkFullAnalysis) {// not a local maximum
525 if (clus->E() < fClusEhighMin) {
526 fhCellNonLocMaxNTimesInClusterElow[ri]->Fill(absId);
527 fhCellNonLocMaxETotalClusterElow[ri]->Fill(absId, clus->E());
529 fhCellNonLocMaxNTimesInClusterEhigh[ri]->Fill(absId);
530 fhCellNonLocMaxETotalClusterEhigh[ri]->Fill(absId, clus->E());
539 //_________________________________________________________________________
540 void AliCaloCellsQA::FillJustCells(Int_t ri, AliVCaloCells *cells)
542 // Fill cell histograms not related with a cluster;
549 for (Short_t c = 0; c < cells->GetNumberOfCells(); c++) {
550 cells->GetCell(c, absId, amp, time);
551 if ((sm = GetSM(absId)) < 0) continue;
553 if (fhECells[ri][sm]) fhECells[ri][sm]->Fill(amp);
555 if (fhCellAmplitude) { // in case InitSummaryHistograms() was not called
556 fhCellAmplitude->Fill(absId, amp);
557 fhCellAmplitudeEhigh->Fill(absId, amp);
558 fhCellTime->Fill(absId, time);
560 // fill not a local maximum distributions
561 if (fkFullAnalysis && !IsCellLocalMaximum(absId, cells)) {
562 fhCellAmplitudeNonLocMax->Fill(absId, amp);
563 fhCellAmplitudeEhighNonLocMax->Fill(absId, amp);
570 //_________________________________________________________________________
571 void AliCaloCellsQA::FillPi0Mass(Int_t ri, TObjArray *clusArray, Double_t vertexXYZ[3])
573 // Fill gamma+gamma invariant mass histograms.
577 TLorentzVector p1, p2, psum;
580 for (Int_t i = 0; i < clusArray->GetEntriesFast(); i++)
582 AliVCluster *clus = (AliVCluster*) clusArray->At(i);
583 if (clus->E() < fPi0EClusMin) continue;
584 if ((sm1 = CheckClusterGetSM(clus)) < 0) continue;
586 clus->GetMomentum(p1, vertexXYZ);
588 // second cluster loop
589 for (Int_t j = i+1; j < clusArray->GetEntriesFast(); j++)
591 AliVCluster *clus2 = (AliVCluster*) clusArray->At(j);
592 if (clus2->E() < fPi0EClusMin) continue;
593 if ((sm2 = CheckClusterGetSM(clus2)) < 0) continue;
595 clus2->GetMomentum(p2, vertexXYZ);
598 if (psum.M2() < 0) continue;
601 Int_t s1 = (sm1 <= sm2) ? sm1 : sm2;
602 Int_t s2 = (sm1 <= sm2) ? sm2 : sm1;
604 if (fhPi0Mass[ri][s1][s2])
605 fhPi0Mass[ri][s1][s2]->Fill(psum.M());
606 } // second cluster loop
610 //_________________________________________________________________________
611 Int_t AliCaloCellsQA::CheckClusterGetSM(AliVCluster* clus)
613 // Apply common cluster cuts and return supermodule number on success.
614 // Return -1 if cuts not passed or an error occured.
616 // check detector and number of cells in cluster
617 if (fDetector == kEMCAL && !clus->IsEMCAL()) return -1;
618 if (fDetector == kPHOS && !clus->IsPHOS()) return -1;
619 if (clus->GetNCells() < 1) return -1;
621 return GetSM(clus->GetCellAbsId(0));
624 //_________________________________________________________________________
625 Int_t AliCaloCellsQA::GetSM(Int_t absId)
627 // Convert cell absId --> supermodule number. Return -1 in case of error.
628 // Note: we use simple and straightforward way to find supermodule number.
629 // This allows to avoid unnecessary external dependencies (on geometry).
633 if (fDetector == kEMCAL) sm = absId/1152;
634 if (fDetector == kPHOS) sm = 1 + (absId-1)/3584;
636 // check for data corruption to avoid segfaults
637 if (sm < 0 || sm > 9) {
638 Error("AliCaloCellsQA::GetSM", "Data corrupted");
645 //____________________________________________________________
646 Bool_t AliCaloCellsQA::IsCellLocalMaximum(Int_t c, AliVCluster* clus, AliVCaloCells* cells)
648 // Returns true if cell is a local maximum in cluster (clusterizer dependent).
649 // Cell fractions are taken into account.
651 // c -- cell number in the cluster.
653 Int_t sm, eta, phi, sm2, eta2, phi2;
655 Int_t absId = clus->GetCellAbsId(c);
656 Double_t amp = cells->GetCellAmplitude(absId);
657 if (clus->GetCellAmplitudeFraction(c) > 1e-5) amp *= clus->GetCellAmplitudeFraction(c);
659 AbsIdToSMEtaPhi(absId, sm, eta, phi);
661 // try to find a neighbour which has bigger amplitude
662 for (Int_t c2 = 0; c2 < clus->GetNCells(); c2++) {
663 if (c == c2) continue;
665 Int_t absId2 = clus->GetCellAbsId(c2);
666 Double_t amp2 = cells->GetCellAmplitude(absId2);
667 if (clus->GetCellAmplitudeFraction(c2) > 1e-5) amp2 *= clus->GetCellAmplitudeFraction(c2);
669 AbsIdToSMEtaPhi(absId2, sm2, eta2, phi2);
670 if (sm != sm2) continue;
672 Int_t deta = TMath::Abs(eta-eta2);
673 Int_t dphi = TMath::Abs(phi-phi2);
675 if ((deta == 0 && dphi == 1) || (deta == 1 && dphi == 0) || (deta == 1 && dphi == 1))
676 if (amp < amp2) return kFALSE;
682 //____________________________________________________________
683 Bool_t AliCaloCellsQA::IsCellLocalMaximum(Int_t absId, AliVCaloCells* cells)
685 // Returns true if cell is a local maximum among cells (clusterizer independent).
687 Int_t sm, eta, phi, sm2, eta2, phi2;
689 Double_t amp = cells->GetCellAmplitude(absId);
690 AbsIdToSMEtaPhi(absId, sm, eta, phi);
692 // try to find a neighbour which has bigger amplitude
693 for (Short_t c2 = 0; c2 < cells->GetNumberOfCells(); c2++) {
694 Short_t absId2 = cells->GetCellNumber(c2);
695 if (absId2 == absId) continue;
697 AbsIdToSMEtaPhi(absId2, sm2, eta2, phi2);
698 if (sm != sm2) continue;
700 Int_t deta = TMath::Abs(eta-eta2);
701 Int_t dphi = TMath::Abs(phi-phi2);
703 if ((deta == 0 && dphi == 1) || (deta == 1 && dphi == 0) || (deta == 1 && dphi == 1))
704 if (amp < cells->GetAmplitude(c2))
711 //____________________________________________________________
712 void AliCaloCellsQA::AbsIdToSMEtaPhi(Int_t absId, Int_t &sm, Int_t &eta, Int_t &phi)
714 // Converts absId --> (sm, eta, phi) for a cell.
715 // Works both for EMCAL and for PHOS.
716 // Geometry must be already initialized.
719 if (fDetector == kEMCAL) {
720 AliEMCALGeometry *geomEMCAL = AliEMCALGeometry::GetInstance();
722 Fatal("AliCaloCellsQA::AbsIdToSMEtaPhi", "EMCAL geometry is not initialized");
724 Int_t nModule, nIphi, nIeta;
725 geomEMCAL->GetCellIndex(absId, sm, nModule, nIphi, nIeta);
726 geomEMCAL->GetCellPhiEtaIndexInSModule(sm, nModule, nIphi, nIeta, phi, eta);
731 if (fDetector == kPHOS) {
732 AliPHOSGeometry *geomPHOS = AliPHOSGeometry::GetInstance();
734 Fatal("AliCaloCellsQA::AbsIdToSMEtaPhi", "PHOS geometry is not initialized");
737 geomPHOS->AbsToRelNumbering(absId, relid);