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 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // EMCAL tender, apply corrections to EMCAl clusters //
20 // and do track matching //
21 // Author : Deepa Thomas (Utrecht University) //
23 ///////////////////////////////////////////////////////////////////////////////
27 //#include "TAlienFile.h"
30 #include "TInterpreter.h"
31 #include "TObjArray.h"
34 #include <AliESDEvent.h>
35 #include <AliAnalysisManager.h>
36 #include <AliTender.h>
37 #include "AliOADBContainer.h"
39 #include "TGeoGlobalMagField.h"
41 #include "AliESDCaloCluster.h"
42 #include "AliEMCALTenderSupply.h"
45 #include "AliEMCALGeometry.h"
46 #include "AliEMCALRecoUtils.h"
49 // Remove all calls to TGrid::Connect - grid connection is global and better steer by the run macro
51 AliEMCALTenderSupply::AliEMCALTenderSupply() :
54 ,fEMCALGeoName("EMCAL_FIRSTYEARV1")
55 ,fEMCALRecoUtils(new AliEMCALRecoUtils)
58 ,fNonLinearFunc(AliEMCALRecoUtils::kNoCorrection)
59 ,fNonLinearThreshold(30)
60 ,fReCalibCluster(kFALSE)
62 ,fRecalClusPos(kFALSE)
64 ,fNCellsFromEMCALBorder(1)
65 ,fRecalDistToBadChannels(kFALSE)
77 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
80 //_____________________________________________________
81 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) :
82 AliTenderSupply(name,tender)
84 ,fEMCALGeoName("EMCAL_FIRSTYEARV1")
85 ,fEMCALRecoUtils(new AliEMCALRecoUtils)
88 ,fNonLinearFunc(AliEMCALRecoUtils::kNoCorrection)
89 ,fNonLinearThreshold(30)
90 ,fReCalibCluster(kFALSE)
92 ,fRecalClusPos(kFALSE)
94 ,fNCellsFromEMCALBorder(1)
95 ,fRecalDistToBadChannels(kFALSE)
107 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
110 //_____________________________________________________
111 AliEMCALTenderSupply::~AliEMCALTenderSupply()
115 delete fEMCALRecoUtils;
120 //_____________________________________________________
121 void AliEMCALTenderSupply::Init()
124 // Initialise EMCAL tender
127 if (fDebugLevel>0) AliInfo("Init EMCAL Tender supply\n");
129 AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
131 fInputTree = mgr->GetTree();
133 if(gROOT->LoadMacro(fConfigName) >=0){
134 AliDebug(1, Form("Loading settings from macro %s", fConfigName.Data()));
135 AliEMCALTenderSupply *tender = (AliEMCALTenderSupply*)gInterpreter->ProcessLine("ConfigEMCALTenderSupply()");
136 fDebugLevel = tender->fDebugLevel;
137 fEMCALGeoName = tender->fEMCALGeoName;
138 fEMCALRecoUtils = tender->fEMCALRecoUtils;
139 fConfigName = tender->fConfigName;
140 fNonLinearFunc = tender->fNonLinearFunc;
141 fNonLinearThreshold = tender->fNonLinearThreshold;
142 fReCalibCluster = tender->fReCalibCluster;
143 fReCalibCell = tender->fReCalibCell;
144 fRecalClusPos = tender->fRecalClusPos;
145 fFiducial = tender->fFiducial;
146 fNCellsFromEMCALBorder = tender->fNCellsFromEMCALBorder;
147 fRecalDistToBadChannels = tender->fRecalDistToBadChannels;
148 fMass = tender->fMass;
149 fStep = tender->fStep;
150 fRcut = tender->fRcut;
154 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ;
156 fEMCALRecoUtils = new AliEMCALRecoUtils();
158 //Initialising Non linearity parameters
159 fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold);
161 //Setting mass, step size and residual cut
162 fEMCALRecoUtils->SwitchOnCutEtaPhiSum();
163 fEMCALRecoUtils->SetCutR(fRcut);
164 fEMCALRecoUtils->SetMass(fMass);
165 fEMCALRecoUtils->SetStep(fStep);
167 if(fDebugLevel>1) fEMCALRecoUtils->Print("");
171 //_____________________________________________________
172 void AliEMCALTenderSupply::ProcessEvent()
175 AliESDEvent *event=fTender->GetEvent();
178 if(fTender->RunChanged()){
179 //Initialising parameters once per run number
180 if (!InitBadChannels()) return;
181 if (fRecalClusPos){ if (!InitMisalignMatrix()) return;}
182 if (fReCalibCluster || fReCalibCell){ if (!InitRecalib()) return;}
185 AliESDCaloCells *cells= event->GetEMCALCells();
187 //------------Good clusters------------
188 TClonesArray *clusArr;
190 clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
191 if(!clusArr) clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
194 for (Int_t icluster=0; icluster < clusArr->GetEntries(); icluster++ ){
195 AliVCluster *clust = static_cast<AliVCluster*>(clusArr->At(icluster));
197 if (!clust->IsEMCAL()) continue;
198 if(fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells() )){
199 delete clusArr->RemoveAt(icluster);
203 if(!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){
204 delete clusArr->RemoveAt(icluster);
208 fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust);
209 if(fRecalDistToBadChannels) fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust);
210 if(fReCalibCluster) fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells);
211 if(fRecalClusPos) fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust);
212 //fEMCALRecoUtils->SetTimeDependentCorrections(event->GetRunNumber());
216 //------------ EMCAL cells loop ------------
219 if(fReCalibCell) RecalibrateCells();
221 //-------- Track Matching ------------------
224 Double_t magF = event->GetMagneticField();
225 Double_t magSign = 1.0;
226 if(magF<0)magSign = -1.0;
228 if (!TGeoGlobalMagField::Instance()->GetField())
230 AliMagF* field = new AliMagF("Maps","Maps", magSign, magSign, AliMagF::k5kG);
231 TGeoGlobalMagField::Instance()->SetField(field);
235 fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo);
237 Int_t nTracks = event->GetNumberOfTracks();
240 SetClusterMatchedToTrack(event);
241 SetTracksMatchedToCluster(event);
246 //_____________________________________________________
247 void AliEMCALTenderSupply::SetClusterMatchedToTrack(AliESDEvent *event)
249 //checks if tracks are matched to EMC clusters and set the matched EMCAL cluster index to ESD track.
251 Int_t matchClusIndex = -1;
252 Int_t nTracks = event->GetNumberOfTracks();
255 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++)
257 AliESDtrack* track = event->GetTrack(iTrack);
259 printf("ERROR: Could not receive track %d\n", iTrack);
263 matchClusIndex = fEMCALRecoUtils->GetMatchedClusterIndex(iTrack);
264 track->SetEMCALcluster(matchClusIndex); //sets -1 if track not matched within residual
267 if (fDebugLevel>2) AliInfo("Track matched to closest cluster\n");
270 //_____________________________________________________
271 void AliEMCALTenderSupply::SetTracksMatchedToCluster(AliESDEvent *event)
273 //checks if EMC clusters are matched to ESD track.
274 //Adds track indexes of all the tracks matched to a cluster withing residuals in ESDCalocluster
276 Int_t matchTrackIndex = -1;
277 Int_t nTracks = event->GetNumberOfTracks();
280 for (Int_t iClus=0; iClus < event->GetNumberOfCaloClusters(); iClus++)
282 AliESDCaloCluster * cluster = event->GetCaloCluster(iClus);
283 if (!cluster->IsEMCAL()) continue;
286 TArrayI arrayTrackMatched(nTracks);
288 //get the closest track matched to the cluster
289 matchTrackIndex = fEMCALRecoUtils->GetMatchedTrackIndex(iClus);
290 arrayTrackMatched[nMatched] = matchTrackIndex;
293 //get all other tracks matched to the cluster
295 for(Int_t iTrk=0; iTrk<nTracks; iTrk++){
296 AliESDtrack* track = event->GetTrack(iTrk);
297 if(iTrk == matchTrackIndex) continue;
299 if(track->GetEMCALcluster() == iClus){
300 arrayTrackMatched[nMatched] = iTrk;
305 arrayTrackMatched.Set(nMatched);
306 cluster->AddTracksMatched(arrayTrackMatched);
308 Float_t eta= -999, phi = -999;
309 if(matchTrackIndex != -1) fEMCALRecoUtils->GetMatchedResiduals(iClus, eta, phi);
310 cluster->SetTrackDistance(phi, eta);
312 if (fDebugLevel>2) AliInfo("Cluster matched to tracks \n");
315 //_____________________________________________________
316 Bool_t AliEMCALTenderSupply::InitMisalignMatrix()
318 //Initialising Misalignment matrix
320 AliESDEvent *event=fTender->GetEvent();
321 if (!event) return kFALSE;
323 if (fDebugLevel>0) AliInfo("Initialising Misalignment matrix \n");
326 fInputFile = fInputTree->GetCurrentFile();
328 const char *fileName = fInputFile->GetName();
329 TString FileName = TString(fileName);
330 if (FileName.Contains("pass1")) fFilepass = TString("pass1");
331 else if(FileName.Contains("pass2")) fFilepass = TString("pass2");
332 else if(FileName.Contains("pass3")) fFilepass = TString("pass3");
333 else AliError("pass number not found");
335 else AliError("File not found");
337 else AliError("Tree not found");
340 runGM = event->GetRunNumber();
342 fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);
344 if(runGM <=140000){ //2010 data
346 Double_t rotationMatrix[4][9] = {{-0.014587, -0.999892, -0.002031, 0.999892, -0.014591, 0.001979, -0.002009, -0.002002, 0.999996},
347 {-0.014587, 0.999892, 0.002031, 0.999892, 0.014591, -0.001979, -0.002009, 0.002002, -0.999996},
348 {-0.345864, -0.938278, -0.003412, 0.938276, -0.345874, 0.003010, -0.004004, -0.002161, 0.999990},
349 {-0.345861, 0.938280, 0.003412, 0.938276, 0.345874, -0.003010, -0.004004, 0.002161, -0.999990}};
351 Double_t translationMatrix[4][3] = {{0.351659, 447.576446, 176.269742},
352 {1.062577, 446.893974, -173.728870},
353 {-154.213287, 419.306156, 176.753692},
354 {-153.018950, 418.623681, -173.243605}};
356 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
358 //if(DebugLevel() > 1) fEMCALMatrix[mod]->Print();
359 fEMCALMatrix[mod] = new TGeoHMatrix(); // mfasel: prevent tender from crashing
360 fEMCALMatrix[mod]->SetRotation(rotationMatrix[mod]);
361 fEMCALMatrix[mod]->SetTranslation(translationMatrix[mod]);
362 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
367 else if(runGM>140000 && runGM <148531 && (fFilepass = "pass1"))
368 { // 2011 LHC11a pass1 data
369 AliOADBContainer emcalgeoCont(Form("emcal2011"));
370 emcalgeoCont.InitFromFile(Form("%s/BetaGood.root",fBasePath),Form("AliEMCALgeo"));
372 TObjArray *mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS");
374 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
375 fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod);
376 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
378 fEMCALMatrix[mod]->Print();
382 else AliInfo("MISALLIGNMENT NOT APPLIED");
387 //_____________________________________________________
388 Bool_t AliEMCALTenderSupply::InitBadChannels()
390 //Initialising Bad channel maps
392 AliESDEvent *event=fTender->GetEvent();
393 if (!event) return kFALSE;
396 fRunBC = event->GetRunNumber();
398 if (fDebugLevel>0) AliInfo("Initialising Bad channel map \n");
401 fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder);
402 fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0();
405 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
406 if(fRecalDistToBadChannels) fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation();
411 fbad = new TFile("BadChannels.root","read");
412 if (fbad->IsZombie()){
413 TString fPath = TString(fBasePath);
414 if(fPath.Contains("alien")) {
415 if (fDebugLevel>1) AliInfo("Connecting to alien to get BadChannels.root \n");
416 fbad = TFile::Open(Form("%s/BadChannelsDB/BadChannels.root",fBasePath));
420 TH2I * hb0 = ( TH2I *)fbad->Get("EMCALBadChannelMap_Mod0");
421 TH2I * hb1 = ( TH2I *)fbad->Get("EMCALBadChannelMap_Mod1");
422 TH2I * hb2 = ( TH2I *)fbad->Get("EMCALBadChannelMap_Mod2");
423 TH2I * hb3 = ( TH2I *)fbad->Get("EMCALBadChannelMap_Mod3");
424 fEMCALRecoUtils->SetEMCALChannelStatusMap(0,hb0);
425 fEMCALRecoUtils->SetEMCALChannelStatusMap(1,hb1);
426 fEMCALRecoUtils->SetEMCALChannelStatusMap(2,hb2);
427 fEMCALRecoUtils->SetEMCALChannelStatusMap(3,hb3);
434 const Int_t nTowers=89;
435 Int_t hotChannels[nTowers]={74, 103, 152, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 368, 369, 370, 371, 372, 373, 374,375, 376, 377, 378, 379, 380, 381, 382, 383, 917, 1275, 1288, 1519, 1595, 1860, 1967, 2022, 2026, 2047, 2117, 2298, 2540, 2776, 3135, 3764, 6095, 6111, 6481, 6592, 6800, 6801, 6802, 6803, 6804, 6805, 6806, 6807, 6808, 6809, 6810, 6811, 6812, 6813, 6814, 6815, 7371, 7425, 7430, 7457, 7491, 7709, 8352, 8353, 8356, 8357, 8808, 8810, 8812, 8814, 9056, 9769, 9815, 9837};
437 Int_t nSupMod=-1, nModule=-1, nIphi=-1, nIeta=-1, iphi=-1, ieta=-1;
438 for(Int_t i=0; i<nTowers; i++)
440 fEMCALGeo->GetCellIndex(hotChannels[i],nSupMod,nModule,nIphi,nIeta);
442 fEMCALGeo->GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta,iphi,ieta);
443 fEMCALRecoUtils->SetEMCALChannelStatus(nSupMod, ieta, iphi);
451 //_____________________________________________________
452 Bool_t AliEMCALTenderSupply::InitRecalib()
454 //Initialising Recalibration Factors
456 AliESDEvent *event=fTender->GetEvent();
457 if (!event) return kFALSE;
459 if (fDebugLevel>0) AliInfo("Initialising Recalibration factors \n");
462 fInputFile = fInputTree->GetCurrentFile();
464 const char *fileName = fInputFile->GetName();
465 TString FileName = TString(fileName);
466 if (FileName.Contains("pass1")) fFilepass = TString("pass1");
467 else if(FileName.Contains("pass2")) fFilepass = TString("pass2");
468 else if(FileName.Contains("pass3")) fFilepass = TString("pass3");
469 else AliError("pass number not found");
471 else AliError("File not found");
473 else AliError("Tree not found");
474 // else {cout << "Tree not found " <<endl; return kFALSE;}
476 Int_t runRC = event->GetRunNumber();
478 //if (event->GetRunNumber()==runRC)
481 fEMCALRecoUtils->SwitchOnRecalibration();
486 fRecalib = new TFile("RecalibrationFactors.root","read");
487 if (fRecalib->IsZombie()){
488 TString fPath = TString(fBasePath);
489 if(fPath.Contains("alien")) {
491 if (fDebugLevel>1) AliInfo("Connecting to alien to get RecalibrationFactors.root \n");
493 if( (runRC >= 114737 && runRC <= 117223 && (fFilepass = "pass2")) || //LHC10b pass2
494 (runRC >= 118503 && runRC <= 121040 && ((fFilepass = "pass2")||(fFilepass = "pass3"))) || //LHC10c pass2, LHC10c pass3
495 (runRC >= 122195 && runRC <= 126437 && (fFilepass = "pass1")) || //LHC10d pass1
496 (runRC >= 127712 && runRC <= 130850 && (fFilepass = "pass1")) || //LHC10e pass1
497 (runRC >= 133004 && runRC < 134657 && (fFilepass = "pass1")))// LHC10f pass1 <134657
499 fRecalib = TFile::Open(Form("%s/RecalDB/summer_december_2010/RecalibrationFactors.root",fBasePath));
502 else if((runRC >= 122195 && runRC <= 126437 && (fFilepass = "pass2")) || //LHC10d pass2
503 (runRC >= 134657 && runRC <= 135029 && (fFilepass = "pass1")) || //LHC10f pass1 >= 134657
504 (runRC >= 135654 && runRC <= 136377 && (fFilepass = "pass1")) || //LHC10g pass1
505 (runRC >= 136851 && runRC < 137231 && (fFilepass = "pass1"))) //LHC10h pass1 untill christmas
507 fRecalib = TFile::Open(Form("%s/RecalDB/december2010/RecalibrationFactors.root",fBasePath));
510 else if(runRC >= 137231 && runRC <= 139517 && (fFilepass = "pass1")) //LHC10h pass1 from christmas
512 fRecalib = TFile::Open(Form("%s/RecalDB/summer2010/RecalibrationFactors.root",fBasePath));
515 AliError("Run number or pass number not found; RECALIBRATION NOT APPLIED");
521 TH2F * r0 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM0");
522 TH2F * r1 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM1");
523 TH2F * r2 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM2");
524 TH2F * r3 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM3");
525 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(0,r0);
526 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(1,r1);
527 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(2,r2);
528 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(3,r3);
532 fRecalib = new TFile("RecalibrationFactors.root","read");
533 if (fRecalib->IsZombie()){
534 TString fPath = TString(fBasePath);
535 if(fPath.Contains("alien")) {
536 if (fDebugLevel>1) AliInfo("Connecting to alien to get RecalibrationFactors.root \n");
538 fRecalib = TFile::Open(Form("%s/RecalDB/2011_v0/RecalibrationFactors.root",fBasePath));
539 if(!fRecalib) AliError("Recalibration file not found");
543 TH2F * r0 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM0");
544 TH2F * r1 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM1");
545 TH2F * r2 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM2");
546 TH2F * r3 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM3");
547 TH2F * r4 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM4");
548 TH2F * r5 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM5");
549 TH2F * r6 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM6");
550 TH2F * r7 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM7");
551 TH2F * r8 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM8");
552 TH2F * r9 = ( TH2F *)fRecalib->Get("EMCALRecalFactors_SM9");
554 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(0,r0);
555 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(1,r1);
556 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(2,r2);
557 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(3,r3);
558 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(4,r4);
559 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(5,r5);
560 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(6,r6);
561 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(7,r7);
562 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(8,r8);
563 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(9,r9);
570 //_____________________________________________________
571 void AliEMCALTenderSupply::RecalibrateCells()
573 AliESDCaloCells *cells = fTender->GetEvent()->GetEMCALCells();
575 Int_t nEMCcell = cells->GetNumberOfCells();
576 Double_t calibFactor = 1.;
578 for(Int_t icell=0; icell<nEMCcell; icell++){
579 Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1;
580 fEMCALGeo->GetCellIndex(cells->GetCellNumber(icell),imod,iTower,iIphi,iIeta);
581 fEMCALGeo->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);
582 calibFactor = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi);
583 cells->SetCell(icell,cells->GetCellNumber(icell),cells->GetAmplitude(icell)*calibFactor,cells->GetTime(icell));