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 //_________________________________________________________________________
17 // This analysis provides a new list of clusters to be used in other analysis
19 // Author: Constantin Loizides, Salvatore Aiola
20 // Adapted from analysis class from Deepa Thomas
23 //_________________________________________________________________________
26 #include <TClonesArray.h>
27 #include <TGeoManager.h>
28 #include <TObjArray.h>
33 #include "AliAODCaloCluster.h"
34 #include "AliAODEvent.h"
35 #include "AliAnalysisManager.h"
36 #include "AliCDBEntry.h"
37 #include "AliCDBManager.h"
38 #include "AliCaloCalibPedestal.h"
39 #include "AliEMCALAfterBurnerUF.h"
40 #include "AliEMCALCalibData.h"
41 #include "AliEMCALClusterizerNxN.h"
42 #include "AliEMCALClusterizerv1.h"
43 #include "AliEMCALClusterizerv2.h"
44 #include "AliEMCALClusterizerFixedWindow.h"
45 #include "AliEMCALDigit.h"
46 #include "AliEMCALGeometry.h"
47 #include "AliEMCALRecParam.h"
48 #include "AliEMCALRecPoint.h"
49 #include "AliEMCALRecoUtils.h"
50 #include "AliESDEvent.h"
51 #include "AliInputEventHandler.h"
54 #include "AliAnalysisTaskEMCALClusterizeFast.h"
56 ClassImp(AliAnalysisTaskEMCALClusterizeFast)
58 //________________________________________________________________________
59 AliAnalysisTaskEMCALClusterizeFast::AliAnalysisTaskEMCALClusterizeFast()
60 : AliAnalysisTaskSE(),
69 fGeomMatrixSet(kFALSE),
70 fLoadGeomMatrices(kFALSE),
84 fNewClusterArrayName("newCaloClusters"),
90 fClusterizeFastORs(0),
96 for(Int_t i = 0; i < 12; ++i)
100 //________________________________________________________________________
101 AliAnalysisTaskEMCALClusterizeFast::AliAnalysisTaskEMCALClusterizeFast(const char *name)
102 : AliAnalysisTaskSE(name),
106 fRecParam(new AliEMCALRecParam),
110 fGeomName("EMCAL_FIRSTYEARV1"),
111 fGeomMatrixSet(kFALSE),
112 fLoadGeomMatrices(kFALSE),
126 fNewClusterArrayName("newCaloClusters"),
132 fClusterizeFastORs(0),
138 fBranchNames = "ESD:AliESDHeader.,AliESDRun.,EMCALCells.,EMCALTrigger. AOD:header,emcalCells";
139 for(Int_t i = 0; i < 12; ++i)
143 //________________________________________________________________________
144 AliAnalysisTaskEMCALClusterizeFast::~AliAnalysisTaskEMCALClusterizeFast()
153 //-------------------------------------------------------------------
154 void AliAnalysisTaskEMCALClusterizeFast::UserCreateOutputObjects()
156 // Create output objects.
158 if (!fOutputAODBrName.IsNull()) {
159 fOutputAODBranch = new TClonesArray("AliAODCaloCluster", 0);
160 fOutputAODBranch->SetName(fOutputAODBrName);
161 AddAODBranch("TClonesArray", &fOutputAODBranch);
162 AliInfo(Form("Created Branch: %s",fOutputAODBrName.Data()));
166 //________________________________________________________________________
167 void AliAnalysisTaskEMCALClusterizeFast::UserExec(Option_t *)
169 // Main loop, called for each event
171 // remove the contents of output list set in the previous event
172 if (fOutputAODBranch)
173 fOutputAODBranch->Clear("C");
175 AliESDEvent *esdevent = dynamic_cast<AliESDEvent*>(InputEvent());
176 AliAODEvent *aodevent = dynamic_cast<AliAODEvent*>(InputEvent());
178 if (!esdevent&&!aodevent) {
179 Error("UserExec","Event not available");
185 UInt_t offtrigger = 0;
187 UInt_t mask1 = esdevent->GetESDRun()->GetDetectorsInDAQ();
188 UInt_t mask2 = esdevent->GetESDRun()->GetDetectorsInReco();
189 Bool_t desc1 = (mask1 >> 18) & 0x1;
190 Bool_t desc2 = (mask2 >> 18) & 0x1;
191 if (desc1==0 || desc2==0) { //AliDAQ::OfflineModuleName(180=="EMCAL"
192 AliError(Form("EMCAL not in DAQ/RECO: %u (%u)/%u (%u)",
193 mask1, esdevent->GetESDRun()->GetDetectorsInReco(),
194 mask2, esdevent->GetESDRun()->GetDetectorsInDAQ()));
197 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
198 offtrigger = ((AliInputEventHandler*)(am->GetInputEventHandler()))->IsEventSelected();
199 } else if (aodevent) {
200 offtrigger = aodevent->GetHeader()->GetOfflineTrigger();
204 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
206 if (am->GetMCtruthEventHandler())
209 if (offtrigger & AliVEvent::kFastOnly) {
210 AliWarning(Form("EMCAL not in fast only partition"));
219 AliWarning("Unfolding not implemented");
227 return; // not requested to run clusterizer
234 if (fOutputAODBranch)
235 RecPoints2Clusters(fOutputAODBranch);
238 //________________________________________________________________________
239 void AliAnalysisTaskEMCALClusterizeFast::Clusterize()
243 if (fSubBackground) {
244 fClusterizer->SetInputCalibrated(kTRUE);
245 fClusterizer->SetCalibrationParameters(0);
248 fClusterizer->Digits2Clusters("");
249 if (fSubBackground) {
251 fClusterizer->SetInputCalibrated(kFALSE);
252 fClusterizer->SetCalibrationParameters(fCalibData);
257 //________________________________________________________________________
258 void AliAnalysisTaskEMCALClusterizeFast::FillDigitsArray()
262 fDigitsArr->Clear("C");
264 if (fCreatePattern) { // Fill digits from a pattern
265 AliEMCALGeometry *fGeom = AliEMCALGeometry::GetInstance(fGeomName);
266 Int_t maxd = fGeom->GetNCells() / 4;
267 for (Int_t idigit = 0; idigit < maxd; idigit++){
268 if (idigit % 24 == 12) idigit += 12;
269 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
270 digit->SetId(idigit * 4);
272 digit->SetTimeR(600);
273 digit->SetIndexInList(idigit);
274 digit->SetType(AliEMCALDigit::kHG);
275 digit->SetAmplitude(0.1);
278 } else if (fClusterizeFastORs) { // Fill digits from FastORs
280 AliEMCALGeometry *fGeom = AliEMCALGeometry::GetInstance(fGeomName);
282 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
284 AliError("Cannot get the ESD event");
288 AliESDCaloTrigger *triggers = esd->GetCaloTrigger("EMCAL");
290 if (!triggers || !(triggers->GetEntries() > 0))
296 while ((triggers->Next())) {
297 Float_t triggerAmplitude = 0;
298 triggers->GetAmplitude(triggerAmplitude);
299 if (triggerAmplitude <= 0)
302 Int_t triggerTime = 0;
304 triggers->GetNL0Times(ntimes);
305 if (!(ntimes > 0) && fCutL0Times)
309 triggers->GetL0Times(trgtimes);
310 triggerTime = trgtimes[0];
312 Int_t triggerCol = 0, triggerRow = 0;
313 triggers->GetPosition(triggerCol, triggerRow);
316 fGeom->GetAbsFastORIndexFromPositionInEMCAL(triggerCol, triggerRow, find);
321 Int_t cidx[4] = {-1};
322 Bool_t ret = fGeom->GetCellIndexFromFastORIndex(find, cidx);
327 for (Int_t idxpos = 0; idxpos < 4; idxpos++) {
328 Int_t triggerNumber = cidx[idxpos];
329 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
330 digit->SetId(triggerNumber);
331 digit->SetTime(triggerTime);
332 digit->SetTimeR(triggerTime);
333 digit->SetIndexInList(idigit);
334 digit->SetType(AliEMCALDigit::kHG);
335 digit->SetAmplitude(triggerAmplitude);
340 } else { // Fill digits from cells.
342 AliVCaloCells *cells = InputEvent()->GetEMCALCells();
343 Double_t avgE = 0; // for background subtraction
344 const Int_t ncells = cells->GetNumberOfCells();
345 for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell) {
346 Double_t cellAmplitude=0, cellTime=0, cellEFrac = 0;
347 Short_t cellNumber=0, cellMCLabel=-1;
348 if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime, cellMCLabel, cellEFrac) != kTRUE)
350 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
351 digit->SetId(cellNumber);
352 digit->SetTime(cellTime);
353 digit->SetTimeR(cellTime);
354 digit->SetIndexInList(idigit);
355 digit->SetType(AliEMCALDigit::kHG);
356 if (fRecalibOnly||fSubBackground) {
357 Float_t energy = cellAmplitude;
358 Float_t time = cellTime;
359 fClusterizer->Calibrate(energy,time,cellNumber);
360 digit->SetAmplitude(energy);
363 digit->SetAmplitude(cellAmplitude);
370 if (fSubBackground) {
371 avgE /= AliEMCALGeometry::GetInstance(fGeomName)->GetNumberOfSuperModules()*48*24;
372 Int_t ndigis = fDigitsArr->GetEntries();
373 for (Int_t i = 0; i < ndigis; ++i) {
374 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(i));
375 Double_t energy = digit->GetAmplitude() - avgE;
377 digit->SetAmplitude(0);
379 digit->SetAmplitude(energy);
386 //________________________________________________________________________________________
387 void AliAnalysisTaskEMCALClusterizeFast::RecPoints2Clusters(TClonesArray *clus)
389 // Cluster energy, global position, cells and their amplitude fractions are restored.
391 Bool_t esdobjects = 0;
392 if (strcmp(clus->GetClass()->GetName(),"AliESDCaloCluster")==0)
395 AliVCaloCells *cells = InputEvent()->GetEMCALCells();
396 AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance(fGeomName);
397 AliVEvent *event = InputEvent();
399 AliError("Cannot get the event");
403 // tracks array for track/cluster matching
404 TClonesArray *tarr = 0;
405 if (!fTrackName.IsNull()) {
406 tarr = dynamic_cast<TClonesArray*>(event->FindListObject(fTrackName));
408 AliError(Form("Cannot get tracks named %s", fTrackName.Data()));
412 const Int_t Ncls = fClusterArr->GetEntries();
413 AliDebug(1, Form("total no of clusters %d", Ncls));
414 for(Int_t i=0, nout=clus->GetEntries(); i < Ncls; ++i) {
415 AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
416 Int_t ncells_true = 0;
417 const Int_t ncells = recpoint->GetMultiplicity();
418 UShort_t absIds[ncells];
419 Double32_t ratios[ncells];
420 Int_t *dlist = recpoint->GetDigitsList();
421 Float_t *elist = recpoint->GetEnergiesList();
422 for (Int_t c = 0; c < ncells; ++c) {
423 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
424 absIds[ncells_true] = digit->GetId();
425 ratios[ncells_true] = elist[c]/digit->GetAmplitude();
429 if (ncells_true < 1) {
430 AliWarning("Skipping cluster with no cells");
434 // calculate new cluster position
436 recpoint->GetGlobalPosition(gpos);
440 AliDebug(1, Form("energy %f", recpoint->GetEnergy()));
442 AliVCluster *c = static_cast<AliVCluster*>(clus->New(nout++));
443 c->SetType(AliVCluster::kEMCALClusterv1);
444 c->SetE(recpoint->GetEnergy());
446 c->SetNCells(ncells_true);
448 AliESDCaloCluster *cesd = static_cast<AliESDCaloCluster*>(c);
449 cesd->SetCellsAbsId(absIds);
450 cesd->SetCellsAmplitudeFraction(ratios);
451 cesd->SetID(recpoint->GetUniqueID());
453 AliAODCaloCluster *caod = static_cast<AliAODCaloCluster*>(c);
454 caod->SetCellsAbsId(absIds);
455 caod->SetCellsAmplitudeFraction(ratios);
457 c->SetDispersion(recpoint->GetDispersion());
458 c->SetEmcCpvDistance(-1);
460 c->SetTOF(recpoint->GetTime()) ; //time-of-flight
461 c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
463 recpoint->GetElipsAxis(elipAxis);
464 c->SetM02(elipAxis[0]*elipAxis[0]);
465 c->SetM20(elipAxis[1]*elipAxis[1]);
467 c->SetDistanceToBadChannel(recpoint->GetDistanceToBadTower());
469 if (fRecoUtils && fRecoUtils->IsBadChannelsRemovalSwitchedOn()) {
470 fRecoUtils->RecalculateClusterDistanceToBadChannel(geom, cells, c);
475 Double_t dEtaMin = 1e9;
476 Double_t dPhiMin = 1e9;
478 Double_t ceta = gpos.Eta();
479 Double_t cphi = gpos.Phi();
480 const Int_t ntrks = tarr->GetEntries();
481 for(Int_t t = 0; t<ntrks; ++t) {
482 AliVTrack *track = static_cast<AliVTrack*>(tarr->At(t));
485 const AliExternalTrackParam *outp = track->GetOuterParam();
488 Double_t trkPos[3] = {0.,0.,0.};
489 if (!outp->GetXYZ(trkPos))
491 TVector3 vec(trkPos[0],trkPos[1],trkPos[2]);
492 Double_t veta = vec.Eta();
493 Double_t vphi = vec.Phi();
495 vphi += 2*TMath::Pi();
496 if (TMath::Abs(veta)>0.75 || (vphi<70*TMath::DegToRad()) || (vphi>190*TMath::DegToRad()))
498 Double_t dR = vec.DeltaR(gpos);
501 Float_t tmpEta=0, tmpPhi=0;
503 AliExternalTrackParam trkParTemp(*outp); // retrieve the starting point every time before the extrapolation
504 Bool_t ret = fRecoUtils->ExtrapolateTrackToCluster(&trkParTemp, c, fRecoUtils->GetMass(), fRecoUtils->GetStep(), tmpEta, tmpPhi);
508 tmpEta = ceta - veta;
509 tmpPhi = cphi - vphi;
511 if (TMath::Abs(tmpEta)<TMath::Abs(dEtaMin) && TMath::Abs(tmpPhi)<TMath::Abs(dPhiMin)) {
517 c->SetEmcCpvDistance(imin);
518 c->SetTrackDistance(dPhiMin, dEtaMin);
523 //________________________________________________________________________
524 void AliAnalysisTaskEMCALClusterizeFast::UpdateCells()
526 // Update cells in case re-calibration was done.
528 if (!fCalibData&&!fSubBackground)
531 AliVCaloCells *cells = InputEvent()->GetEMCALCells();
532 const Int_t ncells = cells->GetNumberOfCells();
533 const Int_t ndigis = fDigitsArr->GetEntries();
534 if (ncells!=ndigis) {
535 cells->DeleteContainer();
536 cells->CreateContainer(ndigis);
538 for (Int_t idigit = 0; idigit < ndigis; ++idigit) {
539 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(idigit));
540 Double_t cellAmplitude = digit->GetCalibAmp();
541 Short_t cellNumber = digit->GetId();
542 Double_t cellTime = digit->GetTime();
543 cells->SetCell(idigit, cellNumber, cellAmplitude, cellTime);
547 //________________________________________________________________________
548 void AliAnalysisTaskEMCALClusterizeFast::UpdateClusters()
550 // Update cells in case re-calibration was done.
552 if (!fAttachClusters)
555 TClonesArray *clus = 0;
558 clus = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject("caloClusters"));
560 clus = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject("CaloClusters"));
564 const Int_t nents = clus->GetEntries();
565 for (Int_t i=0;i<nents;++i) {
566 AliVCluster *c = static_cast<AliVCluster*>(clus->At(i));
570 delete clus->RemoveAt(i);
573 clus = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(fNewClusterArrayName));
575 clus = new TClonesArray("AliESDCaloCluster");
576 clus->SetName(fNewClusterArrayName);
577 InputEvent()->AddObject(clus);
583 RecPoints2Clusters(clus);
586 //________________________________________________________________________________________
587 void AliAnalysisTaskEMCALClusterizeFast::Init()
589 //Select clusterization/unfolding algorithm and set all the needed parameters
591 AliVEvent * event = InputEvent();
593 AliWarning("Event not available!!!");
597 if (event->GetRunNumber()==fRun)
599 fRun = event->GetRunNumber();
602 // init the unfolding afterburner
604 fUnfolder = new AliEMCALAfterBurnerUF(fRecParam->GetW0(),fRecParam->GetLocMaxCut(),fRecParam->GetMinECut());
608 AliEMCALGeometry *geometry = AliEMCALGeometry::GetInstance(fGeomName);
610 AliFatal("Geometry not available!!!");
614 if (!fGeomMatrixSet) {
615 if (fLoadGeomMatrices) {
616 for(Int_t mod=0; mod < geometry->GetNumberOfSuperModules(); ++mod) {
617 if (fGeomMatrix[mod]){
618 if (DebugLevel() > 2)
619 fGeomMatrix[mod]->Print();
620 geometry->SetMisalMatrix(fGeomMatrix[mod],mod);
623 } else { // get matrix from file (work around bug in aliroot)
624 for(Int_t mod=0; mod < geometry->GetEMCGeometry()->GetNumberOfSuperModules(); ++mod) {
625 const TGeoHMatrix *gm = 0;
626 AliESDEvent *esdevent = dynamic_cast<AliESDEvent*>(event);
628 gm = esdevent->GetEMCALMatrix(mod);
630 AliAODHeader *aodheader = dynamic_cast<AliAODHeader*>(event->GetHeader());
632 gm = aodheader->GetEMCALMatrix(mod);
636 if (DebugLevel() > 2)
638 geometry->SetMisalMatrix(gm,mod);
642 fGeomMatrixSet=kTRUE;
645 // setup digit array if needed
647 fDigitsArr = new TClonesArray("AliEMCALDigit", 1000);
648 fDigitsArr->SetOwner(1);
651 // then setup clusterizer
653 if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
654 fClusterizer = new AliEMCALClusterizerv1(geometry);
655 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN) {
656 AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(geometry);
657 clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
658 clusterizer->SetNColDiff(fRecParam->GetNColDiff());
659 fClusterizer = clusterizer;
660 } else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2)
661 fClusterizer = new AliEMCALClusterizerv2(geometry);
662 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerFW){
663 AliEMCALClusterizerFixedWindow *clusterizer = new AliEMCALClusterizerFixedWindow(geometry);
664 clusterizer->SetNphi(fNPhi);
665 clusterizer->SetNeta(fNEta);
666 clusterizer->SetShiftPhi(fShiftPhi);
667 clusterizer->SetShiftEta(fShiftEta);
668 clusterizer->SetTRUshift(fTRUShift);
669 fClusterizer = clusterizer;
672 AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
674 fClusterizer->InitParameters(fRecParam);
676 if ((!fCalibData&&fLoadCalib) || (!fPedestalData&&fLoadPed)) {
677 AliCDBManager *cdb = AliCDBManager::Instance();
678 if (!cdb->IsDefaultStorageSet() && !fOCDBpath.IsNull())
679 cdb->SetDefaultStorage(fOCDBpath);
680 if (fRun!=cdb->GetRun())
683 if (!fCalibData&&fLoadCalib&&fRun>0) {
684 AliCDBEntry *entry = static_cast<AliCDBEntry*>(AliCDBManager::Instance()->Get("EMCAL/Calib/Data"));
686 fCalibData = static_cast<AliEMCALCalibData*>(entry->GetObject());
688 AliFatal("Calibration parameters not found in CDB!");
690 if (!fPedestalData&&fLoadPed&&fRun>0) {
691 AliCDBEntry *entry = static_cast<AliCDBEntry*>(AliCDBManager::Instance()->Get("EMCAL/Calib/Pedestals"));
693 fPedestalData = static_cast<AliCaloCalibPedestal*>(entry->GetObject());
696 fClusterizer->SetInputCalibrated(kFALSE);
697 fClusterizer->SetCalibrationParameters(fCalibData);
699 fClusterizer->SetInputCalibrated(kTRUE);
701 fClusterizer->SetCaloCalibPedestal(fPedestalData);
702 fClusterizer->SetJustClusters(kTRUE);
703 fClusterizer->SetDigitsArr(fDigitsArr);
704 fClusterizer->SetOutput(0);
705 fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());