#include #include #include #include #include #include #include #include #include #include #include #include #include #include "TDecompSVD.h" #include #include #include #include #include #include "Math/WrappedTF1.h" #include "Math/BrentRootFinder.h" #include "Eoe.h" #include "fitPar.h" using namespace std; // Constructor Eoe::Eoe (string inputFileName, TRandom3* ran, ROOT::Math::Random* rgsl) { // read in steering file with data // line 1: L -- number of measurements // lines 2:L+1 -- measured values y_i and stat. errors sigma_y_i // line L+2 -- N, number of nuisance params (=number of control meas) // lines L+3:L+N+2 -- control meas u_i and estimate of its std. dev. s_i // lines L+N+3:2L+N+2 -- matrix R_{ij), one row per line, defined // by E[y_i] = phi_i(mu) + \sum_{j} R_{ij} theta_j ifstream f; f.open(inputFileName.c_str()); if ( f.fail() ){ cout << "Sorry, couldn't open file" << endl; exit(1); } istringstream instream; // Declare an input string stream string line; int lineNum = 0; while ( getline(f, line) ) { bool useLine = !( line.substr(0,1) == "#" || line.substr(0,1) == "!"); if ( useLine ) { instream.clear(); // Reset from possible previous errors instream.str(line); // Use line as source of input lineNum++; double y, sigma_y, s, r, u; if ( lineNum == 1 ) { instream >> m_L; // number of main measurements m_R.resize(m_L); // set number of rows to m_L m_cov_bHat.resize(m_L); for (int i=0; i= 2 && lineNum <= m_L+1 ){ instream >> y >> sigma_y; m_yVec.push_back(y); m_sigma_y_Vec.push_back(sigma_y); } if ( lineNum == m_L+2 ) { instream >> m_N; // number nuisance par / control meas. for (int i = 0; i= m_L+3 && lineNum <= m_L+m_N+2 ) { instream >> u >> s >> r; m_sVec.push_back(s); double v = s*s; m_vVec.push_back(v); m_rVec.push_back(r); m_uVec.push_back(u); } if ( lineNum >= m_L+m_N+3 && lineNum <= 2*m_L+m_N+2) { int i = lineNum - m_L - m_N - 3; // start at row 0 for (int j=0; j> m_R[i][j]; } } } } f.close(); // initialize stuff m_M = 1; // for now support one parameter of interest m_npar = m_N + m_M; // for default fit m_up = 1.; // for MINOS m_parVec.clear(); m_sigParVec.clear(); m_startPar.clear(); m_stepSize.clear(); for (int i=0; i muVec){ double mu = muVec[0]; return mu; // phi_i(mu) = E[y_i] (nominal model, no bias) } double Eoe::phi(int i, double mu){ vector muVec(1); muVec[0] = mu; return this->phi(i, muVec); } double Eoe::lnL(vector parVec){ // y_i ~ Gauss (mu_i + (R theta)_i, sigma_y_i), i = 1,..., L // u_i ~ Gauss (theta_i, sigma_u_i), i = 1,..., N // v_i ~ gamma (alpha_i, beta_i), i = 1,..., N // alpha_i = 1./4r_i^2, beta_i = alpha_i / sigma_u_i^2 // parVec[0:m_M-1] = parameters of interest (e.g. parVec[0] = mu) // parVec[m_M:m_M+m_N-1] = theta_i, i = 0,...,N-1 nuisance parameters // for now implement m_M = 1, fit single value of mu int L = m_L; int M = m_M; int N = m_N; double mu = parVec[0]; vector thetaVec(N); for (int i=0; iphi(i,mu) - Rtheta_i; double w = m_sigma_y_Vec[i]*m_sigma_y_Vec[i]; sum += q*q/w; } for (int i=0; i muVec, vector thetaVec, vector rVec, vector uVec, vector vVec){ double lnL = 0.; int N = thetaVec.size(); for (int i=0; i freePar(m_npar); for (int i=0; ifit(); // fills m_parVec double qVal = -2.*this->lnL(m_parVec); return qVal; } // gof statistic q' (q with Bartlett correction based on MC) double Eoe::qBCMC(){ int L = this->L(); // number of measurements int M = this->M(); // number of parameters of interest int N = this->N(); // number of nuisance parameters & control meas. double ndof = static_cast(L-M); double qVal = this->q(); int status = this->fit(); // sets m_parVec; vector thetaVec(N); for (int i=0; i sigma_u_hh = sigma_u_HatHatVec(thetaVec); vector genParVec(2*N+M); genParVec[0] = m_parVec[0]; // mu for (int i=0; isetEqMC(genParVec); qVal *= ndof / m_EqMC; // apply Bartlett correction return qVal; } // mean values of LR statistics for Bartlett correction; also sets p-value void Eoe::setEqMC(vector parVec) { const int numEvents = 10000; // adjust as needed double eq = 0.; double qObs = this->q(); Eoe eoe = *this; // local object int m = 0; for (int i=0; i= qObs ) { m++; } } m_p = static_cast(m)/static_cast(numEvents); // set p-value eq /= static_cast(numEvents); m_EqMC = eq; m_EqMCSet = true; m_pValSet = true; } // Generate MC data based on Eoe model and input parameter values void Eoe::generateData(vector parVec) { m_yVec.clear(); m_uVec.clear(); m_sVec.clear(); m_vVec.clear(); int N = m_N; double mu = parVec[0]; // for now supports only one param of int. for (int i=0; iGaus(mu + b, sigma_y); double u = m_ran->Gaus(b, sigma_u); double v = m_rgsl->Gamma(alpha, 1./beta); // gsl's convention for beta double s = sqrt(v); m_yVec.push_back(y); m_uVec.push_back(u); m_sVec.push_back(s); m_vVec.push_back(v); } } // profiled values of sigma_u vector Eoe::sigma_u_HatHatVec(vector thetaVec){ vector suhhVec(m_N); for (int i=0; ir(i); double e = 2.*r*r; double v = this->v(i); double umb = this->u(i) - thetaVec[i]; suhhVec[i] = sqrt( (v + e*umb*umb)/(1. + e) ); } return suhhVec; } // Estimate start values and step sizes using ordinary LS and linear approx. void Eoe::setStartPar(){ int L = this->L(); int N = this->N(); int npar = this->npar(); // use ordinary LS for start value of mu, use estimates of biases // but otherwise ignore systematics double wSum = 0.; vector w(L); for (int i=0; isigma_y(i); double su = this->s(i); w[i] = 1./(sy*sy); wSum += w[i]; } double sigmaMuHatLS = 1./sqrt(wSum); // needed for step size double muHatLS = 0.; for (int i=0; iy(i) - this->bHat(i)); } m_startPar[0] = muHatLS; // Approx. profiled theta based on linear (small r) approximation vector thetaHHLVec = this->thetaHatHatLinVec(muHatLS); for (int i=0; is(i); // for theta_i } } vector Eoe::thetaHatHatLinVec(double mu) { vector muVec(1); muVec[0] = mu; vector thetaHHLVec = this->thetaHatHatLinVec(muVec); return thetaHHLVec; } // Approx. profiled theta based on linear (small r) approximation vector Eoe::thetaHatHatLinVec(vector muVec) { int L = this->L(); int M = this->M(); // here this should be 1 int N = this->N(); double mu = muVec[0]; vector thetaHHLVec(N); if ( muVec.size() != 1 ) { cout << "thetaHatHatLinVec: multiple PoI not supported, ret 0" << endl; for (int i=0; im_yVec[j] - this->phi(j, mu)) * m_R[j][i] / (m_sigma_y_Vec[j]*m_sigma_y_Vec[j]); } } TDecompSVD svd(A); Bool_t svdOK; TVectorD thetaHatHatLin = svd.Solve(B, svdOK); if ( !svdOK ) { cout << "getStartPar failed to find thetaHatHat, setting to zero" << endl; thetaHatHatLin.ResizeTo(N); for (int i=0; i