1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 /// Class to hold results about J/psi
18 /// like number of of J/psi (before and after Acc x Eff correction),
19 /// Acc x Eff correction, Yield, RAB, etc...
21 /// author: Laurent Aphecetche (Subatech)
24 #include "AliAnalysisMuMuJpsiResult.h"
26 ClassImp(AliAnalysisMuMuJpsiResult)
29 #include "TFitResult.h"
32 #include "THashList.h"
37 #include "TObjArray.h"
38 #include "TParameter.h"
39 #include "AliAnalysisMuMuBinning.h"
45 const std::map<std::string,Double_t>& MassMap()
47 /// a simple map of masses...
48 static std::map<std::string,Double_t> massMap;
49 // not super elegant, but that way we do not depend on TDatabasePDG and thus
50 // can decide on our particle naming
53 massMap["Jpsi"] = 3.096916e+00;
54 massMap["PsiPrime"] = 3.68609e+00;
55 massMap["Upsilon"] = 9.46030e+00;
56 massMap["UpsilonPrime"] = 1.00233e+01;
62 Double_t funcCB(Double_t* xx, Double_t* par)
66 Double_t norm = par[0];
67 Double_t alpha = par[1];
69 Double_t mean = par[3];
70 Double_t sigma = par[4];
74 Double_t a = TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-0.5*alpha*alpha);
75 Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
77 Double_t y = ( TMath::Abs(sigma) > 1E-12 ? (x-mean)/sigma : 0 );
81 return norm*TMath::Exp(-0.5*y*y);
85 return norm*a*TMath::Power(b-y,-n);
89 Double_t funcJpsiGCBE(Double_t* xx, Double_t* par)
91 /// crystal ball + expo + gaussian
94 Double_t g = par[0]*TMath::Gaus(x,par[1],par[2]);
96 Double_t jpsi = funcCB(xx,par+3);
98 Double_t expo = par[8]*TMath::Exp(par[9]*x);
103 Double_t funcCB2(Double_t* xx, Double_t* par)
105 /// CB2 = extended crystal ball
107 Double_t norm = par[0];
108 Double_t alpha = par[1];
110 Double_t mean = par[3];
111 Double_t sigma = par[4];
112 Double_t alphaprime = par[5];
113 Double_t nprime = par[6];
117 Double_t a = TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-0.5*alpha*alpha);
118 Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
119 Double_t c = TMath::Power(nprime/TMath::Abs(alphaprime),nprime)*TMath::Exp(-0.5*alphaprime*alphaprime);
120 Double_t d = nprime/TMath::Abs(alphaprime) - TMath::Abs(alphaprime);
122 Double_t y = ( TMath::Abs(sigma) > 1E-12 ? (x-mean)/sigma : 0 );
124 if ( y > alphaprime )
126 return norm*c*TMath::Power(d+y,-nprime);
128 else if ( y > alpha*-1.0 )
130 return norm*TMath::Exp(-0.5*y*y);
134 return norm*a*TMath::Power(b-y,-n);
139 Double_t funcJpsiNA48(Double_t*x, Double_t* par)
141 /// Fit function from e.q. 4.8 of Ruben's PhD.
142 Double_t c1 = par[0];
143 Double_t c2 = par[1];
144 Double_t d1 = par[2];
145 Double_t d2 = par[3];
146 Double_t g1 = par[4];
147 Double_t g2 = par[5];
148 Double_t m0 = par[6];
149 Double_t sigma1 = par[7];
150 Double_t sigma2 = par[8];
151 Double_t b1 = par[9];
152 Double_t b2 = par[10];
153 Double_t norm = par[11];
161 Double_t e = d1-g1*TMath::Sqrt(c1*m0-m);
162 rv = TMath::Power(b1*(c1*m0-m),e);
165 else if( m >= c1*m0 && m <= m0 )
169 else if ( m >= m0 && m < c2*m0 )
173 else if( m >= c2*m0 )
175 Double_t e = d2-g2*TMath::Sqrt(m-c2*m0);
176 rv = TMath::Power(b2*(m-c2*m0),e);
180 return norm*TMath::Exp(-(m-m0)*(m-m0)/(2.0*rv*rv));
183 //------------------------------------------------------------------------------
184 Double_t BackgroundVWG(Double_t *x, Double_t *par)
186 // gaussian variable width
187 Double_t sigma = par[2]+par[3]*((x[0]-par[1])/par[1]);
188 return par[0]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/(2.*sigma*sigma));
192 //------------------------------------------------------------------------------
193 Double_t CrystalBallExtended(Double_t *x,Double_t *par)
195 //par[0] = Normalization
203 Double_t t = (x[0]-par[1])/par[2];
204 if (par[3] < 0) t = -t;
206 Double_t absAlpha = fabs((Double_t)par[3]);
207 Double_t absAlpha2 = fabs((Double_t)par[5]);
209 if (t >= -absAlpha && t < absAlpha2) // gaussian core
211 return par[0]*(exp(-0.5*t*t));
214 if (t < -absAlpha) //left tail
216 Double_t a = TMath::Power(par[4]/absAlpha,par[4])*exp(-0.5*absAlpha*absAlpha);
217 Double_t b = par[4]/absAlpha - absAlpha;
218 return par[0]*(a/TMath::Power(b - t, par[4]));
221 if (t >= absAlpha2) //right tail
224 Double_t c = TMath::Power(par[6]/absAlpha2,par[6])*exp(-0.5*absAlpha2*absAlpha2);
225 Double_t d = par[6]/absAlpha2 - absAlpha2;
226 return par[0]*(c/TMath::Power(d + t, par[6]));
233 //---------------------------------------------------------------------------
234 // Double_t fitFunctionVWG(Double_t *x, Double_t *par)
236 // if (x[0] > 2.9 && x[0] < 3.3) TF1::RejectPoint();
237 // return BackgroundVWG(x, par);
240 //---------------------------------------------------------------------------
241 Double_t fitFunctionCB2VWG(Double_t *x, Double_t *par)
243 return BackgroundVWG(x, par) + CrystalBallExtended(x, &par[4]);
246 //---------------------------------------------------------------------------
247 Double_t func2CB2VWG(Double_t *x, Double_t *par)
249 /// 2 extended crystal balls + variable width gaussian
250 /// width of the second CB related to the first (free) one.
254 3.68609+(par[5]-3.096916)/3.096916*3.68609,
255 par[6]/3.096916*3.68609,
261 return BackgroundVWG(x, par) + CrystalBallExtended(x, &par[4]) + CrystalBallExtended(x, par2);
265 //_____________________________________________________________________________
266 AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(TRootIOCtor* /*io*/) :
267 AliAnalysisMuMuResult("",""),
276 fCentralitySelection()
280 //_____________________________________________________________________________
281 AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const TH1& hminv) :
282 AliAnalysisMuMuResult("",""),
291 fCentralitySelection()
296 //_____________________________________________________________________________
297 AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const TH1& hminv,
301 AliAnalysisMuMuResult(Form("%s:%d",fitType,nrebin),""),
310 fCentralitySelection()
315 //_____________________________________________________________________________
316 AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const TH1& hminv,
317 const char* triggerName,
318 const char* eventSelection,
319 const char* pairSelection,
320 const char* centSelection,
321 const AliAnalysisMuMuBinning::Range& bin)
323 AliAnalysisMuMuResult(Form("%s-%s-%s-%s",triggerName,eventSelection,pairSelection,centSelection),""),
329 fTriggerClass(triggerName),
330 fEventSelection(eventSelection),
331 fPairSelection(pairSelection),
332 fCentralitySelection(centSelection)
337 //_____________________________________________________________________________
338 AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const AliAnalysisMuMuJpsiResult& rhs)
340 AliAnalysisMuMuResult(rhs),
341 fNofRuns(rhs.NofRuns()),
342 fNofTriggers(rhs.NofTriggers()),
346 fTriggerClass(rhs.fTriggerClass),
347 fEventSelection(rhs.fEventSelection),
348 fPairSelection(rhs.fPairSelection),
349 fCentralitySelection(rhs.fCentralitySelection)
352 /// Note that the mother is lost
353 /// fKeys remains 0x0 so it will be recomputed if need be
357 fMinv = static_cast<TH1*>(rhs.fMinv->Clone());
361 //_____________________________________________________________________________
362 AliAnalysisMuMuJpsiResult& AliAnalysisMuMuJpsiResult::operator=(const AliAnalysisMuMuJpsiResult& rhs)
364 /// Assignment operator
368 static_cast<AliAnalysisMuMuResult&>(*this) = static_cast<const AliAnalysisMuMuResult&>(rhs);
373 fMinv = static_cast<TH1*>(rhs.fMinv->Clone());
376 fNofRuns = rhs.NofRuns();
377 fNofTriggers = rhs.NofTriggers();
385 //_____________________________________________________________________________
386 AliAnalysisMuMuJpsiResult::~AliAnalysisMuMuJpsiResult()
392 //_____________________________________________________________________________
393 const AliAnalysisMuMuBinning::Range& AliAnalysisMuMuJpsiResult::Bin() const
395 /// Get the bin of this result
396 if ( !Mother() ) return fBin;
397 else return Mother()->Bin();
400 //_____________________________________________________________________________
401 TObject* AliAnalysisMuMuJpsiResult::Clone(const char* /*newname*/) const
403 /// Clone this result
404 return new AliAnalysisMuMuJpsiResult(*this);
407 //_____________________________________________________________________________
408 Bool_t AliAnalysisMuMuJpsiResult::Correct(const AliAnalysisMuMuJpsiResult& other, const char* particle, const char* subResultName)
410 /// Assuming other has an AccxEff entry, correct this value by AccxEff of other
412 if ( HasValue(Form("Nof%s",particle)) )
414 if (!other.HasValue(Form("AccEff%s",particle),subResultName))
416 AliError(Form("Cannot correct as I do not find the AccEff%s value (subResultName=%s)!",particle,subResultName));
420 Double_t acc = other.GetValue(Form("AccEff%s",particle),subResultName);
421 Double_t value = 0.0;
423 if ( acc > 0 ) value = GetValue(Form("Nof%s",particle)) / acc;
425 Double_t error = ErrorAB( GetValue(Form("Nof%s",particle)),
426 GetErrorStat(Form("Nof%s",particle)),
427 other.GetValue(Form("AccEff%s",particle),subResultName),
428 other.GetErrorStat(Form("AccEff%s",particle),subResultName) );
430 Set(Form("CorrNof%s",particle),value,error*value);
436 AliError(Form("Result does not have Nof%s : cannot correct it !",particle));
441 //_____________________________________________________________________________
442 Double_t AliAnalysisMuMuJpsiResult::CountParticle(const TH1& hminv, const char* particle, Double_t sigma)
444 /// Count the number of entries in an invariant mass range
446 const std::map<std::string,Double_t>& m = MassMap();
448 std::map<std::string,Double_t>::const_iterator it = m.find(particle);
452 AliErrorClass(Form("Don't know the mass of particle %s",particle));
456 Double_t mass = it->second;
460 AliDebugClass(1,Form("Oups. Got a sigma of %e for particle %s !",sigma,particle));
461 return hminv.Integral();
464 TAxis* x = hminv.GetXaxis();
466 Int_t b1 = x->FindBin(mass-sigma);
467 Int_t b2 = x->FindBin(mass+sigma);
469 AliDebugClass(1,Form("hminv getentries %e integral %e",hminv.GetEntries(),hminv.Integral(b1,b2)));
471 return hminv.Integral(b1,b2);
474 //_____________________________________________________________________________
475 AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsiGCBE(TH1& h)
477 /// Fit Jpsi spectra with crystal ball + gaussian + exponential
479 std::cout << "Fit with jpsi alone (gaus + CB + expo)" << std::endl;
481 Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
483 AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSIGCBE",nrebin);
485 TH1* hfit = r->Minv();
487 const Double_t xmin(1.0);
488 const Double_t xmax(8.0);
490 TF1* fitTotal = new TF1("fitTotal",funcJpsiGCBE,xmin,xmax,10);
491 fitTotal->SetParNames("cste","x0","sigma0","N","alpha","n","mean","sigma","expocste","exposlope");
493 fitTotal->SetParLimits(3,0,h.GetMaximum()*2); // N
495 const Double_t cbalpha(0.98);
496 const Double_t cbn(5.2);
498 fitTotal->FixParameter(4,cbalpha);
499 fitTotal->FixParameter(5,cbn);
501 fitTotal->SetParLimits(6,2.8,3.2); // mean
502 fitTotal->SetParLimits(7,0.02,0.3); // sigma
504 TF1* fg = new TF1("fg","gaus",xmin,xmax);
506 hfit->Fit(fg,"","",0.75,3.0);
508 fitTotal->SetParameter(0,fg->GetParameter(0));
509 fitTotal->SetParameter(1,fg->GetParameter(1));
510 fitTotal->SetParameter(2,fg->GetParameter(2));
512 TF1* fexpo = new TF1("expo","expo",xmin,xmax);
514 hfit->Fit(fexpo,"","",3.5,5);
516 fitTotal->SetParameter(8,fexpo->GetParameter(0));
517 fitTotal->SetParameter(9,fexpo->GetParameter(1));
519 fitTotal->SetParameter(3,h.GetMaximum()),
520 fitTotal->SetParameter(4,cbalpha);
521 fitTotal->SetParameter(5,cbn);
522 fitTotal->SetParameter(6,3.15);
523 fitTotal->SetParameter(7,0.1);
525 const char* fitOption = "QSI+";
527 TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"",2,5);
529 r->Set("MeanJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
530 r->Set("SigmaJpsi",fitTotal->GetParameter(7),fitTotal->GetParError(7));
532 double m = r->GetValue("MeanJpsi");
533 double s = r->GetValue("SigmaJpsi");
536 TF1* fcb = new TF1("fcb",funcCB,xmin,xmax,5);
537 fcb->SetParameters(fitTotal->GetParameter(3),
538 fitTotal->GetParameter(4),
539 fitTotal->GetParameter(5),
540 fitTotal->GetParameter(6),
541 fitTotal->GetParameter(7));
543 fcb->SetLineColor(6);
545 TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(3));
546 TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(3));
549 h.GetListOfFunctions()->Add(fcb);
550 h.GetListOfFunctions()->Add(l1);
551 h.GetListOfFunctions()->Add(l2);
554 Double_t cbParameters[5];
555 Double_t covarianceMatrix[5][5];
557 cbParameters[0] = fitTotal->GetParameter(3);
558 cbParameters[1] = fitTotal->GetParameter(4);
559 cbParameters[2] = fitTotal->GetParameter(5);
560 cbParameters[3] = fitTotal->GetParameter(6);
561 cbParameters[4] = fitTotal->GetParameter(7);
563 for ( int iy = 0; iy < 5; ++iy )
565 for ( int ix = 0; ix < 5; ++ix )
567 covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+3,iy+3);
571 double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
573 double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
575 r->Set("NofJpsi",njpsi,nerr);
580 //_____________________________________________________________________________
581 AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsi(TH1& h)
583 /// Fit Jpsi spectra using extended crystall ball (CB2) with free tails
585 StdoutToAliDebug(1,std::cout << "Fit with jpsi alone" << std::endl;);
587 Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
589 AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSI",nrebin);
591 TH1* hfit = r->Minv();
593 const Double_t xmin(1.5);
594 const Double_t xmax(8.0);
596 TF1* fitTotal = new TF1("fitTotal",funcCB2,xmin,xmax,7);
597 fitTotal->SetParNames("N","alphaLow","nLow","mean","sigma","alphaUp","nUp");
598 fitTotal->SetParameters(h.GetMaximum(),1,5,3.1,0.07,1.5,3);
599 fitTotal->SetParLimits(0,0,h.GetMaximum()*2); // N
600 fitTotal->SetParLimits(1,0,10); // alpha
601 fitTotal->SetParLimits(2,0.1,10); // n
602 fitTotal->SetParLimits(3,3,3.15); // mean
603 fitTotal->SetParLimits(4,0.01,1); // sigma
604 fitTotal->SetParLimits(5,0,10); // alpha
605 fitTotal->SetParLimits(6,0.1,10); // n
607 hfit->Fit(fitTotal,"QSER+","",2,5);
610 r->Set("MeanJpsi",fitTotal->GetParameter(3),fitTotal->GetParError(3));
611 r->Set("SigmaJpsi",fitTotal->GetParameter(4),fitTotal->GetParError(4));
613 double m = r->GetValue("MeanJpsi");
614 double s = r->GetValue("SigmaJpsi");
617 r->Set("NofJpsi",fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1),fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1));
622 //_____________________________________________________________________________
623 AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsiCB2VWG(const TH1& h)
625 /// Fit Jpsi spectra using extended crystal ball (CB2) + variable width gaussian (VWG)
627 StdoutToAliDebug(1,std::cout << "Fit with jpsi VWG" << std::endl;);
629 Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
631 AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSICB2VWG",nrebin);
634 TH1* hfit = r->Minv();
636 const Double_t xmin(2.0);
637 const Double_t xmax(5.0);
639 // // gaussian variable width
640 // Double_t sigma = par[2]+par[3]*((x[0]-par[1])/par[1]);
641 // return par[0]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/(2.*sigma*sigma));
642 // Double_t CrystalBallExtended(Double_t *x,Double_t *par)
643 // //par[0] = Normalization
651 TF1* fitTotal = new TF1("fitTotal",fitFunctionCB2VWG,xmin,xmax,11);
652 fitTotal->SetParNames("kVWG","mVWG","sVWG1","sVWG2","norm","mean","sigma","alpha","n","alpha'","n'");
654 fitTotal->SetParameter(0, 10000.); // kVWG
655 fitTotal->SetParameter(1, 1.9); // mVWG
657 fitTotal->SetParameter(2, 0.5); // sVWG1
658 fitTotal->SetParLimits(2, 0., 100.);
660 fitTotal->SetParameter(3, 0.3); // sVWG2
661 fitTotal->SetParLimits(3, 0., 100.);
663 fitTotal->SetParameter(4, h.GetMaximum()); // norm
665 fitTotal->SetParameter(5, 3.1); // mean
666 fitTotal->SetParLimits(5, 3.0, 3.2);
668 fitTotal->SetParameter(6, 0.08); // sigma
669 fitTotal->SetParLimits(6, 0.04, 0.20);
671 fitTotal->SetParameter(7,1.0); // alpha
672 fitTotal->SetParameter(8,5); // n
673 fitTotal->SetParameter(9,2.0); // alpha'
674 fitTotal->SetParameter(10,4); // n'
676 // fitTotal->FixParameter(7, 0.93);
677 // fitTotal->FixParameter(8, 5.59);
678 // fitTotal->FixParameter(9, 2.32);
679 // fitTotal->FixParameter(10, 3.39);
680 // fitTotal->SetParameter(11, 10.);
682 const char* fitOption = "QSIER"; //+";
684 TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
686 r->Set("MeanJpsi",fitTotal->GetParameter(5),fitTotal->GetParError(5));
687 r->Set("SigmaJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
689 double m = r->GetValue("MeanJpsi");
690 double s = r->GetValue("SigmaJpsi");
693 TF1* fcb = new TF1("fcb",CrystalBallExtended,xmin,xmax,7);
694 fcb->SetParameters(fitTotal->GetParameter(4),
695 fitTotal->GetParameter(5),
696 fitTotal->GetParameter(6),
697 fitTotal->GetParameter(7),
698 fitTotal->GetParameter(8),
699 fitTotal->GetParameter(9),
700 fitTotal->GetParameter(10));
703 fcb->SetLineColor(1);
705 TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(4));
706 TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(4));
709 hfit->GetListOfFunctions()->Add(fcb);
710 hfit->GetListOfFunctions()->Add(l1);
711 hfit->GetListOfFunctions()->Add(l2);
713 Double_t cbParameters[7];
714 Double_t covarianceMatrix[7][7];
716 for ( int ix = 0; ix < 7; ++ix )
718 cbParameters[ix] = fitTotal->GetParameter(ix+4);
721 for ( int iy = 0; iy < 5; ++iy )
723 for ( int ix = 0; ix < 5; ++ix )
725 covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+4,iy+4);
729 double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
730 double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
732 r->Set("NofJpsi",njpsi,nerr);
737 //_____________________________________________________________________________
738 AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsi2CB2VWG(const TH1& h,
744 /// Fit using extended crystal ball + variable width gaussian
746 StdoutToAliDebug(1,std::cout << Form("Fit with jpsi + psiprime VWG alphaLow=%5.2f nLow=%5.2f alphaUp=%5.2f nUp=%5.2f",
747 alphaLow,nLow,alphaUp,nUp) << std::endl;);
749 Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
751 TString resultName("JPSI2CB2VWG");
754 resultName += TString::Format("alphaLow=%5.2f",alphaLow);
758 resultName += TString::Format("nLow=%5.2f",nLow);
762 resultName += TString::Format("alphaUp=%5.2f",alphaUp);
766 resultName += TString::Format("nUp=%5.2f",nUp);
768 resultName.ReplaceAll(" ","");
770 AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,resultName.Data(),nrebin);
772 TH1* hfit = r->Minv();
774 const Double_t xmin(2.2);
775 const Double_t xmax(5.0);
777 TF1* fitTotal = new TF1("fitTotal",func2CB2VWG,xmin,xmax,12);
778 fitTotal->SetParNames("kVWG","mVWG","sVWG1","sVWG2","kPsi","mPsi","sPsi","alPsi","nlPsi","auPsi","nuPsi");
779 fitTotal->SetParName(11, "kPsi'");
781 fitTotal->SetParameter(0, 10000.);
782 fitTotal->SetParameter(1, 1.9);
783 fitTotal->SetParameter(2, 0.5);
784 fitTotal->SetParLimits(2, 0., 100.);
785 fitTotal->SetParameter(3, 0.3);
786 fitTotal->SetParLimits(3, 0., 100.);
787 fitTotal->SetParameter(4, 100.);
788 fitTotal->SetParameter(5, 3.1);
789 fitTotal->SetParLimits(5, 3.08, 3.2);
790 fitTotal->SetParameter(6, 0.08);
791 fitTotal->SetParLimits(6, 0.05, 0.15);
793 // r = FitJpsi2CB2VWG(*hminv,0.93,5.59,2.32,3.39);
797 fitTotal->FixParameter(7, alphaLow);
801 fitTotal->SetParameter(7,0.9);
802 fitTotal->SetParLimits(7,0.1,10.0);
807 fitTotal->FixParameter(8, nLow);
811 fitTotal->SetParameter(8,5.0);
812 fitTotal->SetParLimits(8,0.0,10.0);
817 fitTotal->FixParameter(9, alphaUp);
821 fitTotal->SetParameter(9, 2.0);
822 fitTotal->SetParLimits(9,0.1,10.0);
827 fitTotal->FixParameter(10, nUp);
831 fitTotal->SetParameter(10,3.0);
832 fitTotal->SetParLimits(10,0.0,10.0);
835 fitTotal->SetParameter(11, 10.);
837 const char* fitOption = "QSER"; //+";
839 TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
841 r->Set("MeanJpsi",fitTotal->GetParameter(5),fitTotal->GetParError(5));
842 r->Set("SigmaJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
844 double m = r->GetValue("MeanJpsi");
845 double s = r->GetValue("SigmaJpsi");
848 TF1* fcb = new TF1("fcb",CrystalBallExtended,xmin,xmax,7);
849 fcb->SetParameters(fitTotal->GetParameter(4),
850 fitTotal->GetParameter(5),
851 fitTotal->GetParameter(6),
852 fitTotal->GetParameter(7),
853 fitTotal->GetParameter(8),
854 fitTotal->GetParameter(9),
855 fitTotal->GetParameter(10));
858 fcb->SetLineColor(1);
860 TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(4));
861 TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(4));
864 hfit->GetListOfFunctions()->Add(fcb);
865 hfit->GetListOfFunctions()->Add(l1);
866 hfit->GetListOfFunctions()->Add(l2);
868 Double_t cbParameters[7];
869 Double_t covarianceMatrix[7][7];
871 for ( int ix = 0; ix < 7; ++ix )
873 cbParameters[ix] = fitTotal->GetParameter(ix+4);
876 for ( int iy = 0; iy < 5; ++iy )
878 for ( int ix = 0; ix < 5; ++ix )
880 covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+4,iy+4);
884 double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
885 double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
887 r->Set("NofJpsi",njpsi,nerr);
892 //_____________________________________________________________________________
893 AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsiNA48(const TH1& h)
895 /// fit using functional form from Ruben Shahoyan's thesis (2001) (eq. 4.8.)
897 StdoutToAliDebug(1,std::cout << "Fit with jpsi NA50 Ruben eq. 4.8" << std::endl;);
899 Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
901 AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSINA",nrebin);
903 TH1* hfit = r->Minv();
905 const Double_t xmin(2.0);
906 const Double_t xmax(5.0);
908 TF1* fitTotal = new TF1("fitTotal",funcJpsiNA48,xmin,xmax,12);
910 fitTotal->SetParName( 0, "c1");
911 fitTotal->FixParameter(0,0.97);
913 fitTotal->SetParName( 1, "c2");
914 fitTotal->FixParameter(1,1.05);
916 fitTotal->SetParName( 2, "d1");
917 fitTotal->SetParameter(2,0.0);
918 fitTotal->SetParLimits(2,0,1);
920 fitTotal->SetParName( 3, "d2");
921 fitTotal->SetParameter(3,0.0);
922 fitTotal->SetParLimits(3,0,1);
924 fitTotal->SetParName( 4, "g1");
925 fitTotal->SetParameter(4,0.0);
926 fitTotal->SetParLimits(4,0.0,1);
928 fitTotal->SetParName( 5, "g2");
929 fitTotal->SetParameter(5,0.0);
930 fitTotal->SetParLimits(5,0.0,1);
932 fitTotal->SetParName( 6, "m0");
933 fitTotal->SetParameter(6,3.1);
934 fitTotal->SetParLimits(6,2.8,3.4);
936 fitTotal->SetParName( 7, "sigma1");
937 fitTotal->SetParameter(7,0.05);
938 fitTotal->SetParLimits(7,0.01,0.2);
940 fitTotal->SetParName( 8, "sigma2");
941 fitTotal->SetParameter(8,0.05);
942 fitTotal->SetParLimits(8,0.01,0.2);
944 fitTotal->SetParName( 9, "b1");
945 fitTotal->SetParameter(9,1.0);
946 fitTotal->SetParLimits(9,0,1);
948 fitTotal->SetParName(10, "b2");
949 fitTotal->SetParameter(10,1.0);
950 fitTotal->SetParLimits(10,0,1);
952 fitTotal->SetParName(11, "norm");
953 fitTotal->SetParameter(11,h.GetMaximum());
955 const char* fitOption = "QSIER"; //+";
957 TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
959 r->Set("MeanJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
961 fitTotal->GetParameter(7)+fitTotal->GetParameter(8),
964 double m = r->GetValue("MeanJpsi");
965 double s = r->GetValue("SigmaJpsi");
968 TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(11));
969 TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(11));
972 hfit->GetListOfFunctions()->Add(l1);
973 hfit->GetListOfFunctions()->Add(l2);
975 double njpsi = fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
976 double nerr = fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1);
978 r->Set("NofJpsi",njpsi,nerr);
983 //_____________________________________________________________________________
984 Bool_t AliAnalysisMuMuJpsiResult::AddFit(const char* fitType, Int_t npar, Double_t* par)
986 // Add a fit to this result
988 TString msg(Form("fitType=%s npar=%d par[]=",fitType,npar));
990 for ( Int_t i = 0; i < npar; ++i )
992 msg += TString::Format("%e,",par[i]);
995 msg += TString::Format(" minv=%p %d",fMinv,fMinv?TMath::Nint(fMinv->GetEntries()):0);
997 if ( !fMinv ) return kFALSE;
999 TString sFitType(fitType);
1003 if (sFitType.CountChar(':'))
1005 Int_t index = sFitType.Index(":");
1006 nrebin = TString(sFitType(index+1,sFitType.Length()-index-1)).Atoi();
1007 sFitType = sFitType(0,index);
1010 msg += TString::Format(" nrebin=%d",nrebin);
1012 AliDebug(1,msg.Data());
1015 if ( fMinv->GetEntries()<100 && !sFitType.Contains("COUNT")) return kFALSE;
1017 TH1* hminv = static_cast<TH1*>(fMinv->Clone());
1019 hminv->Rebin(nrebin);
1020 hminv->SetDirectory(0);
1022 AliAnalysisMuMuJpsiResult* r(0x0);
1024 if ( sFitType=="PSI1")
1026 r = FitJpsi(*hminv);
1028 else if ( sFitType == "PSILOW")
1030 r = FitJpsi2CB2VWG(*hminv,-1,-1,-1,-1); // free tails
1032 else if ( sFitType == "PSILOWMCTAILS" )
1036 AliError("Cannot use PSILOWMCTAILS without being given the MC tails !");
1040 r = FitJpsi2CB2VWG(*hminv,par[0],par[1],par[2],par[3]);
1043 r->SetAlias("MCTAILS");
1046 else if ( sFitType.BeginsWith("PSILOWALPHA") )
1048 Float_t lpar[] = { 0.0, 0.0, 0.0, 0.0 };
1050 AliDebug(1,Form("sFitType=%s",sFitType.Data()));
1052 sscanf(sFitType.Data(),"PSILOWALPHALOW%fNLOW%fALPHAUP%fNUP%f",
1053 &lpar[0],&lpar[1],&lpar[2],&lpar[3]);
1055 AliDebug(1,Form("PSILOW ALPHALOW=%f NLOW=%f ALPHAUP=%f NUP=%f",lpar[0],lpar[1],lpar[2],lpar[3]));
1057 if ( lpar[0] == 0.0 && lpar[1] == 0.0 && lpar[0] == 0.0 && lpar[1] == 0.0 )
1059 AliError("Cannot work with zero tails !");
1063 r = FitJpsi2CB2VWG(*hminv,lpar[0],lpar[1],lpar[2],lpar[3]);
1066 else if ( sFitType == "COUNTJPSI" )
1068 r = new AliAnalysisMuMuJpsiResult(*hminv,"COUNTJPSI",1);
1069 Double_t n = CountParticle(*hminv,"Jpsi");
1070 r->Set("NofJpsi",n,TMath::Sqrt(n));
1076 StdoutToAliDebug(1,r->Print(););
1078 r->SetNofTriggers(NofTriggers());
1079 r->SetNofRuns(NofRuns());
1089 //_____________________________________________________________________________
1090 Long64_t AliAnalysisMuMuJpsiResult::Merge(TCollection* list)
1094 /// Merge a list of AliAnalysisMuMuJpsiResult objects with this
1095 /// Returns the number of merged objects (including this).
1097 /// Note that the merging is to be understood here as an weighted mean operation
1099 /// FIXME ! (compared to base class Merge, should only Minv merging ?)
1101 AliError("Implement me !");
1102 if (!list) return 0;
1104 if (list->IsEmpty()) return 1;
1110 //_____________________________________________________________________________
1111 Int_t AliAnalysisMuMuJpsiResult::NofRuns() const
1113 /// Get the number of runs
1114 if ( !Mother() ) return fNofRuns;
1115 else return Mother()->NofRuns();
1118 //_____________________________________________________________________________
1119 Int_t AliAnalysisMuMuJpsiResult::NofTriggers() const
1121 /// Get the number of triggers
1123 if ( !Mother() ) return fNofTriggers;
1124 else return Mother()->NofTriggers();
1127 //_____________________________________________________________________________
1128 void AliAnalysisMuMuJpsiResult::Print(Option_t* opt) const
1132 std::cout << Form("NRUNS %d - NTRIGGER %10d - %s",
1135 fBin.AsString().Data());
1137 AliAnalysisMuMuResult::Print(opt);
1140 //_____________________________________________________________________________
1141 void AliAnalysisMuMuJpsiResult::PrintValue(const char* key, const char* opt, Double_t value, Double_t errorStat,
1144 /// exclude the particles with zero stat
1146 const std::map<std::string,Double_t>& m = MassMap();
1148 for( std::map<std::string,Double_t>::const_iterator it = m.begin(); it != m.end(); ++it )
1150 TString particle(it->first.c_str());
1152 if (TString(key).Contains(particle.Data()))
1154 if ( GetValue("Nof%s",particle.Data()) <= 0.0 ) return;
1158 AliAnalysisMuMuResult::PrintValue(key,opt,value,errorStat,rms);
1162 //_____________________________________________________________________________
1163 void AliAnalysisMuMuJpsiResult::PrintParticle(const char* particle, const char* opt) const
1165 /// Print all information about one particule type
1167 Double_t npart = GetValue(Form("Nof%s",particle));
1168 if (npart<=0) return;
1171 std::cout << opt << Form("\t%s",particle) << std::endl;
1173 // Double_t npartError = GetErrorStat(Form("Nof%s",particle));
1174 // std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f","Count",npart,npartError) << std::endl;
1179 while ( ( key = static_cast<TObjString*>(next()) ) )
1181 if ( !key->String().Contains(particle) ) continue;
1183 PrintValue(key->String(),opt,GetValue(key->String()),GetErrorStat(key->String()),GetRMS(key->String()));
1187 //_____________________________________________________________________________
1188 void AliAnalysisMuMuJpsiResult::SetBin(const AliAnalysisMuMuBinning::Range& bin)
1192 if (!Mother()) fBin = bin;
1193 else Mother()->SetBin(bin);
1196 //_____________________________________________________________________________
1197 void AliAnalysisMuMuJpsiResult::SetNofInputParticles(const TH1& hminv)
1199 /// Set the number of input particle from the invariant mass spectra
1201 static const char* particleNames[] = { "Jpsi" , "PsiPrime", "Upsilon","UpsilonPrime" };
1203 const std::map<std::string,Double_t>& m = MassMap();
1205 for ( Int_t i = 0; i < 4; ++i )
1207 std::map<std::string,Double_t>::const_iterator it = m.find(particleNames[i]);
1209 Double_t sigma(-1.0);
1213 sigma = it->second*0.1;
1216 Double_t n = CountParticle(hminv,particleNames[i],sigma);
1218 AliDebug(1,Form("i=%d particle %s n %e",i,particleNames[i],n));
1222 SetNofInputParticles(particleNames[i],TMath::Nint(n));
1227 //_____________________________________________________________________________
1228 void AliAnalysisMuMuJpsiResult::SetNofInputParticles(const char* particle, int n)
1230 /// Set the number of input particles (so it is a MC result)
1231 /// and (re)compute the AccxEff values
1233 Set(Form("NofInput%s",particle),n,TMath::Sqrt(n));
1237 Set(Form("AccEff%s",particle),0,0);
1241 Double_t npart = GetValue(Form("Nof%s",particle));
1242 Double_t npartErr = GetErrorStat(Form("Nof%s",particle));
1243 Double_t ninput = GetValue(Form("NofInput%s",particle));
1244 Double_t ninputErr = GetErrorStat(Form("NofInput%s",particle));
1246 Set(Form("AccEff%s",particle),
1248 (npart/ninput)*ErrorAB(npart,npartErr,ninput,ninputErr));
1250 TIter next(SubResults());
1251 AliAnalysisMuMuJpsiResult* r;
1253 while ( ( r = static_cast<AliAnalysisMuMuJpsiResult*>(next())) )
1255 r->Set(Form("NofInput%s",particle),n,TMath::Sqrt(n));
1257 npart = r->GetValue(Form("Nof%s",particle));
1258 npartErr = r->GetErrorStat(Form("Nof%s",particle));
1260 r->Set(Form("AccEff%s",particle),
1262 (npart/ninput)*ErrorAB(npart,npartErr,ninput,ninputErr));
1267 //_____________________________________________________________________________
1268 void AliAnalysisMuMuJpsiResult::SetNofRuns(Int_t n)
1270 if ( !Mother() ) fNofRuns=n;
1271 else Mother()->SetNofRuns(n);
1274 //_____________________________________________________________________________
1275 void AliAnalysisMuMuJpsiResult::SetNofTriggers(Int_t n)
1277 if ( !Mother() ) fNofTriggers=n;
1278 else Mother()->SetNofTriggers(n);
1281 //_____________________________________________________________________________
1282 void AliAnalysisMuMuJpsiResult::SetMinv(const TH1& hminv)
1284 /// Set the inv. mass spectrum to be fitted.
1288 fMinv = static_cast<TH1*>(hminv.Clone(Form("Minv%u",n++)));
1289 fMinv->SetDirectory(0);