• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

BCMTF.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2012, Daniel Kollar and Kevin Kroeninger.
00003  * All rights reserved.
00004  *
00005  * For the licensing terms see doc/COPYING.
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    // default destructor
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    // loop over all channels and compare names
00063    for (int i = 0; i < fNChannels; ++i) {
00064       // get channel
00065       BCMTFChannel * channel = GetChannel(i);
00066 
00067       // compare names
00068       if (!channel->GetName().compare(name))
00069          return i;
00070    }
00071 
00072    // if channel does not exist, return -1
00073    return -1;
00074 }
00075 
00076 // ---------------------------------------------------------
00077 int BCMTF::GetProcessIndex(const char * name)
00078 {
00079    // loop over all processs and compare names
00080    for (int i = 0; i < fNProcesses; ++i) {
00081       // get process
00082       BCMTFProcess * process = GetProcess(i);
00083 
00084       // compare names
00085       if (!process->GetName().compare(name))
00086          return i;
00087    }
00088 
00089    // if process does not exist, return -1
00090    return -1;
00091 }
00092 
00093 // ---------------------------------------------------------
00094 int BCMTF::GetSystematicIndex(const char * name)
00095 {
00096    // loop over all systematics and compare names
00097    for (int i = 0; i < fNSystematics; ++i) {
00098       // get systematic
00099       BCMTFSystematic * systematic = GetSystematic(i);
00100 
00101       // compare names
00102       if (!systematic->GetName().compare(name))
00103          return i;
00104    }
00105 
00106    // if process does not exist, return -1
00107    return -1;
00108 }
00109 
00110 // ---------------------------------------------------------
00111 int BCMTF::SetTemplate(const char * channelname, const char * processname, TH1D hist, double efficiency)
00112 {
00113    // get channel index
00114    int channelindex = GetChannelIndex(channelname);
00115 
00116    // check if channel exists
00117    if (channelindex < 0) {
00118       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00119          return -1;
00120    }
00121 
00122    // get process index
00123    int processindex = GetProcessIndex(processname);
00124 
00125    // check if process exists
00126    if (processindex < 0) {
00127       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00128          return -1;
00129    }
00130 
00131    // get channel
00132    BCMTFChannel * channel = GetChannel(channelindex);
00133 
00134    // get template
00135    BCMTFTemplate * bctemplate = channel->GetTemplate(processindex);
00136 
00137    // normalize histogram
00138    if (hist.Integral())
00139       hist.Scale(1.0 / hist.Integral());
00140 
00141    // remove statistics box
00142    hist.SetStats(kFALSE);
00143 
00144    // set color and fill style
00145    hist.SetFillColor(2 + processindex);
00146    hist.SetFillStyle(1001);
00147 
00148    // create new histogram
00149    TH1D * temphist = new TH1D(hist);
00150 
00151    // set histogram
00152    bctemplate->SetHistogram(temphist);
00153 
00154    // set efficiency
00155    bctemplate->SetEfficiency(efficiency);
00156 
00157    // no error
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    // get channel index
00165    int channelindex = GetChannelIndex(channelname);
00166 
00167    // check if channel exists
00168    if (channelindex < 0) {
00169       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00170          return -1;
00171    }
00172 
00173    // get process index
00174    int processindex = GetProcessIndex(processname);
00175 
00176    // check if process exists
00177    if (processindex < 0) {
00178       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00179          return -1;
00180    }
00181 
00182    // get channel
00183    BCMTFChannel * channel = GetChannel(channelindex);
00184 
00185    // get template
00186    BCMTFTemplate * bctemplate = channel->GetTemplate(processindex);
00187 
00188    // set histogram
00189    bctemplate->SetFunctionContainer(funccont, nbins);
00190 
00191    // set efficiency
00192    bctemplate->SetEfficiency(efficiency);
00193 
00194    // no error
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    // check if channel exists
00204    if (channelindex < 0) {
00205       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00206          return -1;
00207    }
00208 
00209    // get channel
00210    BCMTFChannel * channel = GetChannel(channelindex);
00211 
00212    // get template
00213    BCMTFTemplate * data = channel->GetData();
00214 
00215    // remove statistics box
00216    hist.SetStats(kFALSE);
00217 
00218    // set marker
00219    hist.SetMarkerStyle(20);
00220     hist.SetMarkerSize(1.1);
00221 
00222     // set divisions
00223     hist.SetNdivisions(509);
00224 
00225    // remove old data set if it exists
00226    if (data->GetHistogram()) {
00227       delete data->GetHistogram();
00228       data->SetHistogram(0);
00229    }
00230 
00231     // remove old uncertainty histograms if they exist
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     // create new histograms for uncertainty bands
00242     //    double minimum = floor(TMath::Max(0., hist.GetMinimum() - 7.*sqrt(hist.GetMinimum())));
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    // set histograms
00262    data->SetHistogram(new TH1D(hist));
00263     channel->SetHistUncertaintyBandExpectation(hist_uncbandexp); 
00264     channel->SetHistUncertaintyBandPoisson(hist_uncbandpoisson); 
00265 
00266     // set y-range for printing
00267     channel->SetRangeY(minimum, maximum);
00268 
00269    // no error
00270    return 1;
00271 }
00272 
00273 // ---------------------------------------------------------
00274 int BCMTF::AddChannel(const char * name)
00275 {
00276    // check if channel exists
00277    for (int i = 0; i < fNChannels; ++i) {
00278       // compare names
00279       if (GetChannelIndex(name) >= 0) {
00280       BCLog::OutWarning("BCMultitemplateFitter::AddChannel() : Channel with this name exists already.");
00281          return -1;
00282       }
00283    }
00284 
00285    // create new channel
00286    BCMTFChannel * channel = new BCMTFChannel(name);
00287 
00288    // create new data
00289    BCMTFTemplate * bctemplate = new BCMTFTemplate(channel->GetName().c_str(), "data");
00290 
00291    // add data
00292    channel->SetData(bctemplate);
00293 
00294    // add process templates
00295    for (int i = 0; i < fNProcesses; ++i) {
00296       // get process
00297       BCMTFProcess * process = GetProcess(i);
00298 
00299       // create new template
00300       BCMTFTemplate * bctemplate = new BCMTFTemplate(name, process->GetName().c_str());
00301 
00302       // add template
00303       channel->AddTemplate(bctemplate);
00304    }
00305 
00306    // loop over all systematics
00307    for (int i = 0; i < fNSystematics; ++i) {
00308       // get systematic
00309       BCMTFSystematic * systematic = GetSystematic(i);
00310 
00311       // create new systematic variation
00312       BCMTFSystematicVariation * variation = new BCMTFSystematicVariation(name, systematic->GetName().c_str(), fNProcesses);
00313 
00314       // add systematic variation
00315       channel->AddSystematicVariation(variation);
00316    }
00317 
00318    // add channel
00319    fChannelContainer.push_back(channel);
00320 
00321    // increase number of channels
00322    fNChannels++;
00323 
00324    // no error
00325    return 1;
00326 }
00327 
00328 // ---------------------------------------------------------
00329 int BCMTF::AddProcess(const char * name, double nmin, double nmax)
00330 {
00331    // check if process exists
00332    for (int i = 0; i < fNProcesses; ++i) {
00333       // compare names
00334       if (GetProcessIndex(name) >= 0) {
00335       BCLog::OutWarning("BCMultitemplateFitter::AddProcess() : Process with this name exists already.");
00336          return -1;
00337       }
00338    }
00339 
00340    // create new process
00341    BCMTFProcess * process = new BCMTFProcess(name);
00342 
00343    // add process
00344    fProcessContainer.push_back(process);
00345 
00346    // add process templates
00347    for (int i = 0; i < fNChannels; ++i) {
00348       // get channel
00349       BCMTFChannel * channel = GetChannel(i);
00350 
00351       // create new template
00352       BCMTFTemplate * bctemplate = new BCMTFTemplate(channel->GetName().c_str(), name);
00353 
00354       // add template
00355       channel->AddTemplate(bctemplate);
00356 
00357       // loop over all systematic
00358       for (int j = 0; j < fNSystematics; ++j) {
00359          // get systematic variation
00360          BCMTFSystematicVariation * variation = channel->GetSystematicVariation(j);
00361 
00362          // add histogram
00363          variation->AddHistograms(0, 0);
00364       }
00365    }
00366 
00367    // increase number of processes
00368    fNProcesses++;
00369 
00370    // add parameter index to container
00371    fProcessParIndexContainer.push_back(GetNParameters());
00372 
00373    // add parameter
00374    AddParameter(name, nmin, nmax);
00375 
00376    // add a functional form for the expectation
00377    fExpectationFunctionContainer.push_back(0);
00378 
00379    // no error
00380    return 1;
00381 }
00382 
00383 // ---------------------------------------------------------
00384 int BCMTF::AddSystematic(const char * name, double min, double max)
00385 {
00386    // check if systematic exists
00387    for (int i = 0; i < fNSystematics; ++i) {
00388       // compare names
00389       if (GetSystematicIndex(name) >= 0) {
00390       BCLog::OutWarning("BCMultitemplateFitter::AddSystematic() : Systematic with this name exists already.");
00391          return -1;
00392       }
00393    }
00394 
00395    // create new systematic
00396    BCMTFSystematic * systematic = new BCMTFSystematic(name);
00397 
00398    // add systematic
00399    fSystematicContainer.push_back(systematic);
00400 
00401    // add systematic variations
00402    for (int i = 0; i < fNChannels; ++i) {
00403       // get channel
00404       BCMTFChannel * channel = GetChannel(i);
00405 
00406       // create new systematic variation
00407       BCMTFSystematicVariation * variation = new BCMTFSystematicVariation(channel->GetName().c_str(), name, fNProcesses);
00408 
00409       // add systematic variation
00410       channel->AddSystematicVariation(variation);
00411    }
00412    // ...
00413 
00414    // increase number of systematices
00415    fNSystematics++;
00416 
00417    // add parameter index to container
00418    fSystematicParIndexContainer.push_back(GetNParameters());
00419 
00420    // add parameter
00421    AddParameter(name, min, max);
00422 
00423    // add a functional form for the expectation
00424    fExpectationFunctionContainer.push_back(0);
00425 
00426    // no error
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    // get channel index
00435    int channelindex = GetChannelIndex(channelname);
00436 
00437    // check if channel exists
00438    if (channelindex < 0) {
00439       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00440          return -1;
00441    }
00442 
00443    // get process index
00444    int processindex = GetProcessIndex(processname);
00445 
00446    // check if process exists
00447    if (processindex < 0) {
00448       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00449          return -1;
00450    }
00451 
00452    // get systematic index
00453    int systematicindex = GetSystematicIndex(systematicname);
00454 
00455    // check if systematic exists
00456    if (systematicindex < 0) {
00457       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Systematic does not exist.");
00458          return -1;
00459    }
00460 
00461    // get channel
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    // loop over all bins
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    // get systematic variation
00480    BCMTFSystematicVariation * variation = channel->GetSystematicVariation(systematicindex);
00481 
00482    // set histogram
00483    variation->SetHistograms(processindex, new TH1D(hist_up), new TH1D(hist_down));
00484 
00485    // no error
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    // get channel index
00493    int channelindex = GetChannelIndex(channelname);
00494 
00495    // check if channel exists
00496    if (channelindex < 0) {
00497       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist.");
00498          return -1;
00499    }
00500 
00501    // get process index
00502    int processindex = GetProcessIndex(processname);
00503 
00504    // check if process exists
00505    if (processindex < 0) {
00506       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist.");
00507          return -1;
00508    }
00509 
00510    // get systematic index
00511    int systematicindex = GetSystematicIndex(systematicname);
00512 
00513    // check if systematic exists
00514    if (systematicindex < 0) {
00515       BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Systematic does not exist.");
00516          return -1;
00517    }
00518 
00519    // get channel
00520    BCMTFChannel * channel = GetChannel(channelindex);
00521 
00522    // get systematic variation
00523    BCMTFSystematicVariation * variation = channel->GetSystematicVariation(systematicindex);
00524 
00525    // set histogram
00526    variation->SetHistograms(processindex, new TH1D(hist_up), new TH1D(hist_down));
00527 
00528    // no error
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    // get number of bins
00536    int nbins = hist.GetNbinsX();
00537 
00538    TH1D * hist_up_rel = new TH1D(hist);
00539    TH1D * hist_down_rel = new TH1D(hist);
00540 
00541    // loop over all bins
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    // set the systematic variation
00548    return SetSystematicVariation(channelname, processname, systematicname, *hist_up_rel, *hist_down_rel);
00549 }
00550 
00551 // ---------------------------------------------------------
00552 int BCMTF::PrintSummary(const char * filename)
00553 {
00554    // open file
00555    std::ofstream ofi(filename);
00556    ofi.precision(3);
00557 
00558    // check if file is open
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    // close file
00624    ofi.close();
00625 
00626    // no error
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    // loop over all processes
00636    for (int i = 0; i < fNProcesses; ++i) {
00637        // get efficiency
00638        double efficiency = Efficiency(channelindex, i, binindex, parameters);
00639        
00640        // get probability
00641        double probability = Probability(channelindex, i, binindex, parameters);
00642        
00643        // get parameter index
00644        int parindex = fProcessParIndexContainer[i];
00645        
00646        // add to expectation
00647        expectation += ExpectationFunction(parindex, channelindex, i, parameters)
00648           * efficiency
00649           * probability;
00650    }
00651     
00652    // check if expectation is positive
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   // get function container
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    // get channel
00681    BCMTFChannel * channel = fChannelContainer[channelindex];
00682 
00683    double efficiency = channel->GetTemplate(processindex)->GetEfficiency();
00684 
00685    double defficiency = 1.;
00686 
00687    // loop over all systematics
00688    for (int i = 0; i < fNSystematics; ++i) {
00689       if (!(fSystematicContainer[i]->GetFlagSystematicActive()))
00690          continue;
00691 
00692       // get parameter index
00693       int parindex = fSystematicParIndexContainer[i];
00694 
00695       // get histogram
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       // check if histogram exists
00704       if (!hist)
00705          continue;
00706 
00707       // multiply efficiency
00708       defficiency += parameters[parindex] * hist->GetBinContent(binindex);
00709    }
00710 
00711    // calculate efficiency
00712    efficiency *= defficiency;
00713 
00714    // make sure efficiency is between 0 and 1
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    // get histogram
00729    TH1D * hist = fChannelContainer[channelindex]->GetTemplate(processindex)->GetHistogram();
00730 
00731    // get function container
00732    std::vector<TF1 *> * funccont = fChannelContainer[channelindex]->GetTemplate(processindex)->GetFunctionContainer();
00733 
00734    // this needs to be fast
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    // todo:
00758    // - remove x-error on data points
00759    // - use hatched fill for error band
00760 
00761    // check if parameters are filled
00762    if (!parameters.size())
00763       return -1;
00764 
00765    // check options
00766    bool flag_logx   = false; // plot x-axis in log-scale
00767    bool flag_logy   = false; // plot y-axis in log-scale
00768    bool flag_bw     = false; // plot in black and white
00769 
00770     bool flag_sum    = false; // plot sum of all templates
00771     bool flag_stack  = false; // plot stack of templates
00772 
00773     bool flag_e0     = false; // do not draw error bars on data
00774     bool flag_e1     = false; // draw sqrt(N) error bars on data
00775 
00776     bool flag_b0     = false; // draw an error band on the expectation
00777     bool flag_b1     = false; // draw an error band on the number of events
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    // get channel
00810    BCMTFChannel * channel = GetChannel(channelindex);
00811 
00812    // create canvas
00813    TCanvas * c1 = new TCanvas();
00814    c1->cd();
00815 
00816    // set log or linear scale
00817    if (flag_logx)
00818       c1->SetLogx();
00819 
00820    if (flag_logy)
00821       c1->SetLogy();
00822     
00823     // get data histogram
00824     TH1D* hist_data = channel->GetData()->GetHistogram();
00825 
00826     // get number of bins
00827     int nbins = hist_data->GetNbinsX();
00828 
00829     // define sum of templates
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   // define error band
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     //   graph_error_exp->SetLineWidth(2);
00845     graph_error_exp->SetMarkerStyle(0);
00846     graph_error_exp->SetFillColor(kBlack);
00847     graph_error_exp->SetFillStyle(3005);
00848 
00849     // get histogram for uncertainty band
00850     TH2D* hist_uncbandexp = channel->GetHistUncertaintyBandExpectation(); 
00851 
00852     // fill error band
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    // create stack
00870    THStack * stack = new THStack("", "");
00871 
00872    // create a container of temporary histograms
00873    std::vector<TH1D *> histcontainer;
00874 
00875    // get number of templates
00876    unsigned int ntemplates = GetNProcesses();
00877 
00878    // loop over all templates
00879    for (unsigned int i = 0; i < ntemplates; ++i) {
00880 
00881       // get histogram
00882       TH1D * temphist = channel->GetTemplate(i)->GetHistogram();
00883 
00884       // get function container
00885       std::vector<TF1 *> * funccont = channel->GetTemplate(i)->GetFunctionContainer();
00886 
00887       // create new histogram
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       // scale histogram
00908       for (int ibin = 1; ibin <= nbins; ++ibin) {
00909 
00910          // get efficiency
00911          double efficiency = Efficiency(channelindex, i, ibin, parameters);
00912 
00913          // get probability
00914          double probability = Probability(channelindex, i, ibin, parameters);
00915 
00916          // get parameter index
00917          int parindex = GetParIndexProcess(i);
00918 
00919          // add to expectation
00920          double expectation = parameters[parindex] * efficiency * probability;
00921 
00922          // set bin content
00923          hist->SetBinContent(ibin, expectation);
00924 
00925              // add bin content
00926              hist_sum->SetBinContent(ibin, hist_sum->GetBinContent(ibin) + expectation);
00927       }
00928 
00929       // add histogram to container (for memory management)
00930       histcontainer.push_back(hist);
00931 
00932       // add histogram to stack
00933       stack->Add(hist);
00934    }
00935 
00936    //draw data
00937    hist_data->Draw("P0");
00938 
00939    // set range user
00940    hist_data->GetYaxis()->SetRangeUser(channel->GetRangeYMin(), channel->GetRangeYMax());
00941 
00942     // draw stack
00943     if (flag_stack)
00944        stack->Draw("SAMEHIST");
00945 
00946     // draw error band on number of observed events
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     // draw error band on expectation
00954     if (flag_b0) {
00955        hist_error_band->Draw("SAMEE2");
00956     }
00957 
00958     if (flag_sum)
00959        hist_sum->Draw("SAME");
00960 
00961     //draw data again
00962     if (flag_e0)
00963        hist_data->Draw("SAMEP0");
00964 
00965     if (flag_e1)
00966        hist_data->Draw("SAMEP0E");
00967 
00968    // redraw the axes
00969    gPad->RedrawAxis();
00970 
00971    // print
00972    c1->Print(filename);
00973 
00974    // free memory
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    // no error
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    // get channel
00998    BCMTFChannel * channel = GetChannel(channelindex);
00999 
01000    // get data
01001    BCMTFTemplate * data = channel->GetData();
01002 
01003    // get histogram
01004    TH1D * hist = data->GetHistogram();
01005 
01006    // check if histogram exists
01007    if (hist) {
01008       // get number of bins in data
01009       int nbins = hist->GetNbinsX();
01010 
01011       // loop over all bins
01012       for (int ibin = 1; ibin <= nbins; ++ibin) {
01013          // get expectation value
01014          double expectation = Expectation(channelindex, ibin, parameters);
01015 
01016          // get observation
01017          double observation = hist->GetBinContent(ibin);
01018 
01019          // add Poisson term
01020          chi2 += (expectation - observation) * (expectation - observation) / expectation;
01021       }
01022    }
01023 
01024    // return chi2;
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    // get number of channels
01037    int nchannels = GetNChannels();
01038 
01039    // loop over all channels
01040    for (int i = 0; i < nchannels; ++i) {
01041       chi2 += CalculateChi2(i, parameters);
01042    }
01043 
01044    // return chi2
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    // get channel
01057    BCMTFChannel * channel = GetChannel(channelindex);
01058 
01059    // get data
01060    BCMTFTemplate * data = channel->GetData();
01061 
01062    // get histogram
01063    TH1D * hist = data->GetHistogram();
01064 
01065    // check if histogram exists
01066    if (hist) {
01067       // get number of bins in data
01068       int nbins = hist->GetNbinsX();
01069 
01070       // loop over all bins
01071       for (int ibin = 1; ibin <= nbins; ++ibin) {
01072          // get expectation value
01073          double expectation = Expectation(channelindex, ibin, parameters);
01074 
01075          // get observation
01076          double observation = hist->GetBinContent(ibin);
01077 
01078          // calculate Cash statistic
01079          cash += 2. * (expectation - observation);
01080 
01081          // check negative log
01082          if (observation > 0)
01083             cash += 2. * observation * log (observation/expectation);
01084       }
01085    }
01086 
01087    // return cash;
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    // get number of channels
01101    int nchannels = GetNChannels();
01102 
01103    // loop over all channels
01104    for (int i = 0; i < nchannels; ++i) {
01105       cash += CalculateCash(i, parameters);
01106    }
01107 
01108    // return cash
01109    return cash;
01110 }
01111 
01112 // ---------------------------------------------------------
01113 double BCMTF::LogLikelihood(const std::vector<double> & parameters)
01114 {
01115    double logprob = 0.;
01116 
01117    // loop over all channels
01118    for (int ichannel = 0; ichannel < fNChannels; ++ichannel) {
01119 
01120       // get channel
01121       BCMTFChannel * channel = fChannelContainer[ichannel];
01122 
01123       // check if channel is active
01124       if (!(channel->GetFlagChannelActive()))
01125          continue;
01126 
01127      // get data
01128       BCMTFTemplate * data = channel->GetData();
01129 
01130       // get histogram
01131       TH1D * hist = data->GetHistogram();
01132 
01133       // check if histogram exists
01134       if (!hist)
01135          continue;
01136 
01137       // get number of bins in data
01138       int nbins = data->GetNBins();
01139 
01140       // loop over all bins
01141       for (int ibin = 1; ibin <= nbins; ++ibin) {
01142 
01143          // get expectation value
01144          double expectation = Expectation(ichannel, ibin, parameters);
01145 
01146          // get observation
01147          double observation = hist->GetBinContent(ibin);
01148 
01149          // add Poisson term
01150          logprob += BCMath::LogPoisson(observation, expectation);
01151       }
01152    }
01153 
01154    return logprob;
01155 }
01156 
01157 // ---------------------------------------------------------
01158 void BCMTF::MCMCUserIterationInterface()
01159 {
01160    // loop over all channels
01161    for (int ichannel = 0; ichannel < fNChannels; ++ichannel) {
01162 
01163       // get channel
01164       BCMTFChannel * channel = fChannelContainer[ichannel];
01165 
01166       // check if channel is active
01167       if (!(channel->GetFlagChannelActive()))
01168          continue;
01169 
01170      // get data
01171       BCMTFTemplate * data = channel->GetData();
01172 
01173       // get histogram
01174       TH1D * hist_data = data->GetHistogram();
01175 
01176       // check if histogram exists
01177       if (!hist_data)
01178          continue;
01179 
01180          // get histogram for uncertainty band
01181          TH2D* hist_uncbandexp = channel->GetHistUncertaintyBandExpectation(); 
01182 
01183       // check if histogram exists
01184       if (!hist_uncbandexp)
01185          continue;
01186 
01187       // get number of bins in data
01188       int nbins = hist_data->GetNbinsX();
01189 
01190       // loop over all bins
01191       for (int ibin = 1; ibin <= nbins; ++ibin) {
01192 
01193          // get expectation value
01194          double expectation = Expectation(ichannel, ibin, fMCMCx);
01195 
01196              // fill uncertainty band on expectation
01197              hist_uncbandexp->Fill(hist_data->GetBinCenter(ibin), expectation);
01198       }
01199    }
01200 
01201 }
01202 
01203 // ---------------------------------------------------------

Generated by  doxygen 1.7.1