00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include "NCUtils/Extrapolation/NCExtrapolation.h"
00012 #include "NCUtils/Extrapolation/NCSpectrumInterpolator.h"
00013 #include "NCUtils/NCOscProb.h"
00014 #include "NCUtils/NCUtility.h"
00015
00016 #include "MessageService/MsgService.h"
00017
00018 #include "AnalysisNtuples/ANtpAnalysisInfo.h"
00019 #include "AnalysisNtuples/ANtpBeamInfo.h"
00020 #include "AnalysisNtuples/ANtpRecoInfo.h"
00021 #include "AnalysisNtuples/ANtpHeaderInfo.h"
00022
00023 #include "Conventions/Detector.h"
00024
00025 #include "TCanvas.h"
00026 #include "TGraphErrors.h"
00027 #include "TGraph.h"
00028 #include "TObjArray.h"
00029 #include "TLine.h"
00030 #include "TList.h"
00031 #include "TLegend.h"
00032 #include "TMath.h"
00033 #include "TMarker.h"
00034 #include "TROOT.h"
00035 #include "TStopwatch.h"
00036
00037 #include <cassert>
00038 #include <fstream>
00039
00040 using namespace NCType;
00041 using NC::Utility::SQR;
00042
00043 CVSID("$Id: NCExtrapolation.cxx,v 1.273 2009/12/18 01:30:21 rodriges Exp $");
00044
00045
00046 NCExtrapolation::~NCExtrapolation()
00047 {
00048 if(fBestFitOscPars) delete fBestFitOscPars;
00049
00050 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it)
00051 delete it->second;
00052
00053
00054 for(InterpCache_t::iterator it = fInterpCache.begin();
00055 it != fInterpCache.end(); ++it){
00056 delete it->first;
00057 delete it->second;
00058 }
00059 }
00060
00061
00062 const Registry& NCExtrapolation::DefaultConfig()
00063 {
00064 static Registry r;
00065
00066 r.UnLockValues();
00067
00068 r.Set("EnergyThreshold", 0);
00069
00070 r.Set("UseCCEvents", true);
00071 r.Set("UseNCEvents", true);
00072 r.Set("Prediction", false);
00073 r.Set("PredictionWriteData", false);
00074
00075 r.Set("PrintFDEvents", false);
00076 r.Set("HideFDData", false);
00077
00078 r.Set("DoSystematicInterpolation", false);
00079 r.Set("DisableSystPenalty", false);
00080 r.Set("AddEventsToEnergyBins", true);
00081
00082 r.LockValues();
00083 return r;
00084 }
00085
00086
00087
00088
00089
00090
00091 void NCExtrapolation::Prepare(const Registry& r)
00092 {
00093 MSG("NCExtrapolation", Msg::kInfo) << "NCExtrapolation::Prepare(const Registry& r)"
00094 << endl;
00095 int tmpb;
00096 int tmpi;
00097 double tmpd;
00098
00099 if(r.Get("OscillationModel", tmpi)) fOscillationModel = NCType::EOscModel(tmpi);
00100
00101 if(r.Get("EnergyThreshold", tmpd)) fEnergyThreshold = tmpd;
00102
00103 if(r.Get("UseCCEvents", tmpb)) fUseCC = tmpb;
00104 if(r.Get("UseNCEvents", tmpb)) fUseNC = tmpb;
00105
00106 fCoordConv.Prepare(r);
00107
00108 if(r.Get("PrintFDEvents", tmpb)) fPrintFDEvents = tmpb;
00109 if(r.Get("HideFDData", tmpb)) fHideFDData = tmpb;
00110
00111 if(r.Get("DoSystematicInterpolation", tmpb))
00112 fDoSystematicInterpolation = tmpb;
00113
00114 if(r.Get("DisableSystPenalty", tmpb)) fUseSystPenalty = !tmpb;
00115
00116 if(r.Get("AddEventsToEnergyBins", tmpb)) fAddEventsToEnergyBins = tmpb;
00117 }
00118
00119
00120
00121 void NCExtrapolation::AddEvent(NCEventInfo info,
00122 bool useMCAsData,
00123 NCType::EFileType fileType,
00124 NCBeam::Info beamInfo)
00125 {
00126
00127
00128
00129
00130 if(info.reco->inFiducialVolume < 1 ||
00131 (info.header->detector == int(Detector::kNear) &&
00132 info.reco->isSimpleCutsClean < 1)
00133 )
00134 return;
00135
00136
00137 if(info.reco->nuEnergy < fEnergyThreshold) return;
00138
00139
00140
00141
00142
00143 Detector::Detector_t detector = Detector::Detector_t(info.header->detector);
00144
00145 NCBeam* beam = GetBeam(detector, beamInfo, true);
00146
00147 beam->AddEvent(info.header, info.beam, info.reco,
00148 info.analysis, info.truth, useMCAsData, fileType);
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 if(fPrintFDEvents && detector == Detector::kFar &&
00167 info.header->dataType == int(SimFlag::kData)){
00168
00169 static bool once=true;
00170 if(once){
00171 once=false;
00172 MsgService::Instance()->GetStream("DataEventListAll")->AttachOStream(Msg::kInfo,"ncutils_events_all.txt");
00173
00174 MsgService::Instance()->GetStream("DataEventListCC")->AttachOStream(Msg::kInfo,"ncutils_events_cc.txt");
00175
00176 MsgService::Instance()->GetStream("DataEventListNC")->AttachOStream(Msg::kInfo,"ncutils_events_nc.txt");
00177 }
00178 TString stream = "";
00179 TString date = TString::Format("%d-%02d ", info.header->year, info.header->month);
00180 TString run = TString::Format("F000%d", info.header->run);
00181
00182 if(info.analysis->isNC < 1 && info.analysis->isCC > 0) stream = "DataEventListCC";
00183 if(info.analysis->isNC > 0 && info.analysis->isCC < 1) stream = "DataEventListNC";
00184
00185 if(stream!="")
00186 MSG(stream, Msg::kInfo)
00187 << date
00188 << run << " " << info.header->subRun
00189 << " " << info.header->snarl
00190 << " " << info.reco->nuEnergy
00191 << " " << info.analysis->isCC
00192 << " " << info.analysis->isNC << endl;
00193
00194 MSG("DataEventListAll", Msg::kInfo)
00195 << date
00196 << run << " " << info.header->subRun
00197 << " " << info.header->snarl
00198 << " " << info.reco->nuEnergy
00199 << " " << info.analysis->isCC
00200 << " " << info.analysis->isNC << endl;
00201
00202 }
00203 }
00204
00205
00206
00207 void NCExtrapolation::DrawBestFitSpectra(Detector::Detector_t det)
00208 {
00209 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00210 NCBeam* beam = it->second;
00211 if(beam->GetDetector() != det) continue;
00212
00213 TString name = "bestFitSpectraCanv"+GetShortName();
00214 name += Detector::AsString(det);
00215 name += beam->GetInfo().GetDescription();
00216 TCanvas *canv = new TCanvas(name, name, 150, 10, 1200, 300);
00217 TPad *pad1 = new TPad(name+"pad1", "", 0.00, 0.0, 0.50, 1.0, 10);
00218 TPad *pad2 = new TPad(name+"pad2", "", 0.50, 0.0, 1.00, 1.0, 10);
00219 pad1->Draw();
00220 pad2->Draw();
00221 pad1->cd();
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 for(NCType::EEventType i = NCType::kNC;
00235 i <= NCType::kCC;
00236 i = NCType::EEventType(int(i)+1)){
00237 if(i == NCType::kCC) pad2->cd();
00238
00239 double maxY = 1.3*TMath::Max(beam->GetMCHistogram(i)->GetMaximum(),
00240 beam->GetDataGraph(i)->GetHistogram()->GetMaximum());
00241
00242 beam->GetMCHistogram(i)->SetMaximum(maxY);
00243 TString title = Detector::AsString(det);
00244 if(i == NCType::kNC)
00245 title += " Detector Neutral Current Selected";
00246 else
00247 title += " Detector Charged Current Selected";
00248 beam->GetMCHistogram(i)->SetTitle(title);
00249 beam->GetMCHistogram(i)->Draw();
00250
00251 if(beam->GetMCFitHistogram(i)->Integral() > 0.){
00252 beam->GetMCFitHistogram(i)->Draw("same");
00253 beam->GetMCBackgroundHistogram(i)->Draw("same");
00254 beam->GetMCFitNuMuToNuTauHistogram(i)->Draw("same");
00255 beam->GetMCFitNuEToNuEHistogram(i)->Draw("same");
00256 beam->GetMCFitNuMuToNuEHistogram(i)->Draw("same");
00257 }
00258 else{
00259
00260 beam->GetMCNoFitBackgroundHistogram(i)->Draw("same");
00261 beam->GetMCNoFitNuEToNuEHistogram(i)->Draw("same");
00262 }
00263
00264
00265
00266 beam->GetMCHistogram(i)->GetXaxis()->SetRangeUser(0, 19.9);
00267
00268
00269
00270
00271
00272 if(!fHideFDData || beam->GetDetector() != Detector::kFar){
00273 beam->GetDataGraph(i)->Draw("pe1same");
00274 }
00275
00276 TLegend *leg = new TLegend(0.45, 0.65, 0.85, 0.85);
00277 leg->SetBorderSize(0);
00278 leg->AddEntry(beam->GetDataGraph(i), "Data", "lep");
00279 leg->AddEntry(beam->GetMCHistogram(i),
00280 "Monte Carlo (Nominal)", "l");
00281 if(beam->GetMCFitHistogram(i)->Integral() > 0.){
00282 leg->AddEntry(beam->GetMCFitHistogram(i),
00283 "Monte Carlo (Best Fit)", "l");
00284 leg->AddEntry(beam->GetMCBackgroundHistogram(i),
00285 "Background", "bf");
00286 leg->AddEntry(beam->GetMCFitNuMuToNuTauHistogram(i),
00287 "Background - #nu_{#tau} CC", "bf");
00288 leg->AddEntry(beam->GetMCFitNuEToNuEHistogram(i),
00289 "Background - Beam #nu_{e} CC", "bf");
00290 leg->AddEntry(beam->GetMCFitNuMuToNuEHistogram(i),
00291 "Background - #nu_{e} CC", "bf");
00292 }
00293 else{
00294 leg->AddEntry(beam->GetMCNoFitBackgroundHistogram(i),
00295 "Background", "bf");
00296 leg->AddEntry(beam->GetMCNoFitNuEToNuEHistogram(i),
00297 "Background - Beam #nu_{e} CC", "bf");
00298 }
00299
00300
00301
00302
00303 leg->Draw();
00304
00305 }
00306
00307
00308 canv->Update();
00309
00310
00311
00312 gDirectory->Append(canv);
00313
00314 }
00315 }
00316
00317
00318
00319 void NCExtrapolation::DrawBestFitRatios(Detector::Detector_t det)
00320 {
00321 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00322 NCBeam* beam = it->second;
00323 if(beam->GetDetector() != det) continue;
00324
00325 TString name = "bestFitRatiosCanv"+GetShortName();
00326 name += Detector::AsString(det);
00327 name += beam->GetInfo().GetDescription();
00328 TCanvas *canv = new TCanvas(name, name, 150, 10, 1200, 300);
00329 TPad *pad1 = new TPad(name+"pad1", "", 0.00, 0.0, 0.50, 1.0, 10);
00330 TPad *pad2 = new TPad(name+"pad2", "", 0.50, 0.0, 1.00, 1.0, 10);
00331 pad1->Draw();
00332 pad2->Draw();
00333 pad1->cd();
00334
00335 for(NCType::EEventType i = NCType::kNC;
00336 i <= NCType::kCC;
00337 i = NCType::EEventType(int(i)+1)){
00338 if(i == NCType::kCC) pad2->cd();
00339
00340 TString title = Detector::AsString(det);
00341 if(i == NCType::kNC)
00342 title += " Detector Neutral Current Selected";
00343 else
00344 title += " Detector Charged Current Selected";
00345
00346 TH1* mc_ratio = (TH1*)beam->GetMCFitHistogram(i)->Clone();
00347 TH1* mc_hist = (TH1*)beam->GetMCHistogram(i)->Clone();
00349 mc_ratio->Divide(mc_hist);
00350
00351 mc_ratio->SetTitle(title);
00352 mc_ratio->GetYaxis()->SetRangeUser(0, 1.5);
00353 mc_ratio->GetYaxis()->SetTitle("Ratio to no oscillations");
00354 mc_ratio->Draw("][");
00355
00356
00357
00358
00359
00360 TGraphAsymmErrors* data_ratio = 0;
00361
00362 if(!fHideFDData || beam->GetDetector() != Detector::kFar){
00363 data_ratio = (TGraphAsymmErrors*)beam->GetDataGraph(i)->Clone();
00364
00365 for(int n = 0; n < data_ratio->GetN(); ++n){
00366 double x, y;
00367 data_ratio->GetPoint(n, x, y);
00368 double hi = y+data_ratio->GetErrorYhigh(n);
00369 double lo = y-data_ratio->GetErrorYlow(n);
00370 double div = mc_hist->GetBinContent(mc_hist->FindBin(x));
00371 if(div == 0){
00372 div = 1;
00373 x = -1;
00374 }
00375 y /= div; hi /= div; lo /= div;
00376 data_ratio->SetPoint(n, x, y);
00377 data_ratio->SetPointEYhigh(n, hi-y);
00378 data_ratio->SetPointEYlow(n, y-lo);
00379 }
00380
00381 data_ratio->Draw("pe1same");
00382 }
00383
00384 TLine* one = new TLine(0, 1, mc_ratio->GetXaxis()->GetXmax(), 1);
00385 one->SetLineStyle(7);
00386 one->Draw("same");
00387
00388
00389 TLegend* leg = new TLegend(0.45, 0.35, 0.85, 0.15);
00390 leg->SetBorderSize(0);
00391 if(data_ratio) leg->AddEntry(data_ratio, "Data", "l");
00392 leg->AddEntry(mc_ratio, "Best Fit", "l");
00393
00394 leg->Draw();
00395
00396 }
00397
00398 canv->Update();
00399
00400
00401
00402 gDirectory->Append(canv);
00403
00404 }
00405 }
00406
00407
00408
00409 void IgnoreErrors(int, Bool_t, const char*, const char*){}
00410
00411
00412
00413 void NCExtrapolation::WriteResources(const NC::OscProb::OscPars* )
00414 {
00415 MSG("NCExtrapolation", Msg::kInfo)
00416 << "NCExtrapolation::WriteResources() - "
00417 << GetShortName() << endl;
00418
00419
00420 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it)
00421 FillResultHistograms(it->second);
00422
00423
00424
00425 TDirectory* saveDir = gDirectory;
00426
00427 TDirectory* beamsDir = gDirectory->mkdir("beams", "beams");
00428 beamsDir->cd();
00429
00430
00431
00432 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00433 NCBeam* beam = it->second;
00434 TString dirName = beam->GetInfo().GetDescription();
00435
00436
00437
00438
00439 ErrorHandlerFunc_t handler = GetErrorHandler();
00440 SetErrorHandler(IgnoreErrors);
00441 if(!beamsDir->cd(dirName)) beamsDir->mkdir(dirName)->cd();
00442 SetErrorHandler(handler);
00443
00444 beam->MakeResultPlots();
00445 if(fHideFDData && beam->GetDetector() == Detector::kFar)
00446 beam->WritePredictionResources();
00447 else
00448 beam->WriteResources();
00449
00450 }
00451
00452 saveDir->cd();
00453
00454 DrawBestFitSpectra(Detector::kNear);
00455 DrawBestFitSpectra(Detector::kFar);
00456
00457 DrawBestFitRatios(Detector::kNear);
00458 DrawBestFitRatios(Detector::kFar);
00459
00460
00461 if(fInterpolator){
00462 TDirectory* saveDir = gDirectory;
00463 gDirectory->mkdir("interp")->cd();
00464 fInterpolator->WriteResources();
00465 saveDir->cd();
00466 }
00467
00468
00469 saveDir->cd();
00470 }
00471
00472
00473
00474
00475 NCBeam* NCExtrapolation::GetBeam(Detector::Detector_t det,
00476 NCBeam::Info beamInfo,
00477 bool add)
00478
00479 {
00480 pair<NCBeam::Info, Detector::Detector_t> key(beamInfo, det);
00481 fBeams_t::iterator it = fBeams.find(key);
00482 if(it != fBeams.end()) return it->second;
00483
00484 if(!add) return 0;
00485
00486 NCBeam* beam = new NCBeam(det, beamInfo, fUseCC, fUseNC, fAddEventsToEnergyBins);
00487 fBeams[key] = beam;
00488
00489 MSG("NCExtrapolation", Msg::kInfo) << "adding new beam "
00490 << beamInfo.GetDescription()
00491 << " to "
00492 << Detector::AsString(det)
00493 << endl;
00494
00495 return beam;
00496 }
00497
00498
00499
00500
00501
00502 void NCExtrapolation::FillResultHistograms(NCBeam* beam)
00503 {
00504 NC::OscProb::OscPars* oscPars = GetBestFitOscPars();
00505 if(!oscPars) return;
00506 const NC::SystPars systPars = GetBestFitSysts();
00507 beam->FillResultHistograms(oscPars, &systPars);
00508 }
00509
00510
00511 double NCExtrapolation::FindChiSqrForPars(const NC::OscProb::OscPars* oscPars,
00512 const NC::SystPars& systPars,
00513 double* analyticNorm)
00514 {
00515
00516
00517
00518 const bool addDirectoryRestore = TH1::AddDirectoryStatus();
00519 TH1::AddDirectory(false);
00520
00521
00522 vector<TH1*> exps, obss;
00523
00524
00525 std::vector<NCBeam::Info> beamsToUse;
00526 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00527 NCBeam* beam = it->second;
00528
00529
00530 if(beam->GetDetector() == Detector::kFar &&
00531 beam->GetRunType() != NC::RunUtil::kRunAll &&
00532 beam->GetInfo().IsNominal())
00533 beamsToUse.push_back(beam->GetInfo());
00534 }
00535
00536 FindSpectraForPars(oscPars, systPars, beamsToUse, exps, obss);
00537
00538
00539 if(analyticNorm){
00540 assert(exps.size() == obss.size());
00541 assert(exps.size() == 1);
00542 const double M = exps[0]->Integral();
00543 const double D = obss[0]->Integral();
00544
00545 *analyticNorm = CalculateBestNormalization(M, D);
00546
00547 exps[0]->Scale(*analyticNorm);
00548 }
00549
00550 const double ret = LogLikelihood(exps, obss)+
00551 (fUseSystPenalty ? systPars.PenaltyForShifts() : 0);
00552
00553 CleanupSpectra(exps, obss);
00554
00555
00556 TH1::AddDirectory(addDirectoryRestore);
00557
00558 return ret;
00559 }
00560
00561
00562
00563 void NCExtrapolation::SetBestFitCoordNDim(const NC::Fitter::CoordNDim minCoord)
00564 {
00565 fMinCoord = minCoord;
00566
00567 if(fBestFitOscPars) delete fBestFitOscPars;
00568
00569 fBestFitSysts = fCoordConv.SystParsFromCoordNDim(minCoord);
00570 fBestFitOscPars = fCoordConv.OscParsFromCoordNDim(minCoord);
00571 }
00572
00573
00574
00575 void NCExtrapolation::Reset(bool nearData, bool farData,
00576 bool nearMC, bool farMC)
00577 {
00578 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00579 NCBeam* beam = it->second;
00580 if(beam->GetDetector() == Detector::kFar){
00581 if(farData || farMC) beam->Reset(farData, farMC);
00582 }
00583 else{
00584 if(nearData || nearMC) beam->Reset(nearData, nearMC);
00585 }
00586 }
00587 }
00588
00589
00590
00591 void NCExtrapolation::CleanupSpectra(std::vector<TH1*> ,
00592 std::vector<TH1*> )
00593 {
00594
00595 }
00596
00597
00598
00599 double NCExtrapolation::LogLikelihood(const vector<TH1*>& exps,
00600 const vector<TH1*>& obss) const
00601 {
00602 assert(exps.size() == obss.size());
00603
00604
00605
00606
00607 const double minexp = 1e-40;
00608
00609 double chisqr = 0;
00610
00611 for(unsigned int n = 0; n < exps.size(); ++n){
00612 const int expssize = NC::Utility::GetArraySize(exps[n]);
00613 const int obsssize = NC::Utility::GetArraySize(obss[n]);
00614
00615 assert(expssize == obsssize);
00616
00617 for(int i = 0; i < expssize; ++i){
00618 double exp = exps[n]->GetBinContent(i);
00619 if(exp < minexp) exp = minexp;
00620
00621 const double obs = obss[n]->GetBinContent(i);
00622 assert(obs >= 0);
00623
00624 chisqr += 2*(exp-obs);
00625 if(obs) chisqr += 2*obs*log(obs/exp);
00626 }
00627 }
00628
00629 return chisqr;
00630 }
00631
00632
00633
00634 double NCExtrapolation::CalculateBestNormalization(double M, double D) const
00635 {
00636
00637 if(!fUseSystPenalty) return D/M;
00638
00639 const double sigmaSqr = SQR(NCType::kParams[kNormalization].sigma);
00640
00641 const double x = (1-sigmaSqr*M)/2;
00642
00643 return x + sqrt(SQR(x)+D*sigmaSqr);
00644 }
00645
00646
00647
00648 vector<double> NCExtrapolation::SystsAsSigmas(const NCBeam::Info& info,
00649 bool* simpleScale) const
00650 {
00651
00652
00653 bool shiftedVars[NCType::kNumSystematicParameters] = {false,};
00654 for(fBeams_t::const_iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00655 NCBeam* beam = it->second;
00656 for(int n = 0; n < NCType::kNumSystematicParameters; ++n){
00657 if(beam->GetInfo().IsShifted(NCType::EFitParam(n)))
00658 shiftedVars[n] = true;
00659 }
00660 }
00661
00662
00663
00664
00665
00666 if(simpleScale) *simpleScale = true;
00667
00668
00669 vector<double> shift;
00670 shift.reserve(NCType::kNumSystematicParameters);
00671 for(int n = 0; n < NCType::kNumSystematicParameters; ++n){
00672 if(shiftedVars[n]){
00673 double val;
00674 if(!info.IsShifted(NCType::EFitParam(n), &val)) val = 0;
00675 const double sigmas = val/NCType::kParams[n].sigma;
00676
00677 assert(sigmas == 0 || sigmas == 1 || sigmas == -1);
00678 shift.push_back(sigmas);
00679
00680 if(simpleScale &&
00681 sigmas != 0 &&
00682 n != NCType::kNormalization) *simpleScale = false;
00683
00684 }
00685 }
00686
00687 return shift;
00688 }
00689
00690
00691
00692 bool NCExtrapolation::EnableNearToFarExtrapolation(bool )
00693 {
00694 assert(0 && "EnableNearToFarExtrapolation needs to be overridden");
00695 }
00696
00697
00698
00699 vector<const TH1*> NCExtrapolation::
00700 GetNearMCSpectra(vector<NCBeam::Info> )
00701 {
00702 assert(0 && "GetNearMCSpectra needs to be overridden");
00703 }
00704
00705
00706
00707 void NCExtrapolation::InitializeInterpolator(const NC::OscProb::OscPars* osc)
00708 {
00709 assert(fDoSystematicInterpolation);
00710
00711 using namespace NC::Utility;
00712
00713
00714 static bool already = false;
00715 if(already) return;
00716 already = true;
00717
00718
00719
00720 if(fInterpCache.find(osc) != fInterpCache.end()){
00721 fInterpolator = fInterpCache[osc];
00722 already = false;
00723 return;
00724 }
00725
00726
00727 if(fInterpCache.size() > 100){
00728 const NC::OscProb::OscPars* oldKey = 0;
00729 for(InterpCache_t::iterator it = fInterpCache.begin();
00730 it != fInterpCache.end(); ++it){
00731 if(fInterpolator && it->second == fInterpolator) oldKey = it->first;
00732 if(it->second != fInterpolator){
00733 delete it->first;
00734 delete it->second;
00735 }
00736 }
00737 fInterpCache.clear();
00738 if(oldKey) fInterpCache[oldKey] = fInterpolator;
00739 }
00740
00741
00742 NC::ISpectrumInterpolator* oldInterp = fInterpolator;
00743 fInterpolator = 0;
00744
00745
00746 const bool farNearRestore = EnableNearToFarExtrapolation(false);
00747
00748
00749 vector<NCBeam::Info> allBeams;
00750 for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00751 const pair<NCBeam::Info, Detector::Detector_t> key = it->first;
00752 const NCBeam::Info info = key.first;
00753 const Detector::Detector_t det = key.second;
00754
00755
00756 if(info.GetRunType() == NC::RunUtil::kRunAll) continue;
00757
00758 if(det != Detector::kFar) continue;
00759
00760 allBeams.push_back(info);
00761 }
00762
00763
00764 vector<NCBeam::Info> beamsToUseNom;
00765 for(unsigned int n = 0; n < allBeams.size(); ++n){
00766 if(allBeams[n].IsNominal()) beamsToUseNom.push_back(allBeams[n]);
00767 }
00768
00769 vector<TH1*> junk;
00770 vector<TH1*> noms_fd;
00771 FindSpectraForPars(osc, NC::SystPars(), beamsToUseNom, noms_fd, junk);
00772
00773 vector<const TH1*> noms_nd = GetNearMCSpectra(beamsToUseNom);
00774
00775
00776
00777 vector<const TH1*> noms;
00778 assert(noms_nd.size() == noms_fd.size());
00779 noms.reserve(2*noms_fd.size());
00780 for(unsigned int n = 0; n < noms_fd.size(); ++n){
00781 noms.push_back(CloneFast(noms_fd[n]));
00782 noms.push_back(CloneFast(noms_nd[n]));
00783 }
00784
00785 CleanupSpectra(noms_fd, junk);
00786
00787
00788
00789 NC::ISpectrumInterpolator* interp = new NC::SpectrumInterpolatorSimplest;
00790
00791
00792
00793 map<vector<double>, bool> alreadyFilled;
00794
00795
00796 typedef map<vector<double>, vector<const TH1*> > ExpsMap;
00797 ExpsMap expsMap;
00798
00799 for(unsigned int beamIdx = 0; beamIdx < allBeams.size(); ++beamIdx){
00800 const NCBeam::Info info = allBeams[beamIdx];
00801
00802 bool simpleScale;
00803 const vector<double> shift = SystsAsSigmas(info, &simpleScale);
00804
00805
00806
00807 if(alreadyFilled[shift]) continue;
00808
00809 if(simpleScale && oldInterp){
00810
00811 vector<TH1*> ratios = oldInterp->GetInputSpectra(shift);
00812
00813 alreadyFilled[shift] = true;
00814 interp->AddInputSpectra(shift, ratios);
00815 continue;
00816 }
00817
00818 vector<NCBeam::Info> beamsToUse(1, info);
00819 vector<TH1*> exps_fd;
00820 FindSpectraForPars(osc, NC::SystPars(), beamsToUse, exps_fd, junk);
00821
00822 vector<const TH1*> exps_nd = GetNearMCSpectra(beamsToUse);
00823
00824 vector<const TH1*> exps;
00825 assert(exps_fd.size() == exps_nd.size());
00826 exps.reserve(2*exps_fd.size());
00827
00828
00829 for(unsigned int n = 0; n < exps_fd.size(); ++n){
00830 TH1* exp_fd = CloneFast(exps_fd[n]);
00831 exp_fd->SetName((info.GetDescription()+" FD").Data());
00832 exps.push_back(exp_fd);
00833
00834 TH1* exp_nd = CloneFast(exps_nd[n]);
00835 exp_nd->SetName((info.GetDescription()+" ND").Data());
00836 exps.push_back(exp_nd);
00837 }
00838
00839 CleanupSpectra(exps_fd, junk);
00840
00841
00842 vector<const TH1*>& already = expsMap[shift];
00843 already.insert(already.end(), exps.begin(), exps.end());
00844 }
00845
00846 for(ExpsMap::iterator it = expsMap.begin(); it != expsMap.end(); ++it){
00847 vector<double> shift = it->first;
00848 vector<const TH1*> exps = it->second;
00849
00850
00851 vector<TH1*> ratios;
00852 ratios.reserve(exps.size());
00853 assert(exps.size() == noms.size());
00854 for(unsigned int n = 0; n < exps.size(); ++n){
00855 ratios.push_back(CloneFast(exps[n]));
00856 DivideFast(ratios[n], noms[n]);
00857 }
00858 interp->AddInputSpectra(shift, ratios);
00859 }
00860
00861
00862 for(unsigned int n = 0; n < noms.size(); ++n) delete noms[n];
00863
00864
00865 EnableNearToFarExtrapolation(farNearRestore);
00866
00867
00868
00869 fInterpolator = interp;
00870
00871 assert(fInterpCache.find(osc) == fInterpCache.end());
00872 fInterpCache[const_cast<NC::OscProb::OscPars*>(osc)->Clone()] = fInterpolator;
00873
00874 already = false;
00875 }