00001
00002
00003
00004
00005
00007
00008 #include "NCFitMaster.h"
00009
00010 #include "NCUtils/Extrapolation/NCExtrapolation.h"
00011
00012 #include "MessageService/MsgService.h"
00013
00014 #include "TCanvas.h"
00015 #include "TDirectory.h"
00016 #include "TLegend.h"
00017 #include "TMarker.h"
00018 #include "TStopwatch.h"
00019
00020 CVSID("$Id: NCFitMaster.cxx,v 1.21 2009/06/18 18:12:22 bckhouse Exp $");
00021
00022
00023 using namespace std;
00024 using namespace NC::Fitter;
00025
00026
00027 namespace NC{
00033 class GetChiSqrFromDerived: public ICallableND
00034 {
00035 public:
00036 GetChiSqrFromDerived(){}
00037 GetChiSqrFromDerived(NCExtrapolation* P,
00038 std::vector<NCParameter> pars,
00039 bool penalty,
00040 bool analyticNorm)
00041 :p(P), params(pars), usePenalty(penalty),
00042 fAnalyticNormalization(analyticNorm){}
00043 virtual ~GetChiSqrFromDerived(){}
00044 double EvalAtEx(const CoordNDim& r, CoordNDim* ret) const;
00045 void UsePenalty(bool p){usePenalty = p;}
00046 void DrawAndWriteGraph() const;
00047 private:
00048 NCExtrapolation* p;
00049
00050 static std::map<CoordNDim, double> cache;
00051 std::vector<NCParameter> params;
00052 bool usePenalty;
00053 bool fAnalyticNormalization;
00054 static std::vector<CoordNDim> evaledAt;
00055 static std::vector<double> chisqRets;
00056 };
00057 }
00058
00059
00060 map<CoordNDim, double> NC::GetChiSqrFromDerived::cache;
00061 vector<CoordNDim> NC::GetChiSqrFromDerived::evaledAt;
00062 vector<double> NC::GetChiSqrFromDerived::chisqRets;
00063
00064
00065 double NC::GetChiSqrFromDerived::EvalAtEx(const CoordNDim& r,
00066 CoordNDim* retCoord) const
00067 {
00068 if(retCoord) *retCoord = r;
00069
00070 evaledAt.push_back(r);
00071
00072 const map<CoordNDim, double>::const_iterator it = cache.find(r);
00073 if(it != cache.end()){
00074
00075 chisqRets.push_back(it->second);
00076 return it->second;
00077 }
00078
00079 const unsigned int maxCacheSize = int(1e7);
00080 if(cache.size() > maxCacheSize) cache.clear();
00081
00082
00083 CoordNDim evalAt = r;
00084
00085 if(usePenalty){
00086
00087 for(unsigned int n = 0; n < params.size(); ++n){
00088 if(params[n].UseLimits()){
00089 if(r[n] < params[n].Min()) evalAt[n] = params[n].Min();
00090 if(r[n] > params[n].Max()) evalAt[n] = params[n].Max();
00091 }
00092 }
00093 }
00094
00095 const CoordinateConverter* cc = p->GetCoordConv();
00096 NC::OscProb::OscPars* oscPars = cc->OscParsFromCoordNDim(evalAt);
00097
00098 double norm = 1;
00099 double ret = p->FindChiSqrForPars(oscPars,
00100 cc->SystParsFromCoordNDim(evalAt),
00101 fAnalyticNormalization ? &norm : 0);
00102
00103
00104
00105 delete oscPars;
00106
00107 if(usePenalty){
00108
00109
00110 const double amplitude = 1e3;
00111 for(unsigned int n = 0; n < params.size(); ++n){
00112 if(params[n].UseLimits()){
00113 const double wsqr = (params[n].Min()-params[n].Max())*(params[n].Min()-params[n].Max());
00114 assert(wsqr);
00115 if(r[n] < params[n].Min())
00116 ret += amplitude*(params[n].Min()-r[n])*(params[n].Min()-r[n])/wsqr;
00117 if(r[n] > params[n].Max())
00118 ret += amplitude*(r[n]-params[n].Max())*(r[n]-params[n].Max())/wsqr;
00119 }
00120 }
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130 chisqRets.push_back(ret);
00131
00132 return ret;
00133 }
00134
00135
00136 void NC::GetChiSqrFromDerived::DrawAndWriteGraph() const
00137 {
00138 TCanvas c("minimizer_eval_positions");
00139 TH2D axes("", "Evaluation Positions;time;", 100, 0, evaledAt.size(), 100, -1, 5);
00140 axes.Draw();
00141 for(unsigned int m = 0; m < evaledAt[0].size(); ++m){
00142 TGraph* g = new TGraph;
00143 g->Set(evaledAt.size());
00144 g->SetMarkerColor(m+1);
00145 for(unsigned int n = 0; n < evaledAt.size(); ++n){
00146 g->SetPoint(n, n, evaledAt[n][m]);
00147 g->Draw("p same");
00148 }
00149 }
00150
00151 c.Write();
00152 }
00153
00154
00155
00156 NC::FitMaster::FitMaster(NCExtrapolation* child)
00157 : fExtrap(child), fBestFitOscPars(0), fFixedValsForMarg(0)
00158 {
00159
00160 vector<string> names;
00161 names.push_back("theta23");
00162 names.push_back("theta");
00163 names.push_back("umu3");
00164 vector<double> poss;
00165 poss.push_back(TMath::Pi()/4);
00166 poss.push_back(TMath::Pi()/4);
00167 poss.push_back(0.5);
00168 NC::Fitter::MinFinderSimple::SetSpacePartitions(names, poss);
00169 }
00170
00171
00172
00173 const Registry& NC::FitMaster::DefaultConfig()
00174 {
00175 static Registry r;
00176
00177 r.UnLockValues();
00178
00179
00180 r.Set("LazyContoursUseMinuit", 0);
00181
00182 r.Set("LazyContoursWant68", true);
00183 r.Set("LazyContoursWant90", true);
00184 r.Set("LazyContoursWant99", true);
00185 r.Set("AllowBestFitOutsideRange", false);
00186 r.Set("AllowContoursOutsideRange", false);
00187 r.Set("WantMinimum", true);
00188 r.Set("Want2DProjections", false);
00189 r.Set("WantGridSearch", false);
00190 r.Set("WantSlices", false);
00191 r.Set("Want2DSlices", false);
00192 r.Set("WantCovarianceMatrix", false);
00193 r.Set("TryPreviousMinimum", false);
00194 r.Set("ForceBestFitToTruth", false);
00195 r.Set("PrecScale", 1.0);
00196 r.Set("AnalyticNormalization", false);
00197 r.Set("ContoursList", "");
00198 r.Set("ProjectionsList", "");
00199
00200 r.Merge(NC::CoordinateConverter::DefaultConfig());
00201
00202 r.LockValues();
00203
00204 return r;
00205 }
00206
00207
00208
00209 void NC::FitMaster::Prepare(const Registry& r)
00210 {
00211 MSG("NCFitMaster", Msg::kInfo) << "NC::FitMaster::Prepare(const Registry& r)" << endl;
00212
00213 int tmpb;
00214 int tmpi;
00215 double tmpd;
00216 const char* tmps;
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 if(r.Get("LazyContoursUseMinuit", tmpi)) fContourMethod = tmpi;
00244 if(r.Get("LazyContoursWant68", tmpb)) fWant68 = tmpb;
00245 if(r.Get("LazyContoursWant90", tmpb)) fWant90 = tmpb;
00246 if(r.Get("LazyContoursWant99", tmpb)) fWant99 = tmpb;
00247 if(r.Get("WantMinimum", tmpb)) fWantMinimum = tmpb;
00248 if(r.Get("Want2DProjections", tmpb)) fWant2DProjections = tmpb;
00249 if(r.Get("WantGridSearch", tmpb)) fWantGridSearch = tmpb;
00250 if(r.Get("WantSlices", tmpb)) fWantSlices = tmpb;
00251 if(r.Get("Want2DSlices", tmpb)) fWant2DSlices = tmpb;
00252 if(r.Get("WantCovarianceMatrix", tmpb)) fWantCovariance = tmpb;
00253 if(r.Get("AllowBestFitOutsideRange", tmpb)) fAllowBestFitOutsideRange = tmpb;
00254 if(r.Get("AllowContoursOutsideRange", tmpb)) fAllowContoursOutsideRange = tmpb;
00255 if(r.Get("TryPreviousMinimum", tmpb)) fTryPreviousMinimum = tmpb;
00256 if(r.Get("ForceBestFitToTruth", tmpb)) fForceBestFitToTruth = tmpb;
00257 if(r.Get("PrecScale", tmpd)) fPrecScale = tmpd;
00258
00259 if(r.Get("AnalyticNormalization", tmpb)) fAnalyticNormalization = tmpb;
00260
00261 fCoordConv.Prepare(r);
00262
00263 if(r.Get("ContoursList", tmps)){
00264 vector<int> xs, ys;
00265 ParseContourList(tmps, xs, ys);
00266 fXaxes.clear(); fYaxes.clear();
00267 for(unsigned int n = 0; n < xs.size(); ++n){
00268 fXaxes.push_back(NCType::EFitParam(xs[n]));
00269 fYaxes.push_back(NCType::EFitParam(ys[n]));
00270 }
00271 }
00272
00273 if(r.Get("ProjectionsList", tmps)){
00274 const vector<int> pl = NC::Utility::ParseNumberList(tmps);
00275 for(unsigned int n = 0; n < pl.size(); ++n)
00276 fProjectionsList.push_back(NCType::EFitParam(pl[n]));
00277 }
00278 }
00279
00280
00281
00282 void NC::FitMaster::Run(const NC::OscProb::OscPars* trueOscPars)
00283 {
00284 assert(fXaxes.size() == fYaxes.size());
00285
00286 assert(fContourMethod == 0 || fContourMethod == 1 || fContourMethod == 2);
00287
00288
00289
00290
00291 GetChiSqrFromDerived chiSqrFunc(fExtrap, fCoordConv.fFitParams, !fAllowBestFitOutsideRange, fAnalyticNormalization);
00292
00293 TMinuit* minu;
00294
00295
00296
00297 if((fWantMinimum ||
00298 fWant68 || fWant90 || fWant99 ||
00299 !fProjectionsList.empty() ||
00300 fWantSlices || fWant2DSlices) &&
00301 !fForceBestFitToTruth){
00302 MSG("NCFitMaster", Msg::kInfo) << "Begin fit..." << endl;
00303
00304 TStopwatch fit_sw;
00305
00306 if(fContourMethod == 0){
00307 vector<NCParameter> preciseParams = fCoordConv.fFitParams;
00308 for(unsigned int n = 0; n < preciseParams.size(); ++n)
00309 preciseParams[n].SetPrecision(preciseParams[n].Precision()/100);
00310
00311 MinFinderSimple mf(preciseParams,
00312 !fAllowBestFitOutsideRange,
00313 fTryPreviousMinimum,
00314 &chiSqrFunc);
00315 fMinChiSqr = mf.FindMin(fMinCoord, true);
00316
00317 if(fWantCovariance){
00318 MSG("NCFitMaster", Msg::kInfo)
00319 << "Finding covariance matrix using finite differences...\n";
00320 FindCovarianceMatrix(&chiSqrFunc, fMinCoord, preciseParams).Print();
00321 }
00322 }
00323 if(fContourMethod == 1 || fContourMethod == 2){
00324 fMinChiSqr = MinFinderMinuit(&chiSqrFunc, fCoordConv.fFitParams, fMinCoord, &minu);
00325 if(fWantCovariance){
00326 MSG("NCFitMaster", Msg::kInfo)
00327 << "Printing Minuit covariance matrix...\n";
00328 minu->mnmatu(1);
00329 }
00330 }
00331
00332 MSG("NCFitMaster", Msg::kInfo) << endl << "Best fit - chisq = "
00333 << fMinChiSqr << endl;
00334
00335 for(unsigned int n = 0; n < fCoordConv.fFitParams.size(); ++n){
00336 MSG("NCFitMaster", Msg::kInfo) << " "
00337 << fCoordConv.fFitParams[n].ShortName()
00338 << " = " << fMinCoord[n] << endl;
00339 }
00340 MSG("NCFitMaster", Msg::kInfo) << endl;
00341
00342
00343 SetBestFitCoordNDim(fMinCoord);
00344 fExtrap->SetBestFitCoordNDim(fMinCoord);
00345
00346 MSG("NCFitMaster", Msg::kInfo) << "Fit took ";
00347 fit_sw.Print("m");
00348 }
00349
00350
00351 if(fForceBestFitToTruth){
00352 MSG("NCFitMaster", Msg::kInfo) << "Forcing best fit point to be "
00353 << "input truth point" << endl;
00354 assert(trueOscPars);
00355 fMinCoord = fCoordConv.CoordNDimFromOscPars(trueOscPars);
00356
00357 SetBestFitCoordNDim(fMinCoord);
00358 fExtrap->SetBestFitCoordNDim(fMinCoord);
00359 }
00360
00361
00362 if(fFixedValsForMarg) MargWithFixedVals(&chiSqrFunc);
00363
00364
00365
00366 chiSqrFunc.UsePenalty(!fAllowContoursOutsideRange);
00367
00368
00369
00370
00371
00372 if(fWant68 || fWant90 || fWant99){
00373 TStopwatch cont_sw;
00374
00375
00376 const double contVals[] = {2.30, 4.61, 9.21};
00377
00378 for(int conf = 0; conf < 3; ++conf){
00379 for(unsigned int axisPair = 0; axisPair < fXaxes.size(); ++axisPair){
00380 if(conf == 0 && !fWant68) continue;
00381 if(conf == 1 && !fWant90) continue;
00382 if(conf == 2 && !fWant99) continue;
00383
00384
00385 const NCType::EFitParam x = fXaxes[axisPair];
00386 const NCType::EFitParam y = fYaxes[axisPair];
00387
00388 const NCParameter xPar = fCoordConv.ParameterForFitParam(x);
00389 const NCParameter yPar = fCoordConv.ParameterForFitParam(y);
00390
00391 MSG("NCFitMaster", Msg::kInfo) << "Building contour in "
00392 << xPar.ShortName()
00393 << " and " << yPar.ShortName()
00394 << " (up = " << contVals[conf] << ")..."
00395 << endl;
00396
00397 if(fContourMethod == 2){
00398 fContourGraphs.push_back(GetContourMinuit(minu, x, y, contVals[conf]));
00399 delete minu;
00400 }
00401 else{
00402 vector<TGraph> marg_graphs;
00403 vector<Coord> contour = GetContour(&chiSqrFunc,
00404 fCoordConv.fFitParams,
00405 x, y, contVals[conf],
00406 marg_graphs);
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 TGraph* g = new TGraph(contour.size());
00427 for(unsigned int n = 0; n < contour.size(); ++n)
00428 g->SetPoint(n, contour[n].x, contour[n].y);
00429 fContourGraphs.push_back(g);
00430
00431 MSG("NCFitMaster", Msg::kInfo) << "\nthere are " << contour.size()
00432 << " points on this contour" << endl;
00433 }
00434 }
00435 }
00436
00437 MSG("NCFitMaster", Msg::kInfo) << "Contours took ";
00438 cont_sw.Print("m");
00439 }
00440
00441
00442
00443
00444 if(fWant2DProjections){
00445 for(unsigned int axisPair = 0; axisPair < fXaxes.size(); ++axisPair){
00446
00447 const NCType::EFitParam x = fXaxes[axisPair];
00448 const NCType::EFitParam y = fYaxes[axisPair];
00449
00450 vector<NCParameter> lowResParams = fCoordConv.fFitParams;
00451 for(unsigned int n = 0; n < lowResParams.size(); ++n)
00452 lowResParams[n].SetPrecision(lowResParams[n].Precision()*10);
00453
00454 const NCParameter xPar = fCoordConv.ParameterForFitParam(x);
00455 const NCParameter yPar = fCoordConv.ParameterForFitParam(y);
00456
00457 TH2D* grid = Get2DGrid(&chiSqrFunc, lowResParams, x, y);
00458
00459 grid->SetName(("grid_"+xPar.ShortName()+"-"+yPar.ShortName()).c_str());
00460 grid->SetTitle(("Grid;"+xPar.LatexName()+";"+yPar.LatexName()).c_str());
00461 fLowResGrids.push_back(grid);
00462 }
00463 }
00464
00465
00466 if(!fProjectionsList.empty()){
00467 TStopwatch proj_sw;
00468
00469 for(unsigned int nAxis = 0; nAxis < fProjectionsList.size(); ++nAxis){
00470 const NCType::EFitParam x = fProjectionsList[nAxis];
00471
00472 const NCParameter xPar = fCoordConv.ParameterForFitParam(x);
00473
00474 MSG("NCFitMaster", Msg::kInfo) << "Building 1D projection in "
00475 << xPar.ShortName() << "..." << endl;
00476
00477 double leftErr, rightErr;
00478 vector<TGraph> marg_graphs;
00479
00480
00481 vector<NCParameter> pars = fCoordConv.fFitParams;
00482 for(unsigned int n = 0; n < pars.size(); ++n){
00483 if(n != UInt_t(x)) pars[n].SetPrecision(pars[n].Precision()/10);
00484 }
00485
00486 TGraph* proj = Get1DProjection(&chiSqrFunc, pars, x,
00487 leftErr, rightErr, marg_graphs);
00488
00489 const double bestFit1D = fMinCoord[fCoordConv.FitterIndex(x)];
00490
00491 MSG("NCFitMaster", Msg::kInfo)
00492 << "Asymmetric errors in " << xPar.ShortName()
00493 << " " << leftErr-bestFit1D << " "
00494 << rightErr-bestFit1D << endl;
00495
00496 fOneSigmaErrors[xPar.ShortName()] =
00497 pair<double, double>(bestFit1D-leftErr, rightErr-bestFit1D);
00498
00499 proj->SetName(("projection_"+xPar.ShortName()).c_str());
00500 proj->GetHistogram()->SetTitle((";"+xPar.LatexName()+";#chi^{2}").c_str());
00501 fChiSqGraphs.push_back(proj);
00502
00503
00504 marg_graphs[0].SetName(TString::Format("%s", xPar.ShortName().c_str()));
00505 unsigned int m = 0;
00506 for(unsigned int n = 0; n < marg_graphs.size(); ++n, ++m){
00507 if(m == UInt_t(x)) ++m;
00508 marg_graphs[n].SetTitle(fCoordConv.ParameterForFitterIndex(m).LatexName().c_str());
00509 }
00510 fMarginalGraphs1D.push_back(marg_graphs);
00511
00512 }
00513
00514 MSG("NCFitMaster", Msg::kInfo) << "Projections took ";
00515 proj_sw.Print("m");
00516 }
00517
00518
00519 if(fWantGridSearch){
00520
00521
00522
00523
00524
00525
00526 PrintGridSearch(&chiSqrFunc, fCoordConv.fFitParams, cout);
00527 }
00528
00529 if(fWantSlices){
00530 MSG("NCFitMaster", Msg::kInfo) << "Starting slices" << endl;
00531 fSlices = MakeSlices(&chiSqrFunc, fCoordConv.fFitParams, fMinCoord);
00532 }
00533
00534 if(fWant2DSlices)
00535 f2DSlices = Make2DSlices(&chiSqrFunc, fCoordConv.fFitParams, fMinCoord);
00536
00537
00538
00539
00540 }
00541
00542
00543
00544 void NC::FitMaster::WriteResources()
00545 {
00546 MSG("NCFitMaster", Msg::kInfo)
00547 << "NC::FitMaster::WriteResources() - "
00548 << fExtrap->GetShortName() << endl;
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 gDirectory->mkdir("fit", "fit")->cd();
00559
00560 GetBestFitPointAsRegistry()->Write();
00561 if(!fContourGraphs.empty()) DrawAndWriteContourGraphs();
00562 if(!fChiSqGraphs.empty()) DrawAndWriteChiSqGraphs();
00563 if(!fLowResGrids.empty()) DrawAndWriteLowResGrids();
00564 if(!fSlices.empty()) DrawAndWriteSlices();
00565 if(!f2DSlices.empty()) DrawAndWrite2DSlices();
00566 }
00567
00568
00569
00570 void NC::FitMaster::ParseContourList(TString contList,
00571 vector<int>& xs, vector<int>& ys) const
00572 {
00573 const int p1 = contList.First('(');
00574 const int p2 = contList.First(',');
00575 const int p3 = contList.First(')');
00576
00577
00578
00579 if(p1 < 0 || p2 < 0 || p3 < 0) return;
00580
00581
00582
00583 const TString strX = contList(p1+1, p2-p1-1);
00584 const TString strY = contList(p2+1, p3-p2-1);
00585
00586
00587 assert(strX.IsDigit());
00588 assert(strY.IsDigit());
00589
00590 xs.push_back(strX.Atoi());
00591 ys.push_back(strY.Atoi());
00592
00593
00594 const TString remain = contList(p3+1, contList.Length()-p3);
00595 ParseContourList(remain, xs, ys);
00596 }
00597
00598
00599
00600 vector<NCType::EFitParam> NC::FitMaster::GetUniqueAxes() const
00601 {
00602 vector<NCType::EFitParam> ret;
00603
00604 for(unsigned int n = 0; n < fXaxes.size(); ++n){
00605 const NCType::EFitParam ax = fXaxes[n];
00606 bool add = true;
00607 for(unsigned int m = 0; m < ret.size(); ++m){
00608 if(ret[m] == ax) add = false;
00609 }
00610 if(add) ret.push_back(ax);
00611 }
00612 for(unsigned int n = 0; n < fYaxes.size(); ++n){
00613 const NCType::EFitParam ax = fYaxes[n];
00614 bool add = true;
00615 for(unsigned int m = 0; m < ret.size(); ++m){
00616 if(ret[m] == ax) add = false;
00617 }
00618 if(add) ret.push_back(ax);
00619 }
00620
00621 return ret;
00622 }
00623
00624
00625
00626 vector<Coord> NC::FitMaster::GetContour(ICallableND* chiSqrFunc,
00627 const vector<NCParameter>& params,
00628 NCType::EFitParam x,
00629 NCType::EFitParam y,
00630 double up,
00631 vector<TGraph>& marg_graphs)
00632 {
00633 const int xi = fCoordConv.FitterIndex(x);
00634 const int yi = fCoordConv.FitterIndex(y);
00635
00636 const NCParameter xp = fCoordConv.ParameterForFitParam(x);
00637 const NCParameter yp = fCoordConv.ParameterForFitParam(y);
00638
00639 if(fContourMethod == 0){
00640 MarginalizeSimple func(chiSqrFunc, params, fTryPreviousMinimum,
00641 xi, yi);
00642 return FindContour(&func,
00643 Coord(fMinCoord[xi], fMinCoord[yi]),
00644 fMinChiSqr+up,
00645 Coord(xp.Precision(), yp.Precision()),
00646 &marg_graphs);
00647 }
00648
00649 if(fContourMethod == 1){
00650 MarginalizeHybrid func(chiSqrFunc, params, fTryPreviousMinimum, x, y);
00651 return FindContour(&func,
00652 Coord(fMinCoord[xi], fMinCoord[yi]),
00653 fMinChiSqr+up,
00654 Coord(xp.Precision(), yp.Precision()),
00655 &marg_graphs);
00656 }
00657
00658 assert(0 && "This should never happen");
00659 }
00660
00661
00662
00663 TGraph* NC::FitMaster::GetContourMinuit(TMinuit* minu,
00664 NCType::EFitParam x,
00665 NCType::EFitParam y, double up)
00666 {
00667 const int numContourPoints = 300;
00668 minu->SetErrorDef(up);
00669 TGraph* g = (TGraph*)minu->Contour(numContourPoints,
00670 fCoordConv.FitterIndex(x),
00671 fCoordConv.FitterIndex(y));
00672 if(minu->GetStatus()) MSG("NCExtrapolation", Msg::kWarning) << "Couldn't find contour.\n";
00673 return g;
00674 }
00675
00676
00677
00678 TH2D* NC::FitMaster::Get2DGrid(ICallableND* chiSqrFunc,
00679 const vector<NCParameter>& params,
00680 NCType::EFitParam x, NCType::EFitParam y)
00681 {
00682 const int xi = fCoordConv.FitterIndex(x);
00683 const int yi = fCoordConv.FitterIndex(y);
00684
00685 const NCParameter xp = fCoordConv.ParameterForFitParam(x);
00686 const NCParameter yp = fCoordConv.ParameterForFitParam(y);
00687
00688 if(fContourMethod == 0){
00689 MarginalizeSimple func(chiSqrFunc, params, fTryPreviousMinimum, xi, yi);
00690 return GetLowResGrid(&func,
00691 Coord(xp.Min(), yp.Min()),
00692 Coord(xp.Max(), yp.Max()),
00693 Coord(xp.Precision(), yp.Precision()));
00694 }
00695
00696 if(fContourMethod == 1 || fContourMethod == 2){
00697 MarginalizeHybrid func(chiSqrFunc, params, fTryPreviousMinimum, xi, yi);
00698 return GetLowResGrid(&func,
00699 Coord(xp.Min(), yp.Min()),
00700 Coord(xp.Max(), yp.Max()),
00701 Coord(xp.Precision(), yp.Precision()));
00702 }
00703
00704 assert(0 && "This should never happen");
00705 }
00706
00707
00708
00709 TGraph* NC::FitMaster::Get1DProjection(ICallableND* chiSqrFunc,
00710 const vector<NCParameter>& params,
00711 NCType::EFitParam x,
00712 double& leftErr,
00713 double& rightErr,
00714 vector<TGraph>& marg_graphs)
00715 {
00716 const int xi = fCoordConv.FitterIndex(x);
00717 const NCParameter xp = fCoordConv.ParameterForFitParam(x);
00718
00719 if(fContourMethod == 0){
00720 MarginalizeSimple func(chiSqrFunc, params, fTryPreviousMinimum, xi, -1);
00721 return CreateOneDimProjection(&func, xp, fMinChiSqr, leftErr, rightErr, marg_graphs);
00722 }
00723
00724 if(fContourMethod == 1 || fContourMethod == 2){
00725 MarginalizeHybrid func(chiSqrFunc, params, fTryPreviousMinimum, xi, -1);
00726 return CreateOneDimProjection(&func, xp, fMinChiSqr, leftErr, rightErr, marg_graphs);
00727 }
00728
00729 assert(0 && "This should never happen");
00730 }
00731
00732
00733
00734 Registry* NC::FitMaster::GetBestFitPointAsRegistry() const
00735 {
00736 Registry* rBestFit = new Registry;
00737 rBestFit->SetName("bestFit_registry");
00738 rBestFit->UnLockKeys();
00739 rBestFit->UnLockValues();
00740
00741 for(unsigned int n = 0; n < fMinCoord.size(); ++n){
00742 rBestFit->Set(fCoordConv.ParameterForFitterIndex(n).ShortName().c_str(),
00743 fMinCoord[n]);
00744 }
00745
00746 rBestFit->Set("best_chisq", fMinChiSqr);
00747
00748 for(OneSigmaErrors::const_iterator it = fOneSigmaErrors.begin();
00749 it != fOneSigmaErrors.end(); ++it){
00750 const string name = it->first;
00751 const double lo = it->second.first;
00752 const double hi = it->second.second;
00753 rBestFit->Set((name+"_one_sigma_up").c_str(), lo);
00754 rBestFit->Set((name+"_one_sigma_down").c_str(), hi);
00755 }
00756
00757 for(ChisqMargWithFixed::const_iterator it = fChisqsMargWithFixed.begin();
00758 it != fChisqsMargWithFixed.end(); ++it){
00759 const string name = it->first;
00760 const double chisq = it->second;
00761 rBestFit->Set(("chisq_marg_"+name+"_fixed").c_str(), chisq);
00762 }
00763
00764 return rBestFit;
00765 }
00766
00767
00768
00769 void NC::FitMaster::
00770 SetFixedValuesForMarginalization(const NC::OscProb::OscPars* pars)
00771 {
00772 fFixedValsForMarg = pars;
00773 }
00774
00775
00776
00777 void NC::FitMaster::MargWithFixedVals(const ICallableND* chiSqrFunc)
00778 {
00779 TStopwatch sw;
00780
00781 const vector<NCType::EFitParam> axes = GetUniqueAxes();
00782
00783 for(unsigned int nAxis = 0; nAxis < axes.size(); ++nAxis){
00784 const NCType::EFitParam x = axes[nAxis];
00785
00786 const NCParameter xPar = fCoordConv.ParameterForFitParam(x);
00787
00788 const int fixIndex = fCoordConv.FitterIndex(x);
00789 CoordNDim fix = fCoordConv.CoordNDimFromOscPars(fFixedValsForMarg);
00790 vector<int> vary;
00791 for(unsigned int n = 0; n < fix.size(); ++n){
00792 if(int(n) != fixIndex) vary.push_back(n);
00793 }
00794 FixVars fv(chiSqrFunc, fix, vary);
00795
00796 vector<NCParameter> pars;
00797 for(unsigned int n = 0; n < fCoordConv.fFitParams.size(); ++n){
00798 if(int(n) != fixIndex) pars.push_back(fCoordConv.fFitParams[n]);
00799 }
00800
00801 for(unsigned int n = 0; n < pars.size(); ++n){
00802 pars[n].SetPrecision(pars[n].Precision()/10);
00803 }
00804
00805 MinFinderSimple mf(pars, false, false, &fv);
00806
00807 MSG("NCFitMaster", Msg::kInfo) << "Holding " << xPar.ShortName()
00808 << " fixed at " << fix[fixIndex]
00809 << " while marginalizing over other"
00810 << " parameters..." << endl;
00811
00812 CoordNDim junk;
00813 const double chisq = mf.FindMin(junk);
00814
00815 fChisqsMargWithFixed[xPar.ShortName()] = chisq;
00816 }
00817
00818 MSG("NCFitMaster", Msg::kInfo) << "Marginalizations took ";
00819 sw.Print("m");
00820 }
00821
00822
00823
00824 void NC::FitMaster::DrawAndWriteContourGraphs()
00825 {
00826 assert(fXaxes.size() == fYaxes.size());
00827 for(unsigned int n = 0; n < fXaxes.size(); ++n){
00828 const NCParameter xPar = fCoordConv.ParameterForFitParam(fXaxes[n]);
00829 const NCParameter yPar = fCoordConv.ParameterForFitParam(fYaxes[n]);
00830
00831 const TString canvasName = "contours_"+xPar.ShortName()+"_"+yPar.ShortName();
00832
00833 const double xBest = fMinCoord[fCoordConv.FitterIndex(fXaxes[n])];
00834 const double yBest = fMinCoord[fCoordConv.FitterIndex(fYaxes[n])];
00835
00836 TLegend leg(0.75, 0.75, 0.95, 0.95);
00837 leg.SetBorderSize(0);
00838
00839 TCanvas canv(canvasName);
00840 TH2* forceAxes = fCoordConv.AxesForParameters("", "", fXaxes[n], fYaxes[n]);
00841 forceAxes->SetDirectory(0);
00842 forceAxes->GetXaxis()->CenterTitle();
00843 forceAxes->GetYaxis()->CenterTitle();
00844 forceAxes->Draw();
00845 int trueconf = 0;
00846 for(int conf = 0; conf < 3; ++conf){
00847 if(conf == 0 && !fWant68) continue;
00848 if(conf == 1 && !fWant90) continue;
00849 if(conf == 2 && !fWant99) continue;
00850 TGraph* contGraph = fContourGraphs[trueconf*fXaxes.size()+n];
00851 if(contGraph && contGraph->GetN() > 0){
00852 const TString confText = (conf == 0) ? "68" : ( (conf == 1) ? "90" : "99");
00853 leg.AddEntry(contGraph, confText+"% Confidence Level", "l");
00854 contGraph->SetName(canvasName+confText+"Graph");
00855 contGraph->Draw("l");
00856 gDirectory->Append(contGraph);
00857 }
00858 ++trueconf;
00859 }
00860
00861 TMarker bestFit(xBest, yBest, kFullStar);
00862 bestFit.SetMarkerSize(2);
00863 bestFit.SetMarkerColor(kBlack);
00864 bestFit.Draw("p same");
00865
00866 leg.AddEntry(&bestFit, "Best Fit Point", "p");
00867 leg.Draw();
00868
00869 canv.Write();
00870 }
00871
00872 for(unsigned int n = 0; n < fMarginalGraphs.size(); ++n){
00873 vector<TGraph>& gs = fMarginalGraphs[n];
00874 if(gs.empty()) continue;
00875 TCanvas c(TString::Format("marg_vars_%s_canv", gs[0].GetName()).Data());
00876
00877 double maxx = 0;
00878 for(unsigned int i = 0; i < gs.size(); ++i){
00879 double x, y;
00880 gs[i].GetPoint(gs[i].GetN()-1, x, y);
00881 if(x > maxx) maxx = x;
00882 }
00883
00884 TH2D h("h", "Marginalized variables",
00885 100, 0, maxx, 100, -2, 4.5);
00886 h.Draw();
00887 TLegend l(.5, .6, .85, .85);
00888 l.SetBorderSize(0);
00889 for(unsigned int m = 0; m < gs.size(); ++m){
00890 TGraph& g = gs[m];
00891 g.SetName(TString::Format("marg_graph_%d_%d", n, m).Data());
00892 g.SetMarkerStyle(kFullCircle);
00893 g.SetLineColor(1+m/4);
00894 g.SetMarkerColor(1+m/4);
00895 g.Draw("same lp");
00896 if(m%4==0) l.AddEntry(&g, "", "lp");
00897
00898 }
00899 l.Draw();
00900 c.Write();
00901 }
00902 }
00903
00904
00905
00906 void NC::FitMaster::DrawAndWriteChiSqGraphs()
00907 {
00908 for(unsigned int n = 0; n < fChiSqGraphs.size(); ++n){
00909 TGraph* graph = fChiSqGraphs[n];
00910
00911 TCanvas* canv = new TCanvas(TString::Format("canv_%s", graph->GetName()));
00912
00913 graph->GetXaxis()->CenterTitle();
00914
00915 TAxis* yax = graph->GetYaxis();
00916 yax->CenterTitle();
00917 graph->Draw("al");
00918 const double ymax = yax->GetXmax();
00919 yax->SetRangeUser(0, ymax < 20 ? ymax : 20);
00920
00921 canv->Write();
00922 graph->Write();
00923 }
00924
00925 for(unsigned int n = 0; n < fMarginalGraphs1D.size(); ++n){
00926 vector<TGraph>& gs = fMarginalGraphs1D[n];
00927 if(gs.empty()) continue;
00928 TCanvas c(TString::Format("marg_vars_%s_canv", gs[0].GetName()).Data());
00929
00930 double minx, maxx, y;
00931 gs[0].GetPoint(0, minx, y);
00932 gs[0].GetPoint(gs[0].GetN()-1, maxx, y);
00933
00934 TH2D h("h", "Marginalized variables",
00935 100, minx, maxx, 100, -2, 4.5);
00936 h.Draw();
00937 TLegend l(.5, .6, .85, .85);
00938 l.SetBorderSize(0);
00939 for(unsigned int m = 0; m < gs.size(); ++m){
00940 TGraph& g = gs[m];
00941 g.SetName(TString::Format("marg_graph_%d_%d", n, m).Data());
00942 g.SetMarkerStyle(kFullCircle);
00943 g.SetLineColor(1+m);
00944 g.SetMarkerColor(1+m);
00945 g.Draw("same lp");
00946 l.AddEntry(&g, "", "lp");
00947 }
00948 l.Draw();
00949 c.Write();
00950 }
00951 }
00952
00953
00954
00955 void NC::FitMaster::DrawAndWriteLowResGrids()
00956 {
00957 for(unsigned int n = 0; n < fLowResGrids.size(); ++n){
00958 TString name = "canv";
00959 name += fLowResGrids[n]->GetName();
00960 TCanvas* canv = new TCanvas(name);
00961 fLowResGrids[n]->Draw("colz");
00962 canv->Write();
00963 fLowResGrids[n]->Write();
00964 }
00965 }
00966
00967
00968
00969 void NC::FitMaster::DrawAndWriteSlices()
00970 {
00971 for(unsigned int n = 0; n < fSlices.size(); ++n){
00972 TGraph& graph = fSlices[n];
00973
00974 TCanvas* canv = new TCanvas(TString::Format("canv_%s", graph.GetName()));
00975
00976 graph.GetXaxis()->CenterTitle();
00977
00978 TAxis* yax = graph.GetYaxis();
00979 yax->CenterTitle();
00980 graph.Draw("al");
00981
00982
00983 yax->SetRangeUser(fMinChiSqr, fMinChiSqr+20);
00984
00985 canv->Write();
00986 graph.Write();
00987 }
00988 }
00989
00990
00991 void NC::FitMaster::DrawAndWrite2DSlices()
00992 {
00993 for(unsigned int n = 0; n < f2DSlices.size(); ++n){
00994 TH2D* h = f2DSlices[n];
00995
00996 TCanvas* canv = new TCanvas(TString::Format("canv_%s", h->GetName()));
00997
00998 h->GetXaxis()->CenterTitle();
00999 h->GetYaxis()->CenterTitle();
01000
01001 h->Draw("colz");
01002
01003 canv->Write();
01004 h->Write();
01005 }
01006 }