//Renata Kopecna #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //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 FL_scale = {0.4836193455050577, 1.2251014138607774, 1.274499551405837, 1.1368614009399862}; //Obtained from MC //TODO //Taken from main fit, update when fixed const std::vector 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::vectorevents[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::vectorfit_results[nBins]; std::vectorfitted_FS[nBins]; std::vectorfitted_FSerr[nBins]; std::vectorfitted_FSerrUp[nBins]; std::vectorfitted_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 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 theParams [nBins]; std::vector the2DParams [nBins]; std::vector theProbs [nBins]; std::vector< std::vector* > selection[nBins]; std::vector 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 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 * leEvents = new std::vector; //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::vectoreee; 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 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 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 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 * Events_2015_2016 = new std::vector; std::vector * Events_2017_2018 = new std::vector; 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* > 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); 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); 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); 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",¶m_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 * AllEvents = new std::vector; 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 * prober = (std::vector *) & theProbs[b]; std::vector * paramser = (std::vector *) & 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 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 mom(18, 0.0), obs(18, 0.0); std::vector 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 mom(18, 0.0), obs(18, 0.0);; std::vector 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 * paramser = (std::vector *) & 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",¶m_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; }