1 #include "AliAnaChargedJetResponseMaker.h"
3 #include "TGraphErrors.h"
11 #include "THnSparse.h"
13 #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
18 ClassImp(AliAnaChargedJetResponseMaker)
20 AliAnaChargedJetResponseMaker::AliAnaChargedJetResponseMaker():
22 fResolutionType(kParam),
37 fResponseMatrixFine(0x0),
40 fPtMaxUnfoldedHigh(-1.),
41 fBinWidthFactorUnfolded(2),
43 fExtraBinsUnfolded(5),
44 fbVariableBinning(kFALSE),
45 fPtMaxUnfVarBinning(0),
52 //--------------------------------------------------------------------------------------------------------------------------------------------------
53 AliAnaChargedJetResponseMaker::AliAnaChargedJetResponseMaker(const AliAnaChargedJetResponseMaker& obj):
55 fResolutionType(obj.fResolutionType),
56 fDeltaPt(obj.fDeltaPt),
57 fhDeltaPt(obj.fhDeltaPt),
58 fDimensions(obj.fDimensions),
64 fBinArrayPtRec(obj.fBinArrayPtRec),
65 fPtMeasured(obj.fPtMeasured),
66 fEffFlat(obj.fEffFlat),
67 fEfficiency(obj.fEfficiency),
68 fEfficiencyFine(obj.fEfficiencyFine),
69 fResponseMatrix(obj.fResponseMatrix),
70 fResponseMatrixFine(obj.fResponseMatrixFine),
71 fPtMinUnfolded(obj.fPtMinUnfolded),
72 fPtMaxUnfolded(obj.fPtMaxUnfolded),
73 fPtMaxUnfoldedHigh(obj.fPtMaxUnfoldedHigh),
74 fBinWidthFactorUnfolded(obj.fBinWidthFactorUnfolded),
75 fSkipBinsUnfolded(obj.fSkipBinsUnfolded),
76 fExtraBinsUnfolded(obj.fExtraBinsUnfolded),
77 fbVariableBinning(obj.fbVariableBinning),
78 fPtMaxUnfVarBinning(obj.fPtMaxUnfVarBinning),
79 f1MergeFunction(obj.f1MergeFunction),
80 fFineFrac(obj.fFineFrac),
81 fbCalcErrors(obj.fbCalcErrors)
84 //--------------------------------------------------------------------------------------------------------------------------------------------------
85 AliAnaChargedJetResponseMaker& AliAnaChargedJetResponseMaker::operator=(const AliAnaChargedJetResponseMaker& other)
88 if(&other == this) return *this;
89 AliAnaChargedJetResponseMaker::operator=(other);
90 fDebug = other.fDebug;
91 fResolutionType = other.fResolutionType;
92 fDeltaPt = other.fDeltaPt;
93 fhDeltaPt = other.fhDeltaPt;
94 fDimensions = other.fDimensions;
95 fDimRec = other.fDimRec;
96 fDimGen = other.fDimGen;
97 fPtMin = other.fPtMin;
98 fPtMax = other.fPtMax;
99 fNbins = other.fNbins;
100 fBinArrayPtRec = other.fBinArrayPtRec;
101 fPtMeasured = other.fPtMeasured;
102 fEffFlat = other.fEffFlat;
103 fEfficiency = other.fEfficiency;
104 fEfficiencyFine = other.fEfficiencyFine;
105 fResponseMatrix = other.fResponseMatrix;
106 fResponseMatrixFine = other.fResponseMatrixFine;
107 fPtMinUnfolded = other.fPtMinUnfolded;
108 fPtMaxUnfolded = other.fPtMaxUnfolded;
109 fPtMaxUnfoldedHigh = other.fPtMaxUnfoldedHigh;
110 fBinWidthFactorUnfolded = other.fBinWidthFactorUnfolded;
111 fSkipBinsUnfolded = other.fSkipBinsUnfolded;
112 fExtraBinsUnfolded = other.fExtraBinsUnfolded;
113 fbVariableBinning = other.fbVariableBinning;
114 fPtMaxUnfVarBinning = other.fPtMaxUnfVarBinning;
115 f1MergeFunction = other.f1MergeFunction;
116 fFineFrac = other.fFineFrac;
117 fbCalcErrors = other.fbCalcErrors;
122 //--------------------------------------------------------------------------------------------------------------------------------------------------
123 void AliAnaChargedJetResponseMaker::SetMeasuredSpectrum(TH1D *hPtMeasured)
126 // Set measured spectrum in THnSparse format
127 // This defines the minimum and maximum pT on the reconstructed axis of the response matrix
129 if(fDebug) printf(">>AliAnaChargedJetResponseMaker::SetMeasuredSpectrum \n");
131 fNbins = hPtMeasured->GetXaxis()->GetNbins();
132 fPtMin = hPtMeasured->GetXaxis()->GetXmin();
133 fPtMax = hPtMeasured->GetXaxis()->GetXmax();
135 if(fDebug) printf("fNbins: %d fPtMin: %f fPtMax: %f \n",fNbins,fPtMin,fPtMax);
137 if(fBinArrayPtRec) delete fBinArrayPtRec;
138 fBinArrayPtRec = new Double_t[fNbins+1];
139 for(int j = 0; j<fNbins; j++) {
140 fBinArrayPtRec[j] = hPtMeasured->GetXaxis()->GetBinLowEdge(j+1);
142 fBinArrayPtRec[fNbins] = hPtMeasured->GetXaxis()->GetBinUpEdge(fNbins);
145 Int_t nbins[fDimensions];
146 Double_t xmin[fDimensions];
147 Double_t xmax[fDimensions];
148 for(int dim = 0; dim<fDimensions; dim++) {
154 if(fPtMeasured) delete fPtMeasured;
155 fPtMeasured = new THnSparseD("fPtMeasured","Measured pT spectrum; p_{T}^{rec}",fDimensions,nbins,xmin,xmax);
156 fPtMeasured->Sumw2();
157 fPtMeasured->GetAxis(0)->SetTitle("p_{T}^{rec}");
158 fPtMeasured->SetBinEdges(0,fBinArrayPtRec);
161 if(fDebug) printf("fill measured THnSparse\n");
162 if(fNbins!=hPtMeasured->GetNbinsX())
163 printf("WARNING: nbins not correct \t %d vs %d !!!\n",fNbins,hPtMeasured->GetNbinsX());
167 for(int i = hPtMeasured->FindBin(fPtMin); i<hPtMeasured->FindBin(fPtMax); i++) {
169 pT[0]= hPtMeasured->GetBinCenter(i);
170 fPtMeasured->SetBinContent(bin,(Double_t)hPtMeasured->GetBinContent(i));
171 fPtMeasured->SetBinError(bin,(Double_t)hPtMeasured->GetBinError(i));
175 if(fDebug) printf("fPtMeasured->GetNbins(): %d \n",(int)fPtMeasured->GetNbins());
179 //--------------------------------------------------------------------------------------------------------------------------------------------------
180 void AliAnaChargedJetResponseMaker::SetFlatEfficiency(Double_t eff) {
183 // Set flat efficiency to value of eff
190 Int_t nbins[fDimensions];
191 Double_t xmin[fDimensions];
192 Double_t xmax[fDimensions];
193 for(int dim = 0; dim<fDimensions; dim++) {
199 if(fEfficiency) delete fEfficiency;
200 fEfficiency = new THnSparseD("fEfficiency","Efficiency - no resolution effects; p_{T}^{gen}",fDimensions,nbins,xmin,xmax);
201 fEfficiency->Sumw2();
202 fEfficiency->GetAxis(0)->SetTitle("p_{T}^{gen}");
203 fEfficiency->SetBinEdges(0,fBinArrayPtRec);
205 for(int i=0; i<fNbins; i++) {
208 fEfficiency->SetBinContent(bin,fEffFlat);
209 fEfficiency->SetBinError(bin,0);
214 //--------------------------------------------------------------------------------------------------------------------------------------------------
215 void AliAnaChargedJetResponseMaker::SetEfficiency(TGraphErrors *grEff)
218 // Fill fEfficiency (THnSparse) with values from grEff
221 Int_t nbins[fDimensions];
222 Double_t xmin[fDimensions];
223 Double_t xmax[fDimensions];
224 for(int dim = 0; dim<fDimensions; dim++) {
230 if(fEfficiency) delete fEfficiency;
231 fEfficiency = new THnSparseD("fEfficiency","Efficiency - no resolution effects; p_{T}^{gen}",fDimensions,nbins,xmin,xmax);
232 fEfficiency->Sumw2();
233 fEfficiency->GetAxis(0)->SetTitle("p_{T}^{gen}");
234 fEfficiency->SetBinEdges(0,fBinArrayPtRec);
240 int nbinsgr = grEff->GetN();
242 for(int i=0; i<nbinsgr; i++) {
243 grEff->GetPoint(i,dummy,yield);
245 error = grEff->GetErrorY(i);
247 fEfficiency->Fill(pT,yield);
248 fEfficiency->SetBinError(i,error);
254 //--------------------------------------------------------------------------------------------------------------------------------------------------
255 void AliAnaChargedJetResponseMaker::MakeResponseMatrixJetsFineMerged(Int_t skipBins, Int_t binWidthFactor, Int_t extraBins, Bool_t bVariableBinning, Double_t ptmax)
258 // Make jet response matrix
261 if(fDebug) printf(">>AliAnaChargedJetResponseMaker::MakeResponseMatrixJetsFineMerged\n");
264 if(fDebug) printf("fPtMeasured does not exist. Aborting!!\n");
267 if(fResponseMatrix) { delete fResponseMatrix; }
268 if(fResponseMatrixFine) { delete fResponseMatrixFine; }
270 SetSkipBinsUnfolded(skipBins);
271 SetBinWidthFactorUnfolded(binWidthFactor);
272 SetExtraBinsUnfolded(extraBins);
273 SetVariableBinning(bVariableBinning,ptmax);
275 InitializeResponseMatrix();
276 InitializeEfficiency();
278 InitializeResponseMatrixFine();
279 InitializeEfficiencyFine();
281 FillResponseMatrixFineAndMerge();
285 //--------------------------------------------------------------------------------------------------------------------------------------------------
286 void AliAnaChargedJetResponseMaker::InitializeResponseMatrix() {
288 //Define bin edges of RM to be used for unfolding
291 Int_t nbins[fDimensions*2];
292 nbins[fDimRec] = fNbins;
293 nbins[fDimGen] = fNbins;
295 double binWidthMeas = (double)((fPtMax-fPtMin)/fNbins);
296 double binWidthUnf = (double)fBinWidthFactorUnfolded*binWidthMeas;
297 double binWidthUnfLowPt = -1.;
298 if(fbVariableBinning)
299 binWidthUnfLowPt = binWidthUnf*0.5;
301 if(fExtraBinsUnfolded>0) {
302 fPtMaxUnfolded = fPtMax+(double)(fExtraBinsUnfolded)*binWidthUnf;
303 nbins[fDimGen]+=fExtraBinsUnfolded;
306 printf("fPtMinMeas: %f fPtMaxMeas: %f\n",fPtMin,fPtMax);
307 printf("binWidthMeas: %f binWidthUnf: %f fBinWidthFactorUnfolded: %d\n",binWidthMeas,binWidthUnf,fBinWidthFactorUnfolded);
308 printf("binWidthUnfLowPt: %f\n",binWidthUnfLowPt);
310 int tmp = round((fPtMaxUnfolded-fPtMinUnfolded)/binWidthUnf); //nbins which fit between 0 and fPtMaxUnfolded
311 tmp = tmp - fSkipBinsUnfolded;
312 fPtMinUnfolded = fPtMaxUnfolded-(double)(tmp)*binWidthUnf; //set ptmin unfolded
313 fPtMaxUnfolded = fPtMinUnfolded+(double)(tmp)*binWidthUnf; //set ptmax unfolded
314 nbins[fDimGen] = (int)((fPtMaxUnfolded-fPtMinUnfolded)/binWidthUnf); //adjust nbins to bin width
316 if(fbVariableBinning) {
317 tmp = (int)(fPtMaxUnfVarBinning/binWidthUnfLowPt);
318 tmp = tmp - fSkipBinsUnfolded;
319 fPtMinUnfolded = fPtMaxUnfVarBinning-(double)(tmp)*binWidthUnfLowPt;
320 //Redefine also number of bins on generated axis in case of variable binning
321 nbins[fDimGen] = (int)((fPtMaxUnfVarBinning-fPtMinUnfolded)/binWidthUnfLowPt)+(int)((fPtMaxUnfolded-fPtMaxUnfVarBinning)/binWidthUnf);
324 Double_t binWidth[2];
325 binWidth[fDimRec] = (double)((fPtMax-fPtMin)/nbins[fDimRec]);
326 binWidth[fDimGen] = (double)((fPtMaxUnfolded-fPtMinUnfolded)/nbins[fDimGen]);
328 Double_t xmin[fDimensions*2];
329 Double_t xmax[fDimensions*2];
330 xmin[fDimRec] = fPtMin;
331 xmax[fDimRec] = fPtMax;
332 xmin[fDimGen] = fPtMinUnfolded;
333 xmax[fDimGen] = fPtMaxUnfolded;
335 printf("xmin[fDimRec]: %f xmin[fDimGen]: %f \n",xmin[fDimRec],xmin[fDimGen]);
336 printf("xmax[fDimRec]: %f xmax[fDimGen]: %f \n",xmax[fDimRec],xmax[fDimGen]);
337 printf("nbins[fDimRec]: %d nbins[fDimGen]: %d \n",nbins[fDimRec],nbins[fDimGen]);
338 if(!fbVariableBinning) printf("binWidth[fDimRec]: %f binWidth[fDimGen]: %f \n",binWidth[fDimRec],binWidth[fDimGen]);
340 Double_t binArrayPt0[nbins[fDimRec]+1];
341 Double_t binArrayPt1[nbins[fDimGen]+1];
342 Double_t xmaxGen = TMath::Max(xmax[fDimGen],fPtMaxUnfoldedHigh);
344 //Define bin limits reconstructed/measured axis
345 for(int i=0; i<nbins[fDimRec]; i++) {
346 binArrayPt0[i] = xmin[fDimRec]+(double)i*binWidth[fDimRec];
348 binArrayPt0[nbins[fDimRec]]= xmax[fDimRec];
350 //Define bin limits generated/unfolded axis
351 binArrayPt1[0] = fPtMinUnfolded;
352 for(int i=1; i<nbins[fDimGen]; i++) {
353 if(fbVariableBinning) {
354 double test = xmin[fDimGen]+(double)i*binWidthUnfLowPt;
355 if(test<=fPtMaxUnfVarBinning) binArrayPt1[i] = test;
356 else binArrayPt1[i] = binArrayPt1[i-1]+binWidthUnf;
359 binArrayPt1[i] = xmin[fDimGen]+(double)i*binWidth[fDimGen];
360 //printf("RM. i = %d \t binArrayPt[i] = %f \n",i,binArrayPt1[i]);
362 binArrayPt1[nbins[fDimGen]]= xmaxGen;
365 // Response matrix : dimensions must be 2N = 2 x (number of variables)
366 // dimensions 0 -> N-1 must be filled with reconstructed values
367 // dimensions N -> 2N-1 must be filled with generated values
368 if(fResponseMatrix) delete fResponseMatrix;
369 fResponseMatrix = new THnSparseD("fResponseMatrix","Response Matrix pTMC vs pTrec",fDimensions*2,nbins,xmin,xmax);
370 fResponseMatrix->Sumw2();
371 fResponseMatrix->GetAxis(fDimRec)->SetTitle("p_{T}^{rec}");
372 fResponseMatrix->GetAxis(fDimGen)->SetTitle("p_{T}^{gen}");
374 fResponseMatrix->SetBinEdges(fDimRec,binArrayPt0);
375 fResponseMatrix->SetBinEdges(fDimGen,binArrayPt1);
377 Int_t bin[2] = {1,1};
378 for(int i=1; i<fResponseMatrix->GetAxis(0)->GetNbins(); i++) {
380 for(int j=1; j<fResponseMatrix->GetAxis(1)->GetNbins(); j++) {
382 fResponseMatrix->SetBinContent(bin,0.);
390 //--------------------------------------------------------------------------------------------------------------------------------------------------
391 void AliAnaChargedJetResponseMaker::InitializeEfficiency() {
393 // Define dimensions of efficiency THnSparse
396 if(!fResponseMatrix) {
397 printf("AliAnaChargedJetResponseMaker::InitializeEfficiency()\n");
398 printf("Can not define dimensions efficiency without fResponseMatrix dimensions. Aborting \n");
402 TAxis *genAxis = fResponseMatrix->GetAxis(fDimGen);
404 Int_t nbinsEff[fDimensions];
405 Double_t xminEff[fDimensions];
406 Double_t xmaxEff[fDimensions];
408 for(int dim = 0; dim<fDimensions; dim++) {
409 nbinsEff[dim] = genAxis->GetNbins();
410 xminEff[dim] = genAxis->GetXmin();
411 xmaxEff[dim] = genAxis->GetXmax();
414 if(fEfficiency) delete fEfficiency;
415 fEfficiency = new THnSparseD("fEfficiency","Efficiency - no resolution effects; p_{T}^{gen}",fDimensions,nbinsEff,xminEff,xmaxEff);
416 fEfficiency->Sumw2();
417 fEfficiency->GetAxis(0)->SetTitle("p_{T}^{gen}");
419 const Double_t *binArrayPt = genAxis->GetXbins()->GetArray();
420 fEfficiency->SetBinEdges(0,binArrayPt);
424 //--------------------------------------------------------------------------------------------------------------------------------------------------
425 void AliAnaChargedJetResponseMaker::InitializeResponseMatrixFine() {
427 //Initialize fine response matrix
430 Int_t nbinsFine[fDimensions*2];
431 Double_t xminFine[fDimensions*2];
432 Double_t xmaxFine[fDimensions*2];
433 Double_t pTarrayFine[fDimensions*2];
435 nbinsFine[fDimRec] = fResponseMatrix->GetAxis(fDimRec)->GetNbins()*fFineFrac;
436 nbinsFine[fDimGen] = fResponseMatrix->GetAxis(fDimRec)->GetNbins()*fFineFrac;
437 xminFine[fDimRec] = TMath::Min(fPtMin,0.);
438 xminFine[fDimGen] = TMath::Min(fPtMin,0.);
439 xmaxFine[fDimRec] = fResponseMatrix->GetAxis(fDimGen)->GetXmax()+40.;
440 xmaxFine[fDimGen] = fResponseMatrix->GetAxis(fDimGen)->GetXmax()+40.;
441 pTarrayFine[fDimRec] = 0.;
442 pTarrayFine[fDimGen] = 0.;
444 Double_t binWidth[2];
445 binWidth[fDimRec] = fResponseMatrix->GetAxis(fDimRec)->GetBinWidth(1);
447 Double_t binWidthFine[2];
448 binWidthFine[fDimRec] = binWidth[fDimRec]/((double)fFineFrac);
449 binWidthFine[fDimGen] = binWidthFine[fDimRec]*(double)fBinWidthFactorUnfolded;
451 nbinsFine[fDimRec] = (int)((xmaxFine[fDimRec]-xminFine[fDimRec])/binWidthFine[fDimRec]); //adjust nbins to bin width
452 nbinsFine[fDimGen] = (int)((xmaxFine[fDimGen]-xminFine[fDimGen])/binWidthFine[fDimGen]); //adjust nbins to bin width
454 printf("xminFine[fDimRec]: %f xminFine[fDimGen]: %f \n",xminFine[fDimRec],xminFine[fDimGen]);
455 printf("xmaxFine[fDimRec]: %f xmaxFine[fDimGen]: %f \n",xmaxFine[fDimRec],xmaxFine[fDimGen]);
456 printf("nbinsFine[fDimRec]: %d nbinsFine[fDimGen]: %d \n",nbinsFine[fDimRec],nbinsFine[fDimGen]);
457 printf("binWidthFine[fDimRec]: %f binWidthFine[fDimGen]: %f \n",binWidthFine[fDimRec],binWidthFine[fDimGen]);
460 Double_t binArrayPt0Fine[nbinsFine[fDimRec]+1];
461 Double_t binArrayPt1Fine[nbinsFine[fDimGen]+1];
463 for(int i=0; i<nbinsFine[fDimRec]; i++) {
464 binArrayPt0Fine[i] = xminFine[fDimRec]+(double)i*binWidthFine[fDimRec];
465 // printf("RM. i = %d \t binArrayPtFine[i] = %f \n",i,binArrayPt0Fine[i]);
467 binArrayPt0Fine[nbinsFine[fDimRec]]= xmaxFine[fDimRec];
469 for(int i=0; i<nbinsFine[fDimGen]; i++) {
470 binArrayPt1Fine[i] = xminFine[fDimGen]+(double)i*binWidthFine[fDimGen];
471 // printf("RM. i = %d \t binArrayPtFine[i] = %f \n",i,binArrayPt1Fine[i]);
473 binArrayPt1Fine[nbinsFine[fDimGen]]= xmaxFine[fDimGen];
475 // Response matrix : dimensions must be 2N = 2 x (number of variables)
476 // dimensions 0 -> N-1 must be filled with reconstructed values
477 // dimensions N -> 2N-1 must be filled with generated values
478 if(fResponseMatrixFine) delete fResponseMatrixFine;
479 fResponseMatrixFine = new THnSparseD("fResponseMatrixFine","Response Matrix pTMC vs pTrec",fDimensions*2,nbinsFine,xminFine,xmaxFine);
480 fResponseMatrixFine->Sumw2();
481 fResponseMatrixFine->GetAxis(fDimRec)->SetTitle("p_{T}^{rec}");
482 fResponseMatrixFine->GetAxis(fDimGen)->SetTitle("p_{T}^{gen}");
484 fResponseMatrixFine->SetBinEdges(fDimRec,binArrayPt0Fine);
485 fResponseMatrixFine->SetBinEdges(fDimGen,binArrayPt1Fine);
487 Int_t bin[2] = {1,1};
488 for(int i=1; i<fResponseMatrixFine->GetAxis(0)->GetNbins(); i++) {
490 for(int j=1; j<fResponseMatrixFine->GetAxis(1)->GetNbins(); j++) {
492 fResponseMatrixFine->SetBinContent(bin,0.);
498 //--------------------------------------------------------------------------------------------------------------------------------------------------
499 void AliAnaChargedJetResponseMaker::InitializeEfficiencyFine() {
501 // Define dimensions of efficiency THnSparse
504 if(!fResponseMatrixFine) {
505 printf("AliAnaChargedJetResponseMaker::InitializeEfficiencyFine()\n");
506 printf("Can not define dimensions efficiency without fResponseMatrixFine dimensions. Aborting \n");
510 TAxis *genAxis = fResponseMatrixFine->GetAxis(fDimGen);
512 Int_t nbinsEff[fDimensions];
513 Double_t xminEff[fDimensions];
514 Double_t xmaxEff[fDimensions];
516 for(int dim = 0; dim<fDimensions; dim++) {
517 nbinsEff[dim] = genAxis->GetNbins();
518 xminEff[dim] = genAxis->GetXmin();
519 xmaxEff[dim] = genAxis->GetXmax();
522 if(fEfficiencyFine) delete fEfficiencyFine;
523 fEfficiencyFine = new THnSparseD("fEfficiencyFine","EfficiencyFine - no resolution effects; p_{T}^{gen}",fDimensions,nbinsEff,xminEff,xmaxEff);
524 fEfficiencyFine->Sumw2();
525 fEfficiencyFine->GetAxis(0)->SetTitle("p_{T}^{gen}");
527 const Double_t *binArrayPt = genAxis->GetXbins()->GetArray();
528 fEfficiencyFine->SetBinEdges(0,binArrayPt);
532 //--------------------------------------------------------------------------------------------------------------------------------------------------
533 void AliAnaChargedJetResponseMaker::FillResponseMatrixFineAndMerge() {
535 // Fill fine response matrix
538 if(!fResponseMatrix) {
539 printf("Dimensions of fResponseMatrix have to be defined first. Aborting!");
543 if(!fResponseMatrixFine) {
544 printf("Dimensions of fResponseMatrixFine have to be defined first. Aborting!");
548 TAxis *genAxis = fResponseMatrixFine->GetAxis(fDimGen);
549 TAxis *recAxis = fResponseMatrixFine->GetAxis(fDimRec);
551 Int_t nbinsFine[fDimensions*2];
552 Double_t xminFine[fDimensions*2];
553 Double_t xmaxFine[fDimensions*2];
554 Double_t pTarrayFine[fDimensions*2];
556 nbinsFine[fDimGen] = genAxis->GetNbins();
557 nbinsFine[fDimRec] = recAxis->GetNbins();
558 xminFine[fDimGen] = genAxis->GetXmin();
559 xminFine[fDimRec] = recAxis->GetXmin();
560 xmaxFine[fDimGen] = genAxis->GetXmax();
561 xmaxFine[fDimRec] = recAxis->GetXmax();
562 pTarrayFine[fDimGen] = 0.;
563 pTarrayFine[fDimRec] = 0.;
565 double sumyield = 0.;
566 double sumyielderror2 = 0.;
568 int ipt[2] = {0.,0.};
569 int iptMerged[2] = {0.,0.};
570 int ierror[2] = {0.,0.};
573 Double_t pTgen, pTrec;
577 const int nng = fResponseMatrix->GetAxis(fDimGen)->GetNbins();
578 const int nnr = fResponseMatrix->GetAxis(fDimRec)->GetNbins();
579 Double_t errorArray[nng][nnr];
580 for(int iig =0; iig<nng; iig++) {
581 for(int iir =0; iir<nnr; iir++) {
582 errorArray[iig][iir] = 0.;
586 for(int iy=1; iy<=nbinsFine[fDimGen]; iy++) { //gen
587 pTgen = fResponseMatrixFine->GetAxis(fDimGen)->GetBinCenter(iy);
588 pTarrayFine[fDimGen] = pTgen;
593 for(int ix=1; ix<=nbinsFine[fDimRec]; ix++) { //rec
594 pTrec = fResponseMatrixFine->GetAxis(fDimRec)->GetBinCenter(ix);
595 Double_t width = fResponseMatrixFine->GetAxis(fDimRec)->GetBinWidth(ix);
596 if(fResolutionType==kParam) {
597 yield = fDeltaPt->Eval(pTrec-pTgen);
600 else if(fResolutionType==kResiduals) {
601 yield = fhDeltaPt->Interpolate(pTrec-pTgen);
604 else if(fResolutionType==kResidualsErr) {
605 Double_t deltaPt = pTrec-pTgen;
606 int bin = fhDeltaPt->FindBin(deltaPt);
607 yield = fhDeltaPt->GetBinContent(bin);
608 error = fhDeltaPt->GetBinError(bin);
612 //avoid trouble with empty bins in the high pT tail of deltaPt distribution
613 if(check==0 && yield>0. && pTrec>pTgen) check=1;
614 if(check==1 && yield==0.) ix=nbinsFine[fDimRec];
617 sumyielderror2 += error*error;
619 pTarrayFine[fDimRec] = pTrec;
620 ierror[fDimRec] = ix;
621 fResponseMatrixFine->Fill(pTarrayFine,yield);
622 if(fbCalcErrors) fResponseMatrixFine->SetBinError(ierror,error);
626 //Normalize to total number of counts =1
629 for(int ix=1; ix<=nbinsFine[fDimRec]; ix++) {
631 fResponseMatrixFine->SetBinContent(ipt,fResponseMatrixFine->GetBinContent(ipt)/sumyield);
632 if(fResolutionType==kResidualsErr && fbCalcErrors) {
633 Double_t A = 1./sumyield*fResponseMatrix->GetBinError(ipt);
634 Double_t B = -1.*fResponseMatrix->GetBinContent(ipt)/sumyield/sumyield*TMath::Sqrt(sumyielderror2);
635 Double_t tmp2 = A*A + B*B;
636 fResponseMatrix->SetBinError(ipt,TMath::Sqrt(tmp2));
644 fEfficiencyFine->SetBinContent(bin,sumyield);
645 if(fbCalcErrors) fEfficiencyFine->SetBinError(bin,TMath::Sqrt(sumyielderror2));
647 //fill merged response matrix
649 //find bin in fine RM correspoinding to mimimum/maximum bin of merged RM on rec axis
650 int ixMin = fResponseMatrixFine->GetAxis(fDimRec)->FindBin(fResponseMatrix->GetAxis(fDimRec)->GetXmin());
651 int ixMax = fResponseMatrixFine->GetAxis(fDimRec)->FindBin(fResponseMatrix->GetAxis(fDimRec)->GetXmax());
653 if(fResponseMatrixFine->GetAxis(fDimGen)->GetBinLowEdge(iy) >= fResponseMatrix->GetAxis(fDimGen)->GetXmin()) {
655 iptMerged[fDimGen]=fResponseMatrix->GetAxis(fDimGen)->FindBin(pTgen);
657 Double_t weight = 1.;
658 if(f1MergeFunction) {
659 Double_t loEdge = fResponseMatrix->GetAxis(fDimGen)->GetBinLowEdge(iptMerged[fDimGen]);
660 Double_t upEdge = fResponseMatrix->GetAxis(fDimGen)->GetBinUpEdge(iptMerged[fDimGen]);
661 Float_t powInteg = f1MergeFunction->Integral(loEdge,upEdge);
662 //printf("loEdge = %f upEdge = %f powInteg = %f\n",loEdge,upEdge,powInteg);
664 weight = f1MergeFunction->Integral(fResponseMatrixFine->GetAxis(fDimGen)->GetBinLowEdge(iy),fResponseMatrixFine->GetAxis(fDimGen)->GetBinUpEdge(iy))/powInteg;
665 // printf("weight: %f \n", weight );
667 weight = 1./((double)fFineFrac);
670 for(int ix=ixMin; ix<=ixMax; ix++) { //loop reconstructed axis
671 pTrec = fResponseMatrixFine->GetAxis(fDimRec)->GetBinCenter(ix);
673 iptMerged[fDimRec]=fResponseMatrix->GetAxis(fDimRec)->FindBin(pTrec);
675 fResponseMatrix->AddBinContent(iptMerged,fResponseMatrixFine->GetBinContent(ipt)*weight);
676 if(fbCalcErrors) errorArray[iptMerged[fDimGen]-1][iptMerged[fDimRec]-1] += fResponseMatrixFine->GetBinError(ipt)*fResponseMatrixFine->GetBinError(ipt)*weight*weight;
679 }//loop gen axis fine response matrix
681 } // iy (dimGen) loop
683 //Fill Efficiency corresponding to merged response matrix
684 // FillEfficiency(errorArray,fFineFrac);
686 for(int iy=1; iy<=fResponseMatrix->GetAxis(fDimGen)->GetNbins(); iy++) { //gen
690 for(int ix=1; ix<=fResponseMatrix->GetAxis(fDimRec)->GetNbins(); ix++) { //rec
692 sumyield += fResponseMatrix->GetBinContent(ipt);
694 if(fbCalcErrors) fResponseMatrix->SetBinError(ipt,TMath::Sqrt(errorArray[iy][ix]));
696 printf("RM: pTgen: %f \t sumyield: %f \n",fResponseMatrix->GetAxis(fDimGen)->GetBinCenter(iy),sumyield);
699 fEfficiency->SetBinContent(bin,sumyield);
700 if(fbCalcErrors) fEfficiency->SetBinError(bin,0);
703 if(fDebug) printf("fResponseMatrixFine->GetNbins(): %d \n",(int)fResponseMatrixFine->GetNbins());
704 if(fDebug) printf("fResponseMatrix->GetNbins(): %d \n",(int)fResponseMatrix->GetNbins());
706 if(fDebug) printf("Done constructing response matrix\n");
710 //--------------------------------------------------------------------------------------------------------------------------------------------------
711 TH2* AliAnaChargedJetResponseMaker::MakeResponseMatrixRebin(TH2 *hRMFine, TH2 *hRM) {
714 // Rebin matrix hRMFine to dimensions of hRM
715 // function returns matrix in TH2D format with dimensions from hRM
718 TH2 *hRM2 = (TH2*)hRM->Clone("hRM2");
721 //First normalize columns of input
722 const Int_t nbinsNorm = hRM2->GetNbinsX();
723 cout << "nbinsNorm: " << nbinsNorm << endl;
725 TArrayF *normVector = new TArrayF(nbinsNorm);
727 for(int ix=1; ix<=hRM2->GetNbinsX(); ix++) {
728 Double_t xLow = hRM2->GetXaxis()->GetBinLowEdge(ix);
729 Double_t xUp = hRM2->GetXaxis()->GetBinUpEdge(ix);
730 //cout << "xLow: " << xLow << " xUp: " << xUp << "\t center: " << hRM2->GetXaxis()->GetBinCenter(ix) << endl;
731 Int_t binxLowFine = hRMFine->GetXaxis()->FindBin(xLow);
732 Int_t binxUpFine = hRMFine->GetXaxis()->FindBin(xUp)-1;
733 //cout << "xLowFine: " << hRMFine->GetXaxis()->GetBinLowEdge(binxLowFine) << "\txUpFine: " << hRMFine->GetXaxis()->GetBinUpEdge(binxUpFine) << endl;
734 normVector->SetAt(hRMFine->Integral(binxLowFine,binxUpFine,1,hRMFine->GetYaxis()->GetNbins()),ix-1);
735 if(fDebug) cout << "ix norm: " << normVector->At(ix-1) << endl;
738 Double_t content, oldcontent = 0.;
741 Double_t xvalLo, xvalUp, yvalLo, yvalUp;
742 Double_t xmin = hRM2->GetXaxis()->GetXmin();
743 Double_t ymin = hRM2->GetYaxis()->GetXmin();
744 Double_t xmax = hRM2->GetXaxis()->GetXmax();
745 Double_t ymax = hRM2->GetYaxis()->GetXmax();
746 for(int ix=1; ix<=hRMFine->GetXaxis()->GetNbins(); ix++) {
747 xvalLo = hRMFine->GetXaxis()->GetBinLowEdge(ix);
748 xvalUp = hRMFine->GetXaxis()->GetBinUpEdge(ix);
749 if(xvalLo<xmin || xvalUp>xmax) continue;
750 ixNew = hRM2->GetXaxis()->FindBin(hRMFine->GetXaxis()->GetBinCenter(ix));
751 for(int iy=1; iy<=hRMFine->GetYaxis()->GetNbins(); iy++) {
752 yvalLo = hRMFine->GetYaxis()->GetBinLowEdge(iy);
753 yvalUp = hRMFine->GetYaxis()->GetBinUpEdge(iy);
754 if(yvalLo<ymin || yvalUp>ymax) continue;
755 content = hRMFine->GetBinContent(ix,iy);
756 iyNew = hRM2->GetYaxis()->FindBin(hRMFine->GetYaxis()->GetBinCenter(iy));
757 oldcontent = hRM2->GetBinContent(ixNew,iyNew);
759 //if(fDebug) cout << "ixNew: " << ixNew << " " << xvalLo << " iyNew: " << iyNew << " " << yvalLo << " content: " << content << " oldContent: " << oldcontent << " newContent: " << oldcontent+content << endl;
760 Double_t weight = 1.;
761 if(normVector->At(ixNew-1)>0.) weight = 1./normVector->At(ixNew-1);
762 hRM2->SetBinContent(ixNew,iyNew,oldcontent+content*weight);
766 if(normVector) delete normVector;
772 //--------------------------------------------------------------------------------------------------------------------------------------------------
773 TH2* AliAnaChargedJetResponseMaker::MultiplityResponseMatrices(TH2 *h2RMDeltaPt, TH2 *h2RMDetector) {
776 // Make combined response matrix (background flucutuations + detector effects)
778 // hRMDeltaPt is the response matrix for background fluctuations from \delta(p_t) measurement
779 // hRMDetector is the response matrix for detector effects: needs to be a squared matrix with on each axis the same bins as on the generated axis of the bkg fluctuations response matrix
781 // Function assumes that generated/unfolded axis is x-axis and reconstructed is on y-axis on both respone matrices
784 TH2D *h2ResponseMatrixCombined = (TH2D*)h2RMDeltaPt->Clone("h2ResponseMatrixCombined"); //h2ResponseMatrix is the bkg fluctuations RM which has the dimensions we want for the combined response matrix
785 h2ResponseMatrixCombined->SetTitle("h2ResponseMatrixCombined");
786 h2ResponseMatrixCombined->SetName("h2ResponseMatrixCombined");
788 // M = RM_deltaPt * RM_DetEffects * T (M=measured T=truth)
790 // mx1 = mxd * dxt * tx1
793 // d = rec for RM_DetEffects and gen for RM_deltaPt
794 // RM_comb = RM_deltaPt * RM_DetEffects (dimensions mxt)
795 // RM_comb(m,t) = Sum_d RM_deltaPt(m,d)*RM_DetEffects(d,t)
798 printf("Nt=%d",h2ResponseMatrixCombined->GetNbinsX());
799 printf("Nm=%d",h2ResponseMatrixCombined->GetNbinsY());
800 printf("Nd=%d",h2RMDetector->GetNbinsX());
803 for(Int_t t=1; t<=h2ResponseMatrixCombined->GetNbinsX();t++) {
804 for(Int_t m=1; m<=h2ResponseMatrixCombined->GetNbinsY();m++) {
805 Double_t valueSum = 0.;
806 for(Int_t d=1; d<=h2RMDeltaPt->GetNbinsX();d++) {
807 valueSum += h2RMDeltaPt->GetBinContent(d,m) * h2RMDetector->GetBinContent(t,d);
809 // cout << "t,m = " << t << "," << m << endl;
810 h2ResponseMatrixCombined->SetBinContent(t,m,valueSum);
814 return h2ResponseMatrixCombined;
818 //--------------------------------------------------------------------------------------------------------------------------------------------------
819 TH1D* AliAnaChargedJetResponseMaker::MultiplyResponseGenerated(TH1 *hGen, TH2 *hResponse,TH1 *hEfficiency,Bool_t bDrawSlices) {
822 // Multiply hGen with response matrix to obtain refolded spectrum
823 // Efficiency must be given. In case efficiency is 1 use SetFlatEfficiency(1.) before calling function
827 printf("Efficiency must be given. In case efficiency is 1 use SetFlatEfficiency(1.) before calling function. Aborting!");
833 //y-axis: reconstructed
834 if(fDebug>0) cout << "nbins hGen: " << hGen->GetNbinsX() << "\t nbins hResponseGen: " << hResponse->GetXaxis()->GetNbins() << "\t nbins hResponseRec: " << hResponse->GetYaxis()->GetNbins() << endl;
836 TH1D *hRec = hResponse->ProjectionY("hRec");
839 hRec->SetTitle("hRec");
840 hRec->SetName("hRec");
842 for(int irec=1; irec<=hRec->GetNbinsX(); irec++)
843 hRec->SetBinContent(irec,0);
845 TH1D *hRecGenBin = 0x0;
846 TCanvas *cSlices = 0x0;
848 cSlices = new TCanvas("cSlices","cSlices:Slices",400,400);
852 Double_t yieldMC = 0.;
853 Double_t yieldMCerror = 0.;
854 Double_t sumYield = 0.;
855 const Int_t nbinsRec = hRec->GetNbinsX();
856 Double_t sumError2[nbinsRec+1];
859 for(int igen=1; igen<=hGen->GetNbinsX(); igen++) {
865 eff = hEfficiency->GetBinContent(igen);
866 yieldMC = hGen->GetBinContent(igen)*eff;
867 // yieldMCerror = hGen->GetBinError(igen);
870 hRecGenBin = hResponse->ProjectionY(Form("hRecGenBin%d",igen));
873 hRecGenBin->SetTitle(Form("hRecGenBin%d",igen));
874 hRecGenBin->SetName(Form("hRecGenBin%d",igen));
877 for(int irec=1; irec<=hRec->GetNbinsX(); irec++) {
878 hRec->AddBinContent(irec,yieldMC*hResponse->GetBinContent(igen,irec));
879 sumYield+=hResponse->GetBinContent(igen,irec);
880 Double_t A = yieldMC*hResponse->GetBinError(igen,irec);
881 Double_t B = hResponse->GetBinContent(igen,irec)*yieldMCerror;
882 Double_t tmp2 = A*A + B*B;
883 sumError2[irec-1] += tmp2 ;
886 hRecGenBin->SetBinContent(irec,yieldMC*hResponse->GetBinContent(igen,irec));
891 hRecGenBin->SetLineColor(igen);
892 if(igen==1) hRecGenBin->DrawCopy();
893 else hRecGenBin->DrawCopy("same");
896 if(hRecGenBin) delete hRecGenBin;
898 cout << "igen: " << igen << "\tpTMC: " << hGen->GetXaxis()->GetBinCenter(igen) << "\teff:" << eff << "\tsumYield: " << sumYield << endl;
901 for(int i=0; i<=nbinsRec; i++) {
903 hRec->SetBinError(i+1,TMath::Sqrt(sumError2[i]));
910 //--------------------------------------------------------------------------------------------------------------------------------------------------
911 TH1D* AliAnaChargedJetResponseMaker::MultiplyResponseGenerated(TF1 *fGen, TH2 *hResponse,TH1 *hEfficiency) {
914 // Multiply fGen function with response matrix to obtain (re)folded spectrum
915 // Efficiency must be given. In case efficiency is 1 use SetFlatEfficiency(1.) before calling function
920 //y-axis: reconstructed
922 if(fDebug>0) printf(">>AliAnaChargedJetResponseMaker::MultiplyResponseGenerated(TF1 *fGen, TH2 *hResponse,TH1 *hEfficiency)");
925 printf("Efficiency must be given. In case efficiency is 1 use SetFlatEfficiency(1.) before calling function. Aborting!");
929 TH1D *hRec = hResponse->ProjectionY("hRec");
932 hRec->SetTitle("hRec");
933 hRec->SetName("hRec");
935 // TH1D *hRec = new TH1D("hRec","hRec",hResponse->GetNbinsY(),hResponse->GetYaxis()->GetXmin(),hResponse->GetYaxis()->GetXmax());
937 for(int irec=1; irec<=hRec->GetNbinsX(); irec++)
938 hRec->SetBinContent(irec,0);
940 Double_t yieldMC = 0.;
941 Double_t sumYield = 0.;
943 for(int igen=1; igen<=hResponse->GetNbinsX(); igen++) {
946 double pTMC = hResponse->GetXaxis()->GetBinCenter(igen);
947 int binEff = hEfficiency->FindBin(pTMC);
951 eff = hEfficiency->GetBinContent(binEff);
952 yieldMC = fGen->Eval(pTMC)*eff;
953 for(int irec=1; irec<=hResponse->GetNbinsY(); irec++) {
954 hRec->AddBinContent(irec,yieldMC*hResponse->GetBinContent(igen,irec));
955 sumYield+=hResponse->GetBinContent(igen,irec);
957 cout << "igen: " << igen << "\tpTMC: " << pTMC << "\tsumYield: " << sumYield << endl;
963 //--------------------------------------------------------------------------------------------------------------------------------------------------
964 Double_t AliAnaChargedJetResponseMaker::InterpolateFast(TGraph *gr, Double_t x) {
966 Double_t ipmax = gr->GetN()-1.;
967 Double_t x2,y2,xold,yold;
969 Double_t xmin,ymin,xmax, ymax;
970 gr->GetPoint(0,xmin,ymin);
971 gr->GetPoint(gr->GetN()-1,xmax,ymax);
972 if(x<xmin || x>xmax) return 0;
974 Double_t ip = ipmax/2.;
976 gr->GetPoint((int)(ip),x2,y2);
984 gr->GetPoint((int)(ip),x2,y2);
988 // cout << "ipold: " << ipold << "\tip: " << ip << "\tx2: " << x2 << "\ty2: " << y2 << endl;
993 if(i==0) ipold=ipmax;
995 gr->GetPoint((int)(ip),x2,y2);
999 // cout << "ipold: " << ipold << "\tip: " << ip << "\tx2: " << x2 << "\ty2: " << y2 << endl;
1006 gr->GetPoint(ip2,x2,y2);
1009 gr->GetPoint(ip2,x2,y2);
1011 gr->GetPoint(ip2+1,xold,yold);
1015 gr->GetPoint(ip2,x2,y2);
1018 gr->GetPoint(ip2,x2,y2);
1020 gr->GetPoint(ip2-1,xold,yold);
1023 // cout << "For x=" << x << " interpolate between: " << xold << " and " << x2 << endl;
1024 return ((x-xold)*y2 + (x2-x)*yold) / (x2-xold);
1028 //--------------------------------------------------------------------------------------------------------------------------------------------------
1029 Double_t AliAnaChargedJetResponseMaker::InterpolateFast(TH1 *h, Double_t x) {
1031 // Double_t ipmax = gr->GetN()-1.;
1032 Double_t ipmax = (double)h->GetNbinsX();
1033 Double_t x2,y2,xold,yold;
1035 Double_t xmin = h->GetXaxis()->GetXmin();
1036 Double_t xmax = h->GetXaxis()->GetXmax();
1037 if(x<xmin || x>xmax) return 0;
1039 Double_t ip = ipmax/2.;
1040 Double_t ipold = 0.;
1042 x2 = h->GetBinCenter((int)ip);
1043 y2 = h->GetBinContent((int)ip);
1051 x2 = h->GetBinCenter((int)ip);
1052 y2 = h->GetBinContent((int)ip);
1056 // cout << "ipold: " << ipold << "\tip: " << ip << "\tx2: " << x2 << "\ty2: " << y2 << endl;
1061 if(i==0) ipold=ipmax;
1062 ip += (ipold-ip)/2.;
1063 x2 = h->GetBinCenter((int)ip);
1064 y2 = h->GetBinContent((int)ip);
1065 if(x2>x) ipold = ip;
1068 // cout << "ipold: " << ipold << "\tip: " << ip << "\tx2: " << x2 << "\ty2: " << y2 << endl;
1075 x2 = h->GetBinCenter(ip2);
1076 y2 = h->GetBinContent(ip2);
1079 x2 = h->GetBinCenter(ip2);
1080 y2 = h->GetBinContent(ip2);
1082 xold = h->GetBinCenter(ip2+1);
1083 yold = h->GetBinContent(ip2+1);
1087 x2 = h->GetBinCenter(ip2);
1088 y2 = h->GetBinContent(ip2);
1091 x2 = h->GetBinCenter(ip2);
1092 y2 = h->GetBinContent(ip2);
1094 xold = h->GetBinCenter(ip2-1);
1095 yold = h->GetBinContent(ip2-1);
1098 // cout << "For x=" << x << " interpolate between: " << xold << " and " << x2 << endl;
1099 return ((x-xold)*y2 + (x2-x)*yold) / (x2-xold);