]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/vertexingHF/AliHFMassFitter.cxx
set ownership of cuts container
[u/mrichter/AliRoot.git] / PWG3 / vertexingHF / AliHFMassFitter.cxx
CommitLineData
fabf4d8e 1/**************************************************************************
2 * Copyright(c) 1998-2009, 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//
18// AliHFMassFitter for the fit of invariant mass distribution
19// of charmed mesons
20//
21// Author: C.Bianchin, chiara.bianchin@pd.infn.it
22/////////////////////////////////////////////////////////////
23
dc262918 24#include <Riostream.h>
25#include <TMath.h>
26#include <TNtuple.h>
27#include <TH1F.h>
28#include <TF1.h>
29#include <TList.h>
30#include <TFile.h>
fabf4d8e 31#include <TCanvas.h>
a12d80b8 32#include <TVirtualPad.h>
ad73ca8f 33#include <TGraph.h>
34#include <TVirtualFitter.h>
dc262918 35#include <TMinuit.h>
3c0e7d59 36#include <TStyle.h>
37#include <TPaveText.h>
fabf4d8e 38
39#include "AliHFMassFitter.h"
40
41
dc262918 42
fabf4d8e 43ClassImp(AliHFMassFitter)
44
56cbeefb 45 //************** constructors
2f328d65 46AliHFMassFitter::AliHFMassFitter() :
47 TNamed(),
fabf4d8e 48 fhistoInvMass(0),
49 fminMass(0),
50 fmaxMass(0),
24e73105 51 fminBinMass(0),
52 fmaxBinMass(0),
34c79b83 53 fNbin(0),
2f328d65 54 fParsSize(1),
d22f0682 55 fNFinalPars(1),
2f328d65 56 fFitPars(0),
fabf4d8e 57 fWithBkg(0),
58 ftypeOfFit4Bkg(0),
59 ftypeOfFit4Sgn(0),
60 ffactor(1),
61 fntuParam(0),
24e73105 62 fMass(1.865),
fabf4d8e 63 fSigmaSgn(0.012),
56cbeefb 64 fSideBands(0),
3c0e7d59 65 fFixPar(0),
b7d4bc49 66 fSideBandl(0),
67 fSideBandr(0),
ad73ca8f 68 fcounter(0),
69 fContourGraph(0)
fabf4d8e 70{
71 // default constructor
a12d80b8 72
73 cout<<"Default constructor:"<<endl;
74 cout<<"Remember to set the Histo, the Type, the FixPar"<<endl;
ad73ca8f 75
fabf4d8e 76}
77
78//___________________________________________________________________________
79
dc262918 80AliHFMassFitter::AliHFMassFitter (const TH1F *histoToFit, Double_t minvalue, Double_t maxvalue, Int_t rebin,Int_t fittypeb,Int_t fittypes):
fabf4d8e 81 TNamed(),
82 fhistoInvMass(0),
83 fminMass(0),
84 fmaxMass(0),
24e73105 85 fminBinMass(0),
86 fmaxBinMass(0),
34c79b83 87 fNbin(0),
2f328d65 88 fParsSize(1),
d22f0682 89 fNFinalPars(1),
2f328d65 90 fFitPars(0),
fabf4d8e 91 fWithBkg(0),
92 ftypeOfFit4Bkg(0),
93 ftypeOfFit4Sgn(0),
94 ffactor(1),
95 fntuParam(0),
24e73105 96 fMass(1.865),
fabf4d8e 97 fSigmaSgn(0.012),
56cbeefb 98 fSideBands(0),
3c0e7d59 99 fFixPar(0),
b7d4bc49 100 fSideBandl(0),
101 fSideBandr(0),
ad73ca8f 102 fcounter(0),
103 fContourGraph(0)
fabf4d8e 104{
105 // standard constructor
106
56cbeefb 107 fhistoInvMass= (TH1F*)histoToFit->Clone("fhistoInvMass");
6321ee46 108 fhistoInvMass->SetDirectory(0);
fabf4d8e 109 fminMass=minvalue;
110 fmaxMass=maxvalue;
111 if(rebin!=1) RebinMass(rebin);
112 else fNbin=(Int_t)fhistoInvMass->GetNbinsX();
d22f0682 113 CheckRangeFit();
fabf4d8e 114 ftypeOfFit4Bkg=fittypeb;
115 ftypeOfFit4Sgn=fittypes;
116 if(ftypeOfFit4Bkg!=0 && ftypeOfFit4Bkg!=1 && ftypeOfFit4Bkg!=2) fWithBkg=kFALSE;
117 else fWithBkg=kTRUE;
118 if (!fWithBkg) cout<<"Fit Histogram of Signal only"<<endl;
119 else cout<<"Type of fit For Background = "<<ftypeOfFit4Bkg<<endl;
2f328d65 120
121 ComputeParSize();
122 fFitPars=new Float_t[fParsSize];
a12d80b8 123
4d7b8e51 124 SetDefaultFixParam();
a12d80b8 125
ad73ca8f 126 fContourGraph=new TList();
127 fContourGraph->SetOwner();
128
fabf4d8e 129}
130
74179930 131
132AliHFMassFitter::AliHFMassFitter(const AliHFMassFitter &mfit):
133 TNamed(),
134 fhistoInvMass(mfit.fhistoInvMass),
135 fminMass(mfit.fminMass),
136 fmaxMass(mfit.fmaxMass),
24e73105 137 fminBinMass(mfit.fminBinMass),
138 fmaxBinMass(mfit.fmaxBinMass),
74179930 139 fNbin(mfit.fNbin),
2f328d65 140 fParsSize(mfit.fParsSize),
d22f0682 141 fNFinalPars(mfit.fNFinalPars),
2f328d65 142 fFitPars(0),
74179930 143 fWithBkg(mfit.fWithBkg),
144 ftypeOfFit4Bkg(mfit.ftypeOfFit4Bkg),
145 ftypeOfFit4Sgn(mfit.ftypeOfFit4Sgn),
146 ffactor(mfit.ffactor),
147 fntuParam(mfit.fntuParam),
148 fMass(mfit.fMass),
149 fSigmaSgn(mfit.fSigmaSgn),
56cbeefb 150 fSideBands(mfit.fSideBands),
3c0e7d59 151 fFixPar(0),
b7d4bc49 152 fSideBandl(mfit.fSideBandl),
153 fSideBandr(mfit.fSideBandr),
ad73ca8f 154 fcounter(mfit.fcounter),
155 fContourGraph(mfit.fContourGraph)
74179930 156{
157 //copy constructor
2f328d65 158
159 if(mfit.fParsSize > 0){
160 fFitPars=new Float_t[fParsSize];
4d7b8e51 161 fFixPar=new Bool_t[fNFinalPars];
2f328d65 162 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
4d7b8e51 163 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Bool_t));
2f328d65 164 }
24e73105 165
2f328d65 166}
167
168//_________________________________________________________________________
169
170AliHFMassFitter::~AliHFMassFitter() {
dc262918 171
172 //destructor
173
56cbeefb 174 cout<<"AliHFMassFitter destructor called"<<endl;
a60f573d 175
59c56ce7 176 delete fhistoInvMass;
a60f573d 177
59c56ce7 178 delete fntuParam;
3c0e7d59 179
59c56ce7 180 delete[] fFitPars;
181
182 delete[] fFixPar;
183
56cbeefb 184 fcounter = 0;
74179930 185}
186
187//_________________________________________________________________________
188
189AliHFMassFitter& AliHFMassFitter::operator=(const AliHFMassFitter &mfit){
190
191 //assignment operator
192
193 if(&mfit == this) return *this;
194 fhistoInvMass= mfit.fhistoInvMass;
195 fminMass= mfit.fminMass;
196 fmaxMass= mfit.fmaxMass;
197 fNbin= mfit.fNbin;
2f328d65 198 fParsSize= mfit.fParsSize;
74179930 199 fWithBkg= mfit.fWithBkg;
200 ftypeOfFit4Bkg= mfit.ftypeOfFit4Bkg;
201 ftypeOfFit4Sgn= mfit.ftypeOfFit4Sgn;
202 ffactor= mfit.ffactor;
203 fntuParam= mfit.fntuParam;
204 fMass= mfit.fMass;
205 fSigmaSgn= mfit.fSigmaSgn;
206 fSideBands= mfit.fSideBands;
b7d4bc49 207 fSideBandl= mfit.fSideBandl;
208 fSideBandr= mfit.fSideBandr;
56cbeefb 209 fcounter= mfit.fcounter;
ad73ca8f 210 fContourGraph= mfit.fContourGraph;
211
2f328d65 212 if(mfit.fParsSize > 0){
59c56ce7 213 delete[] fFitPars;
214
2f328d65 215 fFitPars=new Float_t[fParsSize];
216 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
3c0e7d59 217
59c56ce7 218 delete[] fFixPar;
219
d22f0682 220 fFixPar=new Bool_t[fNFinalPars];
221 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Float_t));
2f328d65 222 }
74179930 223
224 return *this;
225}
56cbeefb 226
227//************ tools & settings
228
2f328d65 229//__________________________________________________________________________
230
d22f0682 231void AliHFMassFitter::ComputeNFinalPars() {
4d7b8e51 232
233 //compute the number of parameters of the total (signal+bgk) function
234 cout<<"Info:ComputeNFinalPars... ";
d22f0682 235 switch (ftypeOfFit4Bkg) {//npar background func
236 case 0:
237 fNFinalPars=2;
238 break;
239 case 1:
240 fNFinalPars=2;
241 break;
242 case 2:
243 fNFinalPars=3;
244 break;
245 case 3:
246 fNFinalPars=1;
247 break;
248 default:
249 cout<<"Error in computing fNFinalPars: check ftypeOfFit4Bkg"<<endl;
250 break;
251 }
252
253 fNFinalPars+=3; //gaussian signal
4d7b8e51 254 cout<<": "<<fNFinalPars<<endl;
d22f0682 255}
256//__________________________________________________________________________
257
2f328d65 258void AliHFMassFitter::ComputeParSize() {
dc262918 259
260 //compute the size of the parameter array and set the data member
261
d22f0682 262 switch (ftypeOfFit4Bkg) {//npar background func
2f328d65 263 case 0:
264 fParsSize = 2*3;
265 break;
266 case 1:
267 fParsSize = 2*3;
268 break;
269 case 2:
270 fParsSize = 3*3;
271 break;
272 case 3:
56cbeefb 273 fParsSize = 1*3;
2f328d65 274 break;
275 default:
56cbeefb 276 cout<<"Error in computing fParsSize: check ftypeOfFit4Bkg"<<endl;
2f328d65 277 break;
278 }
279
56cbeefb 280 fParsSize += 3; // npar refl
281 fParsSize += 3; // npar signal gaus
2f328d65 282
56cbeefb 283 fParsSize*=2; // add errors
2f328d65 284 cout<<"Parameters array size "<<fParsSize<<endl;
285}
286
4d7b8e51 287//___________________________________________________________________________
288void AliHFMassFitter::SetDefaultFixParam(){
289
290 //Set default values for fFixPar (only total integral fixed)
291
292 ComputeNFinalPars();
293 fFixPar=new Bool_t[fNFinalPars];
294
295 fFixPar[0]=kTRUE; //default: IntTot fixed
296 cout<<"Parameter 0 is fixed"<<endl;
297 for(Int_t i=1;i<fNFinalPars;i++){
298 fFixPar[i]=kFALSE;
299 }
300
301}
302
3c0e7d59 303//___________________________________________________________________________
304Bool_t AliHFMassFitter::SetFixThisParam(Int_t thispar,Bool_t fixpar){
305
306 //set the value (kFALSE or kTRUE) of one element of fFixPar
307 //return kFALSE if something wrong
308
d22f0682 309 if(thispar>=fNFinalPars) {
310 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
3c0e7d59 311 return kFALSE;
312 }
d22f0682 313 if(!fFixPar){
314 cout<<"Initializing fFixPar...";
4d7b8e51 315 SetDefaultFixParam();
d22f0682 316 cout<<" done."<<endl;
317 }
318
3c0e7d59 319 fFixPar[thispar]=fixpar;
5a8a84f8 320 if(fixpar)cout<<"Parameter "<<thispar<<" is now fixed"<<endl;
321 else cout<<"Parameter "<<thispar<<" is now free"<<endl;
3c0e7d59 322 return kTRUE;
323}
324
325//___________________________________________________________________________
326Bool_t AliHFMassFitter::GetFixThisParam(Int_t thispar)const{
327 //return the value of fFixPar[thispar]
d22f0682 328 if(thispar>=fNFinalPars) {
329 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
3c0e7d59 330 return kFALSE;
331 }
4d7b8e51 332 if(!fFixPar) {
333 cout<<"Error! Parameters to be fixed still not set"<<endl;
334 return kFALSE;
335
336 }
3c0e7d59 337 return fFixPar[thispar];
338
339}
340
56cbeefb 341//___________________________________________________________________________
dc262918 342void AliHFMassFitter::SetHisto(const TH1F *histoToFit){
24e73105 343
a60f573d 344 fhistoInvMass = new TH1F(*histoToFit);
6321ee46 345 fhistoInvMass->SetDirectory(0);
9ca8c21c 346 //cout<<"SetHisto pointer "<<fhistoInvMass<<endl;
56cbeefb 347}
348
2f328d65 349//___________________________________________________________________________
350
24e73105 351void AliHFMassFitter::SetType(Int_t fittypeb, Int_t fittypes) {
352
353 //set the type of fit to perform for signal and background
354
355 ftypeOfFit4Bkg = fittypeb;
356 ftypeOfFit4Sgn = fittypes;
357
358 ComputeParSize();
359 fFitPars = new Float_t[fParsSize];
360
361 SetDefaultFixParam();
2f328d65 362}
74179930 363
fabf4d8e 364//___________________________________________________________________________
365
56cbeefb 366void AliHFMassFitter::Reset() {
dc262918 367
368 //delete the histogram and reset the mean and sigma to default
369
a60f573d 370 cout<<"Reset called: delete histogram, set mean value to 1.85 and sigma to 0.012"<<endl;
0566386c 371 fMass=1.85;
372 fSigmaSgn=0.012;
a60f573d 373 cout<<"Reset "<<fhistoInvMass<<endl;
59c56ce7 374 delete fhistoInvMass;
56cbeefb 375}
376
377//_________________________________________________________________________
378
379void AliHFMassFitter::InitNtuParam(char *ntuname) {
dc262918 380
56cbeefb 381 // Create ntuple to keep fit parameters
dc262918 382
56cbeefb 383 fntuParam=0;
384 fntuParam=new TNtuple(ntuname,"Contains fit parameters","intbkg1:slope1:conc1:intGB:meanGB:sigmaGB:intbkg2:slope2:conc2:inttot:slope3:conc3:intsgn:meansgn:sigmasgn:intbkg1Err:slope1Err:conc1Err:intGBErr:meanGBErr:sigmaGBErr:intbkg2Err:slope2Err:conc2Err:inttotErr:slope3Err:conc3Err:intsgnErr:meansgnErr:sigmasgnErr");
385
386}
387
388//_________________________________________________________________________
389
390void AliHFMassFitter::FillNtuParam() {
391 // Fill ntuple with fit parameters
392
393 Float_t nothing=0.;
394
395 if (ftypeOfFit4Bkg==2) {
396 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
397 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
398 fntuParam->SetBranchAddress("conc1",&fFitPars[2]);
399 fntuParam->SetBranchAddress("intGB",&fFitPars[3]);
400 fntuParam->SetBranchAddress("meanGB",&fFitPars[4]);
401 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[5]);
402 fntuParam->SetBranchAddress("intbkg2",&fFitPars[6]);
403 fntuParam->SetBranchAddress("slope2",&fFitPars[7]);
404 fntuParam->SetBranchAddress("conc2",&fFitPars[8]);
405 fntuParam->SetBranchAddress("inttot",&fFitPars[9]);
406 fntuParam->SetBranchAddress("slope3",&fFitPars[10]);
407 fntuParam->SetBranchAddress("conc3",&fFitPars[11]);
408 fntuParam->SetBranchAddress("intsgn",&fFitPars[12]);
409 fntuParam->SetBranchAddress("meansgn",&fFitPars[13]);
410 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[14]);
411
412 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[15]);
413 fntuParam->SetBranchAddress("slope1Err",&fFitPars[16]);
414 fntuParam->SetBranchAddress("conc1Err",&fFitPars[17]);
415 fntuParam->SetBranchAddress("intGBErr",&fFitPars[18]);
416 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[19]);
417 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[20]);
418 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[21]);
419 fntuParam->SetBranchAddress("slope2Err",&fFitPars[22]);
420 fntuParam->SetBranchAddress("conc2Err",&fFitPars[23]);
421 fntuParam->SetBranchAddress("inttotErr",&fFitPars[24]);
422 fntuParam->SetBranchAddress("slope3Err",&fFitPars[25]);
423 fntuParam->SetBranchAddress("conc3Err",&fFitPars[26]);
424 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[27]);
425 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[28]);
426 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[29]);
427
428 } else {
429
430 if(ftypeOfFit4Bkg==3){
431 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
432 fntuParam->SetBranchAddress("slope1",&nothing);
433 fntuParam->SetBranchAddress("conc1",&nothing);
434 fntuParam->SetBranchAddress("intGB",&fFitPars[1]);
435 fntuParam->SetBranchAddress("meanGB",&fFitPars[2]);
436 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[3]);
437 fntuParam->SetBranchAddress("intbkg2",&fFitPars[4]);
438 fntuParam->SetBranchAddress("slope2",&nothing);
439 fntuParam->SetBranchAddress("conc2",&nothing);
440 fntuParam->SetBranchAddress("inttot",&fFitPars[6]);
441 fntuParam->SetBranchAddress("slope3",&nothing);
442 fntuParam->SetBranchAddress("conc3",&nothing);
443 fntuParam->SetBranchAddress("intsgn",&fFitPars[6]);
444 fntuParam->SetBranchAddress("meansgn",&fFitPars[7]);
445 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[8]);
446
447 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[9]);
448 fntuParam->SetBranchAddress("slope1Err",&nothing);
449 fntuParam->SetBranchAddress("conc1Err",&nothing);
450 fntuParam->SetBranchAddress("intGBErr",&fFitPars[10]);
451 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[11]);
452 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[12]);
453 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[13]);
454 fntuParam->SetBranchAddress("slope2Err",&nothing);
455 fntuParam->SetBranchAddress("conc2Err",&nothing);
456 fntuParam->SetBranchAddress("inttotErr",&fFitPars[15]);
457 fntuParam->SetBranchAddress("slope3Err",&nothing);
458 fntuParam->SetBranchAddress("conc3Err",&nothing);
459 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[15]);
460 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[16]);
461 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[17]);
462
463 }
464 else{
465 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
466 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
467 fntuParam->SetBranchAddress("conc1",&nothing);
468 fntuParam->SetBranchAddress("intGB",&fFitPars[2]);
469 fntuParam->SetBranchAddress("meanGB",&fFitPars[3]);
470 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[4]);
471 fntuParam->SetBranchAddress("intbkg2",&fFitPars[5]);
472 fntuParam->SetBranchAddress("slope2",&fFitPars[6]);
473 fntuParam->SetBranchAddress("conc2",&nothing);
474 fntuParam->SetBranchAddress("inttot",&fFitPars[7]);
475 fntuParam->SetBranchAddress("slope3",&fFitPars[8]);
476 fntuParam->SetBranchAddress("conc3",&nothing);
477 fntuParam->SetBranchAddress("intsgn",&fFitPars[9]);
478 fntuParam->SetBranchAddress("meansgn",&fFitPars[10]);
479 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[11]);
480
481 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[12]);
482 fntuParam->SetBranchAddress("slope1Err",&fFitPars[13]);
483 fntuParam->SetBranchAddress("conc1Err",&nothing);
484 fntuParam->SetBranchAddress("intGBErr",&fFitPars[14]);
485 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[15]);
486 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[16]);
487 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[17]);
488 fntuParam->SetBranchAddress("slope2Err",&fFitPars[18]);
489 fntuParam->SetBranchAddress("conc2Err",&nothing);
490 fntuParam->SetBranchAddress("inttotErr",&fFitPars[19]);
491 fntuParam->SetBranchAddress("slope3Err",&fFitPars[20]);
492 fntuParam->SetBranchAddress("conc3Err",&nothing);
493 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[21]);
494 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[22]);
495 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[23]);
496 }
497
498 }
499 fntuParam->TTree::Fill();
500}
501
502//_________________________________________________________________________
503
504TNtuple* AliHFMassFitter::NtuParamOneShot(char *ntuname){
505 // Create, fill and return ntuple with fit parameters
506
507 InitNtuParam(ntuname);
508 FillNtuParam();
509 return fntuParam;
510}
511//_________________________________________________________________________
512
513void AliHFMassFitter::RebinMass(Int_t bingroup){
514 // Rebin invariant mass histogram
515
3c0e7d59 516 if(!fhistoInvMass){
517 cout<<"Histogram not set"<<endl;
518 return;
519 }
d22f0682 520 Int_t nbinshisto=fhistoInvMass->GetNbinsX();
56cbeefb 521 if(bingroup<1){
522 cout<<"Error! Cannot group "<<bingroup<<" bins\n";
d22f0682 523 fNbin=nbinshisto;
56cbeefb 524 cout<<"Kept original number of bins: "<<fNbin<<endl;
525 } else{
5a8a84f8 526
527 while(nbinshisto%bingroup != 0) {
528 bingroup--;
529 }
530 cout<<"Group "<<bingroup<<" bins"<<endl;
56cbeefb 531 fhistoInvMass->Rebin(bingroup);
532 fNbin = fhistoInvMass->GetNbinsX();
533 cout<<"New number of bins: "<<fNbin<<endl;
534 }
56cbeefb 535
536}
537
538//************* fit
539
540//___________________________________________________________________________
541
fabf4d8e 542Double_t AliHFMassFitter::FitFunction4MassDistr (Double_t *x, Double_t *par){
543 // Fit function for signal+background
544
545
546 //exponential or linear fit
547 //
548 // par[0] = tot integral
549 // par[1] = slope
550 // par[2] = gaussian integral
551 // par[3] = gaussian mean
552 // par[4] = gaussian sigma
553
554 Double_t total,bkg=0,sgn=0;
555
556 if (ftypeOfFit4Bkg==0 || ftypeOfFit4Bkg==1) {
557 if(ftypeOfFit4Sgn == 0) {
558
559 Double_t parbkg[2] = {par[0]-par[2], par[1]};
560 bkg = FitFunction4Bkg(x,parbkg);
561 }
562 if(ftypeOfFit4Sgn == 1) {
563 Double_t parbkg[5] = {par[2],par[3],ffactor*par[4],par[0]-2*par[2], par[1]};
564 bkg = FitFunction4Bkg(x,parbkg);
565 }
566
567 sgn = FitFunction4Sgn(x,&par[2]);
568
569 }
570
571 //polynomial fit
572
573 // par[0] = tot integral
574 // par[1] = coef1
575 // par[2] = coef2
576 // par[3] = gaussian integral
577 // par[4] = gaussian mean
578 // par[5] = gaussian sigma
579
580 if (ftypeOfFit4Bkg==2) {
581
582 if(ftypeOfFit4Sgn == 0) {
56cbeefb 583
fabf4d8e 584 Double_t parbkg[3] = {par[0]-par[3], par[1], par[2]};
585 bkg = FitFunction4Bkg(x,parbkg);
586 }
587 if(ftypeOfFit4Sgn == 1) {
56cbeefb 588
fabf4d8e 589 Double_t parbkg[6] = {par[3],par[4],ffactor*par[5],par[0]-2*par[3], par[1], par[2]};
16856d6e 590 bkg = FitFunction4Bkg(x,parbkg);
fabf4d8e 591 }
592
593 sgn = FitFunction4Sgn(x,&par[3]);
594 }
595
596 if (ftypeOfFit4Bkg==3) {
597
598 if(ftypeOfFit4Sgn == 0) {
599 bkg=FitFunction4Bkg(x,par);
600 sgn=FitFunction4Sgn(x,&par[1]);
601 }
602 if(ftypeOfFit4Sgn == 1) {
603 Double_t parbkg[4]={par[1],par[2],ffactor*par[3],par[0]};
604 bkg=FitFunction4Bkg(x,parbkg);
605 sgn=FitFunction4Sgn(x,&par[1]);
606 }
607 }
608
609 total = bkg + sgn;
610
611 return total;
612}
613
614//_________________________________________________________________________
615Double_t AliHFMassFitter::FitFunction4Sgn (Double_t *x, Double_t *par){
616 // Fit function for the signal
617
618 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
619 //Par:
620 // * [0] = integralSgn
621 // * [1] = mean
622 // * [2] = sigma
623 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
624
625 return par[0]/TMath::Sqrt(2.*TMath::Pi())/par[2]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/2./par[2]/par[2]);
626
627}
628
629//__________________________________________________________________________
630
631Double_t AliHFMassFitter::FitFunction4Bkg (Double_t *x, Double_t *par){
632 // Fit function for the background
633
634 Double_t maxDeltaM = 4.*fSigmaSgn;
635 if(fSideBands && TMath::Abs(x[0]-fMass) < maxDeltaM) {
636 TF1::RejectPoint();
637 return 0;
638 }
639 Int_t firstPar=0;
640 Double_t gaus2=0,total=-1;
641 if(ftypeOfFit4Sgn == 1){
642 firstPar=3;
643 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
644 //Par:
645 // * [0] = integralSgn
646 // * [1] = mean
647 // * [2] = sigma
648 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
649 gaus2 = FitFunction4Sgn(x,par);
650 }
651
652 switch (ftypeOfFit4Bkg){
653 case 0:
654 //exponential
655 //exponential = A*exp(B*x) -> integral(exponential)=A/B*exp(B*x)](min,max)
656 //-> A = B*integral/(exp(B*max)-exp(B*min)) where integral can be written
657 //as integralTot- integralGaus (=par [2])
658 //Par:
659 // * [0] = integralBkg;
660 // * [1] = B;
661 //exponential = [1]*[0]/(exp([1]*max)-exp([1]*min))*exp([1]*x)
662 total = par[0+firstPar]*par[1+firstPar]/(TMath::Exp(par[1+firstPar]*fmaxMass)-TMath::Exp(par[1+firstPar]*fminMass))*TMath::Exp(par[1+firstPar]*x[0]);
663 break;
664 case 1:
665 //linear
666 //y=a+b*x -> integral = a(max-min)+1/2*b*(max^2-min^2) -> a = (integral-1/2*b*(max^2-min^2))/(max-min)=integral/(max-min)-1/2*b*(max+min)
667 // * [0] = integralBkg;
668 // * [1] = b;
669 total= par[0+firstPar]/(fmaxMass-fminMass)+par[1+firstPar]*(x[0]-0.5*(fmaxMass+fminMass));
670 break;
671 case 2:
672 //polynomial
673 //y=a+b*x+c*x**2 -> integral = a(max-min) + 1/2*b*(max^2-min^2) +
674 //+ 1/3*c*(max^3-min^3) ->
675 //a = (integral-1/2*b*(max^2-min^2)-1/3*c*(max^3-min^3))/(max-min)
676 // * [0] = integralBkg;
677 // * [1] = b;
678 // * [2] = c;
679 total = par[0+firstPar]/(fmaxMass-fminMass)+par[1]*(x[0]-0.5*(fmaxMass+fminMass))+par[2+firstPar]*(x[0]*x[0]-1/3.*(fmaxMass*fmaxMass*fmaxMass-fminMass*fminMass*fminMass)/(fmaxMass-fminMass));
680 break;
681 case 3:
682 total=par[0+firstPar];
683 break;
684// default:
685// Types of Fit Functions for Background:
686// * 0 = exponential;
687// * 1 = linear;
688// * 2 = polynomial 2nd order
689// * 3 = no background"<<endl;
690
691 }
692 return total+gaus2;
693}
694
b7d4bc49 695//__________________________________________________________________________
696Bool_t AliHFMassFitter::SideBandsBounds(){
697
dc262918 698 //determines the ranges of the side bands
699
b7d4bc49 700 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
701 Double_t minHisto=fhistoInvMass->GetBinLowEdge(1);
24e73105 702 Double_t maxHisto=fhistoInvMass->GetBinLowEdge(fNbin+1);
703
704 Double_t sidebandldouble,sidebandrdouble;
705 Bool_t leftok=kFALSE, rightok=kFALSE;
b7d4bc49 706
707 if(fMass-fminMass < 0 || fmaxMass-fMass <0) {
708 cout<<"Left limit of range > mean or right limit of range < mean: change left/right limit or initial mean value"<<endl;
709 return kFALSE;
710 }
711
24e73105 712 //histo limit = fit function limit
713 if((TMath::Abs(fminMass-minHisto) < 1e6 || TMath::Abs(fmaxMass - maxHisto) < 1e6) && (fMass-4.*fSigmaSgn-fminMass) < 1e6){
b7d4bc49 714 Double_t coeff = (fMass-fminMass)/fSigmaSgn;
24e73105 715 sidebandldouble=(fMass-0.5*coeff*fSigmaSgn);
716 sidebandrdouble=(fMass+0.5*coeff*fSigmaSgn);
b7d4bc49 717 cout<<"Changed number of sigma from 4 to "<<0.5*coeff<<" for the estimation of the side bands"<<endl;
718 if (coeff<3) cout<<"Side bands inside 3 sigma, may be better use ftypeOfFit4Bkg = 3 (only signal)"<<endl;
b7d4bc49 719 if (coeff<2) {
720 cout<<"Side bands inside 2 sigma. Change mode: ftypeOfFit4Bkg = 3"<<endl;
721 ftypeOfFit4Bkg=3;
722 //set binleft and right without considering SetRangeFit- anyway no bkg!
24e73105 723 sidebandldouble=(fMass-4.*fSigmaSgn);
724 sidebandrdouble=(fMass+4.*fSigmaSgn);
b7d4bc49 725 }
726 }
727 else {
24e73105 728 sidebandldouble=(fMass-4.*fSigmaSgn);
729 sidebandrdouble=(fMass+4.*fSigmaSgn);
730 }
731
732 cout<<"Left side band ";
733 Double_t tmp=0.;
734 tmp=sidebandldouble;
735 //calculate bin corresponding to fSideBandl
736 fSideBandl=fhistoInvMass->FindBin(sidebandldouble);
737 if (sidebandldouble >= fhistoInvMass->GetBinCenter(fSideBandl)) fSideBandl++;
738 sidebandldouble=fhistoInvMass->GetBinLowEdge(fSideBandl);
739
740 if(TMath::Abs(tmp-sidebandldouble) > 1e-6){
741 cout<<tmp<<" is not allowed, changing it to the nearest value allowed: ";
742 leftok=kTRUE;
b7d4bc49 743 }
24e73105 744 cout<<sidebandldouble<<" (bin "<<fSideBandl<<")"<<endl;
745
746 cout<<"Right side band ";
747 tmp=sidebandrdouble;
748 //calculate bin corresponding to fSideBandr
749 fSideBandr=fhistoInvMass->FindBin(sidebandrdouble);
750 if (sidebandrdouble < fhistoInvMass->GetBinCenter(fSideBandr)) fSideBandr--;
751 sidebandrdouble=fhistoInvMass->GetBinLowEdge(fSideBandr+1);
b7d4bc49 752
24e73105 753 if(TMath::Abs(tmp-sidebandrdouble) > 1e-6){
754 cout<<tmp<<" is not allowed, changing it to the nearest value allowed: ";
755 rightok=kTRUE;
756 }
757 cout<<sidebandrdouble<<" (bin "<<fSideBandr<<")"<<endl;
758 if (fSideBandl==0 || fSideBandr==fNbin) {
b7d4bc49 759 cout<<"Error! Range too little";
760 return kFALSE;
761 }
b7d4bc49 762 return kTRUE;
763}
764
16856d6e 765//__________________________________________________________________________
766
b7d4bc49 767void AliHFMassFitter::GetSideBandsBounds(Int_t &left, Int_t &right) const{
dc262918 768
769 // get the range of the side bands
770
b7d4bc49 771 if (fSideBandl==0 && fSideBandr==0){
772 cout<<"Use MassFitter method first"<<endl;
773 return;
774 }
775 left=fSideBandl;
776 right=fSideBandr;
777}
778
d22f0682 779//__________________________________________________________________________
780Bool_t AliHFMassFitter::CheckRangeFit(){
781 //check if the limit of the range correspond to the limit of bins. If not reset the limit to the nearer value which satisfy this condition
782
783 if (!fhistoInvMass) {
784 cout<<"No histogram to fit! SetHisto(TH1F* h) before! "<<endl;
785 return kFALSE;
786 }
787 Bool_t leftok=kFALSE, rightok=kFALSE;
788 Int_t nbins=fhistoInvMass->GetNbinsX();
24e73105 789 Double_t minhisto=fhistoInvMass->GetBinLowEdge(1), maxhisto=fhistoInvMass->GetBinLowEdge(nbins+1);
d22f0682 790
791 //check if limits are inside histogram range
5a8a84f8 792
d22f0682 793 if( fminMass-minhisto < 0. ) {
5a8a84f8 794 cout<<"Out of histogram left bound! Setting to "<<minhisto<<endl;
d22f0682 795 fminMass=minhisto;
796 }
797 if( fmaxMass-maxhisto > 0. ) {
5a8a84f8 798 cout<<"Out of histogram right bound! Setting to"<<maxhisto<<endl;
d22f0682 799 fmaxMass=maxhisto;
800 }
801
d22f0682 802 Double_t tmp=0.;
803 tmp=fminMass;
804 //calculate bin corresponding to fminMass
24e73105 805 fminBinMass=fhistoInvMass->FindBin(fminMass);
806 if (fminMass >= fhistoInvMass->GetBinCenter(fminBinMass)) fminBinMass++;
807 fminMass=fhistoInvMass->GetBinLowEdge(fminBinMass);
d22f0682 808 if(TMath::Abs(tmp-fminMass) > 1e-6){
809 cout<<"Left bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fminMass<<endl;
810 leftok=kTRUE;
811 }
812
813 tmp=fmaxMass;
814 //calculate bin corresponding to fmaxMass
24e73105 815 fmaxBinMass=fhistoInvMass->FindBin(fmaxMass);
816 if (fmaxMass < fhistoInvMass->GetBinCenter(fmaxBinMass)) fmaxBinMass--;
817 fmaxMass=fhistoInvMass->GetBinLowEdge(fmaxBinMass+1);
d22f0682 818 if(TMath::Abs(tmp-fmaxMass) > 1e-6){
819 cout<<"Right bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fmaxMass<<endl;
820 rightok=kTRUE;
821 }
822
823 return (leftok && rightok);
824
825}
826
fabf4d8e 827//__________________________________________________________________________
828
34c79b83 829Bool_t AliHFMassFitter::MassFitter(Bool_t draw){
fabf4d8e 830 // Main method of the class: performs the fit of the histogram
ad73ca8f 831
832 //Set default fitter Minuit in order to use gMinuit in the contour plots
833 TVirtualFitter::SetDefaultFitter("Minuit");
834
24e73105 835
ef6f2bce 836 Bool_t isBkgOnly=kFALSE;
837
838 Int_t fit1status=RefitWithBkgOnly(kFALSE);
839 if(fit1status){
840 Int_t checkinnsigma=4;
841 Double_t range[2]={fMass-checkinnsigma*fSigmaSgn,fMass+checkinnsigma*fSigmaSgn};
842 TF1* func=GetHistoClone()->GetFunction("funcbkgonly");
843 Double_t intUnderFunc=func->Integral(range[0],range[1]);
844 Double_t intUnderHisto=fhistoInvMass->Integral(fhistoInvMass->FindBin(range[0]),fhistoInvMass->FindBin(range[1]),"width");
845 cout<<"Pick zone: IntFunc = "<<intUnderFunc<<"; IntHist = "<<intUnderHisto<<"\tDiff = "<<intUnderHisto-intUnderFunc<<"\tRelDiff = "<<(intUnderHisto-intUnderFunc)/intUnderFunc<<endl;
846 Double_t diffUnderPick=(intUnderHisto-intUnderFunc);
847 intUnderFunc=func->Integral(fminMass,fminMass+checkinnsigma*fSigmaSgn);
848 intUnderHisto=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fminMass+checkinnsigma*fSigmaSgn),"width");
849 cout<<"Band (l) zone: IntFunc = "<<intUnderFunc<<"; IntHist = "<<intUnderHisto<<"\tDiff = "<<intUnderHisto-intUnderFunc<<"\tRelDiff = "<<(intUnderHisto-intUnderFunc)/intUnderFunc<<endl;
850 Double_t diffUnderBands=(intUnderHisto-intUnderFunc);
851 Double_t relDiff=diffUnderPick/diffUnderBands;
852 cout<<"Relative difference = "<<relDiff<<endl;
853 if(TMath::Abs(relDiff) < 1) isBkgOnly=kTRUE;
854 else{
855 cout<<"Relative difference = "<<relDiff<<": I suppose there is some signal, continue with total fit!"<<endl;
856 }
857 }
858 if(isBkgOnly) {
859 cout<<"INFO!! The histogram contains only background"<<endl;
860 if(draw)DrawFit();
ef6f2bce 861
24e73105 862 //increase counter of number of fits done
863 fcounter++;
864
865 return kTRUE;
fabf4d8e 866 }
867
24e73105 868 Int_t bkgPar = fNFinalPars-3; //background function's number of parameters
fabf4d8e 869
24e73105 870 cout<<"fNFinalPars = "<<fNFinalPars<<"\tbkgPar = "<<bkgPar<<endl;
fabf4d8e 871
ad73ca8f 872
873 TString listname="contourplot";
874 listname+=fcounter;
875 if(!fContourGraph){
876 fContourGraph=new TList();
877 fContourGraph->SetOwner();
878 }
879
880 fContourGraph->SetName(listname);
881
882
56cbeefb 883 //function names
884 TString bkgname="funcbkg";
885 TString bkg1name="funcbkg1";
886 TString massname="funcmass";
887
fabf4d8e 888 //Total integral
24e73105 889 Double_t totInt = fhistoInvMass->Integral(fminBinMass,fmaxBinMass, "width");
9ca8c21c 890 //cout<<"Here tot integral is = "<<totInt<<"; integral in whole range is "<<fhistoInvMass->Integral("width")<<endl;
fabf4d8e 891 fSideBands = kTRUE;
34c79b83 892 Double_t width=fhistoInvMass->GetBinWidth(8);
9ca8c21c 893 //cout<<"fNbin = "<<fNbin<<endl;
34c79b83 894 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
24e73105 895
b7d4bc49 896 Bool_t ok=SideBandsBounds();
897 if(!ok) return kFALSE;
34c79b83 898
fabf4d8e 899 //sidebands integral - first approx (from histo)
b7d4bc49 900 Double_t sideBandsInt=(Double_t)fhistoInvMass->Integral(1,fSideBandl,"width") + (Double_t)fhistoInvMass->Integral(fSideBandr,fNbin,"width");
901 cout<<"------nbin = "<<fNbin<<"\twidth = "<<width<<"\tbinleft = "<<fSideBandl<<"\tbinright = "<<fSideBandr<<endl;
fabf4d8e 902 cout<<"------sideBandsInt - first approx = "<<sideBandsInt<<endl;
b7d4bc49 903 if (sideBandsInt<=0) {
904 cout<<"! sideBandsInt <=0. There's a problem, cannot start the fit"<<endl;
905 return kFALSE;
906 }
907
fabf4d8e 908 /*Fit Bkg*/
909
16856d6e 910
d22f0682 911 TF1 *funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
56cbeefb 912 cout<<"Function name = "<<funcbkg->GetName()<<endl<<endl;
fabf4d8e 913
914 funcbkg->SetLineColor(2); //red
915
916 //first fit for bkg: approx bkgint
917
918 switch (ftypeOfFit4Bkg) {
919 case 0: //gaus+expo
920 funcbkg->SetParNames("BkgInt","Slope");
921 funcbkg->SetParameters(sideBandsInt,-2.);
922 break;
923 case 1:
924 funcbkg->SetParNames("BkgInt","Slope");
925 funcbkg->SetParameters(sideBandsInt,-100.);
926 break;
927 case 2:
928 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
929 funcbkg->SetParameters(sideBandsInt,-10.,5);
930 break;
931 case 3:
932 if(ftypeOfFit4Sgn==0){
fabf4d8e 933 funcbkg->SetParNames("Const");
934 funcbkg->SetParameter(0,0.);
935 funcbkg->FixParameter(0,0.);
936 }
937 break;
938 default:
939 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
34c79b83 940 return kFALSE;
fabf4d8e 941 break;
942 }
943 cout<<"\nBACKGROUND FIT - only combinatorial"<<endl;
944 Int_t ftypeOfFit4SgnBkp=ftypeOfFit4Sgn;
945
946 Double_t intbkg1=0,slope1=0,conc1=0;
56cbeefb 947 //if only signal and reflection: skip
fabf4d8e 948 if (!(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn==1)) {
949 ftypeOfFit4Sgn=0;
56cbeefb 950 fhistoInvMass->Fit(bkgname.Data(),"R,L,E,0");
fabf4d8e 951
952 for(Int_t i=0;i<bkgPar;i++){
953 fFitPars[i]=funcbkg->GetParameter(i);
954 //cout<<i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
24e73105 955 fFitPars[fNFinalPars+2*bkgPar+3+i]= funcbkg->GetParError(i);
956 //cout<<fNFinalPars+2*bkgPar+3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
fabf4d8e 957 }
b7d4bc49 958 fSideBands = kFALSE;
34c79b83 959 //intbkg1 = funcbkg->GetParameter(0);
24e73105 960
34c79b83 961 intbkg1 = funcbkg->Integral(fminMass,fmaxMass);
fabf4d8e 962 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg->GetParameter(1);
963 if(ftypeOfFit4Bkg==2) conc1 = funcbkg->GetParameter(2);
9ca8c21c 964 //cout<<"First fit: \nintbkg1 = "<<intbkg1<<"\t(Compare with par0 = "<<funcbkg->GetParameter(0)<<")\nslope1= "<<slope1<<"\nconc1 = "<<conc1<<endl;
56cbeefb 965 }
966 else cout<<"\t\t//"<<endl;
fabf4d8e 967
968 ftypeOfFit4Sgn=ftypeOfFit4SgnBkp;
969 TF1 *funcbkg1=0;
970 if (ftypeOfFit4Sgn == 1) {
971 cout<<"\nBACKGROUND FIT WITH REFLECTION"<<endl;
972 bkgPar+=3;
973
9ca8c21c 974 //cout<<"fNFinalPars = "<<fNFinalPars<<"\tbkgPar = "<<bkgPar<<endl;
56cbeefb 975
976 funcbkg1 = new TF1(bkg1name.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
977 cout<<"Function name = "<<funcbkg1->GetName()<<endl;
978
fabf4d8e 979 funcbkg1->SetLineColor(2); //red
980
981 if(ftypeOfFit4Bkg==2){
982 cout<<"*** Polynomial Fit ***"<<endl;
983 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef1","Coef2");
984 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1,conc1);
6321ee46 985
986 //cout<<"Parameters set to: "<<0.5*(totInt-intbkg1)<<"\t"<<fMass<<"\t"<<ffactor*fSigmaSgn<<"\t"<<intbkg1<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<endl;
987 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<bkgPar<<"\tgsidebands = "<<fSideBands<<endl;
fabf4d8e 988 } else{
989 if(ftypeOfFit4Bkg==3) //no background: gaus sign+ gaus broadened
990 {
991 cout<<"*** No background Fit ***"<<endl;
992 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","Const");
993 funcbkg1->SetParameters(0.5*totInt,fMass,ffactor*fSigmaSgn,0.);
994 funcbkg1->FixParameter(3,0.);
995 } else{ //expo or linear
996 if(ftypeOfFit4Bkg==0) cout<<"*** Exponential Fit ***"<<endl;
997 if(ftypeOfFit4Bkg==1) cout<<"*** Linear Fit ***"<<endl;
998 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Slope");
999 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1);
1000 }
1001 }
6321ee46 1002 Int_t status=fhistoInvMass->Fit(bkg1name.Data(),"R,L,E,+,0");
1003 if (status != 0){
1004 cout<<"Minuit returned "<<status<<endl;
1005 return kFALSE;
1006 }
1007
fabf4d8e 1008 for(Int_t i=0;i<bkgPar;i++){
1009 fFitPars[bkgPar-3+i]=funcbkg1->GetParameter(i);
1010 //cout<<bkgPar-3+i<<"\t"<<funcbkg1->GetParameter(i);
24e73105 1011 fFitPars[fNFinalPars+3*bkgPar-6+i]= funcbkg1->GetParError(i);
1012 //cout<<"\t"<<fNFinalPars+3*bkgPar-6+i<<"\t"<<funcbkg1->GetParError(i)<<endl;
fabf4d8e 1013 }
1014
1015 intbkg1=funcbkg1->GetParameter(3);
1016 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg1->GetParameter(4);
1017 if(ftypeOfFit4Bkg==2) conc1 = funcbkg1->GetParameter(5);
1018
1019 } else {
1020 bkgPar+=3;
1021
1022 for(Int_t i=0;i<3;i++){
1023 fFitPars[bkgPar-3+i]=0.;
56cbeefb 1024 cout<<bkgPar-3+i<<"\t"<<0.<<"\t";
24e73105 1025 fFitPars[fNFinalPars+3*bkgPar-6+i]= 0.;
1026 cout<<fNFinalPars+3*bkgPar-6+i<<"\t"<<0.<<endl;
fabf4d8e 1027 }
1028
1029 for(Int_t i=0;i<bkgPar-3;i++){
1030 fFitPars[bkgPar+i]=funcbkg->GetParameter(i);
56cbeefb 1031 cout<<bkgPar+i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
24e73105 1032 fFitPars[fNFinalPars+3*bkgPar-3+i]= funcbkg->GetParError(i);
1033 cout<<fNFinalPars+3*bkgPar-3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
fabf4d8e 1034 }
1035
1036
1037 }
1038
1039 //sidebands integral - second approx (from fit)
1040 fSideBands = kFALSE;
1041 Double_t bkgInt;
9ca8c21c 1042 //cout<<"Compare intbkg1 = "<<intbkg1<<" and integral = ";
fabf4d8e 1043 if(ftypeOfFit4Sgn == 1) bkgInt=funcbkg1->Integral(fminMass,fmaxMass);
1044 else bkgInt=funcbkg->Integral(fminMass,fmaxMass);
9ca8c21c 1045 //cout<</*"------BkgInt(Fit) = "<<*/bkgInt<<endl;
fabf4d8e 1046
1047 //Signal integral - first approx
1048 Double_t sgnInt;
1049 sgnInt = totInt-bkgInt;
9ca8c21c 1050 //cout<<"------TotInt = "<<totInt<<"\tsgnInt = "<<sgnInt<<endl;
6321ee46 1051 if (sgnInt <= 0){
1052 cout<<"Setting sgnInt = - sgnInt"<<endl;
9ca8c21c 1053 sgnInt=(-1)*sgnInt;
6321ee46 1054 }
24e73105 1055 /*Fit All Mass distribution with exponential + gaussian (+gaussian braodened) */
1056 TF1 *funcmass = new TF1(massname.Data(),this,&AliHFMassFitter::FitFunction4MassDistr,fminMass,fmaxMass,fNFinalPars,"AliHFMassFitter","FitFunction4MassDistr");
56cbeefb 1057 cout<<"Function name = "<<funcmass->GetName()<<endl<<endl;
fabf4d8e 1058 funcmass->SetLineColor(4); //blue
1059
1060 //Set parameters
1061 cout<<"\nTOTAL FIT"<<endl;
1062
24e73105 1063 if(fNFinalPars==5){
fabf4d8e 1064 funcmass->SetParNames("TotInt","Slope","SgnInt","Mean","Sigma");
1065 funcmass->SetParameters(totInt,slope1,sgnInt,fMass,fSigmaSgn);
3c0e7d59 1066
56cbeefb 1067 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
24e73105 1068 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
a12d80b8 1069 if(fFixPar[0]){
a12d80b8 1070 funcmass->FixParameter(0,totInt);
1071 }
1072 if(fFixPar[1]){
a12d80b8 1073 funcmass->FixParameter(1,slope1);
1074 }
1075 if(fFixPar[2]){
a12d80b8 1076 funcmass->FixParameter(2,sgnInt);
1077 }
1078 if(fFixPar[3]){
a12d80b8 1079 funcmass->FixParameter(3,fMass);
1080 }
1081 if(fFixPar[4]){
a12d80b8 1082 funcmass->FixParameter(4,fSigmaSgn);
1083 }
fabf4d8e 1084 }
24e73105 1085 if (fNFinalPars==6){
fabf4d8e 1086 funcmass->SetParNames("TotInt","Coef1","Coef2","SgnInt","Mean","Sigma");
1087 funcmass->SetParameters(totInt,slope1,conc1,sgnInt,fMass,fSigmaSgn);
3c0e7d59 1088
6321ee46 1089 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
24e73105 1090 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
3c0e7d59 1091 if(fFixPar[0])funcmass->FixParameter(0,totInt);
1092 if(fFixPar[1])funcmass->FixParameter(1,slope1);
1093 if(fFixPar[2])funcmass->FixParameter(2,conc1);
1094 if(fFixPar[3])funcmass->FixParameter(3,sgnInt);
1095 if(fFixPar[4])funcmass->FixParameter(4,fMass);
1096 if(fFixPar[5])funcmass->FixParameter(5,fSigmaSgn);
1097 //
1098 //funcmass->FixParameter(2,sgnInt);
fabf4d8e 1099 }
24e73105 1100 if(fNFinalPars==4){
fabf4d8e 1101 funcmass->SetParNames("Const","SgnInt","Mean","Sigma");
56cbeefb 1102 if(ftypeOfFit4Sgn == 1) funcmass->SetParameters(0.,0.5*totInt,fMass,fSigmaSgn);
1103 else funcmass->SetParameters(0.,totInt,fMass,fSigmaSgn);
3c0e7d59 1104 if(fFixPar[0]) funcmass->FixParameter(0,0.);
9ca8c21c 1105 if(fFixPar[1])funcmass->FixParameter(1,sgnInt);
1106 if(fFixPar[2])funcmass->FixParameter(2,fMass);
1107 if(fFixPar[3])funcmass->FixParameter(3,fSigmaSgn);
1108 //cout<<"Parameters set to: "<<0.5*totInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
24e73105 1109 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
fabf4d8e 1110
1111 }
24e73105 1112
6321ee46 1113 Int_t status;
1114
1115 status = fhistoInvMass->Fit(massname.Data(),"R,L,E,+,0");
1116 if (status != 0){
1117 cout<<"Minuit returned "<<status<<endl;
1118 return kFALSE;
1119 }
1120
fabf4d8e 1121 cout<<"fit done"<<endl;
0566386c 1122 //reset value of fMass and fSigmaSgn to those found from fit
24e73105 1123 fMass=funcmass->GetParameter(fNFinalPars-2);
1124 fSigmaSgn=funcmass->GetParameter(fNFinalPars-1);
fabf4d8e 1125
24e73105 1126 for(Int_t i=0;i<fNFinalPars;i++){
fabf4d8e 1127 fFitPars[i+2*bkgPar-3]=funcmass->GetParameter(i);
24e73105 1128 fFitPars[fNFinalPars+4*bkgPar-6+i]= funcmass->GetParError(i);
1129 //cout<<i+2*bkgPar-3<<"\t"<<funcmass->GetParameter(i)<<"\t\t"<<fNFinalPars+4*bkgPar-6+i<<"\t"<<funcmass->GetParError(i)<<endl;
fabf4d8e 1130 }
1131 /*
1132 //check: cout parameters
24e73105 1133 for(Int_t i=0;i<2*(fNFinalPars+2*bkgPar-3);i++){
fabf4d8e 1134 cout<<i<<"\t"<<fFitPars[i]<<endl;
1135 }
1136 */
74179930 1137
24e73105 1138 if(funcmass->GetParameter(fNFinalPars-1) <0 || funcmass->GetParameter(fNFinalPars-2) <0 || funcmass->GetParameter(fNFinalPars-3) <0 ) {
a60f573d 1139 cout<<"IntS or mean or sigma negative. You may tray to SetInitialGaussianSigma(..) and SetInitialGaussianMean(..)"<<endl;
b7d4bc49 1140 return kFALSE;
1141 }
0566386c 1142
56cbeefb 1143 //increase counter of number of fits done
1144 fcounter++;
1145
ad73ca8f 1146 //contour plots
1147 if(draw){
1148
24e73105 1149 for (Int_t kpar=1; kpar<fNFinalPars;kpar++){
ad73ca8f 1150
24e73105 1151 for(Int_t jpar=kpar+1;jpar<fNFinalPars;jpar++){
ad73ca8f 1152 cout<<"Par "<<kpar<<" and "<<jpar<<endl;
1153
1154 // produce 2 contours per couple of parameters
1155 TGraph* cont[2] = {0x0, 0x0};
1156 const Double_t errDef[2] = {1., 4.};
1157 for (Int_t i=0; i<2; i++) {
1158 gMinuit->SetErrorDef(errDef[i]);
1159 cont[i] = (TGraph*)gMinuit->Contour(80,kpar,jpar);
6321ee46 1160 cout<<"Minuit Status = "<<gMinuit->GetStatus()<<endl;
ad73ca8f 1161 }
1162
1163 if(!cont[0] || !cont[1]){
1164 cout<<"Skipping par "<<kpar<<" vs par "<<jpar<<endl;
1165 continue;
1166 }
1167
1168 // set graph titles and add them to the list
1169 TString title = "Contour plot";
1170 TString titleX = funcmass->GetParName(kpar);
1171 TString titleY = funcmass->GetParName(jpar);
1172 for (Int_t i=0; i<2; i++) {
1173 cont[i]->SetName( Form("cperr%d_%d%d", i, kpar, jpar) );
1174 cont[i]->SetTitle(title);
1175 cont[i]->GetXaxis()->SetTitle(titleX);
1176 cont[i]->GetYaxis()->SetTitle(titleY);
1177 cont[i]->GetYaxis()->SetLabelSize(0.033);
1178 cont[i]->GetYaxis()->SetTitleSize(0.033);
1179 cont[i]->GetYaxis()->SetTitleOffset(1.67);
1180
1181 fContourGraph->Add(cont[i]);
1182 }
1183
1184 // plot them
1185 TString cvname = Form("c%d%d", kpar, jpar);
1186 TCanvas *c4=new TCanvas(cvname,cvname,600,600);
1187 c4->cd();
1188 cont[1]->SetFillColor(38);
1189 cont[1]->Draw("alf");
1190 cont[0]->SetFillColor(9);
1191 cont[0]->Draw("lf");
1192
1193 }
1194
1195 }
1196
1197 }
1198
59c56ce7 1199 if (ftypeOfFit4Sgn == 1) {
a60f573d 1200 delete funcbkg1;
a60f573d 1201 }
59c56ce7 1202 delete funcbkg;
1203 delete funcmass;
1204
16856d6e 1205 AddFunctionsToHisto();
a60f573d 1206 if (draw) DrawFit();
16856d6e 1207
1208
34c79b83 1209 return kTRUE;
1210}
5a8a84f8 1211
1212//______________________________________________________________________________
1213
1214Bool_t AliHFMassFitter::RefitWithBkgOnly(Bool_t draw){
1215
1216 //perform a fit with background function only. Can be useful to try when fit fails to understand if it is because there's no signal
1217 //If you want to change the backgroud function or range use SetType or SetRangeFit before
1218
1219 TString bkgname="funcbkgonly";
1220 fSideBands = kFALSE;
1221
1222 TF1* funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1223
1224 funcbkg->SetLineColor(kBlue+3); //dark blue
1225
1226 Double_t integral=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fmaxMass),"width");
1227
1228 switch (ftypeOfFit4Bkg) {
1229 case 0: //gaus+expo
1230 funcbkg->SetParNames("BkgInt","Slope");
1231 funcbkg->SetParameters(integral,-2.);
1232 break;
1233 case 1:
1234 funcbkg->SetParNames("BkgInt","Slope");
1235 funcbkg->SetParameters(integral,-100.);
1236 break;
1237 case 2:
1238 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1239 funcbkg->SetParameters(integral,-10.,5);
1240 break;
1241 case 3:
1242 cout<<"Warning! This choice does not have a lot of sense..."<<endl;
1243 if(ftypeOfFit4Sgn==0){
1244 funcbkg->SetParNames("Const");
1245 funcbkg->SetParameter(0,0.);
1246 funcbkg->FixParameter(0,0.);
1247 }
1248 break;
1249 default:
1250 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
1251 return kFALSE;
1252 break;
1253 }
1254
1255
1256 Int_t status=fhistoInvMass->Fit(bkgname.Data(),"R,L,E,+,0");
1257 if (status != 0){
1258 cout<<"Minuit returned "<<status<<endl;
1259 return kFALSE;
1260 }
1261 AddFunctionsToHisto();
1262
1263 if(draw) DrawFit();
1264
1265 return kTRUE;
1266
1267}
34c79b83 1268//_________________________________________________________________________
1269Double_t AliHFMassFitter::GetChiSquare() const{
1270 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
9b9b53da 1271 if(!funcmass) {
1272 cout<<"funcmass not found"<<endl;
1273 return -1;
1274 }
34c79b83 1275 return funcmass->GetChisquare();
fabf4d8e 1276}
56cbeefb 1277
b7d4bc49 1278//_________________________________________________________________________
1279Double_t AliHFMassFitter::GetReducedChiSquare() const{
1280 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
5a8a84f8 1281 if(!funcmass) {
1282 cout<<"funcmass not found"<<endl;
1283 return -1;
1284 }
b7d4bc49 1285 return funcmass->GetChisquare()/funcmass->GetNDF();
1286}
1287
56cbeefb 1288//*********output
1289
fabf4d8e 1290//_________________________________________________________________________
2f328d65 1291void AliHFMassFitter::GetFitPars(Float_t *vector) const {
fabf4d8e 1292 // Return fit parameters
a12d80b8 1293
2f328d65 1294 for(Int_t i=0;i<fParsSize;i++){
1295 vector[i]=fFitPars[i];
fabf4d8e 1296 }
1297}
fabf4d8e 1298
fabf4d8e 1299
6321ee46 1300//_________________________________________________________________________
dc262918 1301void AliHFMassFitter::IntS(Float_t *valuewitherror) const {
1302
1303 //gives the integral of signal obtained from fit parameters
dc222f77 1304 if(!valuewitherror) {
1305 printf("AliHFMassFitter::IntS: got a null pointer\n");
1306 return;
1307 }
dc262918 1308
6321ee46 1309 Int_t index=fParsSize/2 - 3;
1310 valuewitherror[0]=fFitPars[index];
1311 index=fParsSize - 3;
1312 valuewitherror[1]=fFitPars[index];
dc222f77 1313}
6321ee46 1314
1315
16856d6e 1316//_________________________________________________________________________
1317void AliHFMassFitter::AddFunctionsToHisto(){
fabf4d8e 1318
dc262918 1319 //Add the background function in the complete range to the list of functions attached to the histogram
1320
9ca8c21c 1321 //cout<<"AddFunctionsToHisto called"<<endl;
56cbeefb 1322 TString bkgname = "funcbkg";
16856d6e 1323
5a8a84f8 1324 Bool_t done1=kFALSE,done2=kFALSE;
1325
16856d6e 1326 TString bkgnamesave=bkgname;
1327 TString testname=bkgname;
1328 testname += "FullRange";
1329 TF1 *testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1330 if(testfunc){
5a8a84f8 1331 done1=kTRUE;
1332 testfunc=0x0;
1333 }
1334 testname="funcbkgonly";
1335 testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1336 if(testfunc){
1337 done2=kTRUE;
1338 testfunc=0x0;
1339 }
1340
1341 if(done1 && done2){
16856d6e 1342 cout<<"AddFunctionsToHisto already used: exiting...."<<endl;
1343 return;
1344 }
1345
1346 TList *hlist=fhistoInvMass->GetListOfFunctions();
34c79b83 1347 hlist->ls();
16856d6e 1348
5a8a84f8 1349 if(!done2){
1350 TF1 *bonly=(TF1*)hlist->FindObject(testname.Data());
1351 if(!bonly){
1352 cout<<testname.Data()<<" not found looking for complete fit"<<endl;
1353 }else{
1354 bonly->SetLineColor(kBlue+3);
1355 hlist->Add((TF1*)bonly->Clone());
59c56ce7 1356 delete bonly;
5a8a84f8 1357 }
a60f573d 1358
16856d6e 1359 }
1360
5a8a84f8 1361 if(!done1){
1362 TF1 *b=(TF1*)hlist->FindObject(bkgname.Data());
1363 if(!b){
1364 cout<<bkgname<<" not found, cannot produce "<<bkgname<<"FullRange and "<<bkgname<<"Recalc"<<endl;
1365 return;
1366 }
16856d6e 1367
5a8a84f8 1368 bkgname += "FullRange";
9ca8c21c 1369 TF1 *bfullrange=new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
5a8a84f8 1370 //cout<<bfullrange->GetName()<<endl;
9ca8c21c 1371 for(Int_t i=0;i<fNFinalPars-3;i++){
5a8a84f8 1372 bfullrange->SetParName(i,b->GetParName(i));
1373 bfullrange->SetParameter(i,b->GetParameter(i));
1374 bfullrange->SetParError(i,b->GetParError(i));
1375 }
1376 bfullrange->SetLineStyle(4);
1377 bfullrange->SetLineColor(14);
16856d6e 1378
5a8a84f8 1379 bkgnamesave += "Recalc";
16856d6e 1380
9ca8c21c 1381 TF1 *blastpar=new TF1(bkgnamesave.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
16856d6e 1382
5a8a84f8 1383 TF1 *mass=fhistoInvMass->GetFunction("funcmass");
16856d6e 1384
5a8a84f8 1385 if (!mass){
1386 cout<<"funcmass doesn't exist "<<endl;
1387 return;
1388 }
16856d6e 1389
24e73105 1390 //intBkg=intTot-intS
551bdaf1 1391 blastpar->SetParameter(0,mass->GetParameter(0)-mass->GetParameter(fNFinalPars-3));
1392 blastpar->SetParError(0,mass->GetParError(fNFinalPars-3));
9ca8c21c 1393 if (fNFinalPars>=5) {
5a8a84f8 1394 blastpar->SetParameter(1,mass->GetParameter(1));
1395 blastpar->SetParError(1,mass->GetParError(1));
1396 }
9ca8c21c 1397 if (fNFinalPars==6) {
5a8a84f8 1398 blastpar->SetParameter(2,mass->GetParameter(2));
1399 blastpar->SetParError(2,mass->GetParError(2));
1400 }
1401
1402 blastpar->SetLineStyle(1);
1403 blastpar->SetLineColor(2);
1404
1405 hlist->Add((TF1*)bfullrange->Clone());
1406 hlist->Add((TF1*)blastpar->Clone());
1407 hlist->ls();
34c79b83 1408
59c56ce7 1409 delete bfullrange;
1410 delete blastpar;
1411
a60f573d 1412 }
5a8a84f8 1413
1414
16856d6e 1415}
1416
1417//_________________________________________________________________________
1418
1419TH1F* AliHFMassFitter::GetHistoClone() const{
1420
1421 TH1F* hout=(TH1F*)fhistoInvMass->Clone(fhistoInvMass->GetName());
1422 return hout;
1423}
1424//_________________________________________________________________________
1425
dc262918 1426void AliHFMassFitter::WriteHisto(TString path) const {
1427
1428 //Write the histogram in the default file HFMassFitterOutput.root
1429
16856d6e 1430 if (fcounter == 0) {
1431 cout<<"Use MassFitter method before WriteHisto"<<endl;
1432 return;
1433 }
1434 TH1F* hget=(TH1F*)fhistoInvMass->Clone();
1435
56cbeefb 1436 path += "HFMassFitterOutput.root";
1437 TFile *output;
34c79b83 1438
56cbeefb 1439 if (fcounter == 1) output = new TFile(path.Data(),"recreate");
1440 else output = new TFile(path.Data(),"update");
1441 output->cd();
1442 hget->Write();
ad73ca8f 1443 fContourGraph->Write();
a12d80b8 1444
1445
56cbeefb 1446 output->Close();
fabf4d8e 1447
56cbeefb 1448 cout<<fcounter<<" "<<hget->GetName()<<" written in "<<path<<endl;
fabf4d8e 1449
59c56ce7 1450 delete output;
1451
fabf4d8e 1452}
1453
1454//_________________________________________________________________________
1455
56cbeefb 1456void AliHFMassFitter::WriteNtuple(TString path) const{
a60f573d 1457 //TNtuple* nget=(TNtuple*)fntuParam->Clone();
56cbeefb 1458 path += "HFMassFitterOutput.root";
1459 TFile *output = new TFile(path.Data(),"update");
1460 output->cd();
a60f573d 1461 fntuParam->Write();
1462 //nget->Write();
56cbeefb 1463 output->Close();
a60f573d 1464 //cout<<nget->GetName()<<" written in "<<path<<endl;
1465 cout<<fntuParam->GetName()<<" written in "<<path<<endl;
1466 /*
1467 if(nget) {
1468 //delete nget;
1469 nget=NULL;
1470 }
1471 */
59c56ce7 1472
1473 delete output;
a60f573d 1474}
1475
1476//_________________________________________________________________________
d22f0682 1477void AliHFMassFitter::WriteCanvas(TString userIDstring,TString path,Double_t nsigma,Int_t writeFitInfo,Bool_t draw) const{
1478
1479 //write the canvas in a root file
1480
1481 gStyle->SetOptStat(0);
1482 gStyle->SetCanvasColor(0);
1483 gStyle->SetFrameFillColor(0);
1484
1485 TString type="";
a60f573d 1486
d22f0682 1487 switch (ftypeOfFit4Bkg){
1488 case 0:
1489 type="Exp"; //3+2
1490 break;
1491 case 1:
1492 type="Lin"; //3+2
1493 break;
1494 case 2:
1495 type="Pl2"; //3+3
1496 break;
1497 case 3:
1498 type="noB"; //3+1
1499 break;
1500 }
1501
1502 TString filename=Form("%sMassFit.root",type.Data());
1503 filename.Prepend(userIDstring);
1504 path.Append(filename);
1505
1506 TFile* outputcv=new TFile(path.Data(),"update");
1507
1508 TCanvas* c=(TCanvas*)GetPad(nsigma,writeFitInfo);
1509 c->SetName(Form("%s%s%s",c->GetName(),userIDstring.Data(),type.Data()));
1510 if(draw)c->DrawClone();
1511 outputcv->cd();
1512 c->Write();
1513 outputcv->Close();
1514}
1515
1516//_________________________________________________________________________
1517
1518TVirtualPad* AliHFMassFitter::GetPad(Double_t nsigma,Int_t writeFitInfo)const{
a12d80b8 1519 //return a TVirtualPad with the fitted histograms and info
dc262918 1520
a60f573d 1521 TString cvtitle="fit of ";
1522 cvtitle+=fhistoInvMass->GetName();
1523 TString cvname="c";
1524 cvname+=fcounter;
1525
d22f0682 1526 TCanvas *c=new TCanvas(cvname,cvtitle);
1527 PlotFit(c->cd(),nsigma,writeFitInfo);
a12d80b8 1528 return c->cd();
1529}
1530//_________________________________________________________________________
1531
d22f0682 1532void AliHFMassFitter::PlotFit(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo)const{
1533 //plot histogram, fit functions and write parameters according to verbosity level (0,1,>1)
a12d80b8 1534 gStyle->SetOptStat(0);
1535 gStyle->SetCanvasColor(0);
1536 gStyle->SetFrameFillColor(0);
d22f0682 1537
a12d80b8 1538 cout<<"nsigma = "<<nsigma<<endl;
d22f0682 1539 cout<<"Verbosity = "<<writeFitInfo<<endl;
a12d80b8 1540
3c0e7d59 1541 TH1F* hdraw=GetHistoClone();
5a8a84f8 1542
1543 if(!hdraw->GetFunction("funcmass") && !hdraw->GetFunction("funcbkgFullRange") && !hdraw->GetFunction("funcbkgRecalc")&& !hdraw->GetFunction("funcbkgonly")){
1544 cout<<"Probably fit failed and you didn't try to refit with background only, there's no function to be drawn"<<endl;
1545 return;
1546 }
1547
1548 if(hdraw->GetFunction("funcbkgonly")){ //Warning! if this function is present, no chance to draw the other!
1549 cout<<"Drawing background fit only"<<endl;
1550 hdraw->SetMinimum(0);
1551 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1552 pd->cd();
1553 hdraw->SetMarkerStyle(20);
1554 hdraw->DrawClone("PE");
1555 hdraw->GetFunction("funcbkgonly")->DrawClone("sames");
1556
1557 if(writeFitInfo > 0){
1558 TPaveText *pinfo=new TPaveText(0.6,0.86,1.,1.,"NDC");
1559 pinfo->SetBorderSize(0);
1560 pinfo->SetFillStyle(0);
1561 TF1* f=hdraw->GetFunction("funcbkgonly");
1562 for (Int_t i=0;i<fNFinalPars-3;i++){
1563 pinfo->SetTextColor(kBlue+3);
1564 TString str=Form("%s = %f #pm %f",f->GetParName(i),f->GetParameter(i),f->GetParError(i));
1565 pinfo->AddText(str);
1566 }
1567
1568 pinfo->AddText(Form("Reduced #chi^{2} = %.3f",f->GetChisquare()/f->GetNDF()));
1569 pd->cd();
1570 pinfo->DrawClone();
1571
1572
1573 }
1574
1575 return;
1576 }
1577
a12d80b8 1578 hdraw->SetMinimum(0);
d22f0682 1579 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
a12d80b8 1580 pd->cd();
3c0e7d59 1581 hdraw->SetMarkerStyle(20);
a12d80b8 1582 hdraw->DrawClone("PE");
93849470 1583// if(hdraw->GetFunction("funcbkgFullRange")) hdraw->GetFunction("funcbkgFullRange")->DrawClone("same");
1584// if(hdraw->GetFunction("funcbkgRecalc")) hdraw->GetFunction("funcbkgRecalc")->DrawClone("same");
ef6f2bce 1585 if(hdraw->GetFunction("funcmass")) hdraw->GetFunction("funcmass")->DrawClone("same");
a12d80b8 1586
d22f0682 1587 if(writeFitInfo > 0){
1588 TPaveText *pinfob=new TPaveText(0.6,0.86,1.,1.,"NDC");
1589 TPaveText *pinfom=new TPaveText(0.6,0.7,1.,.87,"NDC");
1590 pinfob->SetBorderSize(0);
1591 pinfob->SetFillStyle(0);
1592 pinfom->SetBorderSize(0);
1593 pinfom->SetFillStyle(0);
a12d80b8 1594 TF1* ff=fhistoInvMass->GetFunction("funcmass");
d22f0682 1595
1596 for (Int_t i=fNFinalPars-3;i<fNFinalPars;i++){
1597 pinfom->SetTextColor(kBlue);
a12d80b8 1598 TString str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
d22f0682 1599 if(!(writeFitInfo==1 && i==fNFinalPars-3)) pinfom->AddText(str);
a12d80b8 1600 }
d22f0682 1601 pd->cd();
1602 pinfom->DrawClone();
a60f573d 1603
a12d80b8 1604 TPaveText *pinfo2=new TPaveText(0.1,0.1,0.6,0.4,"NDC");
1605 pinfo2->SetBorderSize(0);
1606 pinfo2->SetFillStyle(0);
1607
1608 Double_t signif, signal, bkg, errsignif, errsignal, errbkg;
1609
1610 Significance(nsigma,signif,errsignif);
1611 Signal(nsigma,signal,errsignal);
1612 Background(nsigma,bkg, errbkg);
1613 /*
1614 Significance(1.828,1.892,signif,errsignif);
1615 Signal(1.828,1.892,signal,errsignal);
1616 Background(1.828,1.892,bkg, errbkg);
1617 */
d22f0682 1618 TString str=Form("Significance (%.0f#sigma) %.1f #pm %.1f ",nsigma,signif,errsignif);
a12d80b8 1619 pinfo2->AddText(str);
d22f0682 1620 str=Form("S (%.0f#sigma) %.0f #pm %.0f ",nsigma,signal,errsignal);
a12d80b8 1621 pinfo2->AddText(str);
d22f0682 1622 str=Form("B (%.0f#sigma) %.0f #pm %.0f",nsigma,bkg,errbkg);
a12d80b8 1623 pinfo2->AddText(str);
1624
1625 pd->cd();
a12d80b8 1626 pinfo2->Draw();
a60f573d 1627
d22f0682 1628 if(writeFitInfo > 1){
1629 for (Int_t i=0;i<fNFinalPars-3;i++){
1630 pinfob->SetTextColor(kRed);
9ee5e5c3 1631 str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
d22f0682 1632 pinfob->AddText(str);
1633 }
1634 pd->cd();
1635 pinfob->DrawClone();
1636 }
1637
1638
3c0e7d59 1639 }
a12d80b8 1640 return;
1641}
1642
1643//_________________________________________________________________________
1644
d22f0682 1645void AliHFMassFitter::DrawHere(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo) const {
a12d80b8 1646 //draws histogram together with fit functions with default nice colors in user canvas
d22f0682 1647 PlotFit(pd,nsigma,writeFitInfo);
a12d80b8 1648
1649 pd->Draw();
1650
1651}
1652//_________________________________________________________________________
1653void AliHFMassFitter::DrawFit(Double_t nsigma) const{
1654
1655 //draws histogram together with fit functions with default nice colors
1656 gStyle->SetOptStat(0);
1657 gStyle->SetCanvasColor(0);
1658 gStyle->SetFrameFillColor(0);
1659
1660
d22f0682 1661 TCanvas* c=(TCanvas*)GetPad(nsigma,1);
a12d80b8 1662 c->Draw();
1663
fabf4d8e 1664}
fabf4d8e 1665
fabf4d8e 1666
ad73ca8f 1667//_________________________________________________________________________
1668
1669void AliHFMassFitter::PrintParTitles() const{
dc262918 1670
1671 //prints to screen the parameters names
1672
ad73ca8f 1673 TF1 *f=fhistoInvMass->GetFunction("funcmass");
1674 if(!f) {
1675 cout<<"Fit function not found"<<endl;
1676 return;
1677 }
1678
ad73ca8f 1679 cout<<"Parameter Titles \n";
24e73105 1680 for(Int_t i=0;i<fNFinalPars;i++){
ad73ca8f 1681 cout<<"Par "<<i<<": "<<f->GetParName(i)<<endl;
1682 }
1683 cout<<endl;
1684
1685}
1686
56cbeefb 1687//************ significance
fabf4d8e 1688
1689//_________________________________________________________________________
1690
1691void AliHFMassFitter::Signal(Double_t nOfSigma,Double_t &signal,Double_t &errsignal) const {
1692 // Return signal integral in mean+- n sigma
1693
16856d6e 1694 if(fcounter==0) {
1695 cout<<"Use MassFitter method before Signal"<<endl;
1696 return;
1697 }
56cbeefb 1698
a12d80b8 1699 Double_t min=fMass-nOfSigma*fSigmaSgn;
1700 Double_t max=fMass+nOfSigma*fSigmaSgn;
56cbeefb 1701
a12d80b8 1702 Signal(min,max,signal,errsignal);
b7d4bc49 1703
a12d80b8 1704
fabf4d8e 1705 return;
a12d80b8 1706
fabf4d8e 1707}
16856d6e 1708
fabf4d8e 1709//_________________________________________________________________________
1710
16856d6e 1711void AliHFMassFitter::Signal(Double_t min, Double_t max, Double_t &signal,Double_t &errsignal) const {
1712
1713 // Return signal integral in a range
1714
1715 if(fcounter==0) {
1716 cout<<"Use MassFitter method before Signal"<<endl;
1717 return;
1718 }
1719
56cbeefb 1720 //functions names
16856d6e 1721 TString bkgname="funcbkgRecalc";
1722 TString bkg1name="funcbkg1Recalc";
56cbeefb 1723 TString massname="funcmass";
fabf4d8e 1724
b7d4bc49 1725
1726 TF1 *funcbkg=0;
56cbeefb 1727 TF1 *funcmass=fhistoInvMass->GetFunction(massname.Data());
16856d6e 1728 if(!funcmass){
1729 cout<<"AliHFMassFitter::Signal() ERROR -> Mass distr function not found!"<<endl;
1730 return;
1731 }
1732
b7d4bc49 1733 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1734 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1735
16856d6e 1736 if(!funcbkg){
1737 cout<<"AliHFMassFitter::Signal() ERROR -> Bkg function not found!"<<endl;
1738 return;
1739 }
1740
24e73105 1741 Int_t np=fNFinalPars-3;
b7d4bc49 1742
16856d6e 1743 Double_t intS,intSerr;
b7d4bc49 1744
16856d6e 1745 //relative error evaluation
1746 intS=funcmass->GetParameter(np);
1747 intSerr=funcmass->GetParError(np);
fabf4d8e 1748
16856d6e 1749 cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1750 Double_t background,errbackground;
1751 Background(min,max,background,errbackground);
b7d4bc49 1752
16856d6e 1753 //signal +/- error in the range
1754
1755 Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1756 signal=mass - background;
a60f573d 1757 errsignal=(intSerr/intS)*signal;/*assume relative error is the same as for total integral*/
16856d6e 1758
1759}
1760
1761//_________________________________________________________________________
1762
1763void AliHFMassFitter::Background(Double_t nOfSigma,Double_t &background,Double_t &errbackground) const {
1764 // Return background integral in mean+- n sigma
1765
1766 if(fcounter==0) {
1767 cout<<"Use MassFitter method before Background"<<endl;
1768 return;
b7d4bc49 1769 }
a12d80b8 1770 Double_t min=fMass-nOfSigma*fSigmaSgn;
1771 Double_t max=fMass+nOfSigma*fSigmaSgn;
b7d4bc49 1772
a12d80b8 1773 Background(min,max,background,errbackground);
16856d6e 1774
16856d6e 1775 return;
24e73105 1776
16856d6e 1777}
1778//___________________________________________________________________________
1779
1780void AliHFMassFitter::Background(Double_t min, Double_t max, Double_t &background,Double_t &errbackground) const {
1781 // Return background integral in a range
1782
1783 if(fcounter==0) {
1784 cout<<"Use MassFitter method before Background"<<endl;
1785 return;
1786 }
1787
1788 //functions names
1789 TString bkgname="funcbkgRecalc";
1790 TString bkg1name="funcbkg1Recalc";
1791
1792 TF1 *funcbkg=0;
1793 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1794 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1795 if(!funcbkg){
1796 cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1797 return;
1798 }
1799
1800
1801 Double_t intB,intBerr;
1802
1803 //relative error evaluation: from final parameters of the fit
1804 if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1805 else{
1806 intB=funcbkg->GetParameter(0);
1807 intBerr=funcbkg->GetParError(0);
1808 cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1809 }
1810
1811 //relative error evaluation: from histo
1812
1813 intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1814 Double_t sum2=0;
1815 for(Int_t i=1;i<=fSideBandl;i++){
1816 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1817 }
1818 for(Int_t i=fSideBandr;i<=fNbin;i++){
1819 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1820 }
1821
1822 intBerr=TMath::Sqrt(sum2);
1823 cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
1824
1825 cout<<"Last estimation of bkg error is used"<<endl;
1826
1827 //backround +/- error in the range
1828 if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
1829 background = 0;
1830 errbackground = 0;
1831 }
1832 else{
1833 background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
1834 errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
1835 //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
34c79b83 1836 }
fabf4d8e 1837 return;
1838
1839}
1840
16856d6e 1841
fabf4d8e 1842//__________________________________________________________________________
1843
b7d4bc49 1844void AliHFMassFitter::Significance(Double_t nOfSigma,Double_t &significance,Double_t &errsignificance) const {
fabf4d8e 1845 // Return significance in mean+- n sigma
5a8a84f8 1846
1847 Double_t min=fMass-nOfSigma*fSigmaSgn;
1848 Double_t max=fMass+nOfSigma*fSigmaSgn;
1849 Significance(min, max, significance, errsignificance);
fabf4d8e 1850
fabf4d8e 1851 return;
1852}
1853
1854//__________________________________________________________________________
74179930 1855
16856d6e 1856void AliHFMassFitter::Significance(Double_t min, Double_t max, Double_t &significance,Double_t &errsignificance) const {
1857 // Return significance integral in a range
1858
1859 Double_t signal,errsignal,background,errbackground;
1860 Signal(min, max,signal,errsignal);
1861 Background(min, max,background,errbackground);
1862
5a8a84f8 1863 if (signal+background <= 0.){
1864 cout<<"Cannot calculate significance because of div by 0!"<<endl;
1865 significance=-1;
1866 errsignificance=0;
6e429dc7 1867 return;
5a8a84f8 1868 }
1869
16856d6e 1870 significance = signal/TMath::Sqrt(signal+background);
a12d80b8 1871
16856d6e 1872 errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal);
1873
1874 return;
1875}
ad73ca8f 1876
1877