5381 lines
251 KiB
C++
5381 lines
251 KiB
C++
//Renata Kopecna
|
||
|
||
#include <fstream>
|
||
|
||
#include "folder.hh"
|
||
#include <funcs.hh>
|
||
#include <constants.hh>
|
||
#include <bu2kstarmumu_pdf.hh>
|
||
#include <pdf.hh>
|
||
#include <options.hh>
|
||
#include <values.hh>
|
||
#include <design.hh>
|
||
#include <integrals.hh>
|
||
#include <event.hh>
|
||
#include <helpers.hh>
|
||
#include <paths.hh>
|
||
|
||
#include <TMinuit.h>
|
||
#include <spdlog.h>
|
||
|
||
#include <TROOT.h>
|
||
#include <TFile.h>
|
||
#include <TStyle.h>
|
||
|
||
|
||
//Helper function to create a polynomial for the background
|
||
|
||
std::vector<double> init_ch_ctl(const fcnc::bu2kstarmumu_parameters* params){
|
||
std::vector<double> bkg_ctl;
|
||
bkg_ctl.push_back(params->cbkgctl0());
|
||
bkg_ctl.push_back(params->cbkgctl1());
|
||
bkg_ctl.push_back(params->cbkgctl2());
|
||
bkg_ctl.push_back(params->cbkgctl3());
|
||
bkg_ctl.push_back(params->cbkgctl4());
|
||
return bkg_ctl;
|
||
}
|
||
std::vector<double> init_ch_ctk(const fcnc::bu2kstarmumu_parameters* params){
|
||
std::vector<double> bkg_ctk;
|
||
bkg_ctk.push_back(params->cbkgctk0());
|
||
bkg_ctk.push_back(params->cbkgctk1());
|
||
bkg_ctk.push_back(params->cbkgctk2());
|
||
bkg_ctk.push_back(params->cbkgctk3());
|
||
bkg_ctk.push_back(params->cbkgctk4());
|
||
bkg_ctk.push_back(params->cbkgctk5());
|
||
bkg_ctk.push_back(params->cbkgctk6());
|
||
return bkg_ctk;
|
||
}
|
||
std::vector<double> init_ch_phi(const fcnc::bu2kstarmumu_parameters* params){
|
||
std::vector<double> bkg_phi;
|
||
bkg_phi.push_back(params->cbkgphi0());
|
||
bkg_phi.push_back(params->cbkgphi1());
|
||
bkg_phi.push_back(params->cbkgphi2());
|
||
bkg_phi.push_back(params->cbkgphi3());
|
||
bkg_phi.push_back(params->cbkgphi4());
|
||
return bkg_phi;
|
||
}
|
||
|
||
|
||
//using namespace std;
|
||
using namespace fcnc;
|
||
|
||
//this is a wrapper for the complex error function
|
||
//which is needed for a gaussian convolution of exp*cos/sin
|
||
//this fortran implementation however is not thread safe!
|
||
extern "C" void wwerfwrap_(double *zr, double *zi, double *wr, double* wi);
|
||
//boost::mutex global_mutex_2;
|
||
std::mutex global_mutex_2;
|
||
|
||
bu2kstarmumu_pdf* bu2kstarmumu_pdf::current_pdf;
|
||
|
||
bu2kstarmumu_pdf::bu2kstarmumu_pdf(options* o, const bu2kstarmumu_parameters* params):
|
||
opts(o)
|
||
{
|
||
|
||
//vector of efficiency coefficients containing 1260 elements, coefficients stored in bu2kstarmumu_coefficients.cc
|
||
//coeffs_eff_4d = fcnc::coefficients_nominal;
|
||
//load_coeffs_eff_phsp_4d();
|
||
fldr = new fcnc::folder(opts);
|
||
};
|
||
|
||
bu2kstarmumu_pdf::~bu2kstarmumu_pdf()
|
||
{
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::get_moments(std::vector<fcnc::event> events, std::vector<double>& moments, std::vector<double>& covariance) const
|
||
{
|
||
|
||
if(!opts->full_angular){
|
||
spdlog::error("No folding implemented for moments. Debug: 1");
|
||
assert(0);
|
||
}
|
||
|
||
std::vector<double> cov(NTERMS*NTERMS, 0.0);//the actual covariance matrix for the moments
|
||
std::vector<double> m(NTERMS, 0.0);//need to first calculate the mean
|
||
|
||
double nweight = 0.0; //sum of weights
|
||
double nweightsquared = 0.0; //sum of weights squared, not used anywhere
|
||
|
||
for (auto meas: events){
|
||
double weight = meas.weight*meas.sweight;
|
||
nweight += weight;
|
||
nweightsquared += weight*weight;
|
||
}
|
||
for (auto meas: events){
|
||
double weight = meas.weight*meas.sweight;
|
||
weight /= nweight;//nominal
|
||
//Calculate the angular terms for each parameter
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0,
|
||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||
fj(meas.costhetal, meas.costhetak, meas.phi,
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
double ffs=0.0, fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0;
|
||
if(opts->swave){
|
||
swave_fj(meas.costhetal, meas.costhetak, meas.phi,
|
||
ffs, fs1, fs2, fs3, fs4, fs5);
|
||
}
|
||
//TODO when bored: this is very annoying and f_whatever should be a struct or so and one should loop
|
||
m.at(0) += f1*weight;
|
||
m.at(1) += f2*weight;
|
||
m.at(2) += f3*weight;
|
||
m.at(3) += f4*weight;
|
||
m.at(4) += f5*weight;
|
||
m.at(5) += f6*weight;
|
||
m.at(6) += f7*weight;
|
||
m.at(7) += f8*weight;
|
||
m.at(8) += f9*weight;
|
||
m.at(9) += f10*weight;
|
||
m.at(10) += f11*weight;
|
||
m.at(11) += f12*weight;
|
||
if(opts->swave){
|
||
m.at(12) += ffs*weight;
|
||
m.at(13) += fs1*weight;
|
||
m.at(14) += fs2*weight;
|
||
m.at(15) += fs3*weight;
|
||
m.at(16) += fs4*weight;
|
||
m.at(17) += fs5*weight;
|
||
}
|
||
}
|
||
|
||
//calculate rms
|
||
for (auto meas: events){
|
||
double weight = meas.weight*meas.sweight;//dangerous?
|
||
weight /= nweight;//nominal
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0,
|
||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||
fj(meas.costhetal, meas.costhetak, meas.phi,
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
double ffs=0.0, fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0;
|
||
if(opts->swave){
|
||
swave_fj(meas.costhetal, meas.costhetak, meas.phi,
|
||
ffs, fs1, fs2, fs3, fs4, fs5);
|
||
}
|
||
std::vector<double> diff(NTERMS*NTERMS, 0.0);
|
||
diff.at(0) = f1 - m.at(0); //aaaaaaaarrrrggghhh
|
||
diff.at(1) = f2 - m.at(1);
|
||
diff.at(2) = f3 - m.at(2);
|
||
diff.at(3) = f4 - m.at(3);
|
||
diff.at(4) = f5 - m.at(4);
|
||
diff.at(5) = f6 - m.at(5);
|
||
diff.at(6) = f7 - m.at(6);
|
||
diff.at(7) = f8 - m.at(7);
|
||
diff.at(8) = f9 - m.at(8);
|
||
diff.at(9) = f10 - m.at(9);
|
||
diff.at(10) = f11 - m.at(10);
|
||
diff.at(11) = f12 - m.at(11);
|
||
if(opts->swave){
|
||
diff.at(12) = ffs - m.at(12);
|
||
diff.at(13) = fs1 - m.at(13);
|
||
diff.at(14) = fs2 - m.at(14);
|
||
diff.at(15) = fs3 - m.at(15);
|
||
diff.at(16) = fs4 - m.at(16);
|
||
diff.at(17) = fs5 - m.at(17);
|
||
}
|
||
//for swave==false, only loop over the first 12x12 elements
|
||
//the matrix however stays in the 18x18 format, with 0.0 for all j > 11 || k > 11
|
||
UInt_t mm = opts->swave ? NTERMS : NTERMS_P;
|
||
for (unsigned int j = 0; j<mm; j++){
|
||
for (unsigned int k = 0; k<mm; k++){
|
||
cov.at(j*NTERMS+k) += (diff.at(j))*(diff.at(k))*sqr(weight);
|
||
}
|
||
}
|
||
}
|
||
moments = m;
|
||
covariance = cov;
|
||
return;
|
||
};
|
||
|
||
double corr_from_obs(std::vector<double> obs, std::vector<double> obscov, int i, int k){
|
||
return obscov.at(i+NTERMS*k)/sqrt(obscov.at(k+NTERMS*k))/sqrt(obscov.at(i+NTERMS*i));
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::save_moments_to_obs(bu2kstarmumu_parameters* params,
|
||
std::vector<double> obs,
|
||
std::vector<double> obscov) const
|
||
{
|
||
assert(obs.size() == NTERMS);
|
||
assert(obscov.size() == NTERMS*NTERMS);
|
||
|
||
//**** Fl ****//
|
||
params->Fl.set_value(1.0-4.0/3.0*obs.at(0));
|
||
params->Fl.set_error(4.0/3.0*sqrt(obscov.at(0+NTERMS*0)));
|
||
if(opts->fit_fl) params->Fl.set_step_size(0.0001);
|
||
|
||
for(unsigned int i = 0; i < NTERMS; i++){
|
||
if(i == 0) params->Fl.set_correlation(1.0, 0); //self correlation is one by definition
|
||
else if(i == 7 && opts->fit_afb){
|
||
//correlation to Afb is equal to correlation of S1s and S6s
|
||
params->Fl.set_correlation(corr_from_obs(obs,obscov,7,0), 7);
|
||
}
|
||
else{
|
||
params->Fl.set_correlation(corr_from_obs(obs,obscov,i,0)/sqrt(3.0/4.0), i);
|
||
}
|
||
}
|
||
|
||
//**** S1s ****//
|
||
params->S1s.set_value(obs.at(0));
|
||
params->S1s.set_error(sqrt(obscov.at(0+NTERMS*0)));
|
||
if(!opts->fit_fl) params->S1s.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++){
|
||
params->S1s.set_correlation(corr_from_obs(obs,obscov,i,0), i);
|
||
}
|
||
//**** S3 ****//
|
||
params->S3.set_value(obs.at(4));
|
||
params->S3.set_error(sqrt(obscov.at(4+NTERMS*4)));
|
||
params->S3.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++){
|
||
params->S3.set_correlation(corr_from_obs(obs,obscov,i,4), i);
|
||
}
|
||
//**** S4 ****//
|
||
params->S4.set_value(obs.at(5));
|
||
params->S4.set_error(sqrt(obscov.at(5+NTERMS*5)));
|
||
params->S4.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++)
|
||
params->S4.set_correlation(corr_from_obs(obs,obscov,i,5), i);
|
||
|
||
//**** S5 ****//
|
||
params->S5.set_value(obs.at(6));
|
||
params->S5.set_error(sqrt(obscov.at(6+NTERMS*6)));
|
||
params->S5.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++)
|
||
params->S5.set_correlation(corr_from_obs(obs,obscov,i,6), i);
|
||
|
||
//**** Afb ****//
|
||
params->Afb.set_value(3.0/4.0*obs.at(7));
|
||
params->Afb.set_error(3.0/4.0*sqrt(obscov.at(7+NTERMS*7)));
|
||
if(opts->fit_afb)
|
||
params->Afb.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++){
|
||
if(i == 7) params->Afb.set_correlation(1.0, 7);//self correlation is not scaled
|
||
else if(i == 0 && opts->fit_afb){
|
||
//correlation to Fl is equal to correlation of S1s and S6s
|
||
params->Afb.set_correlation(corr_from_obs(obs,obscov,0,7), 0);
|
||
}
|
||
else params->Afb.set_correlation(corr_from_obs(obs,obscov,i,7)/sqrt(4.0/3.0), i);
|
||
}
|
||
|
||
//**** S6s ****//
|
||
params->S6s.set_value(obs.at(7));
|
||
params->S6s.set_error(sqrt(obscov.at(7+NTERMS*7)));
|
||
if(!opts->fit_afb) params->S6s.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->S6s.set_correlation(corr_from_obs(obs,obscov,i,7), i);
|
||
|
||
//**** S7 ****//
|
||
params->S7.set_value(obs.at(9));
|
||
params->S7.set_error(sqrt(obscov.at(9+NTERMS*9)));
|
||
params->S7.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->S7.set_correlation(corr_from_obs(obs,obscov,i,9), i);
|
||
|
||
//**** S8 ****//
|
||
params->S8.set_value(obs.at(10));
|
||
params->S8.set_error(sqrt(obscov.at(10+NTERMS*10)));
|
||
params->S8.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->S8.set_correlation(corr_from_obs(obs,obscov,i,10), i);
|
||
|
||
//**** S9 ****//
|
||
params->S9.set_value(obs.at(11));
|
||
params->S9.set_error(sqrt(obscov.at(11+NTERMS*11)));
|
||
params->S9.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->S9.set_correlation(corr_from_obs(obs,obscov,i,11), i);
|
||
|
||
//**** FS ****//
|
||
params->FS.set_value(obs.at(12));
|
||
params->FS.set_error(sqrt(obscov.at(12+NTERMS*12)));
|
||
if(opts->swave) params->FS.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->FS.set_correlation(corr_from_obs(obs,obscov,i,12), i);
|
||
|
||
//**** SS1 ****//
|
||
params->SS1.set_value(obs.at(13));
|
||
params->SS1.set_error(sqrt(obscov.at(13+NTERMS*13)));
|
||
if(opts->swave) params->SS1.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->SS1.set_correlation(corr_from_obs(obs,obscov,i,13), i);
|
||
|
||
//**** SS2 ****//
|
||
params->SS2.set_value(obs.at(14));
|
||
params->SS2.set_error(sqrt(obscov.at(14+NTERMS*14)));
|
||
if(opts->swave) params->SS2.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->SS2.set_correlation(corr_from_obs(obs,obscov,i,14), i);
|
||
|
||
//**** SS3 ****//
|
||
params->SS3.set_value(obs.at(15));
|
||
params->SS3.set_error(sqrt(obscov.at(15+NTERMS*15)));
|
||
if(opts->swave) params->SS3.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->SS3.set_correlation(corr_from_obs(obs,obscov,i,15), i);
|
||
|
||
//**** SS4 ****//
|
||
params->SS4.set_value(obs.at(16));
|
||
params->SS4.set_error(sqrt(obscov.at(16+NTERMS*16)));
|
||
if(opts->swave)params->SS4.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->SS4.set_correlation(corr_from_obs(obs,obscov,i,16), i);
|
||
|
||
//**** SS5 ****//
|
||
params->SS5.set_value(obs.at(17));
|
||
params->SS5.set_error(sqrt(obscov.at(17+NTERMS*17)));
|
||
if(opts->swave) params->SS5.set_step_size(0.0001);
|
||
for(unsigned int i = 0; i < NTERMS; i++) params->SS5.set_correlation(corr_from_obs(obs,obscov,i,17), i);
|
||
|
||
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::prob(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
|
||
//safety checks:
|
||
if(opts->fit_mkpi && opts->use_mkpi){
|
||
spdlog::critical("Do not use the direct fit of m(Kpi) and the included fit of m(Kpi) in the angular s-Wave at the same time!");
|
||
spdlog::critical("5D fit:\t'use_mkpi'");
|
||
spdlog::critical("4D+1D fit:\t'fit_mkpi'");
|
||
assert(0);
|
||
}
|
||
if(opts->only_mass2DFit && opts->only_Bmass){
|
||
spdlog::critical("Cannot fit m(Kpi) and m(B) with option 'only_Bmass'!");
|
||
assert(0);
|
||
}
|
||
if(opts->only_mass2DFit && !opts->fit_mkpi){
|
||
spdlog::critical("When using the 2D mass fit, enable 'fit_mkpi' as well!");
|
||
assert(0);
|
||
}
|
||
if(opts->only_mkpi && !opts->fit_mkpi){
|
||
spdlog::critical("When using the m(Kpi) mass fit, enable 'fit_mkpi' as well!");
|
||
assert(0);
|
||
}
|
||
if((opts->only_angles && opts->only_Bmass) || (opts->only_mkpi && opts->only_Bmass) || (opts->only_angles && opts->only_mkpi)){
|
||
spdlog::critical("Do not use two or more of 'only_Bmass', 'only_mkpi' and 'only_angles' at the same time!");
|
||
spdlog::critical("only_Bmass = " + boolToString(opts->only_Bmass));
|
||
spdlog::critical("only_mkpi = " + boolToString(opts->only_mkpi));
|
||
spdlog::critical("only_angles = " + boolToString(opts->only_angles));
|
||
assert(0);
|
||
}
|
||
|
||
if(opts->use_angular_acc && opts->weighted_fit){
|
||
spdlog::critical("Do not use 'use_angular_acc' and 'weighted_fit' at the same time!");
|
||
spdlog::critical("'use_angular_acc'\tConvolute acceptance function into fit pdf");
|
||
spdlog::critical("'weighted_fit'\tAssign per event weight according to acceptance");
|
||
assert(0);
|
||
}
|
||
if(opts->twotailedcrystalball && opts->crystalball){
|
||
spdlog::critical("Cannot use CB and two-tailed CB option. Choose only one and chose wisely:");
|
||
spdlog::critical("Either 'twotailedcrystalball' or 'crystalball'");
|
||
assert(0);
|
||
}
|
||
|
||
if(opts->full_angular && opts->folding > -1){
|
||
spdlog::critical("Cannot run full angular fit and folding at the same time");
|
||
assert(0);
|
||
}
|
||
|
||
//determine signal and background probability
|
||
double fsig = (opts->extended_ml ? params->n_sig()/(params->n_sig()+params->n_bkg()) : params->f_sig());
|
||
double sig_part = 0.0;
|
||
double bkg_part = 0.0;
|
||
|
||
if(fsig != 0.0)//signal part:
|
||
sig_part += fsig
|
||
* angular_sig_prob(params, meas)
|
||
* m_sig_prob(params, meas)
|
||
* mkpi_sig_prob(params, meas);
|
||
|
||
if(fsig != 1.0)//background part:
|
||
bkg_part += (1.0-fsig)
|
||
* angular_bkg_prob(params, meas)
|
||
* m_bkg_prob(params, meas)
|
||
* mkpi_bkg_prob(params, meas);
|
||
|
||
//force individual probabilities for signal and background to be positive
|
||
if(opts->individual_penalties){
|
||
if(sig_part < 0.0){
|
||
sig_part = 1.0e-12;
|
||
bkg_part = 0.0;
|
||
}
|
||
if(bkg_part < 0.0){
|
||
bkg_part = 1.0e-12;
|
||
sig_part = 0.0;
|
||
}
|
||
}
|
||
|
||
//add background and signal parts:
|
||
double result = sig_part + bkg_part;
|
||
|
||
//check final probability
|
||
if(result < 0.0){
|
||
std::lock_guard<std::mutex> lock(global_mutex_2);
|
||
spdlog::debug("Event has negative probability {0:e}", result);
|
||
spdlog::debug("Signal_part:\t{0:e}", sig_part);
|
||
spdlog::debug("m(B):\t\t{0:e}",m_sig_prob(params, meas)); //THIS one crashes and idk why
|
||
spdlog::debug("m(Kpi):\t{0:e}",mkpi_sig_prob(params, meas));
|
||
spdlog::debug("angles:\t{0:e}",angular_sig_prob(params, meas));
|
||
spdlog::debug("FS:\t\t{0:e}", params->FS.get_value());
|
||
spdlog::debug("Backgrnd_part:\t{0:e}", bkg_part);
|
||
if (fsig != 1.0){
|
||
spdlog::debug("m(B):\t{0:e}",m_bkg_prob(params, meas));
|
||
spdlog::debug("m(Kpi):\t{0:e}",mkpi_bkg_prob(params, meas));
|
||
spdlog::debug("angles:\t{0:e}",angular_bkg_prob(params, meas));
|
||
}
|
||
|
||
const bool variablepushback = false; //OMFG
|
||
if(variablepushback){
|
||
double baseline = 1.0e-12;
|
||
double absres = fabs(result) > 1.0e-6 ? fabs(result) : 1.0e-6;
|
||
double logres = log10(absres)+6.0;
|
||
double factor = pow(10.0, -logres);
|
||
result = baseline*factor;
|
||
}
|
||
else{
|
||
result = 1.0e-12;
|
||
}
|
||
}
|
||
else if(std::isinf(result) || std::isnan(result)){
|
||
std::lock_guard<std::mutex> lock(global_mutex_2);
|
||
params->print_parameters(false);
|
||
spdlog::error("Event has probability {0:f}", result);
|
||
spdlog::error("Signal_part:\t{0:f}", sig_part);
|
||
spdlog::error("fsig:\t\t{0:f}", fsig);
|
||
spdlog::error("m(B):\t\t{0:f}", m_sig_prob(params, meas));
|
||
spdlog::error("m(Kpi):\t{0:e}", mkpi_sig_prob(params, meas));
|
||
spdlog::error("angles:\t{0:e}",angular_sig_prob(params, meas));
|
||
spdlog::error("FS:\t\t{0:f}", params->FS.get_value());
|
||
spdlog::error("m(K*+) s-Wave NORM:\t{0:f}", mkpi_swave_2_norm);
|
||
spdlog::error("m(K*+) p-Wave NORM:\t{0:f}", mkpi_pwave_2_norm);
|
||
spdlog::error("Backgrnd_part:\t{0:f}", bkg_part);
|
||
assert(0);
|
||
}
|
||
return result;
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::init(parameters* params) {
|
||
init(dynamic_cast<bu2kstarmumu_parameters*>(params));
|
||
//update_cached_normalization(params);
|
||
};
|
||
|
||
|
||
struct bin_edges{ //This could've been a class in case someone is bored in the future
|
||
|
||
//limits for all variable (range) (4D):
|
||
double q2min, q2max;
|
||
double ctkmin, ctkmax;
|
||
double ctlmin, ctlmax;
|
||
double phimin, phimax;
|
||
|
||
unsigned int nq2bins, nctlbins, nctkbins, nphibins;
|
||
|
||
//keep this as functions in case of modyfing the ranges during running the code!
|
||
|
||
//range of each dimension (4D):
|
||
double range_q2(){
|
||
return q2max - q2min;
|
||
}
|
||
double range_ctk(){
|
||
return ctkmax - ctkmin;
|
||
}
|
||
double range_ctl(){
|
||
return ctlmax - ctlmin;
|
||
}
|
||
double range_phi(){
|
||
return phimax - phimin;
|
||
}
|
||
|
||
//bin width for each variable
|
||
double binWidth_q2(){
|
||
return range_q2()/nq2bins;
|
||
}
|
||
double binWidth_ctl(){
|
||
return range_ctl()/nctlbins;
|
||
}
|
||
double binWidth_ctk(){
|
||
return range_ctk()/nctkbins;
|
||
}
|
||
double binWidth_phi(){
|
||
return range_phi()/nphibins;
|
||
}
|
||
|
||
//bin edges for each variable
|
||
std::vector<double> edges_q2(){
|
||
std::vector<double> tmp;
|
||
for (unsigned int h = 0; h<=nq2bins; h++){
|
||
tmp.push_back(q2min + h * binWidth_q2());
|
||
}
|
||
return tmp;
|
||
}
|
||
std::vector<double> edges_ctl(){
|
||
std::vector<double> tmp;
|
||
for (unsigned int h = 0; h<=nctlbins; h++){
|
||
tmp.push_back(ctlmin + h * binWidth_ctl());
|
||
}
|
||
return tmp;
|
||
}
|
||
std::vector<double> edges_ctk(){
|
||
std::vector<double> tmp;
|
||
for (unsigned int h = 0; h<=nctkbins; h++){
|
||
tmp.push_back(ctkmin + h * binWidth_ctk());
|
||
}
|
||
return tmp;
|
||
}
|
||
std::vector<double> edges_phi(){
|
||
std::vector<double> tmp;
|
||
for (unsigned int h = 0; h<=nphibins; h++){
|
||
tmp.push_back(phimin + h * binWidth_phi());
|
||
}
|
||
return tmp;
|
||
}
|
||
|
||
//Total number of bins in 4D
|
||
unsigned int getNbins(){
|
||
return nq2bins*nctlbins*nctkbins*nphibins;
|
||
}
|
||
|
||
//constructor
|
||
bin_edges(fcnc::options *opts, unsigned int nq2,unsigned int nctl,unsigned int nctk,unsigned int nphi){
|
||
|
||
//get the limits for all variables (4D):
|
||
q2min = opts->TheQ2binsmin.front(); q2max = opts->TheQ2binsmax.back();
|
||
ctkmin = opts->ctk_min; ctkmax = opts->ctk_max;
|
||
ctlmin = opts->ctl_min; ctlmax = opts->ctl_max;
|
||
phimin = opts->phi_min; phimax = opts->phi_max;
|
||
|
||
nq2bins = nq2;
|
||
nctlbins = nctl;
|
||
nctkbins = nctk;
|
||
nphibins = nphi;
|
||
}
|
||
|
||
};
|
||
|
||
unsigned int get_bin_in4D(int h, int i, int j, int k, bin_edges edges){
|
||
/// h = q2, i = ctl, j = ctk, k = phi
|
||
|
||
//Return the bin number for given event evt in 4D (q2, thetal, thetak, phi)
|
||
//Starting from 0!
|
||
unsigned int bin = edges.nctlbins*edges.nctkbins*edges.nphibins*h //q2
|
||
+edges.nctkbins*edges.nphibins*i //thetaL
|
||
+edges.nphibins*j //thetaK
|
||
+k; //phi
|
||
if (bin >= edges.getNbins()){
|
||
spdlog::critical("Bin {0:d} is larger than the dimension of {1:d}!",bin,edges.getNbins());
|
||
spdlog::error("h {0:d},\ti {1:d},\tj {2:d},\tk {3:d}", h, i, j, k);
|
||
spdlog::error("q2 {0:d},\tctl {1:d},\tctk {2:d},\tphi {3:d}",
|
||
edges.nq2bins, edges.nctlbins, edges.nctkbins, edges.nphibins);
|
||
assert(0);
|
||
}
|
||
else return bin;
|
||
}
|
||
|
||
unsigned int get_bin_in4D(event evt, bin_edges edges ){
|
||
//Return the bin number for given event evt in 4D (q2, thetal, thetak, phi)
|
||
//Starting from 0!
|
||
unsigned int h = (evt.q2 - edges.q2min ) / edges.binWidth_q2(); //division here truncates the result"chi
|
||
unsigned int i = (evt.costhetal - edges.ctlmin) / edges.binWidth_ctl();//eg 18/10 = 1
|
||
unsigned int j = (evt.costhetak - edges.ctkmin) / edges.binWidth_ctk();
|
||
unsigned int k = (evt.phi - edges.phimin) / edges.binWidth_phi();
|
||
|
||
return get_bin_in4D(h,i,j,k, edges);
|
||
}
|
||
|
||
unsigned int npolynom::get_bin_in4D(int h, int i, int j, int k){
|
||
/// h = q2, i = ctl, j = ctk, k = phi
|
||
|
||
//Return the bin number for given event evt in 4D (q2, thetal, thetak, phi)
|
||
//Starting from 0!
|
||
return ctl*ctk*phi*h //q2
|
||
+ctk*phi*i //thetaL
|
||
+phi*j //thetaK
|
||
+k; //phi
|
||
}
|
||
|
||
unsigned int get_bin_in3D(int i, int j, int k, npolynom npol){
|
||
/// h = q2, i = ctl, j = ctk, k = phi
|
||
|
||
//Return the bin number for given event evt in 4D (q2, thetal, thetak, phi)
|
||
//Starting from 0!
|
||
return npol.ctk*npol.phi*i //thetaL
|
||
+npol.phi*j //thetaK
|
||
+k; //phi
|
||
}
|
||
|
||
unsigned int get_bin_in3D(int i, int j, int k, bin_edges edges){
|
||
/// h = q2, i = ctl, j = ctk, k = phi
|
||
|
||
//Return the bin number for given event evt in 4D (q2, thetal, thetak, phi)
|
||
//Starting from 0!
|
||
return edges.nctkbins*edges.nphibins*i //thetaL
|
||
+edges.nphibins*j //thetaK
|
||
+k; //phi
|
||
}
|
||
|
||
void get_chi2(bin_edges edges, npolynom npol,
|
||
std::vector<event> eventsInQ2bin, std::vector<double> coeffs_moments,
|
||
values* globalvalues,
|
||
bool assumectleven, bool assumePhiEven, bool write_eps,
|
||
std::string subfolder, std::string appendix){
|
||
|
||
spdlog::info( "Starting chi2 calculation" );
|
||
std::vector<double> nsel_hist(edges.getNbins(), 0.0);
|
||
std::vector<double> nsel_hist_errsq(edges.getNbins(), 0.0);
|
||
|
||
//this is actually not the correct error here, due to the weights!
|
||
//should be sqrt(sum_i weights_i^2)
|
||
|
||
double nsel = 0.0;
|
||
int nEvents = eventsInQ2bin.size();
|
||
for (auto &meas: eventsInQ2bin) {
|
||
unsigned int bin = get_bin_in4D(meas,edges);
|
||
nsel_hist.at(bin) += meas.weight;
|
||
nsel += meas.weight;
|
||
nsel_hist_errsq.at(bin) += sqr(meas.weight);
|
||
}
|
||
//Set errors
|
||
for (auto err: nsel_hist_errsq){
|
||
if (err == 0.0) err = 1.0;
|
||
}
|
||
|
||
//compare with prediction
|
||
double neps = 0.0;
|
||
std::vector<double> neps_hist(edges.getNbins(), 0.0);
|
||
std::vector<double> q2_edges = edges.edges_q2();
|
||
std::vector<double> ctl_edges = edges.edges_ctl();
|
||
std::vector<double> ctk_edges = edges.edges_ctk();
|
||
std::vector<double> phi_edges = edges.edges_phi();
|
||
|
||
for (unsigned int h = 0; h<edges.nq2bins; h++){
|
||
for (unsigned int i = 0; i<edges.nctlbins; i++){
|
||
for (unsigned int j = 0; j<edges.nctkbins; j++){
|
||
for (unsigned int k = 0; k<edges.nphibins; k++){
|
||
double integral = 0.0;
|
||
for (unsigned int l = 0; l<npol.q2; l++){
|
||
for (unsigned int m = 0; m<npol.ctl; m++){
|
||
for (unsigned int n = 0; n<npol.ctk; n++){
|
||
for (unsigned int o = 0; o<npol.phi; o++){
|
||
double result = coeffs_moments.at(npol.get_bin_in4D(l,m,n,o))
|
||
*(pow(q2_edges[h+1],l+1) - pow(q2_edges[h],l+1))/(l+1.0)
|
||
*(pow(ctl_edges[i+1],m+1) - pow(ctl_edges[i],m+1))/(m+1.0)
|
||
*(pow(ctk_edges[j+1],n+1) - pow(ctk_edges[j],n+1))/(n+1.0)
|
||
*(pow(phi_edges[k+1],o+1) - pow(phi_edges[k],o+1))/(o+1.0);
|
||
integral += result;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
neps_hist.at(get_bin_in4D(h,i,j,k,edges)) = integral;
|
||
neps += integral;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
spdlog::debug( "nsel {0:f}\n\t nEvents {1:d}\n\t neps {2:f}\n\t nsel/neps {3:f} ", nsel, nEvents, neps, nsel/neps );
|
||
TH1D* hpull = new TH1D("hpull", ";(N_{sel}-N_{fit})/#sqrt{N_{sel}};",100, -5.0, +5.0);
|
||
TH1D* hnsel = new TH1D("hnsel", ";N_{sel};",100, 0.0, +25.0);
|
||
TH1D* hnfit = new TH1D("hnfit", ";N_{fit};",100, 0.0, +25.0);
|
||
|
||
//rescale fitted efficiency to MC statistics
|
||
//This would be nicer in a vector of vectors or so, but oh well
|
||
for (unsigned int h = 0; h<edges.nq2bins; h++)
|
||
for (unsigned int i = 0; i<edges.nctlbins; i++)
|
||
for (unsigned int j = 0; j<edges.nctkbins; j++)
|
||
for (unsigned int k = 0; k<edges.nphibins; k++)
|
||
neps_hist.at(get_bin_in4D(h,i,j,k, edges)) *= nsel/neps;
|
||
|
||
//calculate chi2 and perform "pull" plot
|
||
double chi2 = 0.0;
|
||
|
||
//double errorscale = 1.01;
|
||
for (unsigned int h = 0; h<edges.nq2bins; h++){
|
||
for (unsigned int i = 0; i<edges.nctlbins; i++){
|
||
for (unsigned int j = 0; j<edges.nctkbins; j++){
|
||
for (unsigned int k = 0; k<edges.nphibins; k++){
|
||
unsigned int bin = get_bin_in4D(h,i,j,k, edges);
|
||
//nominal
|
||
|
||
chi2 += sqr(nsel_hist.at(bin)-neps_hist.at(bin))/fabs(neps_hist.at(bin));
|
||
hpull->Fill((nsel_hist.at(bin)-neps_hist.at(bin))/sqrt(fabs(neps_hist.at(bin))));
|
||
spdlog::trace("nsel_hist.at({0:d})\t{1:f}",bin,nsel_hist.at(bin));
|
||
spdlog::trace("neps_hist.at({0:d})\t{1:f}",bin,neps_hist.at(bin));
|
||
hnsel->Fill(nsel_hist.at(bin));
|
||
hnfit->Fill(neps_hist.at(bin));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
spdlog::debug( "chi2\t {0:f}", chi2 );
|
||
|
||
//Calculate the number of parameters
|
||
int nparams = npol.q2*npol.ctl*npol.ctk*npol.phi-1;
|
||
spdlog::debug( "Nparams\t {0:d}", nparams );
|
||
|
||
if (assumectleven && assumePhiEven){
|
||
nparams = npol.q2*((npol.ctl+1)/2)*npol.ctk*((npol.phi+1)/2)-1;
|
||
}
|
||
else{
|
||
if (assumectleven) nparams = npol.q2*((npol.ctl+1)/2)*npol.ctk*npol.phi-1;
|
||
if (assumePhiEven) nparams = npol.q2*npol.ctl*npol.ctk*((npol.phi+1)/2)-1;
|
||
}
|
||
spdlog::debug( "Nparams (accounting for even ctl and phi)\t {0:d}", nparams );
|
||
|
||
//Get degrees of freedom
|
||
int nbins = edges.getNbins();
|
||
spdlog::debug( "Nbins\t {0:d}", nbins);
|
||
|
||
int ndof = nbins - nparams - 1;
|
||
spdlog::debug( "ndof\t {0:d}", ndof );
|
||
|
||
spdlog::debug( "chi2/ndof (accounting for even ctl and phi)\t {0:f}",chi2/ndof );
|
||
spdlog::debug( "chi2/Nbins\t\t {0:f}",chi2/nbins );
|
||
spdlog::debug( "pvalue using ndof\t {0:f}",TMath::Prob(chi2, ndof) );
|
||
spdlog::debug( "pvalue using nbins\t {0:f}", TMath::Prob(chi2, nbins) );
|
||
|
||
//=========================================
|
||
//
|
||
// save chi2 to global values:
|
||
//
|
||
//=========================================
|
||
|
||
globalvalues->angacccorr_chi2 = chi2;
|
||
globalvalues->angacccorr_ndof = ndof;
|
||
|
||
//recount of nparams
|
||
int ncount = 0;
|
||
for (unsigned int l = 0; l<npol.q2; l++)
|
||
for (unsigned int m = 0; m<npol.ctl; m++)
|
||
for (unsigned int n = 0; n<npol.ctk; n++)
|
||
for (unsigned int o = 0; o<npol.phi; o++)
|
||
if (coeffs_moments.at(npol.get_bin_in4D(l,m,n,o)) != 0.0) ncount++;
|
||
spdlog::debug( "Recount of Nparams gives:\t {0:d}",ncount );
|
||
|
||
if(write_eps){
|
||
plotAndSave(hpull,"cpull",subfolder + "pull"+appendix, "eps");
|
||
plotAndSave(hnsel,"csel",subfolder + "nsel"+appendix, "eps");
|
||
plotAndSave(hnfit,"cfit",subfolder + "nfit"+appendix, "eps");
|
||
}
|
||
delete hpull;
|
||
delete hnsel;
|
||
delete hnfit;
|
||
|
||
return;
|
||
|
||
|
||
}
|
||
|
||
|
||
void get_legendre(bin_edges edges, npolynom npol,
|
||
std::vector<event> eventsInQ2bin, double nWeightedEvents,
|
||
std::vector<double> &poly_moments,
|
||
bool fejerkernel, bool assumectleven, bool assumePhiEven,
|
||
bool checkSignificance, bool calculateCovariance){
|
||
//use Legendre polynomials
|
||
spdlog::info("DOLEGENDRE start");
|
||
|
||
//should def use this:
|
||
//calculates all legendre polynomials up to including degree n
|
||
//void fcnc::legendre(double x, int n, std::vector<double>& results)
|
||
|
||
//this is not the best way to do things
|
||
//should rather
|
||
//loop over events
|
||
//determine, for every event the legendre polynomials order 0 to nq2/nctl/nctk/nphi
|
||
//loop over all orders
|
||
//add weight*leg_q2.at(h)*leg_ctl.at(i)*leg_ctk.at(j)*leg_phi.at(k) in correct bin
|
||
|
||
//optimized version
|
||
std::vector<double> chijk_moments = std::vector<double>(npol.getSize(), 0.0);
|
||
for (auto & meas: eventsInQ2bin){ //This is all computed then in the range of -1 to +1
|
||
double q2 = 2.0 * (meas.q2 - edges.q2min ) / edges.range_q2() - 1.0;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin) / edges.range_ctl()- 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin) / edges.range_ctk()- 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin) / edges.range_phi()- 1.0;
|
||
|
||
double weight = meas.weight;
|
||
//calculates all legendre polynomials up to including degree n
|
||
std::vector<double> leg_q2(npol.q2, 0.0);
|
||
fcnc::legendre(q2, npol.q2, leg_q2);
|
||
std::vector<double> leg_ctl(npol.ctl, 0.0);
|
||
fcnc::legendre(ctl, npol.ctl, leg_ctl);
|
||
std::vector<double> leg_ctk(npol.ctk, 0.0);
|
||
fcnc::legendre(ctk, npol.ctk, leg_ctk);
|
||
std::vector<double> leg_phi(npol.phi, 0.0);
|
||
fcnc::legendre(phi, npol.phi, leg_phi);
|
||
|
||
double result = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
result = 0.0;
|
||
//result
|
||
if (assumectleven && i%2 != 0 ) result = 0.0;
|
||
else if (assumePhiEven && k%2 != 0) result = 0.0;
|
||
else{
|
||
result =
|
||
weight
|
||
*leg_q2.at(h)*(2.0*h+1.0)/2.0
|
||
*leg_ctl.at(i)*(2.0*i+1.0)/2.0
|
||
*leg_ctk.at(j)*(2.0*j+1.0)/2.0
|
||
*leg_phi.at(k)*(2.0*k+1.0)/2.0
|
||
/nWeightedEvents;
|
||
if (fejerkernel)
|
||
result *= (1.0 - h/double(npol.q2-1))
|
||
*(1.0 - i/double(npol.ctl-1))
|
||
*(1.0 - j/double(npol.ctk-1))
|
||
*(1.0 - k/double(npol.phi-1));
|
||
}
|
||
chijk_moments.at(bin) += result;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//check significance
|
||
//can be optimized as above
|
||
if (checkSignificance){
|
||
spdlog::info("starting CHECK SIGNIFICANT for LEGENDRE" );
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
double result = chijk_moments.at(bin);
|
||
double sigma = 0.0;
|
||
for (unsigned int e=0; e<eventsInQ2bin.size(); e++){
|
||
const event & meas = eventsInQ2bin.at(e);
|
||
double q2 = 2.0 * (meas.q2 - edges.q2min ) / edges.range_q2() - 1.0;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin ) / edges.range_ctl() - 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin ) / edges.range_ctk() - 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin ) / edges.range_phi() - 1.0;
|
||
|
||
sigma += sqr(result - meas.weight // /nWeightedEvents
|
||
*fcnc::legendre(q2, h)*(2.0*h+1.0)/2.0
|
||
*fcnc::legendre(ctl, i)*(2.0*i+1.0)/2.0
|
||
*fcnc::legendre(ctk, j)*(2.0*j+1.0)/2.0
|
||
*fcnc::legendre(phi, k)*(2.0*k+1.0)/2.0
|
||
);// /eventsInQ2bin.size();
|
||
}
|
||
sigma = sqrt(sigma);
|
||
sigma /= nWeightedEvents;
|
||
if (fabs(result/sigma) < 1.0) chijk_moments.at(bin) = 0.0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
spdlog::info( "finished CHECK SIGNIFICANT for LEGENDRE" );
|
||
}
|
||
|
||
//Log
|
||
spdlog::debug( "//vector of legendre efficiency coefficients containing {0:d} elements", chijk_moments.size());
|
||
spdlog::trace( "legendre_coeffs_eff_4d = { " );
|
||
if (spdlog_trace()){
|
||
for (unsigned int i=0; i<chijk_moments.size(); i++){
|
||
std::cout<< std::setprecision(15) << std::scientific << chijk_moments.at(i) << (i<chijk_moments.size()-1 ? ", " : " ");
|
||
}
|
||
}
|
||
|
||
|
||
//calculate covariance
|
||
if (calculateCovariance){
|
||
const unsigned int nsize = npol.getSize();
|
||
spdlog::info( "Start COVARIANCE matrix for LEGENDRE polynoms" );
|
||
spdlog::debug( "calculating {0:d} by {1:d} convariance matrix ({2:d} doubles)" , nsize, nsize, nsize*nsize );
|
||
|
||
//optimized
|
||
std::vector<double> covariance(nsize*nsize, 0.0);
|
||
//startB = clock();
|
||
for (unsigned int e=0; e<eventsInQ2bin.size(); e++){
|
||
if (e % (eventsInQ2bin.size()/100) == 0)spdlog::debug( "{0:f}%", round(double(e*100)/eventsInQ2bin.size()));
|
||
const event & meas = eventsInQ2bin.at(e);
|
||
|
||
double q2 = 2.0 * (meas.q2 - edges.q2min ) / edges.range_q2() - 1.0;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin) / edges.range_ctl()- 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin) / edges.range_ctk()- 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin) / edges.range_phi()- 1.0;
|
||
|
||
double weight = meas.weight;
|
||
//calculates all legendre polynomials up to including degree n
|
||
std::vector<double> leg_q2(npol.q2, 0.0);
|
||
legendre(q2, npol.q2, leg_q2);
|
||
std::vector<double> leg_ctl(npol.ctl, 0.0);
|
||
legendre(ctl, npol.ctl, leg_ctl);
|
||
std::vector<double> leg_ctk(npol.ctk, 0.0);
|
||
legendre(ctk, npol.ctk, leg_ctk);
|
||
std::vector<double> leg_phi(npol.phi, 0.0);
|
||
legendre(phi, npol.phi, leg_phi);
|
||
double wfactor = weight*weight/(nWeightedEvents*nWeightedEvents);
|
||
double resulti=0.0, resultj=0.0, cov=0.0;
|
||
unsigned int bini=0, binj=0;
|
||
|
||
int hfactor=0, ifactor=0, jfactor=0, kfactor=0,
|
||
lfactor=0, mfactor=0, nfactor=0, ofactor=0,
|
||
hifactor=0, hijfactor=0, hijkfactor=0,
|
||
lmfactor=0, lmnfactor=0, lmnofactor=0;
|
||
double aq2=0.0,aq2ctl=0.0,aq2ctlctk=0.0,aq2ctlctkphi=0.0;
|
||
double bq2=0.0,bq2ctl=0.0,bq2ctlctk=0.0,bq2ctlctkphi=0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
hfactor = (2*h+1);
|
||
aq2 = 0.0625*leg_q2[h];
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
ifactor = (2*i+1);
|
||
hifactor = hfactor*ifactor;
|
||
aq2ctl = aq2*leg_ctl[i];
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
jfactor = (2*j+1);
|
||
hijfactor = hifactor*jfactor;
|
||
aq2ctlctk = aq2ctl*leg_ctk[j];
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
kfactor = (2*k+1);
|
||
hijkfactor = hijfactor*kfactor;
|
||
aq2ctlctkphi = aq2ctlctk*leg_phi[k];
|
||
bini = npol.get_bin_in4D(h,i,j,k);
|
||
resulti = chijk_moments[bini];
|
||
if (resulti != 0.0){
|
||
for (unsigned int l = 0; l<npol.q2; l++){
|
||
lfactor = (2*l+1);
|
||
bq2 = 0.0625*leg_q2[l];
|
||
for (unsigned int m = 0; m<npol.ctl; m++)
|
||
{
|
||
mfactor = (2*m+1);
|
||
lmfactor = lfactor*mfactor;
|
||
bq2ctl = bq2*leg_ctl[m];
|
||
for (unsigned int n = 0; n<npol.ctk; n++){
|
||
nfactor = (2*n+1);
|
||
lmnfactor = lmfactor*nfactor;
|
||
bq2ctlctk = bq2ctl*leg_ctk[n];
|
||
for (unsigned int o = 0; o<npol.phi; o++){
|
||
ofactor = (2*o+1);
|
||
lmnofactor = lmnfactor*ofactor;
|
||
bq2ctlctkphi = bq2ctlctk*leg_phi[o];
|
||
|
||
binj = npol.get_bin_in4D(l,m,n,o);
|
||
resultj = chijk_moments[binj];
|
||
if (binj <= bini && resultj != 0.0){
|
||
cov = (wfactor
|
||
*(resulti-hijkfactor*aq2ctlctkphi)
|
||
*(resultj-lmnofactor*bq2ctlctkphi)
|
||
);
|
||
covariance[nsize*bini+binj] += cov;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
for (unsigned int bini = 0; bini<nsize; bini++){
|
||
for (unsigned int binj = 0; binj<nsize; binj++){
|
||
//covariance matrix is symmetric
|
||
if (binj < bini) covariance.at(nsize*binj+bini) = covariance.at(nsize*bini+binj);
|
||
}
|
||
}
|
||
|
||
//Print uncertanities in a matrix
|
||
spdlog::info("uncertainties[{0:0.8e}]", nsize);
|
||
for (unsigned int i =0; i<nsize; i++) std::cout << covariance.at(nsize*i+i) << (i < nsize-1 ? ", " : " };");
|
||
|
||
|
||
//Print covariance matrix
|
||
spdlog::info("Covariance matrix cov[{0:0.8e}]", nsize*nsize);
|
||
for (unsigned int i =0; i<nsize; i++){
|
||
for (unsigned int j =0; j<nsize; j++){
|
||
std::cout <<covariance.at(nsize*i+j) << ", ";
|
||
}
|
||
std::cout << std::endl;
|
||
}
|
||
std::cout << "};" << std::endl;//needs to be converted into correct range and translated to monomial coefficients? no, should do these transformations after every acceptance randomization
|
||
|
||
double correlation = 0.0;
|
||
for (unsigned int i =0; i<nsize; i++){
|
||
for (unsigned int j =0; j<nsize; j++){
|
||
double corr = covariance.at(nsize*i+j)/sqrt(covariance.at(nsize*i+i))/sqrt(covariance.at(nsize*j+j));
|
||
if (fabs(corr) > fabs(correlation) && i != j) correlation = corr;
|
||
}
|
||
}
|
||
spdlog::info("Largest correlation found is {0:f}", correlation );
|
||
}
|
||
|
||
spdlog::debug("start CONVERT legendre to monomial coefficients" );
|
||
//transform legendre coefficients to monomial coefficients
|
||
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double tmp = chijk_moments.at(npol.get_bin_in4D(h,i,j,k));
|
||
|
||
std::vector<double> leg_coeffs_q2(npol.q2, 0.0);
|
||
std::vector<double> leg_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> leg_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> leg_coeffs_phi(npol.phi, 0.0);
|
||
|
||
std::vector<double> poly_coeffs_q2(npol.q2, 0.0);
|
||
std::vector<double> poly_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> poly_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> poly_coeffs_phi(npol.phi, 0.0);
|
||
|
||
leg_coeffs_q2.at(h) = 1.0;
|
||
leg_coeffs_ctl.at(i) = 1.0;
|
||
leg_coeffs_ctk.at(j) = 1.0;
|
||
leg_coeffs_phi.at(k) = 1.0;
|
||
|
||
legendre_to_poly(leg_coeffs_q2, poly_coeffs_q2);
|
||
legendre_to_poly(leg_coeffs_ctl, poly_coeffs_ctl);
|
||
legendre_to_poly(leg_coeffs_ctk, poly_coeffs_ctk);
|
||
legendre_to_poly(leg_coeffs_phi, poly_coeffs_phi);
|
||
|
||
for (unsigned int l = 0; l<=h; l++)
|
||
for (unsigned int m = 0; m<=i; m++)
|
||
for (unsigned int n = 0; n<=j; n++)
|
||
for (unsigned int o = 0; o<=k; o++){
|
||
unsigned int bin = npol.get_bin_in4D(l,m,n,o);
|
||
poly_moments.at(bin) += tmp*poly_coeffs_q2.at(l)*poly_coeffs_ctl.at(m)*poly_coeffs_ctk.at(n)*poly_coeffs_phi.at(o);
|
||
}
|
||
}//tested, works
|
||
spdlog::debug( "end CONVERT legendre to monomial coefficients" );
|
||
spdlog::debug( "poly_moments size: {0:d}", poly_moments.size() );
|
||
|
||
spdlog::info( "DOLEGENDRE end" );
|
||
|
||
}
|
||
|
||
void get_chebyschev(bin_edges edges, npolynom npol,
|
||
std::vector<event> eventsInQ2bin, double nWeightedEvents,
|
||
std::vector<double> &poly_moments,
|
||
bool fejerkernel, bool assumectleven, bool assumePhiEven,
|
||
bool checkSignificance, bool calculateCovariance
|
||
){
|
||
//use Legendre polynomials
|
||
spdlog::info("CHEBYSCHEV start");
|
||
std::vector<double> chijk_moments = std::vector<double>(npol.getSize(), 0.0);
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double result = 0.0;
|
||
if (assumectleven && i%2 != 0)result = 0.0;
|
||
else if (assumePhiEven && k%2 != 0)result = 0.0;
|
||
else{
|
||
for (auto &meas: eventsInQ2bin){
|
||
double q2 = 2.0 * (meas.q2 - edges.q2min ) / edges.range_q2() - 1.0;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin) / edges.range_ctl()- 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin) / edges.range_ctk()- 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin) / edges.range_phi()- 1.0;
|
||
|
||
result += meas.weight
|
||
*fcnc::chebyshev(q2, h)/sqrt(1.0-q2*q2)*(h == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctl, i)/sqrt(1.0-ctl*ctl)*(i == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctk, j)/sqrt(1.0-ctk*ctk)*(j == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(phi, k)/sqrt(1.0-phi*phi)*(k == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
/nWeightedEvents;// /eventsInQ2bin.size();
|
||
}
|
||
if (fejerkernel){
|
||
result *= (1.0 - h/double(npol.q2-1))
|
||
*(1.0 - i/double(npol.ctl-1))
|
||
*(1.0 - j/double(npol.ctk-1))
|
||
*(1.0 - k/double(npol.phi-1));
|
||
}
|
||
}
|
||
|
||
//now have the "mean" in result
|
||
//mu = sum_i w_i/N
|
||
//sigma(mu) = sqrt(sum_i (w_i-mu)^2)/N
|
||
//else
|
||
chijk_moments.push_back(result);
|
||
}
|
||
//check significance
|
||
if (checkSignificance){
|
||
spdlog::info( "start CHECK SIGNIFICANCE for CHEBYSHEV polynoms" );
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
double result = chijk_moments.at(bin);
|
||
double sigma = 0.0;
|
||
for (auto &meas : eventsInQ2bin){
|
||
double q2 = 2.0 * (meas.q2 - edges.q2min ) / edges.range_q2() - 1.0;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin) / edges.range_ctl()- 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin) / edges.range_ctk()- 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin) / edges.range_phi()- 1.0;
|
||
sigma += sqr(result - meas.weight // /nWeightedEvents
|
||
*fcnc::chebyshev(q2, h)/sqrt(1-q2*q2)*(h == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctl, i)/sqrt(1-ctl*ctl)*(i == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctk, j)/sqrt(1-ctk*ctk)*(j == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(phi, k)/sqrt(1-phi*phi)*(k == 0 ? 1.0/MY_PI : 2.0/MY_PI));// /eventsInQ2bin.size();
|
||
}
|
||
sigma = sqrt(sigma);
|
||
sigma /= nWeightedEvents;
|
||
if (fabs(result/sigma) < 1.0) chijk_moments.at(bin) = 0.0;
|
||
}
|
||
spdlog::info( "end CHECK SIGNIFICANCE for CHEBYSHEV polynoms" );
|
||
}
|
||
//printchebyshev
|
||
spdlog::debug( "//vector of chebyshev efficiency coefficients containing {0:d} elements",chijk_moments.size());
|
||
spdlog::trace( "chebyshev_coeffs_eff_4d = { " );
|
||
if (spdlog_trace()){
|
||
for (unsigned int i=0; i<chijk_moments.size(); i++){
|
||
std::cout<< std::setprecision(15) << std::scientific << chijk_moments.at(i) << (i<chijk_moments.size()-1 ? ", " : " ");
|
||
}
|
||
}
|
||
|
||
|
||
//calculate covariance
|
||
|
||
if (calculateCovariance){
|
||
spdlog::debug( "calculating {0:d} by {1:d} convariance matrix ({2:d} doubles)" , npol.getSize(), npol.getSize(), npol.getSize2() );
|
||
std::vector<double> covariance(npol.getSize2(), 0.0);
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
unsigned int bini = npol.get_bin_in4D(h,i,j,k);
|
||
double resulti = chijk_moments.at(bini);
|
||
if (resulti != 0.0){
|
||
for (unsigned int l = 0; l<npol.q2; l++){
|
||
for (unsigned int m = 0; m<npol.ctl; m++){
|
||
for (unsigned int n = 0; n<npol.ctk; n++){
|
||
for (unsigned int o = 0; o<npol.phi; o++){
|
||
unsigned int binj = npol.get_bin_in4D(l,m,n,o);
|
||
if (binj > bini) continue;//covariance matrix is symmetric
|
||
double resultj = chijk_moments.at(binj);
|
||
if (((bini*npol.getSize()+binj) * 100) % (npol.getSize2()) == 0)
|
||
spdlog::debug( "covariance matrix calculation {0:f}%", ((bini*npol.getSize()+binj) * 100) / (npol.getSize2()));
|
||
if (resultj != 0.0){
|
||
double cov = 0.0;
|
||
for (auto &meas : eventsInQ2bin){
|
||
double q2 = 2.0 * (meas.q2 - edges.q2min ) / edges.range_q2() - 1.0;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin) / edges.range_ctl()- 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin) / edges.range_ctk()- 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin) / edges.range_phi()- 1.0;
|
||
|
||
|
||
cov += ((resulti - meas.weight
|
||
*fcnc::chebyshev(q2, h)/sqrt(1-q2*q2)*(h == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctl, i)/sqrt(1-ctl*ctl)*(i == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctk, j)/sqrt(1-ctk*ctk)*(j == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(phi, k)/sqrt(1-phi*phi)*(k == 0 ? 1.0/MY_PI : 2.0/MY_PI))
|
||
*(resultj - meas.weight
|
||
*fcnc::chebyshev(q2, l)/sqrt(1-q2*q2)*(l == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctl, m)/sqrt(1-ctl*ctl)*(m == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctk, n)/sqrt(1-ctk*ctk)*(n == 0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(phi, o)/sqrt(1-phi*phi)*(o == 0 ? 1.0/MY_PI : 2.0/MY_PI))
|
||
);
|
||
}
|
||
//cov = sqrt(cov); //to get sigma on diagonal
|
||
cov /= sqr(nWeightedEvents);
|
||
covariance.at(npol.getSize()*bini+binj) = cov;
|
||
covariance.at(npol.getSize()*binj+bini) = cov;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
spdlog::info("uncertainties[{0:0.8e}]", npol.getSize());
|
||
if (spdlog_info()){
|
||
for (unsigned int i =0; i<npol.getSize(); i++){
|
||
std::cout <<covariance.at(npol.getSize()*i+i) << (i < npol.getSize()-1 ? ", " : " };");
|
||
}
|
||
std::cout << std::endl;//needs to be converted into correct range and translated to monomial coefficients?
|
||
}
|
||
|
||
spdlog::info("Covariance matrix cov[{0:0.8e}]", npol.getSize2());
|
||
for (unsigned int i =0; i<npol.getSize(); i++){
|
||
for (unsigned int j =0; j<npol.getSize(); j++){
|
||
std::cout << covariance.at(npol.getSize()*i+j) << ", ";
|
||
}
|
||
std::cout << std::endl;
|
||
}
|
||
std::cout <<"};" << std::endl;//needs to be converted into correct range and translated to monomial coefficients? no, should do these transformations after every acceptance randomization
|
||
double correlation = 0.0;
|
||
for (unsigned int i =0; i<npol.getSize(); i++)
|
||
for (unsigned int j =0; j<npol.getSize(); j++)
|
||
{
|
||
double corr = covariance.at(npol.getSize()*i+j)/sqrt(covariance.at(npol.getSize()*i+i))/sqrt(covariance.at(npol.getSize()*j+j));
|
||
if (fabs(corr) > fabs(correlation) && i != j)
|
||
correlation = corr;
|
||
}
|
||
spdlog::info( "Largest correlation found is {0:f}", correlation );
|
||
}
|
||
//transform chebyshev coefficients to monomial coefficients
|
||
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double c = chijk_moments.at(npol.get_bin_in4D(h,i,j,k));
|
||
|
||
std::vector<double> ch_coeffs_q2(npol.q2, 0.0);
|
||
std::vector<double> ch_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> ch_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> ch_coeffs_phi(npol.phi, 0.0);
|
||
|
||
std::vector<double> poly_coeffs_q2(npol.q2, 0.0);
|
||
std::vector<double> poly_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> poly_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> poly_coeffs_phi(npol.phi, 0.0);
|
||
|
||
ch_coeffs_q2.at(h) = 1.0;
|
||
ch_coeffs_ctl.at(i) = 1.0;
|
||
ch_coeffs_ctk.at(j) = 1.0;
|
||
ch_coeffs_phi.at(k) = 1.0;
|
||
|
||
chebyshev_to_poly(ch_coeffs_q2, poly_coeffs_q2);
|
||
chebyshev_to_poly(ch_coeffs_ctl, poly_coeffs_ctl);
|
||
chebyshev_to_poly(ch_coeffs_ctk, poly_coeffs_ctk);
|
||
chebyshev_to_poly(ch_coeffs_phi, poly_coeffs_phi);
|
||
|
||
for (unsigned int l = 0; l<=h; l++){
|
||
for (unsigned int m = 0; m<=i; m++){
|
||
for (unsigned int n = 0; n<=j; n++){
|
||
for (unsigned int o = 0; o<=k; o++){
|
||
unsigned int bin = npol.get_bin_in4D(l,m,n,o);
|
||
poly_moments.at(bin) += c*poly_coeffs_q2.at(l)*poly_coeffs_ctl.at(m)*poly_coeffs_ctk.at(n)*poly_coeffs_phi.at(o);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
double integrate_4D(bin_edges edges, int h, int i, int j, int k){
|
||
return integrate_x_to_n(edges.q2min, edges.q2max,h)//careful with q2max
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax,i)
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax,j)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
}
|
||
|
||
double integrate_3D(bin_edges edges, int i, int j, int k){
|
||
return integrate_x_to_n(edges.ctlmin, edges.ctlmax,i)
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax,j)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
}
|
||
|
||
void fill_moments_hist_1D(TH1D *hist_moments, std::vector<double> coeffs_moments,
|
||
bin_edges edges, npolynom npol, double q2low, double q2high){
|
||
|
||
bool do_ctl = (std::string(hist_moments->GetName()).find("ctl") != std::string::npos);
|
||
bool do_ctk = (std::string(hist_moments->GetName()).find("ctk") != std::string::npos);
|
||
bool do_phi = (std::string(hist_moments->GetName()).find("phi") != std::string::npos);
|
||
bool do_q2 = (std::string(hist_moments->GetName()).find("q2") != std::string::npos);
|
||
|
||
for (int l=1; l<=hist_moments->GetNbinsX(); l++){
|
||
double a = hist_moments->GetBinLowEdge(l);
|
||
double b = hist_moments->GetBinLowEdge(l+1);
|
||
double integral = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double result = coeffs_moments.at(npol.get_bin_in4D(h,i,j,k))
|
||
*(pow(do_q2 ? b : q2high ,h+1)/(h+1.0) - pow(do_q2 ? a : q2low ,h+1)/(h+1.0)) //Possibly replace by get_result;
|
||
*(pow(do_ctl ? b : edges.ctlmax,i+1)/(i+1.0) - pow(do_ctl ? a : edges.ctlmin,i+1)/(i+1.0))
|
||
*(pow(do_ctk ? b : edges.ctkmax,j+1)/(j+1.0) - pow(do_ctk ? a : edges.ctkmin,j+1)/(j+1.0))
|
||
*(pow(do_phi ? b : edges.phimax,k+1)/(k+1.0) - pow(do_phi ? a : edges.phimin,k+1)/(k+1.0));
|
||
integral += result;
|
||
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
hist_moments->SetBinContent(l, integral);
|
||
}
|
||
return;
|
||
|
||
}
|
||
|
||
|
||
void fill_moments_hist_2D(TH2D *hist_moments, std::vector<double> coeffs_moments,
|
||
bin_edges edges, npolynom npol, double q2low, double q2high){
|
||
|
||
bool do_ctl = (std::string(hist_moments->GetName()).find("ctl") != std::string::npos);
|
||
bool do_ctk = (std::string(hist_moments->GetName()).find("ctk") != std::string::npos);
|
||
bool do_phi = (std::string(hist_moments->GetName()).find("phi") != std::string::npos);
|
||
bool do_q2 = (std::string(hist_moments->GetName()).find("q2") != std::string::npos);
|
||
|
||
spdlog::trace("do_ctl\t"+boolToString(do_ctl));
|
||
spdlog::trace("do_ctk\t"+boolToString(do_ctk));
|
||
spdlog::trace("do_phi\t"+boolToString(do_phi));
|
||
spdlog::trace("do_q2\t"+boolToString(do_q2));
|
||
bool is_ctl_First = !do_q2; //ctl is second if q2
|
||
bool is_ctk_First = !(do_q2 || do_ctl); //ctk is second if ctl or q2
|
||
//phi is always second and q2 always first
|
||
spdlog::trace("is_ctl_First\t"+boolToString(is_ctl_First));
|
||
spdlog::trace("is_ctk_First\t"+boolToString(is_ctk_First));
|
||
|
||
for (int l=1; l<=hist_moments->GetNbinsX(); l++){
|
||
double a = hist_moments->GetXaxis()->GetBinLowEdge(l);
|
||
double b = hist_moments->GetXaxis()->GetBinLowEdge(l+1);
|
||
for (int m=1; m<=hist_moments->GetNbinsY(); m++){
|
||
double c = hist_moments->GetYaxis()->GetBinLowEdge(m);
|
||
double d = hist_moments->GetYaxis()->GetBinLowEdge(m+1);
|
||
double integral = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double result = coeffs_moments.at(npol.get_bin_in4D(h,i,j,k))
|
||
*integrate_x_to_n(do_q2 ? a : q2low, do_q2 ? b : q2high ,h)
|
||
*integrate_x_to_n(do_ctl ? (is_ctl_First ? a : c) : edges.ctlmin,
|
||
do_ctl ? (is_ctl_First ? b : d) : edges.ctlmax,i)
|
||
*integrate_x_to_n(do_ctk ? (is_ctk_First ? a : c) : edges.ctkmin,
|
||
do_ctk ? (is_ctk_First ? b : d) : edges.ctkmax, j)
|
||
*integrate_x_to_n(do_phi ? c : edges.phimin,do_phi ? d : edges.phimax,k);
|
||
integral += result;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
spdlog::trace("\t*** fill_moments_hist_2D: ***\t´");
|
||
spdlog::trace("l: {0:d}\tm: {1:d}\tint: {2:f}", l, m, integral);
|
||
hist_moments->SetBinContent(l, m, integral);
|
||
}
|
||
}
|
||
return;
|
||
|
||
}
|
||
|
||
|
||
int get_correct_index(std::string whichVar, int l, int m, int n, int o){
|
||
if (whichVar == "q2") return l;
|
||
if (whichVar == "ctl") return m;
|
||
if (whichVar == "ctk") return n;
|
||
if (whichVar == "phi") return o;
|
||
return -1;
|
||
}
|
||
int change_index(std::string whichVar, npolynom npol, int p, int l, int m, int n, int o){
|
||
if (whichVar == "q2") return npol.get_bin_in4D(p,m,n,o);
|
||
if (whichVar == "ctl") return npol.get_bin_in4D(l,p,n,o);
|
||
if (whichVar == "ctk") return npol.get_bin_in4D(l,m,p,o);
|
||
if (whichVar == "phi") return npol.get_bin_in4D(l,m,n,p);
|
||
return -1;
|
||
}
|
||
void correct_coefficients(npolynom npol, bin_edges edges, std::vector<double> &out_poly_moments, std::vector<double> in_poly_moments, std::string whichVar){
|
||
//Just rebin
|
||
unsigned int npol_var;
|
||
double intvar_min;
|
||
double intvar_max;
|
||
if (whichVar == "q2"){ //If this would be na efin array, my life would be orders of magnitute easier
|
||
npol_var = npol.q2;
|
||
intvar_min = edges.q2min;
|
||
intvar_max = edges.q2max;
|
||
}
|
||
else if (whichVar == "ctl") {
|
||
npol_var = npol.ctl;
|
||
intvar_min = edges.ctlmin;
|
||
intvar_max = edges.ctlmax;
|
||
}
|
||
else if (whichVar == "ctk") {
|
||
npol_var = npol.ctk;
|
||
intvar_min = edges.ctkmin;
|
||
intvar_max = edges.ctkmax;
|
||
}
|
||
else if (whichVar == "phi") {
|
||
npol_var = npol.phi;
|
||
intvar_min = edges.phimin;
|
||
intvar_max = edges.phimax;
|
||
}
|
||
else{
|
||
spdlog::error("Wrong index name! Either q2, ctl, ctk or phi!");
|
||
assert (0);
|
||
}
|
||
spdlog::debug("npol_var = {0:d}\tintvar_min = {1:f}\tintvar_max = {2:f}", npol_var, intvar_min, intvar_max);
|
||
for (unsigned int l = 0; l<npol.q2; l++){
|
||
for (unsigned int m = 0; m<npol.ctl; m++){
|
||
for (unsigned int n = 0; n<npol.ctk; n++){
|
||
for (unsigned int o = 0; o<npol.phi; o++){
|
||
unsigned int bin = npol.get_bin_in4D(l,m,n,o);
|
||
|
||
spdlog::trace("l={0:d}\tm={1:d}\tn={2:d}\to={3:d}\t bin ={4:d}",l,m,n,o,bin);
|
||
std::vector<double> poly(npol_var, 0.0);
|
||
poly.at(get_correct_index(whichVar,l,m,n,o)) = in_poly_moments.at(bin);
|
||
std::vector<double> correct(npol_var, 0.0);
|
||
correct_poly(poly, correct, intvar_min, intvar_max);
|
||
for (unsigned int p = 0; p<npol_var; p++){
|
||
unsigned int tobin = change_index(whichVar,npol,p,l,m,n,o);
|
||
spdlog::trace("p={0:d}\t tobin ={1:d}",p,tobin);
|
||
out_poly_moments.at(tobin) += correct.at(p);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
void bu2kstarmumu_pdf::parametrize_eff_phsp_4d(const std::vector<event>& events, values* globalvalues, int tagNumber, bool assumePhiEven, bool checkSignificance, bool runMinuit, bool checkFactorization, bool do3Dmoments){
|
||
|
||
spdlog::debug("----> start parametrization of angular acceptance correction coefficients with {0:d} events.", events.size());
|
||
|
||
const UInt_t nBinsQ2 = 40;
|
||
const UInt_t nBinsAngles = 40;
|
||
|
||
bool ignore_q2weights = false;
|
||
if (ignore_q2weights) spdlog::warn("Not using weights from genLvl PHSP to flatten the q2 distribution!!!");
|
||
|
||
//Get the pointer to this class of bu2kstarmumu_pdf
|
||
current_pdf = this;
|
||
|
||
std::vector<double> q2binsmin = opts->TheQ2binsmin; //Check TheQ2binsmax and q2binsmin
|
||
std::vector<double> q2binsmax = opts->TheQ2binsmax;
|
||
spdlog::debug("Vector q2binsmin:\t"+convert_vector_to_string(q2binsmin));
|
||
spdlog::debug("Vector q2binsmax:\t"+convert_vector_to_string(q2binsmax));
|
||
|
||
//name tag for all plots:
|
||
std::string appendix = "_"+DECAY_NAME
|
||
+ (opts->KS ? opts->DDLL+"_" : "_")
|
||
+ "Run" + std::to_string(opts->run)
|
||
+ ((opts->angacccorrperyear && opts->year != -1) ? "_"+std::to_string(opts->year) : "")
|
||
+ ((opts->folding != -1) ? "_folding"+std::to_string(opts->folding) : "")
|
||
+ ((opts->systematic == 3) ? "_"+std::to_string(opts->orderincrease)+"moreOrders" : "")
|
||
+ std::string(tagNumber != 0 ? "_"+std::to_string(tagNumber) : "");
|
||
std::string subfolder = "plots/angular/" + std::string(tagNumber != 0 ? "test/" : "");
|
||
spdlog::debug("Saving all plots into folder " + subfolder);
|
||
|
||
//Set orders of chebyshev/legendre polynomials
|
||
npolynom npol(opts); //Should be a const, but then all the future shuffling gets difficult
|
||
|
||
//fold the events if needed:
|
||
spdlog::debug("Init folder....");
|
||
//TODO remove fcnc::folder fldr(opts);
|
||
//only accept events inside q2min and q2max
|
||
std::vector<event> filtered_events;
|
||
//std::vector<event> fullrange_events;
|
||
unsigned int ee;
|
||
unsigned int N = events.size();
|
||
TRandom3 * rnd = new TRandom3(15*opts->job_id);
|
||
|
||
spdlog::debug("Filtering events...");
|
||
for (unsigned int e=0; e<N; e++){
|
||
//choose random events for bootstrapping
|
||
if (opts->systematic == 1) ee = int(rnd->Rndm() * N);
|
||
else ee = e; //or the correct, nominal order
|
||
fcnc::event evt = events.at(ee);
|
||
if (!isEvtInAngleRange(&(evt), opts)) continue;
|
||
filtered_events.push_back(evt);
|
||
if(!opts->full_angular) fldr->fold(&filtered_events.back());
|
||
}
|
||
|
||
if (!ignore_q2weights){
|
||
spdlog::debug("Getting q2 weights...");
|
||
//weight for all events, reweight from PHSP q2 model to flat q2 distribution using histogram
|
||
TFile* fphspweightq2 = new TFile(CONFIG_PHSP_WEIGHT.c_str());
|
||
TH1D* phspweightq2 = dynamic_cast<TH1D*>(fphspweightq2->Get(opts->IsFlatQ2 ? "flatq2weights" : "phspweightq2"));
|
||
|
||
bool keep_weights = opts->systematic != 2;
|
||
bool vary_weights = opts->systematic == 4;
|
||
|
||
//reweight filtered events
|
||
for (auto evt: filtered_events){
|
||
double q2 = evt.q2;
|
||
|
||
if(vary_weights){
|
||
evt.weight += evt.delta_weight * rnd->Gaus(0., 1.);
|
||
}
|
||
|
||
if (q2 < 0.2){
|
||
if(keep_weights) evt.weight *= phspweightq2->GetBinContent(2);//keep loaded totalweight!
|
||
else evt.weight = phspweightq2->GetBinContent(2);
|
||
}
|
||
else{
|
||
int bin = phspweightq2->FindFixBin(q2);
|
||
if (bin >=1 && bin <= phspweightq2->GetNbinsX()){
|
||
if(keep_weights) evt.weight *= phspweightq2->GetBinContent(bin);//keep loaded totalweight!
|
||
else evt.weight = phspweightq2->GetBinContent(bin);
|
||
}
|
||
}
|
||
}
|
||
|
||
delete phspweightq2;
|
||
fphspweightq2->Close();
|
||
delete fphspweightq2;
|
||
}
|
||
|
||
//for systematic 9: trigger weights, multiply existing weights by 1/L0Muon_eff
|
||
if(opts->systematic == 9){
|
||
spdlog::debug("Getting systematic 9");
|
||
//get years from current data-set:
|
||
std::vector<int> years; //empty vector
|
||
for (auto event: filtered_events){
|
||
bool year_found = false;
|
||
for(auto yr: years){
|
||
if(yr == event.year){
|
||
year_found = true;
|
||
break;
|
||
}
|
||
}
|
||
if(!year_found) years.push_back(event.year); //First event always gets filled
|
||
//Technically one should make an if to check it is all years, but given the size of the event sample this is okayish
|
||
}
|
||
assert(years.size());
|
||
std::sort(years.begin(), years.end());
|
||
|
||
//get L0Muon efficiency histo(s)
|
||
TFile * f_L0_w[years.size()];
|
||
TH1D * h_L0_w[years.size()];
|
||
for(unsigned int y = 0; y < years.size(); y++){
|
||
f_L0_w[y] = new TFile((std::string("config/")+(opts->KS?"KshortPiplus":"KplusPi0Resolved")+"_L0MuonEfficiency_"+std::to_string(years.at(y))+".root").c_str(), "READ");
|
||
if(!f_L0_w[y]->IsOpen()){
|
||
spdlog::critical( "Could not find file with L0Muon efficiencies: 'config/" + std::string(opts->KS ? "KshortPiplus" : "KplusPi0Resolved") + "_L0MuonEfficiency_{0:d}.root'", years.at(y) );
|
||
assert(0);
|
||
}
|
||
h_L0_w[y] = dynamic_cast<TH1D*>(f_L0_w[y]->Get("L0MuonEffRatioPHSP"));
|
||
spdlog::info("Succesfully loaded L0Muon efficiency reweighting histogram for year={0:d}", years.at(y));
|
||
}
|
||
|
||
for (unsigned int i=0; i<filtered_events.size(); i++){
|
||
double max_mu_pt = filtered_events.at(i).max_mu_pt;
|
||
unsigned int year_idx = 0;
|
||
for(unsigned int y = 0; y < years.size(); y++){
|
||
if(years.at(y) == filtered_events.at(i).year){
|
||
year_idx = y;
|
||
break;
|
||
}
|
||
}
|
||
if(max_mu_pt > 20000.){
|
||
filtered_events.at(i).weight *= h_L0_w[year_idx]->GetBinContent(h_L0_w[year_idx]->GetNbinsX());
|
||
}
|
||
else{
|
||
int bin = h_L0_w[year_idx]->FindFixBin(max_mu_pt);
|
||
filtered_events.at(i).weight *= h_L0_w[year_idx]->GetBinContent(bin);
|
||
}
|
||
}
|
||
|
||
for(unsigned int y = 0; y < years.size(); y++){
|
||
delete h_L0_w[y];
|
||
f_L0_w[y]->Close();
|
||
delete f_L0_w[y];
|
||
}
|
||
}
|
||
|
||
//set the pointer that is accessible from the minuit fcn
|
||
eff_events = filtered_events;
|
||
|
||
//make plot to check weight distribution if running a test
|
||
if(tagNumber >0){
|
||
spdlog::debug("Plotting weights");
|
||
TH1D* hweight = new TH1D("hweight", ";w;", 100, 0.0, 1.0/EFF_CUTOFF);
|
||
for (unsigned int i=0; i<filtered_events.size(); i++){
|
||
spdlog::trace("Weight of event {0:d}\t\t{1:f}", i , filtered_events.at(i).weight);
|
||
hweight->Fill(filtered_events.at(i).weight);
|
||
}
|
||
TCanvas * cweights = new TCanvas();
|
||
cweights->cd();
|
||
hweight->Draw("");
|
||
if(opts->write_eps)cweights->Print((subfolder + "weights"+appendix+".eps").c_str(), "eps");
|
||
if(opts->write_eps)cweights->Print((subfolder + "weights"+appendix+".root").c_str(), "root");
|
||
|
||
delete hweight;
|
||
delete cweights;
|
||
}
|
||
|
||
//---------------------------------------
|
||
//DETERMINATION FROM ACCEPTANCE HISTOGRAM
|
||
//---------------------------------------
|
||
unsigned int nq2bins = 18;
|
||
unsigned int nctlbins = 10;
|
||
unsigned int nctkbins = 10;
|
||
unsigned int nphibins = 5;
|
||
|
||
bool adapt_bins_to_folding = false;
|
||
if(adapt_bins_to_folding){
|
||
nphibins /= 2;
|
||
if(opts->folding > 0)nctlbins /= 2;
|
||
}
|
||
|
||
spdlog::debug("Options: ");
|
||
spdlog::debug("q2min={0:f}\tq2max={1:f}", opts->TheQ2binsmin.front(),opts->TheQ2binsmax.back());
|
||
spdlog::debug("ctkmin={0:f}\tctkmax={1:f}", opts->ctk_min, opts->ctk_max);
|
||
spdlog::debug("ctlmin={0:f}\tctlmax={1:f}", opts->ctl_min, opts->ctl_max);
|
||
spdlog::debug("phimin={0:f}\tphimax={1:f}", opts->phi_min, opts->phi_max);
|
||
bin_edges edges (opts, nq2bins, nctlbins, nctkbins, nphibins);
|
||
const std::vector<double> q2_edges = edges.edges_q2();
|
||
const std::vector<double> ctl_edges = edges.edges_ctl();
|
||
const std::vector<double> ctk_edges = edges.edges_ctk();
|
||
const std::vector<double> phi_edges = edges.edges_phi(); //This could've been a struct/class
|
||
|
||
spdlog::trace("q2 edges: " + convert_vector_to_string(q2_edges));
|
||
spdlog::trace("ctl edges: " + convert_vector_to_string(ctl_edges));
|
||
spdlog::trace("ctk edges: " + convert_vector_to_string(ctk_edges));
|
||
spdlog::trace("phi edges: " + convert_vector_to_string(phi_edges));
|
||
|
||
|
||
//should compare full 4D with
|
||
//3D in q2 bins
|
||
//3D factorizing in bins of q2
|
||
|
||
spdlog::debug("Getting number of weighted events...");
|
||
std::vector<double> eps_hist(edges.getNbins(), 0.0);
|
||
double nWeightedEvents = 0.0;
|
||
for (auto &meas: filtered_events){
|
||
unsigned int bin = get_bin_in4D(meas,edges);
|
||
eps_hist.at(bin) += meas.weight;
|
||
nWeightedEvents += meas.weight;
|
||
}
|
||
|
||
//rescale efficiency
|
||
spdlog::debug("Rescaling efficiency...");
|
||
for (unsigned int h = 0; h<edges.nq2bins; h++){
|
||
for (unsigned int i = 0; i<edges.nctlbins; i++){
|
||
for (unsigned int j = 0; j<edges.nctkbins; j++){
|
||
for (unsigned int k = 0; k<edges.nphibins; k++){
|
||
eps_hist.at(get_bin_in4D(h,i,j,k,edges)) *= edges.getNbins()/nWeightedEvents;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//determine xis in bins of q2
|
||
spdlog::debug("Getting xis in bins of q2...");
|
||
std::vector<TH1D*> hxi_hist;
|
||
for (auto angObs: get_angObser_withTeX_vec()){
|
||
hxi_hist.push_back(new TH1D(("hxi"+angObs[0]+"hist").c_str(), (";q^{2};"+angObs[1]).c_str(),
|
||
edges.nq2bins, edges.q2min, edges.q2max));
|
||
}
|
||
|
||
std::vector<int>int_xi(hxi_hist.size(),0);
|
||
for (unsigned int h = 0; h<edges.nq2bins; h++){
|
||
std::fill(int_xi.begin(), int_xi.end(), 0); //fill int_xi with zeroes
|
||
for (unsigned int i = 0; i<edges.nctlbins; i++)
|
||
for (unsigned int j = 0; j<edges.nctkbins; j++)
|
||
for (unsigned int k = 0; k<edges.nphibins; k++){
|
||
unsigned int bin = get_bin_in4D(h,i,j,k,edges);
|
||
double eps = eps_hist.at(bin);
|
||
double f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12;
|
||
if(opts->full_angular){
|
||
integrated_fj_noacc(ctl_edges[i], ctl_edges[i+1],
|
||
ctk_edges[j], ctk_edges[j+1],
|
||
phi_edges[k], phi_edges[k+1],
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
}
|
||
else{
|
||
folded_integrated_fj_noacc(ctl_edges[i], ctl_edges[i+1],
|
||
ctk_edges[j], ctk_edges[j+1],
|
||
phi_edges[k], phi_edges[k+1],
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
}
|
||
int_xi[0] += eps*f1; //KILL ME
|
||
int_xi[1] += eps*f2;
|
||
int_xi[2] += eps*f3;
|
||
int_xi[3] += eps*f4;
|
||
int_xi[4] += eps*f5;
|
||
int_xi[5] += eps*f6;
|
||
int_xi[6] += eps*f7;
|
||
int_xi[7] += eps*f8;
|
||
int_xi[8] += eps*f9;
|
||
int_xi[9] += eps*f10;
|
||
int_xi[10] += eps*f11;
|
||
int_xi[11] += eps*f12;
|
||
}
|
||
for_indexed(auto hist: hxi_hist) hist->SetBinContent(h+1,int_xi[i]);
|
||
}
|
||
|
||
//-----------------------------------
|
||
//DETERMINE XIS USING UNBINNED METHOD
|
||
//-----------------------------------
|
||
|
||
spdlog::debug("Getting xis using unbinned method...");
|
||
std::vector<TH1D*> hxi_ub;
|
||
for (auto angObs: get_angObser_withTeX_vec()){
|
||
hxi_ub.push_back(new TH1D(("hxi"+angObs[0]+"ub").c_str(), (";q^{2};"+angObs[1]).c_str(),
|
||
edges.nq2bins, edges.q2min, edges.q2max));
|
||
}
|
||
|
||
//make it pretty
|
||
for (auto hist: hxi_ub) hist->SetLineColor(4);
|
||
|
||
for (unsigned int h = 0; h<edges.nq2bins; h++){
|
||
std::fill(int_xi.begin(), int_xi.end(), 0); //fill int_xi with zeroes, no need to initialize (see line 961)
|
||
//double q2a = hxi_ub[0]->GetBinLowEdge(h); //check this is the same as q2_edges!!!!! should be, but to be sure
|
||
//double q2b = hxi_ub[0]->GetBinLowEdge(h+1);
|
||
for (auto &&meas: filtered_events){
|
||
if (meas.q2 < q2_edges[h] || meas.q2 > q2_edges[h]) continue;
|
||
double f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12;
|
||
if(opts->full_angular){
|
||
fj(meas.costhetal, meas.costhetak, meas.phi,
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
}
|
||
else{
|
||
folded_fj(meas.costhetal, meas.costhetak, meas.phi,
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
}
|
||
|
||
double weight = meas.weight/nWeightedEvents*edges.nq2bins*(edges.range_ctl()*edges.range_ctk()*edges.range_phi());
|
||
int_xi[0] += f1*weight; //KILL ME
|
||
int_xi[1] += f2*weight;
|
||
int_xi[2] += f3*weight;
|
||
int_xi[3] += f4*weight;
|
||
int_xi[4] += f5*weight;
|
||
int_xi[5] += f6*weight;
|
||
int_xi[6] += f7*weight;
|
||
int_xi[7] += f8*weight;
|
||
int_xi[8] += f9*weight;
|
||
int_xi[9] += f10*weight;
|
||
int_xi[10] += f11*weight;
|
||
int_xi[11] += f12*weight;
|
||
}
|
||
|
||
for_indexed(auto hist: hxi_ub) hist->SetBinContent(h,int_xi[i]);
|
||
|
||
}
|
||
|
||
//------------------------------------------------------
|
||
//DETERMINE POLYNOMIAL ACCEPTANCE WITH METHOD OF MOMENTS
|
||
//------------------------------------------------------
|
||
const bool calculateCovariance = false;
|
||
const bool assumectleven = opts->systematic == 2;
|
||
const bool fejerkernel = false; //see Alexander Weisse, Holger Feshke, Chebyshev expansion techniques
|
||
const bool doLegendre = true; //somehow, chebyshev is broken now, great job me
|
||
|
||
std::vector<double> poly_moments(npol.getSize(), 0.0);
|
||
|
||
if (doLegendre){
|
||
get_legendre(edges, npol,
|
||
filtered_events, nWeightedEvents,
|
||
poly_moments,
|
||
fejerkernel, assumectleven, assumePhiEven,
|
||
checkSignificance, calculateCovariance);
|
||
}
|
||
else{
|
||
get_chebyschev(edges, npol,
|
||
filtered_events, nWeightedEvents,
|
||
poly_moments,
|
||
fejerkernel, assumectleven, assumePhiEven,
|
||
checkSignificance, calculateCovariance);
|
||
|
||
}
|
||
|
||
spdlog::debug("Getting correct polynomial coefficients in cos(thetak) and cos(thetal)");
|
||
spdlog::debug("poly_moments size:{0:d}", poly_moments.size());
|
||
//correct coefficients from -1 +1 to ctlmin .. ctlmax for ctl, bit difficult, requires binomial coefficients
|
||
std::vector<double> poly_moments_ctl(npol.getSize(), 0.0);
|
||
std::vector<double> poly_moments_ctk(npol.getSize(), 0.0);
|
||
std::vector<double> poly_moments_phi(npol.getSize(), 0.0);
|
||
std::vector<double> poly_moments_q2(npol.getSize(), 0.0);
|
||
|
||
correct_coefficients(npol,edges,poly_moments_ctl,poly_moments, "ctl");
|
||
correct_coefficients(npol,edges,poly_moments_ctk,poly_moments_ctl, "ctk");
|
||
correct_coefficients(npol,edges,poly_moments_phi,poly_moments_ctk, "phi");
|
||
correct_coefficients(npol,edges,poly_moments_q2, poly_moments_phi, "q2");
|
||
|
||
spdlog::debug("Getting moments....");
|
||
|
||
std::vector<double> coeffs_moments(poly_moments_q2);
|
||
//calculate norm after full integration
|
||
double full_norm = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
full_norm += coeffs_moments.at(npol.get_bin_in4D(h,i,j,k))*integrate_4D(edges, h, i, j, k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//assume a flat efficiency of 1.0 -> scale by edges.range_q2()*RANGE_3D()/full_norm
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
coeffs_moments.at(npol.get_bin_in4D(h,i,j,k)) *= edges.range_q2()*RANGE_3D()/full_norm;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//print to std::out
|
||
|
||
if (spdlog_trace()){
|
||
spdlog::trace( "//vector of efficiency coefficients containing {0:d} elements", coeffs_moments.size());
|
||
spdlog::trace( "coeffs_eff_4d = { " );
|
||
for (unsigned int i=0; i<coeffs_moments.size(); i++){
|
||
std::cout << std::setprecision(5) << std::scientific << coeffs_moments.at(i)<< (i<coeffs_moments.size()-1 ? ", " : " ");
|
||
}
|
||
}
|
||
//set this as default coefficients now
|
||
coeffs_eff_4d = coeffs_moments;
|
||
|
||
//calculate the integrated angular terms int f_i dOmega (q2) = xi(q2)
|
||
std::vector<TH1D*> hxi_moments;
|
||
for (auto &angObs: get_angObser_withTeX_vec()){
|
||
hxi_moments.push_back(new TH1D(("hxi"+angObs[0]+"_moments").c_str(), (";q^{2};"+angObs[1]).c_str(),
|
||
edges.nq2bins, edges.q2min, edges.q2max));
|
||
}
|
||
|
||
for (int l=1; l<=hxi_moments[0]->GetNbinsX(); l++) {
|
||
double a = hxi_moments[0]->GetXaxis()->GetBinLowEdge(l);
|
||
double b = hxi_moments[0]->GetXaxis()->GetBinLowEdge(l+1);
|
||
std::vector<double> integral_xi(hxi_moments.size(),0.0);
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
unsigned int bin =npol.get_bin_in4D(h, i, j, k);
|
||
double coeff = C_PWAVE*coeffs_moments.at(bin)*pow(0.5*(a+b), h);
|
||
//f1 = c * sinthetak2; //j1s
|
||
integral_xi[0] += coeff
|
||
* integrate_x_to_n(edges.ctlmin, edges.ctlmax, i)
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j) - integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
* integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f2 = c * costhetak2; //j1c
|
||
integral_xi[1] += coeff
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i)
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f3 = c * sinthetak2*cos2thetal; //j2s
|
||
integral_xi[2] += coeff
|
||
*(2.0*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2)-integrate_x_to_n(edges.ctlmin, edges.ctlmax, i))
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j)-integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f4 = c * costhetak2*cos2thetal; //j2c
|
||
integral_xi[3] += coeff
|
||
*(2.0*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2)-integrate_x_to_n(edges.ctlmin, edges.ctlmax, i))
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f5 = c * sinthetak2*sinthetal2*cos(2.0*phi); //j3
|
||
integral_xi[4] += coeff
|
||
*(integrate_x_to_n(edges.ctlmin, edges.ctlmax, i)-integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2))
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j)-integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n_times_cos_2x(edges.phimin, edges.phimax,k);
|
||
//f6 = c * sin2thetak*sin2thetal*cos(phi); //j4
|
||
integral_xi[5] += coeff
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i+1)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_cos_x(edges.phimin, edges.phimax,k);
|
||
//f7 = c * sin2thetak*sinthetal*cos(phi); //j5
|
||
integral_xi[6] += coeff
|
||
*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_cos_x(edges.phimin, edges.phimax,k);
|
||
//f8 = c * sinthetak2*costhetal; //j6s
|
||
integral_xi[7] += coeff
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+1)
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j)-integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f9 = c * costhetak2*costhetal; //j6c
|
||
integral_xi[8] += coeff
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+1)
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f10 = c * sin2thetak*sinthetal*sin(phi); //j7
|
||
integral_xi[9] += coeff
|
||
*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_sin_x(edges.phimin, edges.phimax,k);
|
||
//f11 = c * sin2thetak*sin2thetal*sin(phi); //j8
|
||
integral_xi[10] += coeff
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i+1)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_sin_x(edges.phimin, edges.phimax,k);
|
||
//f12 = c * sinthetak2*sinthetal2*sin(2.0*phi); //j9
|
||
integral_xi[11] += coeff
|
||
*(integrate_x_to_n(edges.ctlmin, edges.ctlmax, i) - integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2))
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j) - integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n_times_sin_2x(edges.phimin, edges.phimax,k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for_indexed(auto hist: hxi_moments) hist->SetBinContent(l, is_param_folded(i,opts) ? 0.0 : integral_xi[i]);
|
||
}
|
||
|
||
|
||
//-----------------------------------------------------
|
||
//DETERMINE POLYNOMIAL ACCEPTANCE USING UNBINNED ML FIT
|
||
//-----------------------------------------------------
|
||
std::vector<TH1D*> hxi_ml_hist;
|
||
for (auto &angObs: get_angObser_withTeX_vec()){
|
||
hxi_ml_hist.push_back(new TH1D(("hxi"+angObs[0]+"_ml").c_str(), (";q^{2};"+angObs[1]).c_str(),
|
||
nBinsQ2, edges.q2min, edges.q2max));
|
||
}
|
||
for (auto &hist: hxi_ml_hist){
|
||
hist->SetLineColor(3);
|
||
}
|
||
|
||
//possible TODO for when you're bored: move into it's own function
|
||
//Running minuit is expensive, use only if necesary!
|
||
if (runMinuit){
|
||
spdlog::info("Running Minuit....");
|
||
//setup minuit
|
||
TMinuit* minuit_eff = new TMinuit(10000);
|
||
int errorcode;
|
||
minuit_eff->SetFCN(&(eff_fcn_phsp_4d));
|
||
double strategy_list[1] = {2.0};
|
||
minuit_eff->mnexcm("SET STR", strategy_list, 1, errorcode);
|
||
minuit_eff->SetMaxIterations(1000000);
|
||
minuit_eff->SetErrorDef(1.0);
|
||
const bool second_run = false;
|
||
//define params (could also feed with starting values from method of moments)
|
||
unsigned int q2_limit = 6;
|
||
unsigned int ctl_limit = 3;
|
||
unsigned int ctk_limit = 4;
|
||
unsigned int phi_limit = 1;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
std::ostringstream sout;
|
||
sout << "c" << h << i << j << k;
|
||
if (h==0 && i==0 && j==0 && k==0){
|
||
minuit_eff->DefineParameter(npol.get_bin_in4D(h,i,j,k), sout.str().c_str(), 1.0, 0.0, 0.0, 0.0);
|
||
}
|
||
else if (h >= q2_limit || i >= ctl_limit || j >= ctk_limit || k >= phi_limit){
|
||
//this is to be able to do higher orders with the moments method and lower ones with minuit
|
||
minuit_eff->DefineParameter(npol.get_bin_in4D(h,i,j,k), sout.str().c_str(), 0.0, 0.0, 0.0, 0.0);
|
||
}
|
||
else if ((second_run && i == 0 && k == 0)|| (!second_run && i % 2 == 0 && k % 2 == 0)){
|
||
minuit_eff->DefineParameter(npol.get_bin_in4D(h,i,j,k), sout.str().c_str(), 0.0, 0.001, 0.0, 0.0);
|
||
}
|
||
else{
|
||
minuit_eff->DefineParameter(npol.get_bin_in4D(h,i,j,k), sout.str().c_str(), 0.0, 0.0, 0.0, 0.0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
double migrad_options[2] = {100000000.0, 0.1}; //{max calls, tolerance}
|
||
spdlog::info( "Running Migrad to determine eff shape" );
|
||
minuit_eff->mnset();
|
||
minuit_eff->mnexcm("MIG", migrad_options, 2, errorcode);
|
||
|
||
if (second_run){
|
||
spdlog::info( "Running Migrad a second time releasing parameters" );
|
||
//second run releasing some parameters
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
std::ostringstream sout;
|
||
sout << "c" << h << i << j << k;
|
||
if ((i > 0 || k > 0) && i % 2 == 0 && k % 2 == 0
|
||
&& h < q2_limit && i < ctl_limit && j < ctk_limit && k < phi_limit
|
||
)// && (i+j+k)<=4)
|
||
minuit_eff->DefineParameter(npol.get_bin_in4D(h,i,j,k), sout.str().c_str(), 0.0, 0.001, 0.0, 0.0);
|
||
}
|
||
spdlog::info( "Running Migrad to determine eff shape" );
|
||
minuit_eff->mnexcm("MIG", migrad_options, 2, errorcode);
|
||
}
|
||
//extract fitted parameters
|
||
spdlog::debug("Extracting fitted parameters.");
|
||
std::vector<double> chijk_ml;
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double v,e;
|
||
minuit_eff->GetParameter(npol.get_bin_in4D(h,i,j,k), v, e);
|
||
chijk_ml.push_back(v);
|
||
}
|
||
delete minuit_eff;
|
||
spdlog::info( "Minuit finished" );
|
||
|
||
//transform chebyshev coefficients to monomial coefficients
|
||
std::vector<double> poly_ml(npol.getSize(), 0.0);
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double c = chijk_ml.at(npol.get_bin_in4D(h,i,j,k));
|
||
std::vector<double> ch_coeffs_q2(npol.q2, 0.0);
|
||
std::vector<double> ch_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> ch_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> ch_coeffs_phi(npol.phi,0.0);
|
||
ch_coeffs_q2.at(h) = 1.0;
|
||
ch_coeffs_ctl.at(i) = 1.0;
|
||
ch_coeffs_ctk.at(j) = 1.0;
|
||
ch_coeffs_phi.at(k) = 1.0;
|
||
std::vector<double> poly_coeffs_q2(npol.q2, 0.0);
|
||
std::vector<double> poly_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> poly_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> poly_coeffs_phi(npol.phi,0.0);
|
||
chebyshev_to_poly(ch_coeffs_q2, poly_coeffs_q2);
|
||
chebyshev_to_poly(ch_coeffs_ctl, poly_coeffs_ctl);
|
||
chebyshev_to_poly(ch_coeffs_ctk, poly_coeffs_ctk);
|
||
chebyshev_to_poly(ch_coeffs_phi, poly_coeffs_phi);
|
||
for (unsigned int l = 0; l<=h; l++)
|
||
for (unsigned int m = 0; m<=i; m++)
|
||
for (unsigned int n = 0; n<=j; n++)
|
||
for (unsigned int o = 0; o<=k; o++){
|
||
unsigned int bin = npol.get_bin_in4D(l,m,n,o);
|
||
poly_ml.at(bin) += c*poly_coeffs_q2.at(l)*poly_coeffs_ctl.at(m)*poly_coeffs_ctk.at(n)*poly_coeffs_phi.at(o);
|
||
}
|
||
}//tested, works
|
||
|
||
//correct coefficients from -1 +1 to ctlmin .. ctlmax for ctl, bit difficult, requires binomial coefficients
|
||
std::vector<double> poly_ml_ctl(npol.getSize(), 0.0);
|
||
std::vector<double> poly_ml_ctk(npol.getSize(), 0.0);
|
||
std::vector<double> poly_ml_phi(npol.getSize(), 0.0);
|
||
std::vector<double> poly_ml_q2(npol.getSize(), 0.0);
|
||
correct_coefficients(npol, edges, poly_ml_ctl, poly_ml, "ctl");
|
||
correct_coefficients(npol, edges, poly_ml_ctk, poly_ml_ctl, "ctk");
|
||
correct_coefficients(npol, edges, poly_ml_phi, poly_ml_ctk, "phi");
|
||
correct_coefficients(npol, edges, poly_ml_q2, poly_ml_phi, "q2");
|
||
|
||
|
||
std::vector<double> coeffs_ml(poly_ml_q2);
|
||
//calculate norm after full integration
|
||
double full_norm = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
full_norm += coeffs_ml.at(npol.get_bin_in4D(h,i,j,k))*integrate_4D(edges,h,i,j,k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//assume a flat efficiency of 1.0 -> scale by edges.range_q2()*RANGE_3D()/full_norm
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
coeffs_ml.at(npol.get_bin_in4D(h,i,j,k)) *= edges.range_q2()*RANGE_3D()/full_norm;
|
||
// delta_q2*delta_ctl*delta_ctk*delta_phi/full_norm;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//calculate the integrated angular terms int f_i dOmega (q2) = xi(q2)
|
||
for (int l=1; l<=hxi_ml_hist[0]->GetNbinsX(); l++){
|
||
double a = hxi_ml_hist[0]->GetXaxis()->GetBinLowEdge(l);
|
||
double b = hxi_ml_hist[0]->GetXaxis()->GetBinLowEdge(l+1);
|
||
std::vector<double> integral_xi(hxi_ml_hist.size(), 0.0);
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
double coeff = C_PWAVE*coeffs_ml.at(bin)*pow(0.5*(a+b), h);
|
||
//f1 = c * sinthetak2; //j1s
|
||
integral_xi[0] += coeff
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i)
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j)-integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f2 = c * costhetak2; //j1c
|
||
integral_xi[1] += coeff
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i)
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f3 = c * sinthetak2*cos2thetal; //j2s
|
||
integral_xi[2] += coeff
|
||
*(2.0*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2)-integrate_x_to_n(edges.ctlmin, edges.ctlmax, i))
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j)-integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f4 = c * costhetak2*cos2thetal; //j2c
|
||
integral_xi[3] += coeff
|
||
*(2.0*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2)-integrate_x_to_n(edges.ctlmin, edges.ctlmax, i))
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f5 = c * sinthetak2*sinthetal2*cos(2.0*phi); //j3
|
||
integral_xi[4] += coeff
|
||
*(integrate_x_to_n(edges.ctlmin, edges.ctlmax, i)-integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2))
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j)-integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n_times_cos_2x(edges.phimin, edges.phimax,k);
|
||
//f6 = c * sin2thetak*sin2thetal*cos(phi); //j4
|
||
integral_xi[5] += coeff
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i+1)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_cos_x(edges.phimin, edges.phimax,k);
|
||
//f7 = c * sin2thetak*sinthetal*cos(phi); //j5
|
||
integral_xi[6] += coeff
|
||
*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_cos_x(edges.phimin, edges.phimax,k);
|
||
//f8 = c * sinthetak2*costhetal; //j6s
|
||
integral_xi[7] += coeff
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+1)
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j)-integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f9 = c * costhetak2*costhetal; //j6c
|
||
integral_xi[8] += coeff
|
||
*integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+1)
|
||
*integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2)
|
||
*integrate_x_to_n(edges.phimin, edges.phimax,k);
|
||
//f10 = c * sin2thetak*sinthetal*sin(phi); //j7
|
||
integral_xi[9] += coeff
|
||
*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_sin_x(edges.phimin, edges.phimax,k);
|
||
//f11 = c * sin2thetak*sin2thetal*sin(phi); //j8
|
||
integral_xi[10] += coeff
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctlmin, edges.ctlmax, i+1)
|
||
*2.0*integrate_x_to_n_times_sqrt_1_minus_x2(edges.ctkmin, edges.ctkmax, j+1)
|
||
*integrate_x_to_n_times_sin_x(edges.phimin, edges.phimax,k);
|
||
//f12 = c * sinthetak2*sinthetal2*sin(2.0*phi); //j9
|
||
integral_xi[11] += coeff
|
||
*(integrate_x_to_n(edges.ctlmin, edges.ctlmax, i) - integrate_x_to_n(edges.ctlmin, edges.ctlmax, i+2))
|
||
*(integrate_x_to_n(edges.ctkmin, edges.ctkmax, j) - integrate_x_to_n(edges.ctkmin, edges.ctkmax, j+2))
|
||
*integrate_x_to_n_times_sin_2x(edges.phimin, edges.phimax,k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for_indexed(auto hist: hxi_ml_hist) hist->SetBinContent(l, is_param_folded(i,opts) ? 0.0 : integral_xi[i]);
|
||
}
|
||
}
|
||
|
||
//-----------------------
|
||
// Factorization in q2 bins
|
||
//-----------------------
|
||
//std::vector<double> nfact();
|
||
if (checkFactorization){ //possible TODO for when you're bored: move into it's own function
|
||
spdlog::info( "CHECKFACTORIZATION start " );
|
||
//fill histo for comparison
|
||
std::vector<double> nsel_hist(edges.getNbins(), 0.0);
|
||
std::vector<double> nsel_hist_errsq(edges.getNbins(), 0.0);
|
||
for (auto &meas: filtered_events){
|
||
unsigned int h = (meas.q2 - edges.q2min ) / edges.binWidth_q2();
|
||
unsigned int i = (meas.costhetal - edges.ctlmin ) / edges.binWidth_ctl();
|
||
unsigned int j = (meas.costhetak - edges.ctkmin ) / edges.binWidth_ctk();
|
||
unsigned int k = (meas.phi - edges.phimin ) / edges.binWidth_phi();
|
||
|
||
unsigned int bin = get_bin_in4D(h,i,j,k,edges);
|
||
nsel_hist.at(bin) += meas.weight;
|
||
nsel_hist_errsq.at(bin) += sqr(meas.weight);
|
||
}
|
||
for (unsigned int i=0; i<nsel_hist_errsq.size(); i++){
|
||
if (nsel_hist_errsq.at(i) == 0.0) nsel_hist_errsq.at(i) = 1.0;
|
||
}
|
||
|
||
//loop over all q2 bins
|
||
double chi2 = 0.0;
|
||
for (unsigned int h=0; h<q2_edges.size()-1; h++){
|
||
double q2a = q2_edges.at(h);
|
||
double q2b = q2_edges.at(h+1);
|
||
std::vector<double> ctl_moments(npol.ctl, 0.0);
|
||
std::vector<double> ctk_moments(npol.ctk, 0.0);
|
||
std::vector<double> phi_moments(npol.phi,0.0);
|
||
double nfactweighted = 0.0;
|
||
//determine weighted number of events in this bin and fill control histos
|
||
std::ostringstream sout;
|
||
sout << h;
|
||
sout << "_" << DECAY_NAME << (opts->KS ? opts->DDLL+"_" : "_")
|
||
<< "Run" << opts->run
|
||
<< ((opts->angacccorrperyear && opts->year != -1) ? "_"+std::to_string(opts->year) : "")
|
||
<< "_" << tagNumber;
|
||
TH1D* hctl = new TH1D("hctl", ";cos#Theta_{L};", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* hctk = new TH1D("hctk", ";cos#Theta_{K};", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* hphi = new TH1D("hphi", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
for (auto &meas : filtered_events){
|
||
if (meas.q2 > q2a && meas.q2 < q2b){
|
||
nfactweighted += meas.weight;
|
||
hctl->Fill(meas.costhetal, meas.weight);
|
||
hctk->Fill(meas.costhetak, meas.weight);
|
||
hphi->Fill(meas.phi, meas.weight);
|
||
}
|
||
}
|
||
//loop over events in this bin, determine factorizing moments
|
||
for (auto & meas: filtered_events){
|
||
if (meas.q2 > q2a && meas.q2 < q2b){
|
||
double weight = meas.weight;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin ) / edges.range_ctl() - 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin ) / edges.range_ctk() - 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin ) / edges.range_phi() - 1.0;
|
||
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
if (assumectleven && i%2 != 0){
|
||
ctl_moments.at(i) = 0.0;
|
||
}
|
||
else{
|
||
//ctl_moments.at(i)+=weight*fcnc::chebyshev(ctl,i)/sqrt(1-ctl*ctl)*(i==0?1.0/pi:2.0/pi)/nfactweighted;
|
||
ctl_moments.at(i) += weight*fcnc::legendre(ctl, i)*(2.0*i+1.0)/2.0/nfactweighted;
|
||
}
|
||
}
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
//ctk_moments.at(j) += weight*fcnc::chebyshev(ctk, j)/sqrt(1-ctk*ctk)*(j == 0 ? 1.0/pi : 2.0/pi)/nfactweighted;
|
||
ctk_moments.at(j) += weight*fcnc::legendre(ctk, j)*(2.0*j+1.0)/2.0/nfactweighted;
|
||
}
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
if (assumePhiEven && k%2 != 0){
|
||
phi_moments.at(k) = 0.0;
|
||
}
|
||
else{
|
||
//phi_moments.at(k) += weight*fcnc::chebyshev(phi, k)/sqrt(1-phi*phi)*(k == 0 ? 1.0/pi : 2.0/pi)/nfactweighted;
|
||
phi_moments.at(k) += weight*fcnc::legendre(phi, k)*(2.0*k+1.0)/2.0/nfactweighted;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//make polynomial
|
||
std::vector<double> ctl_polys(npol.ctl, 0.0);
|
||
std::vector<double> ctk_polys(npol.ctk, 0.0);
|
||
std::vector<double> phi_polys(npol.phi,0.0);
|
||
if (doLegendre){
|
||
legendre_to_poly(ctl_moments, ctl_polys);
|
||
legendre_to_poly(ctk_moments, ctk_polys);
|
||
legendre_to_poly(phi_moments, phi_polys);
|
||
}
|
||
else{
|
||
chebyshev_to_poly(ctl_moments, ctl_polys);
|
||
chebyshev_to_poly(ctk_moments, ctk_polys);
|
||
chebyshev_to_poly(phi_moments, phi_polys);
|
||
}
|
||
|
||
//transform angles from -1 +1 to angle_min angle_max
|
||
std::vector<double> ctl_correct(npol.ctl, 0.0);
|
||
std::vector<double> ctk_correct(npol.ctk, 0.0);
|
||
std::vector<double> phi_correct(npol.phi,0.0);
|
||
|
||
for (unsigned int i=0; i<ctk_polys.size(); i++) ctk_correct.at(i) = ctk_polys.at(i);
|
||
for (unsigned int i=0; i<ctl_polys.size(); i++) ctl_correct.at(i) = ctl_polys.at(i);
|
||
correct_poly(phi_polys, phi_correct, -TMath::Pi(), +TMath::Pi());
|
||
|
||
//determine chi2 in this bin
|
||
std::vector<double> neps_hist(nctlbins*nctkbins*nphibins, 0.0);
|
||
for (unsigned int i = 0; i<nctlbins; i++){
|
||
double ctla = edges.ctlmin + edges.range_ctl() * i /double(edges.nctlbins);
|
||
double ctlb = edges.ctlmin + edges.range_ctl() * (i+1.0) /double(edges.nctlbins);
|
||
for (unsigned int j = 0; j<nctkbins; j++){
|
||
double ctka = edges.ctkmin + edges.range_ctk() * j /double(edges.nctkbins);
|
||
double ctkb = edges.ctkmin + edges.range_ctk() * (j+1.0) /double(edges.nctkbins);
|
||
for (unsigned int k = 0; k<nphibins; k++){
|
||
double phi_a = edges.phimin + edges.range_phi() * k / double(edges.nphibins);
|
||
double phi_b = edges.phimin + edges.range_phi() * (k+1.0) / double(edges.nphibins);
|
||
double result_ctl = 0.0, result_ctk = 0.0, result_phi = 0.0;
|
||
for (unsigned int m = 0; m<npol.ctl; m++) result_ctl += ctl_correct.at(m)*integrate_x_to_n(ctla,ctlb,m);
|
||
for (unsigned int n = 0; n<npol.ctk; n++) result_ctk += ctk_correct.at(n)*integrate_x_to_n(ctka,ctkb,n);
|
||
for (unsigned int o = 0; o<npol.phi; o++) result_phi += phi_correct.at(o)*integrate_x_to_n(phi_a,phi_b,o);
|
||
neps_hist.at(get_bin_in3D(i,j,k,edges)) = result_ctl*result_ctk*result_phi;
|
||
}
|
||
}
|
||
}
|
||
//rescale to be sure
|
||
double nnorm_ctl = 0.0, nnorm_ctk = 0.0, nnorm_phi = 0.0;
|
||
for (unsigned int m = 0; m<npol.ctl; m++) nnorm_ctl += ctl_correct.at(m)*integrate_x_to_n(edges.ctlmin, edges.ctlmax, m);
|
||
for (unsigned int n = 0; n<npol.ctk; n++) nnorm_ctk += ctk_correct.at(n)*integrate_x_to_n(edges.ctkmin, edges.ctkmax, n);
|
||
for (unsigned int o = 0; o<npol.phi; o++) nnorm_phi += phi_correct.at(o)*integrate_x_to_n(edges.phimin, edges.phimax, o);
|
||
for (unsigned int i = 0; i<nctlbins; i++){
|
||
for (unsigned int j = 0; j<nctkbins; j++){
|
||
for (unsigned int k = 0; k<nphibins; k++){
|
||
neps_hist.at(get_bin_in3D(i,j,k,edges)) *= (nfactweighted/nnorm_ctl/nnorm_ctk/nnorm_phi);
|
||
}
|
||
}
|
||
}
|
||
//should scale nfactweighted/nfactfit
|
||
|
||
//determine chi2 //TODO: not working?
|
||
double curr_chi2 = 0.0;
|
||
TH1D* hpull = new TH1D("hpull", ";(N_{sel}-N_{fit})/#sqrt{N_{sel}};", 100, -5.0, 5.0);
|
||
for (unsigned int i = 0; i<nctlbins; i++){
|
||
for (unsigned int j = 0; j<nctkbins; j++){
|
||
for (unsigned int k = 0; k<nphibins; k++){
|
||
unsigned int bin = get_bin_in4D(h,i,j,k,edges);
|
||
curr_chi2 += sqr(nsel_hist.at(bin)-neps_hist.at(get_bin_in3D(i,j,k,edges)))/fabs(neps_hist.at(get_bin_in3D(i,j,k,edges))); //TODO: h is a wrong bin!
|
||
hpull->Fill((nsel_hist.at(bin)-neps_hist.at(get_bin_in3D(i,j,k,edges)))/sqrt(fabs(neps_hist.at(get_bin_in3D(i,j,k,edges)))));//TODO: h is a wrong bin!
|
||
}
|
||
}
|
||
}
|
||
//do plots
|
||
TH1D* ectl = new TH1D("ectl", ";cos#Theta_{L};", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* ectk = new TH1D("ectk", ";cos#Theta_{K};", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* ephi = new TH1D("ephi", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
for (int l=1; l<=ectl->GetNbinsX(); l++){
|
||
double integral = 0.0;
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
integral += ctl_correct.at(i)*integrate_x_to_n(ectl->GetBinLowEdge(l),ectl->GetBinLowEdge(l+1),i);
|
||
}
|
||
ectl->SetBinContent(l, integral);
|
||
}
|
||
for (int l=1; l<=ectk->GetNbinsX(); l++){
|
||
double integral = 0.0;
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
integral += ctk_correct.at(j)*integrate_x_to_n(ectl->GetBinLowEdge(l),ectl->GetBinLowEdge(l+1),j);
|
||
}
|
||
ectk->SetBinContent(l, integral);
|
||
}
|
||
for (int l=1; l<=ephi->GetNbinsX(); l++){
|
||
double integral = 0.0;
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
integral += phi_correct.at(k)*integrate_x_to_n(ectl->GetBinLowEdge(l),ectl->GetBinLowEdge(l+1),k);
|
||
}
|
||
ephi->SetBinContent(l, integral);
|
||
}
|
||
TLatex *tex = getPrettyTex(0.06,31);
|
||
|
||
std::ostringstream sregion;
|
||
sregion << std::fixed << std::setprecision(2) << q2a << "<q^{2}<" << q2b;
|
||
|
||
TCanvas* c_pull = new TCanvas("c_pull", "c_pull", 1600, 1200);
|
||
c_pull->cd();
|
||
hpull->Draw();
|
||
tex->DrawLatex(0.85, 0.15, sregion.str().c_str());
|
||
if(opts->write_eps)c_pull->Print((std::string(subfolder + "fact_pull")+sout.str()+std::string(".eps")).c_str(),"eps");
|
||
|
||
plotAngular(hctl,ectl,opts->write_eps,"fact_ctleff",sout.str(),sregion.str(),tex,subfolder);
|
||
plotAngular(hctk,ectk,opts->write_eps,"fact_ctkeff",sout.str(),sregion.str(),tex,subfolder);
|
||
plotAngular(hphi,ephi,opts->write_eps,"fact_phieff",sout.str(),sregion.str(),tex,subfolder);
|
||
|
||
delete hpull;
|
||
delete ectl;
|
||
delete ectk;
|
||
delete ephi;
|
||
delete hctl;
|
||
delete hctk;
|
||
delete hphi;
|
||
|
||
delete c_pull;
|
||
|
||
spdlog::debug( "fact chi2 in bin {0:d}: {1:f}", h, curr_chi2 );
|
||
chi2 += curr_chi2;
|
||
}
|
||
spdlog::info( "fact total chi2: {0:f}",chi2 );
|
||
spdlog::info( "uses {0:d}*{1:d}*{2:d}*{3:d}={4:d} bins",edges.nq2bins, edges.nctlbins, edges.nctkbins, edges.nphibins, edges.getNbins());
|
||
spdlog::info( "Chi2/Nbins = {0:f}", chi2/(edges.getNbins()) );
|
||
spdlog::info( "CHECKFACTORIZATION end " );
|
||
}
|
||
//-----------------------
|
||
// 3D MOMENTS in q2 bins
|
||
//-----------------------
|
||
if (do3Dmoments){
|
||
spdlog::info("DOTHREEDMOMENTS start ");
|
||
//fill histo for comparison
|
||
std::vector<double> nsel_hist(edges.getNbins(), 0.0);
|
||
std::vector<double> nsel_hist_errsq(edges.getNbins(), 0.0);
|
||
for (unsigned int e=0; e<filtered_events.size(); e++){
|
||
const event & meas = filtered_events.at(e);
|
||
unsigned int bin = get_bin_in4D(meas,edges);
|
||
nsel_hist.at(bin) += meas.weight;
|
||
nsel_hist_errsq.at(bin) += sqr(meas.weight);
|
||
}
|
||
for (unsigned int i=0; i<nsel_hist_errsq.size(); i++){
|
||
if (nsel_hist_errsq.at(i) == 0.0) nsel_hist_errsq.at(i) = 1.0;
|
||
}
|
||
|
||
//loop over all q2 bins
|
||
double chi2 = 0.0;
|
||
for (unsigned int h=0; h<q2_edges.size()-1; h++){
|
||
double q2a = q2_edges.at(h);
|
||
double q2b = q2_edges.at(h+1);
|
||
double nthreedweighted = 0.0;
|
||
//determine weighted number of events in this bin and fill control histos
|
||
std::ostringstream sout;
|
||
sout << h;
|
||
sout << "_" << DECAY_NAME << (opts->KS ? opts->DDLL+"_" : "_")
|
||
<< "Run" << opts->run
|
||
<< ((opts->angacccorrperyear && opts->year != -1) ? "_"+std::to_string(opts->year) : "");
|
||
TH1D* hctl = new TH1D("hctl", ";cos#Theta_{L};", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* hctk = new TH1D("hctk", ";cos#Theta_{K};", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* hphi = new TH1D("hphi", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
for (auto &meas: filtered_events){
|
||
if (meas.q2 > q2a && meas.q2 < q2b){
|
||
nthreedweighted += meas.weight;
|
||
hctl->Fill(meas.costhetal, meas.weight);
|
||
hctk->Fill(meas.costhetak, meas.weight);
|
||
hphi->Fill(meas.phi, meas.weight);
|
||
}
|
||
}
|
||
//loop over events in this bin, determine factorizing moments
|
||
spdlog::debug("Getting factorizing moments");
|
||
std::vector<double> threed_moments(npol.ctl*npol.ctk*npol.phi,0.0);
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
for (auto &meas: filtered_events){
|
||
if (meas.q2 > q2a && meas.q2 < q2b){
|
||
double weight = meas.weight;
|
||
double ctl = 2.0 * (meas.costhetal - edges.ctlmin ) / edges.range_ctl() - 1.0;
|
||
double ctk = 2.0 * (meas.costhetak - edges.ctkmin ) / edges.range_ctk() - 1.0;
|
||
double phi = 2.0 * (meas.phi - edges.phimin ) / edges.range_phi() - 1.0;
|
||
|
||
double result = 0.0;
|
||
if (assumectleven && i%2 != 0) result = 0.0;
|
||
else if (assumePhiEven && k%2 != 0) result = 0.0;
|
||
else {
|
||
if (doLegendre){
|
||
result = weight
|
||
*fcnc::legendre(ctl, i)*(2.0*i+1.0)/2.0
|
||
*fcnc::legendre(ctk, j)*(2.0*j+1.0)/2.0
|
||
*fcnc::legendre(phi, k)*(2.0*k+1.0)/2.0
|
||
/nthreedweighted;// /filtered_events.size();
|
||
}
|
||
else{
|
||
result = weight
|
||
*fcnc::chebyshev(ctl, i)/sqrt(1-ctl*ctl)*(i==0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(ctk, j)/sqrt(1-ctk*ctk)*(j==0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
*fcnc::chebyshev(phi, k)/sqrt(1-phi*phi)*(k==0 ? 1.0/MY_PI : 2.0/MY_PI)
|
||
/nthreedweighted;// /filtered_events.size();
|
||
}
|
||
}
|
||
threed_moments.at( get_bin_in3D(i,j,k,npol)) += result;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//make polynomial
|
||
|
||
//transform legendre coefficients to monomial coefficients
|
||
spdlog::debug("Transforming legendre coefficients to monomial coefficients....");
|
||
std::vector<double> threedpoly_moments(npol.ctl*npol.ctk*npol.phi,0.0);
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
|
||
double tmp = threed_moments.at(get_bin_in3D(i,j,k,npol));
|
||
std::vector<double> leg_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> leg_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> leg_coeffs_phi(npol.phi,0.0);
|
||
leg_coeffs_ctl.at(i) = 1.0;
|
||
leg_coeffs_ctk.at(j) = 1.0;
|
||
leg_coeffs_phi.at(k) = 1.0;
|
||
std::vector<double> poly_coeffs_ctl(npol.ctl, 0.0);
|
||
std::vector<double> poly_coeffs_ctk(npol.ctk, 0.0);
|
||
std::vector<double> poly_coeffs_phi(npol.phi,0.0);
|
||
legendre_to_poly(leg_coeffs_ctl, poly_coeffs_ctl);
|
||
legendre_to_poly(leg_coeffs_ctk, poly_coeffs_ctk);
|
||
legendre_to_poly(leg_coeffs_phi, poly_coeffs_phi);
|
||
|
||
for (unsigned int m = 0; m<=i; m++){
|
||
for (unsigned int n = 0; n<=j; n++){
|
||
for (unsigned int o = 0; o<=k; o++){
|
||
unsigned int bin = get_bin_in3D(m,n,o,npol);
|
||
threedpoly_moments.at(bin) += tmp*poly_coeffs_ctl.at(m)*poly_coeffs_ctk.at(n)*poly_coeffs_phi.at(o);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//correct coefficients from -1 +1 to -pi .. +pi for phi, this is easy
|
||
std::vector<double> threedpoly_moments_phi(threedpoly_moments);
|
||
for (unsigned int m = 0; m<npol.ctl; m++){
|
||
for (unsigned int n = 0; n<npol.ctk; n++){
|
||
for (unsigned int o = 0; o<npol.phi; o++){
|
||
threedpoly_moments_phi.at(get_bin_in3D(m,n,o,npol)) *= pow(1.0/MY_PI, o);
|
||
}
|
||
}
|
||
}
|
||
|
||
//calculate norm after full integration
|
||
double full_norm = 0.0;
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double result = threedpoly_moments_phi.at(get_bin_in3D(i,j,k,npol))*integrate_3D(edges,i,j,k);
|
||
full_norm += result;
|
||
}
|
||
}
|
||
}
|
||
spdlog::debug("Rescaling...");
|
||
//rescale to be sure
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
threedpoly_moments_phi.at(get_bin_in3D(i,j,k,npol)) *= nthreedweighted/full_norm;
|
||
}
|
||
}
|
||
}
|
||
|
||
//determine nfit in this bin
|
||
std::vector<double> neps_hist(nctlbins*nctkbins*nphibins, 0.0);
|
||
for (unsigned int i = 0; i<nctlbins; i++){
|
||
double ctla = edges.ctlmin + i * edges.range_ctl();
|
||
double ctlb = edges.ctlmin + (i+1) * edges.range_ctl();
|
||
for (unsigned int j = 0; j<nctkbins; j++){
|
||
double ctka = edges.ctkmin + j * edges.range_ctk();
|
||
double ctkb = edges.ctkmin + (j+1) * edges.range_ctk();
|
||
for (unsigned int k = 0; k<nphibins; k++){
|
||
double phi_a = edges.phimin + k * edges.range_phi();
|
||
double phi_b = edges.phimin + (k+1) * edges.range_phi();
|
||
double result = 0.0;
|
||
for (unsigned int m = 0; m<npol.ctl; m++)
|
||
for (unsigned int n = 0; n<npol.ctk; n++)
|
||
for (unsigned int o = 0; o<npol.phi; o++)
|
||
result += threedpoly_moments_phi.at(get_bin_in3D(m,n,o,npol))
|
||
*(pow(ctlb,m+1)/(m+1.0) - pow(ctla, m+1)/(m+1.0))
|
||
*(pow(ctkb,n+1)/(n+1.0) - pow(ctka, n+1)/(n+1.0))
|
||
*(pow(phi_b,o+1)/(o+1.0) - pow(phi_a, o+1)/(o+1.0));
|
||
unsigned int bin = get_bin_in3D(i,j,k,edges);
|
||
neps_hist.at(bin) = result;
|
||
}
|
||
}
|
||
}
|
||
spdlog::debug("Getting chi2...");
|
||
//determine chi2
|
||
double curr_chi2 = 0.0;
|
||
TH1D* hpull = new TH1D("hpull", ";(N_{sel}-N_{fit})/#sqrt{N_{sel}};", 100, -5.0, 5.0);
|
||
for (unsigned int i = 0; i<nctlbins; i++)
|
||
for (unsigned int j = 0; j<nctkbins; j++)
|
||
for (unsigned int k = 0; k<nphibins; k++){
|
||
unsigned int bin =get_bin_in4D(h,i,j,k,edges);
|
||
curr_chi2 += sqr(nsel_hist.at(bin)-neps_hist.at(get_bin_in3D(i,j,k,edges)))/fabs(neps_hist.at(get_bin_in3D(i,j,k,edges)));
|
||
hpull->Fill((nsel_hist.at(bin)-neps_hist.at(get_bin_in3D(i,j,k,edges)))/sqrt(fabs(neps_hist.at(get_bin_in3D(i,j,k,edges)))));
|
||
}
|
||
//spdlog::debug( "ok" );
|
||
//do plots
|
||
TH1D* ectl = new TH1D("ectl", ";cos#Theta_{L};", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* ectk = new TH1D("ectk", ";cos#Theta_{K};", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* ephi = new TH1D("ephi", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
for (int l=1; l<=ectl->GetNbinsX(); l++){
|
||
double a = ectl->GetBinLowEdge(l);
|
||
double b = ectl->GetBinLowEdge(l+1);
|
||
double integral = 0.0;
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double result = threedpoly_moments_phi.at(get_bin_in3D(i,j,k,npol))
|
||
*(pow(b ,i+1)/(i+1.0) - pow(a ,i+1)/(i+1.0))
|
||
*(pow(edges.ctkmax,j+1)/(j+1.0) - pow(edges.ctkmin,j+1)/(j+1.0))
|
||
*(pow(edges.phimax,k+1)/(k+1.0) - pow(edges.phimin,k+1)/(k+1.0));
|
||
integral += result;
|
||
}
|
||
ectl->SetBinContent(l, integral);
|
||
}
|
||
for (int l=1; l<=ectk->GetNbinsX(); l++){
|
||
double a = ectk->GetBinLowEdge(l);
|
||
double b = ectk->GetBinLowEdge(l+1);
|
||
double integral = 0.0;
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double result = threedpoly_moments_phi.at(get_bin_in3D(i,j,k,npol))
|
||
*(pow(edges.ctlmax,i+1)/(i+1.0) - pow(edges.ctlmin,i+1)/(i+1.0))
|
||
*(pow(b ,j+1)/(j+1.0) - pow(a ,j+1)/(j+1.0))
|
||
*(pow(edges.phimax,k+1)/(k+1.0) - pow(edges.phimin,k+1)/(k+1.0));
|
||
integral += result;
|
||
}
|
||
ectk->SetBinContent(l, integral);
|
||
}
|
||
for (int l=1; l<=ephi->GetNbinsX(); l++){
|
||
double a = ephi->GetBinLowEdge(l);
|
||
double b = ephi->GetBinLowEdge(l+1);
|
||
double integral = 0.0;
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double result = threedpoly_moments_phi.at(get_bin_in3D(i,j,k,npol))
|
||
*(pow(edges.ctlmax,i+1)/(i+1.0) - pow(edges.ctlmin,i+1)/(i+1.0))
|
||
*(pow(edges.ctkmax,j+1)/(j+1.0) - pow(edges.ctkmin,j+1)/(j+1.0))
|
||
*(pow(b ,k+1)/(k+1.0) - pow(a ,k+1)/(k+1.0));
|
||
integral += result;
|
||
}
|
||
ephi->SetBinContent(l, integral);
|
||
}
|
||
|
||
spdlog::debug("Plotting...");
|
||
TLatex *tex = getPrettyTex(0.06,31);
|
||
std::ostringstream sregion;
|
||
sregion << std::fixed << std::setprecision(2) << q2a << "<q^{2}<" << q2b;
|
||
|
||
TCanvas* c_zero = new TCanvas("c_zero", "c_zero", 1600, 1200);
|
||
c_zero->cd();
|
||
hpull->Draw();
|
||
tex->DrawLatex(0.85, 0.15, sregion.str().c_str());
|
||
if(opts->write_eps)c_zero->Print((std::string(subfolder + "3d_pull")+sout.str()+std::string(".eps")).c_str(),"eps");
|
||
|
||
plotAngular(hctl,ectl,opts->write_eps,"3d_ctleff", sout.str(), sregion.str(),tex,subfolder);
|
||
plotAngular(hctk,ectk,opts->write_eps,"3d_ctkeff", sout.str(), sregion.str(),tex,subfolder);
|
||
plotAngular(hphi,ephi,opts->write_eps,"3d_phieff", sout.str(), sregion.str(),tex,subfolder);
|
||
|
||
delete hpull;
|
||
delete ectl;
|
||
delete ectk;
|
||
delete ephi;
|
||
delete hctl;
|
||
delete hctk;
|
||
delete hphi;
|
||
|
||
delete c_zero;
|
||
|
||
spdlog::debug( "3d chi2 in bin {0:d}: {1:f}", h, curr_chi2 );
|
||
chi2 += curr_chi2;
|
||
}
|
||
spdlog::debug( "3d total chi2: {0:f}",chi2 );
|
||
spdlog::debug( "3d uses {0:d}*{1:d}*{2:d}*{3:d}={4_d} bins",edges.nq2bins, edges.nctlbins, edges.nctkbins, edges.nphibins, edges.getNbins());
|
||
spdlog::debug( "3d chi2/Nbins = {0:f}", chi2/(edges.getNbins()) );
|
||
spdlog::info( "DOTHREEDMOMENTS end " );
|
||
|
||
}
|
||
//-----------------------
|
||
// CHI2 TEST FOR MOMENTS
|
||
//-----------------------
|
||
bool dochi2test = true;
|
||
if(opts->only_4_1D_chi2)dochi2test = false;
|
||
spdlog::debug("dochi2: "+boolToString(dochi2test));
|
||
if (dochi2test) {
|
||
get_chi2(edges, npol, filtered_events, coeffs_moments, globalvalues,
|
||
assumectleven, assumePhiEven, opts->write_eps, subfolder, appendix);
|
||
}
|
||
|
||
//-----------------------
|
||
//MAKE NICE CONTROL PLOTS
|
||
//-----------------------
|
||
const bool do_plots = opts->write_eps || opts->only_4_1D_chi2;
|
||
if (do_plots){
|
||
|
||
spdlog::info( "Start PLOTS.." );
|
||
|
||
gROOT->SetStyle("Plain");
|
||
TPad foo;
|
||
const int NRGBs = 5;
|
||
const int NCont = 250;
|
||
double stops[NRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
|
||
double red[NRGBs] = { 0.00, 0.00, 0.87, 1.00, 0.51 };
|
||
double green[NRGBs] = { 0.00, 0.81, 1.00, 0.20, 0.00 };
|
||
double blue[NRGBs] = { 0.51, 1.00, 0.12, 0.00, 0.00 };
|
||
TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
|
||
gStyle->SetNumberContours(NCont);
|
||
gStyle->SetLabelFont(132, "xyz");
|
||
gStyle->SetTitleFont(132, "xyz");
|
||
gStyle->SetLegendFont(132);
|
||
gStyle->SetStatFont(132);
|
||
//new histograms binned in q2
|
||
//compare the three angular projections for data and moments
|
||
|
||
for (unsigned int u=0; u<q2_edges.size()-1; u++){
|
||
std::ostringstream sout;
|
||
sout << u;
|
||
std::string binno = sout.str();
|
||
TH1D* hctl = new TH1D("hctl", ";cos#Theta_{L};", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* hctk = new TH1D("hctk", ";cos#Theta_{K};", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* hphi = new TH1D("hphi", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctlctk = new TH2D("hctlctk", ";cos#Theta_{L};cos#Theta_{K}", nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH2D* hctlphi = new TH2D("hctlphi", ";cos#Theta_{L};#phi [rad]" , nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctkphi = new TH2D("hctkphi", ";cos#Theta_{K};#phi [rad]" , nBinsAngles, edges.ctkmin, edges.ctkmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
double q2a = q2_edges.at(u);
|
||
double q2b = q2_edges.at(u+1);
|
||
for (auto & meas: filtered_events){
|
||
if (meas.q2 > q2a && meas.q2 < q2b){
|
||
hctl->Fill(meas.costhetal, meas.weight);
|
||
hctk->Fill(meas.costhetak, meas.weight);
|
||
hphi->Fill(meas.phi, meas.weight);
|
||
|
||
hctlctk->Fill(meas.costhetal, meas.costhetak, meas.weight);
|
||
hctlphi->Fill(meas.costhetal, meas.phi, meas.weight);
|
||
hctkphi->Fill(meas.costhetak, meas.phi, meas.weight);
|
||
}
|
||
}
|
||
|
||
TH1D* hctl_moments = new TH1D("hctl_moments", ";cos#Theta_{L};", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* hctk_moments = new TH1D("hctk_moments", ";cos#Theta_{K};", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* hphi_moments = new TH1D("hphi_moments", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctlctk_moments = new TH2D("hctlctk_moments", ";cos#Theta_{L};cos#Theta_{K}", nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH2D* hctlphi_moments = new TH2D("hctlphi_moments", ";cos#Theta_{L};#phi [rad]" , nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctkphi_moments = new TH2D("hctkphi_moments", ";cos#Theta_{K};#phi [rad]" , nBinsAngles, edges.ctkmin, edges.ctkmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
|
||
//1d plots
|
||
fill_moments_hist_1D(hctl_moments, coeffs_moments, edges, npol, q2a, q2b);
|
||
fill_moments_hist_1D(hctk_moments, coeffs_moments, edges, npol, q2a, q2b);
|
||
fill_moments_hist_1D(hphi_moments, coeffs_moments, edges, npol, q2a, q2b);
|
||
|
||
//2d plots
|
||
fill_moments_hist_2D(hctlctk_moments, coeffs_moments, edges, npol, q2a, q2b);
|
||
fill_moments_hist_2D(hctlphi_moments, coeffs_moments, edges, npol, q2a, q2b);
|
||
fill_moments_hist_2D(hctkphi_moments, coeffs_moments, edges, npol, q2a, q2b);
|
||
|
||
|
||
TLatex *tex = getPrettyTex(0.06,31);
|
||
std::ostringstream sregion;
|
||
sregion << std::fixed << std::setprecision(2) << q2a << "<q^{2}<" << q2b;
|
||
|
||
plotAngular(hctl,hctl_moments,opts->write_eps,"ctleff",binno+appendix,sregion.str(), tex, subfolder);
|
||
plotAngular(hctk,hctk_moments,opts->write_eps,"ctkeff",binno+appendix,sregion.str(), tex, subfolder);
|
||
plotAngular(hphi,hphi_moments,opts->write_eps,"phieff",binno+appendix,sregion.str(), tex, subfolder);
|
||
|
||
if (tagNumber < 0){ //Do not plot when testing quickly
|
||
plotAngular(hctlctk,hctlctk_moments,opts->write_eps,"ctlctkeff",binno+appendix,
|
||
sregion.str(), tex, subfolder);
|
||
plotAngular(hctlphi,hctlphi_moments,opts->write_eps,"ctlphieff",binno+appendix,
|
||
sregion.str(), tex, subfolder);
|
||
plotAngular(hctkphi,hctkphi_moments,opts->write_eps,"ctkphieff",binno+appendix,
|
||
sregion.str(), tex, subfolder);
|
||
}
|
||
|
||
delete hctl; delete hctl_moments;
|
||
delete hctk; delete hctk_moments;
|
||
delete hphi; delete hphi_moments;
|
||
delete hctlctk; delete hctlctk_moments;
|
||
delete hctkphi; delete hctkphi_moments;
|
||
delete hctlphi; delete hctlphi_moments;
|
||
|
||
}//end extra plots in bins of q2
|
||
|
||
//data histograms
|
||
TH1D* hq2 = new TH1D("hq2" , ";q^{2} [GeV^{2}];" , nBinsQ2 ,edges.q2min, edges.q2max);
|
||
TH1D* hctl = new TH1D("hctl", ";cos(#Theta_{L});", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* hctk = new TH1D("hctk", ";cos(#Theta_{K});", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* hphi = new TH1D("hphi", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctlctk = new TH2D("hctlctk", ";cos#Theta_{L};cos#Theta_{K}", nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH2D* hctlphi = new TH2D("hctlphi", ";cos#Theta_{L};#phi [rad]" , nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctkphi = new TH2D("hctkphi", ";cos#Theta_{K};#phi [rad]" , nBinsAngles, edges.ctkmin, edges.ctkmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hq2ctl = new TH2D("hq2ctl", ";q^{2};cos#Theta_{L}", nBinsQ2, edges.q2min, edges.q2max, nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH2D* hq2ctk = new TH2D("hq2ctk", ";q^{2};cos#Theta_{K}", nBinsQ2, edges.q2min, edges.q2max, nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH2D* hq2phi = new TH2D("hq2phi", ";q^{2};#phi [rad]" , nBinsQ2, edges.q2min, edges.q2max, nBinsAngles, edges.phimin, edges.phimax);
|
||
hq2->Sumw2();
|
||
hctl->Sumw2();
|
||
hctk->Sumw2();
|
||
hphi->Sumw2();
|
||
for (unsigned int i=0; i<filtered_events.size(); i++){
|
||
const event& meas = filtered_events.at(i);
|
||
|
||
hq2->Fill(meas.q2, meas.weight);
|
||
hctl->Fill(meas.costhetal, meas.weight);
|
||
hctk->Fill(meas.costhetak, meas.weight);
|
||
hphi->Fill(meas.phi, meas.weight);
|
||
|
||
hctlctk->Fill(meas.costhetal, meas.costhetak, meas.weight);
|
||
hctlphi->Fill(meas.costhetal, meas.phi, meas.weight);
|
||
hctkphi->Fill(meas.costhetak, meas.phi, meas.weight);
|
||
hq2ctl->Fill(meas.q2, meas.costhetal, meas.weight);
|
||
hq2ctk->Fill(meas.q2, meas.costhetak, meas.weight);
|
||
hq2phi->Fill(meas.q2, meas.phi, meas.weight);
|
||
}
|
||
//fitted histograms, moments method
|
||
TH1D* hq2_moments = new TH1D("hq2_moments" , ";q^{2} [GeV^{2}];" , nBinsQ2, edges.q2min, edges.q2max);
|
||
TH1D* hctl_moments = new TH1D("hctl_moments", ";cos(#Theta_{L});", nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH1D* hctk_moments = new TH1D("hctk_moments", ";cos(#Theta_{K});", nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH1D* hphi_moments = new TH1D("hphi_moments", ";#phi [rad];" , nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctlctk_moments = new TH2D("hctlctk_moments", ";cos#Theta_{L};cos#Theta_{K}", nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH2D* hctlphi_moments = new TH2D("hctlphi_moments", ";cos#Theta_{L};#phi [rad]" , nBinsAngles, edges.ctlmin, edges.ctlmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hctkphi_moments = new TH2D("hctkphi_moments", ";cos#Theta_{K};#phi [rad]" , nBinsAngles, edges.ctkmin, edges.ctkmax, nBinsAngles, edges.phimin, edges.phimax);
|
||
TH2D* hq2ctl_moments = new TH2D("hq2ctl_moments", ";q^{2};cos#Theta_{L}", nBinsQ2, edges.q2min, edges.q2max, nBinsAngles, edges.ctlmin, edges.ctlmax);
|
||
TH2D* hq2ctk_moments = new TH2D("hq2ctk_moments", ";q^{2};cos#Theta_{K}", nBinsQ2, edges.q2min, edges.q2max, nBinsAngles, edges.ctkmin, edges.ctkmax);
|
||
TH2D* hq2phi_moments = new TH2D("hq2phi_moments", ";q^{2};#phi [rad]" , nBinsQ2, edges.q2min, edges.q2max, nBinsAngles, edges.phimin, edges.phimax);
|
||
|
||
//1d plots
|
||
fill_moments_hist_1D(hq2_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_1D(hctl_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_1D(hctk_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_1D(hphi_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
|
||
//2d plots
|
||
fill_moments_hist_2D(hctlctk_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_2D(hctlphi_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_2D(hctkphi_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_2D(hq2ctl_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_2D(hq2ctk_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
fill_moments_hist_2D(hq2phi_moments,coeffs_moments,edges,npol,edges.q2min,edges.q2max);
|
||
|
||
if(opts->only_4_1D_chi2){
|
||
//reset globalvalues
|
||
globalvalues->chi2_4_1D = 0.0;
|
||
globalvalues->chi2_4_1D_ctk = 0.0;
|
||
globalvalues->chi2_4_1D_ctl = 0.0;
|
||
globalvalues->chi2_4_1D_phi = 0.0;
|
||
globalvalues->chi2_4_1D_q2 = 0.0;
|
||
globalvalues->ndof_4_1D = 0;
|
||
globalvalues->ndof_4_1D_ctk = 0;
|
||
globalvalues->ndof_4_1D_ctl = 0;
|
||
globalvalues->ndof_4_1D_phi = 0;
|
||
globalvalues->ndof_4_1D_q2 = 0;
|
||
|
||
//first scale moments to match integral of event histograms
|
||
hctk_moments->Scale(hctk->Integral()/hctk_moments->Integral());
|
||
hctl_moments->Scale(hctl->Integral()/hctl_moments->Integral());
|
||
hphi_moments->Scale(hphi->Integral()/hphi_moments->Integral());
|
||
hq2_moments ->Scale(hq2->Integral()/hq2_moments->Integral());
|
||
|
||
//get chi2 from all 4 variables
|
||
for(UInt_t b = 1; b <= nBinsAngles; b++){
|
||
globalvalues->chi2_4_1D_ctk += sqr((hctk->GetBinContent(b) - hctk_moments->GetBinContent(b))) / fabs(hctk_moments->GetBinContent(b));
|
||
globalvalues->chi2_4_1D_ctl += sqr((hctl->GetBinContent(b) - hctl_moments->GetBinContent(b))) / fabs(hctl_moments->GetBinContent(b));
|
||
globalvalues->chi2_4_1D_phi += sqr((hphi->GetBinContent(b) - hphi_moments->GetBinContent(b))) / fabs(hphi_moments->GetBinContent(b));
|
||
}
|
||
for(UInt_t b = 1; b <= nBinsQ2; b++){
|
||
globalvalues->chi2_4_1D_q2 += sqr((hq2->GetBinContent(b) - hq2_moments->GetBinContent(b))) / fabs(hq2_moments->GetBinContent(b));
|
||
}
|
||
//sum of all four 1D histograms
|
||
globalvalues->chi2_4_1D = globalvalues->chi2_4_1D_ctk + globalvalues->chi2_4_1D_ctl + globalvalues->chi2_4_1D_phi + globalvalues->chi2_4_1D_q2;
|
||
|
||
//determine ndof for all angles and q2
|
||
//NOT sure if these ndofs are 100% correct, but good enough for a relative measure
|
||
globalvalues->ndof_4_1D_ctk = nBinsAngles - (npol.ctk-1) - 1;
|
||
globalvalues->ndof_4_1D_ctl = nBinsAngles - (npol.ctl-1) - 1;
|
||
globalvalues->ndof_4_1D_phi = nBinsAngles - (npol.phi-1) - 1;
|
||
globalvalues->ndof_4_1D_q2 = nBinsQ2 - (npol.q2-1) - 1;
|
||
globalvalues->ndof_4_1D = 3*nBinsAngles + nBinsQ2 - 1 - (npol.ctk + npol.ctl + npol.phi + npol.q2 - 1);
|
||
|
||
}
|
||
|
||
//plot
|
||
plotAngular(hq2,hq2_moments,opts->write_eps,"q2eff",appendix, subfolder);
|
||
plotAngular(hctl,hctl_moments,opts->write_eps,"ctleff",appendix, subfolder);
|
||
plotAngular(hctk,hctk_moments,opts->write_eps,"ctkeff",appendix, subfolder);
|
||
plotAngular(hphi,hphi_moments,opts->write_eps,"phieff",appendix, subfolder);
|
||
|
||
if (tagNumber < 0){ //do not plot when testing
|
||
plotAngular(hctlctk,hctlctk_moments,opts->write_eps,"ctlctkeff",appendix, subfolder);
|
||
plotAngular(hctlphi,hctlphi_moments,opts->write_eps,"ctlphieff",appendix, subfolder);
|
||
plotAngular(hctkphi,hctkphi_moments,opts->write_eps,"ctkphieff",appendix, subfolder);
|
||
plotAngular(hq2ctl,hq2ctl_moments,opts->write_eps,"q2ctleff",appendix, subfolder);
|
||
plotAngular(hq2ctk,hq2ctk_moments,opts->write_eps,"q2ctkeff",appendix, subfolder);
|
||
plotAngular(hq2phi,hq2phi_moments,opts->write_eps,"q2phieff",appendix, subfolder);
|
||
}
|
||
|
||
delete hq2; delete hq2_moments;
|
||
delete hctl; delete hctl_moments;
|
||
delete hctk; delete hctk_moments;
|
||
delete hphi; delete hphi_moments;
|
||
delete hctlctk; delete hctlctk_moments;
|
||
delete hctkphi; delete hctkphi_moments;
|
||
delete hctlphi; delete hctlphi_moments;
|
||
delete hq2ctl; delete hq2ctl_moments;
|
||
delete hq2ctk; delete hq2ctk_moments;
|
||
delete hq2phi; delete hq2phi_moments;
|
||
|
||
|
||
hxi_moments[0]->SetMinimum(1.0); hxi_moments[0]->SetMaximum(+2.0);
|
||
hxi_moments[1]->SetMinimum(0.25); hxi_moments[1]->SetMaximum(+1.25);
|
||
hxi_moments[2]->SetMinimum(-1.0); hxi_moments[2]->SetMaximum(+0.0);
|
||
hxi_moments[3]->SetMinimum(-0.75); hxi_moments[3]->SetMaximum(+0.25);
|
||
|
||
for (int i = 4; i<12; i++){
|
||
hxi_moments[i]->SetMinimum(-0.5);
|
||
hxi_moments[i]->SetMaximum(+0.5);
|
||
}
|
||
|
||
for (auto hist: hxi_moments) hist->GetYaxis()->SetTitleOffset(1.4);
|
||
|
||
TCanvas* c10 = new TCanvas("c10", "c10", 1600, 1200);
|
||
c10->Divide(4,3);
|
||
plotAngularInOne(c10,1,hxi_moments[0],hxi_ub[0],hxi_hist[0],hxi_ml_hist[0],runMinuit,edges.q2min,edges.q2max,1.5,false);
|
||
plotAngularInOne(c10,2,hxi_moments[1],hxi_ub[1],hxi_hist[1],hxi_ml_hist[1],runMinuit,edges.q2min,edges.q2max,0.75,false);
|
||
plotAngularInOne(c10,3,hxi_moments[2],hxi_ub[2],hxi_hist[2],hxi_ml_hist[2],runMinuit,edges.q2min,edges.q2max,-0.5,false);
|
||
plotAngularInOne(c10,4,hxi_moments[3],hxi_ub[3],hxi_hist[3],hxi_ml_hist[3],runMinuit,edges.q2min,edges.q2max,-0.25,false);
|
||
for (int i = 4; i<12; i++){
|
||
plotAngularInOne(c10,i+1,hxi_moments[i],hxi_ub[i],hxi_hist[i],hxi_ml_hist[i],runMinuit,
|
||
edges.q2min,edges.q2max,0.0,is_param_folded(i,opts));
|
||
}
|
||
|
||
if(opts->write_eps)c10->Print((subfolder + "/xis"+appendix+".eps").c_str(),"eps");
|
||
|
||
delete c10;
|
||
|
||
spdlog::info( "end PLOTS" );
|
||
|
||
}//end make plots
|
||
|
||
//delete histograms
|
||
for (auto hist: hxi_moments) delete hist;
|
||
for (auto hist: hxi_ml_hist) delete hist;
|
||
for (auto hist: hxi_hist) delete hist;
|
||
for (auto hist: hxi_ub) delete hist;
|
||
|
||
|
||
}; //end parametrize_eff_phsp_4d()
|
||
|
||
double bu2kstarmumu_pdf::get_ang_eff(fcnc::options *opts,
|
||
double q2, double ctl, double ctk, double phi) const{
|
||
npolynom npol(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
|
||
//Posibly can be faster, but with more memory consumption and unless I calculate this for like a million events it doesn't make a difference. This way the code is readable and usable at many places
|
||
double eff = 0.0;
|
||
|
||
for(unsigned int h = 0; h<npol.q2; h++){
|
||
for(unsigned int i = 0; i<npol.ctl; i++){
|
||
for(unsigned int j = 0; j<npol.ctk; j++){
|
||
for(unsigned int k = 0; k<npol.phi; k++){
|
||
eff += coeffs_eff_4d[npol.get_bin_in4D(h,i,j,k)]
|
||
*pow(q2,h)*pow(ctl,i)*pow(ctk,j)*pow(phi,k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//spdlog::trace("ctl={0:f}\t ctk={1:f}\t phi={2:f}\t eff={3:f}", ctl, ctk, phi, eff);
|
||
return eff;
|
||
}
|
||
|
||
|
||
double bu2kstarmumu_pdf::get_ang_eff(fcnc::options *opts, fcnc::event evt, bool fa) const{
|
||
//fa=true meansusing the evt. _fa values
|
||
if (fa) return get_ang_eff(opts, evt.q2, evt.costhetal_fa, evt.costhetak_fa, evt.phi_fa);
|
||
else return get_ang_eff(opts, evt.q2, evt.costhetal, evt.costhetak, evt.phi);
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::eff_fcn(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag)
|
||
{
|
||
//TODO full angular fit
|
||
npolynom npol(current_pdf->opts);
|
||
|
||
std::vector<double> chebyshev_costhetal(npol.ctl, 0.0);
|
||
std::vector<double> chebyshev_costhetak(npol.ctk, 0.0);
|
||
std::vector<double> chebyshev_phi(npol.phi, 0.0);
|
||
|
||
for (unsigned int j = 0; j<npol.ctl; j++) chebyshev_costhetal.at(j) = params[j];
|
||
for (unsigned int j = 0; j<npol.ctk; j++) chebyshev_costhetak.at(j) = params[npol.ctl+j];
|
||
for (unsigned int j = 0; j<npol.phi; j++) chebyshev_phi.at(j) = params[npol.ctl+npol.ctk+j];
|
||
|
||
std::vector<double> coeffs_costhetal(npol.ctl, 0.0);
|
||
std::vector<double> coeffs_costhetak(npol.ctk, 0.0);
|
||
std::vector<double> coeffs_phi(npol.phi, 0.0);
|
||
|
||
std::vector<double> temp_ctl(npol.ctl, 0.0);
|
||
std::vector<double> temp_ctk(npol.ctk, 0.0);
|
||
std::vector<double> temp_phi(npol.phi, 0.0);
|
||
|
||
chebyshev_to_poly(chebyshev_costhetal, temp_ctl);
|
||
chebyshev_to_poly(chebyshev_costhetak, temp_ctk);
|
||
chebyshev_to_poly(chebyshev_phi, temp_phi);
|
||
|
||
for (unsigned int i=0; i<coeffs_costhetak.size(); i++){
|
||
coeffs_costhetak.at(i) = temp_ctk.at(i);
|
||
}
|
||
for (unsigned int i=0; i<coeffs_costhetal.size(); i++){
|
||
coeffs_costhetal.at(i) = temp_ctl.at(i);
|
||
}
|
||
correct_poly(temp_phi, coeffs_phi, -TMath::Pi(), +TMath::Pi());
|
||
|
||
double cijk = 0.0;
|
||
double f1 = 0.0, f2 = 0.0, f3 = 0.0, f4 = 0.0, f5 = 0.0,
|
||
f6 = 0.0, f7 = 0.0, f8 = 0.0, f9 = 0.0, f10 = 0.0, f11 = 0.0, f12 = 0.0;
|
||
const double pi = MY_PI;
|
||
double c = C_PWAVE;
|
||
if(current_pdf->opts->full_angular)c *= 2.0; //folding in phi
|
||
|
||
if (current_pdf->opts->full_angular)
|
||
{
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++)
|
||
{
|
||
cijk = c*coeffs_costhetal.at(i)*coeffs_costhetak.at(j)*coeffs_phi.at(k);
|
||
|
||
f1 += cijk * (pow(-1,i)/(i+1.0)+1.0/(i+1.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))*(pow(-1,k)*pow(pi,k+1)/(k+1.0)+pow(pi,k+1)/(k+1.0));
|
||
f2 += cijk * (pow(-1,i)/(i+1.0)+1.0/(i+1.0))*(pow(-1,j)/(j+3.0)+1.0/(j+3.0))*(pow(-1,k)*pow(pi,k+1)/(k+1.0)+pow(pi,k+1)/(k+1.0));
|
||
f3 += cijk * (((i-1.0)*pow(-1,i)/(i*i+4.0*i+3.0)+(i-1.0)/(i*i+4.0*i+3.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))*(pow(-1,k)*pow(pi,k+1)/(k+1.0)+pow(pi,k+1)/(k+1.0)));
|
||
f4 += cijk * (((i-1.0)*pow(-1,i)/(i*i+4.0*i+3.0)+(i-1.0)/(i*i+4.0*i+3.0))*(pow(-1,j)/(j+3.0)+1/(j+3.0))*(pow(-1,k)*pow(pi,k+1.0)/(k+1.0)+pow(pi,k+1)/(k+1.0)));
|
||
|
||
f5 += cijk * (2.0*pow(-1,i)/(i*i+4.0*i+3.0)+2.0/(i*i+4.0*i+3.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))
|
||
*(integral_x_to_n_times_cos_2x(pi,k)-integral_x_to_n_times_cos_2x(-pi,k));
|
||
f6 += cijk * 4.0
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,j+1)-integral_x_to_n_times_sqrt_1_minus_x2(-1,j+1))
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,i+1)-integral_x_to_n_times_sqrt_1_minus_x2(-1,i+1))
|
||
*(integral_x_to_n_times_cos_x(pi,k)-integral_x_to_n_times_cos_x(-pi,k));
|
||
f7 += cijk * 2.0
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,j+1)-integral_x_to_n_times_sqrt_1_minus_x2(-1,j+1))
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,i)-integral_x_to_n_times_sqrt_1_minus_x2(-1,i))
|
||
*(integral_x_to_n_times_cos_x(pi,k)-integral_x_to_n_times_cos_x(-pi,k));
|
||
f8 += cijk * (1.0/(i+2.0)-pow(-1,i)/(i+2.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))*(pow(-1,k)*pow(pi,k+1)/(k+1.0)+pow(pi,k+1)/(k+1.0));
|
||
|
||
f9 += cijk * (1.0/(i+2.0)-pow(-1,i)/(i+2.0))*(pow(-1,j)/(j+3.0)+1.0/(j+3.0))*(pow(-1,k)*pow(pi,k+1)/(k+1.0)+pow(pi,k+1)/(k+1.0));
|
||
f10 += cijk * 2.0
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,j+1)-integral_x_to_n_times_sqrt_1_minus_x2(-1,j+1))
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,i)-integral_x_to_n_times_sqrt_1_minus_x2(-1,i))
|
||
*(integral_x_to_n_times_sin_x(pi,k)-integral_x_to_n_times_sin_x(-pi,k));
|
||
f11 += cijk * 4.0
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,j+1)-integral_x_to_n_times_sqrt_1_minus_x2(-1,j+1))
|
||
*(integral_x_to_n_times_sqrt_1_minus_x2(1,i+1)-integral_x_to_n_times_sqrt_1_minus_x2(-1,i+1))
|
||
*(integral_x_to_n_times_sin_x(pi,k)-integral_x_to_n_times_sin_x(-pi,k));
|
||
f12 += cijk * (2.0*pow(-1,i)/(i*i+4.0*i+3.0)+2.0/(i*i+4.0*i+3.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))
|
||
*(integral_x_to_n_times_sin_2x(pi,k)-integral_x_to_n_times_sin_2x(-pi,k));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++)
|
||
{
|
||
cijk = c * coeffs_costhetal.at(i)*coeffs_costhetak.at(j)*coeffs_phi.at(k);
|
||
/*
|
||
f1 += cijk * 2.0*(2.0*pow(-1,i)/(i*i+4.0*i+3.0)+2.0/(i*i+4.0*i+3.0))*(pow(-1,j)/(j+3.0)+1.0/(j+3.0))*pow(MY_PI,k+1)/(k+1.0);
|
||
f2 += cijk * ((i+2.0)*pow(-1,i)/(i*i+4.0*i+3.0)+(i+2.0)/(i*i+4.0*i+3.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))*pow(MY_PI,k+1)/(k+1.0);
|
||
f3 += cijk * (2.0*pow(-1,i)/(i*i+4.0*i+3.0)+2.0/(i*i+4.0*i+3.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))
|
||
*(integral_x_to_n_times_cos_2x(MY_PI, k) - integral_x_to_n_times_cos_2x(0.0, k));
|
||
f4 += cijk * 4.0*(1.0/(i+2.0)-pow(-1,i)/(i+2.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))*pow(MY_PI,k+1)/(3.0*(k+1.0));
|
||
f5 += cijk * (2.0*pow(-1,i)/(i*i+4.0*i+3.0)+2.0/(i*i+4.0*i+3.0))*(2.0*pow(-1,j)/(j*j+4.0*j+3.0)+2.0/(j*j+4.0*j+3.0))
|
||
*(integral_x_to_n_times_sin_2x(MY_PI, k) - integral_x_to_n_times_sin_2x(0.0, k));
|
||
*/
|
||
//TODO add f1 to f12 for new folding!
|
||
|
||
spdlog::error("Function 'eff_fcn' not yet implemented for folding");
|
||
assert(0);
|
||
|
||
|
||
}
|
||
}
|
||
|
||
//calculate eps()
|
||
std::vector<double> ch_costhetal;
|
||
std::vector<double> ch_costhetak;
|
||
std::vector<double> ch_phi;
|
||
double lh_costhetal = 0.0;
|
||
double lh_costhetak = 0.0;
|
||
double lh_phi = 0.0;
|
||
unsigned int nsize = current_pdf->eff_events.size();
|
||
for (unsigned int i=0; i<nsize; i++)
|
||
{
|
||
event meas = current_pdf->eff_events.at(i);
|
||
chebyshev(meas.costhetal, npol.ctl, ch_costhetal);
|
||
chebyshev(meas.costhetak, npol.ctk, ch_costhetak);
|
||
|
||
if (current_pdf->opts->full_angular)
|
||
chebyshev(meas.phi/MY_PI, npol.phi, ch_phi);
|
||
else
|
||
chebyshev(2.0*meas.phi/MY_PI-1.0, npol.phi, ch_phi);
|
||
//double result = 0.0;
|
||
double result_costhetal = 0.0;
|
||
for (unsigned int j = 0; j<npol.ctl; j++){
|
||
result_costhetal += params[j]*ch_costhetal.at(j);// /norm_costhetal;
|
||
}
|
||
lh_costhetal += -2.0*TMath::Log(result_costhetal);
|
||
double result_costhetak = 0.0;
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
result_costhetak += params[npol.ctl+j]*ch_costhetak.at(j);// /norm_costhetak;
|
||
}
|
||
lh_costhetak += -2.0*TMath::Log(result_costhetak);
|
||
double result_phi = 0.0;
|
||
for (unsigned int j = 0; j<npol.phi; j++){
|
||
result_phi += params[npol.ctl+npol.ctk+j]*ch_phi.at(j);// /norm_phi;
|
||
}
|
||
lh_phi += -2.0*TMath::Log(result_phi);
|
||
}
|
||
|
||
//multiply with the pdf
|
||
const double j1s = current_pdf->eff_params->J1s();
|
||
const double j1c = current_pdf->eff_params->J1c();
|
||
const double j2s = current_pdf->eff_params->J2s();
|
||
const double j2c = current_pdf->eff_params->J2c();
|
||
const double j3 = current_pdf->eff_params->J3();
|
||
const double j4 = current_pdf->eff_params->J4();
|
||
const double j5 = current_pdf->eff_params->J5();
|
||
const double j6s = current_pdf->eff_params->J6s();
|
||
const double j6c = current_pdf->eff_params->J6c();
|
||
const double j7 = current_pdf->eff_params->J7();
|
||
const double j8 = current_pdf->eff_params->J8();
|
||
const double j9 = current_pdf->eff_params->J9();
|
||
|
||
double sig_norm = 0.0;
|
||
sig_norm = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9);
|
||
double lh_sig = 0.0, prob = 0.0;
|
||
|
||
for (unsigned int i=0; i<nsize; i++)
|
||
{
|
||
event meas = current_pdf->eff_events.at(i);
|
||
if (current_pdf->opts->full_angular)
|
||
{
|
||
current_pdf->fj(meas.costhetal, meas.costhetak, meas.phi,
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
prob = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)/sig_norm;
|
||
}
|
||
else
|
||
{
|
||
current_pdf->folded_fj(meas.costhetal, meas.costhetak, meas.phi, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
/*
|
||
prob = 9.0/16.0/MY_PI * (fl * f1
|
||
+ft * f2
|
||
+s3 * f3
|
||
+afb * f4
|
||
+aim * f5
|
||
)/sig_norm;
|
||
*/
|
||
prob = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)/sig_norm;
|
||
}
|
||
lh_sig += -2.0*TMath::Log(prob);
|
||
}
|
||
//is the integral correct here?
|
||
//need to do a nice integration over pdf_sig(costhetal,costhetak,phi)*eps(costhetal,costhetak,phi)
|
||
lh = lh_sig + lh_costhetal + lh_costhetak + lh_phi;
|
||
};
|
||
|
||
//this does not assume factorisation of the three dependencies, but assumes phsp MC in 3D
|
||
void bu2kstarmumu_pdf::eff_fcn_phsp(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag)
|
||
{
|
||
//TODO
|
||
unsigned int ncosthetal = 5;
|
||
unsigned int ncosthetak = 5;
|
||
unsigned int nphi = 5;
|
||
|
||
//make sure we are doing full angular acceptance, no phi folding
|
||
assert(current_pdf->opts->full_angular);
|
||
|
||
//need to account for the norm given the current parameters
|
||
double norm = 0.0;
|
||
for (unsigned int i = 0; i<ncosthetal; i++)
|
||
for (unsigned int j = 0; j<ncosthetak; j++)
|
||
for (unsigned int k = 0; k<nphi; k++)
|
||
{
|
||
double cijk = params[ncosthetak*nphi*i+nphi*j+k];
|
||
norm += cijk
|
||
*(integral_chebyshev(+1.0, i)-integral_chebyshev(-1.0, i)) //TODO: check the -1,+1
|
||
*(integral_chebyshev(+1.0, j)-integral_chebyshev(-1.0, j))
|
||
*(integral_chebyshev(+1.0, k)-integral_chebyshev(-1.0, k));//there surely is a more efficient way
|
||
}
|
||
//this gives Sum_events Log(eps(event))
|
||
lh = 0.0;
|
||
unsigned int nsize = current_pdf->eff_events.size();
|
||
//loop over all events
|
||
for (unsigned int l=0; l<nsize; l++) {
|
||
const event& meas = current_pdf->eff_events.at(l);
|
||
std::vector<double> ch_costhetal;
|
||
std::vector<double> ch_costhetak;
|
||
std::vector<double> ch_phi;
|
||
chebyshev(meas.costhetal, ncosthetal, ch_costhetal);
|
||
chebyshev(meas.costhetak, ncosthetak, ch_costhetak);
|
||
chebyshev(meas.phi/MY_PI, nphi, ch_phi);
|
||
|
||
double result = 0.0;
|
||
for (unsigned int i = 0; i<ncosthetal; i++)
|
||
for (unsigned int j = 0; j<ncosthetak; j++)
|
||
for (unsigned int k = 0; k<nphi; k++)
|
||
{
|
||
double cijk = params[ncosthetak*nphi*i+nphi*j+k];
|
||
result += cijk*ch_costhetal.at(i)*ch_costhetak.at(j)*ch_phi.at(k);
|
||
}
|
||
if (result > 0.0 && !std::isnan(result) && !std::isinf(result))
|
||
lh += -2.0*TMath::Log(result/norm) - (-2.0*TMath::Log(1.0/8.0));//can subtract
|
||
else
|
||
lh += (-100.0*2.0*TMath::Log(1.0/8.0));
|
||
}
|
||
spdlog::debug( "eff_fcn_phsp lh {0:f}\t npar {1:d}\tiflag {2:d}\tnorm {3:f}", lh, npar, iflag, norm);
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::eff_fcn_phsp_4d(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag)
|
||
{
|
||
npolynom npol(current_pdf->opts);
|
||
|
||
double q2min = current_pdf->opts->TheQ2binsmin.front(), q2max = current_pdf->opts->TheQ2binsmax.back();
|
||
double ctkmin = current_pdf->opts->ctk_min, ctkmax = current_pdf->opts->ctk_max;
|
||
double ctlmin = current_pdf->opts->ctl_min, ctlmax = current_pdf->opts->ctl_max;
|
||
double phimin = current_pdf->opts->phi_min, phimax = current_pdf->opts->phi_max;
|
||
|
||
spdlog::warn("The TMinuit version was not yet tested for folded analysis!");
|
||
assert(current_pdf->opts->full_angular);
|
||
|
||
//need to account for the norm given the current parameters
|
||
double norm = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
double chijk = params[npol.get_bin_in4D(h,i,j,k)];
|
||
if (chijk == 0.0) continue;
|
||
norm += chijk
|
||
*(integral_chebyshev(+1.0, h)-integral_chebyshev(-1.0, h))
|
||
*(integral_chebyshev(+1.0, i)-integral_chebyshev(-1.0, i))
|
||
*(integral_chebyshev(+1.0, j)-integral_chebyshev(-1.0, j))
|
||
*(integral_chebyshev(+1.0, k)-integral_chebyshev(-1.0, k));//there surely is a more efficient way
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//this gives Sum_events Log(eps(event))
|
||
lh = 0.0;
|
||
unsigned int nsize = current_pdf->eff_events.size();
|
||
//loop over all events
|
||
for (unsigned int l=0; l<nsize; l++){
|
||
const event& meas = current_pdf->eff_events.at(l);
|
||
if (meas.q2 < q2min || meas.q2 > q2max) continue;
|
||
|
||
std::vector<double> ch_q2;
|
||
std::vector<double> ch_costhetal;
|
||
std::vector<double> ch_costhetak;
|
||
std::vector<double> ch_phi;
|
||
chebyshev(2.0*(meas.q2 - q2min ) / (q2max - q2min ) - 1.0, npol.q2, ch_q2);
|
||
chebyshev(2.0*(meas.costhetal - ctlmin) / (ctlmax - ctlmin) - 1.0, npol.ctl, ch_costhetal);
|
||
chebyshev(2.0*(meas.costhetak - ctkmin) / (ctkmax - ctkmin) - 1.0, npol.ctk, ch_costhetak);
|
||
chebyshev(2.0*(meas.phi - phimin) / (phimax - phimin) - 1.0, npol.phi, ch_phi);
|
||
/*
|
||
chebyshev(meas.costhetal, ncosthetal, ch_costhetal);
|
||
chebyshev(meas.costhetak, ncosthetak, ch_costhetak);
|
||
chebyshev(meas.phi/pi, nphi, ch_phi);
|
||
*/
|
||
double result = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.q2; k++)
|
||
{
|
||
double chijk = params[npol.get_bin_in4D(h,i,j,k)];
|
||
result += chijk*ch_q2.at(h)*ch_costhetal.at(i)*ch_costhetak.at(j)*ch_phi.at(k);
|
||
}
|
||
if (result > 0.0 && !std::isnan(result) && !std::isinf(result)){
|
||
lh += -2.0*meas.weight*TMath::Log(result/norm) - (-2.0*TMath::Log(1.0/16.0));
|
||
}
|
||
else{
|
||
lh += (-100.0*2.0*TMath::Log(1.0/8.0));
|
||
}
|
||
}
|
||
|
||
spdlog::debug( "eff_fcn_phsp_4d lh {0:f}\t npar {1:d}\tiflag {2:d}\tnorm {3:f}", lh, npar, iflag, norm);
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::update_cached_normalization(const bu2kstarmumu_parameters* params)
|
||
{
|
||
spdlog::trace("updating cached normalisation");
|
||
//this caches the overall normalisation for both signal and background
|
||
double q2 = params->eff_q2();
|
||
//swave norm
|
||
if (opts->use_mkpi || opts->fit_mkpi){
|
||
double mkpi_min = opts->mkpi_min/1.0e+3;
|
||
double mkpi_max = opts->mkpi_max/1.0e+3;
|
||
//double q2 = params->eff_q2();
|
||
double asphase = params->asphase();
|
||
double a = params->a();
|
||
double r = params->r();
|
||
double gammakstar = params->gammakstar();
|
||
double mkstar = params->mkstar();
|
||
double gammakstarplus = params->gammakstarplus();
|
||
double mkstarplus = params->mkstarplus();
|
||
double R = params->R();
|
||
|
||
double gammaf800 = params->gammaf800();
|
||
double mf800 = params->mf800();
|
||
double f800mag = params->f800mag();
|
||
double f800phase = params->f800phase();
|
||
//integrate over mkpi2
|
||
const double mk = PDGMASS_KST_KAON/1.0e+3;
|
||
const double mpi = PDGMASS_KST_PION/1.0e+3;
|
||
const double mb = PDGMASS_B/1.0e+3;
|
||
const double from = opts->mkpi_full_range_norm ? (mk+mpi) : mkpi_min;
|
||
const double to = opts->mkpi_full_range_norm ? mb : mkpi_max;
|
||
std::complex<double> mkpi_swavepwave_norm;
|
||
if (opts->simple_mkpi){
|
||
mkpi_swave_2_norm = int_mkpi_simple_kstarzero_amp_squared(from, to, q2,
|
||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
|
||
mkpi_pwave_2_norm = int_mkpi_simple_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar);
|
||
mkpi_swavepwave_norm = int_mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(from, to, q2,
|
||
gammakstar, mkstar, asphase,
|
||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
|
||
mkpi_re_swavepwave_norm = mkpi_swavepwave_norm.real();
|
||
mkpi_im_swavepwave_norm = mkpi_swavepwave_norm.imag();
|
||
}
|
||
else if (opts->isobar){
|
||
mkpi_swave_2_norm = int_mkpi_kstarzero_isobar_amp_squared(from, to, q2,
|
||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
|
||
mkpi_pwave_2_norm = int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
|
||
mkpi_swavepwave_norm = int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(from, to, q2,
|
||
gammakstar, mkstar, asphase,
|
||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
|
||
mkpi_re_swavepwave_norm = mkpi_swavepwave_norm.real();
|
||
mkpi_im_swavepwave_norm = mkpi_swavepwave_norm.imag();
|
||
}
|
||
else{//nominal lass
|
||
mkpi_swave_2_norm = int_mkpi_kstarzero_lass_amp_squared(from, to, q2, asphase, a, r, gammakstarplus, mkstarplus, R);
|
||
mkpi_pwave_2_norm = int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
|
||
mkpi_swavepwave_norm = int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(from, to, q2,
|
||
gammakstar, mkstar,
|
||
asphase, a, r, gammakstarplus, mkstarplus, R);
|
||
mkpi_re_swavepwave_norm = mkpi_swavepwave_norm.real();
|
||
mkpi_im_swavepwave_norm = mkpi_swavepwave_norm.imag();
|
||
}
|
||
|
||
if (opts->use_p2){
|
||
//mkpi_bkg(
|
||
std::vector<double> ch_p2(5, 0.0);
|
||
ch_p2.at(0) = params->cbkgp20();
|
||
ch_p2.at(1) = params->cbkgp21();
|
||
ch_p2.at(2) = params->cbkgp22();
|
||
ch_p2.at(3) = params->cbkgp23();
|
||
ch_p2.at(4) = params->cbkgp24();
|
||
std::vector<double> poly_p2(ch_p2.size(), 0.0);
|
||
chebyshev_to_poly(ch_p2, poly_p2);
|
||
std::vector<double> poly_corr_p2(ch_p2.size(), 0.0);
|
||
correct_poly(poly_p2, poly_corr_p2, mkpi_min*mkpi_min, mkpi_max*mkpi_max);
|
||
|
||
mkpi_bkg_norm = 0.0;
|
||
for (unsigned int i=0; i<ch_p2.size(); i++)
|
||
mkpi_bkg_norm += poly_corr_p2.at(i)*(pow(mkpi_max*mkpi_max,i+1)-pow(mkpi_min*mkpi_min,i+1))/(i+1.0);
|
||
}
|
||
else{
|
||
std::vector<double> ch_mkpi(5, 0.0);
|
||
ch_mkpi.at(0) = params->cbkgmkpi0();
|
||
ch_mkpi.at(1) = params->cbkgmkpi1();
|
||
ch_mkpi.at(2) = params->cbkgmkpi2();
|
||
ch_mkpi.at(3) = params->cbkgmkpi3();
|
||
ch_mkpi.at(4) = params->cbkgmkpi4();
|
||
std::vector<double> poly_mkpi(ch_mkpi.size(), 0.0);
|
||
chebyshev_to_poly(ch_mkpi, poly_mkpi);
|
||
std::vector<double> poly_corr_mkpi(ch_mkpi.size(), 0.0);
|
||
correct_poly(poly_mkpi, poly_corr_mkpi, mkpi_min, mkpi_max);
|
||
|
||
mkpi_bkg_norm = 0.0;
|
||
if (opts->mkpi_threshold){
|
||
mkpi_bkg_norm = fcnc::int_threshold(mkpi_min, mkpi_max, 0.633, params->nthreshold());
|
||
}
|
||
else{
|
||
for(unsigned int i=0; i<poly_mkpi.size(); i++)
|
||
mkpi_bkg_norm += poly_corr_mkpi.at(i)*(pow(mkpi_max,i+1)-pow(mkpi_min,i+1))/(i+1.0);
|
||
}
|
||
}
|
||
}
|
||
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0,
|
||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||
|
||
double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;
|
||
|
||
const double j1s = params->J1s();
|
||
const double j1c = params->J1c();
|
||
const double j2s = params->J2s();
|
||
const double j2c = params->J2c();
|
||
const double j3 = params->J3();
|
||
const double j4 = params->J4();
|
||
const double j5 = params->J5();
|
||
const double j6s = params->J6s();
|
||
const double j6c = params->J6c();
|
||
const double j7 = params->J7();
|
||
const double j8 = params->J8();
|
||
const double j9 = params->J9();
|
||
|
||
const double fs = params->FS();
|
||
const double js1 = params->SS1();
|
||
const double js2 = params->SS2();
|
||
const double js3 = params->SS3();
|
||
const double js4 = params->SS4();
|
||
const double js5 = params->SS5();
|
||
|
||
if(spdlog_trace()){ //print out the integrated angular moments. with and without weights, as well as their ratios
|
||
|
||
load_coeffs_eff_phsp_4d();
|
||
|
||
integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12, q2);
|
||
double pwave_weighted = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9);
|
||
|
||
integrated_fj_noacc(f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
double pwave_noweights = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9);
|
||
|
||
swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
|
||
swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
|
||
spdlog::trace("Integrated P-wave:");
|
||
spdlog::trace("P-wave no weights: {0:0.5f}",pwave_noweights);
|
||
spdlog::trace("P-wave weighted: {0:0.5f}",pwave_weighted);
|
||
spdlog::trace("P-wave ratio: {0:0.5f}\n",pwave_weighted / pwave_noweights);
|
||
|
||
if (opts->swave){
|
||
double swave_noweights = (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
double swave_weighted = (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
spdlog::trace("Integrated S-wave:");
|
||
spdlog::trace("S-wave weighted: {0:0.5f}{0:0.5f}",swave_weighted);
|
||
spdlog::trace("S-wave no weights: {0:0.5f}",swave_noweights);
|
||
spdlog::trace("S-wave ratio: {0:0.5f}\n",swave_weighted / swave_noweights);
|
||
spdlog::trace("Double ratio (s/p):{0:0.5f}",(swave_weighted / swave_noweights) / (pwave_weighted / pwave_noweights));
|
||
}
|
||
|
||
//assert(0);
|
||
|
||
}
|
||
|
||
if(opts->full_angular){
|
||
if(!opts->cache_fis){
|
||
if(opts->use_angular_acc){
|
||
integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12, q2);
|
||
}
|
||
else{//this is also what the weighted fit uses!
|
||
integrated_fj_noacc(f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
}
|
||
fbuffer_f1 = f1;
|
||
fbuffer_f2 = f2;
|
||
fbuffer_f3 = f3;
|
||
fbuffer_f4 = f4;
|
||
fbuffer_f5 = f5;
|
||
fbuffer_f6 = f6;
|
||
fbuffer_f7 = f7;
|
||
fbuffer_f8 = f8;
|
||
fbuffer_f9 = f9;
|
||
fbuffer_f10 = f10;
|
||
fbuffer_f11 = f11;
|
||
fbuffer_f12 = f12;
|
||
}
|
||
else{
|
||
f1 = fbuffer_f1;
|
||
f2 = fbuffer_f2;
|
||
f3 = fbuffer_f3;
|
||
f4 = fbuffer_f4;
|
||
f5 = fbuffer_f5;
|
||
f6 = fbuffer_f6;
|
||
f7 = fbuffer_f7;
|
||
f8 = fbuffer_f8;
|
||
f9 = fbuffer_f9;
|
||
f10 = fbuffer_f10;
|
||
f11 = fbuffer_f11;
|
||
f12 = fbuffer_f12;
|
||
}
|
||
fnorm_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9);
|
||
if (opts->fit_asymmetries){
|
||
fnorm_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c);
|
||
}
|
||
|
||
bool swave = opts->swave;
|
||
if (swave){
|
||
if (!opts->cache_fis){
|
||
if (opts->use_angular_acc){
|
||
swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
}
|
||
else{//weighted fit and fit without acceptance
|
||
swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
|
||
fbuffer_fs1 = fs1;
|
||
fbuffer_fs2 = fs2;
|
||
fbuffer_fs3 = fs3;
|
||
fbuffer_fs4 = fs4;
|
||
fbuffer_fs5 = fs5;
|
||
fbuffer_fs6 = fs6;
|
||
}
|
||
else{
|
||
fs1 = fbuffer_fs1;
|
||
fs2 = fbuffer_fs2;
|
||
fs3 = fbuffer_fs3;
|
||
fs4 = fbuffer_fs4;
|
||
fs5 = fbuffer_fs5;
|
||
fs6 = fbuffer_fs6;
|
||
}
|
||
fnorm_sig = (1.0-fs) * (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4 + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
|
||
+ (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
if (opts->fit_asymmetries){
|
||
fnorm_sig = (1.0-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c)
|
||
+ (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
}
|
||
}
|
||
|
||
spdlog::trace("Fnormsig (full_angular) {0:f}",fnorm_sig );
|
||
spdlog::trace("Normalization integrals P-wave");
|
||
spdlog::trace("\tj1s {0:0.4f}",f1/fnorm_sig);
|
||
spdlog::trace("\tj1c {0:0.4f}",f2/fnorm_sig);
|
||
spdlog::trace("\tj2s {0:0.4f}",f3/fnorm_sig);
|
||
spdlog::trace("\tj2c {0:0.4f}",f4/fnorm_sig);
|
||
spdlog::trace("\tj3 {0:0.4f}",f5/fnorm_sig);
|
||
spdlog::trace("\tj4 {0:0.4f}",f6/fnorm_sig);
|
||
spdlog::trace("\tj5 {0:0.4f}",f7/fnorm_sig);
|
||
spdlog::trace("\tj6s {0:0.4f}",f8/fnorm_sig);
|
||
spdlog::trace("\tj6c {0:0.4f}",f9/fnorm_sig);
|
||
spdlog::trace("\tj7 {0:0.4f}",f10/fnorm_sig);
|
||
spdlog::trace("\tj8 {0:0.4f}",f11/fnorm_sig);
|
||
spdlog::trace("\tj9 {0:0.4f}",f12/fnorm_sig);
|
||
if(opts->swave){
|
||
spdlog::trace("Normalization integrals S-wave");
|
||
spdlog::trace("fs {0:0.4f}",fs1/fnorm_sig);
|
||
spdlog::trace("\tas1 {0:0.4f}",fs2/fnorm_sig);
|
||
spdlog::trace("\tas2 {0:0.4f}",fs3/fnorm_sig);
|
||
spdlog::trace("\tas3 {0:0.4f}",fs4/fnorm_sig);
|
||
spdlog::trace("\tas4 {0:0.4f}",fs5/fnorm_sig);
|
||
spdlog::trace("\tas5 {0:0.4f}",fs6/fnorm_sig);
|
||
}
|
||
|
||
spdlog::trace("Angular amplitudes: ");
|
||
spdlog::trace("\tj1s {0:0.4f}",j1s);
|
||
spdlog::trace("\tj1c {0:0.4f}",j1c);
|
||
spdlog::trace("\tj2s {0:0.4f}",j2s);
|
||
spdlog::trace("\tj2c {0:0.4f}",j2c);
|
||
spdlog::trace("\tj3 {0:0.4f}",j3);
|
||
spdlog::trace("\tj4 {0:0.4f}",j4);
|
||
spdlog::trace("\tj5 {0:0.4f}",j5);
|
||
spdlog::trace("\tj6s {0:0.4f}",j6s);
|
||
spdlog::trace("\tj6c {0:0.4f}",j6c);
|
||
spdlog::trace("\tj7 {0:0.4f}",j7);
|
||
spdlog::trace("\tj8 {0:0.4f}",j8);
|
||
spdlog::trace("\tj9 {0:0.4f}",j9);
|
||
|
||
}
|
||
else //folded normalization!
|
||
{
|
||
if (!opts->cache_fis) {
|
||
if (opts->use_angular_acc){
|
||
folded_integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12, q2);
|
||
}
|
||
else{//this is also what the weighted fit uses!
|
||
folded_integrated_fj_noacc(f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12);
|
||
}
|
||
fbuffer_f1 = f1;
|
||
fbuffer_f2 = f2;
|
||
fbuffer_f3 = f3;
|
||
fbuffer_f4 = f4;
|
||
fbuffer_f5 = f5;
|
||
fbuffer_f6 = f6;
|
||
fbuffer_f7 = f7;
|
||
fbuffer_f8 = f8;
|
||
fbuffer_f9 = f9;
|
||
fbuffer_f10 = f10;
|
||
fbuffer_f11 = f11;
|
||
fbuffer_f12 = f12;
|
||
}
|
||
else{
|
||
f1 = fbuffer_f1;
|
||
f2 = fbuffer_f2;
|
||
f3 = fbuffer_f3;
|
||
f4 = fbuffer_f4;
|
||
f5 = fbuffer_f5;
|
||
f6 = fbuffer_f6;
|
||
f7 = fbuffer_f7;
|
||
f8 = fbuffer_f8;
|
||
f9 = fbuffer_f9;
|
||
f10 = fbuffer_f10;
|
||
f11 = fbuffer_f11;
|
||
f12 = fbuffer_f12;
|
||
}
|
||
|
||
fnorm_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9);
|
||
if (opts->fit_asymmetries){
|
||
fnorm_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c);
|
||
}
|
||
bool swave = opts->swave;
|
||
if (swave){
|
||
if (!opts->cache_fis) {
|
||
if (opts->use_angular_acc ){
|
||
folded_swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
}
|
||
else{//weighted fit and fit without acceptance
|
||
folded_swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
|
||
fbuffer_fs1 = fs1;
|
||
fbuffer_fs2 = fs2;
|
||
fbuffer_fs3 = fs3;
|
||
fbuffer_fs4 = fs4;
|
||
fbuffer_fs5 = fs5;
|
||
fbuffer_fs6 = fs6;
|
||
}
|
||
else {
|
||
fs1 = fbuffer_fs1;
|
||
fs2 = fbuffer_fs2;
|
||
fs3 = fbuffer_fs3;
|
||
fs4 = fbuffer_fs4;
|
||
fs5 = fbuffer_fs5;
|
||
fs6 = fbuffer_fs6;
|
||
}
|
||
fnorm_sig = (1-fs) * (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4 + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
|
||
+ (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
if (opts->fit_asymmetries)
|
||
fnorm_sig = (1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c)
|
||
+(fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
}
|
||
|
||
spdlog::trace("Fnormsig (folding {0:d}) {1:f}", opts->folding, fnorm_sig );
|
||
spdlog::trace("Normalization integrals P-wave");
|
||
spdlog::trace("\tj1s {0:0.4f}",f1/fnorm_sig);
|
||
spdlog::trace("\tj1c {0:0.4f}",f2/fnorm_sig);
|
||
spdlog::trace("\tj2s {0:0.4f}",f3/fnorm_sig);
|
||
spdlog::trace("\tj2c {0:0.4f}",f4/fnorm_sig);
|
||
spdlog::trace("\tj3 {0:0.4f}",f5/fnorm_sig);
|
||
spdlog::trace("\tj4 {0:0.4f}",f6/fnorm_sig);
|
||
spdlog::trace("\tj5 {0:0.4f}",f7/fnorm_sig);
|
||
spdlog::trace("\tj6s {0:0.4f}",f8/fnorm_sig);
|
||
spdlog::trace("\tj6c {0:0.4f}",f9/fnorm_sig);
|
||
spdlog::trace("\tj7 {0:0.4f}",f10/fnorm_sig);
|
||
spdlog::trace("\tj8 {0:0.4f}",f11/fnorm_sig);
|
||
spdlog::trace("\tj9 {0:0.4f}",f12/fnorm_sig);
|
||
|
||
if(opts->swave){
|
||
spdlog::trace("Normalization integrals S-wave");
|
||
spdlog::trace("fs {0:0.4f}",fs1/fnorm_sig);
|
||
spdlog::trace("\tas1 {0:0.4f}",fs2/fnorm_sig);
|
||
spdlog::trace("\tas2 {0:0.4f}",fs3/fnorm_sig);
|
||
spdlog::trace("\tas3 {0:0.4f}",fs4/fnorm_sig);
|
||
spdlog::trace("\tas4 {0:0.4f}",fs5/fnorm_sig);
|
||
spdlog::trace("\tas5 {0:0.4f}",fs6/fnorm_sig);
|
||
}
|
||
|
||
spdlog::trace("Angular amplitudes: ");
|
||
spdlog::trace("\tj1s {0:0.4f}",j1s);
|
||
spdlog::trace("\tj1c {0:0.4f}",j1c);
|
||
spdlog::trace("\tj2s {0:0.4f}",j2s);
|
||
spdlog::trace("\tj2c {0:0.4f}",j2c);
|
||
spdlog::trace("\tj3 {0:0.4f}",j3);
|
||
spdlog::trace("\tj4 {0:0.4f}",j4);
|
||
spdlog::trace("\tj5 {0:0.4f}",j5);
|
||
spdlog::trace("\tj6s {0:0.4f}",j6s);
|
||
spdlog::trace("\tj6c {0:0.4f}",j6c);
|
||
spdlog::trace("\tj7 {0:0.4f}",j7);
|
||
spdlog::trace("\tj8 {0:0.4f}",j8);
|
||
spdlog::trace("\tj9 {0:0.4f}",j9);
|
||
|
||
|
||
}
|
||
|
||
//bkg norm
|
||
//this is used to convolute the acceptance into the pdf
|
||
if(opts->use_angular_acc && opts->use_weighted_bkg){ //weighted background pdf
|
||
if (opts->full_angular){
|
||
fnorm_bkg = integral_bkg_chebyshev(params, CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX, q2);
|
||
}
|
||
else if(opts->fit_full_angular_bkg){
|
||
|
||
fnorm_bkg = integral_bkg_chebyshev(params, CTL_MIN, CTL_MAX, opts->ctk_min, opts->ctk_max, PHI_MIN, PHI_MAX, q2); //TODO: check here whether this makes any sense (https://gitlab.cern.ch/LHCb-RD/ewp-Bplus2Kstmumu-AngAna/-/merge_requests/21)
|
||
}
|
||
else{
|
||
fnorm_bkg = integral_bkg_chebyshev(params, opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max, q2);
|
||
}
|
||
}
|
||
else{ //non weighted background pdf
|
||
if (opts->full_angular){
|
||
if (opts->flat_bkg) fnorm_bkg = RANGE_3D();
|
||
else fnorm_bkg = integral_bkg(params, opts->ctl_min, opts->ctl_max,
|
||
opts->ctk_min, opts->ctk_max,
|
||
opts->phi_min, opts->phi_max);
|
||
}
|
||
else{ //folded angles
|
||
if (opts->flat_bkg){
|
||
fnorm_bkg = (opts->ctk_max - opts->ctk_min) * (opts->ctl_max - opts->ctl_min) * (opts->phi_max - opts->phi_min);
|
||
}
|
||
else{
|
||
if(opts->fit_full_angular_bkg){
|
||
fnorm_bkg = integral_bkg(params, CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX);
|
||
}
|
||
else{
|
||
fnorm_bkg = integral_bkg(params, opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::update_cached_integrated_fis(const bu2kstarmumu_parameters* params)
|
||
{
|
||
if(opts->cache_fis){
|
||
double q2 = params->eff_q2();
|
||
if(opts->full_angular){
|
||
if(opts->use_angular_acc){
|
||
integrated_fj_chebyshev(fbuffer_f1, fbuffer_f2, fbuffer_f3, fbuffer_f4, fbuffer_f5, fbuffer_f6,
|
||
fbuffer_f7, fbuffer_f8, fbuffer_f9, fbuffer_f10, fbuffer_f11, fbuffer_f12, q2);
|
||
swave_integrated_fj_chebyshev(fbuffer_fs1, fbuffer_fs2, fbuffer_fs3, fbuffer_fs4, fbuffer_fs5, fbuffer_fs6, q2);
|
||
}
|
||
else{//this is also what the weighted fit uses!
|
||
integrated_fj_noacc(fbuffer_f1, fbuffer_f2, fbuffer_f3, fbuffer_f4, fbuffer_f5, fbuffer_f6,
|
||
fbuffer_f7, fbuffer_f8, fbuffer_f9, fbuffer_f10, fbuffer_f11, fbuffer_f12);
|
||
swave_integrated_fj_noacc(fbuffer_fs1, fbuffer_fs2, fbuffer_fs3, fbuffer_fs4, fbuffer_fs5, fbuffer_fs6);
|
||
}
|
||
}
|
||
else{ //folded
|
||
if(opts->use_angular_acc){
|
||
folded_integrated_fj_chebyshev(fbuffer_f1, fbuffer_f2, fbuffer_f3, fbuffer_f4, fbuffer_f5, fbuffer_f6,
|
||
fbuffer_f7, fbuffer_f8, fbuffer_f9, fbuffer_f10, fbuffer_f11, fbuffer_f12, q2);
|
||
folded_swave_integrated_fj_chebyshev(fbuffer_fs1, fbuffer_fs2, fbuffer_fs3, fbuffer_fs4, fbuffer_fs5, fbuffer_fs6, q2);
|
||
}
|
||
else{//this is also what the weighted fit uses!
|
||
folded_integrated_fj_noacc(fbuffer_f1, fbuffer_f2, fbuffer_f3, fbuffer_f4, fbuffer_f5, fbuffer_f6,
|
||
fbuffer_f7, fbuffer_f8, fbuffer_f9, fbuffer_f10, fbuffer_f11, fbuffer_f12);
|
||
folded_swave_integrated_fj_noacc(fbuffer_fs1, fbuffer_fs2, fbuffer_fs3, fbuffer_fs4, fbuffer_fs5, fbuffer_fs6);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::mkpi_pwave_2(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
double mkpi = meas.mkpi/1.0e+3;
|
||
double q2 = params->eff_q2();
|
||
//if (opts->weighted_fit) TODO
|
||
// q2 = meas.q2;
|
||
double gammakstar = params->gammakstar();
|
||
double mkstar = params->mkstar();
|
||
double R = params->R();
|
||
if (opts->simple_mkpi) return mkpi_simple_bw_kstar_amp_squared(mkpi, q2, gammakstar, mkstar);
|
||
else return mkpi_bw_kstar_amp_squared(mkpi, q2, gammakstar, mkstar, R);
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::mkpi_swave_2(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
double mkpi = meas.mkpi/1.0e+3;
|
||
double q2 = params->eff_q2();
|
||
//if (opts->weighted_fit) TODO
|
||
// q2 = meas.q2;
|
||
double asphase = params->asphase();
|
||
double a = params->a();
|
||
double r = params->r();
|
||
double R = params->R();
|
||
double gammakstarplus = params->gammakstarplus();
|
||
double mkstarplus = params->mkstarplus();
|
||
|
||
double gammaf800 = params->gammaf800();
|
||
double mf800 = params->mf800();
|
||
double f800mag = params->f800mag();
|
||
double f800phase = params->f800phase();
|
||
if (opts->simple_mkpi){
|
||
return mkpi_simple_kstarzero_amp_squared(mkpi, q2,
|
||
f800mag, f800phase, gammaf800, mf800,
|
||
gammakstarplus, mkstarplus);
|
||
}
|
||
else if (opts->isobar){
|
||
return mkpi_kstarzero_isobar_amp_squared(mkpi, q2,
|
||
f800mag, f800phase, gammaf800, mf800,
|
||
gammakstarplus, mkstarplus, R);
|
||
}
|
||
else{//LASS
|
||
return mkpi_kstarzero_lass_amp_squared(mkpi, q2, asphase, a, r, gammakstarplus, mkstarplus, R);
|
||
}
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::mkpi_re_swavepwave(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
double mkpi = meas.mkpi/1.0e+3;
|
||
double q2 = params->eff_q2();
|
||
// if (opts->weighted_fit) //TODO
|
||
// q2 = meas.q2;
|
||
double gammakstar = params->gammakstar();
|
||
double mkstar = params->mkstar();
|
||
double asphase = params->asphase();
|
||
double a = params->a();
|
||
double r = params->r();
|
||
double gammakstarplus = params->gammakstarplus();
|
||
double mkstarplus = params->mkstarplus();
|
||
double R = params->R();
|
||
|
||
double gammaf800 = params->gammaf800();
|
||
double mf800 = params->mf800();
|
||
double f800mag = params->f800mag();
|
||
double f800phase = params->f800phase();
|
||
|
||
std::complex<double> swavepwave;
|
||
if (opts->simple_mkpi){
|
||
swavepwave = mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(mkpi, q2,
|
||
gammakstar, mkstar, asphase,
|
||
f800mag, f800phase, gammaf800, mf800,
|
||
gammakstarplus, mkstarplus);
|
||
}
|
||
else if (opts->isobar){
|
||
swavepwave = mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(mkpi, q2,
|
||
gammakstar, mkstar, asphase,
|
||
f800mag, f800phase, gammaf800, mf800,
|
||
gammakstarplus, mkstarplus, R);
|
||
}
|
||
else{//LASS
|
||
swavepwave = mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(mkpi, q2, gammakstar, mkstar, asphase,
|
||
a, r, gammakstarplus, mkstarplus, R);
|
||
}
|
||
return swavepwave.real();
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::mkpi_im_swavepwave(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
double mkpi = meas.mkpi/1.0e+3;
|
||
double q2 = params->eff_q2();
|
||
//if (opts->weighted_fit) //TODO
|
||
// q2 = meas.q2;
|
||
double gammakstar = params->gammakstar();
|
||
double mkstar = params->mkstar();
|
||
double asphase = params->asphase();
|
||
double a = params->a();
|
||
double r = params->r();
|
||
double gammakstarplus = params->gammakstarplus();
|
||
double mkstarplus = params->mkstarplus();
|
||
double R = params->R();
|
||
|
||
double gammaf800 = params->gammaf800();
|
||
double mf800 = params->mf800();
|
||
double f800mag = params->f800mag();
|
||
double f800phase = params->f800phase();
|
||
|
||
std::complex<double> swavepwave;
|
||
if (opts->simple_mkpi){
|
||
swavepwave = mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(mkpi, q2,
|
||
gammakstar, mkstar, asphase,
|
||
f800mag, f800phase, gammaf800, mf800,
|
||
gammakstarplus, mkstarplus);
|
||
}
|
||
else if (opts->isobar){
|
||
swavepwave = mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(mkpi, q2,
|
||
gammakstar, mkstar, asphase,
|
||
f800mag, f800phase, gammaf800, mf800,
|
||
gammakstarplus, mkstarplus, R);
|
||
}
|
||
else{//LASS
|
||
swavepwave = mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(mkpi, q2, gammakstar, mkstar, asphase,
|
||
a, r, gammakstarplus, mkstarplus, R);
|
||
}
|
||
|
||
return swavepwave.imag();
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::mkpi_bkg(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
double mkpi = meas.mkpi/1.0e+3;
|
||
double mkpi_min = opts->mkpi_min/1.0e+3;
|
||
double mkpi_max = opts->mkpi_max/1.0e+3;
|
||
double probbkg = 0.0;
|
||
if (opts->use_p2) {
|
||
std::vector<double> ch_p2(5, 0.0);
|
||
ch_p2.at(0) = params->cbkgp20();
|
||
ch_p2.at(1) = params->cbkgp21();
|
||
ch_p2.at(2) = params->cbkgp22();
|
||
ch_p2.at(3) = params->cbkgp23();
|
||
ch_p2.at(4) = params->cbkgp24();
|
||
std::vector<double> poly_p2(ch_p2.size(), 0.0);
|
||
chebyshev_to_poly(ch_p2, poly_p2);
|
||
std::vector<double> poly_corr_p2(ch_p2.size(), 0.0);
|
||
correct_poly(poly_p2, poly_corr_p2, mkpi_min*mkpi_min, mkpi_max*mkpi_max);
|
||
|
||
for (unsigned int i=0; i<ch_p2.size(); i++)
|
||
probbkg += poly_corr_p2.at(i)*pow(mkpi*mkpi,i);
|
||
}
|
||
else
|
||
{
|
||
std::vector<double> ch_mkpi(5, 0.0);
|
||
ch_mkpi.at(0) = params->cbkgmkpi0();
|
||
ch_mkpi.at(1) = params->cbkgmkpi1();
|
||
ch_mkpi.at(2) = params->cbkgmkpi2();
|
||
ch_mkpi.at(3) = params->cbkgmkpi3();
|
||
ch_mkpi.at(4) = params->cbkgmkpi4();
|
||
std::vector<double> poly_mkpi(ch_mkpi.size(), 0.0);
|
||
chebyshev_to_poly(ch_mkpi, poly_mkpi);
|
||
std::vector<double> poly_corr_mkpi(ch_mkpi.size(), 0.0);
|
||
correct_poly(poly_mkpi, poly_corr_mkpi, mkpi_min, mkpi_max);
|
||
|
||
if (opts->mkpi_threshold){
|
||
//threshold(double x, double thr, double n);
|
||
probbkg = fcnc::threshold(mkpi, 0.633, params->nthreshold());
|
||
}
|
||
else{
|
||
for (unsigned int i=0; i<ch_mkpi.size(); i++) probbkg += poly_corr_mkpi.at(i)*pow(mkpi,i);
|
||
}
|
||
}
|
||
|
||
return probbkg;
|
||
}
|
||
|
||
|
||
void bu2kstarmumu_pdf::update_cached_xis(const bu2kstarmumu_parameters* params, std::vector<event>* events)
|
||
{
|
||
spdlog::info("Updating cached xis");
|
||
//this is used if per_event_norm is on
|
||
//it stores the 18 xis for every event
|
||
//otherwise using a different norm per event is computationally not possible
|
||
//double q2 = params->eff_q2();
|
||
assert(opts->use_event_norm);
|
||
/*
|
||
for (unsigned int e=0; e<events->size(); e++)
|
||
{
|
||
if ((e*100) % events->size() == 0)
|
||
std::cout << (e*100)/events->size() << "% " << std::endl;
|
||
event& meas = events->at(e);D
|
||
double q2 = meas.q2;
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0,
|
||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||
integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12, q2);
|
||
meas.xis[0] = f1;
|
||
meas.xis[1] = f2;
|
||
meas.xis[2] = f3;
|
||
meas.xis[3] = f4;
|
||
meas.xis[4] = f5;
|
||
meas.xis[5] = f6;
|
||
meas.xis[6] = f7;
|
||
meas.xis[7] = f8;
|
||
meas.xis[8] = f9;
|
||
meas.xis[9] = f10;
|
||
meas.xis[10] = f11;
|
||
meas.xis[11] = f12;
|
||
bool swave = opts->swave;
|
||
if (swave)
|
||
{
|
||
double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;
|
||
swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
meas.xis[12] = fs1;
|
||
meas.xis[13] = fs2;
|
||
meas.xis[14] = fs3;
|
||
meas.xis[15] = fs4;
|
||
meas.xis[16] = fs5;
|
||
meas.xis[17] = fs6;
|
||
}
|
||
}
|
||
*/
|
||
/*
|
||
for (unsigned int e=0; e<events->size(); e++)
|
||
{
|
||
event& meas = events->at(e);
|
||
std::cout << meas.xis[0] << " "
|
||
<< meas.xis[1] << " "
|
||
<< meas.xis[2] << " "
|
||
<< meas.xis[3] << " "
|
||
<< meas.xis[4] << " "
|
||
<< meas.xis[5] << " "
|
||
<< meas.xis[6] << " "
|
||
<< meas.xis[7] << " "
|
||
<< meas.xis[8] << " "
|
||
<< meas.xis[9] << " "
|
||
<< meas.xis[10] << " "
|
||
<< meas.xis[11] << " "
|
||
<< meas.xis[12] << " "
|
||
<< meas.xis[13] << " "
|
||
<< meas.xis[14] << " "
|
||
<< meas.xis[15] << " "
|
||
<< meas.xis[16] << " "
|
||
<< meas.xis[17] << " q2 " << meas.q2 << std::endl;
|
||
}
|
||
*/
|
||
//std::cout << std::endl;
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::update_cached_normalization(const parameters* params){
|
||
update_cached_normalization(static_cast<const bu2kstarmumu_parameters*>(params));
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::update_cached_integrated_fis(const parameters* params){
|
||
update_cached_integrated_fis(static_cast<const bu2kstarmumu_parameters*>(params));
|
||
}
|
||
|
||
|
||
void bu2kstarmumu_pdf::update_cached_efficiencies(const parameters* params, std::vector<event>* events)
|
||
{
|
||
update_cached_efficiencies(static_cast<const bu2kstarmumu_parameters*>(params), events);
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::update_cached_xis(const parameters* params, std::vector<event>* events)
|
||
{
|
||
update_cached_xis(static_cast<const bu2kstarmumu_parameters*>(params), events);
|
||
}
|
||
|
||
|
||
double bu2kstarmumu_pdf::m_sig_prob(const bu2kstarmumu_parameters* params, const event& meas) const{
|
||
if (opts->only_angles || opts->only_mkpi) return 1.0;
|
||
|
||
double mmin=params->m_b.get_min();
|
||
double mmax=params->m_b.get_max();
|
||
|
||
if(meas.m > mmax || meas.m < mmin){
|
||
spdlog::error("m(B) outside of allowed range: mmin={0:f}, mmax={1:f} m={2:f}", mmin, mmax, meas.m);
|
||
assert(0);
|
||
}
|
||
|
||
double result = 0.0;
|
||
if(opts->crystalball){
|
||
result = params->m_res_1()
|
||
* crystalball(meas.m, params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->n_1())
|
||
/ integrate_crystalball(params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->n_1(), mmin, mmax);
|
||
if(params->m_res_1() != 1.0)
|
||
result += (1.0-params->m_res_1())
|
||
* crystalball(meas.m, params->m_b(), params->m_scale()*params->m_sigma_2(), params->alpha_2(), params->n_2())
|
||
/ integrate_crystalball(params->m_b(), params->m_scale()*params->m_sigma_2(), params->alpha_2(), params->n_2(), mmin, mmax);
|
||
}
|
||
else if(opts->twotailedcrystalball){
|
||
result = twotailedcrystalball(meas.m, params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->alpha_2(), params->n_1(), params->n_2())
|
||
/ integrate_twotailedcrystalball(params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->alpha_2(), params->n_1(), params->n_2(), mmin, mmax);
|
||
}
|
||
else{
|
||
result = params->m_res_1()
|
||
* normed_gauss(meas.m, params->m_scale()*params->m_sigma_1(), params->m_b(), mmin, mmax);
|
||
if(params->m_res_1() != 1.0)
|
||
result += (1.0-params->m_res_1())
|
||
* normed_gauss(meas.m, params->m_scale()*params->m_sigma_2(), params->m_b(), mmin, mmax);
|
||
}
|
||
return result;
|
||
|
||
};
|
||
|
||
double bu2kstarmumu_pdf::mkpi_sig_prob(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
if(!opts->fit_mkpi || opts->only_angles || opts->only_Bmass) return 1.0;
|
||
|
||
assert(meas.mkpi <= opts->mkpi_max);
|
||
assert(meas.mkpi >= opts->mkpi_min);
|
||
|
||
double result = 0.0;
|
||
|
||
double prob_mkpi_pwave = mkpi_pwave_2(params, meas);
|
||
double prob_mkpi_swave = mkpi_swave_2(params, meas);
|
||
double prob_mkpi_pwaveswave_re = mkpi_re_swavepwave(params, meas);
|
||
double prob_mkpi_pwaveswave_im = mkpi_im_swavepwave(params, meas);
|
||
double fs = params->FS();
|
||
|
||
//only m(B) and m(K*+) fitted
|
||
if(opts->only_mass2DFit){
|
||
if(opts->swave){
|
||
result = (1.0-fs)
|
||
* prob_mkpi_pwave/mkpi_pwave_2_norm
|
||
+ fs
|
||
* prob_mkpi_swave/mkpi_swave_2_norm;
|
||
}
|
||
else{
|
||
result = prob_mkpi_pwave/mkpi_pwave_2_norm;
|
||
}
|
||
}//end only m(B) and m(K*+)
|
||
else{//angular dimensions included in the fit
|
||
|
||
double q2 = meas.q2;
|
||
|
||
//integrated S_i
|
||
double xi1, xi2, xi3, xi4, xi5, xi6, xi7, xi8, xi9, xi10, xi11, xi12;
|
||
if(opts->use_angular_acc) integrated_fj_chebyshev(xi1, xi2, xi3, xi4, xi5, xi6, xi7, xi8, xi9, xi10, xi11, xi12, q2);
|
||
else integrated_fj_noacc(xi1, xi2, xi3, xi4, xi5, xi6, xi7, xi8, xi9, xi10, xi11, xi12);
|
||
|
||
//integrated SS_i
|
||
double sxi1, sxi2, sxi3, sxi4, sxi5, sxi6;
|
||
if(opts->use_angular_acc) swave_integrated_fj_chebyshev(sxi1, sxi2, sxi3, sxi4, sxi5, sxi6, q2);
|
||
else swave_integrated_fj_noacc(sxi1, sxi2, sxi3, sxi4, sxi5, sxi6);
|
||
|
||
//load values for required parameters:
|
||
const double s1s = params->S1s();
|
||
const double s2s = s1s/3.0;
|
||
const double s1c = 1.0 - 4.0/3.0 * s1s;
|
||
const double s2c = -s1c;
|
||
const double s3 = params->S3();
|
||
const double s4 = params->S4();
|
||
const double s5 = params->S5();
|
||
const double s6s = params->S6s();
|
||
const double s6c = 0.;
|
||
const double s7 = params->S7();
|
||
const double s8 = params->S8();
|
||
const double s9 = params->S9();
|
||
|
||
const double ss1 = params->SS1();
|
||
const double ss2 = params->SS2();
|
||
const double ss3 = params->SS3();
|
||
const double ss4 = params->SS4();
|
||
const double ss5 = params->SS5();
|
||
|
||
double norm = (1 - fs) * (xi1*s1s + xi2*s1c + xi3*s2s + xi4*s2c + xi5*s3 + xi6*s4
|
||
+ xi7*s5 + xi8*s6s + xi9*s6c + xi10*s7 + xi11*s8 + xi12*s9)
|
||
+ (sxi1*fs)
|
||
+ (sxi2*ss1 + sxi3*ss2 + sxi4*ss3)
|
||
+ (sxi5*ss4 + sxi6*ss5);
|
||
|
||
double A = (xi1*s1s + xi2*s1c + xi3*s2s + xi4*s2c + xi5*s3 + xi6*s4
|
||
+ xi7*s5 + xi8*s6s + xi9*s6c + xi10*s7 + xi11*s8 + xi12*s9)/norm;
|
||
double B = sxi1/norm;
|
||
double C = (sxi2*ss1 + sxi3*ss2 + sxi4*ss3)/norm;
|
||
double D = (sxi5*ss4 + sxi6*ss5)/norm;
|
||
|
||
result = (1.0-fs) * A * prob_mkpi_pwave/mkpi_pwave_2_norm
|
||
+ fs * B * prob_mkpi_swave/mkpi_swave_2_norm
|
||
+ C * prob_mkpi_pwaveswave_re/mkpi_re_swavepwave_norm
|
||
+ D * prob_mkpi_pwaveswave_im/mkpi_im_swavepwave_norm;
|
||
}//end of prob with angular parts included
|
||
return result;
|
||
};
|
||
|
||
double bu2kstarmumu_pdf::integral_m_sig_prob(const bu2kstarmumu_parameters* params, double ma, double mb) const
|
||
{
|
||
|
||
double result = 0.0;
|
||
if (opts->crystalball){
|
||
double mmin=params->m_b.get_min(), mmax=params->m_b.get_max();
|
||
result = params->m_res_1()*integrate_crystalball(params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->n_1(), ma, mb)
|
||
/ integrate_crystalball(params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->n_1(), mmin, mmax);
|
||
if (params->m_res_1() != 1.0)
|
||
result += (1.0-params->m_res_1()) * integrate_crystalball(params->m_b(), params->m_scale()*params->m_sigma_2(), params->alpha_2(), params->n_2(), ma, mb)
|
||
/ integrate_crystalball(params->m_b(), params->m_scale()*params->m_sigma_2(), params->alpha_2(), params->n_2(), mmin, mmax);
|
||
}
|
||
else if(opts->twotailedcrystalball){
|
||
double mmin=params->m_b.get_min(), mmax=params->m_b.get_max();
|
||
result = integrate_twotailedcrystalball(params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->alpha_2(), params->n_1(), params->n_2(), ma, mb)
|
||
/ integrate_twotailedcrystalball(params->m_b(), params->m_scale()*params->m_sigma_1(), params->alpha_1(), params->alpha_2(), params->n_1(), params->n_2(), mmin, mmax);
|
||
}
|
||
else{
|
||
double mean = params->m_b();
|
||
double min = params->m_b.get_min();
|
||
double max = params->m_b.get_max();
|
||
double sigma1 = params->m_scale()*params->m_sigma_1();
|
||
double sigma2 = params->m_scale()*params->m_sigma_2();
|
||
double fres = params->m_res_1();
|
||
double fullrange = (fres)*1.0/2.0*(TMath::Erf((max-mean)/(sqrt(2.0)*sigma1))-TMath::Erf((min-mean)/(sqrt(2.0)*sigma1)));
|
||
if (params->m_res_1() != 1.0)
|
||
fullrange += (1.0-fres)*1.0/2.0*(TMath::Erf((max-mean)/(sqrt(2.0)*sigma2))-TMath::Erf((min-mean)/(sqrt(2.0)*sigma2)));
|
||
double integral = (fres)*1.0/2.0*(TMath::Erf((mb-mean)/(sqrt(2.0)*sigma1))-TMath::Erf((ma-mean)/(sqrt(2.0)*sigma1)));
|
||
if (params->m_res_1() != 1.0)
|
||
integral += (1.0-fres)*1.0/2.0*(TMath::Erf((mb-mean)/(sqrt(2.0)*sigma2))-TMath::Erf((ma-mean)/(sqrt(2.0)*sigma2)));
|
||
result = integral/fullrange;
|
||
}
|
||
return result;
|
||
|
||
};
|
||
|
||
|
||
double bu2kstarmumu_pdf::m_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
if (opts->only_angles || opts->only_mkpi) return 1.0;
|
||
|
||
double mmin=params->m_b.get_min(), mmax=params->m_b.get_max();
|
||
assert(meas.m <= mmax);
|
||
assert(meas.m >= mmin);
|
||
|
||
if(opts->cutsignalwindow){
|
||
assert(meas.m <= opts->m_min || meas.m >= opts->m_max);
|
||
}
|
||
|
||
double fm1 = params->fm_tau();
|
||
double tau1 = params->m_tau();
|
||
double tau2 = params->m_tau_2();
|
||
double lambda1 = params->m_lambda();
|
||
double lambda2 = params->m_lambda_2();
|
||
|
||
double result = 0.;
|
||
|
||
if(opts->fit_lambda){
|
||
if(lambda1 == 0.0) return 1.0;
|
||
double norm1 = 1.0/lambda1*(exp(mmax*lambda1) - exp(mmin*lambda1));
|
||
if(opts->cutsignalwindow){
|
||
norm1 -= 1.0/lambda1*(exp(opts->m_max*lambda1) - exp(opts->m_min*lambda1));
|
||
}
|
||
result = exp(meas.m*lambda1)/norm1;
|
||
if (fm1 != 1.0){
|
||
if(lambda2 == 0.0) return result;
|
||
result *= fm1;
|
||
double norm2 = 1.0/lambda2*(exp(mmax*lambda2) - exp(mmin*lambda2));
|
||
if(opts->cutsignalwindow)
|
||
norm2 -= 1.0/lambda2*(exp(opts->m_max*lambda2) - exp(opts->m_min*lambda2));
|
||
result += (1.0-fm1)*exp(meas.m*lambda2)/norm2;
|
||
}
|
||
}
|
||
else{
|
||
double norm1 = tau1*(exp(-mmin/tau1) - exp(-mmax/tau1));
|
||
if(opts->cutsignalwindow)
|
||
norm1 -= tau1*(exp(-opts->m_min/tau1) - exp(-opts->m_max/tau1));
|
||
result = exp(-meas.m/tau1)/norm1;
|
||
if (fm1 != 1.0){
|
||
result *= fm1;
|
||
double norm2 = tau2*(exp(-mmin/tau2) - exp(-mmax/tau2));
|
||
if(opts->cutsignalwindow)
|
||
norm2 -= tau2*(exp(-opts->m_min/tau2) - exp(-opts->m_max/tau2));
|
||
result += (1.0-fm1)*exp(-meas.m/tau2)/norm2;
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
double bu2kstarmumu_pdf::mkpi_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
if(!(opts->fit_mkpi || opts->use_mkpi) || opts->only_angles || opts->only_Bmass)
|
||
return 1.0;
|
||
|
||
assert(meas.mkpi <= opts->mkpi_max);
|
||
assert(meas.mkpi >= opts->mkpi_min);
|
||
|
||
double result = 0.0;
|
||
|
||
double mkpi_min = opts->mkpi_min/1.0e+3;
|
||
double mkpi_max = opts->mkpi_max/1.0e+3;
|
||
double mkpi = meas.mkpi/1.0e+3;
|
||
|
||
double normbkg=0.0;
|
||
std::vector<double> ch_mkpi(5, 0.0);
|
||
ch_mkpi.at(0) = params->cbkgmkpi0();
|
||
ch_mkpi.at(1) = params->cbkgmkpi1();
|
||
ch_mkpi.at(2) = params->cbkgmkpi2();
|
||
ch_mkpi.at(3) = params->cbkgmkpi3();
|
||
ch_mkpi.at(4) = params->cbkgmkpi4();
|
||
std::vector<double> poly_mkpi(ch_mkpi.size(), 0.0);
|
||
chebyshev_to_poly(ch_mkpi, poly_mkpi);
|
||
std::vector<double> poly_corr_mkpi(ch_mkpi.size(), 0.0);
|
||
correct_poly(poly_mkpi, poly_corr_mkpi, mkpi_min, mkpi_max);
|
||
for(unsigned int i=0; i<poly_mkpi.size(); i++)
|
||
normbkg += poly_corr_mkpi.at(i)*(pow(mkpi_max,i+1)-pow(mkpi_min,i+1))/(i+1.0);
|
||
|
||
double probbkg = 0.0;
|
||
for (unsigned int i=0; i<ch_mkpi.size(); i++)
|
||
probbkg += poly_corr_mkpi.at(i)*pow(mkpi,i);
|
||
|
||
result = probbkg/normbkg;
|
||
|
||
return result;
|
||
};
|
||
|
||
double bu2kstarmumu_pdf::integral_m_bkg_prob(const bu2kstarmumu_parameters* params, double ma, double mb) const
|
||
{
|
||
double mmin=params->m_b.get_min(), mmax=params->m_b.get_max();
|
||
|
||
double bkg_frac = params->fm_tau();
|
||
double tau1 = params->m_tau();
|
||
double tau2 = params->m_tau_2();
|
||
double lambda1 = params->m_lambda();
|
||
double lambda2 = params->m_lambda_2();
|
||
|
||
double result = 0.0;
|
||
|
||
if(opts->fit_lambda){
|
||
assert(lambda1 <= 0.);
|
||
double fullrange1 = 1.0/lambda1*(exp(mmax*lambda1) - exp(mmin*lambda1));
|
||
if(opts->cutsignalwindow){
|
||
fullrange1 -= 1.0/lambda1*(exp(opts->m_max*lambda1) - exp(opts->m_min*lambda1));
|
||
}
|
||
double integral1 = 1.0/lambda1*(exp(mb*lambda1) - exp(ma*lambda1));
|
||
result = integral1/fullrange1;
|
||
if (bkg_frac != 1.0){
|
||
assert(lambda2 <= 0.);
|
||
result *= bkg_frac;
|
||
double fullrange2 = 1.0/lambda2*(exp(mmax*lambda2) - exp(mmin*lambda2));
|
||
if(opts->cutsignalwindow){
|
||
fullrange2 -= 1.0/lambda2*(exp(opts->m_max*lambda2) - exp(opts->m_min*lambda2));
|
||
}
|
||
double integral2 = 1.0/lambda2*(exp(mb*lambda2) - exp(ma*lambda2));
|
||
result += (1.0-bkg_frac)*integral2/fullrange2;
|
||
}
|
||
}
|
||
else{
|
||
double fullrange1 = tau1*(exp(-mmin/tau1) - exp(-mmax/tau1));
|
||
if(opts->cutsignalwindow){
|
||
fullrange1 -= tau1*(exp(opts->m_max/tau1) - exp(opts->m_min/tau1));
|
||
}
|
||
double integral1 = tau1*(exp(-ma/tau1) - exp(-mb/tau1));
|
||
result = integral1/fullrange1;
|
||
if (bkg_frac != 1.0){
|
||
result *= bkg_frac;
|
||
double fullrange2 = tau2*(exp(-mmin/tau2) - exp(-mmax/tau2));
|
||
if(opts->cutsignalwindow){
|
||
fullrange2 -= tau2*(exp(opts->m_max/tau2) - exp(opts->m_min/tau2));
|
||
}
|
||
double integral2 = tau2*(exp(-ma/tau2) - exp(-mb/tau2));
|
||
result += (1.0-bkg_frac)*integral2/fullrange2;
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
double bu2kstarmumu_pdf::angular_sig_prob(const bu2kstarmumu_parameters* params, const event& meas) const
|
||
{
|
||
//Don't when only fitting the mass
|
||
if (opts->only_Bmass || opts->only_mass2DFit || opts->only_mkpi) return 1.0;
|
||
|
||
double ctl = meas.costhetal;
|
||
double ctk = meas.costhetak;
|
||
double phi = meas.phi;
|
||
|
||
double result_swave = 0.0, result_pwave = 0.0;
|
||
double result = 0.0;
|
||
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0,
|
||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||
const double j1s = params->J1s();
|
||
const double j1c = params->J1c();
|
||
const double j2s = params->J2s();
|
||
const double j2c = params->J2c();
|
||
const double j3 = params->J3();
|
||
const double j4 = params->J4();
|
||
const double j5 = params->J5();
|
||
const double j6s = params->J6s();
|
||
const double j6c = params->J6c();
|
||
const double j7 = params->J7();
|
||
const double j8 = params->J8();
|
||
const double j9 = params->J9();
|
||
|
||
if (opts->full_angular) fj(ctl, ctk, phi, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
else folded_fj(ctl, ctk, phi, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
|
||
if (opts->fit_asymmetries && meas.cp_conjugate){
|
||
result_pwave += (f1*j1s + f2*j1c + f3*j2s + f4*j2c - f5*j3 - f6*j4
|
||
- f7*j5 - f8*j6s - f9*j6c - f10*j7 - f11*j8 - f12*j9);
|
||
}
|
||
else{
|
||
result_pwave += (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9);
|
||
}
|
||
|
||
if (opts->swave){
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0;
|
||
if(opts->full_angular) swave_fj(ctl, ctk, phi, f1, f2, f3, f4, f5, f6);
|
||
else folded_swave_fj(ctl, ctk, phi, f1, f2, f3, f4, f5, f6);
|
||
const double fs = params->FS();
|
||
const double js1 = params->SS1();
|
||
const double js2 = params->SS2();
|
||
const double js3 = params->SS3();
|
||
const double js4 = params->SS4();
|
||
const double js5 = params->SS5();
|
||
result_pwave *= (1.0 - fs);
|
||
result_swave += (fs*f1 + js1*f2 + js2*f3 + js3*f4 + js4*f5 + js5*f6);
|
||
if (opts->use_mkpi){
|
||
double prob_mkpi_pwave = mkpi_pwave_2(params, meas);
|
||
double prob_mkpi_swave = mkpi_swave_2(params, meas);
|
||
double prob_mkpi_re_swavepwave = mkpi_re_swavepwave(params, meas);
|
||
double prob_mkpi_im_swavepwave = mkpi_im_swavepwave(params, meas);
|
||
|
||
result_pwave *= prob_mkpi_pwave/mkpi_pwave_2_norm;
|
||
if (std::isnan(result_pwave)) spdlog::warn("prob_mkpi_pwave {0:f}",prob_mkpi_pwave );
|
||
|
||
result_swave = (fs*f1*prob_mkpi_swave/mkpi_swave_2_norm
|
||
+ (js1*f2 + js2*f3 + js3*f4)*prob_mkpi_re_swavepwave/mkpi_re_swavepwave_norm
|
||
+ (js4*f5 + js5*f6)*prob_mkpi_im_swavepwave/mkpi_im_swavepwave_norm);
|
||
}
|
||
if (std::isnan(result_swave) || std::isinf(result_swave)){
|
||
spdlog::warn("\tresult_swave {0:0.6f}",result_swave);
|
||
spdlog::warn("\t mkpi_swave_2_norm {0:0.6f}",mkpi_swave_2_norm);
|
||
spdlog::warn("\t mkpi_pwave_2_norm {0:0.6f}",mkpi_pwave_2_norm);
|
||
spdlog::warn("\t prob_mkpi_swave {0:0.6f}",mkpi_swave_2(params, meas));
|
||
spdlog::warn("\t prob_mkpi_re_swavepwave {0:0.6f}",mkpi_re_swavepwave(params, meas));
|
||
spdlog::warn("\t prob_mkpi_im_swavepwave {0:0.6f}",mkpi_im_swavepwave(params, meas));
|
||
result_swave = 1.0e-12;
|
||
}
|
||
}
|
||
|
||
result = result_pwave + result_swave;
|
||
|
||
if(std::isnan(result) || std::isinf(result)){
|
||
spdlog::error("result={0:0f}",result );
|
||
spdlog::error("pwave={0:0f}",result_pwave );
|
||
spdlog::error("swave={0:0f}",result_swave );
|
||
assert(0);
|
||
}
|
||
|
||
//spdlog::trace("result={0:0f}",result );
|
||
//spdlog::trace("pwave={0:0f}",result_pwave );
|
||
//spdlog::trace("swave={0:0f}",result_swave );
|
||
|
||
|
||
double eff = 1.0;
|
||
if (opts->use_angular_acc){
|
||
//for fixed effq2 the efficiency should have been calculated beforehand
|
||
//for floating q2 should recalculate as done below
|
||
//for event_norm, the efficiency should also have been calculated before
|
||
bool q2fixed = (params->eff_q2.get_step_size() == 0.0);
|
||
if ((q2fixed || opts->use_event_norm) && (!opts->mcweight)) { //use event norm is only used when convoluting the acceptance into the pdf
|
||
if (meas.weight > 0.0) eff = 1.0/meas.weight;
|
||
spdlog::trace("eff={0:f}",eff);
|
||
}
|
||
else{
|
||
double q2 = params->eff_q2();
|
||
eff = this->get_ang_eff(opts,q2,meas.costhetal_fa, meas.costhetal_fa,meas.phi_fa);
|
||
spdlog::trace("eff={0:f}",eff);
|
||
spdlog::trace("q2={0:f}",q2);
|
||
}
|
||
}
|
||
if(std::isnan(eff) || std::isinf(eff)){
|
||
spdlog::error("eff={0:f}",eff );
|
||
assert(0);
|
||
}
|
||
|
||
if(eff/fnorm_sig < 0.0){
|
||
spdlog::info("negative acc corr and/or normalizing");
|
||
spdlog::info("eff={0:f}",eff );
|
||
spdlog::info("norm={0:f}",fnorm_sig );
|
||
assert(eff > 0.0);
|
||
assert(fnorm_sig > 0.0);
|
||
}
|
||
//spdlog::trace("eff={0:f},\t fnorm_sig={1:f}",eff, fnorm_sig);
|
||
|
||
result *= eff/fnorm_sig;
|
||
|
||
return result;
|
||
};
|
||
|
||
double bu2kstarmumu_pdf::angular_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const{
|
||
|
||
//Don't when only fitting the mass
|
||
if (opts->only_Bmass || opts->only_mass2DFit || opts->only_mkpi) return 1.0;
|
||
|
||
//calculate bkg prob for all 2(4) possible inversed folding angles:
|
||
if(opts->fit_full_angular_bkg && !opts->flat_bkg && !opts->full_angular){
|
||
fcnc::event e[3];
|
||
|
||
fldr->invers_fold(&meas, &e[0], &e[1], &e[2]);
|
||
|
||
double p1, p2, p3, p4;
|
||
|
||
p1 = simple_angular_bkg_prob(params, meas);
|
||
p4 = simple_angular_bkg_prob(params, e[2]);
|
||
|
||
if(opts->folding > 0){
|
||
p2 = simple_angular_bkg_prob(params, e[0]);
|
||
p3 = simple_angular_bkg_prob(params, e[1]);
|
||
return p1+p2+p3+p4;
|
||
}
|
||
else{
|
||
return p1+p4;
|
||
}
|
||
}
|
||
else{
|
||
return simple_angular_bkg_prob(params, meas);
|
||
}
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::simple_angular_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const{
|
||
|
||
if (opts->only_Bmass) return 1.0;
|
||
if (opts->only_mass2DFit) return 1.0; //Don't when fitting only mass
|
||
|
||
double result = 1.0;
|
||
|
||
double costhetal = meas.costhetal;
|
||
double costhetak = meas.costhetak;
|
||
double phi = meas.phi;
|
||
|
||
npolynom npol(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
|
||
//determine weight/efficiency for this event
|
||
double eff = 1.0;
|
||
if(opts->use_angular_acc && opts->use_weighted_bkg){
|
||
//for fixed effq2 the efficiency should have been calculated beforehand
|
||
//for floating q2 should recalculate as done below
|
||
//for event_norm, the efficiency should also have been calculated before
|
||
bool q2fixed = (params->eff_q2.get_step_size() == 0.0);
|
||
if ((q2fixed || opts->use_event_norm) && (!opts->mcweight)){//use event norm is only used when convoluting the acceptance into the pdf
|
||
if (meas.weight > 0.0) eff = 1.0/meas.weight;
|
||
}
|
||
else eff = this->get_ang_eff(opts,meas,true);
|
||
}
|
||
|
||
if (opts->flat_bkg){ //for a flat background, only - if at all - the angular acceptance correction is needed
|
||
result *= eff/fnorm_bkg;
|
||
}
|
||
else{ //Chebyshev background
|
||
|
||
//read angular bkg coefficients from parameter object
|
||
std::vector<double> ch_ctl = init_ch_ctl(params);
|
||
std::vector<double> ch_ctk = init_ch_ctk(params);
|
||
std::vector<double> ch_phi = init_ch_phi(params);
|
||
|
||
//reserve vectors for the (non-)Chebyshev polynomial coefficients
|
||
std::vector<double> poly_ctl(ch_ctl.size(), 0.0);
|
||
std::vector<double> poly_ctk(ch_ctk.size(), 0.0);
|
||
std::vector<double> poly_phi(ch_phi.size(), 0.0);
|
||
|
||
//these temporary coefficients are defined in the range from -1 to +1
|
||
std::vector<double> temp_ctl(ch_ctl.size(), 0.0);
|
||
std::vector<double> temp_ctk(ch_ctk.size(), 0.0);
|
||
std::vector<double> temp_phi(ch_phi.size(), 0.0);
|
||
|
||
//transform chebyshev polynomial coefficients to Standard Form polynomials
|
||
chebyshev_to_poly(ch_ctl, temp_ctl);
|
||
chebyshev_to_poly(ch_ctk, temp_ctk);
|
||
chebyshev_to_poly(ch_phi, temp_phi);
|
||
|
||
//stretch or squeeze the definition of the polynomials in phi
|
||
//for (unsigned int i=0; i<poly_ctk.size(); i++) poly_ctk.at(i) = temp_ctk.at(i);
|
||
for (unsigned int i=0; i<poly_ctk.size(); i++) poly_ctk.at(i) = temp_ctk.at(i);
|
||
for (unsigned int i=0; i<poly_ctl.size(); i++) poly_ctl.at(i) = temp_ctl.at(i);
|
||
correct_poly(temp_phi, poly_phi, -TMath::Pi(), +TMath::Pi());
|
||
|
||
|
||
//add up all power terms of the polynomials
|
||
double p_costhetal = 0.0;
|
||
for (unsigned int i=0; i<ch_ctl.size(); i++) p_costhetal += poly_ctl.at(i)*pow(costhetal,i);
|
||
double p_costhetak = 0.0;
|
||
for (unsigned int i=0; i<ch_ctk.size(); i++) p_costhetak += poly_ctk.at(i)*pow(costhetak,i);
|
||
double p_phi = 0.0;
|
||
for (unsigned int i=0; i<ch_phi.size(); i++) p_phi += poly_phi.at(i)*pow(phi,i);
|
||
|
||
//multiply the indidivual angular dimensions. divide by the normalisation to obtain the angular background probability
|
||
result = p_costhetal*p_costhetak*p_phi*eff/fnorm_bkg;
|
||
}
|
||
return result;
|
||
};
|
||
|
||
double bu2kstarmumu_pdf::integral_bkg(const bu2kstarmumu_parameters* params, double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b) const
|
||
{
|
||
if (opts->flat_bkg){
|
||
return (ctl_b-ctl_a)*(ctk_b-ctk_a)*(phi_b-phi_a); // RANGE_3D() for non-folded
|
||
}
|
||
else{
|
||
|
||
std::vector<double> ch_ctl = init_ch_ctl(params);
|
||
std::vector<double> ch_ctk = init_ch_ctk(params);
|
||
std::vector<double> ch_phi = init_ch_phi(params);
|
||
|
||
std::vector<double> poly_ctl(ch_ctl.size(), 0.0);
|
||
std::vector<double> poly_ctk(ch_ctk.size(), 0.0);
|
||
std::vector<double> poly_phi(ch_phi.size(), 0.0);
|
||
|
||
std::vector<double> temp_ctl(ch_ctl.size(), 0.0);
|
||
std::vector<double> temp_ctk(ch_ctk.size(), 0.0);
|
||
std::vector<double> temp_phi(ch_phi.size(), 0.0);
|
||
|
||
chebyshev_to_poly(ch_ctl, temp_ctl);
|
||
chebyshev_to_poly(ch_ctk, temp_ctk);
|
||
chebyshev_to_poly(ch_phi, temp_phi);
|
||
|
||
for (unsigned int i=0; i<poly_ctk.size(); i++) poly_ctk.at(i) = temp_ctk.at(i);
|
||
for (unsigned int i=0; i<poly_ctl.size(); i++)poly_ctl.at(i) = temp_ctl.at(i);
|
||
correct_poly(temp_phi, poly_phi, -TMath::Pi(), +TMath::Pi());
|
||
|
||
|
||
double norm_costhetal = 0.0;
|
||
for (unsigned int i=0; i<poly_ctl.size(); i++)norm_costhetal += poly_ctl.at(i)*(pow(ctl_b,i+1)-pow(ctl_a,i+1))/(i+1.0);
|
||
double norm_costhetak = 0.0;
|
||
for (unsigned int i=0; i<poly_ctk.size(); i++)norm_costhetak += poly_ctk.at(i)*(pow(ctk_b,i+1)-pow(ctk_a,i+1))/(i+1.0);
|
||
double norm_phi = 0.0;
|
||
for (unsigned int i=0; i<poly_phi.size(); i++)norm_phi += poly_phi.at(i)*(pow(phi_b,i+1)-pow(phi_a,i+1))/(i+1.0);
|
||
|
||
return norm_costhetal*norm_costhetak*norm_phi;
|
||
}
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::integral_bkg_chebyshev(const bu2kstarmumu_parameters* params, double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, double q2) const{
|
||
|
||
double result = 0.0;
|
||
|
||
if (opts->flat_bkg){
|
||
|
||
double c = 1.0;
|
||
|
||
//new improved non-factorizing acceptance
|
||
|
||
npolynom npol = npolynom(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
double chijk = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
const unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
chijk = c*pow(q2, h)*coeffs_eff_4d.at(bin);
|
||
result += chijk
|
||
* (pow(ctl_b, i+1)/(i+1.0) - pow(ctl_a, i+1)/(i+1.0))
|
||
* (pow(ctk_b, j+1)/(j+1.0) - pow(ctk_a, j+1)/(j+1.0))
|
||
* (pow(phi_b, k+1)/(k+1.0) - pow(phi_a, k+1)/(k+1.0));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else{
|
||
//calculate integral of background with efficiency correction
|
||
|
||
std::vector<double> ch_ctl = init_ch_ctl(params);
|
||
std::vector<double> ch_ctk = init_ch_ctk(params);
|
||
std::vector<double> ch_phi = init_ch_phi(params);
|
||
|
||
std::vector<double> poly_ctl(ch_ctl.size(), 0.0);
|
||
std::vector<double> poly_ctk(ch_ctk.size(), 0.0);
|
||
std::vector<double> poly_phi(ch_phi.size(), 0.0);
|
||
|
||
std::vector<double> temp_ctl(ch_ctl.size(), 0.0);
|
||
std::vector<double> temp_ctk(ch_ctk.size(), 0.0);
|
||
std::vector<double> temp_phi(ch_phi.size(), 0.0);
|
||
|
||
chebyshev_to_poly(ch_ctl, temp_ctl);
|
||
chebyshev_to_poly(ch_ctk, temp_ctk);
|
||
chebyshev_to_poly(ch_phi, temp_phi);
|
||
|
||
for (unsigned int i=0; i<poly_ctk.size(); i++) poly_ctk.at(i) = temp_ctk.at(i);
|
||
for (unsigned int i=0; i<poly_ctl.size(); i++) poly_ctl.at(i) = temp_ctl.at(i);
|
||
correct_poly(temp_phi, poly_phi, -TMath::Pi(), +TMath::Pi());
|
||
|
||
double c = 1.0;
|
||
|
||
//new improved non-factorizing acceptance
|
||
//double q2 = params->eff_q2();
|
||
npolynom npol(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
double chijk = 0.0;
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
const unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
chijk = c*pow(q2, h)*coeffs_eff_4d.at(bin);
|
||
for (unsigned int l=0; l<poly_ctl.size(); l++){
|
||
for (unsigned int m=0; m<poly_ctk.size(); m++){
|
||
for (unsigned int n=0; n<poly_phi.size(); n++){
|
||
result += chijk * poly_ctl.at(l) * poly_ctk.at(m) * poly_phi.at(n)
|
||
* (pow(ctl_b, i+l+1) - pow(ctl_a, i+l+1)) / (i+l+1.0)
|
||
* (pow(ctk_b, j+m+1) - pow(ctk_a, j+m+1)) / (j+m+1.0)
|
||
* (pow(phi_b, k+n+1) - pow(phi_a, k+n+1)) / (k+n+1.0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::angular_bkg_norm(const bu2kstarmumu_parameters* params, bool weighted){
|
||
npolynom npol(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
|
||
//bkg norm
|
||
if(weighted){ //weighted background pdf
|
||
double q2 = params->eff_q2();
|
||
if (opts->full_angular){
|
||
if (opts->flat_bkg){
|
||
double integral = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
integral += pow(q2, h)*coeffs_eff_4d.at(npol.get_bin_in4D(h,i,j,k))
|
||
* integrate_x_to_n(CTL_MIN,CTL_MAX,i)
|
||
* integrate_x_to_n(CTK_MIN,CTK_MAX,j)
|
||
* integrate_x_to_n(PHI_MIN,PHI_MAX,k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return integral;
|
||
}
|
||
else{
|
||
return integral_bkg_chebyshev(params, CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX, q2);
|
||
}
|
||
}
|
||
else{ //folded angles
|
||
if (opts->flat_bkg){
|
||
double integral = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
integral += pow(q2, h)*coeffs_eff_4d.at(npol.get_bin_in4D(h,i,j,k))
|
||
* integrate_x_to_n(opts->ctl_min,opts->ctl_max,i)
|
||
* integrate_x_to_n(opts->ctk_min,opts->ctk_max,j)
|
||
* integrate_x_to_n(opts->phi_min,opts->phi_max,k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return integral;
|
||
}
|
||
else{
|
||
if(opts->fit_full_angular_bkg){
|
||
return integral_bkg_chebyshev(params, CTL_MIN, CTL_MAX, opts->ctk_min, opts->ctk_max, PHI_MIN, PHI_MAX, q2); //TODO: check if that makes sense (https://gitlab.cern.ch/LHCb-RD/ewp-Bplus2Kstmumu-AngAna/-/merge_requests/21)
|
||
}
|
||
else{
|
||
return integral_bkg_chebyshev(params, opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max, q2);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else{ //non weighted background pdf
|
||
if (opts->full_angular){
|
||
if (opts->flat_bkg) return RANGE_3D();
|
||
else return integral_bkg(params, CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX);
|
||
}
|
||
else{ //folded angles
|
||
if (opts->flat_bkg){
|
||
return (opts->ctk_max - opts->ctk_min) * (opts->ctl_max - opts->ctl_min) * (opts->phi_max - opts->phi_min);
|
||
}
|
||
else{
|
||
if(opts->fit_full_angular_bkg){
|
||
return integral_bkg(params, CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX);
|
||
}
|
||
else{
|
||
return integral_bkg(params, opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::angular_sig_norm(const bu2kstarmumu_parameters* params, bool weighted){
|
||
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0,
|
||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||
|
||
double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;
|
||
|
||
const double j1s = params->J1s();
|
||
const double j1c = params->J1c();
|
||
const double j2s = params->J2s();
|
||
const double j2c = params->J2c();
|
||
const double j3 = params->J3();
|
||
const double j4 = params->J4();
|
||
const double j5 = params->J5();
|
||
const double j6s = params->J6s();
|
||
const double j6c = params->J6c();
|
||
const double j7 = params->J7();
|
||
const double j8 = params->J8();
|
||
const double j9 = params->J9();
|
||
|
||
const double fs = params->FS();
|
||
const double js1 = params->SS1();
|
||
const double js2 = params->SS2();
|
||
const double js3 = params->SS3();
|
||
const double js4 = params->SS4();
|
||
const double js5 = params->SS5();
|
||
|
||
//sig norm
|
||
double q2 = params->eff_q2();
|
||
if (opts->full_angular){
|
||
//get signal pdf
|
||
if (weighted) integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, q2);
|
||
else integrated_fj_noacc(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
|
||
//swave
|
||
if(opts->swave){
|
||
if (weighted) swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
else swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
|
||
//if asymmetries are fitted:
|
||
if(opts->fit_asymmetries){
|
||
if(opts->swave) return (1.0-fs) * (f1*j1s + f2*j1c + f3*j2s + f4*j2c) + (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
else return f1*j1s + f2*j1c + f3*j2s + f4*j2c;
|
||
}
|
||
|
||
if (opts->swave){
|
||
return (1.0-fs) * (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4 + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
|
||
+ (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
}
|
||
|
||
//signal pdf without swave, without asymmetries and without m(Kpi)
|
||
return f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4 + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9;
|
||
}
|
||
else{ //folded angles
|
||
if (weighted) folded_integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, q2);
|
||
else folded_integrated_fj_noacc(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
|
||
if(opts->swave){
|
||
if (weighted) folded_swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
else folded_swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
|
||
if(opts->fit_asymmetries){
|
||
if(opts->swave) return (1-fs) * (f1*j1s + f2*j1c + f3*j2s + f4*j2c) + (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
else return (f1*j1s + f2*j1c + f3*j2s + f4*j2c);
|
||
}
|
||
|
||
if(opts->swave){
|
||
return (1-fs) * (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4 + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
|
||
+ (fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5);
|
||
}
|
||
|
||
//signal pdf without swave, without asymmetries and without m(Kpi)
|
||
return f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4 + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9;
|
||
}
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::angular_swave_norm(const bu2kstarmumu_parameters* params, bool weighted){
|
||
|
||
double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;
|
||
const double fs = params->FS();
|
||
|
||
//sig norm
|
||
double q2 = params->eff_q2();
|
||
if (opts->full_angular){
|
||
if (weighted) swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
else swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
else{ //folded angles
|
||
if (weighted) folded_swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
else folded_swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
return fs1*fs;
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::angular_pwave_norm(const bu2kstarmumu_parameters* params, bool weighted){
|
||
|
||
double f1=0.0, f2=0.0, f3=0.0, f4=0.0, f5=0.0, f6=0.0,
|
||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||
|
||
const double j1s = params->J1s();
|
||
const double j1c = params->J1c();
|
||
const double j2s = params->J2s();
|
||
const double j2c = params->J2c();
|
||
const double j3 = params->J3();
|
||
const double j4 = params->J4();
|
||
const double j5 = params->J5();
|
||
const double j6s = params->J6s();
|
||
const double j6c = params->J6c();
|
||
const double j7 = params->J7();
|
||
const double j8 = params->J8();
|
||
const double j9 = params->J9();
|
||
|
||
//sig norm
|
||
double q2 = params->eff_q2();
|
||
if (opts->full_angular){
|
||
if (weighted) integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, q2);
|
||
else integrated_fj_noacc(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
}
|
||
else{ //folded angles
|
||
if (weighted) folded_integrated_fj_chebyshev(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, q2);
|
||
else folded_integrated_fj_noacc(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
}
|
||
//if asymmetries are fitted:
|
||
if(opts->fit_asymmetries)return f1*j1s + f2*j1c + f3*j2s + f4*j2c;
|
||
else return f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4 + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9;
|
||
}
|
||
|
||
double bu2kstarmumu_pdf::angular_pswave_norm(const bu2kstarmumu_parameters* params, bool weighted){
|
||
|
||
double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;
|
||
|
||
const double js1 = params->SS1();
|
||
const double js2 = params->SS2();
|
||
const double js3 = params->SS3();
|
||
const double js4 = params->SS4();
|
||
const double js5 = params->SS5();
|
||
|
||
//sig norm
|
||
double q2 = params->eff_q2();
|
||
if (opts->full_angular){
|
||
if (weighted) swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
else swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
else{ //folded angles
|
||
if (weighted) folded_swave_integrated_fj_chebyshev(fs1, fs2, fs3, fs4, fs5, fs6, q2);
|
||
else folded_swave_integrated_fj_noacc(fs1, fs2, fs3, fs4, fs5, fs6);
|
||
}
|
||
return fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5;
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::update_cached_efficiencies(const bu2kstarmumu_parameters* params, std::vector<event>* events)
|
||
{
|
||
if (opts->update_efficiencies){
|
||
spdlog::info("Updating cached efficiencies");
|
||
//assert(0);
|
||
//three ways this is usefull
|
||
//-q2_eff is fixed and you want to avoid recalculating this every time
|
||
//-weighted fit to determine the event weight that needs to be used
|
||
//-when using per event norm this can also be cached
|
||
npolynom npol(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
double q2 = params->eff_q2();
|
||
|
||
unsigned int N = events->size();
|
||
for (unsigned int e=0; e<N; e++){
|
||
double eff = 0.0;
|
||
event& meas = events->at(e);
|
||
if (opts->weighted_fit || (opts->use_angular_acc && opts->use_event_norm)){
|
||
q2 = meas.q2;
|
||
}
|
||
eff = this->get_ang_eff(opts,q2, meas.costhetal_fa, meas.costhetak_fa, meas.phi_fa);
|
||
|
||
if (eff > EFF_CUTOFF){
|
||
if (opts->multiply_eff) meas.weight *= 1.0/eff;
|
||
else meas.weight = 1.0/eff;
|
||
}
|
||
else{
|
||
spdlog::warn("Event with too low efficiency: {0:f}", eff);
|
||
spdlog::warn("\t q2: {0:f} \tq2_eff {1:f} \tctl: {2:f} \tctk: {3:f} \tphi: {4:f} ",
|
||
meas.q2, q2, meas.costhetal_fa, meas.costhetak_fa , meas.phi_fa);
|
||
if (opts->multiply_eff) meas.weight *= 1.0;
|
||
else meas.weight = 1.0;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
else return;
|
||
}
|
||
|
||
////////////////////////
|
||
/// Full angular ///
|
||
////////////////////////
|
||
|
||
//--------------------//
|
||
// S-wave
|
||
//--------------------//
|
||
|
||
void bu2kstarmumu_pdf::swave_fj(double ctl, double ctk, double phi,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const{
|
||
f1 = C_SWAVE * sintheta2(ctl);
|
||
f2 = C_SWAVE * sintheta2(ctl)*ctk;
|
||
f3 = C_SWAVE * sin2theta(ctl)*sintheta_abs(ctk)*cos(phi);
|
||
f4 = C_SWAVE * sintheta_abs(ctl)*sintheta_abs(ctk)*cos(phi);
|
||
f5 = C_SWAVE * sintheta_abs(ctl)*sintheta_abs(ctk)*sin(phi);
|
||
f6 = C_SWAVE * sin2theta(ctl)*sintheta_abs(ctk)*sin(phi);
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::swave_integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const{
|
||
f1 = 1.0;
|
||
f2 = 0.0;
|
||
f3 = 0.0;
|
||
f4 = 0.0;
|
||
f5 = 0.0;
|
||
f6 = 0.0;
|
||
|
||
swave_integrated_fj_noacc(opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max,
|
||
f1, f2, f3, f4, f5, f6);
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::swave_integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const{
|
||
f1 = C_SWAVE * integrate_s_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f2 = C_SWAVE * integrate_s_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f3 = C_SWAVE * integrate_s_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f4 = C_SWAVE * integrate_s_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f5 = C_SWAVE * integrate_s_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f6 = C_SWAVE * integrate_s_f6(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
return;
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::swave_integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const //TODO: modify this according to the normDebug branch
|
||
{
|
||
|
||
f1 = 0.0; f2 = 0.0; f3 = 0.0; f4 = 0.0; f5 = 0.0; f6 = 0.0;
|
||
|
||
npolynom npol(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
double chijk = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
const unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
chijk = C_SWAVE*pow(q2, h)*coeffs_eff_4d.at(bin);
|
||
|
||
f1 += chijk * integrate_s_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f2 += chijk * integrate_s_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f3 += chijk * integrate_s_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f4 += chijk * integrate_s_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f5 += chijk * integrate_s_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f6 += chijk * integrate_s_f6(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return;
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::swave_integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const{
|
||
f1 = 0.0; f2 = 0.0; f3 = 0.0; f4 = 0.0; f5 = 0.0; f6 = 0.0;
|
||
swave_integrated_fj_chebyshev(CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX,
|
||
f1, f2, f3, f4, f5, f6, q2);
|
||
return;
|
||
};
|
||
|
||
//--------------------//
|
||
// P-wave
|
||
//--------------------//
|
||
|
||
void bu2kstarmumu_pdf::fj(double ctl, double ctk, double phi,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const{
|
||
f1 = C_PWAVE * sintheta2(ctk); //j1s = 3/4*(1-FL)
|
||
f2 = C_PWAVE * costheta2(ctk); //j1c = FL
|
||
f3 = C_PWAVE * sintheta2(ctk)*cos2theta(ctl); //j2s = 1/4*(1-FL)
|
||
f4 = C_PWAVE * costheta2(ctk)*cos2theta(ctl); //j2c = -FL
|
||
f5 = C_PWAVE * sintheta2(ctk)*sintheta2(ctl)*cos(2.0*phi); //j3
|
||
f6 = C_PWAVE * sin2theta(ctk)*sin2theta(ctl)*cos(phi); //j4
|
||
f7 = C_PWAVE * sin2theta(ctk)*sintheta_abs(ctl)*cos(phi); //j5
|
||
f8 = C_PWAVE * sintheta2(ctk)*ctl; //j6s
|
||
f9 = C_PWAVE * costheta2(ctk)*ctl; //j6c
|
||
f10 = C_PWAVE * sin2theta(ctk)*sintheta_abs(ctl)*sin(phi); //j7
|
||
f11 = C_PWAVE * sin2theta(ctk)*sin2theta(ctl)*sin(phi); //j8
|
||
f12 = C_PWAVE * sintheta2(ctk)*sintheta2(ctl)*sin(2.0*phi); //j9
|
||
};
|
||
|
||
|
||
void bu2kstarmumu_pdf::integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const{
|
||
//Normalization of the p-wave in principle
|
||
f1 = 0.0; f2 = 0.0; f3 = 0.0; f4 = 0.0; f5 = 0.0; f6 = 0.0;
|
||
f7 = 0.0; f8 = 0.0; f9 = 0.0; f10 = 0.0; f11 = 0.0; f12 = 0.0;
|
||
integrated_fj_noacc(CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX,
|
||
f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
return;
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const{
|
||
f1 = C_PWAVE * integrate_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f2 = C_PWAVE * integrate_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f3 = C_PWAVE * integrate_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f4 = C_PWAVE * integrate_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f5 = C_PWAVE * integrate_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f6 = C_PWAVE * integrate_f6(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f7 = C_PWAVE * integrate_f7(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f8 = C_PWAVE * integrate_f8(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f9 = C_PWAVE * integrate_f9(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f10 = C_PWAVE * integrate_f10(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f11 = C_PWAVE * integrate_f11(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f12 = C_PWAVE * integrate_f12(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
return;
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const{
|
||
|
||
f1 = 0.0;
|
||
f2 = 0.0;
|
||
f3 = 0.0;
|
||
f4 = 0.0;
|
||
f5 = 0.0;
|
||
f6 = 0.0;
|
||
f7 = 0.0;
|
||
f8 = 0.0;
|
||
f9 = 0.0;
|
||
f10 = 0.0;
|
||
f11 = 0.0;
|
||
f12 = 0.0;
|
||
|
||
//new improved non-factorizing acceptance
|
||
npolynom npol = npolynom(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
const unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
double chijk = C_PWAVE*coeffs_eff_4d.at(bin)*pow(q2, h); //9/32pi * angCorr(bin) * q2^h (not integrating over q2)
|
||
|
||
f1 += chijk * integrate_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f2 += chijk * integrate_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f3 += chijk * integrate_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f4 += chijk * integrate_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f5 += chijk * integrate_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f6 += chijk * integrate_f6(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f7 += chijk * integrate_f7(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f8 += chijk * integrate_f8(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f9 += chijk * integrate_f9(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f10 += chijk * integrate_f10(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f11 += chijk * integrate_f11(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f12 += chijk * integrate_f12(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const{
|
||
f1 = 0.0; f2 = 0.0; f3 = 0.0; f4 = 0.0; f5 = 0.0; f6 = 0.0;
|
||
f7 = 0.0; f8 = 0.0; f9 = 0.0; f10 = 0.0; f11 = 0.0; f12 = 0.0;
|
||
integrated_fj_chebyshev(CTL_MIN, CTL_MAX, CTK_MIN, CTK_MAX, PHI_MIN, PHI_MAX,
|
||
f1, f2, f3, f4, f5, f6,
|
||
f7, f8, f9, f10, f11, f12, q2);
|
||
return;
|
||
};
|
||
|
||
/////////////////////
|
||
///Angular folding///
|
||
/////////////////////
|
||
|
||
//S-wave
|
||
|
||
void bu2kstarmumu_pdf::folded_swave_fj(double ctl, double ctk, double phi,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const
|
||
{
|
||
double c = C_SWAVE*2.0; // folding in phi
|
||
if(opts->folding > 0) c *= 2.0; //folding in cos(thetaL)
|
||
|
||
f2 = 0.0; f3 = 0.0; f4 = 0.0; f5 = 0.0; f6 = 0.0;
|
||
|
||
f1 = c * sintheta2(ctl);
|
||
if(opts->folding != 4) f2 = c * sintheta2(ctl)*(ctk);
|
||
if(opts->folding == 1) f3 = c * sintheta_abs(ctk)*sin2theta(ctl)*cos(phi);
|
||
if(opts->folding == 2) f4 = c * sintheta_abs(ctk)*sintheta_abs(ctl)*cos(phi);
|
||
if(opts->folding > 2) f5 = c * sintheta_abs(ctk)*sintheta_abs(ctl)*sin(phi);
|
||
//f6 always zero no matter what folding
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::folded_swave_integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const
|
||
{
|
||
f1 = 1.0;
|
||
f2 = 0.0;
|
||
f3 = 0.0;
|
||
f4 = 0.0;
|
||
f5 = 0.0;
|
||
f6 = 0.0;
|
||
|
||
folded_swave_integrated_fj_noacc(opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max,
|
||
f1, f2, f3, f4, f5, f6);
|
||
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::folded_swave_integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const{
|
||
double c = C_SWAVE*2.0; // folding in phi
|
||
if(opts->folding > 0) c *= 2.0; //folding in cos(thetaL)
|
||
|
||
f2 = 0.0; f3 = 0.0; f4 = 0.0; f5 = 0.0;
|
||
f1 = c * integrate_s_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
if(opts->folding != 4) f2 = c * integrate_s_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
if(opts->folding == 1) f3 = c * integrate_s_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
if(opts->folding == 2) f4 = c * integrate_s_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
if(opts->folding > 2) f5 = c * integrate_s_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f6 = 0.0;
|
||
|
||
return;
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::folded_swave_integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const{
|
||
double c = C_SWAVE*2.0; // folding in phi
|
||
if(opts->folding > 0) c *= 2.0; //folding in cos(thetaL)
|
||
|
||
f1 = 0.0; f2 = 0.0; f3 = 0.0; f4 = 0.0; f5 = 0.0; f6 = 0.0;
|
||
|
||
npolynom npol = npolynom(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
|
||
double chijk = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++){
|
||
for (unsigned int i = 0; i<npol.ctl; i++){
|
||
for (unsigned int j = 0; j<npol.ctk; j++){
|
||
for (unsigned int k = 0; k<npol.phi; k++){
|
||
const unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
chijk = c*pow(q2, h)*coeffs_eff_4d.at(bin);
|
||
f1 += chijk * integrate_s_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
if(opts->folding != 4) f2 += chijk * integrate_s_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
if(opts->folding == 1) f3 += chijk * integrate_s_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
if(opts->folding == 2) f4 += chijk * integrate_s_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
if(opts->folding > 2) f5 += chijk * integrate_s_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f6 = 0.0;
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::folded_swave_integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const{
|
||
|
||
folded_swave_integrated_fj_chebyshev(opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max,
|
||
f1, f2, f3, f4, f5, f6, q2);
|
||
return;
|
||
}
|
||
|
||
//P-wave
|
||
|
||
void bu2kstarmumu_pdf::folded_fj(double ctl, double ctk, double phi, double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const
|
||
{
|
||
//reset all coefficients that might not be calculated due to folding!
|
||
f6 = 0.;
|
||
f7 = 0.;
|
||
f8 = 0.;
|
||
f9 = 0.;
|
||
f10 = 0.;
|
||
f11 = 0.;
|
||
f12 = 0.;
|
||
|
||
//constant coefficient
|
||
double c = 2.0*C_PWAVE; //multiply by 2 due to folding in phi
|
||
if(opts->folding > 0) c *= 2.0; //folding in cos(thetaL)
|
||
|
||
f1 = c * sintheta2(ctk); //j1s = 3/4*(1-FL)
|
||
f2 = c * costheta2(ctk); //j1c = FL
|
||
f3 = c * sintheta2(ctk)*cos2theta(ctl); //j2s = 1/4*(1-FL)
|
||
f4 = c * costheta2(ctk)*cos2theta(ctl); //j2c = -FL
|
||
f5 = c * sintheta2(ctk)*sintheta2(ctl)*cos(2.0*phi); //j3
|
||
if(opts->folding == 1) f6 = c * sin2theta(ctk)*sin2theta(ctl)*cos(phi); //j4
|
||
if(opts->folding == 2) f7 = c * sin2theta(ctk)*sintheta_abs(ctl)*cos(phi); //j5
|
||
if(opts->folding == 0){
|
||
f8 = c * sintheta2(ctk)*ctl; //j6s
|
||
f9 = c * costheta2(ctk)*ctl; //j6c
|
||
}
|
||
if(opts->folding == 3) f10 = c * sin2theta(ctk)*sintheta_abs(ctl)*sin(phi); //j7
|
||
if(opts->folding == 4) f11 = c * sin2theta(ctk)*sin2theta(ctl)*sin(phi); //j8
|
||
if(opts->folding == 0) f12 = c * sintheta2(ctk)*sintheta2(ctl)*sin(2.0*phi); //j9
|
||
};
|
||
|
||
|
||
void bu2kstarmumu_pdf::folded_integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const
|
||
{
|
||
folded_integrated_fj_noacc(opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max,
|
||
f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12);
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::folded_integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const
|
||
{
|
||
|
||
if(opts->full_angular){
|
||
spdlog::error("Cannot use folded integrals for full angular fit");
|
||
assert(0);
|
||
}
|
||
|
||
f1 = 0.0;
|
||
f2 = 0.0;
|
||
f3 = 0.0;
|
||
f4 = 0.0;
|
||
f5 = 0.0;
|
||
f6 = 0.0;
|
||
f7 = 0.0;
|
||
f8 = 0.0;
|
||
f9 = 0.0;
|
||
f10 = 0.0;
|
||
f11 = 0.0;
|
||
f12 = 0.0;
|
||
|
||
//copied from full angular integral:
|
||
double c = C_PWAVE*2.; //folding in phi
|
||
if(opts->folding > 0)c *= 2.; //folding in cos(theta_L)
|
||
|
||
f1 = c * integrate_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f2 = c * integrate_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f3 = c * integrate_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f4 = c * integrate_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f5 = c * integrate_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
if(opts->folding == 0){
|
||
f8 = c * integrate_f8(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f9 = c * integrate_f9(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
f12 = c * integrate_f12(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
}
|
||
else if(opts->folding == 1) f6 = c * integrate_f6(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
else if(opts->folding == 2) f7 = c * integrate_f7(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
else if(opts->folding == 3) f10 = c * integrate_f10(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
else if(opts->folding == 4) f11 = c * integrate_f11(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, 0, 0, 0);
|
||
|
||
return;
|
||
|
||
};
|
||
|
||
|
||
void bu2kstarmumu_pdf::folded_integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const{
|
||
|
||
if(opts->full_angular){
|
||
spdlog::error("Cannot use folded integrals for full angular fit");
|
||
assert(0);
|
||
}
|
||
|
||
double c = C_PWAVE* 2.; //folding in phi
|
||
if(opts->folding > 0)c *= 2.; //folding in cos(theta_L)
|
||
|
||
f1 = 0.0;
|
||
f2 = 0.0;
|
||
f3 = 0.0;
|
||
f4 = 0.0;
|
||
f5 = 0.0;
|
||
f6 = 0.0;
|
||
f7 = 0.0;
|
||
f8 = 0.0;
|
||
f9 = 0.0;
|
||
f10 = 0.0;
|
||
f11 = 0.0;
|
||
f12 = 0.0;
|
||
|
||
//new improved non-factorizing acceptance
|
||
|
||
npolynom npol = npolynom(opts);
|
||
assert(coeffs_eff_4d.size() == npol.getSize());
|
||
double chijk = 0.0;
|
||
for (unsigned int h = 0; h<npol.q2; h++)
|
||
for (unsigned int i = 0; i<npol.ctl; i++)
|
||
for (unsigned int j = 0; j<npol.ctk; j++)
|
||
for (unsigned int k = 0; k<npol.phi; k++)
|
||
{
|
||
const unsigned int bin = npol.get_bin_in4D(h,i,j,k);
|
||
chijk = c*pow(q2, h)*coeffs_eff_4d.at(bin);
|
||
f1 += chijk*integrate_f1(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f2 += chijk*integrate_f2(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f3 += chijk*integrate_f3(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f4 += chijk*integrate_f4(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f5 += chijk*integrate_f5(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
if(opts->folding == 0){
|
||
f8 += chijk*integrate_f8(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f9 += chijk*integrate_f9(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
f12 += chijk*integrate_f12(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
}
|
||
else if(opts->folding == 1) f6 += chijk*integrate_f6(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
else if(opts->folding == 2) f7 += chijk*integrate_f7(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
else if(opts->folding == 3) f10 += chijk*integrate_f10(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
else if(opts->folding == 4) f11 += chijk*integrate_f11(ctl_a, ctl_b, ctk_a, ctk_b, phi_a, phi_b, i, j, k);
|
||
|
||
}
|
||
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::folded_integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const{
|
||
folded_integrated_fj_chebyshev(opts->ctl_min, opts->ctl_max, opts->ctk_min, opts->ctk_max, opts->phi_min, opts->phi_max,
|
||
f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, q2);
|
||
return;
|
||
};
|
||
|
||
|
||
|
||
void bu2kstarmumu_pdf::calculate_sweights(const bu2kstarmumu_parameters* parms, std::vector<event>* ev) const
|
||
{
|
||
assert(opts->extended_ml);
|
||
parameter* psig = parms->get_parameter("n_sig");
|
||
parameter* pbkg = parms->get_parameter("n_bkg");
|
||
if (psig != 0 && pbkg != 0){
|
||
double nsig = psig->get_value();
|
||
double nbkg = pbkg->get_value();
|
||
|
||
double sweight = 0.0, prob_sig_m = 0.0, prob_bkg_m = 0.0;
|
||
|
||
//obtain inverse variant matrix (V_{nj}^{-1})
|
||
double inv_cov_matrix[2*2] = {0.0, 0.0, 0.0, 0.0};
|
||
for (unsigned int i = 0; i<ev->size(); i++){
|
||
const event& meas = ev->at(i);
|
||
prob_sig_m = m_sig_prob(parms, meas);
|
||
prob_bkg_m = m_bkg_prob(parms, meas);
|
||
|
||
inv_cov_matrix[0] += prob_sig_m*prob_sig_m/sqr(nsig*prob_sig_m + nbkg*prob_bkg_m);
|
||
inv_cov_matrix[1] += prob_sig_m*prob_bkg_m/sqr(nsig*prob_sig_m + nbkg*prob_bkg_m);
|
||
inv_cov_matrix[2] += prob_bkg_m*prob_sig_m/sqr(nsig*prob_sig_m + nbkg*prob_bkg_m);
|
||
inv_cov_matrix[3] += prob_bkg_m*prob_bkg_m/sqr(nsig*prob_sig_m + nbkg*prob_bkg_m);
|
||
}
|
||
spdlog::info("Inverse covariance matrix");
|
||
spdlog::info("{0:0.8f} {1:.8f}", inv_cov_matrix[0],inv_cov_matrix[1] );
|
||
spdlog::info("{0:0.8f} {1:.8f}", inv_cov_matrix[2],inv_cov_matrix[3] );
|
||
|
||
//invert inserve matrix to get V_{nj}
|
||
double cov_matrix[2*2] = {0.0, 0.0, 0.0, 0.0};
|
||
cov_matrix[0] = +inv_cov_matrix[3]/(inv_cov_matrix[0]*inv_cov_matrix[3]-inv_cov_matrix[1]*inv_cov_matrix[2]);
|
||
cov_matrix[1] = -inv_cov_matrix[1]/(inv_cov_matrix[0]*inv_cov_matrix[3]-inv_cov_matrix[1]*inv_cov_matrix[2]);
|
||
cov_matrix[2] = -inv_cov_matrix[2]/(inv_cov_matrix[0]*inv_cov_matrix[3]-inv_cov_matrix[1]*inv_cov_matrix[2]);
|
||
cov_matrix[3] = +inv_cov_matrix[0]/(inv_cov_matrix[0]*inv_cov_matrix[3]-inv_cov_matrix[1]*inv_cov_matrix[2]);
|
||
spdlog::info("Covariance matrix");
|
||
spdlog::info("{0:0.8f} {1:.8f}", cov_matrix[0], cov_matrix[1] );
|
||
spdlog::info("{0:0.8f} {1:.8f}", cov_matrix[2], cov_matrix[3] );
|
||
|
||
//get sWeights for all events
|
||
for (unsigned int i = 0; i<ev->size(); i++){
|
||
const event& meas = ev->at(i);
|
||
prob_sig_m = m_sig_prob(parms, meas);
|
||
prob_bkg_m = m_bkg_prob(parms, meas);
|
||
sweight = (prob_sig_m * cov_matrix[0] + prob_bkg_m * cov_matrix[1]) / ( prob_sig_m * nsig + prob_bkg_m * nbkg );
|
||
ev->at(i).sweight = sweight;
|
||
}
|
||
}
|
||
};
|
||
|
||
void bu2kstarmumu_pdf::save_coeffs_eff_phsp_4d(){
|
||
std::ofstream ostr(coeffs_eff_phsp_4D(opts));
|
||
for(unsigned int c = 0; c < this->coeffs_eff_4d.size(); c++){
|
||
ostr << std::setprecision(15) << std::scientific << this->coeffs_eff_4d.at(c) << "\n";
|
||
}
|
||
spdlog::info("[SAVE]\t\tSaved a total of {0:d} angular acceptance correction coefficients",this->coeffs_eff_4d.size());
|
||
}
|
||
|
||
std::vector<double> bu2kstarmumu_pdf::read_coeffs_eff_phsp_4d(){
|
||
|
||
unsigned int nCoeffs = opts->eff_order_q2 * opts->eff_order_costhetal * opts->eff_order_costhetak * opts->eff_order_phi;
|
||
|
||
std::string filename = coeffs_eff_phsp_4D(opts);
|
||
std::ifstream file(filename);
|
||
if(!file.is_open())spdlog::error("File " + filename + " not found to load coefficients!");
|
||
else spdlog::info("Loading a total of {0:d} coefficients from file " + filename + ".",nCoeffs);
|
||
std::string line;
|
||
|
||
double coeff;
|
||
std::vector<double>coeffs;
|
||
|
||
assert(file.is_open());
|
||
|
||
while(1){
|
||
getline(file, line);
|
||
if(file.eof())break;
|
||
std::istringstream istr(line);
|
||
istr >> coeff;
|
||
coeffs.push_back(coeff);
|
||
}
|
||
|
||
if(coeffs.size() != nCoeffs){
|
||
spdlog::critical("Number of coefficients loaded from file ({0:d}) does not match the number of configurated coefficients ({1:d}). Abort", coeffs.size(), nCoeffs);
|
||
assert(0);
|
||
}
|
||
|
||
|
||
return coeffs;
|
||
}
|
||
|
||
void bu2kstarmumu_pdf::load_coeffs_eff_phsp_4d(){
|
||
this->coeffs_eff_4d = read_coeffs_eff_phsp_4d();
|
||
}
|
||
|