00001 #include "NCUtils/Extrapolation/PIDSpectrum.h"
00002
00003 #include "NCUtils/Extrapolation/NCBeam.h"
00004 #include "NCUtils/NCUtility.h"
00005
00006 #include "TCanvas.h"
00007 #include "TLatex.h"
00008 #include "TMath.h"
00009 #include "TPad.h"
00010 #include "TStyle.h"
00011 #include "TLegend.h"
00012
00013 #include <cmath>
00014 #include <iostream>
00015 #include <algorithm>
00016
00017 using namespace std;
00018
00019 ClassImp(PIDSpectrum)
00020
00021 PIDSpectrum::PIDSpectrum(string _name, string _title,
00022 int _nPIDBins, double _PIDmin, double _PIDmax,
00023 int _trueBinFactor, NCBeam::Info _beamInfo,
00024 double _cutValue)
00025 : TNamed(_name, _title),
00026 fNumPIDBins(_nPIDBins),
00027 fPIDmin(_PIDmin), fPIDmax(_PIDmax),
00028 fTrueBinFactor(_trueBinFactor),
00029 fBeamInfo(_beamInfo),
00030 fCutValue(_cutValue)
00031 {
00032 fEvtTypes.push_back(kNC);
00033 fEvtTypes.push_back(kNumu);
00034 fEvtTypes.push_back(kBeamNue);
00035 fEvtTypes.push_back(kOscNue);
00036 fEvtTypes.push_back(kNutau);
00037
00038 fDrawColors.resize(fEvtTypes.size());
00039 fDrawColors[kNC]=kRed;
00040 fDrawColors[kNumu]=kBlue;
00041 fDrawColors[kBeamNue]=kGreen+2;
00042 fDrawColors[kOscNue]=kOrange-3;
00043 fDrawColors[kNutau]=kMagenta+2;
00044
00045
00046 Double_t* trueEBins=MultiplyBins(fTrueBinFactor, kNumEnergyBinsFar,
00047 kEnergyBinsFar);
00048 int nTrueEBins=kNumEnergyBinsFar*fTrueBinFactor;
00049
00050
00051
00052 if (fNumPIDBins==-1) {
00053
00054 fPIDBins=new Double_t[3];
00055 fPIDBins[0]=fPIDmin; fPIDBins[2]=fPIDmax;
00056 fPIDBins[1]=fCutValue;
00057
00058
00059 fNumPIDBins=2;
00060 } else {
00061 fPIDBins=new Double_t[fNumPIDBins+1];
00062 for (int i=0; i<fNumPIDBins+1; ++i)
00063 fPIDBins[i]=fPIDmin+float(i)*(fPIDmax-fPIDmin)/fNumPIDBins;
00064 }
00065
00066
00067 fNumBinEdgesDontUseThis=fNumPIDBins+1;
00068
00069 for (vector<evtType>::iterator it=fEvtTypes.begin(); it!=fEvtTypes.end(); ++it) {
00070 string tmp("hTrue");
00071 tmp+=GetName();
00072 tmp+=EvtTypeAsString(*it);
00073
00074 fCmpTrue[*it]=new TH2F(tmp.c_str(), "True energy spectrum;True Energy (GeV);PID",
00075 nTrueEBins, trueEBins,
00076 fNumPIDBins, fPIDBins);
00077 tmp="t2r_";
00078 tmp+=GetName();
00079 tmp+=EvtTypeAsString(*it);
00080
00081 fTrueToReco[*it]=new TH3F(tmp.c_str(), "True-to-reco;Reco Energy;PID;True energy",
00082 kNumEnergyBinsFar, kEnergyBinsFar,
00083 fNumPIDBins, fPIDBins,
00084 nTrueEBins, trueEBins);
00085 }
00086
00087 delete[] trueEBins;
00088
00089 string tmp("hData");
00090 tmp+=GetName();
00091
00092 fData=new TH2F(tmp.c_str(), "Far Data;Reco Energy;PID",
00093 kNumEnergyBinsFar, kEnergyBinsFar,
00094 fNumPIDBins, fPIDBins);
00095
00096 tmp="hNearMC";
00097 tmp+=GetName();
00098 fNearMC=new TH2F(tmp.c_str(), "Near MC;Reco Energy;PID",
00099 kNumEnergyBinsFar, kEnergyBinsFar,
00100 fNumPIDBins, fPIDBins);
00101
00102 tmp="hNearData";
00103 tmp+=GetName();
00104 fNearData=new TH2F(tmp.c_str(), "Near Data;Reco Energy;PID",
00105 kNumEnergyBinsFar, kEnergyBinsFar,
00106 fNumPIDBins, fPIDBins);
00107
00108 }
00109
00110
00111
00112 Double_t* PIDSpectrum::MultiplyBins(int factor, int nBinsOrig,
00113 const Double_t* origBins) const
00114 {
00115 Double_t* newBins=new Double_t[(nBinsOrig+1)*factor+2];
00116
00117 for (int iOrig=0; iOrig<nBinsOrig+1; ++iOrig) {
00118 for (int j=0; j<factor; ++j) {
00119 newBins[iOrig*factor+j]=origBins[iOrig]+
00120 float(j)/factor*(origBins[iOrig+1]-origBins[iOrig]);
00121 }
00122 }
00123
00124 return newBins;
00125 }
00126
00127
00128
00129 TH2F* PIDSpectrum::GetPredicted(const NC::OscProb::OscPars* coords,
00130 const char* histname,
00131 bool doFN,
00132 TH1* nearSpectrum) const
00133 {
00134 TH2F* pred=new TH2F(histname, "Predicted total",
00135 kNumEnergyBinsFar, kEnergyBinsFar,
00136 fNumPIDBins, fPIDBins);
00137 pred->SetDirectory(0);
00138
00139 for (vector<evtType>::const_iterator it=fEvtTypes.begin(); it!=fEvtTypes.end(); ++it) {
00140 AddOnePredicted(pred, *it, coords);
00141 }
00142
00143
00144
00145
00146
00147 pred->SetEntries(int(pred->Integral()));
00148
00149
00150 if (doFN)
00151 FarNearCorrect(pred, fNearData, nearSpectrum ? nearSpectrum : fNearMC);
00152
00153 return pred;
00154
00155 }
00156
00157
00158
00159 TH2F* PIDSpectrum::GetOnePredicted(evtType t,
00160 const NC::OscProb::OscPars* coords,
00161 const char* histname) const
00162 {
00163
00164 string tmp = GetName();
00165 tmp+="_pred";
00166 tmp+=histname ? histname : "";
00167 tmp+=EvtTypeAsString(t);
00168 TH2F* onePred=new TH2F(tmp.c_str(),
00169 Form("Predicted %s", EvtTypeAsString(t).c_str()),
00170 kNumEnergyBinsFar, kEnergyBinsFar,
00171 fNumPIDBins, fPIDBins);
00172
00173 AddOnePredicted(onePred, t, coords);
00174
00175 return onePred;
00176 }
00177
00178
00179
00180 void PIDSpectrum::AddOnePredicted(TH2F* onePred, evtType t, const NC::OscProb::OscPars* coords) const
00181 {
00182
00183 Double_t* trueEBins=MultiplyBins(fTrueBinFactor, kNumEnergyBinsFar,
00184 kEnergyBinsFar);
00185 const int nTrueEBins=kNumEnergyBinsFar*fTrueBinFactor;
00186
00187 TH1F* oscProb=GetOscWeightHist(t, coords, nTrueEBins, trueEBins);
00188 delete[] trueEBins;
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 TH3F* t2r=fTrueToReco.find(t)->second;
00210 TH2F* trueCmp=fCmpTrue.find(t)->second;
00211
00212
00213
00214
00215
00216
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
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 float* pt2r = t2r->fArray;
00255
00256 for(int iTrueE = 0; iTrueE <= nTrueEBins+1; ++iTrueE){
00257 const float oscWeight = oscProb->fArray[iTrueE];
00258
00259
00260 float* pOnePred = onePred->fArray;
00261
00262 for(int iPID=0; iPID <= fNumPIDBins+1; ++iPID){
00263
00264
00265
00266 const int trueE_PIDBin = iTrueE+(nTrueEBins+2)*iPID;
00267
00268 const float pidWeight = trueCmp->fArray[trueE_PIDBin];
00269 const float oscPidWeight = oscWeight * pidWeight;
00270
00271 for(int iRecoE = 0; iRecoE <= kNumEnergyBinsFar+1; ++iRecoE){
00272
00273 const float fillValue = (*pt2r)*oscPidWeight;
00274
00275 *pOnePred += fillValue;
00276
00277
00278 ++pt2r;
00279 ++pOnePred;
00280
00281 }
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 }
00294
00295
00296
00297 double PIDSpectrum::GetEventWeight(evtType t, double trueE,
00298 const NC::OscProb::OscPars* coords) const
00299 {
00300 switch (t) {
00301 case PIDSpectrum::kNC:
00302
00303
00304
00305
00306
00307
00308 return coords->TransitionProbability(NCType::kNuMuToNuMu,
00309 NCType::kNC,
00310 NCType::kBaseLineFar,
00311 trueE);
00312 break;
00313 case PIDSpectrum::kNumu:
00314 return coords->TransitionProbability(NCType::kNuMuToNuMu,
00315 NCType::kCC,
00316 NCType::kBaseLineFar,
00317 trueE);
00318 break;
00319 case PIDSpectrum::kBeamNue:
00320
00321
00322
00323
00324
00325 return 1.;
00326 break;
00327 case PIDSpectrum::kOscNue:
00328 return coords->TransitionProbability(NCType::kNuMuToNuE,
00329 NCType::kCC,
00330 NCType::kBaseLineFar,
00331 trueE);
00332 break;
00333 case PIDSpectrum::kNutau:
00334 return coords->TransitionProbability(NCType::kNuMuToNuTau,
00335 NCType::kCC,
00336 NCType::kBaseLineFar,
00337 trueE);
00338 break;
00339 default:
00340
00341 cerr << "GetOnePredicted got unknown evtType " << t << endl;
00342 assert(0);
00343 }
00344 }
00345
00346
00347
00348 TH1F* PIDSpectrum::GetOscWeightHist(evtType t,
00349 const NC::OscProb::OscPars* coords,
00350 int nBins, Double_t* binEdges) const
00351 {
00352
00353 static TH1F* oscProb=new TH1F("oscProb", "Oscillation probability", nBins, binEdges);
00354
00355
00356
00357
00358
00359
00360 for (int i=1; i<=oscProb->GetNbinsX()+1; ++i) {
00361
00362 double Emin=oscProb->GetXaxis()->GetBinLowEdge(i);
00363 double Emax=oscProb->GetXaxis()->GetBinUpEdge(i);
00364 double trueE=0.5*(Emin+Emax);
00365 oscProb->fArray[i] = GetEventWeight(t, trueE, coords);
00366 }
00367
00368 return oscProb;
00369 }
00370
00371
00372
00373 double PIDSpectrum::PIDWithinRange(double origPID) const
00374 {
00375 if(origPID>fPIDmax) return fPIDmax-1e-3;
00376 if(origPID<fPIDmin) return fPIDmin+1e-3;
00377 return origPID;
00378 }
00379
00380
00381
00382 void PIDSpectrum::FillMC(Detector::Detector_t det,
00383 const ANtpTruthInfoBeam* t,
00384 const ANtpRecoInfo* ,
00385 const ANtpAnalysisInfo* ana,
00386 double E, double scale)
00387 {
00388 evtType evt(GetEvtType(t));
00389
00390 double pidVal=PIDWithinRange(ana->separationParameter);
00391
00392
00393
00394
00395 E=std::min(E,kEnergyBinsFar[kNumEnergyBinsFar]-0.01);
00396
00397 if (det==Detector::kFar) {
00398 fCmpTrue[evt]->Fill(t->nuEnergy, pidVal, scale);
00399 fTrueToReco[evt]->Fill(E, pidVal, t->nuEnergy, scale);
00400 } else if (det==Detector::kNear) {
00401 fNearMC->Fill(E, pidVal, scale);
00402 } else {
00403 cout << "Unknown detector " << det << ". Bailing" << endl;
00404 exit(1);
00405 }
00406 }
00407
00408
00409
00410 void PIDSpectrum::FillData(Detector::Detector_t det,
00411 const ANtpTruthInfoBeam* ,
00412 const ANtpRecoInfo* ,
00413 const ANtpAnalysisInfo* ana,
00414 double E, double scale)
00415 {
00416
00417
00418
00419
00420 E=std::min(E,kEnergyBinsFar[kNumEnergyBinsFar]-0.01);
00421
00422 double pidVal=PIDWithinRange(ana->separationParameter);
00423 if (det==Detector::kFar) fData->Fill(E, pidVal, scale);
00424 else if (det==Detector::kNear) fNearData->Fill(E, pidVal, scale);
00425 else {
00426 cout << "Unknown detector " << det << ". Bailing" << endl;
00427 exit(1);
00428 }
00429 }
00430
00431
00432
00433 void PIDSpectrum::NormalizeTrueToRecos()
00434 {
00435
00436
00437
00438 for(vector<evtType>::iterator it = fEvtTypes.begin();
00439 it != fEvtTypes.end(); ++it){
00440 TH3F* t2r = fTrueToReco[*it];
00441 const int maxE = t2r->GetNbinsZ()+1;
00442
00443 for(int iTrueE = 1; iTrueE <= maxE; ++iTrueE){
00444 for(int iPID = 1; iPID <= fNumPIDBins; ++iPID){
00445
00446 float integral = 0;
00447 for(int iRecoE = 1; iRecoE <= kNumEnergyBinsFar; ++iRecoE){
00448 integral += t2r->GetBinContent(iRecoE, iPID, iTrueE);
00449 }
00450 if(integral == 0) integral = 1;
00451
00452 for(int iRecoE = 1; iRecoE <= kNumEnergyBinsFar; ++iRecoE){
00453 const float content = t2r->GetBinContent(iRecoE, iPID, iTrueE);
00454 t2r->SetBinContent(iRecoE, iPID, iTrueE, content/integral);
00455 }
00456
00457 }
00458 }
00459 }
00460 }
00461
00462
00463
00464 PIDSpectrum::evtType PIDSpectrum::GetEvtType(const ANtpTruthInfoBeam* t) const
00465 {
00466 if (t->interactionType==0) return kNC;
00467 else if (abs(t->nuFlavor)==14) return kNumu;
00468 else if (abs(t->nuFlavor)==12 && abs(t->nonOscNuFlavor)==12) return kBeamNue;
00469 else if (abs(t->nuFlavor)==12 && abs(t->nonOscNuFlavor)!=12) return kOscNue;
00470 else if (abs(t->nuFlavor)==16) return kNutau;
00471 else {
00472 cerr << "Unknown particle type " << t->nuFlavor << endl;
00473 assert(0);
00474 }
00475 }
00476
00477
00478
00479 string PIDSpectrum::EvtTypeAsString(evtType t) const
00480 {
00481
00482 switch (t) {
00483 case kNC:
00484 return "NC";
00485 case kNumu:
00486 return "NuMu";
00487 case kBeamNue:
00488 return "BeamNuE";
00489 case kOscNue:
00490 return "OscNuE";
00491 case kNutau:
00492 return "NuTau";
00493 default:
00494 cerr << "EvtTypeAsString got unknown evtType " << t << endl;
00495 return "Unknown";
00496 }
00497 }
00498
00499
00500
00501 TCanvas* PIDSpectrum::DrawSpectrum(const NC::OscProb::OscPars* coords,
00502 TH1* systratios,
00503 string suffix) const
00504 {
00505 TH2F* hPred=GetPredicted(coords, "total", false);
00506
00507 if (systratios) hPred->Multiply(systratios);
00508 string canName("can_");
00509 canName+=GetName();
00510 canName+=suffix;
00511 TCanvas *c = new TCanvas(canName.c_str(), GetTitle());
00512 c->Divide(2,2);
00513
00514 c->cd(1);
00515 hPred->DrawCopy("colz");
00516 TLatex* la=new TLatex;
00517 la->SetNDC();
00518 la->DrawLatex(0.2, 0.95, "Predicted");
00519
00520 c->cd(2);
00521 fData->DrawCopy("colz");
00522 la->DrawLatex(0.2, 0.95, "Data");
00523
00524 c->cd(3);
00525 TH2F* hRatio=(TH2F*)NC::Utility::CloneFast(fData);
00526 hRatio->SetName("ratio");
00527 hRatio->Divide(hPred);
00528 hRatio->Draw("colz");
00529 la->DrawLatex(0.2, 0.95, "Ratio");
00530
00531 c->cd(4);
00532 fCmpTrue.find(kNC)->second->DrawCopy("colz");
00533 la->DrawLatex(0.2, 0.95, "True NC true E");
00534
00535
00536
00537 return c;
00538 }
00539
00540
00541
00542 vector<TCanvas*> PIDSpectrum::DrawEnergySlices(const NC::OscProb::OscPars* coords,
00543 TH1* systratios,
00544 string suffix) const
00545 {
00546 return DrawSlices("energy", coords, systratios, suffix);
00547 }
00548
00549
00550
00551 vector<TCanvas*> PIDSpectrum::DrawPIDSlices(const NC::OscProb::OscPars* coords,
00552 TH1* systratios,
00553 string suffix) const
00554 {
00555 return DrawSlices("pid", coords, systratios, suffix);
00556 }
00557
00558
00559
00560 void PIDSpectrum::ResetMC()
00561 {
00562 typedef map<evtType, TH2F*>::iterator it2;
00563 for(it2 it = fCmpTrue.begin(); it != fCmpTrue.end(); ++it)
00564 it->second->Reset();
00565
00566 typedef map<evtType, TH3F*>::iterator it3;
00567 for(it3 it = fTrueToReco.begin(); it != fTrueToReco.end(); ++it)
00568 it->second->Reset();
00569 }
00570
00571
00572
00573 vector<TCanvas*> PIDSpectrum::DrawSlices(string variable,
00574 const NC::OscProb::OscPars* coords,
00575 TH1* systratios,
00576 string suffix) const
00577 {
00578
00579 assert(variable == "energy" || variable == "pid");
00580 bool energySlice=(variable=="energy");
00581
00582 vector<TCanvas*> v;
00583
00584
00585
00586
00587
00588 static int canvN=0;
00589 TCanvas* cTotal = new TCanvas((variable+"Total_"+suffix+fBeamInfo.GetDescription()+
00590 Form("_%d", canvN)));
00591
00592 TCanvas* cSlices = new TCanvas((variable+"Slices_"+suffix+fBeamInfo.GetDescription()+
00593 Form("_%d", canvN)));
00594 ++canvN;
00595
00596 v.push_back(cTotal); v.push_back(cSlices);
00597
00598 cSlices->cd();
00599 int nPlots = energySlice ? fNumPIDBins : kNumEnergyBinsFar;
00600 int nDiv = (int)TMath::Ceil(TMath::Sqrt(nPlots));
00601
00602
00603 if ((nDiv-1)*nDiv>=nPlots)
00604 cSlices->Divide(nDiv-1, nDiv);
00605 else if ((nDiv+1)*(nDiv-1)>=nPlots)
00606 cSlices->Divide(nDiv-1, nDiv+1);
00607 else
00608 cSlices->Divide(nDiv, nDiv);
00609
00610 TH2F* hTotal=GetPredicted(coords, "total", false);
00611 if (systratios) hTotal->Multiply(systratios);
00612
00613
00614 hTotal->SetTitle("Best fit");
00615 NC::OscProb::NoOscillations oscParsNoOsc;
00616 TH2F* hNoOsc=GetPredicted(&oscParsNoOsc, "noosc", false);
00617 hNoOsc->SetTitle("No Oscillations");
00618
00619 map<evtType, TH2F*> cmpHists;
00620
00621 for (vector<evtType>::const_iterator it=fEvtTypes.begin();
00622 it!=fEvtTypes.end(); ++it) {
00623
00624 if (*it==kNC) continue;
00625 cmpHists[*it]=GetOnePredicted(*it, coords, (variable+"Slices_"+suffix).c_str());
00626 cmpHists[*it]->SetLineColor(fDrawColors[*it]);
00627 }
00628
00629 hTotal->SetLineColor(kRed);
00630 hNoOsc->SetLineColor(kRed); hNoOsc->SetLineStyle(2);
00631 fData->SetLineColor(kBlack);
00632
00633
00634 gStyle->SetOptStat(0);
00635
00636
00637 cTotal->cd();
00638 TH1F* noOsc1D=(TH1F*)ProjectHist(hNoOsc, variable, "NoOsc")->DrawCopy();
00639 noOsc1D->SetLineStyle(2);
00640 if (energySlice) noOsc1D->GetXaxis()->SetRangeUser(0,19.9);
00641 ProjectHist(hTotal, variable, "Total")->DrawCopy("same");
00642
00643 for (vector<evtType>::const_iterator it=fEvtTypes.begin(); it!=fEvtTypes.end(); ++it) {
00644
00645 if (*it==kNC) continue;
00646 ProjectHist(cmpHists[*it], variable,
00647 string("slice")+EvtTypeAsString(*it))->DrawCopy("same");
00648 }
00649 ProjectHist(fData, variable, "Data")->DrawCopy("same e");
00650
00651 ((TPad*)gPad)->BuildLegend()->SetFillColor(kWhite);
00652 if (!energySlice && noOsc1D->GetEntries()) ((TPad*)gPad)->SetLogy();
00653
00654
00655 for (int i=1; i<nPlots+1; ++i) {
00656 cSlices->cd(i);
00657
00658 TH1F* noOsc1DSlice=(TH1F*)ProjectHist(hNoOsc, variable,
00659 "NoOsc", i, i)->DrawCopy();
00660 noOsc1DSlice->SetLineStyle(2);
00661 if (energySlice) noOsc1DSlice->GetXaxis()->SetRangeUser(0,19.9);
00662
00663 ProjectHist(hTotal, variable, "Total", i, i)->DrawCopy("same");
00664
00665 for(unsigned int n = 0; n < fEvtTypes.size(); ++n){
00666
00667 if (fEvtTypes[n]==kNC) continue;
00668
00669 ProjectHist(cmpHists[fEvtTypes[n]], variable,
00670 EvtTypeAsString(fEvtTypes[n]),
00671 i, i)->DrawCopy("same");
00672 }
00673 ProjectHist(fData, variable, "Data", i, i)->DrawCopy("same e");
00674
00675 if (!energySlice && noOsc1DSlice->GetEntries()) ((TPad*)gPad)->SetLogy();
00676 }
00677
00678 return v;
00679 }
00680
00681
00682
00683 TH1D* PIDSpectrum::ProjectHist(TH2* h, string axis, string histname,
00684 int lobin, int hibin) const
00685 {
00686 TH1D* ret;
00687 histname=axis+histname;
00688 if(lobin) histname+=TString::Format("%d", lobin);
00689 else histname+="Integ";
00690
00691 if (axis=="energy") ret = h->ProjectionX(histname.c_str(), lobin, hibin);
00692 else if (axis=="pid") ret = h->ProjectionY(histname.c_str(), lobin, hibin);
00693 else assert(0 && "unknown projection requested");
00694 ret->SetDirectory(0);
00695 TH1D* clone=(TH1D*)NC::Utility::CloneFast(ret);
00696 clone->SetDirectory(0);
00697 return clone;
00698 }
00699
00700
00701
00702 vector<TCanvas*> PIDSpectrum::DrawNearSpectra(TH1* systratios, string suffix) const
00703 {
00704 vector<TCanvas*> ret;
00705 TString canvName("nearSpectra "+fBeamInfo.GetDescription());
00706 canvName+=suffix.c_str();
00707 TCanvas* c = new TCanvas(canvName, "Near detector spectra");
00708 c->Divide(2,2);
00709 c->cd(1);
00710 TH2F* nearMCShifted=(TH2F*)NC::Utility::CloneFast(fNearMC);
00711 nearMCShifted->SetName("nearMCShifted");
00712 if (systratios) nearMCShifted->Multiply(systratios);
00713 nearMCShifted->Draw("colz");
00714 c->cd(2);
00715 fNearData->Draw("colz");
00716 c->cd(3);
00717 TH2F* hRatio=(TH2F*)NC::Utility::CloneFast(fNearData);
00718 hRatio->SetName("hRatio");
00719 hRatio->Divide(nearMCShifted);
00720 hRatio->Draw("colz");
00721 ret.push_back(c);
00722
00723 nearMCShifted->SetLineColor(kRed);
00724 fNearData->SetLineColor(kBlack);
00725
00726 TCanvas* cE=new TCanvas(canvName+"energy_1D", "Near detector 1D spectra");
00727 cE->cd();
00728 ProjectHist(nearMCShifted, "energy", "nearMC")->DrawCopy();
00729 ProjectHist(fNearData, "energy", "nearData")->DrawCopy("same e");
00730 ret.push_back(cE);
00731
00732 TCanvas* cPID=new TCanvas(canvName+"pid_1D", "Near detector 1D spectra");
00733 cPID->cd();
00734 ProjectHist(nearMCShifted, "pid", "nearMC")->DrawCopy();
00735 ProjectHist(fNearData, "pid", "nearData")->DrawCopy("same e");
00736 ret.push_back(cPID);
00737
00738 return ret;
00739 }
00740
00741
00742
00743 void PIDSpectrum::FarNearCorrect(TH2F* fdPred,
00744 const TH2F* ndData,
00745 const TH1* ndMC1D) const
00746 {
00747
00748
00749
00750
00751
00752 TH2F* ndMC = (TH2F*)ndMC1D;
00753
00754
00755
00756 for (int i=0; i<fdPred->fN; ++i) {
00757
00758
00759 if (ndMC->fArray[i]) fdPred->fArray[i]*=ndData->fArray[i]/ndMC->fArray[i];
00760 }
00761 }
00762
00763
00764
00765 TH1D* PIDSpectrum::GetPseudoNCCCSpectrum(NCType::EEventType nccc,
00766 evtType t,
00767 const NC::OscProb::OscPars* coords) const
00768 {
00769 TH2F* spec2d;
00770 if(t==kAll){
00771
00772
00773 spec2d=GetPredicted(coords, "", true);
00774 }
00775 else{
00776 spec2d=GetOnePredicted(t, coords);
00777 spec2d->SetDirectory(0);
00778
00779 FarNearCorrect(spec2d, fNearData, fNearMC);
00780 }
00781
00782 return GetPseudoNCCCComponent(spec2d, nccc);
00783 }
00784
00785
00786
00787 TH1D* PIDSpectrum::GetPseudoNCCCComponent(TH2F* h, NCType::EEventType nccc) const
00788 {
00789
00790 int cutBin=h->GetYaxis()->FindBin(fCutValue);
00791 TH1D* spec1d;
00792 if(nccc==NCType::kNC)
00793 spec1d=h->ProjectionX("pseudonc", 0, cutBin);
00794 else
00795 spec1d=h->ProjectionX("pseudocc", cutBin+1, -1);
00796
00797
00798
00799
00800
00801 spec1d->SetDirectory(0);
00802
00803 return spec1d;
00804 }