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 **************************************************************************/
19 #include <TClonesArray.h>
20 #include <TGeoManager.h>
21 #include <TObjArray.h>
26 #include "AliAODCaloCluster.h"
27 #include "AliAODEvent.h"
28 #include "AliAnalysisManager.h"
29 #include "AliCDBEntry.h"
30 #include "AliCDBManager.h"
31 #include "AliCaloCalibPedestal.h"
32 #include "AliEMCALAfterBurnerUF.h"
33 #include "AliEMCALCalibData.h"
34 #include "AliEMCALClusterizerNxN.h"
35 #include "AliEMCALClusterizerv1.h"
36 #include "AliEMCALClusterizerv2.h"
37 #include "AliEMCALClusterizerFixedWindow.h"
38 #include "AliEMCALDigit.h"
39 #include "AliEMCALGeometry.h"
40 #include "AliEMCALRecParam.h"
41 #include "AliEMCALRecPoint.h"
42 #include "AliEMCALRecoUtils.h"
43 #include "AliESDEvent.h"
44 #include "AliInputEventHandler.h"
47 #include "AliAnalysisTaskEMCALClusterizeFast.h"
49 ClassImp(AliAnalysisTaskEMCALClusterizeFast)
51 //________________________________________________________________________
52 AliAnalysisTaskEMCALClusterizeFast::AliAnalysisTaskEMCALClusterizeFast()
53 : AliAnalysisTaskSE(),
62 fGeomMatrixSet(kFALSE),
63 fLoadGeomMatrices(kFALSE),
77 fNewClusterArrayName("newCaloClusters"),
88 //________________________________________________________________________
89 AliAnalysisTaskEMCALClusterizeFast::AliAnalysisTaskEMCALClusterizeFast(const char *name)
90 : AliAnalysisTaskSE(name),
94 fRecParam(new AliEMCALRecParam),
98 fGeomName("EMCAL_FIRSTYEARV1"),
99 fGeomMatrixSet(kFALSE),
100 fLoadGeomMatrices(kFALSE),
114 fNewClusterArrayName("newCaloClusters"),
120 fClusterizeFastORs(0)
124 fBranchNames = "ESD:AliESDHeader.,AliESDRun.,EMCALCells.,EMCALTrigger. AOD:header,emcalCells";
125 for(Int_t i = 0; i < 12; ++i)
129 //________________________________________________________________________
130 AliAnalysisTaskEMCALClusterizeFast::~AliAnalysisTaskEMCALClusterizeFast()
140 //-------------------------------------------------------------------
141 void AliAnalysisTaskEMCALClusterizeFast::UserCreateOutputObjects()
143 // Create output objects.
145 if (!fOutputAODBrName.IsNull()) {
146 fOutputAODBranch = new TClonesArray("AliAODCaloCluster", 0);
147 fOutputAODBranch->SetName(fOutputAODBrName);
148 AddAODBranch("TClonesArray", &fOutputAODBranch);
149 AliInfo(Form("Created Branch: %s",fOutputAODBrName.Data()));
153 //________________________________________________________________________
154 void AliAnalysisTaskEMCALClusterizeFast::UserExec(Option_t *)
156 // Main loop, called for each event
158 // remove the contents of output list set in the previous event
159 if (fOutputAODBranch)
160 fOutputAODBranch->Clear("C");
162 AliESDEvent *esdevent = dynamic_cast<AliESDEvent*>(InputEvent());
163 AliAODEvent *aodevent = dynamic_cast<AliAODEvent*>(InputEvent());
165 if (!esdevent&&!aodevent) {
166 Error("UserExec","Event not available");
172 UInt_t offtrigger = 0;
174 UInt_t mask1 = esdevent->GetESDRun()->GetDetectorsInDAQ();
175 UInt_t mask2 = esdevent->GetESDRun()->GetDetectorsInReco();
176 Bool_t desc1 = (mask1 >> 18) & 0x1;
177 Bool_t desc2 = (mask2 >> 18) & 0x1;
178 if (desc1==0 || desc2==0) { //AliDAQ::OfflineModuleName(180=="EMCAL"
179 AliError(Form("EMCAL not in DAQ/RECO: %u (%u)/%u (%u)",
180 mask1, esdevent->GetESDRun()->GetDetectorsInReco(),
181 mask2, esdevent->GetESDRun()->GetDetectorsInDAQ()));
184 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
185 offtrigger = ((AliInputEventHandler*)(am->GetInputEventHandler()))->IsEventSelected();
186 } else if (aodevent) {
187 offtrigger = aodevent->GetHeader()->GetOfflineTrigger();
189 if (offtrigger & AliVEvent::kFastOnly) {
190 AliWarning(Form("EMCAL not in fast only partition"));
197 AliWarning("Unfolding not implemented");
205 return; // not requested to run clusterizer
212 if (fOutputAODBranch)
213 RecPoints2Clusters(fOutputAODBranch);
216 //________________________________________________________________________
217 void AliAnalysisTaskEMCALClusterizeFast::Clusterize()
221 if (fSubBackground) {
222 fClusterizer->SetInputCalibrated(kTRUE);
223 fClusterizer->SetCalibrationParameters(0);
226 fClusterizer->Digits2Clusters("");
227 if (fSubBackground) {
229 fClusterizer->SetInputCalibrated(kFALSE);
230 fClusterizer->SetCalibrationParameters(fCalibData);
235 //________________________________________________________________________
236 void AliAnalysisTaskEMCALClusterizeFast::FillDigitsArray()
240 fDigitsArr->Clear("C");
242 if (fCreatePattern) { // Fill digits from a pattern
243 AliEMCALGeometry *fGeom = AliEMCALGeometry::GetInstance(fGeomName);
244 Int_t maxd = fGeom->GetNCells() / 4;
245 for (Int_t idigit = 0; idigit < maxd; idigit++){
246 if (idigit % 24 == 12) idigit += 12;
247 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
248 digit->SetId(idigit * 4);
250 digit->SetTimeR(600);
251 digit->SetIndexInList(idigit);
252 digit->SetType(AliEMCALDigit::kHG);
253 digit->SetAmplitude(0.1);
256 } else if (fClusterizeFastORs) { // Fill digits from FastORs
258 AliEMCALGeometry *fGeom = AliEMCALGeometry::GetInstance(fGeomName);
260 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
262 AliError("Cannot get the ESD event");
266 AliESDCaloTrigger *triggers = esd->GetCaloTrigger("EMCAL");
268 if (!triggers || !(triggers->GetEntries() > 0))
274 while ((triggers->Next())) {
275 Float_t triggerAmplitude = 0;
276 triggers->GetAmplitude(triggerAmplitude);
277 if (triggerAmplitude <= 0)
280 Int_t triggerTime = 0;
282 triggers->GetNL0Times(ntimes);
285 triggers->GetL0Times(trgtimes);
286 triggerTime = trgtimes[0];
289 Int_t triggerCol = 0, triggerRow = 0;
290 triggers->GetPosition(triggerCol, triggerRow);
293 fGeom->GetAbsFastORIndexFromPositionInEMCAL(triggerCol, triggerRow, find);
298 Int_t cidx[4] = {-1};
299 Bool_t ret = fGeom->GetCellIndexFromFastORIndex(find, cidx);
304 for (Int_t idxpos = 0; idxpos < 4; idxpos++) {
305 Int_t triggerNumber = cidx[idxpos];
306 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
307 digit->SetId(triggerNumber);
308 digit->SetTime(triggerTime);
309 digit->SetTimeR(triggerTime);
310 digit->SetIndexInList(idigit);
311 digit->SetType(AliEMCALDigit::kHG);
312 digit->SetAmplitude(triggerAmplitude);
317 } else { // Fill digits from cells.
319 AliVCaloCells *cells = InputEvent()->GetEMCALCells();
320 Double_t avgE = 0; // for background subtraction
321 Int_t ncells = cells->GetNumberOfCells();
322 for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell) {
323 Double_t cellAmplitude=0, cellTime=0;
324 Short_t cellNumber=0;
325 if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime) != kTRUE)
327 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
328 digit->SetId(cellNumber);
329 digit->SetTime(cellTime);
330 digit->SetTimeR(cellTime);
331 digit->SetIndexInList(idigit);
332 digit->SetType(AliEMCALDigit::kHG);
333 if (fRecalibOnly||fSubBackground) {
334 Float_t energy = cellAmplitude;
335 Float_t time = cellTime;
336 fClusterizer->Calibrate(energy,time,cellNumber);
337 digit->SetAmplitude(energy);
340 digit->SetAmplitude(cellAmplitude);
345 if (fSubBackground) {
346 avgE /= AliEMCALGeometry::GetInstance(fGeomName)->GetNumberOfSuperModules()*48*24;
347 Int_t ndigis = fDigitsArr->GetEntries();
348 for (Int_t i = 0; i < ndigis; ++i) {
349 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(i));
350 Double_t energy = digit->GetAmplitude() - avgE;
352 digit->SetAmplitude(0);
354 digit->SetAmplitude(energy);
361 //________________________________________________________________________________________
362 void AliAnalysisTaskEMCALClusterizeFast::RecPoints2Clusters(TClonesArray *clus)
364 // Cluster energy, global position, cells and their amplitude fractions are restored.
366 Bool_t esdobjects = 0;
367 if (strcmp(clus->GetClass()->GetName(),"AliESDCaloCluster")==0)
370 AliVCaloCells *cells = InputEvent()->GetEMCALCells();
371 AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance(fGeomName);
373 AliDebug(1, Form("total no of clusters %d", fClusterArr->GetEntriesFast()));
375 Int_t Ncls = fClusterArr->GetEntriesFast();
376 for(Int_t i=0, nout=clus->GetEntries(); i < Ncls; ++i) {
377 AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
378 Int_t ncells_true = 0;
379 const Int_t ncells = recpoint->GetMultiplicity();
380 UShort_t absIds[ncells];
381 Double32_t ratios[ncells];
382 Int_t *dlist = recpoint->GetDigitsList();
383 Float_t *elist = recpoint->GetEnergiesList();
384 for (Int_t c = 0; c < ncells; ++c) {
385 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
386 absIds[ncells_true] = digit->GetId();
387 ratios[ncells_true] = elist[c]/digit->GetAmplitude();
391 if (ncells_true < 1) {
392 AliWarning("Skipping cluster with no cells");
396 // calculate new cluster position
398 recpoint->GetGlobalPosition(gpos);
402 AliDebug(1, Form("energy %f", recpoint->GetEnergy()));
404 AliVCluster *c = static_cast<AliVCluster*>(clus->New(nout++));
405 c->SetType(AliVCluster::kEMCALClusterv1);
406 c->SetE(recpoint->GetEnergy());
408 c->SetNCells(ncells_true);
409 c->SetDispersion(recpoint->GetDispersion());
410 c->SetEmcCpvDistance(-1); //not yet implemented
411 c->SetChi2(-1); //not yet implemented
412 c->SetTOF(recpoint->GetTime()) ; //time-of-flight
413 c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
415 recpoint->GetElipsAxis(elipAxis);
416 c->SetM02(elipAxis[0]*elipAxis[0]);
417 c->SetM20(elipAxis[1]*elipAxis[1]);
419 c->SetDistanceToBadChannel(recpoint->GetDistanceToBadTower());
422 if (fRecoUtils && fRecoUtils->IsBadChannelsRemovalSwitchedOn()) {
423 fRecoUtils->RecalculateClusterDistanceToBadChannel(geom, cells, c);
428 AliESDCaloCluster *cesd = static_cast<AliESDCaloCluster*>(c);
429 cesd->SetCellsAbsId(absIds);
430 cesd->SetCellsAmplitudeFraction(ratios);
431 cesd->SetID(recpoint->GetUniqueID());
433 AliAODCaloCluster *caod = static_cast<AliAODCaloCluster*>(c);
434 caod->SetCellsAbsId(absIds);
435 caod->SetCellsAmplitudeFraction(ratios);
439 AliESDEvent *esdevent = dynamic_cast<AliESDEvent*>(InputEvent());
445 AliAnalysisManager::GetAnalysisManager()->LoadBranch("Tracks");
446 fRecoUtils->FindMatches(esdevent,clus);
449 Int_t Nclus = clus->GetEntries();
450 for(Int_t i=0; i < Nclus; ++i) {
451 AliAODCaloCluster *c = static_cast<AliAODCaloCluster*>(clus->At(i));
452 Int_t trackIndex = fRecoUtils->GetMatchedTrackIndex(i);
453 if (trackIndex >= 0) {
455 fRecoUtils->GetMatchedResiduals(i,dR, dZ);
456 c->AddTrackMatched(0x0); //esdevent->GetTrack(trackIndex));
457 c->SetTrackDistance(dR,dZ); // not implemented
458 c->SetEmcCpvDistance(dR);
460 if (DebugLevel() > 1)
461 AliInfo(Form("Matched Track index %d to new cluster %d\n",trackIndex,i));
465 Int_t Nclus = clus->GetEntries();
466 for(Int_t i=0; i < Nclus; ++i) {
467 AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->At(i));
468 Int_t trackIndex = fRecoUtils->GetMatchedTrackIndex(i);
469 if (trackIndex >= 0) {
471 fRecoUtils->GetMatchedResiduals(i,dR, dZ);
472 c->SetTrackDistance(dR,dZ);
473 c->SetEmcCpvDistance(dR); //to be consistent with AODs
474 c->SetChi2(dZ); //to be consistent with AODs
475 TArrayI tm(1,&trackIndex);
476 c->AddTracksMatched(tm);
477 if (DebugLevel() > 1)
478 AliInfo(Form("Matched Track index %d to new cluster %d\n",trackIndex,i));
484 //________________________________________________________________________
485 void AliAnalysisTaskEMCALClusterizeFast::UpdateCells()
487 // Update cells in case re-calibration was done.
489 if (!fCalibData&&!fSubBackground)
492 AliVCaloCells *cells = InputEvent()->GetEMCALCells();
493 Int_t ncells = cells->GetNumberOfCells();
494 Int_t ndigis = fDigitsArr->GetEntries();
496 if (ncells!=ndigis) {
497 cells->DeleteContainer();
498 cells->CreateContainer(ndigis);
500 for (Int_t idigit = 0; idigit < ndigis; ++idigit) {
501 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(idigit));
502 Double_t cellAmplitude = digit->GetCalibAmp();
503 Short_t cellNumber = digit->GetId();
504 Double_t cellTime = digit->GetTime();
505 cells->SetCell(idigit, cellNumber, cellAmplitude, cellTime);
509 //________________________________________________________________________
510 void AliAnalysisTaskEMCALClusterizeFast::UpdateClusters()
512 // Update cells in case re-calibration was done.
514 if (!fAttachClusters)
517 TClonesArray *clus = 0;
520 clus = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject("caloClusters"));
522 clus = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject("CaloClusters"));
526 Int_t nents = clus->GetEntries();
527 for (Int_t i=0;i<nents;++i) {
528 AliVCluster *c = static_cast<AliVCluster*>(clus->At(i));
532 delete clus->RemoveAt(i);
535 clus = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(fNewClusterArrayName));
537 clus = new TClonesArray("AliESDCaloCluster");
538 clus->SetName(fNewClusterArrayName);
539 InputEvent()->AddObject(clus);
545 RecPoints2Clusters(clus);
548 //________________________________________________________________________________________
549 void AliAnalysisTaskEMCALClusterizeFast::Init()
551 //Select clusterization/unfolding algorithm and set all the needed parameters
553 AliVEvent * event = InputEvent();
555 AliWarning("Event not available!!!");
559 if (event->GetRunNumber()==fRun)
561 fRun = event->GetRunNumber();
564 // init the unfolding afterburner
566 fUnfolder = new AliEMCALAfterBurnerUF(fRecParam->GetW0(),fRecParam->GetLocMaxCut());
570 AliEMCALGeometry *geometry = AliEMCALGeometry::GetInstance(fGeomName);
572 AliFatal("Geometry not available!!!");
576 if (!fGeomMatrixSet) {
577 if (fLoadGeomMatrices) {
578 for(Int_t mod=0; mod < geometry->GetNumberOfSuperModules(); ++mod) {
579 if (fGeomMatrix[mod]){
580 if (DebugLevel() > 2)
581 fGeomMatrix[mod]->Print();
582 geometry->SetMisalMatrix(fGeomMatrix[mod],mod);
585 } else { // get matrix from file (work around bug in aliroot)
586 for(Int_t mod=0; mod < geometry->GetEMCGeometry()->GetNumberOfSuperModules(); ++mod) {
587 const TGeoHMatrix *gm = 0;
588 AliESDEvent *esdevent = dynamic_cast<AliESDEvent*>(event);
590 gm = esdevent->GetEMCALMatrix(mod);
592 AliAODHeader *aodheader = dynamic_cast<AliAODHeader*>(event->GetHeader());
594 gm = aodheader->GetEMCALMatrix(mod);
598 if (DebugLevel() > 2)
600 geometry->SetMisalMatrix(gm,mod);
604 fGeomMatrixSet=kTRUE;
607 // setup digit array if needed
609 fDigitsArr = new TClonesArray("AliEMCALDigit", 1000);
610 fDigitsArr->SetOwner(1);
613 // then setup clusterizer
615 if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
616 fClusterizer = new AliEMCALClusterizerv1(geometry);
617 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN) {
618 AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(geometry);
619 clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
620 clusterizer->SetNColDiff(fRecParam->GetNColDiff());
621 fClusterizer = clusterizer;
622 } else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2)
623 fClusterizer = new AliEMCALClusterizerv2(geometry);
624 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerFW){
625 AliEMCALClusterizerFixedWindow *clusterizer = new AliEMCALClusterizerFixedWindow(geometry);
626 clusterizer->SetNphi(fNPhi);
627 clusterizer->SetNeta(fNEta);
628 clusterizer->SetShiftPhi(fShiftPhi);
629 clusterizer->SetShiftEta(fShiftEta);
630 clusterizer->SetTRUshift(fTRUShift);
631 fClusterizer = clusterizer;
634 AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
636 fClusterizer->InitParameters(fRecParam);
638 if ((!fCalibData&&fLoadCalib) || (!fPedestalData&&fLoadPed)) {
639 AliCDBManager *cdb = AliCDBManager::Instance();
640 if (!cdb->IsDefaultStorageSet() && !fOCDBpath.IsNull())
641 cdb->SetDefaultStorage(fOCDBpath);
642 if (fRun!=cdb->GetRun())
645 if (!fCalibData&&fLoadCalib&&fRun>0) {
646 AliCDBEntry *entry = static_cast<AliCDBEntry*>(AliCDBManager::Instance()->Get("EMCAL/Calib/Data"));
648 fCalibData = static_cast<AliEMCALCalibData*>(entry->GetObject());
650 AliFatal("Calibration parameters not found in CDB!");
652 if (!fPedestalData&&fLoadPed&&fRun>0) {
653 AliCDBEntry *entry = static_cast<AliCDBEntry*>(AliCDBManager::Instance()->Get("EMCAL/Calib/Pedestals"));
655 fPedestalData = static_cast<AliCaloCalibPedestal*>(entry->GetObject());
658 fClusterizer->SetInputCalibrated(kFALSE);
659 fClusterizer->SetCalibrationParameters(fCalibData);
661 fClusterizer->SetInputCalibrated(kTRUE);
663 fClusterizer->SetCaloCalibPedestal(fPedestalData);
664 fClusterizer->SetJustClusters(kTRUE);
665 fClusterizer->SetDigitsArr(fDigitsArr);
666 fClusterizer->SetOutput(0);
667 fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());