00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <iostream>
00011 #include <fstream>
00012
00013 #include <TCanvas.h>
00014 #include <THStack.h>
00015 #include <TH1D.h>
00016 #include <TH2D.h>
00017 #include <TAxis.h>
00018 #include <TF1.h>
00019 #include <TMath.h>
00020 #include <TGraphAsymmErrors.h>
00021
00022 #include "../../BAT/BCMath.h"
00023 #include "../../BAT/BCLog.h"
00024
00025 #include "BCMTFChannel.h"
00026 #include "BCMTFProcess.h"
00027 #include "BCMTFTemplate.h"
00028 #include "BCMTFSystematic.h"
00029 #include "BCMTFSystematicVariation.h"
00030
00031 #include "BCMTF.h"
00032
00033
00034 BCMTF::BCMTF()
00035 : BCModel("Multi-template Fitter")
00036 , fNChannels(0)
00037 , fNProcesses(0)
00038 , fNSystematics(0)
00039 , fFlagEfficiencyConstraint(false)
00040 {}
00041
00042
00043 BCMTF::BCMTF(const char * name)
00044 : BCModel(name)
00045 , fNChannels(0)
00046 , fNProcesses(0)
00047 , fNSystematics(0)
00048 , fFlagEfficiencyConstraint(false)
00049 {}
00050
00051
00052 BCMTF::~BCMTF()
00053
00054 {
00055 for (int i = 0; i < fNChannels; ++i)
00056 delete fChannelContainer.at(i);
00057 }
00058
00059
00060 int BCMTF::GetChannelIndex(const char * name)
00061 {
00062
00063 for (int i = 0; i < fNChannels; ++i) {
00064
00065 BCMTFChannel * channel = GetChannel(i);
00066
00067
00068 if (!channel->GetName().compare(name))
00069 return i;
00070 }
00071
00072
00073 return -1;
00074 }
00075
00076
00077 int BCMTF::GetProcessIndex(const char * name)
00078 {
00079
00080 for (int i = 0; i < fNProcesses; ++i) {
00081
00082 BCMTFProcess * process = GetProcess(i);
00083
00084
00085 if (!process->GetName().compare(name))
00086 return i;
00087 }
00088
00089
00090 return -1;
00091 }
00092
00093
00094 int BCMTF::GetSystematicIndex(const char * name)
00095 {
00096
00097 for (int i = 0; i < fNSystematics; ++i) {
00098
00099 BCMTFSystematic * systematic = GetSystematic(i);
00100
00101
00102 if (!systematic->GetName().compare(name))
00103 return i;
00104 }
00105
00106
00107 return -1;
00108 }
00109
00110
00111 int BCMTF::SetTemplate(const char * channelname, const char * processname, TH1D hist, double efficiency)
00112 {
00113
00114 int channelindex = GetChannelIndex(channelname);
00115
00116
00117 if (channelindex < 0) {
00118 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00119 return -1;
00120 }
00121
00122
00123 int processindex = GetProcessIndex(processname);
00124
00125
00126 if (processindex < 0) {
00127 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00128 return -1;
00129 }
00130
00131
00132 BCMTFChannel * channel = GetChannel(channelindex);
00133
00134
00135 BCMTFTemplate * bctemplate = channel->GetTemplate(processindex);
00136
00137
00138 if (hist.Integral())
00139 hist.Scale(1.0 / hist.Integral());
00140
00141
00142 hist.SetStats(kFALSE);
00143
00144
00145 hist.SetFillColor(2 + processindex);
00146 hist.SetFillStyle(1001);
00147
00148
00149 TH1D * temphist = new TH1D(hist);
00150
00151
00152 bctemplate->SetHistogram(temphist);
00153
00154
00155 bctemplate->SetEfficiency(efficiency);
00156
00157
00158 return 1;
00159 }
00160
00161
00162 int BCMTF::SetTemplate(const char * channelname, const char * processname, std::vector<TF1 *> * funccont, int nbins, double efficiency)
00163 {
00164
00165 int channelindex = GetChannelIndex(channelname);
00166
00167
00168 if (channelindex < 0) {
00169 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00170 return -1;
00171 }
00172
00173
00174 int processindex = GetProcessIndex(processname);
00175
00176
00177 if (processindex < 0) {
00178 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00179 return -1;
00180 }
00181
00182
00183 BCMTFChannel * channel = GetChannel(channelindex);
00184
00185
00186 BCMTFTemplate * bctemplate = channel->GetTemplate(processindex);
00187
00188
00189 bctemplate->SetFunctionContainer(funccont, nbins);
00190
00191
00192 bctemplate->SetEfficiency(efficiency);
00193
00194
00195 return 1;
00196 }
00197
00198
00199 int BCMTF::SetData(const char * channelname, TH1D hist, double minimum, double maximum)
00200 {
00201 int channelindex = GetChannelIndex(channelname);
00202
00203
00204 if (channelindex < 0) {
00205 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00206 return -1;
00207 }
00208
00209
00210 BCMTFChannel * channel = GetChannel(channelindex);
00211
00212
00213 BCMTFTemplate * data = channel->GetData();
00214
00215
00216 hist.SetStats(kFALSE);
00217
00218
00219 hist.SetMarkerStyle(20);
00220 hist.SetMarkerSize(1.1);
00221
00222
00223 hist.SetNdivisions(509);
00224
00225
00226 if (data->GetHistogram()) {
00227 delete data->GetHistogram();
00228 data->SetHistogram(0);
00229 }
00230
00231
00232 if (channel->GetHistUncertaintyBandExpectation()) {
00233 delete channel->GetHistUncertaintyBandExpectation();
00234 channel->SetHistUncertaintyBandExpectation(0);
00235 }
00236 if (channel->GetHistUncertaintyBandPoisson()) {
00237 delete channel->GetHistUncertaintyBandPoisson();
00238 channel->SetHistUncertaintyBandPoisson(0);
00239 }
00240
00241
00242
00243 if (minimum==-1)
00244 minimum = 0;
00245 if (maximum==-1)
00246 maximum = ceil(hist.GetMaximum() + 5.*sqrt(hist.GetMaximum()));
00247
00248 std::vector<double> a(hist.GetNbinsX()+1);
00249 for (int i = 0; i < hist.GetNbinsX()+1; ++i) {
00250 a[i] = hist.GetXaxis()->GetBinLowEdge(i+1);
00251 }
00252
00253 TH2D* hist_uncbandexp = new TH2D(TString::Format("UncertaintyBandExpectation_%i", BCLog::GetHIndex()), "",
00254 hist.GetNbinsX(), &a[0], 1000, minimum, maximum);
00255 hist_uncbandexp->SetStats(kFALSE);
00256
00257 TH2D* hist_uncbandpoisson = new TH2D(TString::Format("UncertaintyBandPoisson_%i", BCLog::GetHIndex()), "",
00258 hist.GetNbinsX(), &a[0], int(maximum-minimum), minimum, maximum);
00259 hist_uncbandpoisson->SetStats(kFALSE);
00260
00261
00262 data->SetHistogram(new TH1D(hist));
00263 channel->SetHistUncertaintyBandExpectation(hist_uncbandexp);
00264 channel->SetHistUncertaintyBandPoisson(hist_uncbandpoisson);
00265
00266
00267 channel->SetRangeY(minimum, maximum);
00268
00269
00270 return 1;
00271 }
00272
00273
00274 int BCMTF::AddChannel(const char * name)
00275 {
00276
00277 for (int i = 0; i < fNChannels; ++i) {
00278
00279 if (GetChannelIndex(name) >= 0) {
00280 BCLog::OutWarning("BCMultitemplateFitter::AddChannel() : Channel with this name exists already.");
00281 return -1;
00282 }
00283 }
00284
00285
00286 BCMTFChannel * channel = new BCMTFChannel(name);
00287
00288
00289 BCMTFTemplate * bctemplate = new BCMTFTemplate(channel->GetName().c_str(), "data");
00290
00291
00292 channel->SetData(bctemplate);
00293
00294
00295 for (int i = 0; i < fNProcesses; ++i) {
00296
00297 BCMTFProcess * process = GetProcess(i);
00298
00299
00300 BCMTFTemplate * bctemplate = new BCMTFTemplate(name, process->GetName().c_str());
00301
00302
00303 channel->AddTemplate(bctemplate);
00304 }
00305
00306
00307 for (int i = 0; i < fNSystematics; ++i) {
00308
00309 BCMTFSystematic * systematic = GetSystematic(i);
00310
00311
00312 BCMTFSystematicVariation * variation = new BCMTFSystematicVariation(name, systematic->GetName().c_str(), fNProcesses);
00313
00314
00315 channel->AddSystematicVariation(variation);
00316 }
00317
00318
00319 fChannelContainer.push_back(channel);
00320
00321
00322 fNChannels++;
00323
00324
00325 return 1;
00326 }
00327
00328
00329 int BCMTF::AddProcess(const char * name, double nmin, double nmax)
00330 {
00331
00332 for (int i = 0; i < fNProcesses; ++i) {
00333
00334 if (GetProcessIndex(name) >= 0) {
00335 BCLog::OutWarning("BCMultitemplateFitter::AddProcess() : Process with this name exists already.");
00336 return -1;
00337 }
00338 }
00339
00340
00341 BCMTFProcess * process = new BCMTFProcess(name);
00342
00343
00344 fProcessContainer.push_back(process);
00345
00346
00347 for (int i = 0; i < fNChannels; ++i) {
00348
00349 BCMTFChannel * channel = GetChannel(i);
00350
00351
00352 BCMTFTemplate * bctemplate = new BCMTFTemplate(channel->GetName().c_str(), name);
00353
00354
00355 channel->AddTemplate(bctemplate);
00356
00357
00358 for (int j = 0; j < fNSystematics; ++j) {
00359
00360 BCMTFSystematicVariation * variation = channel->GetSystematicVariation(j);
00361
00362
00363 variation->AddHistograms(0, 0);
00364 }
00365 }
00366
00367
00368 fNProcesses++;
00369
00370
00371 fProcessParIndexContainer.push_back(GetNParameters());
00372
00373
00374 AddParameter(name, nmin, nmax);
00375
00376
00377 fExpectationFunctionContainer.push_back(0);
00378
00379
00380 return 1;
00381 }
00382
00383
00384 int BCMTF::AddSystematic(const char * name, double min, double max)
00385 {
00386
00387 for (int i = 0; i < fNSystematics; ++i) {
00388
00389 if (GetSystematicIndex(name) >= 0) {
00390 BCLog::OutWarning("BCMultitemplateFitter::AddSystematic() : Systematic with this name exists already.");
00391 return -1;
00392 }
00393 }
00394
00395
00396 BCMTFSystematic * systematic = new BCMTFSystematic(name);
00397
00398
00399 fSystematicContainer.push_back(systematic);
00400
00401
00402 for (int i = 0; i < fNChannels; ++i) {
00403
00404 BCMTFChannel * channel = GetChannel(i);
00405
00406
00407 BCMTFSystematicVariation * variation = new BCMTFSystematicVariation(channel->GetName().c_str(), name, fNProcesses);
00408
00409
00410 channel->AddSystematicVariation(variation);
00411 }
00412
00413
00414
00415 fNSystematics++;
00416
00417
00418 fSystematicParIndexContainer.push_back(GetNParameters());
00419
00420
00421 AddParameter(name, min, max);
00422
00423
00424 fExpectationFunctionContainer.push_back(0);
00425
00426
00427 return 1;
00428 }
00429
00430
00431 int BCMTF::SetSystematicVariation(const char * channelname, const char * processname, const char * systematicname, double variation_up, double variation_down)
00432 {
00433
00434
00435 int channelindex = GetChannelIndex(channelname);
00436
00437
00438 if (channelindex < 0) {
00439 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00440 return -1;
00441 }
00442
00443
00444 int processindex = GetProcessIndex(processname);
00445
00446
00447 if (processindex < 0) {
00448 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00449 return -1;
00450 }
00451
00452
00453 int systematicindex = GetSystematicIndex(systematicname);
00454
00455
00456 if (systematicindex < 0) {
00457 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Systematic does not exist.");
00458 return -1;
00459 }
00460
00461
00462 BCMTFChannel * channel = GetChannel(channelindex);
00463
00464 BCMTFTemplate * bctemplate = channel->GetTemplate(processindex);
00465
00466 TH1D * hist_template = bctemplate->GetHistogram();
00467
00468 TH1D hist_up = TH1D(*hist_template);
00469 TH1D hist_down = TH1D(*hist_template);
00470
00471 int nbins = hist_up.GetNbinsX();
00472
00473
00474 for (int ibin = 1; ibin <= nbins; ++ibin) {
00475 hist_up.SetBinContent(ibin, variation_up);
00476 hist_down.SetBinContent(ibin, variation_down);
00477 }
00478
00479
00480 BCMTFSystematicVariation * variation = channel->GetSystematicVariation(systematicindex);
00481
00482
00483 variation->SetHistograms(processindex, new TH1D(hist_up), new TH1D(hist_down));
00484
00485
00486 return 1;
00487 }
00488
00489
00490 int BCMTF::SetSystematicVariation(const char * channelname, const char * processname, const char * systematicname, TH1D hist_up, TH1D hist_down)
00491 {
00492
00493 int channelindex = GetChannelIndex(channelname);
00494
00495
00496 if (channelindex < 0) {
00497 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00498 return -1;
00499 }
00500
00501
00502 int processindex = GetProcessIndex(processname);
00503
00504
00505 if (processindex < 0) {
00506 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00507 return -1;
00508 }
00509
00510
00511 int systematicindex = GetSystematicIndex(systematicname);
00512
00513
00514 if (systematicindex < 0) {
00515 BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Systematic does not exist.");
00516 return -1;
00517 }
00518
00519
00520 BCMTFChannel * channel = GetChannel(channelindex);
00521
00522
00523 BCMTFSystematicVariation * variation = channel->GetSystematicVariation(systematicindex);
00524
00525
00526 variation->SetHistograms(processindex, new TH1D(hist_up), new TH1D(hist_down));
00527
00528
00529 return 1;
00530 }
00531
00532
00533 int BCMTF::SetSystematicVariation(const char * channelname, const char * processname, const char * systematicname, TH1D hist, TH1D hist_up, TH1D hist_down)
00534 {
00535
00536 int nbins = hist.GetNbinsX();
00537
00538 TH1D * hist_up_rel = new TH1D(hist);
00539 TH1D * hist_down_rel = new TH1D(hist);
00540
00541
00542 for (int ibin = 1; ibin <= nbins; ++ibin) {
00543 hist_up_rel->SetBinContent(ibin, (hist_up.GetBinContent(ibin) - hist.GetBinContent(ibin)) / hist.GetBinContent(ibin));
00544 hist_down_rel->SetBinContent(ibin, (hist.GetBinContent(ibin) - hist_down.GetBinContent(ibin)) / hist.GetBinContent(ibin));
00545 }
00546
00547
00548 return SetSystematicVariation(channelname, processname, systematicname, *hist_up_rel, *hist_down_rel);
00549 }
00550
00551
00552 int BCMTF::PrintSummary(const char * filename)
00553 {
00554
00555 std::ofstream ofi(filename);
00556 ofi.precision(3);
00557
00558
00559 if(!ofi.is_open()) {
00560 BCLog::OutWarning(Form("BCMultitemplateFitter::PrintSummary() : Could not open file %s", filename));
00561 return 0;
00562 }
00563
00564 ofi
00565 << " Multi template fitter summary " << std::endl
00566 << " ----------------------------- " << std::endl
00567 << std::endl
00568 << " Number of channels : " << fNChannels << std::endl
00569 << " Number of processes : " << fNProcesses << std::endl
00570 << " Number of systematics : " << fNSystematics << std::endl
00571 << std::endl;
00572
00573 ofi
00574 << " Channels :" << std::endl;
00575 for (int i = 0; i < GetNChannels(); ++i) {
00576 ofi
00577 << " " << i
00578 << " : \"" << GetChannel(i)->GetName().c_str() << "\""
00579 << std::endl;
00580 }
00581 ofi
00582 << std::endl;
00583
00584 ofi
00585 << " Processes :" << std::endl;
00586 for (int i = 0; i < GetNProcesses(); ++i) {
00587 ofi
00588 << " " << i
00589 << " : \"" << GetProcess(i)->GetName().c_str() << "\""
00590 << " (par index " << GetParIndexProcess(i) << ")"
00591 << std::endl;
00592 }
00593 ofi
00594 << std::endl;
00595
00596 ofi
00597 << " Systematics :" << std::endl;
00598 for (int i = 0; i < GetNSystematics(); ++i) {
00599 ofi
00600 << " " << i
00601 << " : \"" << GetSystematic(i)->GetName().c_str() << "\""
00602 << " (par index " << GetParIndexSystematic(i) << ")"
00603 << std::endl;
00604 }
00605 ofi
00606 << std::endl;
00607 if (GetNSystematics() == 0)
00608 ofi
00609 << " - none - " << std::endl;
00610
00611 ofi
00612 << " Goodness-of-fit: " << std::endl;
00613 for (int i = 0; i < GetNChannels(); ++i) {
00614 ofi
00615 << " i : \"" << GetChannel(i)->GetName().c_str() << "\" : chi2 = "
00616 << CalculateChi2( i, GetBestFitParameters() )
00617 << std::endl;
00618 }
00619 ofi
00620 << std::endl;
00621
00622
00623
00624 ofi.close();
00625
00626
00627 return 1;
00628 }
00629
00630
00631 double BCMTF::Expectation(int channelindex, int binindex, const std::vector<double> & parameters)
00632 {
00633 double expectation = 0.;
00634
00635
00636 for (int i = 0; i < fNProcesses; ++i) {
00637
00638 double efficiency = Efficiency(channelindex, i, binindex, parameters);
00639
00640
00641 double probability = Probability(channelindex, i, binindex, parameters);
00642
00643
00644 int parindex = fProcessParIndexContainer[i];
00645
00646
00647 expectation += ExpectationFunction(parindex, channelindex, i, parameters)
00648 * efficiency
00649 * probability;
00650 }
00651
00652
00653 if (expectation < 0)
00654 expectation = 0.;
00655
00656 return expectation;
00657 }
00658
00659
00660 double BCMTF::ExpectationFunction(int parindex, int channelindex, int processindex, const std::vector<double> & parameters)
00661 {
00662
00663 std::vector<TF1 *> * funccont = fChannelContainer[channelindex]->GetTemplate(processindex)->GetFunctionContainer();
00664
00665 if (funccont->size()>0)
00666 return 1.;
00667
00668 else if (!fExpectationFunctionContainer[parindex])
00669 return parameters[parindex];
00670
00671 else {
00672 TF1 * func = fExpectationFunctionContainer[parindex];
00673 return func->Eval(parameters[parindex]);
00674 }
00675 }
00676
00677
00678 double BCMTF::Efficiency(int channelindex, int processindex, int binindex, const std::vector<double> & parameters)
00679 {
00680
00681 BCMTFChannel * channel = fChannelContainer[channelindex];
00682
00683 double efficiency = channel->GetTemplate(processindex)->GetEfficiency();
00684
00685 double defficiency = 1.;
00686
00687
00688 for (int i = 0; i < fNSystematics; ++i) {
00689 if (!(fSystematicContainer[i]->GetFlagSystematicActive()))
00690 continue;
00691
00692
00693 int parindex = fSystematicParIndexContainer[i];
00694
00695
00696 TH1D * hist = 0;
00697
00698 if (parameters[parindex] > 0)
00699 hist = channel->GetSystematicVariation(i)->GetHistogramUp(processindex);
00700 else
00701 hist = channel->GetSystematicVariation(i)->GetHistogramDown(processindex);
00702
00703
00704 if (!hist)
00705 continue;
00706
00707
00708 defficiency += parameters[parindex] * hist->GetBinContent(binindex);
00709 }
00710
00711
00712 efficiency *= defficiency;
00713
00714
00715 if (fFlagEfficiencyConstraint) {
00716 if (efficiency < 0.)
00717 efficiency = 0.;
00718 if (efficiency > 1.)
00719 efficiency = 1.;
00720 }
00721
00722 return efficiency;
00723 }
00724
00725
00726 double BCMTF::Probability(int channelindex, int processindex, int binindex, const std::vector<double> & parameters)
00727 {
00728
00729 TH1D * hist = fChannelContainer[channelindex]->GetTemplate(processindex)->GetHistogram();
00730
00731
00732 std::vector<TF1 *> * funccont = fChannelContainer[channelindex]->GetTemplate(processindex)->GetFunctionContainer();
00733
00734
00735 if (!hist && !(funccont->size()>0))
00736 return 0.;
00737
00738 if (hist)
00739 return hist->GetBinContent(binindex);
00740 else {
00741 int parindex = fProcessParIndexContainer[processindex];
00742 return funccont->at(binindex-1)->Eval(parameters[parindex]);
00743 }
00744 }
00745
00746
00747 int BCMTF::PrintStack(const char * channelname, const std::vector<double> & parameters, const char * filename, const char * options)
00748 {
00749 int index = GetChannelIndex(channelname);
00750
00751 return PrintStack(index, parameters, filename, options);
00752 }
00753
00754
00755 int BCMTF::PrintStack(int channelindex, const std::vector<double> & parameters, const char * filename, const char * options)
00756 {
00757
00758
00759
00760
00761
00762 if (!parameters.size())
00763 return -1;
00764
00765
00766 bool flag_logx = false;
00767 bool flag_logy = false;
00768 bool flag_bw = false;
00769
00770 bool flag_sum = false;
00771 bool flag_stack = false;
00772
00773 bool flag_e0 = false;
00774 bool flag_e1 = false;
00775
00776 bool flag_b0 = false;
00777 bool flag_b1 = false;
00778
00779 if (std::string(options).find("logx") < std::string(options).size())
00780 flag_logx = true;
00781
00782 if (std::string(options).find("logy") < std::string(options).size())
00783 flag_logy = true;
00784
00785 if (std::string(options).find("bw") < std::string(options).size())
00786 flag_bw = true;
00787
00788 if (std::string(options).find("sum") < std::string(options).size())
00789 flag_sum = true;
00790
00791 if (std::string(options).find("stack") < std::string(options).size())
00792 flag_stack = true;
00793
00794 if (std::string(options).find("e0") < std::string(options).size())
00795 flag_e0 = true;
00796
00797 if (std::string(options).find("e1") < std::string(options).size())
00798 flag_e1 = true;
00799
00800 if (std::string(options).find("b0") < std::string(options).size())
00801 flag_b0 = true;
00802
00803 if (std::string(options).find("b1") < std::string(options).size())
00804 flag_b1 = true;
00805
00806 if (!flag_e0)
00807 flag_e1=true;
00808
00809
00810 BCMTFChannel * channel = GetChannel(channelindex);
00811
00812
00813 TCanvas * c1 = new TCanvas();
00814 c1->cd();
00815
00816
00817 if (flag_logx)
00818 c1->SetLogx();
00819
00820 if (flag_logy)
00821 c1->SetLogy();
00822
00823
00824 TH1D* hist_data = channel->GetData()->GetHistogram();
00825
00826
00827 int nbins = hist_data->GetNbinsX();
00828
00829
00830 TH1D* hist_sum = new TH1D(*hist_data);
00831 hist_sum->SetLineColor(kBlack);
00832 for (int i = 1; i <= nbins; ++i)
00833 hist_sum->SetBinContent(i, 0);
00834
00835
00836 TH1D* hist_error_band = new TH1D(*hist_data);
00837 hist_error_band->SetFillColor(kBlack);
00838 hist_error_band->SetFillStyle(3005);
00839 hist_error_band->SetLineWidth(1);
00840 hist_error_band->SetStats(kFALSE);
00841 hist_error_band->SetMarkerSize(0);
00842
00843 TGraphAsymmErrors * graph_error_exp = new TGraphAsymmErrors(nbins);
00844
00845 graph_error_exp->SetMarkerStyle(0);
00846 graph_error_exp->SetFillColor(kBlack);
00847 graph_error_exp->SetFillStyle(3005);
00848
00849
00850 TH2D* hist_uncbandexp = channel->GetHistUncertaintyBandExpectation();
00851
00852
00853 if (flag_b0) {
00854 for (int i = 1; i <= nbins; ++i) {
00855 TH1D * proj = hist_uncbandexp->ProjectionY("_py", i, i);
00856 if (proj->Integral() > 0)
00857 proj->Scale(1.0 / proj->Integral());
00858 double quantiles[3];
00859 double sums[3] = {0.16, 0.5, 0.84};
00860 proj->GetQuantiles(3, quantiles, sums);
00861 graph_error_exp->SetPoint(i-1, hist_data->GetBinCenter(i), quantiles[1]);
00862 graph_error_exp->SetPointError(i-1, 0.0, 0.0, quantiles[1] - quantiles[0], quantiles[2]-quantiles[1]);
00863 hist_error_band->SetBinContent(i, 0.5*(quantiles[2]+quantiles[0]));
00864 hist_error_band->SetBinError(i, 0, 0.5*(quantiles[2]-quantiles[0]));
00865 delete proj;
00866 }
00867 }
00868
00869
00870 THStack * stack = new THStack("", "");
00871
00872
00873 std::vector<TH1D *> histcontainer;
00874
00875
00876 unsigned int ntemplates = GetNProcesses();
00877
00878
00879 for (unsigned int i = 0; i < ntemplates; ++i) {
00880
00881
00882 TH1D * temphist = channel->GetTemplate(i)->GetHistogram();
00883
00884
00885 std::vector<TF1 *> * funccont = channel->GetTemplate(i)->GetFunctionContainer();
00886
00887
00888 TH1D * hist(0);
00889
00890 if (temphist)
00891 hist = new TH1D( *(temphist) );
00892 else if (funccont)
00893 hist = new TH1D( *(channel->GetData()->GetHistogram()));
00894 else
00895 continue;
00896
00897 if (flag_bw) {
00898 hist->SetFillColor(0);
00899 hist->SetLineWidth(1);
00900 hist->SetLineStyle(int(1+i));
00901 }
00902 else {
00903 hist->SetFillColor(2 + i);
00904 hist->SetFillStyle(1001);
00905 }
00906
00907
00908 for (int ibin = 1; ibin <= nbins; ++ibin) {
00909
00910
00911 double efficiency = Efficiency(channelindex, i, ibin, parameters);
00912
00913
00914 double probability = Probability(channelindex, i, ibin, parameters);
00915
00916
00917 int parindex = GetParIndexProcess(i);
00918
00919
00920 double expectation = parameters[parindex] * efficiency * probability;
00921
00922
00923 hist->SetBinContent(ibin, expectation);
00924
00925
00926 hist_sum->SetBinContent(ibin, hist_sum->GetBinContent(ibin) + expectation);
00927 }
00928
00929
00930 histcontainer.push_back(hist);
00931
00932
00933 stack->Add(hist);
00934 }
00935
00936
00937 hist_data->Draw("P0");
00938
00939
00940 hist_data->GetYaxis()->SetRangeUser(channel->GetRangeYMin(), channel->GetRangeYMax());
00941
00942
00943 if (flag_stack)
00944 stack->Draw("SAMEHIST");
00945
00946
00947 if (flag_b1) {
00948 channel->CalculateUncertaintyBandPoisson(0.001, 0.999, kRed)->Draw("SAMEE2");
00949 channel->CalculateUncertaintyBandPoisson(0.023, 0.977, kOrange)->Draw("SAMEE2");
00950 channel->CalculateUncertaintyBandPoisson(0.159, 0.841, kGreen)->Draw("SAMEE2");
00951 }
00952
00953
00954 if (flag_b0) {
00955 hist_error_band->Draw("SAMEE2");
00956 }
00957
00958 if (flag_sum)
00959 hist_sum->Draw("SAME");
00960
00961
00962 if (flag_e0)
00963 hist_data->Draw("SAMEP0");
00964
00965 if (flag_e1)
00966 hist_data->Draw("SAMEP0E");
00967
00968
00969 gPad->RedrawAxis();
00970
00971
00972 c1->Print(filename);
00973
00974
00975 for (unsigned int i = 0; i < histcontainer.size(); ++i) {
00976 TH1D * hist = histcontainer.at(i);
00977 delete hist;
00978 }
00979 delete stack;
00980 delete c1;
00981 delete graph_error_exp;
00982 delete hist_error_band;
00983 delete hist_sum;
00984
00985
00986 return 1;
00987 }
00988
00989
00990 double BCMTF::CalculateChi2(int channelindex, const std::vector<double> & parameters)
00991 {
00992 if (parameters.size() == 0)
00993 return -1;
00994
00995 double chi2 = 0;
00996
00997
00998 BCMTFChannel * channel = GetChannel(channelindex);
00999
01000
01001 BCMTFTemplate * data = channel->GetData();
01002
01003
01004 TH1D * hist = data->GetHistogram();
01005
01006
01007 if (hist) {
01008
01009 int nbins = hist->GetNbinsX();
01010
01011
01012 for (int ibin = 1; ibin <= nbins; ++ibin) {
01013
01014 double expectation = Expectation(channelindex, ibin, parameters);
01015
01016
01017 double observation = hist->GetBinContent(ibin);
01018
01019
01020 chi2 += (expectation - observation) * (expectation - observation) / expectation;
01021 }
01022 }
01023
01024
01025 return chi2;
01026 }
01027
01028
01029 double BCMTF::CalculateChi2(const std::vector<double> & parameters)
01030 {
01031 if (parameters.size() == 0)
01032 return -1;
01033
01034 double chi2 = 0;
01035
01036
01037 int nchannels = GetNChannels();
01038
01039
01040 for (int i = 0; i < nchannels; ++i) {
01041 chi2 += CalculateChi2(i, parameters);
01042 }
01043
01044
01045 return chi2;
01046 }
01047
01048
01049 double BCMTF::CalculateCash(int channelindex, const std::vector<double> & parameters)
01050 {
01051 if (parameters.size() == 0)
01052 return -1;
01053
01054 double cash = 0;
01055
01056
01057 BCMTFChannel * channel = GetChannel(channelindex);
01058
01059
01060 BCMTFTemplate * data = channel->GetData();
01061
01062
01063 TH1D * hist = data->GetHistogram();
01064
01065
01066 if (hist) {
01067
01068 int nbins = hist->GetNbinsX();
01069
01070
01071 for (int ibin = 1; ibin <= nbins; ++ibin) {
01072
01073 double expectation = Expectation(channelindex, ibin, parameters);
01074
01075
01076 double observation = hist->GetBinContent(ibin);
01077
01078
01079 cash += 2. * (expectation - observation);
01080
01081
01082 if (observation > 0)
01083 cash += 2. * observation * log (observation/expectation);
01084 }
01085 }
01086
01087
01088 return cash;
01089
01090 }
01091
01092
01093 double BCMTF::CalculateCash(const std::vector<double> & parameters)
01094 {
01095 if (parameters.size() == 0)
01096 return -1;
01097
01098 double cash = 0;
01099
01100
01101 int nchannels = GetNChannels();
01102
01103
01104 for (int i = 0; i < nchannels; ++i) {
01105 cash += CalculateCash(i, parameters);
01106 }
01107
01108
01109 return cash;
01110 }
01111
01112
01113 double BCMTF::LogLikelihood(const std::vector<double> & parameters)
01114 {
01115 double logprob = 0.;
01116
01117
01118 for (int ichannel = 0; ichannel < fNChannels; ++ichannel) {
01119
01120
01121 BCMTFChannel * channel = fChannelContainer[ichannel];
01122
01123
01124 if (!(channel->GetFlagChannelActive()))
01125 continue;
01126
01127
01128 BCMTFTemplate * data = channel->GetData();
01129
01130
01131 TH1D * hist = data->GetHistogram();
01132
01133
01134 if (!hist)
01135 continue;
01136
01137
01138 int nbins = data->GetNBins();
01139
01140
01141 for (int ibin = 1; ibin <= nbins; ++ibin) {
01142
01143
01144 double expectation = Expectation(ichannel, ibin, parameters);
01145
01146
01147 double observation = hist->GetBinContent(ibin);
01148
01149
01150 logprob += BCMath::LogPoisson(observation, expectation);
01151 }
01152 }
01153
01154 return logprob;
01155 }
01156
01157
01158 void BCMTF::MCMCUserIterationInterface()
01159 {
01160
01161 for (int ichannel = 0; ichannel < fNChannels; ++ichannel) {
01162
01163
01164 BCMTFChannel * channel = fChannelContainer[ichannel];
01165
01166
01167 if (!(channel->GetFlagChannelActive()))
01168 continue;
01169
01170
01171 BCMTFTemplate * data = channel->GetData();
01172
01173
01174 TH1D * hist_data = data->GetHistogram();
01175
01176
01177 if (!hist_data)
01178 continue;
01179
01180
01181 TH2D* hist_uncbandexp = channel->GetHistUncertaintyBandExpectation();
01182
01183
01184 if (!hist_uncbandexp)
01185 continue;
01186
01187
01188 int nbins = hist_data->GetNbinsX();
01189
01190
01191 for (int ibin = 1; ibin <= nbins; ++ibin) {
01192
01193
01194 double expectation = Expectation(ichannel, ibin, fMCMCx);
01195
01196
01197 hist_uncbandexp->Fill(hist_data->GetBinCenter(ibin), expectation);
01198 }
01199 }
01200
01201 }
01202
01203