Angular analysis of B+->K*+(K+pi0)mumu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1324 lines
67 KiB

//Renata Kopecna
#include <momfit.hh>
#include <fitter.hh>
#include <folder.hh>
#include <paths.hh>
#include <funcs.hh>
#include <design.hh>
#include <event.hh>
#include <constants.hh>
#include <bu2kstarmumu_pdf.hh>
#include <bu2kstarmumu_plotter.hh>
#include <bu2kstarmumu_parameters.hh>
#include <bu2kstarmumu_generator.hh>
#include <spdlog.h>
#include <TRandom3.h>
#include <TTree.h>
//background coefficients, obtained from fits to the sideband data of the rare channel (David thinks)
//4 cause David had 4 PDFs
const double Bctl1[4] = { 0.11700, -0.0568, 0.0367, 0.0160};
const double Bctl2[4] = {-0.0697, -0.1243, -0.0788, -0.1197};
const double Bctk1[4] = { 0.0720, 0.4544, 0.0761, 0.2105};
const double Bctk2[4] = { 0.1652, 0.2065, 0.1177, 0.1951};
//Obtained from MC //TODO //Taken from main fit, update when fixed
const double f_m_B[4] = {5282.32, 5282.08, 5278.57, 5279.48};
const double f_lambda1[4] = {-0.00386, -0.00610, -0.00362, -0.00578};
const double f_lambda2[4] = {-0.03320, -0.00120, -0.04600, -0.00100};
const double f_alpha_1[4] = { 1.7910, 1.8000, 1.6510, 1.5400};
const double f_alpha_2[4] = { 2.3200, 2.4300, 2.0100, 2.2500};
const double f_n_1[4] = { 1.4400, 1.4900, 1.6800, 1.6100};
const double f_n_2[4] = { 2.8900, 3.7000, 3.8700, 3.7000};
const double f_sigma_1[4] = {14.8300, 15.4800, 14.8400, 14.4};
const double f_sigma_2[4] = {14.0700, 13.1000, 15.6200, 13.3};
const double f_f_CB[4] = { 0.6360, 0.3600, 0.3040, 0.6200};
const double f_m_scale[4] = { 1.1814, 1.0648, 1.1547, 1.1168};
//Obtained from MC //TODO //Taken from main fit, update when fixed
///including the first q2bin: //TODO: get from my MC
const std::vector<double> FL_scale = {0.4836193455050577, 1.2251014138607774, 1.274499551405837, 1.1368614009399862};
//Obtained from MC //TODO //Taken from main fit, update when fixed
const std::vector<double> FL_scale_toys = { //TODO Get from my MC!
0.5, //scaled from average of bin 1-4
1.0 + 0.07 / (61.*4) * (61.+ 62.+ 96.+ 125.),
1.0 + 0.12 / (62.*4) * (61.+ 62.+ 96.+ 125.),
1.0 - 0.02 / (96.*4) * (61.+ 62.+ 96.+ 125.),
1.0 - 0.17 / (125.*4) * (61.+ 62.+ 96.+ 125.),
1.0,//evaluated by itself
1.0 + 0.04 / (129. * 2) * (129. + 69.),
1.0 - 0.04 / (69. * 2) * (129. + 69.),
};
//TODO: not used at the moment, check for constants and everything before usage
int momfit(fcnc::options opts,
bool fitReference, bool fitSignalMC, bool fitData, bool blind,
bool Fit1bin, bool Fit2bins, bool FitAllbins){
if (fitReference) spdlog::info("[MOM]\t\tMoM from reference channel: J/psi K*+");
// (jobs_to_do[7]) //reference channel only
if (fitSignalMC) spdlog::info("[MOM]\t\tMoM from signal fitSignalMC");
//if(jobs_to_do[8]) //signal fitSignalMC only
if (fitData) spdlog::info("[MOM]\t\tMoM signal data");
// if(jobs_to_do[9]) //signal data << FINAL FIT!!
//const bool blind = jobs_to_do[9];
//have extra option for the usage of binning:
const bool SimultaneousMoM = fitReference;
const bool SimultaneousFit = true;
const bool UseAccPerRun = true;
const bool UseAccPer2Years = true;
const bool LargeBinning = !fitSignalMC && !fitReference && !fitData;
const bool WeightedFit = true;
const bool OnlyBackground = false;
const bool OnlySignal = false;
const bool OneFit = !fitSignalMC && !fitReference && !SimultaneousFit;
const bool FitR = fitReference;
const bool SystematicsWithToys = opts.systematic == 0;
if (!fitSignalMC && SystematicsWithToys){
spdlog::critical("Cannot run data AND generate toys for systematics!");
return 2; //TODO: decide what error is for wrong parameters
}
const bool FitFinalToySamples = false;
const bool FSfrom2DLargeBins = !fitSignalMC && !fitReference && !LargeBinning && !SystematicsWithToys && !FitFinalToySamples;
const bool UseExternalFS = true;
const bool FixFStoStart = false;
const bool FitOnlyMagDown = opts.job_id == 3 && !SystematicsWithToys;
const bool FitOnlyMagUp = opts.job_id == 4 && !SystematicsWithToys;
const bool LargerMKpiRange = false;
const bool NP = false;
//TODO: big time, go through the couts and the constants here
if(!fitReference && !fitSignalMC) opts.plots_m_bins = 50;
assert(!OneFit || !SimultaneousMoM);
if(fitReference){
opts.TheQ2binsmin = {8.68};
opts.TheQ2binsmax = {10.09};
}
else if(LargeBinning){
opts.TheQ2binsmin = {1.0, 11.0, 15.0};
opts.TheQ2binsmax = {8.0, 12.5, 19.0};
}
if(fitSignalMC && !fitReference){ //Fit also Jpsi region in fitSignalMC
opts.TheQ2binsmin.push_back(8.68);
opts.TheQ2binsmax.push_back(10.09);
}
if(LargerMKpiRange){
opts.mkpi_min -= 50.;
opts.mkpi_max += 50.;
}
opts.write_eps = !(FitOnlyMagDown || FitOnlyMagUp || SystematicsWithToys || FitFinalToySamples);
opts.write_C = !(FitOnlyMagDown || FitOnlyMagUp || SystematicsWithToys || FitFinalToySamples);
//configurate for 2D mass fit to obtain sWeights
opts.only_mass2DFit = true;
opts.only_angles = false;
opts.only_Bmass = false;
opts.squared_hesse = !fitData;
opts.minos_errors = false;
opts.weighted_fit = WeightedFit;
opts.fit_mkpi = true;
opts.use_mkpi = false;
opts.generate_mkpi = true;
opts.simple_mkpi = false;
opts.isobar = false;
opts.shift_lh = false;
opts.swave = (opts.use_mkpi || opts.fit_mkpi) && !(fitSignalMC || OnlyBackground);
opts.extended_ml = !fitSignalMC && !OnlyBackground && !OnlySignal; //extended maximum likelyhood
//Needed for sWeights
opts.fit_fl = !fitData && SystematicsWithToys;
opts.fit_afb = opts.fit_fl;
opts.full_angular = true;
//how many individual pdfs are used?
const UInt_t nPDFs = 2;
std::vector< std::string > samplename;
samplename.push_back("Run1 DD"); //TODO
samplename.push_back("Run1 LL");
samplename.push_back("Run2 DD");
samplename.push_back("Run2 LL");
//load events from data tuple:
std::vector<fcnc::event>events[nPDFs];
//TODO
if(FitFinalToySamples){
events[0] = fcnc::load_events(get_finalToySamplePath(0,opts.job_id,fitReference), "Events", -1); //Run1
events[1] = fcnc::load_events(get_finalToySamplePath(1,opts.job_id,fitReference), "Events", -1); //Run2
}
else{
events[0] = fcnc::load_events(get_theFCNCpath(fitSignalMC,1), "Events", -1); //Run1
events[1] = fcnc::load_events(get_theFCNCpath(fitSignalMC,2), "Events", -1); //Run2
}
spdlog::info("Events:");
for(UInt_t n = 0; n < nPDFs; n++){
std::cout << samplename.at(n) << ":\t" << (blind ? "Larger 1 " : std::to_string(events[n].size())) << std::endl;
assert(events[n].size() || SystematicsWithToys);
}
TRandom3 * rnd = new TRandom3(0);
//determine number of bins:
const UInt_t nBins = opts.TheQ2binsmin.size();
std::vector<int>fit_results[nBins];
std::vector<double>fitted_FS[nBins];
std::vector<double>fitted_FSerr[nBins];
std::vector<double>fitted_FSerrUp[nBins];
std::vector<double>fitted_FSerrDown[nBins];
//signal event number estimations:
double N_sig_Rare[8] = {101., 61., 62., 96., 125., 124., 129., 69.};
double N_bkg_Rare[8] = {131., 206., 279., 358., 358., 247., 158., 93.};
//estimation of how many events lie within each sub-set: Run I DD, Run I LL, Run II DD, Run II LL. taken from jpsi!
double ev_frac[4] = {0.14, 0.09, 0.46, 0.30};
if(OneFit)
ev_frac[0] = 1.0;
//TODO whyyyy is this all here
std::vector<double> s1s, s1c, s2s, s2c, s3, s4, s5, s6s, s6c, s7, s8, s9;
if(nBins == 9){
s1s = { 0.5010, 0.1660, 0.1270, 0.1760, 0.2570, 0.3910, 0.4670, 0.4930, 0.329};
s1c = { 0.2450, 0.6996, 0.7993, 0.7384, 0.6414, 0.4201, 0.3513, 0.3344, 0.000};
s2s = { 0.1448, 0.0749, 0.0514, 0.0662, 0.0900, 0.1449, 0.1620, 0.1662, 0.000};
s2c = {-0.1953,-0.6639,-0.7774,-0.7254,-0.6334,-0.4171,-0.3497,-0.3332, 0.000};
s3 = { 0.0110,-0.0030, 0.0010,-0.0100,-0.0330,-0.0520,-0.1460,-0.2240,-0.006};
s4 = { 0.0050, 0.0100,-0.1140,-0.1970,-0.2530,-0.2620,-0.2910,-0.2980,-0.244};
s5 = { 0.2330, 0.0730,-0.1630,-0.3100,-0.4130,-0.4430,-0.3410,-0.2570, 0.000};
s6s = {-0.0650,-0.1950,-0.0860, 0.0950, 0.2930, 0.4920, 0.5410, 0.4650, 0.000};
s6c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.000};
s7 = { 0.0030, 0.0350, 0.0120, 0.0080,-0.0110, 0.0150,-0.0140, 0.0130, 0.000};
s8 = {-0.0050, 0.0060,-0.0040,-0.0050,-0.0120, 0.0160, 0.0010, 0.0060,-0.060};
s9 = {-0.0220, 0.0010,-0.0020,-0.0090, 0.0130, 0.0010, 0.0100, 0.0000,-0.084};
}
else if(nBins == 8){
//results from signal channel generator level fitSignalMC fit
s1s = { 0.5120, 0.1800, 0.1370, 0.1930, 0.2750, 0.4170, 0.4840, 0.5030};
s1c = { 0.2450, 0.6996, 0.7993, 0.7384, 0.6414, 0.4201, 0.3513, 0.3344};
s2s = { 0.1448, 0.0749, 0.0514, 0.0662, 0.0900, 0.1449, 0.1620, 0.1662};
s2c = {-0.1953,-0.6639,-0.7774,-0.7254,-0.6334,-0.4171,-0.3497,-0.3332};
s3 = { 0.0000, 0.0020,-0.0080,-0.0120,-0.0240,-0.0620,-0.1520,-0.2330};
s4 = { 0.0870, 0.0040,-0.1080,-0.1950,-0.2510,-0.2770,-0.2900,-0.3040};
s5 = { 0.2440, 0.0950,-0.1590,-0.3050,-0.4140,-0.4210,-0.3400,-0.2490};
s6s = {-0.1270,-0.2070,-0.0860, 0.0950, 0.3020, 0.5140, 0.5570, 0.4700};
s6c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
s7 = {-0.0060,-0.0100,-0.0030, 0.0020, 0.0030,-0.0020,-0.0020, 0.0050};
s8 = { 0.0010,-0.0030,-0.0040,-0.0030,-0.0010, 0.0030,-0.0010, 0.0030};
s9 = {-0.0020, 0.0000, 0.0020, 0.0040,-0.0020,-0.0010,-0.0010, 0.0010};
/* OLD MoM start values
s1s = { 0.5010, 0.1660, 0.1270, 0.1760, 0.2570, 0.3910, 0.4670, 0.4930};
s1c = { 0.2450, 0.6996, 0.7993, 0.7384, 0.6414, 0.4201, 0.3513, 0.3344};
s2s = { 0.1448, 0.0749, 0.0514, 0.0662, 0.0900, 0.1449, 0.1620, 0.1662};
s2c = {-0.1953,-0.6639,-0.7774,-0.7254,-0.6334,-0.4171,-0.3497,-0.3332};
s3 = { 0.0110,-0.0030, 0.0010,-0.0100,-0.0330,-0.0520,-0.1460,-0.2240};
s4 = { 0.0050, 0.0100,-0.1140,-0.1970,-0.2530,-0.2620,-0.2910,-0.2980};
s5 = { 0.2330, 0.0730,-0.1630,-0.3100,-0.4130,-0.4430,-0.3410,-0.2570};
s6s = {-0.0650,-0.1950,-0.0860, 0.0950, 0.2930, 0.4920, 0.5410, 0.4650};
s6c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
s7 = { 0.0030, 0.0350, 0.0120, 0.0080,-0.0110, 0.0150,-0.0140, 0.0130};
s8 = {-0.0050, 0.0060,-0.0040,-0.0050,-0.0120, 0.0160, 0.0010, 0.0060};
s9 = {-0.0220, 0.0010,-0.0020,-0.0090, 0.0130, 0.0010, 0.0100, 0.0000};
*/
//TODO whyyyy is this all here
if(NP){
s1s = {0.5602306113691828,0.23270880313206915,0.1882591401081556,0.2360087282257996,0.3049337611889009,0.4271747118350757,0.49093645131734026,0.5057945417334112};
s1c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
s2s = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
s2c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
s3 = {0.010889127654682522,0.002826464227113492,-0.009846207821458525,-0.0236075131233653,-0.03873716522303356,-0.08541706129465602,-0.17283544777091792,-0.2508649715871772};
s4 = {0.06515621731101214,-0.03441408879881635,-0.14972587209244403,-0.22058159609322783,-0.2569091889106349,-0.28043043274306023,-0.2933132627545414,-0.3090558271133447};
s5 = {0.28355403122517436,0.15060676750257493,-0.08697300891551848,-0.2453363631814247,-0.3317290913621316,-0.37328734325703,-0.28988943793825117,-0.20704345542879504};
s6s = {-0.14203502700533388,-0.2517350722752868,-0.12322680301923153,0.05716905988908093,0.22412264548364097,0.4666205500210169,0.48430363375918584,0.38863572446689215};
s6c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
s7 = {-0.018795316409125306,-0.023477089751902755,-0.019670089562814908,-0.015167436307089688,-0.010845329740737182,-0.002747600804479865,-0.0017200885766387283,-0.0006988704922596641};
s8 = {-0.010521697907580636,-0.008845120251655493,-0.005715190092060276,-0.004200375084315877,-0.0032359717141892687,0.0016256878486157777,0.0005880437600457862,0.00023165273472761083};
s9 = {-0.0006861229900257304,-0.0006888890894988537,-0.0006222598407671807,-0.0005993069103744563,-0.0006186949055500562,0.0006613554952330075,0.0004840128898600523,0.0003040455330802454};
}
}
else if(nBins == 3){
s1s = { 0.329, 0.329, 0.329};
s1c = { 0.0, 0.0, 0.0};
s2s = { 0.0, 0.0, 0.0};
s2c = { 0.0, 0.0, 0.0};
s3 = {-0.006, -0.006, -0.006};
s4 = {-0.244, -0.244, -0.244};
s5 = {-0.005, -0.005, -0.005};
s6s = {-0.002, -0.002, -0.002};
s6c = { 0.0, 0.0, 0.0};
s7 = { 0.000, 0.000, 0.000};
s8 = {-0.060, -0.060, -0.060};
s9 = {-0.084, -0.084, -0.084};
}
else if(nBins == 2){
s1s = { 0.1959, 0.4917};
s1c = { 0.7441, 0.3447};
s2s = { 0.0646, 0.1636};
s2c = {-0.7217, -0.3432};
s3 = {-0.0042, -0.1747};
s4 = { 0.1033, 0.2929};
s5 = {-0.1458, -0.3157};
s6s = { 0.0652, -0.5338};
s6c = { 0.0000, 0.0000};
s7 = { 0.0340, -0.0000};
s8 = {-0.0115, -0.0002};
s9 = { 0.0003, 0.0003};
}
else if(nBins == 1){
s1s = { 0.329};
s1c = { 0.0};
s2s = { 0.0};
s2c = { 0.0};
s3 = {-0.006};
s4 = {-0.244};
s5 = {-0.005};
s6s = {-0.002};
s6c = { 0.0};
s7 = { 0.000};
s8 = {-0.060};
s9 = {-0.084};
}
else{
spdlog::error("No init values found for S_i in binning scheme with number of q2 bins: {0:d}", nBins);
assert(0);
}
//current fitter, plotter, parameteres and pdfs:
fcnc::fitter f(&opts);
fcnc::folder fldr(&opts);
fcnc::options theOptions[nPDFs];
fcnc::bu2kstarmumu_plotter * thePlotter[nPDFs];
std::vector<fcnc::parameters*> theParams [nBins];
std::vector<fcnc::parameters*> the2DParams [nBins];
std::vector<fcnc::pdf*> theProbs [nBins];
std::vector< std::vector<fcnc::event>* > selection[nBins];
std::vector<UInt_t> pdf_idx;
pdf_idx.push_back(0); //Run1 DD
pdf_idx.push_back(1); //Run1 LL
pdf_idx.push_back(2); //Run2 DD
pdf_idx.push_back(3); //Run2 LL
//set parameter FS common:
std::vector<std::string> common_params;
common_params.push_back("FS");
if(FitR)
common_params.push_back("R");
if(!fitReference){
common_params.push_back("gamkst");
common_params.push_back("mkst");
}
f.set_common_parameters(common_params);
for(UInt_t n = 0; n < nPDFs; n++){
theOptions[n] = opts;
theOptions[n].name = std::to_string(n+1);
theOptions[n].run = UseAccPerRun ? (n > 1 ? 2 : 1) : 12;
theOptions[n].DDLL = (n % 2 == 0) ? "DD" : "LL";
theOptions[n].update_angle_ranges();
thePlotter[n] = new fcnc::bu2kstarmumu_plotter(&theOptions[n]);
}
double sig_frac[nBins];
unsigned int event_numbers[nBins][4];
for(unsigned int b = 0; b < nBins; b++){
for(unsigned int n = 0; n < 4; n++){
//get event numbers and signal fraction from global function, given the total number of events
EventNumbers(b, n, sig_frac[b], event_numbers[b][n], 2597, nBins, 4);
if(OnlySignal)
event_numbers[b][n] *= sig_frac[b];
}
}
for(UInt_t b = 0; b < nBins; b++){
selection[b].clear();
for(UInt_t n = 0; n < nPDFs; n++){
//create parameter sets:
fcnc::bu2kstarmumu_parameters * leParameters = new fcnc::bu2kstarmumu_parameters(&theOptions[n]);
theOptions[n].q2_min = opts.TheQ2binsmin.at(b);
theOptions[n].q2_max = opts.TheQ2binsmax.at(b);
//create PDFs
fcnc::bu2kstarmumu_pdf * lePDF = new fcnc::bu2kstarmumu_pdf(&theOptions[n], leParameters);
//initiate parameters for mass fit
if(opts.extended_ml){
if(fitSignalMC){
spdlog::error("Never use extended_ml option for a pure signal sample, like in fitSignalMC!");
assert(0);
}
if(OnlyBackground){
spdlog::error("Never use extended_ml option for a pure background sample!");
assert(0);
}
else{
if((SystematicsWithToys || FitFinalToySamples) && !fitReference){
leParameters->n_sig.init(event_numbers[b][n]*sig_frac[b], event_numbers[b][n]*sig_frac[b]*0.2, event_numbers[b][n]*sig_frac[b]*5., 0.1);
leParameters->n_bkg.init(event_numbers[b][n]*(1.-sig_frac[b]), event_numbers[b][n]*(1.-sig_frac[b])*0.2, event_numbers[b][n]*(1.-sig_frac[b])*5., 0.1);
leParameters->f_sig.init(sig_frac[b], 0.0, 1.0, 0.0);
}
else if(fitData && !LargeBinning){
leParameters->n_sig.init(N_sig_Rare[b]*ev_frac[n], 0.0/*N_sig_Rare[b]*ev_frac[n]*0.2*/, N_sig_Rare[b]*ev_frac[n]*5., 0.1);
leParameters->n_bkg.init(N_bkg_Rare[b]*ev_frac[n], N_bkg_Rare[b]*ev_frac[n]*0.2, N_bkg_Rare[b]*ev_frac[n]*5., 0.1);
leParameters->f_sig.init(N_sig_Rare[b]*ev_frac[n]/(N_sig_Rare[b]*ev_frac[n]+N_bkg_Rare[b]*ev_frac[n]), 0.0, 1.0, 0.0);
}
else if(fitData && LargeBinning){
leParameters->n_sig.init(100., 5., 5000., 0.1);
leParameters->n_bkg.init(100., 5., 5000., 0.1);
leParameters->f_sig.init(0.5, 0.0, 1.0, 0.0);
}
else{
leParameters->n_sig.init(events[n].size() * 0.85, events[n].size() * 0.4, events[n].size() * 1.2, 0.1);
leParameters->n_bkg.init(events[n].size() * 0.15, events[n].size() * 0.01, events[n].size() * 0.5, 0.1);
leParameters->f_sig.init(0.5, 0.0, 1.0, 0.0);
}
}
}
else{
if(fitSignalMC || OnlySignal)
leParameters->f_sig.init(1.0, 0.0, 1.0, 0.0);
else if(OnlyBackground){
leParameters->f_sig.init(0.0, 0.0, 1.0, 0.0);
}
else
leParameters->f_sig.init(0.35, 0.0, 1.0, 0.01);
}
leParameters->m_b.init(f_m_B[n], B_MASS_LOW, B_MASS_HIGH, OnlyBackground ? 0.0 : 0.01);
if(opts.twotailedcrystalball)
leParameters->m_res_1.init(1.0, 0.0, 1.0, 0.0);
else
leParameters->m_res_1.init(f_f_CB[n], 0.0, 1.0, fitSignalMC ? 0.01 : 0.0);
if(leParameters->f_sig.get_value() != 1.0){
if(fitData || true){ //only use single exponential for all cases
leParameters->fm_tau.init(1.0, 0.0, 1.0, 0.0);
leParameters->m_lambda.init(f_lambda1[n], -1.0e-2, -1.0e-6, 1.0e-6);
leParameters->m_lambda_2.init(f_lambda2[n], -1.0e-2, -1.0e-6, 0.0);
}
else{
leParameters->fm_tau.init((n % 2 == 1) ? 1.0 : 0.8, 0.0, 1.0, (n % 2 == 1) ? 0.0 : 0.01);
leParameters->m_lambda.init(f_lambda1[n], -1.0e-1, -1.0e-6, 1.0e-6);
leParameters->m_lambda_2.init(f_lambda2[n], -1.0e-1, -1.0e-6, (n % 2 == 1) ? 0.0 : 1.0e-6);
}
leParameters->m_tau.init( 1./2.835e-3, 100.0, 1.0e+4, 0.0);
leParameters->m_tau_2.init(1./1.664e-3, 0.0, 1.0e+4, 0.0);
}
else{
leParameters->fm_tau.init(0.8, 0.0, 1.0, 0.0);
leParameters->m_lambda.init(-2.835e-3, -1.0e-1, -1.0e-6, 0.0);
leParameters->m_lambda_2.init(-1.664e-4, -1.0e-1, -1.0e-6, 0.0);
leParameters->m_tau.init( 1./2.835e-3, 100.0, 1.0e+4, 0.0);
leParameters->m_tau_2.init(6.01e+2, 0.0, 1.0e+4, 0.0);
}
if(opts.twotailedcrystalball)
leParameters->m_sigma_1.init(f_sigma_1[n], 5.0, 50.0, ((fitReference || fitSignalMC) && !OnlyBackground) ? 0.01 : 0.0);
else{
leParameters->m_sigma_1.init(f_sigma_1[n], 5.0, 50.0, ((fitReference || fitSignalMC) && !OnlyBackground) ? 0.01 : 0.0);
leParameters->m_sigma_2.init(f_sigma_2[n], 5.0, 50.0, ((fitReference || fitSignalMC) && !OnlyBackground) ? 0.01 : 0.0);
}
leParameters->alpha_1.init(f_alpha_1[n], 0.5, 5.0, fitSignalMC ? 0.0001 : 0.0);
leParameters->alpha_2.init(f_alpha_2[n], 0.5, 5.0, fitSignalMC ? 0.0001 : 0.0);
leParameters->n_1.init(f_n_1[n], 0.1, 50.0, fitSignalMC ? 0.001 : 0.0);
leParameters->n_2.init(f_n_2[n], 0.1, 50.0, fitSignalMC ? 0.001 : 0.0);
if(!fitReference && !fitSignalMC && !SystematicsWithToys)
leParameters->m_scale.init(f_m_scale[n], 0.0, 2.0, 0.0);
else
leParameters->m_scale.init(1.0, 0.0, 2.0, 0.0);
leParameters->eff_q2.init(0.5*(opts.TheQ2binsmin.at(b)+opts.TheQ2binsmax.at(b)), opts.TheQ2binsmin.front(), opts.TheQ2binsmax.back(), 0.0);
/*
if(!fitSignalMC && !fitReference){
if(LargeBinning)
leParameters->load_only_Bmass_param_values("fitresult_SignalFit_fitSignalMC_SimultaneousFit_2Dfit_bin"+std::to_string(b)+"_pdf"+std::to_string(n)+".txt");
else{
if(leParameters->eff_q2() < 8.68)
leParameters->load_only_Bmass_param_values("fitresult_SignalFit_fitSignalMC_SimultaneousFit_2Dfit_bin2_pdf"+std::to_string(n)+".txt");
else if(leParameters->eff_q2() > 15.0)
leParameters->load_only_Bmass_param_values("fitresult_SignalFit_fitSignalMC_SimultaneousFit_2Dfit_bin6_pdf"+std::to_string(n)+".txt");
else
leParameters->load_only_Bmass_param_values("fitresult_SignalFit_fitSignalMC_SimultaneousFit_2Dfit_bin5_pdf"+std::to_string(n)+".txt");
}
}
*/
//initialize parameters to blind them!
//leParameters->Fl.init(3.0/4.0*(s1c.at(b)-s2c.at(b)/3.0), 0.0, 1.0, 0.0);
leParameters->Fl.init(1.0-4.0/3.0*s1s.at(b), 0.0, 1.0, 0.0);
leParameters->S1s.init(s1s.at(b), -1.0, 1.0, 0.0);
leParameters->S3.init(s3.at(b), -1.0, 1.0, 0.0);
leParameters->S4.init(s4.at(b), -1.0, 1.0, 0.0);
leParameters->S5.init(s5.at(b), -1.0, 1.0, 0.0);
leParameters->Afb.init(3.0/4.0*s6s.at(b), -0.75, 0.75, 0.0);
leParameters->S6s.init(s6s.at(b), -1.0, 1.0, 0.0);
leParameters->S7.init(s7.at(b), -1.0, 1.0, 0.0);
leParameters->S8.init(s8.at(b), -1.0, 1.0, 0.0);
leParameters->S9.init(s9.at(b), -1.0, 1.0, 0.0);
leParameters->SS1.init(0.0, -1.0, 1.0, 0.0);
leParameters->SS2.init(0.0, -1.0, 1.0, 0.0);
leParameters->SS3.init(0.0, -1.0, 1.0, 0.0);
leParameters->SS4.init(0.0, -1.0, 1.0, 0.0);
leParameters->SS5.init(0.0, -1.0, 1.0, 0.0);
if(blind){
double blind_scale = 1.0;
leParameters->Fl.set_blinding(true, blind_scale, true);
leParameters->S1s.set_blinding(true, blind_scale, true);
leParameters->S3.set_blinding(true, blind_scale, true);
leParameters->S4.set_blinding(true, blind_scale, true);
leParameters->S5.set_blinding(true, blind_scale, true);
leParameters->Afb.set_blinding(true, blind_scale, true);
leParameters->S6s.set_blinding(true, blind_scale, true);
leParameters->S7.set_blinding(true, blind_scale, true);
leParameters->S8.set_blinding(true, blind_scale, true);
leParameters->S9.set_blinding(true, blind_scale, true);
}
leParameters->FS .init(opts.swave ? 0.1*FL_scale[b] : 0.0, -1.0, 1.0, opts.swave ? 0.001 : 0.0);
if(opts.fit_mkpi || opts.use_mkpi){
//p-wave
if(fitData)
leParameters->gammakstar.init(0.0503, 0.01, 0.10, 0.001, 0.01, true);//PDG value
else
leParameters->gammakstar.init(0.0503, 0.01, 0.10, OnlyBackground ? 0.0 : 0.001);//PDG value
leParameters->mkstar.init(PDGMASS_K_STAR_PLUS / 1000., 0.85, 1.0, OnlyBackground ? 0.0 : 0.001);//PDG value
//s-wave
leParameters->gammakstarplus.init(0.236, 0.1, 1.0, 0.0); //PDG value
leParameters->mkstarplus.init(1.41, 1.2, 1.6, 0.0); //PDG value
leParameters->asphase.init(TMath::Pi(), 0.0, 2.0*TMath::Pi(), 0.0);
leParameters->a.init(1.95, 0.001, 20.0, 0.0);
leParameters->r.init(1.78, 0.001, 10.0, 0.0);
leParameters->R.init(1.6, 0.0, 10.0, FitR ? 0.001 : 0.0);
//background parameter
if(leParameters->f_sig() != 1.0){
leParameters->cbkgmkpi0.init(1.0, -1.0, 1.0, 0.0);
leParameters->cbkgmkpi1.init(0.1, -1.0, 1.0, 0.01);
leParameters->cbkgmkpi2.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgmkpi3.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgmkpi4.init(0.0, -1.0, 1.0, 0.0);
opts.mkpi_threshold = false;
leParameters->nthreshold.init(1.5, 0.0, 15.0, 0.0);
}
}
//background parameter //TODO loop //TODO nPDFs
if(leParameters->f_sig() != 1.0){
leParameters->cbkgctl0.init(1.0, -1.0, 1.0, 0.0);
leParameters->cbkgctl1.init(Bctl1[n], -1.0, 1.0, 0.0);
leParameters->cbkgctl2.init(Bctl2[n], -1.0, 1.0, 0.0);
leParameters->cbkgctl3.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgctl4.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgctk0.init(1.0, -1.0, 1.0, 0.0);
leParameters->cbkgctk1.init(Bctk1[n], -1.0, 1.0, 0.0);
leParameters->cbkgctk2.init(Bctk2[n], -1.0, 1.0, 0.0);
leParameters->cbkgctk3.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgctk4.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgphi0.init(1.0, -1.0, 1.0, 0.0);
leParameters->cbkgphi1.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgphi2.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgphi3.init(0.0, -1.0, 1.0, 0.0);
leParameters->cbkgphi4.init(0.0, -1.0, 1.0, 0.0);
}
if(SystematicsWithToys || FitFinalToySamples){
fcnc::bu2kstarmumu_parameters * le2DParameters = new fcnc::bu2kstarmumu_parameters(&theOptions[n]);
le2DParameters->eff_q2.init(0.5*(opts.TheQ2binsmin.at(b)+opts.TheQ2binsmax.at(b)), opts.TheQ2binsmin.front(), opts.TheQ2binsmax.back(), 0.0);
//initiate parameters for B mass fit
if(OnlySignal)
le2DParameters->f_sig.init(1.0, 0.0, 1.0, 0.0);
else
le2DParameters->f_sig.init(N_sig_Rare[b]*ev_frac[n]/(N_sig_Rare[b]*ev_frac[n]+N_bkg_Rare[b]*ev_frac[n]), 0.0, 1.0, 0.001);
le2DParameters->m_b.init(f_m_B[n], B_MASS_LOW, B_MASS_HIGH, 0.01);
if(opts.twotailedcrystalball)
le2DParameters->m_res_1.init(1.0, 0.0, 1.0, 0.0);
else
le2DParameters->m_res_1.init(f_f_CB[n], 0.0, 1.0, 0.0);
le2DParameters->fm_tau.init(1.0, 0.0, 1.0, 0.0);
le2DParameters->m_lambda.init(f_lambda1[n], -1.0e-1, -1.0e-6, 1.0e-6);
le2DParameters->m_lambda_2.init(f_lambda2[n], -1.0e-1, -1.0e-6, 0.0);
if(opts.twotailedcrystalball){
le2DParameters->m_sigma_1.init(f_sigma_1[n], 5.0, 40.0, 0.0);
}
else{
le2DParameters->m_sigma_1.init(f_sigma_1[n], 5.0, 40.0, 0.0);
le2DParameters->m_sigma_2.init(f_sigma_2[n], 5.0, 40.0, 0.0);
}
le2DParameters->alpha_1.init(f_alpha_1[n], 0.5, 5.0, 0.0);
le2DParameters->alpha_2.init(f_alpha_2[n], 0.5, 3.0, 0.0);
le2DParameters->n_1.init(f_n_1[n], 0.1, 15.0, 0.0);
le2DParameters->n_2.init(f_n_2[n], 0.1, 10.0, 0.0);
le2DParameters->m_scale.init(1.0, 0.0, 2.0, 0.0);
//mK*
le2DParameters->gammakstar.init(0.0503, 0.01, 0.8, 0.0); //PDG value
le2DParameters->mkstar.init(PDGMASS_K_STAR_PLUS / 1000., 0.7, 1.2, 0.01); //PDG value
//s-wave
if(opts.swave)
le2DParameters->FS.init(0.063, -1.00, 1.00, 0.001);
else
le2DParameters->FS.init(0.0, -1.00, 1.00, 0.0);
le2DParameters->gammakstarplus.init(0.236, 0.1, 1.0, 0.0); //PDG value
le2DParameters->mkstarplus.init(1.41, 1.2, 1.6, 0.0); //PDG value
le2DParameters->asphase.init(TMath::Pi(), 0.0, 2.0*TMath::Pi(), 0.0);
le2DParameters->a.init(1.95, 0.0, 20.0, 0.0);
le2DParameters->r.init(1.78, 0.0, 10.0, 0.0);
le2DParameters->R.init(1.6, 0.0, 10.0, 0.0);
//background parameter
le2DParameters->cbkgmkpi0.init(1.0, -1.0, 1.0, 0.0);
le2DParameters->cbkgmkpi1.init(0.0, -1.0, 1.0, 0.01);
the2DParams[b].push_back(le2DParameters);
}
//define center of q2bin as effective q2:
lePDF->load_coeffs_eff_phsp_4d();
lePDF->update_cached_normalization(leParameters);
//save parameters and pdfs in vectors:
bool include = false;
for(UInt_t m = 0; m < pdf_idx.size(); m++){
if(n == pdf_idx.at(m)){
include = true;
break;
}
}
if(include){
theParams [b].push_back(leParameters);
theProbs [b].push_back(lePDF);
}
spdlog::info("[PDF{0:d}]\tSaved PDF and parameters!", n);
//create vector with events according to the requested fits/pulls
std::vector<fcnc::event> * leEvents = new std::vector<fcnc::event>;
//choose events from the event vector and sort corresponding to q2bin or non-resonant:
UInt_t NNN = events[n].size();
//This randomly pre-selected list of events is used, if not all events are wanted:
std::vector<UInt_t>eee;
for(UInt_t e = 0; e < NNN; e++){
fcnc::event meas;
meas = events[n].at(e);
//if wanted, only choose events from within q2 bin
if(meas.q2 < opts.TheQ2binsmin.at(b) || meas.q2 > opts.TheQ2binsmax.at(b))
continue;
if(meas.q2 > 0.98 && meas.q2 < 1.1)//exclude phi resonance
continue;
if(meas.m < opts.m_low || meas.m > opts.m_high)
continue;
if(OnlyBackground)
if(meas.m > 5230. && meas.m < 5330.)//exclude B peak
continue;
//crosscheck between mag up and mag down:
if(FitOnlyMagDown && meas.magnet > 0)
continue;
if(FitOnlyMagUp && meas.magnet < 0)
continue;
if(meas.costhetal < -1. || meas.costhetal > +1.){
spdlog::warn("cos(theta_L) out of range: {0:f}", meas.costhetal);
continue;
}
if(meas.costhetak < -1. || meas.costhetak > +1.){
spdlog::warn("cos(theta_K) out of range: {0:f}", meas.costhetak);
continue;
}
if(meas.phi < -TMath::Pi() || meas.phi > +TMath::Pi()){
spdlog::warn("phi out of range: {0:f}", meas.phi);
continue;
}
if(meas.mkpi < opts.mkpi_min || meas.mkpi > opts.mkpi_max){
spdlog::warn("m(Kpi) out of range: {0:f}", meas.mkpi);
continue;
}
leEvents->push_back(meas);
}
if(SystematicsWithToys){
leEvents->clear();
fcnc::bu2kstarmumu_generator gen(&theOptions[n]);
UInt_t idx = pdf_idx.at(n);
if(UseAccPer2Years && theOptions[n].run == 2){
theOptions[n].run = 21;
lePDF->load_coeffs_eff_phsp_4d();
lePDF->update_cached_normalization(leParameters);
std::vector<fcnc::event> eves1516 = gen.generate(0.5 + event_numbers[b][idx] * (idx%2==0 ? 0.275 : 0.292) , leParameters, lePDF);
for(unsigned int k = 0; k < eves1516.size(); k++)
eves1516.at(k).year = 2016;
theOptions[n].run = 22;
lePDF->load_coeffs_eff_phsp_4d();
lePDF->update_cached_normalization(leParameters);
std::vector<fcnc::event> eves1718 = gen.generate(0.5 + event_numbers[b][idx] * (idx%2==0 ? 0.725 : 0.708), leParameters, lePDF);
for(unsigned int k = 0; k < eves1718.size(); k++)
eves1718.at(k).year = 2018;
theOptions[n].run = 2;
leEvents->insert(leEvents->end(), eves1516.begin(), eves1516.end());
leEvents->insert(leEvents->end(), eves1718.begin(), eves1718.end());
}
else{
lePDF->load_coeffs_eff_phsp_4d();
lePDF->update_cached_normalization(leParameters);
std::vector<fcnc::event> genevents = gen.generate(0.5 + event_numbers[b][idx], leParameters, lePDF);
for(unsigned int k = 0; k < genevents.size(); k++)
genevents.at(k).year = (theOptions[idx].run == 2 ? 2016 : 2012);
leEvents->insert(leEvents->end(), genevents.begin(), genevents.end());
}
}
if(UseAccPer2Years && theOptions[n].run == 2){
//split the Run2 data-set into two groups: [0]: 2015+16 [1]: 2017+18
std::vector<fcnc::event> * Events_2015_2016 = new std::vector<fcnc::event>;
std::vector<fcnc::event> * Events_2017_2018 = new std::vector<fcnc::event>;
UInt_t nBefore = leEvents->size();
for(UInt_t e = 0; e < leEvents->size(); e++){
fcnc::event meas = leEvents->at(e);
if(meas.year == 2015 || meas.year == 2016)
Events_2015_2016->push_back(meas);
else if(meas.year == 2017 || meas.year == 2018)
Events_2017_2018->push_back(meas);
else{
spdlog::critical("Invalid year found in data-set of Run2: {0:d}", meas.year);
assert(0);
}
}
//update cached eff for 2015+16 and 2017+18 individually
theOptions[n].run = 21;
lePDF->load_coeffs_eff_phsp_4d();
lePDF->update_cached_normalization(leParameters);
lePDF->update_cached_efficiencies(leParameters, Events_2015_2016);
theOptions[n].run = 22;
lePDF->load_coeffs_eff_phsp_4d();
lePDF->update_cached_normalization(leParameters);
lePDF->update_cached_efficiencies(leParameters, Events_2017_2018);
//recombine both data-sets:
theOptions[n].run = 2;
leEvents->clear();
leEvents->insert(leEvents->end(), Events_2015_2016->begin(), Events_2015_2016->end());
leEvents->insert(leEvents->end(), Events_2017_2018->begin(), Events_2017_2018->end());
assert(nBefore == leEvents->size());
}
else{
lePDF->load_coeffs_eff_phsp_4d();
lePDF->update_cached_normalization(leParameters);
lePDF->update_cached_efficiencies(leParameters, leEvents);
}
if(include)
selection[b].push_back(leEvents);
spdlog::info("[PDF{0:d}]\tFinished selecting {1:f} events!", n, leEvents->size());
} // end of PDF
} // end of q2 bins
double FSfromLargeBins[3], dFSfromLargeBins[3];
if((SystematicsWithToys || FitFinalToySamples) && !OnlySignal && !fitReference){
//combine events to larger bins and fit before fitting all 8 bins:
int fit_results[3];
std::vector< std::vector<fcnc::event>* > combinedEvents[3];
bool ex_ml_buffer = theOptions[0].extended_ml;
for(unsigned int n = 0; n < nPDFs; n++){
combinedEvents[0].push_back(new std::vector<fcnc::event>);
combinedEvents[0].back()->insert(combinedEvents[0].back()->end(), selection[1].at(n)->begin(), selection[1].at(n)->end());
combinedEvents[0].back()->insert(combinedEvents[0].back()->end(), selection[2].at(n)->begin(), selection[2].at(n)->end());
combinedEvents[0].back()->insert(combinedEvents[0].back()->end(), selection[3].at(n)->begin(), selection[3].at(n)->end());
combinedEvents[0].back()->insert(combinedEvents[0].back()->end(), selection[4].at(n)->begin(), selection[4].at(n)->end());
combinedEvents[1].push_back(new std::vector<fcnc::event>);
combinedEvents[1].back()->insert(combinedEvents[1].back()->end(), selection[5].at(n)->begin(), selection[5].at(n)->end());
combinedEvents[2].push_back(new std::vector<fcnc::event>);
combinedEvents[2].back()->insert(combinedEvents[2].back()->end(), selection[6].at(n)->begin(), selection[6].at(n)->end());
combinedEvents[2].back()->insert(combinedEvents[2].back()->end(), selection[7].at(n)->begin(), selection[7].at(n)->end());
theOptions[n].extended_ml = false;
}
//extract FS from this fit and constrain FS to this value:
for(int b = 0; b < 3; b++){
fit_results[b] = f.fit(theProbs[b], the2DParams[b], combinedEvents[b]);
for(unsigned int n = 0; n < nPDFs; n++){
fcnc::bu2kstarmumu_parameters * dieParameter = (fcnc::bu2kstarmumu_parameters *) the2DParams[b].at(n);
FSfromLargeBins[b] = dieParameter->FS.get_value();
dFSfromLargeBins[b] = dieParameter->FS.get_error();
spdlog::info("[LARGEBIN{0:d}][PDF{1:d}]\tFS = {2:f} +/- {3:f}",b, n, FSfromLargeBins[b], dFSfromLargeBins[b]);
}
}
if(false){
TFile* fout = new TFile(("finalresult_OnlyToys"+std::to_string(opts.job_id)+"_2DfitLargeBins"+(LargerMKpiRange ? "_MediumMKpiRange" : "")+".root").c_str(), "RECREATE");
fout->cd();
int param_index = 0;
fcnc::bu2kstarmumu_parameters * dieParameter = (fcnc::bu2kstarmumu_parameters *) the2DParams[0].at(0);
for(UInt_t p = 0; p < dieParameter->nparameters(); p++){
fcnc::parameter* param = dieParameter->get_parameter(p);
if(param->get_step_size() != 0.0){//skip constant parameters
std::string parname(param->get_name());
std::string pardesc(param->get_description());
spdlog::info("Creating new TTree for parameter: " +parname);
TTree* t = new TTree(parname.c_str(), pardesc.c_str());
double q2a, q2b, value, error, error_up, error_down, start_value, nominal_value, nominal_error=0.0;
int pdf, bin, migrad, status_cov;
const unsigned int corr_max = param->correlations.size();
double tmp_corr[corr_max];
t->Branch("pdf",&pdf,"pdf/I");
t->Branch("bin",&bin,"bin/I");
t->Branch("value",&value,"value/D");
t->Branch("q2min",&q2a,"q2min/D");
t->Branch("q2max",&q2b,"q2max/D");
t->Branch("error",&error,"error/D");
t->Branch("error_up",&error_up,"error_up/D");
t->Branch("error_down",&error_down,"error_down/D");
t->Branch("start_value",&start_value,"start_value/D");
t->Branch("migrad",&migrad,"migrad/I");
t->Branch("status_cov",&status_cov,"status_cov/I");
t->Branch("nominal_value",&nominal_value,"nominal_value/D");
t->Branch("nominal_error",&nominal_error,"nominal_error/D");
t->Branch("index",&param_index, "index/I");
std::stringstream corr_stream;
corr_stream << "correlations[" << corr_max << "]/D";
t->Branch("correlations",&tmp_corr,corr_stream.str().c_str());
pdf = 1;
for(UInt_t b = 0; b < 3; b++){
fcnc::parameter* par = the2DParams[b].at(0)->get_parameter(p);
UInt_t paridx = 0;
while(par->get_name() != parname.c_str()){
par = the2DParams[b].at(0)->get_parameter(paridx);
paridx++;
if(paridx == the2DParams[b].at(0)->nparameters()){
spdlog::warn("Parameter '"+parname+"' not found in PDF 0. Continue with next PDF.");
break;
}
}
if(paridx == the2DParams[b].at(0)->nparameters())
break;
bin = b;
q2a = opts.TheQ2binsmin[b];
q2b = opts.TheQ2binsmax[b];
value = par->get_value();
error = par->get_error();
error_up = par->get_error_up();
error_down = par->get_error_down();
start_value = par->get_start_value();
nominal_value = par->get_start_value();
migrad = fit_results[b] % 100;
status_cov = fit_results[b] / 100;
for (unsigned int l = 0; l < corr_max; l++)
tmp_corr[l] = 0.0;
for (unsigned int l = 0; l < par->correlations.size(); l++)
tmp_corr[l] = par->correlations.at(l);
t->Fill();
}
t->Write();
delete t;
param_index++;
}
}
fout->Close();
}
if(false){
for(UInt_t b = 0; b < 3; b++){
for(unsigned int n = 0; n < nPDFs; n++){
std::cout << "|| BIN " << b << "\tPDF " << n << std::endl;
the2DParams[b].at(n)->print_parameters(false);
}
}
}
if(false){
for(UInt_t b = 0; b < 3; b++){
for(unsigned int n = 0; n < nPDFs; n++){
fcnc::bu2kstarmumu_parameters * dieParameter = (fcnc::bu2kstarmumu_parameters *) the2DParams[b].at(n);
fcnc::bu2kstarmumu_pdf * leProb = (fcnc::bu2kstarmumu_pdf *) theProbs[b].at(n);
thePlotter[n]->plot_data(leProb, dieParameter, combinedEvents[b].at(n), get_MoMPlot_path(), "ToyMoM_LargeBins_bin"+std::to_string(b)+"_pdf"+std::to_string(n), true);
}
}
}
for(unsigned int n = 0; n < nPDFs; n++){
theOptions[n].extended_ml = ex_ml_buffer;
}
}
bool do_fit = !OnlySignal;
int fitresult = 0;
if(do_fit){
for(UInt_t b = 0; b < nBins; b++){
std::vector<fcnc::event> * AllEvents = new std::vector<fcnc::event>;
for(UInt_t n = 0; n < nPDFs; n++){
if(SimultaneousFit){
if(n == 0){
fitresult = f.fit(theProbs[b], theParams[b], selection[b]);
}
}
else if(OneFit){
if(n > 0)
continue;
AllEvents->clear();
for(UInt_t nn = 0; nn < nPDFs; nn++)
AllEvents->insert(AllEvents->end(), selection[b].at(nn)->begin(), selection[b].at(nn)->end());
fitresult = f.fit(theProbs[b].at(n), theParams[b].at(n), AllEvents);
}
else{
fitresult = f.fit(theProbs[b].at(n), theParams[b].at(n), selection[b].at(n));
}
fit_results[b].push_back(fitresult);
fcnc::bu2kstarmumu_parameters * leParameters = (fcnc::bu2kstarmumu_parameters *) theParams[b].at(n);
fcnc::bu2kstarmumu_pdf * leProb = (fcnc::bu2kstarmumu_pdf *) theProbs[b].at(n);
if(!SimultaneousFit || n == 0){
double fitted_fs = leParameters->FS.get_value();
double fitted_dfs_up = leParameters->FS.get_error_up();
double fitted_dfs_down = leParameters->FS.get_error_down();
double fitted_dfs = leParameters->FS.get_error();
if(opts.minos_errors)
fitted_dfs = std::max(fabs(fitted_dfs_up), fabs(fitted_dfs_down));
if(fitSignalMC || !opts.swave){
fitted_fs = 0.0;
fitted_dfs = 0.0;
}
else if(FSfrom2DLargeBins){
if(leParameters->eff_q2() < 9.0){
fitted_fs = 0.252622 * FL_scale[b];
fitted_dfs = 0.103659 * FL_scale[b];
}
else if(leParameters->eff_q2() < 15.0){
fitted_fs = 0.013818 * FL_scale[b];
fitted_dfs = 0.146519 * FL_scale[b];
}
else{
fitted_fs = 0.0164393 * FL_scale[b];
fitted_dfs = 0.0895912 * FL_scale[b];
}
}
else if((SystematicsWithToys || FitFinalToySamples) && !fitReference){//use FS obtained from the fit in the larger q2bins:
if(leParameters->eff_q2() < 9.0){
fitted_fs = FSfromLargeBins[0] * FL_scale[b];
fitted_dfs = dFSfromLargeBins[0] * FL_scale[b];
}
else if(leParameters->eff_q2() < 15.0){
fitted_fs = FSfromLargeBins[1] * FL_scale[b];
fitted_dfs = dFSfromLargeBins[1] * FL_scale[b];
}
else{
fitted_fs = FSfromLargeBins[2] * FL_scale[b];
fitted_dfs = dFSfromLargeBins[2] * FL_scale[b];
}
}
std::cout << std::setprecision(5) << "FS: " << fitted_fs << "+/-" << fitted_dfs << std::endl;
fitted_FS[b].push_back(fitted_fs);
fitted_FSerr[b].push_back(fitted_dfs);
fitted_FSerrUp[b].push_back(fitted_dfs_up);
fitted_FSerrDown[b].push_back(fitted_dfs_down);
}
//plot fit projections of 2Dfit
std::ostringstream eps_label;
spdlog::info("[PLOT]\tStart configurations for plotting!");
if(fitReference){
eps_label << "JpsiFit";
}
else if(fitSignalMC){
eps_label << "FCNC_SignalfitSignalMC_fit_bin" << std::to_string(b);
}
else{
eps_label << "FCNCfit_bin" << std::to_string(b);
}
if (LargeBinning) eps_label << "_LargeBins";
else if(Fit2bins) eps_label << "_2BINS";
else if(Fit1bin) eps_label << "_1BIN";
else if(FitAllbins) eps_label << "_9BINS";
if(OneFit) eps_label << "_FullDataSet";
else eps_label << (n % 2 == 0 ? "_DD_Run" : "_LL_Run") << std::to_string( (int) (1+n/2));
eps_label << "_MoM_2Dfit";
theOptions[n].plot_label = "LHCb data";
theOptions[n].q2_label = q2_label(theOptions[n].TheQ2binsmin.at(b),theOptions[n].TheQ2binsmax.at(b));
if(opts.write_eps){
std::cout << "[PLOT]\t" << eps_label.str() << std::endl;
if(OneFit)
thePlotter[n]->plot_data(leProb, leParameters, AllEvents, get_MoMPlot_path(), eps_label.str(), false);
else
thePlotter[n]->plot_data(leProb, leParameters, selection[b].at(n), get_MoMPlot_path(), eps_label.str(), false);
}
}//end loop PDFs
if(SimultaneousFit){
std::ostringstream eps_label;
spdlog::info("[PLOT]\tStart configurations for combined plotting!");
if(fitReference){
eps_label << "JpsiFit";
}
else if(fitSignalMC){
eps_label << "FCNC_SignalfitSignalMC_fit_bin" << std::to_string(b);
}
else{
eps_label << "FCNCfit_bin" << std::to_string(b);
}
if (LargeBinning) eps_label << "_LargeBins";
else if(Fit2bins) eps_label << "_2BINS";
else if(Fit1bin) eps_label << "_1BIN";
else if(FitAllbins) eps_label << "_9BINS";
eps_label << "_AllPDFs";
eps_label << "_MoM_2Dfit";
std::vector<fcnc::bu2kstarmumu_pdf*> * prober = (std::vector<fcnc::bu2kstarmumu_pdf*> *) & theProbs[b];
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
thePlotter[0]->SetPulls(true);
thePlotter[0]->plot_added_pdfs(prober, paramser, & selection[b],
get_MoMPlot_path(), eps_label.str(), true);
thePlotter[0]->SetPulls(false);
eps_label << "_noPulls";
thePlotter[0]->plot_added_pdfs(prober, paramser, & selection[b],
get_MoMPlot_path(), eps_label.str(), true);
}
}//end loop q2 bins
}//end do_fit
else{//fill vectors with nominal values, if fit was not done:
for(UInt_t b = 0; b < nBins; b++){
for(UInt_t n = 0; n < nPDFs; n++){
if(FixFStoStart)
fitted_FS[b].push_back( opts.swave ? 0.1*FL_scale[b] : 0.0);
else
fitted_FS[b].push_back(0.);
fitted_FSerr[b].push_back(0.);
fitted_FSerrUp[b].push_back(0.);
fitted_FSerrDown[b].push_back(0.);
}
fit_results[b].push_back(300);
}
}
bool do_mom = !LargeBinning;
if(do_mom){
for(UInt_t b = 0; b < nBins; b++){
std::vector<fcnc::event> allEvents;
allEvents.clear();
//assign sWeights:
if(!(fitSignalMC || OnlySignal) && do_fit){//pure signal and fitSignalMC don't need sWeights
if(OneFit){
//for the combined fit, first add all events together and then apply sWeights according to first parameter idx
for(UInt_t n = 0; n < nPDFs; n++){
spdlog::info("[MOM]\tCombine events into one set for bin={0:d} pdf={1:d}",b, n);
allEvents.insert(allEvents.end(), selection[b].at(n)->begin(), selection[b].at(n)->end());
}
spdlog::info("[MOM]\tGet sWeights from fit for the full dataset of bin={0:d}",b);
fcnc::bu2kstarmumu_parameters * leParameters = (fcnc::bu2kstarmumu_parameters *) theParams[b].at(0);
fcnc::bu2kstarmumu_pdf * leProb = (fcnc::bu2kstarmumu_pdf *) theProbs[b].at(0);
spdlog::info("[MOM]\tGet combined sWeights from fit for bin={0:d}",b);
leProb->calculate_sweights(leParameters, &allEvents);
spdlog::info("[MOM]\tGet combined sWeights from fit for bin={0:d} ... DONE!",b);
}
else{
//for individual mom, each sub-sets gets sWeights and no sub-sets are added together
for(UInt_t n = 0; n < nPDFs; n++){
fcnc::bu2kstarmumu_parameters * leParameters = (fcnc::bu2kstarmumu_parameters *) theParams[b].at(n);
fcnc::bu2kstarmumu_pdf * leProb = (fcnc::bu2kstarmumu_pdf *) theProbs[b].at(n);
spdlog::info("[MOM]\tGet sWeights from fit for bin={0:d} pdf={1:d}",b, n);
leProb->calculate_sweights(leParameters, selection[b].at(n));
spdlog::info("[MOM]\tGet sWeights from fit for bin={0:d} pdf={1:d} ...DONE.",b, n);
//for the simultaneous mom, first apply sWeights according to parameters[n], then add all events together
if(SimultaneousMoM){
spdlog::info("[MOM]\tCombine events (after sWeights have been applied) into one set for bin={0:d} pdf={1:d}",b, n);
allEvents.insert(allEvents.end(), selection[b].at(n)->begin(), selection[b].at(n)->end());
}
}
}
}//end of sWeight assignments
//extract and save angular moments:
if(SimultaneousMoM || SimultaneousFit || OneFit){//do MoM for the full dataset of this q2bin
std::vector<double> mom(18, 0.0), obs(18, 0.0);
std::vector<double> momcov(18*18, 0.0), obscov(18*18, 0.0);
spdlog::info("[MoM]\tGet moments from the combined dataset! bin={0:d}",b);
if(!allEvents.size()){
for(UInt_t n = 0; n < nPDFs; n++){
spdlog::info("[MOM]\tCombine events for MoM into one set for bin={0:d} pdf={1:d}",b, n);
allEvents.insert(allEvents.end(), selection[b].at(n)->begin(), selection[b].at(n)->end());
}
}
fcnc::bu2kstarmumu_parameters * leParameters = (fcnc::bu2kstarmumu_parameters *) theParams[b].at(0);
fcnc::bu2kstarmumu_pdf * leProb = (fcnc::bu2kstarmumu_pdf *) theProbs[b].at(0);
leProb->get_moments(allEvents, mom, momcov);
spdlog::info("[MoM]\tConvert moments to angular observables for the combined dataset! bin={0:d}",b);
fcnc::moments_to_observables(rnd, mom, momcov, fitted_FS[b].at(0), fitted_FSerr[b].at(0), obs, obscov, FixFStoStart || UseExternalFS);
spdlog::info("[MoM]\tSave angular observables to parameters for the combined dataset! bin={0:d}",b);
leProb->save_moments_to_obs(leParameters, obs, obscov);
spdlog::info("[MoM]\tDone for the combined dataset of bin={0:d}",b);
}
else{//do MoM individually for each sub-set
for(UInt_t n = 0; n < nPDFs; n++){
std::vector<double> mom(18, 0.0), obs(18, 0.0);;
std::vector<double> momcov(18*18, 0.0), obscov(18*18, 0.0);
spdlog::info("[MoM]\tGet moments from the combined dataset! bin={0:d} pdf={1:d}",b, n);
fcnc::bu2kstarmumu_parameters * leParameters = (fcnc::bu2kstarmumu_parameters *) theParams[b].at(n);
fcnc::bu2kstarmumu_pdf * leProb = (fcnc::bu2kstarmumu_pdf *) theProbs[b].at(n);
leProb->get_moments(*selection[b].at(n), mom, momcov);
spdlog::info("[MoM]\tConvert moments to angular observables for bin={0:d} pdf={1:d}",b, n);
fcnc::moments_to_observables(rnd, mom, momcov, fitted_FS[b].at(n), fitted_FSerr[b].at(n), obs, obscov, FixFStoStart || UseExternalFS);
spdlog::info("[MoM]\tSave angular observables to parameters for bin={0:d} pdf={1:d}",b, n);
leProb->save_moments_to_obs(leParameters, obs, obscov);
spdlog::info("[MoM]\tDone for bin={0:d} pdf={1:d}",b, n);
}
}
//plot all four PDFs:
for(UInt_t n = 0; n < nPDFs; n++){
if((SimultaneousMoM || OneFit) && n > 0)
continue;
std::ostringstream qqbin;
std::ostringstream eps_label;
std::cout << "[PLOT]\tStart configurations for plotting!" << std::endl;
if(fitReference) eps_label << "JpsiFit";
else if(fitSignalMC) eps_label << "FCNC_SignalfitSignalMC_fit_bin" << std::to_string(b);
else eps_label << "FCNCfit_bin" << std::to_string(b);
if (LargeBinning) eps_label << "_LargeBins";
else if(Fit2bins) eps_label << "_2BINS";
else if(Fit1bin) eps_label << "_1BIN";
else if(FitAllbins) eps_label << "_9BINS";
if(SimultaneousMoM || OneFit) eps_label << "_FullDataSet";
else eps_label << (n % 2 == 0 ? "_DD_Run" : "_LL_Run") << std::to_string( (int) (1+n/2));
eps_label << "_MoM";
theOptions[n].plot_label = "LHCb data";
theOptions[n].q2_label = q2_label(theOptions[n].TheQ2binsmin.at(b),theOptions[n].TheQ2binsmax.at(b));
if(opts.write_eps){
bool wf = theOptions[n].weighted_fit;
bool mf = theOptions[n].only_mass2DFit;
bool oa = theOptions[n].only_angles;
bool el = theOptions[n].extended_ml;
theOptions[n].weighted_fit = true; //only for the plotter
theOptions[n].only_mass2DFit = false; //only for the plotter
theOptions[n].only_angles = true; //only for the plotter
theOptions[n].extended_ml = false;//only for the plotter
std::cout << "[PLOT]\t" << eps_label.str() << std::endl;
if(SimultaneousMoM || OneFit)
thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n), (fcnc::bu2kstarmumu_parameters*)theParams[b].at(n), &allEvents, get_MoMPlot_path(), eps_label.str(), true);
else
thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n), (fcnc::bu2kstarmumu_parameters*)theParams[b].at(n), selection[b].at(n), get_MoMPlot_path(), eps_label.str(), true);
theOptions[n].weighted_fit = wf;
theOptions[n].only_mass2DFit = mf;
theOptions[n].only_angles = oa;
theOptions[n].extended_ml = el;
}
} //end loop PDFs
} //end loop over bins
} //end do_mom
bool print_parameters = false;
//print and save-to-.txt of all parameters:
std::cout << std::endl;
std::cout << "==========================================" << std::endl;
std::cout << "|| PARAMETERS ||" << std::endl;
std::cout << "==========================================" << std::endl;
for(UInt_t b = 0; b < nBins; b++){
for(UInt_t i = 0; i < (SimultaneousMoM || OneFit ? 1 : pdf_idx.size()); i++){
if(print_parameters){
std::cout << "|| BIN " << b << "\tPDF " << pdf_idx.at(i) << std::endl;
theParams[b].at(i)->print_parameters(false);
}
std::ostringstream oss;
oss << "momresult";
if(fitReference) oss << "_JpsiFit";
else oss << "_SignalFit";
if(fitSignalMC) oss << "_fitSignalMC";
if(SimultaneousFit) oss << "_SimultaneousFit";
else oss << "_IndividualFit";
oss << "_2Dfit";
if(!opts.full_angular) oss << "_folding" << opts.folding;
if(nBins > 1) oss << "_bin" << b;
if (LargeBinning) oss << "_LargeBins";
else if(Fit2bins) oss << "_2BINS";
else if(Fit1bin) oss << "_1BIN";
else if(FitAllbins) oss << "_9BINS";
if(FitOnlyMagDown) oss << "_OnlyMagDown";
if(FitOnlyMagUp) oss << "_OnlyMagUp";
if(!(SimultaneousMoM || OneFit)) oss << "_pdf" << i;
oss << ".txt";
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
if(!(SystematicsWithToys || FitFinalToySamples))
paramser->at(i)->save_param_values(oss.str());
}
}
//print all fitresults:
std::cout << std::endl;
std::cout << "==========================================" << std::endl;
std::cout << "|| FIT RESULTS ||" << std::endl;
std::cout << "==========================================" << std::endl;
if(SimultaneousFit)
std::cout << "|| BIN\t\tfit result\tF_S ||" << std::endl;
else
std::cout << "|| BIN\t\tPDF\t\tfit result\tF_S ||" << std::endl;
for(UInt_t b = 0; b < nBins; b++){
if(SimultaneousFit || OneFit){
if(opts.minos_errors)
printf("|| %d\t\t%d\t\t%f (+)%f\t (-)%f\t||\n", b, fit_results[b].at(0), fitted_FS[b].at(0), fitted_FSerrUp[b].at(0), fitted_FSerrDown[b].at(0));
else
printf("|| %d\t\t%d\t\t%f +/- %f\t||\n", b, fit_results[b].at(0), fitted_FS[b].at(0), fitted_FSerr[b].at(0));
}
else{
for(UInt_t i = 0; i < pdf_idx.size(); i++){
if(opts.minos_errors)
printf("|| %d\t\t%d\t\t%d\t\t%f (+)%f\t (-)%f\t||\n", b, pdf_idx.at(i), fit_results[b].at(i), fitted_FS[b].at(i), fitted_FSerr[b].at(i), fitted_FSerrDown[b].at(i));
else
printf("|| %d\t\t%d\t\t%d\t\t%f +/- %f\t||\n", b, pdf_idx.at(i), fit_results[b].at(i), fitted_FS[b].at(i), fitted_FSerr[b].at(i));
}
}
}
std::cout << std::endl;
//save all values to TTree:
std::ostringstream sout;
sout << "finalresults_";
if(fitSignalMC) sout << "fitSignalMC_";
else if(fitReference) sout << "Jpsi_";
if(SystematicsWithToys) sout << "OnlyToys" << opts.job_id << "_";
if(FitFinalToySamples) sout << "FinalToys" << opts.job_id << "_";
if(FitOnlyMagDown) sout << "OnlyMagDown_";
if(FitOnlyMagUp) sout << "OnlyMagUp_";
if(LargeBinning) sout << "LargeBins_";
if(NP) sout << "NP_";
sout << "MoM.root";
TFile* fout = new TFile(sout.str().c_str(), "RECREATE");
fout->cd();
int param_index = 0;
//loop over parameters:
UInt_t pdf_null_idx = (SimultaneousMoM || OneFit || SimultaneousFit ? 0 : nPDFs-1);
for(UInt_t p = 0; p < theParams[0].at(pdf_null_idx)->nparameters(); p++){
fcnc::parameter* param = theParams[0].at(pdf_null_idx)->get_parameter(p);
if(param->get_step_size() != 0.0){//skip constant parameters
std::string parname(param->get_name());
std::string pardesc(param->get_description());
spdlog::info("Creating new TTree for parameter:"+ parname);
TTree* t = new TTree(parname.c_str(), pardesc.c_str());
double q2a, q2b, value, error, error_up, error_down, start_value, nominal_value, nominal_error=0.0;
int pdf, bin, migrad, status_cov;
const unsigned int corr_max = param->correlations.size();
double tmp_corr[corr_max];
t->Branch("pdf",&pdf,"pdf/I");
t->Branch("bin",&bin,"bin/I");
t->Branch("value",&value,"value/D");
t->Branch("q2min",&q2a,"q2min/D");
t->Branch("q2max",&q2b,"q2max/D");
t->Branch("error",&error,"error/D");
t->Branch("error_up",&error_up,"error_up/D");
t->Branch("error_down",&error_down,"error_down/D");
t->Branch("start_value",&start_value,"start_value/D");
t->Branch("migrad",&migrad,"migrad/I");
t->Branch("status_cov",&status_cov,"status_cov/I");
t->Branch("nominal_value",&nominal_value,"nominal_value/D");
t->Branch("nominal_error",&nominal_error,"nominal_error/D");
t->Branch("index",&param_index, "index/I");
std::stringstream corr_stream;
corr_stream << "correlations[" << corr_max << "]/D";
t->Branch("correlations",&tmp_corr,corr_stream.str().c_str());
UInt_t startPDF = 0;
UInt_t stopPDF = pdf_idx.size();
if(SimultaneousMoM)
startPDF = stopPDF - 1;
else if(OneFit)
stopPDF = 1;
for(UInt_t i = startPDF; i < stopPDF; i++){
pdf = i + 1;
for(UInt_t b = 0; b < nBins; b++){
fcnc::parameter* par = theParams[b].at(i)->get_parameter(p);
UInt_t paridx = 0;
while(par->get_name() != parname.c_str()){
par = theParams[b].at(i)->get_parameter(paridx);
paridx++;
if(paridx == theParams[b].at(i)->nparameters()){
spdlog::warn("Parameter '"+parname+"' not found in PDF{0:d}. Continue with next PDF.",i);
break;
}
}
if(paridx == theParams[b].at(i)->nparameters())
break;
bin = b;
q2a = opts.TheQ2binsmin[b];
q2b = opts.TheQ2binsmax[b];
value = par->get_value();
error = par->get_error();
error_up = par->get_error_up();
error_down = par->get_error_down();
start_value = par->get_start_value();
nominal_value = par->get_start_value();
if(SimultaneousFit){
migrad = fit_results[b].at(0) % 100;
status_cov = fit_results[b].at(0) / 100;
}
else{
migrad = fit_results[b].at(i) % 100;
status_cov = fit_results[b].at(i) / 100;
}
if (opts.minos_errors){
if (error_up==0.0 && value < par->get_max())
error_up = par->get_max() - value;
if (error_down==0.0 && value > par->get_min())
error_down = par->get_min() - value;//needs to be negative
}
for (unsigned int l = 0; l < corr_max; l++)
tmp_corr[l] = 0.0;
for (unsigned int l = 0; l < par->correlations.size(); l++)
tmp_corr[l] = par->correlations.at(l);
t->Fill();
}
}
t->Write();
delete t;
param_index++;
}
}
fout->Close();
return 0;
}