]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGJE/EMCALJetTasks/UserTasks/AliAnalysisTaskJetMatching.cxx
added pdet-ppart over ppart histogram for detector response
[u/mrichter/AliRoot.git] / PWGJE / EMCALJetTasks / UserTasks / AliAnalysisTaskJetMatching.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // 
17 // General task to match two sets of jets
18 //
19 // This task takes two TClonesArray's as input: 
20 // [1] fSourceJets - e.g. pythia jets
21 // [2] fTargetJets - e.g. a samle containing pythia jets embedded in a pbpb event
22 // the task will try to match jets from the source array to the target array, and
23 // save the found TARGET jets in a new array 'fMatchedJets'
24 // the purpose of this task is twofold
25 // [1] matching for embedding studies
26 // [2] matching to create a detector response function
27 //
28 // matching is done in three steps
29 // [1] geometric matching, where jets are matched by R = sqrt(dphi*dphi-deta*deta) or directly via dphi and deta
30 // [2] optional injection / bijection check 
31 //     in this check, it is made sure that fSourceJets -> fMatchedJets is either an injective non-surjective 
32 //     or bijective map, depending on the matching resolution which is chosen for step [1]
33 //     so that each source jet has a unique target and vice-versa.
34 //     if R (or dphi, deta) are proportional to, or larger than, the jet radius, matching tends to be 
35 //     bijective (each source has a target), if R is chosen to be very small, source jets might be lost 
36 //     as no target can be found.
37 //     the mapping is done in such a way that each target is matched to its closest source and each source
38 //     is mapped to its closest target
39 // [3] constituent matching
40 //     - how many constituents of the source jet are present in the matched jet? 
41 //       a cut on the constituent fraction can be performed (not recommended)
42 //     - how much of the original pt is recovered in the matched jet? 
43 //       a cut on the fraction of recovered / original pt can be performed (recommended)
44 //
45 // detector response
46 //     to obtain a detector respose function, supply
47 // [1] fSourceJets - particle level jets
48 // [2] fTargetJets - detector level jets
49 // 
50 // Author: Redmer Alexander Bertens, Utrecht Univeristy, Utrecht, Netherlands
51 // rbertens@cern.ch, rbertens@nikhef.nl, r.a.bertens@uu.nl 
52
53 // root includes
54 #include <TClonesArray.h>
55 #include <TChain.h>
56 #include <TMath.h>
57 #include <TF1.h>
58 #include <TF2.h>
59 #include <TH1F.h>
60 #include <TH2F.h>
61 #include <TProfile.h>
62 // aliroot includes
63 #include <AliAnalysisTask.h>
64 #include <AliAnalysisManager.h>
65 #include <AliLog.h>
66 #include <AliVEvent.h>
67 #include <AliVParticle.h>
68 // emcal jet framework includes
69 #include <AliEmcalJet.h>
70 #include <AliAnalysisTaskJetMatching.h>
71 #include <AliLocalRhoParameter.h>
72
73 class AliAnalysisTaskJetMatching;
74 using namespace std;
75
76 ClassImp(AliAnalysisTaskJetMatching)
77
78 AliAnalysisTaskJetMatching::AliAnalysisTaskJetMatching() : AliAnalysisTaskEmcalJet("AliAnalysisTaskJetMatching", kTRUE), 
79     fDebug(0), fSourceJets(0), fSourceJetsName(0), fTargetJets(0), fTargetJetsName(0), fMatchedJets(0), fMatchedJetsName(GetName()), fSourceRho(0), fSourceRhoName(0), fTargetRho(0), fTargetRhoName(0), fUseScaledRho(0), fSourceRadius(0.3), fTargetRadius(0.3), fMatchingScheme(kGeoEtaPhi), fUseEmcalBaseJetCuts(kFALSE), fSourceBKG(kNoSourceBKG), fTargetBKG(kNoTargetBKG), fOutputList(0), fHistUnsortedCorrelation(0), fHistMatchedCorrelation(0), fHistSourceJetPt(0), fHistMatchedSourceJetPt(0), fHistTargetJetPt(0), fHistMatchedJetPt(0), fHistSourceMatchedJetPt(0), fHistDetectorResponseProb(0), fHistNoConstSourceJet(0), fHistNoConstTargetJet(0), fHistNoConstMatchJet(0), fProfFracPtMatched(0), fProfFracPtJets(0), fProfFracNoMatched(0), fProfFracNoJets(0), fHistAnalysisSummary(0), fProfQAMatched(0), fProfQA(0), fNoMatchedJets(200), fMatchEta(.3), fMatchPhi(.3), fMatchR(.08), fDoDetectorResponse(kFALSE), fMatchConstituents(kTRUE), fMinFracRecoveredConstituents(.5), fMinFracRecoveredConstituentPt(0.5), fGetBijection(kTRUE) {
80     // default constructor
81     ClearMatchedJetsCache();
82 }
83 //_____________________________________________________________________________
84 AliAnalysisTaskJetMatching::AliAnalysisTaskJetMatching(const char* name) : AliAnalysisTaskEmcalJet(name, kTRUE),
85     fDebug(0), fSourceJets(0), fSourceJetsName(0), fTargetJets(0), fTargetJetsName(0), fMatchedJets(0), fMatchedJetsName(GetName()), fSourceRho(0), fSourceRhoName(0), fTargetRho(0), fTargetRhoName(0), fUseScaledRho(0), fSourceRadius(0.3), fTargetRadius(0.3), fMatchingScheme(kGeoEtaPhi), fUseEmcalBaseJetCuts(kFALSE), fSourceBKG(kNoSourceBKG), fTargetBKG(kNoTargetBKG), fOutputList(0), fHistUnsortedCorrelation(0), fHistMatchedCorrelation(0), fHistSourceJetPt(0), fHistMatchedSourceJetPt(0), fHistTargetJetPt(0), fHistMatchedJetPt(0), fHistSourceMatchedJetPt(0), fHistDetectorResponseProb(0), fHistNoConstSourceJet(0), fHistNoConstTargetJet(0), fHistNoConstMatchJet(0), fProfFracPtMatched(0), fProfFracPtJets(0), fProfFracNoMatched(0), fProfFracNoJets(0), fHistAnalysisSummary(0), fProfQAMatched(0), fProfQA(0), fNoMatchedJets(200), fMatchEta(.3), fMatchPhi(.3), fMatchR(.08), fDoDetectorResponse(kFALSE), fMatchConstituents(kTRUE), fMinFracRecoveredConstituents(0.5), fMinFracRecoveredConstituentPt(0.5), fGetBijection(kTRUE) {
86     // constructor
87     ClearMatchedJetsCache();
88     DefineInput(0, TChain::Class());
89     DefineOutput(1, TList::Class());
90 }
91 //_____________________________________________________________________________
92 AliAnalysisTaskJetMatching::~AliAnalysisTaskJetMatching()
93 {
94     // destructor
95     if(fOutputList)             delete fOutputList;
96 }
97 //_____________________________________________________________________________
98 void AliAnalysisTaskJetMatching::ExecOnce() 
99 {
100     // initialize the anaysis
101     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
102     // get the stand alone jets from the input event
103     fSourceJets = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(fSourceJetsName.Data()));
104     if(!fSourceJets) AliFatal(Form("%s: Container with name %s not found. Aborting", GetName(), fSourceJetsName.Data()));
105     fTargetJets = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(fTargetJetsName.Data()));
106     if(!fTargetJets) AliFatal(Form("%s: Container with name %s not found. Aborting", GetName(), fSourceJetsName.Data()));
107     // append the list of matched jets to the event
108     fMatchedJets->Delete();
109     if (!(InputEvent()->FindListObject(fMatchedJetsName))) InputEvent()->AddObject(fMatchedJets);
110     else AliFatal(Form("%s: Object with name %s already in event! Aborting", GetName(), fMatchedJetsName.Data()));
111     FillAnalysisSummaryHistogram();
112     switch (fSourceBKG) {
113         case kSourceLocalRho : {
114             fSourceRho = dynamic_cast<AliLocalRhoParameter*>(InputEvent()->FindListObject(fSourceRhoName));
115             if(!fSourceRho) AliFatal(Form("%s: Object with name %s requested but not found! Aborting", GetName(), fSourceRhoName.Data()));
116         } break;
117         default : break;
118     }
119     switch (fTargetBKG) {
120         case kTargetLocalRho : {
121             fTargetRho = dynamic_cast<AliLocalRhoParameter*>(InputEvent()->FindListObject(fTargetRhoName));
122             if(!fTargetRho) AliFatal(Form("%s: Object with name %s requested but not found! Aborting", GetName(), fTargetRhoName.Data()));
123         } break;
124         default : break;
125     }
126     AliAnalysisTaskEmcalJet::ExecOnce(); // init base class
127     if(fDoDetectorResponse) fMatchConstituents = kFALSE;
128 }
129 //_____________________________________________________________________________
130 void AliAnalysisTaskJetMatching::UserCreateOutputObjects()
131 {
132     // create output objects
133     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
134      // add the matched jets array to the event
135     fMatchedJets = new TClonesArray("AliEmcalJet");
136     fMatchedJets->SetName(fMatchedJetsName);
137     fOutputList = new TList();
138     fOutputList->SetOwner(kTRUE);
139     // add analysis histograms
140     fHistUnsortedCorrelation = BookTH1F("fHistUnsortedCorrelation", "#Delta #varphi unsorted", 50, 0, TMath::Pi());
141     fHistMatchedCorrelation = BookTH1F("fHistMatchedCorrelation", "#Delta #varphi matched", 50, 0, TMath::Pi());
142     fHistSourceJetPt = (fDoDetectorResponse) ? BookTH1F("fHistParticleLevelJetPt", "p_{t}^{gen} [GeV/c]", 150, -50, 250) :  BookTH1F("fHistSourceJetPt", "p_{t} [GeV/c]", 150, -50, 250);      
143     fHistMatchedSourceJetPt = (fDoDetectorResponse) ? BookTH1F("fHistMatchedParticleLevelJetPt", "p_{t}^{gen} [GeV/c]", 150, -50, 250) : BookTH1F("fHistMatchedSourceJetPt", "p_{t} [GeV/c]", 150, -50, 250);
144     fHistTargetJetPt = BookTH1F("fHistTargetJetPt", "p_{t} [GeV/c]", 150, -50, 250);
145     fHistMatchedJetPt = (fDoDetectorResponse) ? BookTH1F("fHistDetectorLevelJet", "p_{t}^{rec}", 150, -50, 250) : BookTH1F("fHistMatchedJetPt", "p_{t} [GeV/c]", 150, -50, 250);
146     fHistSourceMatchedJetPt = (fDoDetectorResponse) ? BookTH2F("fHistDetectorResponse", "particle level jet p_{t}^{gen} [GeV/c]", "detector level jet p_{t}^{rec} [GeV/c]", 300, -50, 250, 300, -50, 250) : BookTH2F("fHistSourceMatchedJetPt", "source jet p_{t} [GeV/c]", "matched jet p_{t} [GeV/c]", 300, -50, 250, 300, -50, 250);
147     if(fDoDetectorResponse) {
148         fHistDetectorResponseProb = BookTH1F("fHistDetectorResponseProb", "(p_{t}^{det} - p_{t}^{part})/p_{t}^{part} ", 100, -1.5, 1.);
149     }
150     fHistNoConstSourceJet = BookTH1F("fHistNoConstSourceJet", "number of constituents source jets", 50, 0, 50);
151     fHistNoConstTargetJet = BookTH1F("fHistNoConstTargetJet", "number of constituents target jets", 50, 0, 50);
152     fHistNoConstMatchJet = BookTH1F("fHistNoConstMatchJet", "number of constituents matched jets", 50, 0, 50);
153     if(!fDoDetectorResponse) { // these observables cannot be measured in current detector response mode
154         fProfFracPtMatched = new TProfile("fProfFracPtMatched", "recovered target p_{T} / source p_{T}", 15, -50, 250);
155         fOutputList->Add(fProfFracPtMatched);
156         fProfFracNoMatched = new TProfile("fProfFracNoMatched", "recovered target constituents / source constituents", 15, -50, 250);
157         fOutputList->Add(fProfFracNoMatched);
158     }
159     // the analysis summary histo which stores all the analysis flags is always written to file
160     fHistAnalysisSummary = BookTH1F("fHistAnalysisSummary", "flag", 51, -0.5, 15.5);
161     fProfQAMatched = new TProfile("fProfQAMatched", "fProfQAMatched", 3, 0, 3);
162     fProfQAMatched->GetXaxis()->SetBinLabel(1, "<#delta p_{t} >");
163     fProfQAMatched->GetXaxis()->SetBinLabel(2, "<#delta #eta>");
164     fProfQAMatched->GetXaxis()->SetBinLabel(3, "<#delta #varphi>");
165     fOutputList->Add(fProfQAMatched);
166     fProfQA = new TProfile("fProfQA", "fProfQA", 3, 0, 3);
167     fProfQA->GetXaxis()->SetBinLabel(1, "<#delta p_{t} >");
168     fProfQA->GetXaxis()->SetBinLabel(2, "<#delta #eta>");
169     fProfQA->GetXaxis()->SetBinLabel(3, "<#delta #varphi>");
170     fOutputList->Add(fProfQA);
171     fProfFracPtJets = new TProfile("fProfFracPtJets", "source p_{T} / target p_{T}", 15, -50, 250);
172     fOutputList->Add(fProfFracPtJets);
173     fProfFracNoJets = new TProfile("fProfFracNoJets", "source constituents / target constituents", 15, -50, 250);
174     fOutputList->Add(fProfFracNoJets);
175     fOutputList->Sort();
176     PostData(1, fOutputList);
177 }
178 //_____________________________________________________________________________
179 TH1F* AliAnalysisTaskJetMatching::BookTH1F(const char* name, const char* x, Int_t bins, Double_t min, Double_t max, Bool_t append)
180 {
181     // book a TH1F and connect it to the output container
182     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
183     if(!fOutputList) return 0x0;
184     TString title(name);
185     title += Form(";%s;[counts]", x);
186     TH1F* histogram = new TH1F(name, title.Data(), bins, min, max);
187     histogram->Sumw2();
188     if(append) fOutputList->Add(histogram);
189     return histogram;   
190 }
191 //_____________________________________________________________________________
192 TH2F* AliAnalysisTaskJetMatching::BookTH2F(const char* name, const char* x, const char*y, Int_t binsx, Double_t minx, Double_t maxx, Int_t binsy, Double_t miny, Double_t maxy, Bool_t append)
193 {
194     // book a TH2F and connect it to the output container
195     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
196     if(!fOutputList) return 0x0;
197     TString title(name);
198     title += Form(";%s;%s", x, y);
199     TH2F* histogram = new TH2F(name, title.Data(), binsx, minx, maxx, binsy, miny, maxy);
200     histogram->Sumw2();
201     if(append) fOutputList->Add(histogram);
202     return histogram;   
203 }
204 //_____________________________________________________________________________
205 Bool_t AliAnalysisTaskJetMatching::Run()
206 {
207     // execute once for each event
208     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
209     if(!(InputEvent() && fSourceJets && fTargetJets && IsEventSelected())) return kFALSE;
210     // step one: do geometric matching 
211     switch (fMatchingScheme) {
212         case kGeoEtaPhi : {
213             DoGeometricMatchingEtaPhi();
214         } break;
215         case kGeoR : {
216             DoGeometricMatchingR();
217         } break;
218         default : break;
219     }
220     // break if no jet was matched
221     if(!fMatchedJetContainer[1][0]) return kTRUE;
222     // optional step two: get a bijection (avoid duplicate matches)
223     if(fGetBijection)           GetBijection();
224     // optional step three: match constituents within matched jets
225     if(fMatchConstituents)      DoConstituentMatching();
226     // stream data to output
227     PostMatchedJets();
228     FillMatchedJetHistograms();
229     if(fDebug > 0) PrintInfo();
230     PostData(1, fOutputList);
231     return kTRUE;
232 }
233 //_____________________________________________________________________________
234 void AliAnalysisTaskJetMatching::DoGeometricMatchingEtaPhi()
235 {
236     // do geometric matching based on eta phi distance between jet centers
237     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
238     fNoMatchedJets = 0; // reset the matched jet counter
239     Int_t iSource(fSourceJets->GetEntriesFast()), iTarget(fTargetJets->GetEntriesFast());
240     for(Int_t i(0); i < iSource; i++) {
241         AliEmcalJet* sourceJet(static_cast<AliEmcalJet*>(fSourceJets->At(i)));
242         if(!PassesCuts(sourceJet, 0)) continue;
243         for(Int_t j(0); j < iTarget; j++) {
244             AliEmcalJet* targetJet(static_cast<AliEmcalJet*>(fTargetJets->At(j)));
245             if(!PassesCuts(targetJet, 1)) continue;
246             if (fUseEmcalBaseJetCuts && !AcceptJet(targetJet, 1)) continue;
247             if((TMath::Abs(sourceJet->Eta() - targetJet->Eta()) < fMatchEta )) {
248                 Double_t sourcePhi(sourceJet->Phi()), targetPhi(targetJet->Phi());
249                 if(TMath::Abs(sourcePhi-targetPhi) > TMath::Abs(sourcePhi-targetPhi+TMath::TwoPi())) sourcePhi+=TMath::TwoPi();
250                 if(TMath::Abs(sourcePhi-targetPhi) > TMath::Abs(sourcePhi-targetPhi-TMath::TwoPi())) sourcePhi-=TMath::TwoPi();
251                 if(TMath::Abs(sourcePhi-targetPhi) < fMatchPhi) {       // accept the jets as matching 
252                 Bool_t isBestMatch(kTRUE);
253                     if(fGetBijection) { // match has been found, for bijection only store it if there's no better match
254                         if(fDebug > 0) printf(" > Entering first bbijection test \n");
255                         for(Int_t k(i); k < iSource; k++) {
256                             AliEmcalJet* candidateSourceJet(static_cast<AliEmcalJet*>(fSourceJets->At(k)));
257                             if(PassesCuts(candidateSourceJet, 0)) continue;
258                             if(fDebug > 0) printf("source distance %.2f \t candidate distance %.2f \n", GetR(sourceJet, targetJet),GetR(candidateSourceJet, targetJet));
259                             if(GetR(sourceJet, targetJet) > GetR(candidateSourceJet, targetJet)) {
260                                 isBestMatch = kFALSE;
261                                 break;
262                             }
263                         }
264                         if(fDebug > 0) (isBestMatch) ? printf(" kept source \n ") : printf(" we can do better (rejected source) \n");
265                     }
266                     if(isBestMatch) {
267                         fMatchedJetContainer[fNoMatchedJets][0] = sourceJet;
268                         fMatchedJetContainer[fNoMatchedJets][1] = targetJet;
269                         fNoMatchedJets++;
270                     }
271                     if(fNoMatchedJets > 199) {   // maximum to keep the cache at reasonable size
272                         AliError(Form("%s: Found too many matched jets (> 100). Adjust matching criteria !", GetName()));
273                         return;
274                     }
275                 }
276             }
277         }
278     }
279 }
280 //_____________________________________________________________________________
281 void AliAnalysisTaskJetMatching::DoGeometricMatchingR()
282 {
283     // do geometric matching based on shortest path between jet centers
284     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
285     fNoMatchedJets = 0; // reset the matched jet counter
286     Int_t iSource(fSourceJets->GetEntriesFast()), iTarget(fTargetJets->GetEntriesFast());
287     for(Int_t i(0); i < iSource; i++) {
288         AliEmcalJet* sourceJet(static_cast<AliEmcalJet*>(fSourceJets->At(i)));
289         if(!PassesCuts(sourceJet, 0)) continue;
290         for(Int_t j(0); j < iTarget; j++) {
291             AliEmcalJet* targetJet(static_cast<AliEmcalJet*>(fTargetJets->At(j)));
292             if(!PassesCuts(targetJet, 1)) continue;
293             else if (fUseEmcalBaseJetCuts && !AcceptJet(targetJet, 1)) continue;
294             if(GetR(sourceJet, targetJet) <= fMatchR) {
295                 Bool_t isBestMatch(kTRUE);
296                 if(fGetBijection) { // match has been found, for bijection only store it if there's no better match
297                     if(fDebug > 0) printf(" > Entering first bijection test \n");
298                     for(Int_t k(i); k < iSource; k++) {
299                         AliEmcalJet* candidateSourceJet(static_cast<AliEmcalJet*>(fSourceJets->At(k)));
300                         if(!PassesCuts(candidateSourceJet, 0)) continue;
301                         if(fDebug > 0) printf("source distance %.2f \t candidate distance %.2f \n", GetR(sourceJet, targetJet),GetR(candidateSourceJet, targetJet));
302                         if(GetR(sourceJet, targetJet) > GetR(candidateSourceJet, targetJet)) {
303                             isBestMatch = kFALSE;
304                             break;
305                         }
306                     }
307                     if(fDebug > 0) (isBestMatch) ? printf(" kept source \n ") : printf(" we can do better (rejected source) \n");
308                 }
309                 if(isBestMatch) {
310                     fMatchedJetContainer[fNoMatchedJets][0] = sourceJet;
311                     fMatchedJetContainer[fNoMatchedJets][1] = targetJet;
312                     fNoMatchedJets++;
313                 }
314                 if(fNoMatchedJets > 99) {
315                     AliError(Form("%s: Found too many matched jets (> 100). Adjust matching criteria !", GetName()));
316                     return;
317                 }
318             }
319         }
320     }
321 }
322 //_____________________________________________________________________________
323 void AliAnalysisTaskJetMatching::DoConstituentMatching()
324 {
325     // match constituents within matched jets 
326     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
327     if(!fTracks) {
328         AliFatal(Form("%s Fatal error! To do deep matching, supply jet constituents ! \n", GetName()));
329         return; // coverity ...
330     }
331     for(Int_t i(0); i < fNoMatchedJets; i++) {
332         AliEmcalJet* sourceJet = fMatchedJetContainer[i][0];
333         AliEmcalJet* targetJet = fMatchedJetContainer[i][1];
334         if(sourceJet && targetJet) {    // duplicate check: slot migth be NULL
335             Double_t targetPt(0);
336             Int_t iSJ(sourceJet->GetNumberOfTracks());
337             Int_t iTJ(targetJet->GetNumberOfTracks());
338             Int_t overlap(0), alreadyFound(0);
339             for(Int_t j(0); j < iSJ; j++) {
340                 alreadyFound = 0;
341                 Int_t idSource((Int_t)sourceJet->TrackAt(j));
342                 for(Int_t k(0); k < iTJ; k++) { // compare all target tracks to the source track
343                     if(idSource == targetJet->TrackAt(k) && alreadyFound == 0) {
344                         overlap++;
345                         alreadyFound++; // avoid possible duplicate matching
346                         AliVParticle* vp(static_cast<AliVParticle*>(targetJet->TrackAt(k, fTracks)));
347                         if(vp) targetPt += vp->Pt();
348                         continue;
349                     }
350                 }
351             }
352             if((float)overlap/(float)iSJ < fMinFracRecoveredConstituents || targetPt/sourceJet->Pt() < fMinFracRecoveredConstituentPt) {
353                 if(fDebug > 0) printf("  \n > Purging jet, recovered constituents ratio  %i / %i = %.2f <  or pt ratio %.2f / %.2f = %.2f < %.2f", 
354                         overlap, iSJ, (float)overlap/(float)iSJ, targetPt, sourceJet->Pt(), targetPt/sourceJet->Pt(), fMinFracRecoveredConstituentPt);
355                 fMatchedJetContainer[i][0] = 0x0;
356                 fMatchedJetContainer[i][1] = 0x0;
357                 continue;
358             }
359             if(sourceJet->Pt() > 0) {
360                 Double_t sourceRho(0), targetRho(0);
361                 if(fSourceRho) sourceRho = fSourceRho->GetLocalVal(sourceJet->Phi(), fSourceRadius)*sourceJet->Area();
362                 if(fTargetRho) targetRho = fTargetRho->GetLocalVal(targetJet->Phi(), fTargetRadius)*targetJet->Area();
363                 fProfFracPtMatched->Fill(sourceJet->Pt()-sourceRho, (targetPt-targetRho) / (sourceJet->Pt()-sourceRho));
364                 fProfFracPtJets->Fill(sourceJet->Pt()-sourceRho, (targetJet->Pt()-targetRho) / (sourceJet->Pt()-sourceRho));
365                 fProfFracNoMatched->Fill(sourceJet->Pt()-sourceRho, (double)overlap / (double)sourceJet->GetNumberOfTracks());
366                 fProfFracNoJets->Fill(sourceJet->Pt()-sourceRho, (double)targetJet->GetNumberOfTracks() / (double)sourceJet->GetNumberOfTracks());
367             }
368             if(fDebug > 0) {
369                 printf("\n > Jet A: %i const\t", iSJ);
370                 printf(" > Jet B %i const\t", iTJ);
371                 printf(" -> OVERLAP: %i tracks <- \n", overlap);
372             }
373         }
374     }
375 }
376 //_____________________________________________________________________________
377 void AliAnalysisTaskJetMatching::GetBijection()
378 {
379     // bijection of source and matched jets, based on closest distance between jets
380     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
381     for(Int_t i(0); i < fNoMatchedJets; i++) {
382         for(Int_t j(i+1); j < fNoMatchedJets; j++) {
383             if(fMatchedJetContainer[i][0] == fMatchedJetContainer[j][0]) {
384                 // found source with two targets, now see which target is closer to the source
385                 if(!(fMatchedJetContainer[i][0] && fMatchedJetContainer[i][1] && fMatchedJetContainer[j][0] && fMatchedJetContainer[j][1] )) continue;
386                 Double_t rA(GetR(fMatchedJetContainer[i][0], fMatchedJetContainer[i][1]));      // distance between connection A = i
387                 Double_t rB(GetR(fMatchedJetContainer[j][0], fMatchedJetContainer[j][1]));      // distance between connection B = j
388                 if (rB > rA) {  // jet two is far away, clear it from both target and source list
389                     fMatchedJetContainer[j][0] = 0x0;
390                     fMatchedJetContainer[j][1] = 0x0;
391                 } else {                // jet one is far away, clear it from both target and source list
392                     fMatchedJetContainer[i][0] = fMatchedJetContainer[j][0];    // switch to avoid breaking loop
393                     fMatchedJetContainer[i][1] = fMatchedJetContainer[j][1];    
394                     fMatchedJetContainer[j][0] = 0x0;                           // clear duplicate jet from cache
395                     fMatchedJetContainer[j][1] = 0x0;
396                 }
397                 if(fDebug > 0) printf(" found duplicate jet, chose %.2f over %.2f \n" , (rB > rA) ? rA : rB, (rB > rA) ? rB : rA);
398             }
399         }
400     }
401 }
402 //_____________________________________________________________________________
403 void AliAnalysisTaskJetMatching::PostMatchedJets()
404 {
405     // post matched jets
406     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
407     fMatchedJets->Delete();     // should be a NULL operation, but added just in case
408     for(Int_t i(0), p(0); i < fNoMatchedJets; i++) {
409         if(fMatchedJetContainer[i][1]) {        // duplicate jets will have NULL value here and are skipped
410             new((*fMatchedJets)[p]) AliEmcalJet(*fMatchedJetContainer[i][1]);
411             p++; 
412         }
413     }
414 }
415 //_____________________________________________________________________________
416 void AliAnalysisTaskJetMatching::FillAnalysisSummaryHistogram() const
417 {
418     // fill the analysis summary histrogram, saves all relevant analysis settigns
419     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
420     fHistAnalysisSummary->GetXaxis()->SetBinLabel(1, "fUseScaledRho");
421     fHistAnalysisSummary->SetBinContent(1, (int)fUseScaledRho);
422     fHistAnalysisSummary->GetXaxis()->SetBinLabel(2, "fMatchingScheme");
423     fHistAnalysisSummary->SetBinContent(2, (int)fMatchingScheme);
424     fHistAnalysisSummary->GetXaxis()->SetBinLabel(3, "fSourceBKG");
425     fHistAnalysisSummary->SetBinContent(3, (int)fSourceBKG);
426     fHistAnalysisSummary->GetXaxis()->SetBinLabel(4, "fTargetBKG");
427     fHistAnalysisSummary->SetBinContent(4, (int)fTargetBKG);
428     fHistAnalysisSummary->GetXaxis()->SetBinLabel(5, "fMatchEta");
429     fHistAnalysisSummary->SetBinContent(5, fMatchEta);
430     fHistAnalysisSummary->GetXaxis()->SetBinLabel(6, "fMatchPhi");
431     fHistAnalysisSummary->SetBinContent(6, fMatchPhi);
432     fHistAnalysisSummary->GetXaxis()->SetBinLabel(7, "fMatchR");
433     fHistAnalysisSummary->SetBinContent(7, fMatchR);
434     fHistAnalysisSummary->GetXaxis()->SetBinLabel(8, "iter");
435     fHistAnalysisSummary->SetBinContent(8, 1.);
436 }
437 //_____________________________________________________________________________
438 void AliAnalysisTaskJetMatching::FillMatchedJetHistograms() 
439 {
440     // fill matched jet histograms
441     if(fDebug > 0) printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
442     for(Int_t i(0); i < fSourceJets->GetEntriesFast(); i++) {
443         AliEmcalJet* source = static_cast<AliEmcalJet*>(fSourceJets->At(i));
444         if(!source) continue;
445         else if(fUseEmcalBaseJetCuts && !AcceptJet(source, 0)) continue;
446         Double_t sourceRho(0), targetRho(0);
447         if(fSourceRho) sourceRho = fSourceRho->GetLocalVal(source->Phi(), fSourceRadius)*source->Area();
448         fHistSourceJetPt->Fill(source->Pt()-sourceRho);
449         fHistNoConstSourceJet->Fill(source->GetNumberOfConstituents());
450         for(Int_t j(0); j < fTargetJets->GetEntriesFast(); j++) {
451             AliEmcalJet* target = static_cast<AliEmcalJet*>(fTargetJets->At(j));
452             if(target) {
453                 if(fUseEmcalBaseJetCuts && !AcceptJet(target, 1)) continue;
454                 if(fTargetRho) targetRho = fTargetRho->GetLocalVal(target->Phi(), fTargetRadius)*target->Area();
455                 fProfQA->Fill(0.5, TMath::Abs((source->Pt()-sourceRho)-(target->Pt()-targetRho)));  
456                 fProfQA->Fill(1.5, TMath::Abs(source->Eta()-target->Eta()));
457                 fProfQA->Fill(2.5, TMath::Abs(source->Phi()-target->Phi()));
458                 fHistUnsortedCorrelation->Fill(PhaseShift(source->Phi()-target->Phi(), 2));
459                 if(j==0) {
460                     fHistTargetJetPt->Fill(target->Pt()-targetRho);
461                     fHistNoConstTargetJet->Fill(target->GetNumberOfConstituents());
462                 }
463             }
464         }
465     }
466     for(Int_t i(0); i < fNoMatchedJets; i++) {
467         if(fMatchedJetContainer[i][0] && fMatchedJetContainer[i][1]) {
468             Double_t sourceRho(0), targetRho(0);
469             if(fSourceRho) sourceRho = fSourceRho->GetLocalVal(fMatchedJetContainer[i][0]->Phi(), fSourceRadius)*fMatchedJetContainer[i][0]->Area();
470             if(fTargetRho) targetRho = fTargetRho->GetLocalVal(fMatchedJetContainer[i][1]->Phi(), fTargetRadius)*fMatchedJetContainer[i][1]->Area();
471             fHistMatchedCorrelation->Fill(PhaseShift(fMatchedJetContainer[i][0]->Phi()-fMatchedJetContainer[i][1]->Phi(), 2));
472             fHistMatchedSourceJetPt->Fill(fMatchedJetContainer[i][0]->Pt()-sourceRho);
473             fHistMatchedJetPt->Fill(fMatchedJetContainer[i][1]->Pt()-targetRho);
474             fHistNoConstMatchJet->Fill(fMatchedJetContainer[i][1]->Pt()-targetRho);
475             fProfQAMatched->Fill(0.5, TMath::Abs((fMatchedJetContainer[i][0]->Pt()-sourceRho)-(fMatchedJetContainer[i][1]->Pt()-targetRho)));
476             fProfQAMatched->Fill(1.5, TMath::Abs(fMatchedJetContainer[i][0]->Eta()-fMatchedJetContainer[i][1]->Eta()));
477             fProfQAMatched->Fill(2.5, TMath::Abs(fMatchedJetContainer[i][0]->Phi()-fMatchedJetContainer[i][1]->Phi()));
478             
479             fHistSourceMatchedJetPt->Fill(fMatchedJetContainer[i][0]->Pt()-sourceRho, fMatchedJetContainer[i][1]->Pt()-targetRho);
480             if(fDoDetectorResponse) {
481                 fProfFracPtJets->Fill(fMatchedJetContainer[i][0]->Pt()-sourceRho, (fMatchedJetContainer[i][1]->Pt()-targetRho) / (fMatchedJetContainer[i][0]->Pt()-sourceRho));
482                 fProfFracNoJets->Fill(fMatchedJetContainer[i][0]->Pt()-sourceRho, (double)fMatchedJetContainer[i][1]->GetNumberOfTracks() / (double)fMatchedJetContainer[i][0]->GetNumberOfTracks());
483                 fHistDetectorResponseProb->Fill((fMatchedJetContainer[i][1]->Pt()-fMatchedJetContainer[i][0]->Pt())/fMatchedJetContainer[i][0]->Pt());
484             }
485         }
486     }
487 }
488 //_____________________________________________________________________________
489 void AliAnalysisTaskJetMatching::PrintInfo() const
490 {
491     // print some info 
492     printf("\n > No. of source jets from %s \n \t %i \n ", fSourceJetsName.Data(), fSourceJets->GetEntriesFast());
493     printf(" > No. of target jets from %s \n \t %i \n ", fTargetJetsName.Data(), fTargetJets->GetEntriesFast());
494     printf(" > No. of matched jets from %s \n \t %i \n ", fMatchedJetsName.Data(), fMatchedJets->GetEntriesFast());
495     if(fDebug > 3) InputEvent()->GetList()->ls();
496 }
497 //_____________________________________________________________________________
498 void AliAnalysisTaskJetMatching::Terminate(Option_t *)
499 {
500     // terminate
501 }
502 //_____________________________________________________________________________