11 #include "BCMVCombination.h"
13 #include "BCMVCMeasurement.h"
14 #include "BCMVCObservable.h"
15 #include "BCMVCUncertainty.h"
17 #include "../../BAT/BCLog.h"
18 #include "../../BAT/BCMath.h"
19 #include "../../BAT/BCParameter.h"
26 BCMVCombination::BCMVCombination()
30 , fNNuisanceCorrelation(0)
35 BCMVCombination::~BCMVCombination()
37 int nuncertainties = GetNUncertainties();
38 int nmeasurements = GetNMeasurements();
40 for (
int i = 0; i < nuncertainties; ++i) {
44 fUncertainties.clear();
46 for (
int i = 0; i < nmeasurements; ++i) {
50 fMeasurements.clear();
54 void BCMVCombination::AddObservable(std::string name,
double min,
double max)
57 int index = GetIndexObservable(name);
64 obs->SetMinMax(min, max);
65 fObservables.push_back(obs);
75 void BCMVCombination::AddUncertainty(std::string name)
79 fUncertainties.push_back(u);
83 void BCMVCombination::AddMeasurement(std::string name, std::string observable,
double value, std::vector<double> uncertainties)
86 int index = GetIndexObservable(observable);
90 BCLog::OutWarning(Form(
"BCMVCombination::AddMeasurement. Observable \"%s\" does not exist. Measurement was not added.", observable.c_str()));
95 m->SetObservable(index);
96 m->SetCentralValue(value);
97 m->SetUncertainties(uncertainties);
99 fMeasurements.push_back(m);
101 fVectorObservable.push_back(index);
103 int n = GetNMeasurements();
104 fVectorMeasurements.ResizeTo(n);
105 fVectorMeasurements[n-1]=value;
113 if (fNNuisanceCorrelation > 0) {
114 CalculateCovarianceMatrix(parameters);
115 if (!PositiveDefinite())
119 int nmeas = GetNActiveMeasurements();
122 TVectorD observables(nmeas);
124 for (
int i = 0; i < nmeas; ++i) {
125 observables[i] = parameters[fVectorActiveObservable[i]];
128 TVectorD prod1 = observables - fVectorActiveMeasurements;
129 TVectorD prod2 = fInvCovarianceMatrix * prod1;
130 double prod = prod1 * prod2;
132 logprob = -0.5 * prod - log(TMath::Power(2*TMath::Pi(), nmeas/2.) * sqrt(fabs(fDetCovariance)));
138 int BCMVCombination::ReadInput(std::string filename)
141 std::ifstream infile;
142 infile.open(filename.c_str(), std::ifstream::in);
145 if (!infile.is_open()) {
146 BCLog::OutWarning(Form(
"BCMVCombination::ReadInput. Could not open input file %s.", filename.c_str()));
155 infile >> nobservables >> nmeasurements >> nuncertainties >> nnuisance;
157 std::vector<std::string> observable_names;
159 for (
int i = 0; i < nobservables; ++i) {
163 infile >> name >> min >> max;
166 AddObservable(name.c_str(), min, max);
169 for (
int i = 0; i < nuncertainties; ++i) {
174 AddUncertainty(name);
177 for (
int i = 0; i < nmeasurements; ++i) {
179 std::string observable;
181 std::vector<double> uncertainties(0);
184 infile >> observable;
187 for (
int j = 0; j < nuncertainties; ++j) {
189 infile >> uncertainty;
190 uncertainties.push_back(uncertainty);
194 AddMeasurement(name, observable, central, uncertainties);
197 for (
int i = 0; i < nuncertainties; ++i) {
198 TMatrixD mat(nmeasurements, nmeasurements);
200 for (
int j = 0; j < nmeasurements; ++j)
201 for (
int k = 0; k < nmeasurements; ++k) {
208 GetUncertainty(i)->SetCorrelationMatrix(mat);
211 for (
int i = 0; i < nnuisance; ++i) {
212 std::string uncertainty;
213 std::string measurement1;
214 std::string observable1;
215 std::string measurement2;
216 std::string observable2;
221 std::string priorshape;
223 infile >> uncertainty >> measurement1 >> observable1 >> measurement2 >> observable2 >> parname;
228 for (
unsigned int i = 0; i < GetNParameters(); i++)
229 if (parname.c_str() == GetParameter(i)->GetName())
237 infile >> min >> max >> priorshape;
246 index = GetNParameters()-1;
248 if (priorshape ==
"flat") {
251 else if (priorshape ==
"gauss") {
255 infile >> mean >> std;
260 BCLog::OutWarning(Form(
"BCMVCombination::ReadInput. Unknown prior shape %s.", priorshape.c_str()));
265 fNNuisanceCorrelation++;
268 p.index_uncertainty = GetIndexUncertainty(uncertainty);
269 p.index_measurement1 = GetIndexMeasurement(measurement1, observable1);
270 p.index_measurement2 = GetIndexMeasurement(measurement2, observable2);
271 p.index_rhoparameter = index;
274 fNuisanceCorrelation.push_back(p);
287 void BCMVCombination::PrepareAnalysis()
289 int nuncertainties = GetNUncertainties();
292 for (
int i = 0; i < nuncertainties; ++i)
293 CalculateCorrelationMatrix(i);
295 CalculateCovarianceMatrix();
297 if (!PositiveDefinite()) {
298 BCLog::OutWarning(
"BCMVCombination::PrepareAnalysis. Covariance matrix is not positive definite.");
301 CalculateHelperVectors();
306 int BCMVCombination::GetNActiveMeasurements()
308 int n = GetNMeasurements();
312 for (
int i = 0; i < n; ++i) {
314 if (m->GetFlagActive())
321 void BCMVCombination::CalculateHelperVectors()
323 int nmeasurements = GetNMeasurements();
325 fVectorMeasurements.Clear();
326 fVectorMeasurements.ResizeTo(nmeasurements);
327 fVectorObservable.clear();
329 for (
int i = 0; i < nmeasurements; ++i) {
331 fVectorMeasurements[i] = m->GetCentralValue();
332 fVectorObservable.push_back(m->GetObservable());
335 int nactive = GetNActiveMeasurements();
337 fVectorActiveMeasurements.Clear();
338 fVectorActiveMeasurements.ResizeTo(nactive);
339 fVectorActiveObservable.clear();
342 for (
int i = 0; i < nmeasurements; ++i) {
344 if (m->GetFlagActive()) {
345 fVectorActiveMeasurements[counter] = m->GetCentralValue();
346 fVectorActiveObservable.push_back(m->GetObservable());
354 void BCMVCombination::CalculateCorrelationMatrix(
int index)
358 int n = GetNMeasurements();
359 int nactive = GetNActiveMeasurements();
361 TMatrixD cov(nactive, nactive);
363 TMatrixD corr = u->GetCorrelationMatrix();
366 for (
int i = 0; i < n; ++i) {
368 double sigma_i = mi->GetUncertainty(index);
371 if (!mi->GetFlagActive())
375 for (
int j = 0; j < n; ++j) {
377 double sigma_j = mj->GetUncertainty(index);
379 if (mj->GetFlagActive()) {
380 cov[counteri][counterj] = corr[i][j]*sigma_i*sigma_j;
387 u->SetCovarianceMatrix(cov);
391 void BCMVCombination::CalculateCovarianceMatrix(std::vector<double> parameters)
393 int n = GetNUncertainties();
394 int nmeasurements = GetNMeasurements();
395 int nnuisance = fNNuisanceCorrelation;
397 fCovarianceMatrix.Clear();
398 fCovarianceMatrix.ResizeTo(GetNActiveMeasurements(), GetNActiveMeasurements());
401 for (
int unc_i = 0; unc_i < n; ++unc_i) {
405 TMatrixD mat_small = u->GetCovarianceMatrix();
409 for (
int meas_i = 0; meas_i < nmeasurements; ++meas_i) {
413 if (!mi->GetFlagActive())
418 for (
int meas_j = 0; meas_j < nmeasurements; ++meas_j) {
422 if (!mj->GetFlagActive())
426 if (parameters.size() > 0) {
429 for (
int nuis_k = 0; nuis_k < nnuisance; ++nuis_k) {
432 NuisanceParameter p = fNuisanceCorrelation.at(nuis_k);
435 if (p.index_uncertainty == unc_i) {
436 double sigma_i = GetMeasurement(p.index_measurement1)->GetUncertainty(unc_i);
437 double sigma_j = GetMeasurement(p.index_measurement2)->GetUncertainty(unc_i);
441 if (meas_i == p.index_measurement1 && meas_j == p.index_measurement2) {
442 mat_small[counteri][counterj] = pre * parameters.at(p.index_rhoparameter) * sigma_i*sigma_j;
443 mat_small[counterj][counteri] = mat_small[counteri][counterj];
458 if (u->GetFlagActive())
459 fCovarianceMatrix += mat_small;
461 fInvCovarianceMatrix.Clear();
462 fInvCovarianceMatrix.ResizeTo(fCovarianceMatrix);
463 fInvCovarianceMatrix = fCovarianceMatrix;
464 fInvCovarianceMatrix.Invert();
466 fDetCovariance = fCovarianceMatrix.Determinant();
470 bool BCMVCombination::PositiveDefinite()
472 TMatrixDEigen m(fCovarianceMatrix);
475 TVectorD eigen_re = m.GetEigenValuesRe();
477 int n_eigen = eigen_re.GetNoElements();
479 bool flag_ispositive =
true;
482 for (
int i = 0; i < n_eigen; ++i) {
484 flag_ispositive =
false;
488 return flag_ispositive;
492 void BCMVCombination::CalculateBLUE()
494 int nmeas = GetNMeasurements();
495 int nactivemeas = GetNActiveMeasurements();
496 int nobs = GetNObservables();
497 int nunc = GetNUncertainties();
501 TMatrixD u(nactivemeas, nobs);
504 for (
int i = 0; i < nmeas; ++i) {
508 if (m->GetFlagActive()) {
509 for (
int j = 0; j < nobs; ++j) {
510 if (m->GetObservable() == j)
523 TMatrixD m1 = ut * fInvCovarianceMatrix;
524 TMatrixD m2 = m1 * u;
527 fBLUEWeights.Clear();
529 fBLUEWeights.ResizeTo(nobs, nactivemeas);
531 fBLUEWeights = m2*m1;
534 fBLUECentral.Clear();
535 fBLUECentral.ResizeTo(nobs);
538 fBLUECentral = fBLUEWeights * fVectorActiveMeasurements;
541 fBLUECovarianceMatrix.Clear();
542 fBLUECovarianceMatrix.ResizeTo(nobs, nobs);
544 TMatrixD weightt = fBLUEWeights;
545 weightt.Transpose(weightt);
547 fBLUECovarianceMatrix = fBLUEWeights * fCovarianceMatrix * weightt;
550 for (
int i = 0; i < nunc; ++i) {
554 if (!u->GetFlagActive())
557 TMatrixD cov = u->GetCovarianceMatrix();
558 TMatrixD mat = fBLUEWeights * cov * weightt;
559 fBLUECovarianceMatrices.push_back(mat);
563 for (
int j = 0; j < nobs; ++j) {
564 double sigma_j = sqrt(mat[j][j]);
567 fBLUEUncertaintiesPerSource.push_back(vec);
569 TMatrixD mat2(nobs, nobs);
570 for (
int j = 0; j < nobs; ++j)
571 for (
int k = 0; k < nobs; ++k) {
572 mat2[j][k] = mat[j][k]/vec[j]/vec[k];
574 fBLUECorrelationMatrices.push_back(mat2);
578 fBLUEUncertainties.Clear();
579 fBLUEUncertainties.ResizeTo(nobs);
581 for (
int i = 0; i < nobs; ++i)
582 fBLUEUncertainties[i] = sqrt(fBLUECovarianceMatrix[i][i]);
585 fBLUECorrelationMatrix.Clear();
586 fBLUECorrelationMatrix.ResizeTo(nobs, nobs);
588 for (
int i = 0; i < nobs; ++i)
589 for (
int j = 0; j < nobs; ++j)
590 fBLUECorrelationMatrix[i][j] = fBLUECovarianceMatrix[i][j] / fBLUEUncertainties[i] / fBLUEUncertainties[j];
594 void BCMVCombination::PrintBLUEResults(std::string filename)
597 std::ofstream ofi(filename.c_str());
600 if (!ofi.is_open()) {
601 std::cerr <<
"Couldn't open file " << filename << std::endl;
605 int nobs = GetNObservables();
606 int nmeas = GetNMeasurements();
607 int nunc = GetNUncertainties();
610 ofi <<
"Summary of the combination" << std::endl;
611 ofi <<
"==========================" << std::endl << std::endl;
613 ofi <<
"* Observables:" << std::endl;
614 ofi <<
" Observable (range): " << std::endl;
615 for (
int i = 0; i < nobs; ++i)
616 ofi <<
" " << std::setiosflags(std::ios::left) << GetParameter(i)->GetName()
617 <<
" (" << GetParameter(i)->GetLowerLimit() <<
" - " << GetParameter(i)->GetUpperLimit() <<
")" << std::endl;
620 ofi <<
"* Measurements:" << std::endl;
621 ofi <<
" Measurement (observable): central value +- total uncertainty" << std::endl;
622 for (
int i = 0; i < nmeas; ++i) {
624 if (m->GetFlagActive()) {
626 for (
int j = 0; j < nunc; ++j) {
627 if (GetUncertainty(j)->GetFlagActive())
628 total2+=m->GetUncertainty(j)*m->GetUncertainty(j);
630 ofi <<
" " << std::setiosflags(std::ios::left) << std::setw(20) << m->GetName()
631 << std::setiosflags(std::ios::left) <<
" (" << GetParameter(m->GetObservable())->
GetName() <<
")"
632 <<
": " << std::setiosflags(std::ios::left) << std::setw(7) << std::setprecision(4) << m->GetCentralValue()
633 <<
" +- " << std::setiosflags(std::ios::left) << std::setw(7) << std::setprecision(4) << sqrt(total2) << std::endl;
638 ofi <<
"* Uncertainties:" << std::endl;
639 ofi <<
" Measurement (observable): Uncertainty (";
640 for (
int j = 0; j < nunc-1; ++j )
641 if (GetUncertainty(j)->GetFlagActive())
642 ofi << GetUncertainty(j)->GetName() <<
", ";
643 if (GetUncertainty(nunc-1)->GetFlagActive())
644 ofi << GetUncertainty(nunc-1)->GetName() <<
")" << std::endl;
646 ofi <<
")" << std::endl;
648 for (
int i = 0; i < nmeas; ++i) {
650 if (m->GetFlagActive()) {
651 ofi <<
" " << std::setiosflags(std::ios::left) << std::setw(20) << m->GetName()
652 << std::setiosflags(std::ios::left) <<
" (" << GetParameter(m->GetObservable())->
GetName() <<
"): ";
653 for (
int j = 0; j < nunc; ++j )
654 if (GetUncertainty(j)->GetFlagActive())
655 ofi << std::setiosflags(std::ios::left) << std::setw(7) << m->GetUncertainty(j);
661 for (
int i = 0; i < nunc; ++i) {
664 if (!u->GetFlagActive())
667 ofi <<
" " << u->GetName() <<
" " <<
"(correlation matrix)" << std::endl;
668 TMatrixD mat = u->GetCorrelationMatrix();
671 for (
int k = 0; k < nmeas; ++k) {
675 if (!mk->GetFlagActive())
681 for (
int j = 0; j < nmeas; ++j) {
684 if (mj->GetFlagActive()) {
685 ofi << std::setw(7) << std::showpos << mat[k][j] <<
" ";
689 ofi << std::noshowpos << std::endl;
695 ofi <<
"* BLUE results: " << std::endl;
696 ofi <<
" Observable: estimate +- total uncertainty" << std::endl;
697 for (
int i = 0; i < nobs; ++i) {
698 if (i < fBLUECentral.GetNoElements())
699 ofi <<
" " << GetParameter(i)->GetName() <<
": " << fBLUECentral[i] <<
" +- " << std::setprecision(4) << fBLUEUncertainties[i] << std::endl;
703 ofi <<
" Observable: Uncertainty (";
704 for (
int j = 0; j < nunc-1; ++j )
705 if (GetUncertainty(j)->GetFlagActive())
706 ofi << GetUncertainty(j)->GetName() <<
", ";
707 if (GetUncertainty(nunc-1)->GetFlagActive())
708 ofi << GetUncertainty(nunc-1)->GetName() <<
")" << std::endl;
710 ofi <<
")" << std::endl;
712 for (
int i = 0; i < nobs; ++i) {
713 ofi <<
" " << std::setiosflags(std::ios::left) << GetParameter(i)->GetName()<<
":";
715 for (
int j = 0; j < nunc; ++j )
716 if (GetUncertainty(j)->GetFlagActive()) {
717 ofi <<
" " << std::setiosflags(std::ios::left) << std::setw(7) << std::setprecision(4) << GetBLUEUncertainties(counterj)[i];
725 ofi <<
" Individual correlation matrices " << std::endl;
726 for (
int i = 0; i < nunc; ++i) {
727 if (GetUncertainty(i)->GetFlagActive()) {
728 TMatrixD mat = GetBLUECorrelationMatrix(i);
729 ofi <<
" " << GetUncertainty(i)->GetName() << std::endl;
730 for (
int j = 0; j < nobs; ++j) {
732 for (
int k = 0; k < nobs; ++k) {
733 ofi << std::setw(7) << std::setprecision(4) << std::showpos << mat[j][k] <<
" ";
735 ofi << std::noshowpos << std::endl;
743 ofi <<
" Overall correlation matrix" << std::endl;
744 TMatrixD mat = fBLUECorrelationMatrix;
745 for (
int j = 0; j < nobs; ++j) {
747 for (
int k = 0; k < nobs; ++k)
748 ofi << std::setw(7) << std::setprecision(4) << std::showpos << mat[j][k] <<
" ";
749 ofi << std::noshowpos << std::endl;
754 ofi <<
" Weights [%]:" <<std::endl;
756 for (
int j = 0; j < nmeas; ++j) {
757 if (GetMeasurement(j)->GetFlagActive()) {
758 ofi <<
" " << std::setw(20) << GetMeasurement(j)->GetName() <<
" : ";
759 for (
int k = 0; k < nobs; ++k)
760 ofi << std::setw(7) << std::setprecision(4) << std::showpos << fBLUEWeights[k][counter]*100. <<
" ";
772 void BCMVCombination::PrintMatrix(TMatrixD &matrix, std::string name)
774 int nrows = matrix.GetNrows();
775 int ncols = matrix.GetNcols();
777 std::cout << std::endl;
778 std::cout << name.c_str() <<
" (" << nrows <<
"x" << ncols <<
"):" << std::endl;
780 for (
int i = 0; i < nrows; ++i) {
781 for (
int j = 0; j < ncols; ++j)
782 std::cout << std::setprecision(3) << std::setw(7) << matrix[i][j] <<
" ";
783 std::cout << std::endl;
788 void BCMVCombination::PrintVector(TVectorD &vector, std::string name)
790 int nrows = vector.GetNoElements();
792 std::cout << std::endl;
793 std::cout << name.c_str() <<
" (" << nrows <<
"):" << std::endl;
795 for (
int i = 0; i < nrows; ++i) {
796 std::cout << std::setprecision(3) << std::setw(7) << vector[i] <<
" ";
797 std::cout << std::endl;
802 int BCMVCombination::GetIndexMeasurement(std::string measurement, std::string observable)
804 int index_observable = GetIndexObservable(observable);
806 int nmeasurements = GetNMeasurements();
808 for (
int i = 0; i < nmeasurements; ++i) {
809 if ((measurement == GetMeasurement(i)->
GetName()) && (index_observable == GetMeasurement(i)->GetObservable()))
817 int BCMVCombination::GetIndexUncertainty(std::string name)
819 int nuncertainties = GetNUncertainties();
823 for (
int i = 0; i < nuncertainties; ++i) {
824 if (name == GetUncertainty(i)->
GetName())
832 int BCMVCombination::GetIndexObservable(std::string name)
834 int n = GetNObservables();
837 for (
int i = 0; i < n; ++i) {
839 if (name == std::string(fObservables.at(i)->GetName()))
int SetPriorGauss(int index, double mean, double sigma)
The base class for all user-defined models.
double LogLikelihood(const std::vector< double > ¶meters)
virtual int AddParameter(BCParameter *parameter)
int SetPriorConstant(int index)
const std::string & GetName() const