1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Authors: Friederike Bock, Baldo Sahlmueller *
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 //---------------------------------------------
18 // Class handling all kinds of selection cuts for
19 // Photon from EMCAL clusters
20 //---------------------------------------------
21 ////////////////////////////////////////////////
23 #include "AliCaloPhotonCuts.h"
24 #include "AliAnalysisManager.h"
25 #include "AliInputEventHandler.h"
26 #include "AliMCEventHandler.h"
27 #include "AliAODHandler.h"
32 #include "AliAODConversionMother.h"
33 #include "AliAODConversionPhoton.h"
34 #include "TObjString.h"
35 #include "AliAODEvent.h"
36 #include "AliESDEvent.h"
37 #include "AliCentrality.h"
41 #include "AliV0ReaderV1.h"
42 #include "AliAODMCParticle.h"
43 #include "AliAODMCHeader.h"
44 #include "AliPicoTrack.h"
45 #include "AliEMCALRecoUtils.h"
51 ClassImp(AliCaloPhotonCuts)
54 const char* AliCaloPhotonCuts::fgkCutNames[AliCaloPhotonCuts::kNCuts] = {
55 "ClusterType", //0 0: all, 1: EMCAL, 2: PHOS
56 "EtaMin", //1 0: -10, 1: -0.6687, 2: -0,5, 3: -2
57 "EtaMax", //2 0: 10, 1: 0.66465, 2: 0.5, 3: 2
58 "PhiMin", //3 0: -10000, 1: 1.39626
59 "PhiMax", //4 0: 10000, 1: 3.125
60 "DistanceToBadChannel", //5 0: 0, 1: 5
61 "Timing", //6 0: no cut
62 "TrackMatching", //7 0: 0, 1: 5
63 "ExoticCell", //8 0: no cut
64 "MinEnergy", //9 0: no cut, 1: 0.05, 2: 0.1, 3: 0.15, 4: 0.2, 5: 0.3, 6: 0.5, 7: 0.75, 8: 1, 9: 1.25 (all GeV)
65 "MinNCells", //10 0: no cut, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6
70 "MaximumDispersion", //15
75 //________________________________________________________________________
76 AliCaloPhotonCuts::AliCaloPhotonCuts(const char *name,const char *title) :
77 AliAnalysisCuts(name,title),
86 fMinDistanceToBadChannel(0),
87 fUseDistanceToBadChannel(0),
90 fMinDistTrackToCluster(0),
91 fUseDistTrackToCluster(0),
104 fMaxDispersion(1000),
111 fHistAcceptanceCuts(NULL),
112 fHistClusterIdentificationCuts(NULL),
113 fHistClusterEtavsPhiBeforeAcc(NULL),
114 fHistClusterEtavsPhiAfterAcc(NULL),
115 fHistClusterEtavsPhiAfterQA(NULL),
116 fHistDistanceToBadChannelBeforeAcc(NULL),
117 fHistDistanceToBadChannelAfterAcc(NULL),
118 fHistClusterTimevsEBeforeQA(NULL),
119 fHistClusterTimevsEAfterQA(NULL),
120 fHistExoticCellBeforeQA(NULL),
121 fHistExoticCellAfterQA(NULL),
122 fHistNMatchedTracks(NULL),
123 fHistDistanceTrackToClusterBeforeQA(NULL),
124 fHistDistanceTrackToClusterAfterQA(NULL),
125 fHistEnergyOfClusterBeforeQA(NULL),
126 fHistEnergyOfClusterAfterQA(NULL),
127 fHistNCellsBeforeQA(NULL),
128 fHistNCellsAfterQA(NULL),
129 fHistM02BeforeQA(NULL),
130 fHistM02AfterQA(NULL),
131 fHistM20BeforeQA(NULL),
132 fHistM20AfterQA(NULL),
133 fHistDispersionBeforeQA(NULL),
134 fHistDispersionAfterQA(NULL),
135 fHistNLMBeforeQA(NULL),
136 fHistNLMAfterQA(NULL)
138 for(Int_t jj=0;jj<kNCuts;jj++){fCuts[jj]=0;}
139 fCutString=new TObjString((GetCutNumber()).Data());
142 //________________________________________________________________________
143 AliCaloPhotonCuts::AliCaloPhotonCuts(const AliCaloPhotonCuts &ref) :
144 AliAnalysisCuts(ref),
146 fClusterType(ref.fClusterType),
147 fMinEtaCut(ref.fMinEtaCut),
148 fMaxEtaCut(ref.fMaxEtaCut),
149 fUseEtaCut(ref.fUseEtaCut),
150 fMinPhiCut(ref.fMinPhiCut),
151 fMaxPhiCut(ref.fMaxPhiCut),
152 fUsePhiCut(ref.fUsePhiCut),
153 fMinDistanceToBadChannel(ref.fMinDistanceToBadChannel),
154 fUseDistanceToBadChannel(ref.fUseDistanceToBadChannel),
155 fMaxTimeDiff(ref.fMaxTimeDiff),
156 fUseTimeDiff(ref.fUseTimeDiff),
157 fMinDistTrackToCluster(ref.fMinDistTrackToCluster),
158 fUseDistTrackToCluster(ref.fUseDistTrackToCluster),
159 fExoticCell(ref.fExoticCell),
160 fUseExoticCell(ref.fUseExoticCell),
161 fMinEnergy(ref.fMinEnergy),
162 fUseMinEnergy(ref.fUseMinEnergy),
163 fMinNCells(ref.fMinNCells),
164 fUseNCells(ref.fUseNCells),
165 fMaxM02(ref.fMaxM02),
166 fMinM02(ref.fMinM02),
167 fUseM02(ref.fUseM02),
168 fMaxM20(ref.fMaxM20),
169 fMinM20(ref.fMinM20),
170 fUseM20(ref.fUseDispersion),
171 fMaxDispersion(ref.fMaxDispersion),
172 fUseDispersion(ref.fUseDispersion),
173 fMinNLM(ref.fMinNLM),
174 fMaxNLM(ref.fMaxNLM),
175 fUseNLM(ref.fUseNLM),
178 fHistAcceptanceCuts(NULL),
179 fHistClusterIdentificationCuts(NULL),
180 fHistClusterEtavsPhiBeforeAcc(NULL),
181 fHistClusterEtavsPhiAfterAcc(NULL),
182 fHistClusterEtavsPhiAfterQA(NULL),
183 fHistDistanceToBadChannelBeforeAcc(NULL),
184 fHistDistanceToBadChannelAfterAcc(NULL),
185 fHistClusterTimevsEBeforeQA(NULL),
186 fHistClusterTimevsEAfterQA(NULL),
187 fHistExoticCellBeforeQA(NULL),
188 fHistExoticCellAfterQA(NULL),
189 fHistNMatchedTracks(NULL),
190 fHistDistanceTrackToClusterBeforeQA(NULL),
191 fHistDistanceTrackToClusterAfterQA(NULL),
192 fHistEnergyOfClusterBeforeQA(NULL),
193 fHistEnergyOfClusterAfterQA(NULL),
194 fHistNCellsBeforeQA(NULL),
195 fHistNCellsAfterQA(NULL),
196 fHistM02BeforeQA(NULL),
197 fHistM02AfterQA(NULL),
198 fHistM20BeforeQA(NULL),
199 fHistM20AfterQA(NULL),
200 fHistDispersionBeforeQA(NULL),
201 fHistDispersionAfterQA(NULL),
202 fHistNLMBeforeQA(NULL),
203 fHistNLMAfterQA(NULL)
206 for(Int_t jj=0;jj<kNCuts;jj++){fCuts[jj]=ref.fCuts[jj];}
207 fCutString=new TObjString((GetCutNumber()).Data());
212 //________________________________________________________________________
213 AliCaloPhotonCuts::~AliCaloPhotonCuts() {
215 //Deleting fHistograms leads to seg fault it it's added to output collection of a task
217 // delete fHistograms;
218 // fHistograms = NULL;
219 if(fCutString != NULL){
225 //________________________________________________________________________
226 void AliCaloPhotonCuts::InitCutHistograms(TString name){
228 // Initialize Cut Histograms for QA (only initialized and filled if function is called)
229 TH1::AddDirectory(kFALSE);
231 if(fHistograms != NULL){
235 if(fHistograms==NULL){
236 fHistograms=new TList();
237 fHistograms->SetOwner(kTRUE);
238 if(name=="")fHistograms->SetName(Form("CaloCuts_%s",GetCutNumber().Data()));
239 else fHistograms->SetName(Form("%s_%s",name.Data(),GetCutNumber().Data()));
243 fHistCutIndex=new TH1F(Form("IsPhotonSelected %s",GetCutNumber().Data()),"IsPhotonSelected",5,-0.5,4.5);
244 fHistCutIndex->GetXaxis()->SetBinLabel(kPhotonIn+1,"in");
245 fHistCutIndex->GetXaxis()->SetBinLabel(kDetector+1,"detector");
246 fHistCutIndex->GetXaxis()->SetBinLabel(kAcceptance+1,"acceptance");
247 fHistCutIndex->GetXaxis()->SetBinLabel(kClusterQuality+1,"cluster QA");
248 fHistCutIndex->GetXaxis()->SetBinLabel(kPhotonOut+1,"out");
249 fHistograms->Add(fHistCutIndex);
252 fHistAcceptanceCuts=new TH1F(Form("AcceptanceCuts %s",GetCutNumber().Data()),"AcceptanceCuts",5,-0.5,4.5);
253 fHistAcceptanceCuts->GetXaxis()->SetBinLabel(1,"in");
254 fHistAcceptanceCuts->GetXaxis()->SetBinLabel(2,"eta");
255 fHistAcceptanceCuts->GetXaxis()->SetBinLabel(3,"phi");
256 fHistAcceptanceCuts->GetXaxis()->SetBinLabel(4,"distance to bad channel");
257 fHistAcceptanceCuts->GetXaxis()->SetBinLabel(5,"out");
258 fHistograms->Add(fHistAcceptanceCuts);
261 fHistClusterIdentificationCuts =new TH1F(Form("ClusterQualityCuts %s",GetCutNumber().Data()),"ClusterQualityCuts",11,-0.5,10.5);
262 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(1,"in");
263 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(2,"timing");
264 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(3,"track matching");
265 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(4,"Exotics");
266 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(5,"minimum energy");
267 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(6,"minimum NCells");
268 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(7,"M02");
269 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(8,"M20");
270 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(9,"dispersion");
271 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(10,"NLM");
272 fHistClusterIdentificationCuts->GetXaxis()->SetBinLabel(11,"out");
273 fHistograms->Add(fHistClusterIdentificationCuts);
275 // Acceptance related histogramms
276 fHistClusterEtavsPhiBeforeAcc=new TH2F(Form("EtaPhi_beforeAcceptance %s",GetCutNumber().Data()),"EtaPhi_beforeAcceptance",462,-TMath::Pi(),TMath::Pi(),110,-0.7,0.7);
277 fHistograms->Add(fHistClusterEtavsPhiBeforeAcc);
278 fHistClusterEtavsPhiAfterAcc=new TH2F(Form("EtaPhi_afterAcceptance %s",GetCutNumber().Data()),"EtaPhi_afterAcceptance",462,-TMath::Pi(),TMath::Pi(),110,-0.7,0.7);
279 fHistograms->Add(fHistClusterEtavsPhiAfterAcc);
280 fHistClusterEtavsPhiAfterQA=new TH2F(Form("EtaPhi_afterClusterQA %s",GetCutNumber().Data()),"EtaPhi_afterClusterQA",462,-TMath::Pi(),TMath::Pi(),110,-0.7,0.7);
281 fHistograms->Add(fHistClusterEtavsPhiAfterQA);
282 fHistDistanceToBadChannelBeforeAcc = new TH1F(Form("DistanceToBadChannel_beforeAcceptance %s",GetCutNumber().Data()),"DistanceToBadChannel_beforeAcceptance",200,0,40);
283 fHistograms->Add(fHistDistanceToBadChannelBeforeAcc);
284 fHistDistanceToBadChannelAfterAcc = new TH1F(Form("DistanceToBadChannel_afterAcceptance %s",GetCutNumber().Data()),"DistanceToBadChannel_afterAcceptance",200,0,40);
285 fHistograms->Add(fHistDistanceToBadChannelAfterAcc);
287 // Cluster quality related histograms
288 fHistClusterTimevsEBeforeQA=new TH2F(Form("ClusterTimeVsE_beforeClusterQA %s",GetCutNumber().Data()),"ClusterTimeVsE_beforeClusterQA",400,-10e-6,10e-6,100,0.,40);
289 fHistograms->Add(fHistClusterTimevsEBeforeQA);
290 fHistClusterTimevsEAfterQA=new TH2F(Form("ClusterTimeVsE_afterClusterQA %s",GetCutNumber().Data()),"ClusterTimeVsE_afterClusterQA",400,-10e-6,10e-6,100,0.,40);
291 fHistograms->Add(fHistClusterTimevsEAfterQA);
292 fHistExoticCellBeforeQA=new TH2F(Form("ExoticCell_beforeClusterQA %s",GetCutNumber().Data()),"ExoticCell_beforeClusterQA",400,0,40,50,0.75,1);
293 fHistograms->Add(fHistExoticCellBeforeQA);
294 fHistExoticCellAfterQA=new TH2F(Form("ExoticCell_afterClusterQA %s",GetCutNumber().Data()),"ExoticCell_afterClusterQA",400,0,40,50,0.75,1);
295 fHistograms->Add(fHistExoticCellAfterQA);
296 fHistNMatchedTracks = new TH1F(Form("NMatchedTracks_%s",GetCutNumber().Data()),"NMatchedTracks",22,-1.5,20.5);
297 fHistograms->Add(fHistNMatchedTracks);
298 fHistDistanceTrackToClusterBeforeQA = new TH1F(Form("DistanceToTrack_beforeClusterQA %s",GetCutNumber().Data()),"DistanceToTrack_beforeClusterQA",200,0,2);
299 fHistograms->Add(fHistDistanceTrackToClusterBeforeQA);
300 fHistDistanceTrackToClusterAfterQA = new TH1F(Form("DistanceToTrack_afterClusterQA %s",GetCutNumber().Data()),"DistanceToTrack_afterClusterQA",200,0,2);
301 fHistograms->Add(fHistDistanceTrackToClusterAfterQA);
302 fHistEnergyOfClusterBeforeQA = new TH1F(Form("EnergyOfCluster_beforeClusterQA %s",GetCutNumber().Data()),"EnergyOfCluster_beforeClusterQA",300,0,30);
303 fHistograms->Add(fHistEnergyOfClusterBeforeQA);
304 fHistEnergyOfClusterAfterQA = new TH1F(Form("EnergyOfCluster_afterClusterQA %s",GetCutNumber().Data()),"EnergyOfCluster_afterClusterQA",300,0,30);
305 fHistograms->Add(fHistEnergyOfClusterAfterQA);
306 fHistNCellsBeforeQA = new TH1F(Form("NCellPerCluster_beforeClusterQA %s",GetCutNumber().Data()),"NCellPerCluster_beforeClusterQA",50,0,50);
307 fHistograms->Add(fHistNCellsBeforeQA);
308 fHistNCellsAfterQA = new TH1F(Form("NCellPerCluster_afterClusterQA %s",GetCutNumber().Data()),"NCellPerCluster_afterClusterQA",50,0,50);
309 fHistograms->Add(fHistNCellsAfterQA);
310 fHistM02BeforeQA = new TH1F(Form("M02_beforeClusterQA %s",GetCutNumber().Data()),"M02_beforeClusterQA",100,0,5);
311 fHistograms->Add(fHistM02BeforeQA);
312 fHistM02AfterQA = new TH1F(Form("M02_afterClusterQA %s",GetCutNumber().Data()),"M02_afterClusterQA",100,0,5);
313 fHistograms->Add(fHistM02AfterQA);
314 fHistM20BeforeQA = new TH1F(Form("M20_beforeClusterQA %s",GetCutNumber().Data()),"M20_beforeClusterQA",100,0,2.5);
315 fHistograms->Add(fHistM20BeforeQA);
316 fHistM20AfterQA = new TH1F(Form("M20_afterClusterQA %s",GetCutNumber().Data()),"M20_afterClusterQA",100,0,2.5);
317 fHistograms->Add(fHistM20AfterQA);
318 fHistDispersionBeforeQA = new TH1F(Form("Dispersion_beforeClusterQA %s",GetCutNumber().Data()),"Dispersion_beforeClusterQA",100,0,4);
319 fHistograms->Add(fHistDispersionBeforeQA);
320 fHistDispersionAfterQA = new TH1F(Form("Dispersion_afterClusterQA %s",GetCutNumber().Data()),"Dispersion_afterClusterQA",100,0,4);
321 fHistograms->Add(fHistDispersionAfterQA);
322 fHistNLMBeforeQA = new TH1F(Form("NLM_beforeClusterQA %s",GetCutNumber().Data()),"NLM_beforeClusterQA",10,0,10);
323 fHistograms->Add(fHistNLMBeforeQA);
324 fHistNLMAfterQA = new TH1F(Form("NLM_afterClusterQA %s",GetCutNumber().Data()),"NLM_afterClusterQA",10,0,10);
325 fHistograms->Add(fHistNLMAfterQA);
327 TH1::AddDirectory(kTRUE);
331 ///________________________________________________________________________
332 Bool_t AliCaloPhotonCuts::ClusterIsSelectedMC(TParticle *particle,AliStack *fMCStack){
333 // MonteCarlo Photon Selection
335 if(!fMCStack)return kFALSE;
337 if (particle->GetPdgCode() == 22){
339 if ( particle->Eta() < fMinEtaCut || particle->Eta() > fMaxEtaCut ) return kFALSE;
340 if ( particle->Phi() < fMinPhiCut || particle->Phi() > fMaxPhiCut ) return kFALSE;
342 if(particle->GetMother(0) >-1 && fMCStack->Particle(particle->GetMother(0))->GetPdgCode() == 22){
343 return kFALSE; // no photon as mothers!
345 if(particle->GetMother(0) >= fMCStack->GetNprimary()){
346 return kFALSE; // the gamma has a mother, and it is not a primary particle
352 ///________________________________________________________________________
353 Bool_t AliCaloPhotonCuts::ClusterIsSelectedAODMC(AliAODMCParticle *particle,TClonesArray *aodmcArray){
354 // MonteCarlo Photon Selection
356 if(!aodmcArray)return kFALSE;
357 if (particle->GetPdgCode() == 22){
358 if ( particle->Eta() < fMinEtaCut || particle->Eta() > fMaxEtaCut ) return kFALSE;
359 if ( particle->Phi() < fMinPhiCut || particle->Phi() > fMaxPhiCut ) return kFALSE;
360 if(particle->GetMother() > -1){
361 if((static_cast<AliAODMCParticle*>(aodmcArray->At(particle->GetMother())))->GetPdgCode() == 22){
362 return kFALSE; // no photon as mothers!
364 if(!(static_cast<AliAODMCParticle*>(aodmcArray->At(particle->GetMother()))->IsPrimary())){
365 return kFALSE; // the gamma has a mother, and it is not a primary particle
368 return kTRUE; // return in case of accepted gamma
375 ///________________________________________________________________________
376 // This function selects the clusters based on their quality criteria
377 ///________________________________________________________________________
378 Bool_t AliCaloPhotonCuts::ClusterQualityCuts(AliVCluster* cluster, AliVEvent *event, Bool_t isMC)
379 { // Specific Photon Cuts
382 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex);
385 // Double_t minR = 999.0;
386 // get the minimum radius of tracks to cluster
387 // if(fHistDistanceTrackToClusterBeforeQA || fHistDistanceTrackToClusterAfterQA){
389 // cluster->GetPosition(pos); // Get cluster position
392 // int NtrMatched = 0;
393 // NtrMatched = cluster->GetNTracksMatched();
394 // fHistNMatchedTracks->Fill(NtrMatched);
395 // //loop over tracks for Jet QA
396 // TList *l = event->GetList();
397 // TClonesArray *tracks = dynamic_cast<TClonesArray*>(l->FindObject("Tracks"));
398 // for(int itrack = 0; itrack < NtrMatched; itrack++){
399 // AliVTrack *trackcluster = static_cast<AliVTrack*>(tracks->At(itrack));
400 // if (! trackcluster) {
401 // AliError(Form("Couldn't get ESD track %d\n", itrack));
404 // Double_t dphi = -999.0;
405 // Double_t deta = -999.0;
406 // AliPicoTrack::GetEtaPhiDiff(trackcluster, cluster, dphi, deta);
407 // cout << "here" << endl;
408 // Double_t dr = sqrt(dphi*dphi + deta+deta);
411 // }//loop over tracks
414 // Fill Histos before Cuts
415 if(fHistClusterTimevsEBeforeQA) fHistClusterTimevsEBeforeQA->Fill(cluster->GetTOF(), cluster->E());
416 // if(fHistExoticCellBeforeQA) fHistExoticCellBeforeQA->Fill(cluster->E(), );
417 // if(fHistDistanceTrackToClusterBeforeQA) fHistDistanceTrackToClusterBeforeQA->Fill(minR);
418 if(fHistEnergyOfClusterBeforeQA) fHistEnergyOfClusterBeforeQA->Fill(cluster->E());
419 if(fHistNCellsBeforeQA) fHistNCellsBeforeQA->Fill(cluster->GetNCells());
420 if(fHistM02BeforeQA) fHistM02BeforeQA->Fill(cluster->GetM02());
421 if(fHistM20BeforeQA) fHistM20BeforeQA->Fill(cluster->GetM20());
422 if(fHistDispersionBeforeQA) fHistDispersionBeforeQA->Fill(cluster->GetDispersion());
423 // if(fHistNLMBeforeQA) fHistNLMBeforeQA->Fill(cluster->GetNExMax());
425 // Check wether timing is ok
427 if(abs(cluster->GetTOF()) > fMaxTimeDiff && !isMC){
428 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //1
432 cutIndex++; //2, next cut
434 // Minimum distance to track
435 // if (fUseDistTrackToCluster){
437 // cluster->GetPosition(pos); // Get cluster position
439 // int NtrMatched = 0;
440 // NtrMatched = cluster->GetNTracksMatched();
441 // fHistNMatchedTracks->Fill(NtrMatched);
442 // if(NtrMatched > 0){
443 // //loop over tracks for QA
444 // TList *l = event->GetList();
445 // TClonesArray *tracks = dynamic_cast<TClonesArray*>(l->FindObject("Tracks"));
447 // Double_t dphi = 999.0;
448 // Double_t deta = 999.0;
449 // Double_t dr2 = 999.0;
451 // for(int itrack = 0; itrack < NtrMatched; itrack++){
452 // AliVTrack *trackcluster = NULL;
453 // trackcluster = static_cast<AliVTrack*>(tracks->At(itrack));
454 // if (! trackcluster) {
455 // AliError(Form("Couldn't get ESD track %d\n", itrack));
458 // AliPicoTrack::GetEtaPhiDiff(trackcluster, cluster, dphi, deta);
459 // dr2 = dphi*dphi + deta+deta;
460 // //cout << dr << endl;
461 // if(dr2 < fMinDistTrackToCluster*fMinDistTrackToCluster){
462 // // if(dphi < fMinDistTrackToCluster || deta < fMinDistTrackToCluster){
463 // if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //2
467 // }//loop over tracks
469 // // if(cluster->GetEmcCpvDistance() < fMinDistTrackToCluster){
470 // // if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //2
474 cutIndex++;//3, next cut
476 // exotic cell cut --IMPLEMENT LATER---
477 // if(!AcceptanceCuts(photon)){
478 // if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //3
481 cutIndex++; //4, next cut
483 // minimum cell energy cut
485 if(cluster->E() < fMinEnergy){
486 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //4
490 cutIndex++; //5, next cut
492 // minimum number of cells
494 if(cluster->GetNCells() < fMinNCells) {
495 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //5
499 cutIndex++; //6, next cut
503 if( cluster->GetM02()< fMinM02 || cluster->GetM02() > fMaxM02 ) {
504 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //6
508 cutIndex++; //7, next cut
512 if( cluster->GetM20()< fMinM20 || cluster->GetM20() > fMaxM20 ) {
513 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //7
517 cutIndex++; //8, next cut
521 if( cluster->GetDispersion()> fMaxDispersion) {
522 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //8
526 cutIndex++; //9, next cut
528 // NLM cut --IMPLEMENT LATER---
530 // if( cluster->GetDispersion()> fMaxDispersion) {
531 // if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //9
535 cutIndex++; //9, next cut
537 // DONE with selecting photons
538 if(fHistClusterIdentificationCuts)fHistClusterIdentificationCuts->Fill(cutIndex); //10
541 Double_t vertex[3] = {0};
542 event->GetPrimaryVertex()->GetXYZ(vertex);
543 // TLorentzvector with cluster
544 TLorentzVector clusterVector;
545 cluster->GetMomentum(clusterVector,vertex);
546 Double_t etaCluster = clusterVector.Eta();
547 Double_t phiCluster = clusterVector.Phi();
549 if(fHistClusterEtavsPhiAfterQA) fHistClusterEtavsPhiAfterQA->Fill(phiCluster,etaCluster);
550 if(fHistClusterTimevsEAfterQA) fHistClusterTimevsEAfterQA->Fill(cluster->GetTOF(), cluster->E());
551 // if(fHistExoticCellAfterQA) fHistExoticCellAfterQA->Fill(cluster->E(), );
552 // if(fHistDistanceTrackToClusterAfterQA) fHistDistanceTrackToClusterAfterQA->Fill(minR);
553 if(fHistEnergyOfClusterAfterQA) fHistEnergyOfClusterAfterQA->Fill(cluster->E());
554 if(fHistNCellsAfterQA) fHistNCellsAfterQA->Fill(cluster->GetNCells());
555 if(fHistM02AfterQA) fHistM02AfterQA->Fill(cluster->GetM02());
556 if(fHistM20AfterQA) fHistM20AfterQA->Fill(cluster->GetM20());
557 if(fHistDispersionAfterQA) fHistDispersionAfterQA->Fill(cluster->GetDispersion());
558 // if(fHistNLMBeforeQA) fHistNLMAfterQA->Fill(cluster->GetNExMax());
565 ///________________________________________________________________________
566 Bool_t AliCaloPhotonCuts::ClusterIsSelected(AliVCluster *cluster, AliVEvent * event, Bool_t isMC)
568 //Selection of Reconstructed photon clusters with Calorimeters
570 FillClusterCutIndex(kPhotonIn);
572 Double_t vertex[3] = {0};
573 event->GetPrimaryVertex()->GetXYZ(vertex);
574 // TLorentzvector with cluster
575 TLorentzVector clusterVector;
576 cluster->GetMomentum(clusterVector,vertex);
577 Double_t etaCluster = clusterVector.Eta();
578 Double_t phiCluster = clusterVector.Phi();
580 // Histos before cuts
581 if(fHistClusterEtavsPhiBeforeAcc) fHistClusterEtavsPhiBeforeAcc->Fill(phiCluster,etaCluster);
583 // Cluster Selection - 0= accept any calo cluster
584 if (fClusterType > 0){
585 //Select EMCAL cluster
586 if (fClusterType == 1 && !cluster->IsEMCAL()){
587 FillClusterCutIndex(kDetector);
590 //Select PHOS cluster
591 if (fClusterType == 2 && !cluster->IsPHOS()){
592 FillClusterCutIndex(kDetector);
598 if(!AcceptanceCuts(cluster,event)){
599 FillClusterCutIndex(kAcceptance);
602 // Cluster Quality Cuts
603 if(!ClusterQualityCuts(cluster,event,isMC)){
604 FillClusterCutIndex(kClusterQuality);
608 // Photon passed cuts
609 FillClusterCutIndex(kPhotonOut);
614 ///________________________________________________________________________
615 Bool_t AliCaloPhotonCuts::AcceptanceCuts(AliVCluster *cluster, AliVEvent* event)
617 // Exclude certain areas for photon reconstruction
620 if(fHistAcceptanceCuts)fHistAcceptanceCuts->Fill(cutIndex);
624 Double_t vertex[3] = {0};
625 event->GetPrimaryVertex()->GetXYZ(vertex);
626 // TLorentzvector with cluster
627 TLorentzVector clusterVector;
628 cluster->GetMomentum(clusterVector,vertex);
629 Double_t etaCluster = clusterVector.Eta();
630 Double_t phiCluster = clusterVector.Phi();
634 if (etaCluster < fMinEtaCut || etaCluster > fMaxEtaCut){
635 if(fHistAcceptanceCuts)fHistAcceptanceCuts->Fill(cutIndex);
643 if (phiCluster < fMinPhiCut || phiCluster > fMaxEtaCut){
644 if(fHistAcceptanceCuts)fHistAcceptanceCuts->Fill(cutIndex);
650 // check distance to bad channel
651 if (fUseDistanceToBadChannel){
652 if (cluster->GetDistanceToBadChannel() < fMinDistanceToBadChannel){
653 if(fHistAcceptanceCuts)fHistAcceptanceCuts->Fill(cutIndex);
658 if(fHistAcceptanceCuts)fHistAcceptanceCuts->Fill(cutIndex);
661 if(fHistClusterEtavsPhiAfterAcc) fHistClusterEtavsPhiAfterAcc->Fill(phiCluster,etaCluster);
666 Bool_t AliCaloPhotonCuts::MatchConvPhotonToCluster(AliAODConversionPhoton* convPhoton, AliVCluster* cluster, AliVEvent* event ){
668 if (!fUseDistTrackToCluster) return kFALSE;
670 AliESDEvent *esdev = dynamic_cast<AliESDEvent*>(event);
671 AliAODEvent *aodev = 0;
673 aodev = dynamic_cast<AliAODEvent*>(event);
675 AliError("Task needs AOD or ESD event, returning");
680 // cout << "Got the event" << endl;
682 Double_t vertex[3] = {0};
683 event->GetPrimaryVertex()->GetXYZ(vertex);
684 // TLorentzvector with cluster
685 TLorentzVector clusterVector;
686 cluster->GetMomentum(clusterVector,vertex);
687 Double_t etaCluster = clusterVector.Eta();
688 Double_t phiCluster = clusterVector.Phi();
690 Bool_t matched = kFALSE;
691 for (Int_t i = 0; i < 2; i++){
692 Int_t tracklabel = convPhoton->GetLabel(i);
693 AliVTrack *inTrack = 0x0;
695 if(tracklabel > event->GetNumberOfTracks() ) continue;
696 inTrack = esdev->GetTrack(tracklabel);
698 if(((AliV0ReaderV1*)AliAnalysisManager::GetAnalysisManager()->GetTask("V0ReaderV1"))->AreAODsRelabeled()){
699 inTrack = dynamic_cast<AliVTrack*>(event->GetTrack(tracklabel));
701 for(Int_t ii=0; ii<event->GetNumberOfTracks(); ii++) {
702 inTrack = dynamic_cast<AliVTrack*>(event->GetTrack(ii));
704 if(inTrack->GetID() == tracklabel) {
711 // cout << "found track " << endl;
712 // AliVTrack *outTrack = 0x00;
714 // outTrack = new AliESDtrack(*((AliESDtrack*)inTrack));
716 // outTrack = new AliAODTrack(*((AliAODTrack*)inTrack));
720 Bool_t propagated = AliEMCALRecoUtils::ExtrapolateTrackToEMCalSurface(inTrack,440, 0.000510999,20,0.05);
722 // cout << "Track "<< i << "\t"<< inTrack->GetTrackPhiOnEMCal() << "\t" << inTrack->GetTrackEtaOnEMCal() << endl;
723 // cout << "Cluster " << phiCluster << "\t" << etaCluster << endl;
724 Double_t dPhi = abs(phiCluster-inTrack->GetTrackPhiOnEMCal());
725 Double_t dEta = abs(etaCluster-inTrack->GetTrackEtaOnEMCal());
727 Double_t dR2 = dPhi*dPhi + dEta+dEta;
728 // cout << "distance to cluster \t" << sqrt(dR2) << endl;
729 if (fHistDistanceTrackToClusterBeforeQA)fHistDistanceTrackToClusterBeforeQA->Fill(sqrt(dR2));
730 if(dR2 < fMinDistTrackToCluster*fMinDistTrackToCluster){
732 if (fHistDistanceTrackToClusterAfterQA)fHistDistanceTrackToClusterAfterQA->Fill(sqrt(dR2));
739 //____________________________________________________________________________________________
742 ///________________________________________________________________________
743 Bool_t AliCaloPhotonCuts::UpdateCutString() {
744 ///Update the cut string (if it has been created yet)
746 if(fCutString && fCutString->GetString().Length() == kNCuts) {
747 fCutString->SetString(GetCutNumber());
754 ///________________________________________________________________________
755 Bool_t AliCaloPhotonCuts::InitializeCutsFromCutString(const TString analysisCutSelection ) {
756 // Initialize Cuts from a given Cut string
757 AliInfo(Form("Set CaloCut Number: %s",analysisCutSelection.Data()));
758 if(analysisCutSelection.Length()!=kNCuts) {
759 AliError(Form("Cut selection has the wrong length! size is %d, number of cuts is %d", analysisCutSelection.Length(), kNCuts));
762 if(!analysisCutSelection.IsDigit()){
763 AliError("Cut selection contains characters");
767 const char *cutSelection = analysisCutSelection.Data();
768 #define ASSIGNARRAY(i) fCuts[i] = cutSelection[i] - '0'
769 for(Int_t ii=0;ii<kNCuts;ii++){
773 // Set Individual Cuts
774 for(Int_t ii=0;ii<kNCuts;ii++){
775 if(!SetCut(cutIds(ii),fCuts[ii]))return kFALSE;
777 PrintCutsWithValues();
781 ///________________________________________________________________________
782 Bool_t AliCaloPhotonCuts::SetCut(cutIds cutID, const Int_t value) {
783 ///Set individual cut ID
788 if( SetClusterTypeCut(value)) {
789 fCuts[kClusterType] = value;
792 } else return kFALSE;
795 if( SetMinEtaCut(value)) {
796 fCuts[kEtaMin] = value;
799 } else return kFALSE;
802 if( SetMaxEtaCut(value)) {
803 fCuts[kEtaMax] = value;
806 } else return kFALSE;
809 if( SetMinPhiCut(value)) {
810 fCuts[kPhiMin] = value;
813 } else return kFALSE;
816 if( SetMaxPhiCut(value)) {
817 fCuts[kPhiMax] = value;
820 } else return kFALSE;
822 case kDistanceToBadChannel:
823 if( SetDistanceToBadChannelCut(value)) {
824 fCuts[kDistanceToBadChannel] = value;
827 } else return kFALSE;
830 if( SetTimingCut(value)) {
831 fCuts[kTiming] = value;
834 } else return kFALSE;
837 if( SetTrackMatchingCut(value)) {
838 fCuts[kTrackMatching] = value;
841 } else return kFALSE;
844 if( SetExoticCellCut(value)) {
845 fCuts[kExoticCell] = value;
848 } else return kFALSE;
851 if( SetMinEnergyCut(value)) {
852 fCuts[kMinEnery] = value;
855 } else return kFALSE;
858 if( SetMinNCellsCut(value)) {
859 fCuts[kNMinCells] = value;
862 } else return kFALSE;
865 if( SetMinM02(value)) {
866 fCuts[kMinM02] = value;
869 } else return kFALSE;
872 if( SetMaxM02(value)) {
873 fCuts[kMaxM02] = value;
876 } else return kFALSE;
879 if( SetMinM20(value)) {
880 fCuts[kMinM20] = value;
883 } else return kFALSE;
886 if( SetMaxM20(value)) {
887 fCuts[kMaxM20] = value;
890 } else return kFALSE;
893 if( SetDispersion(value)) {
894 fCuts[kDispersion] = value;
897 } else return kFALSE;
904 } else return kFALSE;
907 AliError("Cut id out of range");
911 AliError("Cut id %d not recognized");
916 ///________________________________________________________________________
917 void AliCaloPhotonCuts::PrintCuts() {
918 // Print out current Cut Selection
919 for(Int_t ic = 0; ic < kNCuts; ic++) {
920 printf("%-30s : %d \n", fgkCutNames[ic], fCuts[ic]);
924 void AliCaloPhotonCuts::PrintCutsWithValues() {
925 // Print out current Cut Selection with value
926 printf("\nCluster cutnumber \n");
927 for(Int_t ic = 0; ic < kNCuts; ic++) {
928 printf("%d",fCuts[ic]);
932 printf("Acceptance cuts: \n");
933 if (fClusterType == 0) printf("\tall calorimeter clusters are used\n");
934 if (fClusterType == 1) printf("\tEMCAL calorimeter clusters are used\n");
935 if (fClusterType == 2) printf("\tPHOS calorimeter clusters are used\n");
936 if (fUseEtaCut) printf("\t%3.2f < eta_{cluster} < %3.2f\n", fMinEtaCut, fMaxEtaCut );
937 if (fUsePhiCut) printf("\t%3.2f < phi_{cluster} < %3.2f\n", fMinPhiCut, fMaxPhiCut );
938 if (fUseDistanceToBadChannel) printf("\tcut on exotics applied \n");
940 printf("Cluster Quality cuts: \n");
941 if (fUseTimeDiff) printf("\t time difference < %3.2f\n", fMaxTimeDiff );
942 if (fUseDistTrackToCluster) printf("\tmin distance to track > %3.2f\n", fMinDistTrackToCluster );
943 if (fUseExoticCell)printf("\t min distance to track > %3.2f\n", fMinDistTrackToCluster );
944 if (fUseMinEnergy)printf("\t E_{cluster} > %3.2f\n", fMinEnergy );
945 if (fUseNCells) printf("\t number of cells per cluster > %d\n", fMinNCells );
946 if (fUseM02) printf("\t %3.2f < M02 < %3.2f\n", fMinM02, fMaxM02 );
947 if (fUseM20) printf("\t %3.2f < M20 < %3.2f\n", fMinM20, fMaxM20 );
948 if (fUseDispersion) printf("\t dispersion < %3.2f\n", fMaxDispersion );
949 if (fUseNLM) printf("\t %d < NLM < %d\n", fMinNLM, fMaxNLM );
953 // EMCAL acceptance 2011
954 // 1.39626, 3.125 (phi)
958 ///________________________________________________________________________
959 Bool_t AliCaloPhotonCuts::SetClusterTypeCut(Int_t clusterType)
962 case 0: // all clusters
965 case 1: // EMCAL clusters
968 case 2: // PHOS clusters
972 AliError(Form("ClusterTypeCut not defined %d",clusterType));
978 //___________________________________________________________________
979 Bool_t AliCaloPhotonCuts::SetMinEtaCut(Int_t minEta)
983 if (!fUseEtaCut) fUseEtaCut=0;
987 if (!fUseEtaCut) fUseEtaCut=1;
991 if (!fUseEtaCut) fUseEtaCut=1;
995 if (!fUseEtaCut) fUseEtaCut=1;
999 AliError(Form("MinEta Cut not defined %d",minEta));
1006 //___________________________________________________________________
1007 Bool_t AliCaloPhotonCuts::SetMaxEtaCut(Int_t maxEta)
1011 if (!fUseEtaCut) fUseEtaCut=0;
1015 if (!fUseEtaCut) fUseEtaCut=1;
1019 if (!fUseEtaCut) fUseEtaCut=1;
1023 if (!fUseEtaCut) fUseEtaCut=1;
1027 AliError(Form("MaxEta Cut not defined %d",maxEta));
1033 //___________________________________________________________________
1034 Bool_t AliCaloPhotonCuts::SetMinPhiCut(Int_t minPhi)
1038 if (!fUsePhiCut) fUsePhiCut=0;
1042 if (!fUsePhiCut) fUsePhiCut=1;
1046 AliError(Form("MinPhi Cut not defined %d",minPhi));
1052 //___________________________________________________________________
1053 Bool_t AliCaloPhotonCuts::SetMaxPhiCut(Int_t maxPhi)
1057 if (!fUsePhiCut) fUsePhiCut=0;
1061 if (!fUsePhiCut) fUsePhiCut=1;
1065 AliError(Form("Max Phi Cut not defined %d",maxPhi));
1071 //___________________________________________________________________
1072 Bool_t AliCaloPhotonCuts::SetDistanceToBadChannelCut(Int_t distanceToBadChannel)
1074 switch(distanceToBadChannel){
1076 fUseDistanceToBadChannel=0;
1077 fMinDistanceToBadChannel=0;
1080 if (!fUseDistanceToBadChannel) fUseDistanceToBadChannel=1;
1081 fMinDistanceToBadChannel=5;
1084 AliError(Form("minimum distance to bad channel Cut not defined %d",distanceToBadChannel));
1090 //___________________________________________________________________
1091 Bool_t AliCaloPhotonCuts::SetTimingCut(Int_t timing)
1099 if (!fUseTimeDiff) fUseTimeDiff=1;
1100 fMaxTimeDiff=10e-7; //1000ns
1103 if (!fUseTimeDiff) fUseTimeDiff=1;
1104 fMaxTimeDiff=50e-8; //500ns
1107 if (!fUseTimeDiff) fUseTimeDiff=1;
1108 fMaxTimeDiff=20e-8; //200ns
1111 if (!fUseTimeDiff) fUseTimeDiff=1;
1112 fMaxTimeDiff=10e-8; //100ns
1115 if (!fUseTimeDiff) fUseTimeDiff=1;
1116 fMaxTimeDiff=50e-9; //50ns
1120 AliError(Form("Timing Cut not defined %d",timing));
1126 //___________________________________________________________________
1127 Bool_t AliCaloPhotonCuts::SetTrackMatchingCut(Int_t trackMatching)
1129 switch(trackMatching){
1131 fUseDistTrackToCluster=0;
1132 fMinDistTrackToCluster=0;
1135 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1136 fMinDistTrackToCluster=0.04;
1139 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1140 fMinDistTrackToCluster=0.05;
1143 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1144 fMinDistTrackToCluster=0.1;
1147 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1148 fMinDistTrackToCluster=0.13;
1151 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1152 fMinDistTrackToCluster=0.15;
1155 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1156 fMinDistTrackToCluster=0.2;
1159 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1160 fMinDistTrackToCluster=0.3;
1163 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1164 fMinDistTrackToCluster=0.4;
1167 if (!fUseDistTrackToCluster) fUseDistTrackToCluster=1;
1168 fMinDistTrackToCluster=0.5;
1172 AliError(Form("Track Matching Cut not defined %d",trackMatching));
1178 //___________________________________________________________________
1179 Bool_t AliCaloPhotonCuts::SetExoticCellCut(Int_t exoticCell)
1187 if (!fUseExoticCell) fUseExoticCell=1;
1191 AliError(Form("Exotic cell Cut not defined %d",exoticCell));
1197 //___________________________________________________________________
1198 Bool_t AliCaloPhotonCuts::SetMinEnergyCut(Int_t minEnergy)
1202 if (!fUseMinEnergy) fUseMinEnergy=0;
1206 if (!fUseMinEnergy) fUseMinEnergy=1;
1210 if (!fUseMinEnergy) fUseMinEnergy=1;
1214 if (!fUseMinEnergy) fUseMinEnergy=1;
1218 if (!fUseMinEnergy) fUseMinEnergy=1;
1222 if (!fUseMinEnergy) fUseMinEnergy=1;
1226 if (!fUseMinEnergy) fUseMinEnergy=1;
1230 if (!fUseMinEnergy) fUseMinEnergy=1;
1234 if (!fUseMinEnergy) fUseMinEnergy=1;
1238 if (!fUseMinEnergy) fUseMinEnergy=1;
1242 AliError(Form("Minimum Energy Cut not defined %d",minEnergy));
1248 //___________________________________________________________________
1249 Bool_t AliCaloPhotonCuts::SetMinNCellsCut(Int_t minNCells)
1253 if (!fUseNCells) fUseNCells=0;
1257 if (!fUseNCells) fUseNCells=1;
1261 if (!fUseNCells) fUseNCells=1;
1265 if (!fUseNCells) fUseNCells=1;
1269 if (!fUseNCells) fUseNCells=1;
1273 if (!fUseNCells) fUseNCells=1;
1277 if (!fUseNCells) fUseNCells=1;
1282 AliError(Form("Min N cells Cut not defined %d",minNCells));
1288 //___________________________________________________________________
1289 Bool_t AliCaloPhotonCuts::SetMaxM02(Int_t maxM02)
1293 if (!fUseM02) fUseM02=0;
1297 if (!fUseM02) fUseM02=1;
1301 if (!fUseM02) fUseM02=1;
1305 if (!fUseM02) fUseM02=1;
1309 if (!fUseM02) fUseM02=1;
1313 AliError(Form("Max M02 Cut not defined %d",maxM02));
1319 //___________________________________________________________________
1320 Bool_t AliCaloPhotonCuts::SetMinM02(Int_t minM02)
1324 if (!fUseM02) fUseM02=0;
1328 if (!fUseM02) fUseM02=1;
1332 AliError(Form("Min M02 not defined %d",minM02));
1338 //___________________________________________________________________
1339 Bool_t AliCaloPhotonCuts::SetMaxM20(Int_t maxM20)
1343 if (!fUseM20) fUseM20=0;
1347 if (!fUseM20) fUseM20=1;
1351 AliError(Form("Max M20 Cut not defined %d",maxM20));
1357 //___________________________________________________________________
1358 Bool_t AliCaloPhotonCuts::SetMinM20(Int_t minM20)
1362 if (!fUseM20) fUseM20=0;
1366 if (!fUseM20) fUseM20=1;
1370 AliError(Form("Min M20 Cut not defined %d",minM20));
1376 //___________________________________________________________________
1377 Bool_t AliCaloPhotonCuts::SetDispersion(Int_t dispersion)
1381 if (!fUseDispersion) fUseDispersion=0;
1382 fMaxDispersion =100;
1385 if (!fUseDispersion) fUseDispersion=1;
1389 AliError(Form("Maximum Dispersion Cut not defined %d",dispersion));
1395 //___________________________________________________________________
1396 Bool_t AliCaloPhotonCuts::SetNLM(Int_t nlm)
1400 if (!fUseNLM) fUseNLM=0;
1405 if (!fUseNLM) fUseNLM=1;
1410 AliError(Form("NLM Cut not defined %d",nlm));
1416 ///________________________________________________________________________
1417 TString AliCaloPhotonCuts::GetCutNumber(){
1418 // returns TString with current cut number
1420 for(Int_t ii=0;ii<kNCuts;ii++){
1421 a.Append(Form("%d",fCuts[ii]));