diff --git a/src/T2K/T2K_CC0pi_XSec_H2O_2DPcos_anu.cxx b/src/T2K/T2K_CC0pi_XSec_H2O_2DPcos_anu.cxx index 2e01352..1603212 100755 --- a/src/T2K/T2K_CC0pi_XSec_H2O_2DPcos_anu.cxx +++ b/src/T2K/T2K_CC0pi_XSec_H2O_2DPcos_anu.cxx @@ -1,187 +1,186 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "T2K_SignalDef.h" #include "T2K_CC0pi_XSec_H2O_2DPcos_anu.h" static int nmombins = 7; static double mom_binning[] = { 400., 530., 670., 800., 1000., 1380., 2010., 3410. }; static int ncosbins[] = { 2, 3, 3, 3, 3, 3, 2 }; static double costheta_binning[][7] = { { 0.84, 0.94, 1. }, { 0.85, 0.92, 0.96, 1. }, { 0.88, 0.93, 0.97, 1. }, { 0.90, 0.94, 0.97, 1. }, { 0.91, 0.95, 0.97, 1. }, { 0.92, 0.96, 0.98, 1. }, { 0.95, 0.98, 1. } }; //******************************************************************** T2K_CC0pi_XSec_H2O_2DPcos_anu::T2K_CC0pi_XSec_H2O_2DPcos_anu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC0pi_XSec_H2O_2DPcos_anu. \n" "Target: H2O \n" "Flux: T2K 2.5 degree off-axis (ND280-P0D) \n" "Signal: CC0pi\n" "arXiv:1908.10249"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#mu}-p_{#mu}"); fSettings.SetYTitle("d^{2}#sigma/dp_{#mu}dcos#theta_{#mu} (cm^{2}/GeV)"); fSettings.SetAllowedTypes("FULL,DIAG/FREE,SHAPE,FIX/SYSTCOV/STATCOV","FIX/FULL"); fSettings.SetEnuRange(0.0, 10.0); fSettings.DefineAllowedTargets("H,O"); // CCQELike plot information fSettings.SetTitle("T2K_CC0pi_XSec_H2O_2DPcos_anu"); fSettings.DefineAllowedSpecies("numub"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/water molecule fScaleFactor = ((GetEventHistogram()->Integral("weight")/(fNEvents+0.)) * 18E-38 / (TotalIntegratedFlux(""))); // Setup Histograms SetHistograms(); // Final setup FinaliseMeasurement(); }; bool T2K_CC0pi_XSec_H2O_2DPcos_anu::isSignal(FitEvent *event){ return SignalDef::isT2K_CC0piAnuP0D(event, EnuMin, EnuMax); }; void T2K_CC0pi_XSec_H2O_2DPcos_anu::FillEventVariables(FitEvent* event){ if (event->NumFSParticle(-13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP; double pmu = Pmu.Vect().Mag(); double CosThetaMu = cos(Pnu.Vect().Angle(Pmu.Vect())); fXVar = pmu; fYVar = CosThetaMu; return; }; void T2K_CC0pi_XSec_H2O_2DPcos_anu::FillHistograms(){ Measurement1D::FillHistograms(); if (Signal){ FillMCSlice( fXVar, fYVar, Weight ); } } // Modification is needed after the full reconfigure to move bins around // Otherwise this would need to be replaced by a TH2Poly which is too awkward. void T2K_CC0pi_XSec_H2O_2DPcos_anu::ConvertEventRates(){ - for (int i = 0; i < 7; i++){ + for (int i = 0; i < nmombins; i++){ fMCHist_Slices[i]->GetSumw2(); } // Do standard conversion. Measurement1D::ConvertEventRates(); - // Do we need this?? Maybe already normalized in Thomas data results for (size_t i = 0; i < nmombins; ++i) { - fMCHist_Slices[i]->Scale(1. / (mom_binning[i + 1] - mom_binning[i])); + fMCHist_Slices[i]->Scale(fScaleFactor / (mom_binning[i + 1] - mom_binning[i])); } // Now Convert into 1D list fMCHist->Reset(); int bincount = 0; - for (int i = 0; i < 7; i++){ + for (int i = 0; i < nmombins; i++){ for (int j = 0; j < fDataHist_Slices[i]->GetNbinsX(); j++){ fMCHist->SetBinContent(bincount+1, fMCHist_Slices[i]->GetBinContent(j+1)); bincount++; } } return; } void T2K_CC0pi_XSec_H2O_2DPcos_anu::FillMCSlice(double x, double y, double w){ for (size_t i = 0; i < nmombins; ++i) { if ((y > mom_binning[i]) && (y <= mom_binning[i + 1])) { fMCHist_Slices[i]->Fill(x, w); } } } void T2K_CC0pi_XSec_H2O_2DPcos_anu::SetHistograms(){ // Read in 1D Data Histograms fInputFile = new TFile( (FitPar::GetDataBase() + "/T2K/CC0pi/AntiNuMuH2O/AntiNuMuOnH2O_unreg.root").c_str(),"READ"); fDataHist = (TH1D*) fInputFile->Get("xsecDataRelease"); int Nbins = fDataHist->GetNbinsX(); TH2D* tempcov = (TH2D*) fInputFile->Get("covDataRelease"); // Read in 1D Data fFullCovar = new TMatrixDSym(Nbins); for (int i = 0; i < Nbins; i++){ for (int j = 0; j < Nbins; j++){ (*fFullCovar)(i,j) = tempcov->GetBinContent(i+1, j+1)*1E-6; } } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); // Read in 2D Data Slices and Make MC Slices int bincount = 0; for (int i = 0; i < nmombins; ++i) { // Get Data Histogram fDataHist_Slices.push_back(new TH1D(Form("T2K_CC0pi_XSec_H2O_2DPcos_anu_data_Slice%i",i),Form("T2K_CC0pi_XSec_H2O_2DPcos_anu_data_Slice%i",i),ncosbins[i],costheta_binning[i])); for (int j = 0; j < ncosbins[i]; ++j) { fDataHist->SetBinError(bincount+1,sqrt((*fFullCovar)(bincount,bincount))*1e-41); fDataHist_Slices[i]->SetBinContent(j+1, fDataHist->GetBinContent(bincount+1)); - fDataHist_Slices[i]->SetBinError(j+1, sqrt((*fFullCovar)(bincount,bincount))*1e-41); + fDataHist_Slices[i]->SetBinError(j+1, sqrt((*fFullCovar)(bincount,bincount))*1e-38); bincount++; } fMCHist_Slices.push_back((TH1D*) fDataHist_Slices[i]->Clone()); fMCHist_Slices[i]->SetNameTitle(Form("T2K_CC0pi_XSec_H2O_2DPcos_anu_MC_Slice%i",i), (Form("T2K_CC0pi_XSec_H2O_2DPcos_anu_MC_Slice%i",i))); SetAutoProcessTH1(fDataHist_Slices[i],kCMD_Write); SetAutoProcessTH1(fMCHist_Slices[i]); } return; }; diff --git a/src/T2K/T2K_SignalDef.cxx b/src/T2K/T2K_SignalDef.cxx index 1a463fe..def7bbf 100644 --- a/src/T2K/T2K_SignalDef.cxx +++ b/src/T2K/T2K_SignalDef.cxx @@ -1,342 +1,336 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "T2K_SignalDef.h" #include "FitUtils.h" namespace SignalDef { // T2K H2O signal definition // https://doi.org/10.1103/PhysRevD.97.012001 bool isCC1pip_T2K_PRD97_012001(FitEvent *event, double EnuMin, double EnuMax) { if (!isCC1pi(event, 14, 211, EnuMin, EnuMax)) return false; TLorentzVector Pnu = event->GetHMISParticle(14)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; double p_mu = FitUtils::p(Pmu) * 1000; double p_pi = FitUtils::p(Ppip) * 1000; double cos_th_mu = cos(FitUtils::th(Pnu, Pmu)); double cos_th_pi = cos(FitUtils::th(Pnu, Ppip)); if (p_mu <= 200 || p_pi <= 200 || cos_th_mu <= 0.3 || cos_th_pi <= 0.3) { return false; } return true; }; // ****************************************************** // T2K CC1pi+ CH analysis (Raquel's thesis) // Has different phase space cuts depending on if using Michel tag or not // // Essentially consists of two samples: one sample which has Michel e (which we // can't get pion direction from); this covers backwards angles quite well. // Measurements including this sample does not have include pion kinematics cuts // one sample which has PID in FGD and TPC // and no Michel e. These are mostly // forward-going so require a pion // kinematics cut // // Essentially, cuts are: // 1 negative muon // 1 positive pion // Any number of nucleons // No other particles in the final state // // https://arxiv.org/abs/1909.03936 bool isCC1pip_T2K_arxiv1909_03936(FitEvent *event, double EnuMin, double EnuMax, int pscuts) { // ****************************************************** if (!isCC1pi(event, 14, 211, EnuMin, EnuMax)) { return false; } TLorentzVector Pnu = event->GetHMISParticle(14)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double cos_th_mu = cos(FitUtils::th(Pnu, Pmu)); if (pscuts == kMuonFwd) { return (cos_th_mu > 0); } double p_mu = FitUtils::p(Pmu) * 1000; if (pscuts & kMuonHighEff) { if ((cos_th_mu <= 0.2) || (p_mu <= 200)) { return false; } } int npicuts = 0; npicuts += bool(pscuts & kPionFwdHighMom); npicuts += bool(pscuts & kPionHighMom); npicuts += bool(pscuts & kPionHighEff); if (npicuts != 1) { NUIS_ABORT( "isCC1pip_T2K_arxiv1909_03936 signal definition passed incompatible " "pion phase space cuts. Should be either kMuonHighEff, or one of " "kPionFwdHighMom,kPionHighMom, or kPionHighEff"); } TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; double cos_th_pi = cos(FitUtils::th(Pnu, Ppip)); double p_pi = FitUtils::p(Ppip) * 1000; if (pscuts & kPionFwdHighMom) { return ((cos_th_pi > 0) && (p_pi > 200)); } if (pscuts & kPionHighMom) { return (p_pi > 200); } if (pscuts & kMuonHighEff) { return ((cos_th_pi > 0.0) && (p_pi > 200)); } return false; }; bool isT2K_CC0pi(FitEvent *event, double EnuMin, double EnuMax, int ana) { // Require a numu CC0pi event if (!isCC0pi(event, 14, EnuMin, EnuMax)) return false; TLorentzVector Pnu = event->GetHMISParticle(14)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double CosThetaMu = cos(Pnu.Vect().Angle(Pmu.Vect())); double p_mu = Pmu.Vect().Mag(); // If we're doing a restricted phase space, Analysis II asks for: // Cos(theta_mu) > 0.0 and p_mu > 200 MeV if (ana == kAnalysis_II) { if ((CosThetaMu < 0.0) || (p_mu < 200)) { return false; } } return true; } bool isT2K_CC0pi1p(FitEvent *event, double EnuMin, double EnuMax) { // Require a numu CC0pi event if (!isCC0pi(event, 14, EnuMin, EnuMax)) return false; // Require at least one FS proton if (event->NumFSParticle(2212) == 0) return false; TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; TLorentzVector pp = event->GetHMFSParticle(2212)->fP; // Proton phase space if (pp.Vect().Mag() < 500) { return false; } // Need exactly one proton with 500 MeV or more momentum std::vector protons = event->GetAllFSProton(); int nProtonsAboveThresh = 0; for (size_t i = 0; i < protons.size(); i++) { if (protons[i]->p() > 500) nProtonsAboveThresh++; } if (nProtonsAboveThresh != 1) return false; return true; } // CC0pi antinu in the P0D https://arxiv.org/abs/1908.10249 bool isT2K_CC0piAnuP0D(FitEvent *event, double EnuMin, double EnuMax) { // Require a anumu CC0pi event if (!isCC0pi(event, -14, EnuMin, EnuMax)) return false; TLorentzVector pnu = event->GetHMISParticle(-14)->fP; TLorentzVector pmu = event->GetHMFSParticle(-13)->fP; double Pmu = pmu.Vect().Mag(); double CosThetaMu = cos(pnu.Vect().Angle(pmu.Vect())); // Muon phase space - if (Pmu < 400 || Pmu > 3410) - return false; - if (Pmu < 530 && CosThetaMu < 0.85) - return false; - if (Pmu < 670 && CosThetaMu < 0.88) - return false; - if (Pmu < 800 && CosThetaMu < 0.9) - return false; - if (Pmu < 1000 && CosThetaMu < 0.91) - return false; - if (Pmu < 1380 && CosThetaMu < 0.92) - return false; - if (Pmu < 2010 && CosThetaMu < 0.95) - return false; + if (Pmu < 400 || Pmu > 3410) return false; + if (Pmu < 530 && Pmu>=400 && CosThetaMu<0.84) return false; + if (Pmu < 670 && Pmu>=530 && CosThetaMu<0.85) return false; + if (Pmu < 800 && Pmu>=670 && CosThetaMu<0.88) return false; + if (Pmu < 1000 &&Pmu>=800 && CosThetaMu<0.9) return false; + if (Pmu < 1380 && Pmu>=1000 && CosThetaMu<0.91) return false; + if (Pmu < 2010 && Pmu>=1380 && CosThetaMu<0.92) return false; + if (Pmu < 3410 && Pmu>=2010 && CosThetaMu<0.95) return false; return true; } bool isT2K_CC0piNp(FitEvent *event, double EnuMin, double EnuMax) { // Require a numu CC0pi event if (!isCC0pi(event, 14, EnuMin, EnuMax)) return false; // Require at least one FS proton if (event->NumFSParticle(2212) == 0) return false; TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; TLorentzVector pp = event->GetHMFSParticle(2212)->fP; // Proton phase space if (pp.Vect().Mag() < 500) { return false; } // Need exactly one proton with 500 MeV or more momentum std::vector protons = event->GetAllFSProton(); int nProtonsAboveThresh = 0; for (size_t i = 0; i < protons.size(); i++) { if (protons[i]->p() > 500) nProtonsAboveThresh++; } if (nProtonsAboveThresh < 2) return false; return true; } bool isT2K_CC0pi0p(FitEvent *event, double EnuMin, double EnuMax) { // Require a numu CC0pi event if (!isCC0pi(event, 14, EnuMin, EnuMax)) return false; // Require at least one FS proton if (event->NumFSParticle(2212) == 0) return false; TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; TLorentzVector pp = event->GetHMFSParticle(2212)->fP; // Proton phase space if (pp.Vect().Mag() > 500) { return false; } return true; } bool isT2K_CC0pi_STV(FitEvent *event, double EnuMin, double EnuMax) { // Require a numu CC0pi event if (!isCC0pi(event, 14, EnuMin, EnuMax)) return false; // Require at least one FS proton if (event->NumFSParticle(2212) == 0) return false; TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; TLorentzVector pp = event->GetHMFSParticle(2212)->fP; // Muon phase space // Pmu > 250 MeV, cos(theta_mu) > -0.6 (Sweet phase space!) if ((pmu.Vect().Mag() < 250) || cos(pnu.Vect().Angle(pmu.Vect())) < -0.6) { return false; } // Proton phase space // Pprot > 450 MeV, cos(theta_proton) > 0.4 if ((pp.Vect().Mag() < 450) || (pp.Vect().Mag() > 1E3) || (cos(pnu.Vect().Angle(pp.Vect())) < 0.4)) { return false; } return true; } bool isT2K_CC0pi_ifk(FitEvent *event, double EnuMin, double EnuMax) { // Require a numu CC0pi event if (!isCC0pi(event, 14, EnuMin, EnuMax)) return false; // Require at least one FS proton if (event->NumFSParticle(2212) == 0) return false; TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; TLorentzVector pp = event->GetHMFSParticle(2212)->fP; // Proton phase space // Pprot > 450 MeV, cos(theta_proton) > 0.4 if ((pp.Vect().Mag() < 450) || (cos(pnu.Vect().Angle(pp.Vect())) < 0.4)) { return false; } return true; } bool isT2K_CC0pi_1bin(FitEvent *event, double EnuMin, double EnuMax) { // Require a numu CC0pi event if (!isCC0pi(event, 14, EnuMin, EnuMax)) return false; // Require at least one FS proton if (event->NumFSParticle(2212) == 0) return false; TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; TLorentzVector pp = event->GetHMFSParticle(2212)->fP; // Muon phase space // if ((pmu.Vect().Mag() < 250) || cos(pnu.Vect().Angle(pmu.Vect())) < -0.6) { // return false; //} // Proton phase space if ((pp.Vect().Mag() < 450) || (cos(pnu.Vect().Angle(pp.Vect())) < 0.4)) { return false; } return true; } } // namespace SignalDef