A class for fitting several templates to a data set. More...
#include <BCMTF.h>
Inherits BCModel.
Public Member Functions | |
Constructors and destructors | |
BCMTF () | |
BCMTF (const char *name) | |
~BCMTF () | |
Member functions (get) | |
int | GetNChannels () |
int | GetNProcesses () |
int | GetNSystematics () |
int | GetChannelIndex (const char *name) |
int | GetProcessIndex (const char *name) |
int | GetSystematicIndex (const char *name) |
int | GetParIndexProcess (int index) |
int | GetParIndexSystematic (int index) |
BCMTFChannel * | GetChannel (int index) |
BCMTFProcess * | GetProcess (int index) |
BCMTFSystematic * | GetSystematic (int index) |
Member functions (set) | |
int | SetData (const char *channelname, TH1D hist, double minimum=-1, double maximum=-1) |
int | SetTemplate (const char *channelname, const char *processname, TH1D hist, double efficiency=1.) |
int | SetTemplate (const char *channelname, const char *processname, std::vector< TF1 * > *funccont, int nbins, double efficiency=1.) |
void | SetExpectationFunction (int parindex, TF1 *func) |
int | SetSystematicVariation (const char *channelname, const char *processname, const char *systematicname, double variation_up, double variation_down) |
int | SetSystematicVariation (const char *channelname, const char *processname, const char *systematicname, TH1D hist_up, TH1D hist_down) |
int | SetSystematicVariation (const char *channelname, const char *processname, const char *systematicname, TH1D hist, TH1D hist_up, TH1D hist_down) |
void | SetFlagEfficiencyConstraint (bool flag) |
Member functions (miscellaneous methods) | |
int | AddChannel (const char *name) |
int | AddProcess (const char *name, double nmin=0., double nmax=1.) |
int | AddSystematic (const char *name, double min=-5., double max=5.) |
double | Expectation (int channelindex, int binindex, const std::vector< double > ¶meters) |
double | ExpectationFunction (int parindex, int channelindex, int processindex, const std::vector< double > ¶meters) |
double | Efficiency (int channelindex, int processindex, int binindex, const std::vector< double > ¶meters) |
double | Probability (int channelindex, int processindex, int binindex, const std::vector< double > ¶meters) |
double | CalculateChi2 (int channelindex, const std::vector< double > ¶meters) |
double | CalculateChi2 (const std::vector< double > ¶meters) |
double | CalculateCash (int channelindex, const std::vector< double > ¶meters) |
double | CalculateCash (const std::vector< double > ¶meters) |
Member functions (output methods) | |
int | PrintSummary (const char *filename="summary.txt") |
int | PrintStack (int channelindex, const std::vector< double > ¶meters, const char *filename="stack.eps", const char *options="e1b0stack") |
int | PrintStack (const char *channelname, const std::vector< double > ¶meters, const char *filename="stack.eps", const char *options="e1b0stack") |
Member functions (overloaded from BCModel) | |
double | LogLikelihood (const std::vector< double > ¶meters) |
void | MCMCUserIterationInterface () |
Private Attributes | |
std::vector< BCMTFChannel * > | fChannelContainer |
std::vector< BCMTFProcess * > | fProcessContainer |
std::vector< BCMTFSystematic * > | fSystematicContainer |
int | fNChannels |
int | fNProcesses |
int | fNSystematics |
std::vector< int > | fProcessParIndexContainer |
std::vector< int > | fSystematicParIndexContainer |
bool | fFlagEfficiencyConstraint |
std::vector< TF1 * > | fExpectationFunctionContainer |
A class for fitting several templates to a data set.
Definition at line 37 of file BCMTF.h.
BCMTF::BCMTF | ( | ) |
The default constructor.
Definition at line 34 of file BCMTF.cxx.
: BCModel("Multi-template Fitter") , fNChannels(0) , fNProcesses(0) , fNSystematics(0) , fFlagEfficiencyConstraint(false) {}
BCMTF::BCMTF | ( | const char * | name | ) |
A constructor.
name | The name of the model |
Definition at line 43 of file BCMTF.cxx.
: BCModel(name) , fNChannels(0) , fNProcesses(0) , fNSystematics(0) , fFlagEfficiencyConstraint(false) {}
BCMTF::~BCMTF | ( | ) |
The default destructor.
Definition at line 52 of file BCMTF.cxx.
{ for (int i = 0; i < fNChannels; ++i) delete fChannelContainer.at(i); }
int BCMTF::AddChannel | ( | const char * | name | ) |
Add a channel
name | The channel name. |
Definition at line 274 of file BCMTF.cxx.
{ // check if channel exists for (int i = 0; i < fNChannels; ++i) { // compare names if (GetChannelIndex(name) >= 0) { BCLog::OutWarning("BCMultitemplateFitter::AddChannel() : Channel with this name exists already."); return -1; } } // create new channel BCMTFChannel * channel = new BCMTFChannel(name); // create new data BCMTFTemplate * bctemplate = new BCMTFTemplate(channel->GetName().c_str(), "data"); // add data channel->SetData(bctemplate); // add process templates for (int i = 0; i < fNProcesses; ++i) { // get process BCMTFProcess * process = GetProcess(i); // create new template BCMTFTemplate * bctemplate = new BCMTFTemplate(name, process->GetName().c_str()); // add template channel->AddTemplate(bctemplate); } // loop over all systematics for (int i = 0; i < fNSystematics; ++i) { // get systematic BCMTFSystematic * systematic = GetSystematic(i); // create new systematic variation BCMTFSystematicVariation * variation = new BCMTFSystematicVariation(name, systematic->GetName().c_str(), fNProcesses); // add systematic variation channel->AddSystematicVariation(variation); } // add channel fChannelContainer.push_back(channel); // increase number of channels fNChannels++; // no error return 1; }
int BCMTF::AddProcess | ( | const char * | name, | |
double | nmin = 0. , |
|||
double | nmax = 1. | |||
) |
Add a process and the associated BAT parameter.
name | The process name | |
nmin | The minimum number of expected events (lower limit on the BAT parameter values). | |
nmax | The maximum number of expected events (upper limit on the BAT parameter values). |
Definition at line 329 of file BCMTF.cxx.
{ // check if process exists for (int i = 0; i < fNProcesses; ++i) { // compare names if (GetProcessIndex(name) >= 0) { BCLog::OutWarning("BCMultitemplateFitter::AddProcess() : Process with this name exists already."); return -1; } } // create new process BCMTFProcess * process = new BCMTFProcess(name); // add process fProcessContainer.push_back(process); // add process templates for (int i = 0; i < fNChannels; ++i) { // get channel BCMTFChannel * channel = GetChannel(i); // create new template BCMTFTemplate * bctemplate = new BCMTFTemplate(channel->GetName().c_str(), name); // add template channel->AddTemplate(bctemplate); // loop over all systematic for (int j = 0; j < fNSystematics; ++j) { // get systematic variation BCMTFSystematicVariation * variation = channel->GetSystematicVariation(j); // add histogram variation->AddHistograms(0, 0); } } // increase number of processes fNProcesses++; // add parameter index to container fProcessParIndexContainer.push_back(GetNParameters()); // add parameter AddParameter(name, nmin, nmax); // add a functional form for the expectation fExpectationFunctionContainer.push_back(0); // no error return 1; }
int BCMTF::AddSystematic | ( | const char * | name, | |
double | min = -5. , |
|||
double | max = 5. | |||
) |
Add a source of systematic uncertainty and the associated BAT (nuisance) parameter.
name | The systematic uncertainty name. | |
min | The lower limit on the BAT parameter values, typically -5 sigma if Gaussian constraint is used. | |
max | The upper limit on the BAT parameter values, typically +5 sigma if Gaussian constraint is used. |
Definition at line 384 of file BCMTF.cxx.
{ // check if systematic exists for (int i = 0; i < fNSystematics; ++i) { // compare names if (GetSystematicIndex(name) >= 0) { BCLog::OutWarning("BCMultitemplateFitter::AddSystematic() : Systematic with this name exists already."); return -1; } } // create new systematic BCMTFSystematic * systematic = new BCMTFSystematic(name); // add systematic fSystematicContainer.push_back(systematic); // add systematic variations for (int i = 0; i < fNChannels; ++i) { // get channel BCMTFChannel * channel = GetChannel(i); // create new systematic variation BCMTFSystematicVariation * variation = new BCMTFSystematicVariation(channel->GetName().c_str(), name, fNProcesses); // add systematic variation channel->AddSystematicVariation(variation); } // ... // increase number of systematices fNSystematics++; // add parameter index to container fSystematicParIndexContainer.push_back(GetNParameters()); // add parameter AddParameter(name, min, max); // add a functional form for the expectation fExpectationFunctionContainer.push_back(0); // no error return 1; }
double BCMTF::CalculateCash | ( | int | channelindex, | |
const std::vector< double > & | parameters | |||
) |
Calculate the Cash statistic for a single channel
channelindex | The channel index. | |
parameters | A reference to the parameters used to calculate the Cash statistic. |
Definition at line 1049 of file BCMTF.cxx.
{ if (parameters.size() == 0) return -1; double cash = 0; // get channel BCMTFChannel * channel = GetChannel(channelindex); // get data BCMTFTemplate * data = channel->GetData(); // get histogram TH1D * hist = data->GetHistogram(); // check if histogram exists if (hist) { // get number of bins in data int nbins = hist->GetNbinsX(); // loop over all bins for (int ibin = 1; ibin <= nbins; ++ibin) { // get expectation value double expectation = Expectation(channelindex, ibin, parameters); // get observation double observation = hist->GetBinContent(ibin); // calculate Cash statistic cash += 2. * (expectation - observation); // check negative log if (observation > 0) cash += 2. * observation * log (observation/expectation); } } // return cash; return cash; }
double BCMTF::CalculateCash | ( | const std::vector< double > & | parameters | ) |
Calculate the Cash statistic for all channels
parameters | A reference to the parameters used to calculate the Cash statistic. |
Definition at line 1093 of file BCMTF.cxx.
{ if (parameters.size() == 0) return -1; double cash = 0; // get number of channels int nchannels = GetNChannels(); // loop over all channels for (int i = 0; i < nchannels; ++i) { cash += CalculateCash(i, parameters); } // return cash return cash; }
double BCMTF::CalculateChi2 | ( | const std::vector< double > & | parameters | ) |
Calculate a chi2 for all channels together given a set of parameters.
parameters | A reference to the parameters used to calculate the chi2. |
Definition at line 1029 of file BCMTF.cxx.
{ if (parameters.size() == 0) return -1; double chi2 = 0; // get number of channels int nchannels = GetNChannels(); // loop over all channels for (int i = 0; i < nchannels; ++i) { chi2 += CalculateChi2(i, parameters); } // return chi2 return chi2; }
double BCMTF::CalculateChi2 | ( | int | channelindex, | |
const std::vector< double > & | parameters | |||
) |
Calculate a chi2 for a single channel given a set of parameters.
channelindex | The channel index. | |
parameters | A reference to the parameters used to calculate the chi2. |
Definition at line 990 of file BCMTF.cxx.
{ if (parameters.size() == 0) return -1; double chi2 = 0; // get channel BCMTFChannel * channel = GetChannel(channelindex); // get data BCMTFTemplate * data = channel->GetData(); // get histogram TH1D * hist = data->GetHistogram(); // check if histogram exists if (hist) { // get number of bins in data int nbins = hist->GetNbinsX(); // loop over all bins for (int ibin = 1; ibin <= nbins; ++ibin) { // get expectation value double expectation = Expectation(channelindex, ibin, parameters); // get observation double observation = hist->GetBinContent(ibin); // add Poisson term chi2 += (expectation - observation) * (expectation - observation) / expectation; } } // return chi2; return chi2; }
double BCMTF::Efficiency | ( | int | channelindex, | |
int | processindex, | |||
int | binindex, | |||
const std::vector< double > & | parameters | |||
) |
Return the efficiency for a process in a channel and for a particular bin.
channelindex | The channel index. | |
processindex | The process index. | |
binindex | The bin index. | |
parameters | A reference to the parameters used to calculate the efficiency. |
Definition at line 678 of file BCMTF.cxx.
{ // get channel BCMTFChannel * channel = fChannelContainer[channelindex]; double efficiency = channel->GetTemplate(processindex)->GetEfficiency(); double defficiency = 1.; // loop over all systematics for (int i = 0; i < fNSystematics; ++i) { if (!(fSystematicContainer[i]->GetFlagSystematicActive())) continue; // get parameter index int parindex = fSystematicParIndexContainer[i]; // get histogram TH1D * hist = 0; if (parameters[parindex] > 0) hist = channel->GetSystematicVariation(i)->GetHistogramUp(processindex); else hist = channel->GetSystematicVariation(i)->GetHistogramDown(processindex); // check if histogram exists if (!hist) continue; // multiply efficiency defficiency += parameters[parindex] * hist->GetBinContent(binindex); } // calculate efficiency efficiency *= defficiency; // make sure efficiency is between 0 and 1 if (fFlagEfficiencyConstraint) { if (efficiency < 0.) efficiency = 0.; if (efficiency > 1.) efficiency = 1.; } return efficiency; }
double BCMTF::Expectation | ( | int | channelindex, | |
int | binindex, | |||
const std::vector< double > & | parameters | |||
) |
Return the expected number of events for a channel and bin.
channelindex | The channel index. | |
binindex | The bin index. | |
parameters | A reference to the parameters used to calculate the expectation. |
Definition at line 631 of file BCMTF.cxx.
{ double expectation = 0.; // loop over all processes for (int i = 0; i < fNProcesses; ++i) { // get efficiency double efficiency = Efficiency(channelindex, i, binindex, parameters); // get probability double probability = Probability(channelindex, i, binindex, parameters); // get parameter index int parindex = fProcessParIndexContainer[i]; // add to expectation expectation += ExpectationFunction(parindex, channelindex, i, parameters) * efficiency * probability; } // check if expectation is positive if (expectation < 0) expectation = 0.; return expectation; }
double BCMTF::ExpectationFunction | ( | int | parindex, | |
int | channelindex, | |||
int | processindex, | |||
const std::vector< double > & | parameters | |||
) |
Return the function value of the expectation function for a parameter, channel and process.
parindex | The parameter index. | |
channelindex | The channel index. | |
processindex | The process index. | |
A | reference to the parameters used to calculate the expectation. |
Definition at line 660 of file BCMTF.cxx.
{ // get function container std::vector<TF1 *> * funccont = fChannelContainer[channelindex]->GetTemplate(processindex)->GetFunctionContainer(); if (funccont->size()>0) return 1.; else if (!fExpectationFunctionContainer[parindex]) return parameters[parindex]; else { TF1 * func = fExpectationFunctionContainer[parindex]; return func->Eval(parameters[parindex]); } }
BCMTFChannel* BCMTF::GetChannel | ( | int | index | ) | [inline] |
name | The channel index. |
Definition at line 107 of file BCMTF.h.
{ return fChannelContainer.at(index); };
int BCMTF::GetChannelIndex | ( | const char * | name | ) |
name | The name of the channel. |
Definition at line 60 of file BCMTF.cxx.
{ // loop over all channels and compare names for (int i = 0; i < fNChannels; ++i) { // get channel BCMTFChannel * channel = GetChannel(i); // compare names if (!channel->GetName().compare(name)) return i; } // if channel does not exist, return -1 return -1; }
int BCMTF::GetNChannels | ( | ) | [inline] |
int BCMTF::GetNProcesses | ( | ) | [inline] |
int BCMTF::GetNSystematics | ( | ) | [inline] |
Definition at line 74 of file BCMTF.h.
{ return fNSystematics; };
int BCMTF::GetParIndexProcess | ( | int | index | ) | [inline] |
index | The parameter index (mtf counting) . |
Definition at line 95 of file BCMTF.h.
{ return fProcessParIndexContainer.at(index); };
int BCMTF::GetParIndexSystematic | ( | int | index | ) | [inline] |
name | The systematic uncertainty index (mtf counting). |
Definition at line 101 of file BCMTF.h.
{ return fSystematicParIndexContainer.at(index); };
BCMTFProcess* BCMTF::GetProcess | ( | int | index | ) | [inline] |
name | The process index. |
Definition at line 113 of file BCMTF.h.
{ return fProcessContainer.at(index); };
int BCMTF::GetProcessIndex | ( | const char * | name | ) |
name | The name of the process. |
Definition at line 77 of file BCMTF.cxx.
{ // loop over all processs and compare names for (int i = 0; i < fNProcesses; ++i) { // get process BCMTFProcess * process = GetProcess(i); // compare names if (!process->GetName().compare(name)) return i; } // if process does not exist, return -1 return -1; }
BCMTFSystematic* BCMTF::GetSystematic | ( | int | index | ) | [inline] |
name | The systematic ucnertainty index. |
Definition at line 119 of file BCMTF.h.
{ return fSystematicContainer.at(index); };
int BCMTF::GetSystematicIndex | ( | const char * | name | ) |
name | The name of the systematic. |
Definition at line 94 of file BCMTF.cxx.
{ // loop over all systematics and compare names for (int i = 0; i < fNSystematics; ++i) { // get systematic BCMTFSystematic * systematic = GetSystematic(i); // compare names if (!systematic->GetName().compare(name)) return i; } // if process does not exist, return -1 return -1; }
double BCMTF::LogLikelihood | ( | const std::vector< double > & | parameters | ) | [virtual] |
Calculates natural logarithm of the likelihood. Method needs to be overloaded by the user.
params | A set of parameter values |
Implements BCModel.
Definition at line 1113 of file BCMTF.cxx.
{ double logprob = 0.; // loop over all channels for (int ichannel = 0; ichannel < fNChannels; ++ichannel) { // get channel BCMTFChannel * channel = fChannelContainer[ichannel]; // check if channel is active if (!(channel->GetFlagChannelActive())) continue; // get data BCMTFTemplate * data = channel->GetData(); // get histogram TH1D * hist = data->GetHistogram(); // check if histogram exists if (!hist) continue; // get number of bins in data int nbins = data->GetNBins(); // loop over all bins for (int ibin = 1; ibin <= nbins; ++ibin) { // get expectation value double expectation = Expectation(ichannel, ibin, parameters); // get observation double observation = hist->GetBinContent(ibin); // add Poisson term logprob += BCMath::LogPoisson(observation, expectation); } } return logprob; }
void BCMTF::MCMCUserIterationInterface | ( | ) | [virtual] |
Method executed for every iteration of the MCMC. User's code should be provided via overloading in the derived class
Reimplemented from BCIntegrate.
Definition at line 1158 of file BCMTF.cxx.
{ // loop over all channels for (int ichannel = 0; ichannel < fNChannels; ++ichannel) { // get channel BCMTFChannel * channel = fChannelContainer[ichannel]; // check if channel is active if (!(channel->GetFlagChannelActive())) continue; // get data BCMTFTemplate * data = channel->GetData(); // get histogram TH1D * hist_data = data->GetHistogram(); // check if histogram exists if (!hist_data) continue; // get histogram for uncertainty band TH2D* hist_uncbandexp = channel->GetHistUncertaintyBandExpectation(); // check if histogram exists if (!hist_uncbandexp) continue; // get number of bins in data int nbins = hist_data->GetNbinsX(); // loop over all bins for (int ibin = 1; ibin <= nbins; ++ibin) { // get expectation value double expectation = Expectation(ichannel, ibin, fMCMCx); // fill uncertainty band on expectation hist_uncbandexp->Fill(hist_data->GetBinCenter(ibin), expectation); } } }
int BCMTF::PrintStack | ( | int | channelindex, | |
const std::vector< double > & | parameters, | |||
const char * | filename = "stack.eps" , |
|||
const char * | options = "e1b0stack" | |||
) |
Print the stack of templates together with the data in a particular channel. Several plot options are available:
"logx" : plot the x-axis on a log scale
"logy" : plot the y-axis on a log scale
"bw" : plot in black and white
"sum" : draw a line corresponding to the sum of all templates
"stack" : draw the templates as a stack
"e0" : do not draw error bars
"e1" : draw error bars corresponding to sqrt(n)
"b0" : draw an error band on the expectation corresponding to the central 68% probability
"b1" : draw bands showing the probability to observe a certain number of events given the expectation. The green (yellow, red) bands correspond to the central 68% (95%, 99.8%) probability
channelindex | The channel index. | |
parameters | A reference to the parameters used to scale the templates. | |
options | The plotting options. |
Definition at line 755 of file BCMTF.cxx.
{ // todo: // - remove x-error on data points // - use hatched fill for error band // check if parameters are filled if (!parameters.size()) return -1; // check options bool flag_logx = false; // plot x-axis in log-scale bool flag_logy = false; // plot y-axis in log-scale bool flag_bw = false; // plot in black and white bool flag_sum = false; // plot sum of all templates bool flag_stack = false; // plot stack of templates bool flag_e0 = false; // do not draw error bars on data bool flag_e1 = false; // draw sqrt(N) error bars on data bool flag_b0 = false; // draw an error band on the expectation bool flag_b1 = false; // draw an error band on the number of events if (std::string(options).find("logx") < std::string(options).size()) flag_logx = true; if (std::string(options).find("logy") < std::string(options).size()) flag_logy = true; if (std::string(options).find("bw") < std::string(options).size()) flag_bw = true; if (std::string(options).find("sum") < std::string(options).size()) flag_sum = true; if (std::string(options).find("stack") < std::string(options).size()) flag_stack = true; if (std::string(options).find("e0") < std::string(options).size()) flag_e0 = true; if (std::string(options).find("e1") < std::string(options).size()) flag_e1 = true; if (std::string(options).find("b0") < std::string(options).size()) flag_b0 = true; if (std::string(options).find("b1") < std::string(options).size()) flag_b1 = true; if (!flag_e0) flag_e1=true; // get channel BCMTFChannel * channel = GetChannel(channelindex); // create canvas TCanvas * c1 = new TCanvas(); c1->cd(); // set log or linear scale if (flag_logx) c1->SetLogx(); if (flag_logy) c1->SetLogy(); // get data histogram TH1D* hist_data = channel->GetData()->GetHistogram(); // get number of bins int nbins = hist_data->GetNbinsX(); // define sum of templates TH1D* hist_sum = new TH1D(*hist_data); hist_sum->SetLineColor(kBlack); for (int i = 1; i <= nbins; ++i) hist_sum->SetBinContent(i, 0); // define error band TH1D* hist_error_band = new TH1D(*hist_data); hist_error_band->SetFillColor(kBlack); hist_error_band->SetFillStyle(3005); hist_error_band->SetLineWidth(1); hist_error_band->SetStats(kFALSE); hist_error_band->SetMarkerSize(0); TGraphAsymmErrors * graph_error_exp = new TGraphAsymmErrors(nbins); // graph_error_exp->SetLineWidth(2); graph_error_exp->SetMarkerStyle(0); graph_error_exp->SetFillColor(kBlack); graph_error_exp->SetFillStyle(3005); // get histogram for uncertainty band TH2D* hist_uncbandexp = channel->GetHistUncertaintyBandExpectation(); // fill error band if (flag_b0) { for (int i = 1; i <= nbins; ++i) { TH1D * proj = hist_uncbandexp->ProjectionY("_py", i, i); if (proj->Integral() > 0) proj->Scale(1.0 / proj->Integral()); double quantiles[3]; double sums[3] = {0.16, 0.5, 0.84}; proj->GetQuantiles(3, quantiles, sums); graph_error_exp->SetPoint(i-1, hist_data->GetBinCenter(i), quantiles[1]); graph_error_exp->SetPointError(i-1, 0.0, 0.0, quantiles[1] - quantiles[0], quantiles[2]-quantiles[1]); hist_error_band->SetBinContent(i, 0.5*(quantiles[2]+quantiles[0])); hist_error_band->SetBinError(i, 0, 0.5*(quantiles[2]-quantiles[0])); delete proj; } } // create stack THStack * stack = new THStack("", ""); // create a container of temporary histograms std::vector<TH1D *> histcontainer; // get number of templates unsigned int ntemplates = GetNProcesses(); // loop over all templates for (unsigned int i = 0; i < ntemplates; ++i) { // get histogram TH1D * temphist = channel->GetTemplate(i)->GetHistogram(); // get function container std::vector<TF1 *> * funccont = channel->GetTemplate(i)->GetFunctionContainer(); // create new histogram TH1D * hist(0); if (temphist) hist = new TH1D( *(temphist) ); else if (funccont) hist = new TH1D( *(channel->GetData()->GetHistogram())); else continue; if (flag_bw) { hist->SetFillColor(0); hist->SetLineWidth(1); hist->SetLineStyle(int(1+i)); } else { hist->SetFillColor(2 + i); hist->SetFillStyle(1001); } // scale histogram for (int ibin = 1; ibin <= nbins; ++ibin) { // get efficiency double efficiency = Efficiency(channelindex, i, ibin, parameters); // get probability double probability = Probability(channelindex, i, ibin, parameters); // get parameter index int parindex = GetParIndexProcess(i); // add to expectation double expectation = parameters[parindex] * efficiency * probability; // set bin content hist->SetBinContent(ibin, expectation); // add bin content hist_sum->SetBinContent(ibin, hist_sum->GetBinContent(ibin) + expectation); } // add histogram to container (for memory management) histcontainer.push_back(hist); // add histogram to stack stack->Add(hist); } //draw data hist_data->Draw("P0"); // set range user hist_data->GetYaxis()->SetRangeUser(channel->GetRangeYMin(), channel->GetRangeYMax()); // draw stack if (flag_stack) stack->Draw("SAMEHIST"); // draw error band on number of observed events if (flag_b1) { channel->CalculateUncertaintyBandPoisson(0.001, 0.999, kRed)->Draw("SAMEE2"); channel->CalculateUncertaintyBandPoisson(0.023, 0.977, kOrange)->Draw("SAMEE2"); channel->CalculateUncertaintyBandPoisson(0.159, 0.841, kGreen)->Draw("SAMEE2"); } // draw error band on expectation if (flag_b0) { hist_error_band->Draw("SAMEE2"); } if (flag_sum) hist_sum->Draw("SAME"); //draw data again if (flag_e0) hist_data->Draw("SAMEP0"); if (flag_e1) hist_data->Draw("SAMEP0E"); // redraw the axes gPad->RedrawAxis(); // print c1->Print(filename); // free memory for (unsigned int i = 0; i < histcontainer.size(); ++i) { TH1D * hist = histcontainer.at(i); delete hist; } delete stack; delete c1; delete graph_error_exp; delete hist_error_band; delete hist_sum; // no error return 1; }
int BCMTF::PrintStack | ( | const char * | channelname, | |
const std::vector< double > & | parameters, | |||
const char * | filename = "stack.eps" , |
|||
const char * | options = "e1b0stack" | |||
) |
Print the stack of templates together with the data in a particular channel.
channelname | The name of the channel. | |
parameters | A reference to the parameters used to scale the templates. | |
options | The plotting options. |
Definition at line 747 of file BCMTF.cxx.
{ int index = GetChannelIndex(channelname); return PrintStack(index, parameters, filename, options); }
int BCMTF::PrintSummary | ( | const char * | filename = "summary.txt" |
) |
Print a summary of the fit into an ASCII file.
filename | The name of the file. |
Definition at line 552 of file BCMTF.cxx.
{ // open file std::ofstream ofi(filename); ofi.precision(3); // check if file is open if(!ofi.is_open()) { BCLog::OutWarning(Form("BCMultitemplateFitter::PrintSummary() : Could not open file %s", filename)); return 0; } ofi << " Multi template fitter summary " << std::endl << " ----------------------------- " << std::endl << std::endl << " Number of channels : " << fNChannels << std::endl << " Number of processes : " << fNProcesses << std::endl << " Number of systematics : " << fNSystematics << std::endl << std::endl; ofi << " Channels :" << std::endl; for (int i = 0; i < GetNChannels(); ++i) { ofi << " " << i << " : \"" << GetChannel(i)->GetName().c_str() << "\"" << std::endl; } ofi << std::endl; ofi << " Processes :" << std::endl; for (int i = 0; i < GetNProcesses(); ++i) { ofi << " " << i << " : \"" << GetProcess(i)->GetName().c_str() << "\"" << " (par index " << GetParIndexProcess(i) << ")" << std::endl; } ofi << std::endl; ofi << " Systematics :" << std::endl; for (int i = 0; i < GetNSystematics(); ++i) { ofi << " " << i << " : \"" << GetSystematic(i)->GetName().c_str() << "\"" << " (par index " << GetParIndexSystematic(i) << ")" << std::endl; } ofi << std::endl; if (GetNSystematics() == 0) ofi << " - none - " << std::endl; ofi << " Goodness-of-fit: " << std::endl; for (int i = 0; i < GetNChannels(); ++i) { ofi << " i : \"" << GetChannel(i)->GetName().c_str() << "\" : chi2 = " << CalculateChi2( i, GetBestFitParameters() ) << std::endl; } ofi << std::endl; // close file ofi.close(); // no error return 1; }
double BCMTF::Probability | ( | int | channelindex, | |
int | processindex, | |||
int | binindex, | |||
const std::vector< double > & | parameters | |||
) |
Return the probability for a process in a channel and for a particular bin. This corresponds to the (normalized) bin content of the template.
channelindex | The channel index. | |
processindex | The process index. | |
binindex | The bin index. | |
parameters | A reference to the parameters used to calculate the probability. |
Definition at line 726 of file BCMTF.cxx.
{ // get histogram TH1D * hist = fChannelContainer[channelindex]->GetTemplate(processindex)->GetHistogram(); // get function container std::vector<TF1 *> * funccont = fChannelContainer[channelindex]->GetTemplate(processindex)->GetFunctionContainer(); // this needs to be fast if (!hist && !(funccont->size()>0)) return 0.; if (hist) return hist->GetBinContent(binindex); else { int parindex = fProcessParIndexContainer[processindex]; return funccont->at(binindex-1)->Eval(parameters[parindex]); } }
int BCMTF::SetData | ( | const char * | channelname, | |
TH1D | hist, | |||
double | minimum = -1 , |
|||
double | maximum = -1 | |||
) |
Set the data histogram in a particular channel.
channelname | The name of the channel. | |
hist | The TH1D histogram. | |
minimum | The minimum number of expected events (used for calculation of uncertainty bands). | |
maximum | The maximum number of expected events (used for calculation of uncertainty bands). |
Definition at line 199 of file BCMTF.cxx.
{ int channelindex = GetChannelIndex(channelname); // check if channel exists if (channelindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist."); return -1; } // get channel BCMTFChannel * channel = GetChannel(channelindex); // get template BCMTFTemplate * data = channel->GetData(); // remove statistics box hist.SetStats(kFALSE); // set marker hist.SetMarkerStyle(20); hist.SetMarkerSize(1.1); // set divisions hist.SetNdivisions(509); // remove old data set if it exists if (data->GetHistogram()) { delete data->GetHistogram(); data->SetHistogram(0); } // remove old uncertainty histograms if they exist if (channel->GetHistUncertaintyBandExpectation()) { delete channel->GetHistUncertaintyBandExpectation(); channel->SetHistUncertaintyBandExpectation(0); } if (channel->GetHistUncertaintyBandPoisson()) { delete channel->GetHistUncertaintyBandPoisson(); channel->SetHistUncertaintyBandPoisson(0); } // create new histograms for uncertainty bands // double minimum = floor(TMath::Max(0., hist.GetMinimum() - 7.*sqrt(hist.GetMinimum()))); if (minimum==-1) minimum = 0; if (maximum==-1) maximum = ceil(hist.GetMaximum() + 5.*sqrt(hist.GetMaximum())); std::vector<double> a(hist.GetNbinsX()+1); for (int i = 0; i < hist.GetNbinsX()+1; ++i) { a[i] = hist.GetXaxis()->GetBinLowEdge(i+1); } TH2D* hist_uncbandexp = new TH2D(TString::Format("UncertaintyBandExpectation_%i", BCLog::GetHIndex()), "", hist.GetNbinsX(), &a[0], 1000, minimum, maximum); hist_uncbandexp->SetStats(kFALSE); TH2D* hist_uncbandpoisson = new TH2D(TString::Format("UncertaintyBandPoisson_%i", BCLog::GetHIndex()), "", hist.GetNbinsX(), &a[0], int(maximum-minimum), minimum, maximum); hist_uncbandpoisson->SetStats(kFALSE); // set histograms data->SetHistogram(new TH1D(hist)); channel->SetHistUncertaintyBandExpectation(hist_uncbandexp); channel->SetHistUncertaintyBandPoisson(hist_uncbandpoisson); // set y-range for printing channel->SetRangeY(minimum, maximum); // no error return 1; }
void BCMTF::SetExpectationFunction | ( | int | parindex, | |
TF1 * | func | |||
) | [inline] |
Set an expectation function.
parindex | The index of the parameter | |
func | The pointer to a TF1 function. |
Definition at line 166 of file BCMTF.h.
{ fExpectationFunctionContainer[parindex] = func; };
void BCMTF::SetFlagEfficiencyConstraint | ( | bool | flag | ) | [inline] |
Set a flag for the efficiency: if true then the total efficiency including all systematic uncertainties has to be between 0 and 1 at all times. Larger (smaller) values are set to 1 (0) during the calculation.
flag | The flag |
Definition at line 221 of file BCMTF.h.
{ fFlagEfficiencyConstraint = flag; };
int BCMTF::SetSystematicVariation | ( | const char * | channelname, | |
const char * | processname, | |||
const char * | systematicname, | |||
TH1D | hist_up, | |||
TH1D | hist_down | |||
) |
Set the impact of a source of systematic uncertainty for a particular source of systematic uncertainty and process in a given channel. The variation depends on x and is given as a histogram.
channelname | The name of the channel. | |
processname | The name of the process. | |
systematicname | The name of the source of systematic uncertainty. | |
hist_up | The TH1D histogram defining the relative shift between the up-variation and the nominal template: (up-nom)/nom. | |
hist_down | The TH1D histogram defining the relative shift between the down-variation and the nominal template: (nom-down)/nom. |
Definition at line 490 of file BCMTF.cxx.
{ // get channel index int channelindex = GetChannelIndex(channelname); // check if channel exists if (channelindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist."); return -1; } // get process index int processindex = GetProcessIndex(processname); // check if process exists if (processindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist."); return -1; } // get systematic index int systematicindex = GetSystematicIndex(systematicname); // check if systematic exists if (systematicindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Systematic does not exist."); return -1; } // get channel BCMTFChannel * channel = GetChannel(channelindex); // get systematic variation BCMTFSystematicVariation * variation = channel->GetSystematicVariation(systematicindex); // set histogram variation->SetHistograms(processindex, new TH1D(hist_up), new TH1D(hist_down)); // no error return 1; }
int BCMTF::SetSystematicVariation | ( | const char * | channelname, | |
const char * | processname, | |||
const char * | systematicname, | |||
TH1D | hist, | |||
TH1D | hist_up, | |||
TH1D | hist_down | |||
) |
Set the impact of a source of systematic uncertainty for a particular source of systematic uncertainty and process in a given channel. The variation depends on x. The histograms are the raw histograms after the shift and the variation wrt the nominal template will be calculated automatically.
channelname | The name of the channel. | |
processname | The name of the process. | |
systematicname | The name of the source of systematic uncertainty. | |
hist | The histogram with the nominal template | |
hist_up | The TH1D histogram after up-scaling of the systematic uncertainty. | |
hist_down | The TH1D histogram after down-scaling of the systematic uncertainty. |
Definition at line 533 of file BCMTF.cxx.
{ // get number of bins int nbins = hist.GetNbinsX(); TH1D * hist_up_rel = new TH1D(hist); TH1D * hist_down_rel = new TH1D(hist); // loop over all bins for (int ibin = 1; ibin <= nbins; ++ibin) { hist_up_rel->SetBinContent(ibin, (hist_up.GetBinContent(ibin) - hist.GetBinContent(ibin)) / hist.GetBinContent(ibin)); hist_down_rel->SetBinContent(ibin, (hist.GetBinContent(ibin) - hist_down.GetBinContent(ibin)) / hist.GetBinContent(ibin)); } // set the systematic variation return SetSystematicVariation(channelname, processname, systematicname, *hist_up_rel, *hist_down_rel); }
int BCMTF::SetSystematicVariation | ( | const char * | channelname, | |
const char * | processname, | |||
const char * | systematicname, | |||
double | variation_up, | |||
double | variation_down | |||
) |
Set the impact of a source of systematic uncertainty for a particular source of systematic uncertainty and process in a given channel. The impact is the relative deviation between the varied and the nominal template, i.e., if the variation is set to 0.05 then the efficiency is multiplied by (1+0.05*eps), where eps is the corresponding nuisance parameter.
channelname | The name of the channel. | |
processname | The name of the process. | |
systematicname | The name of the source of systematic uncertainty. | |
variation_up | The relative shift between the up-variation and the nominal template: (up-nom)/nom. | |
variation_down | The relative shift between the down-variation and the nominal template: (nom-down)/nom. |
Definition at line 431 of file BCMTF.cxx.
{ // get channel index int channelindex = GetChannelIndex(channelname); // check if channel exists if (channelindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist."); return -1; } // get process index int processindex = GetProcessIndex(processname); // check if process exists if (processindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist."); return -1; } // get systematic index int systematicindex = GetSystematicIndex(systematicname); // check if systematic exists if (systematicindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Systematic does not exist."); return -1; } // get channel BCMTFChannel * channel = GetChannel(channelindex); BCMTFTemplate * bctemplate = channel->GetTemplate(processindex); TH1D * hist_template = bctemplate->GetHistogram(); TH1D hist_up = TH1D(*hist_template); TH1D hist_down = TH1D(*hist_template); int nbins = hist_up.GetNbinsX(); // loop over all bins for (int ibin = 1; ibin <= nbins; ++ibin) { hist_up.SetBinContent(ibin, variation_up); hist_down.SetBinContent(ibin, variation_down); } // get systematic variation BCMTFSystematicVariation * variation = channel->GetSystematicVariation(systematicindex); // set histogram variation->SetHistograms(processindex, new TH1D(hist_up), new TH1D(hist_down)); // no error return 1; }
int BCMTF::SetTemplate | ( | const char * | channelname, | |
const char * | processname, | |||
TH1D | hist, | |||
double | efficiency = 1. | |||
) |
Set the template for a specific process in a particular channel.
channelname | The name of the channel. | |
processname | The name of the process. | |
hist | The TH1D histogram. | |
efficiency | The efficiency of this process in this channel. |
Definition at line 111 of file BCMTF.cxx.
{ // get channel index int channelindex = GetChannelIndex(channelname); // check if channel exists if (channelindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist."); return -1; } // get process index int processindex = GetProcessIndex(processname); // check if process exists if (processindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist."); return -1; } // get channel BCMTFChannel * channel = GetChannel(channelindex); // get template BCMTFTemplate * bctemplate = channel->GetTemplate(processindex); // normalize histogram if (hist.Integral()) hist.Scale(1.0 / hist.Integral()); // remove statistics box hist.SetStats(kFALSE); // set color and fill style hist.SetFillColor(2 + processindex); hist.SetFillStyle(1001); // create new histogram TH1D * temphist = new TH1D(hist); // set histogram bctemplate->SetHistogram(temphist); // set efficiency bctemplate->SetEfficiency(efficiency); // no error return 1; }
int BCMTF::SetTemplate | ( | const char * | channelname, | |
const char * | processname, | |||
std::vector< TF1 * > * | funccont, | |||
int | nbins, | |||
double | efficiency = 1. | |||
) |
Set the template for a specific process in a particular channel. This is an alternative way to describe the number of expected events. It is used in the rare case that processes cannot be summed directly, but interference effects have to be taken into account. The expected number of events is then parametrized as a function for each bin.
channelname | The name of the channel. | |
processname | The name of the process. | |
funccont | A vector of pointers of TF1 functions. | |
nbins | The number of bins used for the histogram. | |
efficiency | The efficiency of this process in this channel. |
Definition at line 162 of file BCMTF.cxx.
{ // get channel index int channelindex = GetChannelIndex(channelname); // check if channel exists if (channelindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Channel does not exist."); return -1; } // get process index int processindex = GetProcessIndex(processname); // check if process exists if (processindex < 0) { BCLog::OutWarning("BCMultitemplateFitter::SetTemplate() : Process does not exist."); return -1; } // get channel BCMTFChannel * channel = GetChannel(channelindex); // get template BCMTFTemplate * bctemplate = channel->GetTemplate(processindex); // set histogram bctemplate->SetFunctionContainer(funccont, nbins); // set efficiency bctemplate->SetEfficiency(efficiency); // no error return 1; }
std::vector<BCMTFChannel *> BCMTF::fChannelContainer [private] |
std::vector<TF1 *> BCMTF::fExpectationFunctionContainer [private] |
bool BCMTF::fFlagEfficiencyConstraint [private] |
int BCMTF::fNChannels [private] |
int BCMTF::fNProcesses [private] |
int BCMTF::fNSystematics [private] |
std::vector<BCMTFProcess *> BCMTF::fProcessContainer [private] |
std::vector<int> BCMTF::fProcessParIndexContainer [private] |
std::vector<BCMTFSystematic *> BCMTF::fSystematicContainer [private] |
std::vector<int> BCMTF::fSystematicParIndexContainer [private] |