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