2 // Jet mass structure analysis task.
6 #include <TClonesArray.h>
10 #include <TProfile2D.h>
11 #include <THnSparse.h>
13 #include <TLorentzVector.h>
22 #include "AliVCluster.h"
23 #include "AliVTrack.h"
24 #include "AliEmcalJet.h"
25 #include "AliRhoParameter.h"
27 #include "AliEmcalParticle.h"
28 #include "AliMCEvent.h"
29 #include "AliGenPythiaEventHeader.h"
30 #include "AliAODMCHeader.h"
31 #include "AliMCEvent.h"
32 #include "AliAnalysisManager.h"
33 #include "AliParticleContainer.h"
34 #include "AliJetContainer.h"
35 #include "AliEmcalJetByJetCorrection.h"
37 #include "AliAODEvent.h"
39 #include "AliAnalysisTaskEmcalJetMassStructure.h"
41 ClassImp(AliAnalysisTaskEmcalJetMassStructure)
43 //________________________________________________________________________
44 AliAnalysisTaskEmcalJetMassStructure::AliAnalysisTaskEmcalJetMassStructure() :
45 AliAnalysisTaskEmcalJet("AliAnalysisTaskEmcalJetMassStructure", kTRUE),
47 fMinFractionShared(0),
60 fhnMassResponseCorr(0),
64 // Default constructor.
66 fh3PtDRMass = new TH3F*[fNcentBins];
67 fh3PtDRRho = new TH3F*[fNcentBins];
68 fh3PtDRMassCorr = new TH3F*[fNcentBins];
69 fh3PtDRRhoCorr = new TH3F*[fNcentBins];
70 fh2PtMass = new TH2F*[fNcentBins];
71 fh2PtMassCorr = new TH2F*[fNcentBins];
72 fh3JetPtDRTrackPt = new TH3F*[fNcentBins];
74 for (Int_t i = 0; i < fNcentBins; i++) {
77 fh3PtDRMassCorr[i] = 0;
78 fh3PtDRRhoCorr[i] = 0;
81 fh3JetPtDRTrackPt[i] = 0;
84 SetMakeGeneralHistograms(kTRUE);
87 //________________________________________________________________________
88 AliAnalysisTaskEmcalJetMassStructure::AliAnalysisTaskEmcalJetMassStructure(const char *name) :
89 AliAnalysisTaskEmcalJet(name, kTRUE),
91 fMinFractionShared(0),
104 fhnMassResponseCorr(0),
105 fh3JetPtDRTrackPt(0),
108 // Standard constructor.
110 fh3PtDRMass = new TH3F*[fNcentBins];
111 fh3PtDRRho = new TH3F*[fNcentBins];
112 fh3PtDRMassCorr = new TH3F*[fNcentBins];
113 fh3PtDRRhoCorr = new TH3F*[fNcentBins];
114 fh2PtMass = new TH2F*[fNcentBins];
115 fh2PtMassCorr = new TH2F*[fNcentBins];
116 fh3JetPtDRTrackPt = new TH3F*[fNcentBins];
118 for (Int_t i = 0; i < fNcentBins; i++) {
121 fh3PtDRMassCorr[i] = 0;
122 fh3PtDRRhoCorr[i] = 0;
124 fh2PtMassCorr[i] = 0;
125 fh3JetPtDRTrackPt[i] = 0;
127 SetMakeGeneralHistograms(kTRUE);
130 //________________________________________________________________________
131 AliAnalysisTaskEmcalJetMassStructure::~AliAnalysisTaskEmcalJetMassStructure()
137 //________________________________________________________________________
138 void AliAnalysisTaskEmcalJetMassStructure::UserCreateOutputObjects()
140 // Create user output.
142 AliAnalysisTaskEmcalJet::UserCreateOutputObjects();
144 if(!fRandom) fRandom = new TRandom3(0);
146 if(fCorrType==kMeanPtR && fEJetByJetCorr) fEJetByJetCorr->Init();
148 Bool_t oldStatus = TH1::AddDirectoryStatus();
149 TH1::AddDirectory(kFALSE);
151 const Int_t nBinsPt = 200;
152 const Double_t minPt = -50.;
153 const Double_t maxPt = 150.;
154 Double_t *binsPt = new Double_t[nBinsPt+1];
155 for(Int_t i=0; i<=nBinsPt; i++) binsPt[i]=(Double_t)minPt + (maxPt-minPt)/nBinsPt*(Double_t)i ;
157 const Int_t nBinsM = 120;
158 const Double_t minM = -20.;
159 const Double_t maxM = 40.;
160 Double_t *binsM = new Double_t[nBinsM+1];
161 for(Int_t i=0; i<=nBinsM; i++) binsM[i]=(Double_t)minM + (maxM-minM)/nBinsM*(Double_t)i ;
163 const Int_t nBinsR = 80;
164 const Double_t minR = -0.005;
165 const Double_t maxR = 0.795;
166 Double_t *binsR = new Double_t[nBinsR+1];
167 for(Int_t i=0; i<=nBinsR; i++) binsR[i]=(Double_t)minR + (maxR-minR)/nBinsR*(Double_t)i ;
170 Double_t binWidth1 = 0.1;
171 Double_t binWidth2 = 1.;
172 Double_t binWidth3 = 1.;
173 const Float_t ptmin1 = 0.;
174 const Float_t ptmax1 = 5.;
175 const Float_t ptmin2 = ptmax1;
176 const Float_t ptmax2 = 10.;
177 const Float_t ptmin3 = ptmax2 ;
178 const Float_t ptmax3 = 100.;
179 const Int_t nbin11 = (int)((ptmax1-ptmin1)/binWidth1);
180 const Int_t nbin12 = (int)((ptmax2-ptmin2)/binWidth2)+nbin11;
181 const Int_t nbin13 = (int)((ptmax3-ptmin3)/binWidth3)+nbin12;
182 Int_t nBinsPtTr=nbin13;
183 //Create array with low edges of each bin
184 Double_t *binsPtTr=new Double_t[nBinsPtTr+1];
185 for(Int_t i=0; i<=nBinsPtTr; i++) {
186 if(i<=nbin11) binsPtTr[i]=(Double_t)ptmin1 + (ptmax1-ptmin1)/nbin11*(Double_t)i ;
187 if(i<=nbin12 && i>nbin11) binsPtTr[i]=(Double_t)ptmin2 + (ptmax2-ptmin2)/(nbin12-nbin11)*((Double_t)i-(Double_t)nbin11) ;
188 if(i<=nbin13 && i>nbin12) binsPtTr[i]=(Double_t)ptmin3 + (ptmax3-ptmin3)/(nbin13-nbin12)*((Double_t)i-(Double_t)nbin12) ;
191 //Binning for THnSparse
192 const Int_t nBinsSparse0 = 5;
193 const Int_t nBins0[nBinsSparse0] = {nBinsM,nBinsM,nBinsPt,nBinsPt};
194 const Double_t xmin0[nBinsSparse0] = { minM, minM, minPt, minPt};
195 const Double_t xmax0[nBinsSparse0] = { maxM, maxM, maxPt, maxPt};
197 TString histName = "";
198 TString histTitle = "";
199 for (Int_t i = 0; i < fNcentBins; i++) {
200 histName = TString::Format("fh3PtDRMass_%d",i);
201 histTitle = TString::Format("%s;#it{p}_{T,jet};r;sum m",histName.Data());
202 fh3PtDRMass[i] = new TH3F(histName.Data(),histTitle.Data(),nBinsPt,minPt,maxPt,nBinsR,minR,maxR,101,-0.005,1.005);
203 fOutput->Add(fh3PtDRMass[i]);
205 histName = TString::Format("fh3PtDRRho_%d",i);
206 histTitle = TString::Format("%s;#it{p}_{T,jet};r;sum #it{p}_{T}",histName.Data());
207 fh3PtDRRho[i] = new TH3F(histName.Data(),histTitle.Data(),nBinsPt,minPt,maxPt,nBinsR,minR,maxR,101,-0.005,1.005);
208 fOutput->Add(fh3PtDRRho[i]);
210 histName = TString::Format("fh3PtDRMassCorr_%d",i);
211 histTitle = TString::Format("%s;#it{p}_{T,jet};r;sum m",histName.Data());
212 fh3PtDRMassCorr[i] = new TH3F(histName.Data(),histTitle.Data(),nBinsPt,minPt,maxPt,nBinsR,minR,maxR,101,-0.005,1.005);
213 fOutput->Add(fh3PtDRMassCorr[i]);
215 histName = TString::Format("fh3PtDRRhoCorr_%d",i);
216 histTitle = TString::Format("%s;#it{p}_{T,jet};r;sum #it{p}_{T}",histName.Data());
217 fh3PtDRRhoCorr[i] = new TH3F(histName.Data(),histTitle.Data(),nBinsPt,minPt,maxPt,nBinsR,minR,maxR,101,-0.005,1.005);
218 fOutput->Add(fh3PtDRRhoCorr[i]);
220 histName = TString::Format("fh2PtMass_%d",i);
221 histTitle = TString::Format("%s;#it{p}_{T,jet};#it{M}_{jet}",histName.Data());
222 fh2PtMass[i] = new TH2F(histName.Data(),histTitle.Data(),nBinsPt,minPt,maxPt,nBinsM,minM,maxM);
223 fOutput->Add(fh2PtMass[i]);
225 histName = TString::Format("fh2PtMassCorr_%d",i);
226 histTitle = TString::Format("%s;#it{p}_{T,jet};#it{M}_{jet}",histName.Data());
227 fh2PtMassCorr[i] = new TH2F(histName.Data(),histTitle.Data(),nBinsPt,minPt,maxPt,nBinsM,minM,maxM);
228 fOutput->Add(fh2PtMassCorr[i]);
230 histName = TString::Format("fh3JetPtDRTrackPt_%d",i);
231 histTitle = TString::Format("%s;#it{p}_{T,jet};r;#it{p}_{T,track}",histName.Data());
232 fh3JetPtDRTrackPt[i] = new TH3F(histName.Data(),histTitle.Data(),nBinsPt,binsPt,nBinsR,binsR,nBinsPtTr,binsPtTr);
233 fOutput->Add(fh3JetPtDRTrackPt[i]);
236 histName = "fhnMassResponse";
237 histTitle = Form("%s;#it{M}_{det};#it{M}_{part};#it{p}_{T,det};#it{p}_{T,part}",histName.Data());
238 fhnMassResponse = new THnSparseF(histName.Data(),histTitle.Data(),nBinsSparse0,nBins0,xmin0,xmax0);
239 fOutput->Add(fhnMassResponse);
241 histName = "fhnMassResponseCorr";
242 histTitle = Form("%s;#it{M}_{det};#it{M}_{part};#it{p}_{T,det};#it{p}_{T,part}",histName.Data());
243 fhnMassResponseCorr = new THnSparseF(histName.Data(),histTitle.Data(),nBinsSparse0,nBins0,xmin0,xmax0);
244 fOutput->Add(fhnMassResponseCorr);
246 if(fEJetByJetCorr) fpUsedEfficiency = fEJetByJetCorr->GetAppliedEfficiency();
247 fOutput->Add(fpUsedEfficiency);
249 TH1::AddDirectory(oldStatus);
251 PostData(1, fOutput); // Post data for ALL output slots > 0 here.
253 if(binsPt) delete [] binsPt;
254 if(binsPtTr) delete [] binsPtTr;
255 if(binsM) delete [] binsM;
256 if(binsR) delete [] binsR;
260 //________________________________________________________________________
261 Bool_t AliAnalysisTaskEmcalJetMassStructure::Run()
263 // Run analysis code here, if needed. It will be executed before FillHistograms().
268 //________________________________________________________________________
269 Bool_t AliAnalysisTaskEmcalJetMassStructure::FillHistograms()
271 // study how jet mass builds up as function of radial distance to jet axis
273 if(fCorrType==kMeanPtR && !fEJetByJetCorr) return kFALSE;
275 AliEmcalJet* jet1 = NULL;
276 AliJetContainer *jetCont = GetJetContainer(fContainerBase);
278 jetCont->ResetCurrentID();
279 while((jet1 = jetCont->GetNextAcceptJet())) {
281 Double_t ptJet1 = jet1->Pt() - GetRhoVal(fContainerBase)*jet1->Area();
282 Double_t mJet1 = GetJetMass(jet1);
283 fh2PtMass[fCentBin]->Fill(ptJet1,mJet1);
284 AliEmcalJet *jPart = jet1->ClosestJet();
285 //fill detector response
287 Double_t var[4] = {mJet1,jPart->M(),ptJet1,jPart->Pt()};
288 fhnMassResponse->Fill(var);
291 // if(jet1->GetTagStatus()<1 || !jet1->GetTaggedJet())
294 //Sort array based on distance to jet axis
295 static Int_t indexes[9999] = {-1};
296 static Float_t dr[9999] = {0};
297 if(!GetSortedArray(indexes,dr,jet1)) continue;
299 for(Int_t i=jet1->GetNumberOfTracks()-1; i>-1; i--) {
300 AliVParticle *vp = static_cast<AliVParticle*>(jet1->TrackAt(indexes[i], fTracks));
302 fh3JetPtDRTrackPt[fCentBin]->Fill(ptJet1,dr[indexes[i]],vp->Pt());
305 if(fCorrType==kAnnulus) {
306 TLorentzVector sumVec; sumVec.SetPtEtaPhiM(0.,0.,0.,0.);
307 TLorentzVector corrVec; corrVec.SetPtEtaPhiM(0.,0.,0.,0.);
308 TLorentzVector curVec;
309 for(Int_t i=jet1->GetNumberOfTracks()-1; i>-1; i--) {
310 AliVParticle *vp = static_cast<AliVParticle*>(jet1->TrackAt(indexes[i], fTracks));
313 curVec.SetPtEtaPhiM(vp->Pt(),vp->Eta(),vp->Phi(),vp->M());
317 fh3PtDRMass[fCentBin]->Fill(ptJet1,dr[indexes[i]],sumVec.M()/mJet1);
318 fh3PtDRRho[fCentBin]->Fill(ptJet1,dr[indexes[i]],sumVec.Pt()/ptJet1);
320 fh3PtDRMassCorr[fCentBin]->Fill(ptJet1,dr[indexes[i]],corrVec.M()/mJet1);
321 fh3PtDRRhoCorr[fCentBin]->Fill(ptJet1,dr[indexes[i]],corrVec.Pt()/ptJet1);
323 Double_t eff = GetEfficiency(vp->Pt());
324 Double_t rnd = fRandom->Uniform(1.);
325 if(rnd>eff) {//put particle back at random position in annulus; using now zero width for annulus
326 Double_t t = TMath::TwoPi()*gRandom->Uniform(1.);
327 Double_t rr = dr[indexes[i]];
328 rr = fRandom->Uniform(0.,jetCont->GetJetRadius());
329 Double_t deta = rr*TMath::Cos(t);
330 Double_t dphi = rr*TMath::Sin(t);
331 curVec.SetPtEtaPhiM(vp->Pt(),deta+jet1->Eta(),dphi+jet1->Phi(),vp->M());
334 fh3PtDRMassCorr[fCentBin]->Fill(ptJet1,dr[indexes[i]],corrVec.M()/mJet1);
335 fh3PtDRRhoCorr[fCentBin]->Fill(ptJet1,dr[indexes[i]],corrVec.Pt()/ptJet1);
339 fh2PtMassCorr[fCentBin]->Fill(corrVec.Pt(), corrVec.M());
341 Double_t varCorr[4] = {corrVec.M(),jPart->M(),corrVec.Pt(),jPart->Pt()};
342 fhnMassResponseCorr->Fill(varCorr);
345 else if(fCorrType==kMeanPtR) {
346 //jet-by-jet correction based on templates
347 AliEmcalJet *jetCorr = fEJetByJetCorr->Eval(jet1,jetCont->GetParticleContainer()->GetArray());
348 if(jPart && jetCorr) {
349 Double_t varCorr[4] = {jetCorr->M(),jPart->M(),jetCorr->Pt(),jPart->Pt()};
350 fhnMassResponseCorr->Fill(varCorr);
359 //________________________________________________________________________
360 Double_t AliAnalysisTaskEmcalJetMassStructure::GetEfficiency(Double_t pt) {
363 if(fEfficiencyFixed<1.) return fEfficiencyFixed;
368 //________________________________________________________________________
369 Bool_t AliAnalysisTaskEmcalJetMassStructure::GetSortedArray(Int_t indexes[], Float_t dr[], AliEmcalJet *jet) const
372 const Int_t n = (Int_t)jet->GetNumberOfTracks();//(Int_t)array.size();
373 if (n < 1) return kFALSE;
375 for (Int_t i = 0; i < n; i++) {
376 AliVParticle *vp = static_cast<AliVParticle*>(jet->TrackAt(i, fTracks));
378 dr[i] = jet->DeltaR(vp);
380 TMath::Sort(n, dr, indexes);
385 //________________________________________________________________________
386 Double_t AliAnalysisTaskEmcalJetMassStructure::GetJetMass(AliEmcalJet *jet) {
387 //calc subtracted jet mass
388 if(fJetMassType==kRaw)
390 else if(fJetMassType==kDeriv)
391 return jet->GetSecondOrderSubtracted();
396 //________________________________________________________________________
397 Bool_t AliAnalysisTaskEmcalJetMassStructure::RetrieveEventObjects() {
399 // retrieve event objects
401 if (!AliAnalysisTaskEmcalJet::RetrieveEventObjects())
407 //_______________________________________________________________________
408 void AliAnalysisTaskEmcalJetMassStructure::Terminate(Option_t *)
410 // Called once at the end of the analysis.