Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/cmake/NuWroSetup.cmake b/cmake/NuWroSetup.cmake
index 149bfb9..f649bff 100644
--- a/cmake/NuWroSetup.cmake
+++ b/cmake/NuWroSetup.cmake
@@ -1,93 +1,112 @@
# 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 <http://www.gnu.org/licenses/>.
################################################################################
if(NOT NUWRO_INPUT_FILE STREQUAL "")
if(NOT EXISTS ${NUWRO_INPUT_FILE})
cmessage(FATAL_ERROR "Expected -DNUWRO_INPUT_FILE to point to a valid input file. Cannot find: '${NUWRO_INPUT_FILE}'")
endif()
if(CMAKE_BUILD_TYPE MATCHES DEBUG)
BuildROOTProject(NuWro_event1 ${NUWRO_INPUT_FILE} "event,vec,vect,particle,flags,params,line" STATIC)
SET(ROOTLIBNAME "libNuWro_event1.a")
else(CMAKE_BUILD_TYPE MATCHES RELEASE)
BuildROOTProject(NuWro_event1 ${NUWRO_INPUT_FILE} "event,vec,vect,particle,flags,params,line" SHARED)
SET(ROOTLIBNAME "libNuWro_event1.so")
endif()
ADD_CUSTOM_TARGET(NuWro_event1HeaderLink ALL
COMMAND ${CMAKE_COMMAND} -E create_symlink
${CMAKE_BINARY_DIR}/NuWro_event1/event.h
${CMAKE_BINARY_DIR}/NuWro_event1/event1.h
DEPENDS NuWro_event1)
LIST(APPEND EXTRA_CXX_FLAGS -D__NUWRO_ENABLED__)
LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/NuWro_event1)
LIST(APPEND EXTRA_LINK_DIRS ${CMAKE_BINARY_DIR})
LIST(APPEND EXTRA_LIBS NuWro_event1)
LIST(APPEND PROJECTWIDE_EXTRA_DEPENDENCIES NuWro_event1HeaderLink )
install(TARGETS NuWro_event1 DESTINATION lib)
SET(NUWRO_BUILT_FROM_FILE TRUE)
else()
if(NUWRO STREQUAL "")
cmessage(FATAL_ERROR "Variable NUWRO is not defined. "
"This must be set to point to a prebuilt NuWro instance.")
endif()
- if(NUWRO_INC STREQUAL "")
- cmessage(FATAL_ERROR "Variable NUWRO_INC is not defined. "
- "This must be set to point to an installed NuWro instance.")
- endif()
# If you are using a version of NuWro without reweighting use this to compile.
if(USE_NuWro_RW)
+ if(NUWRO_INC STREQUAL "")
+ cmessage(FATAL_ERROR "Variable NUWRO_INC is not defined. "
+ "This must be set to point to an installed NuWro instance.")
+ endif()
+
LIST(APPEND EXTRA_CXX_FLAGS -D__NUWRO_ENABLED__ -D__NUWRO_REWEIGHT_ENABLED__)
if(USE_NuWro_SRW_Event)
LIST(APPEND EXTRA_CXX_FLAGS -D__USE_NUWRO_SRW_EVENTS__)
endif()
LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES
${NUWRO}/src
${NUWRO}/src/reweight
${NUWRO_INC}/nuwro)
LIST(APPEND EXTRA_LINK_DIRS ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib)
LIST(APPEND EXTRA_LIBS reweight event)
else ()
LIST(APPEND EXTRA_CXX_FLAGS -D__NUWRO_ENABLED__)
LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${NUWRO}/src)
- LIST(APPEND EXTRA_SHAREDOBJS ${NUWRO}/bin/event1.so)
+ if(NOT EXISTS ${NUWRO}/bin/event1.so)
+ if(EXISTS ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib)
+
+ if(NUWRO_INC STREQUAL "")
+ cmessage(FATAL_ERROR "Variable NUWRO_INC is not defined. "
+ "This must be set to point to an installed NuWro instance.")
+ endif()
+
+ LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${NUWRO_INC}/nuwro)
+
+ LIST(APPEND EXTRA_LINK_DIRS ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib)
+ LIST(APPEND EXTRA_LIBS event)
+ else()
+ cmessage(FATAL_ERROR "Expected to find the NuWro event library in: ${NUWRO}/bin/event1.so, or if using NuWro with reweight support: ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib/libevent.a. Is NuWro built?")
+ endif()
+ else()
+ LIST(APPEND EXTRA_SHAREDOBJS ${NUWRO}/bin/event1.so)
+ endif()
+
endif()
set(NEED_PYTHIA6 TRUE)
set(NEED_ROOTPYTHIA6 TRUE)
endif()
diff --git a/cmake/setup.sh.in b/cmake/setup.sh.in
index 9acb3f8..f5ef12e 100644
--- a/cmake/setup.sh.in
+++ b/cmake/setup.sh.in
@@ -1,130 +1,134 @@
# 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 <http://www.gnu.org/licenses/>.
################################################################################
#!/bin/sh
if ! [[ ":$PATH:" == *":@CMAKE_INSTALL_PREFIX@/bin:"* ]]; then
export PATH=@CMAKE_INSTALL_PREFIX@/bin:$PATH
fi
if ! [[ ":$LD_LIBRARY_PATH:" == *":@CMAKE_INSTALL_PREFIX@/lib:"* ]]; then
export LD_LIBRARY_PATH=@CMAKE_INSTALL_PREFIX@/lib:$LD_LIBRARY_PATH
fi
if [[ ! "${ROOTSYS}" ]]; then
echo "[INFO]: Sourcing ROOT from: @CMAKE_ROOTSYS@"
source "@CMAKE_ROOTSYS@/bin/thisroot.sh"
fi
if [[ "@USE_NEUT@" != "FALSE" ]]; then
echo "[INFO]: Adding NEUT library paths to the environment."
export NEUT_ROOT=@NEUT_ROOT@
export CERN=@CERN@
export CERN_LEVEL=@CERN_LEVEL@
if ! [[ ":$LD_LIBRARY_PATH:" == *":${NEUT_ROOT}/lib/Linux_pc:"* ]]; then
export LD_LIBRARY_PATH=${NEUT_ROOT}/lib/Linux_pc:$LD_LIBRARY_PATH
fi
if ! [[ ":$LD_LIBRARY_PATH:" == *":${NEUT_ROOT}/src/reweight:"* ]]; then
export LD_LIBRARY_PATH=${NEUT_ROOT}/src/reweight:$LD_LIBRARY_PATH
fi
fi
if [[ "@USE_NuWro@" != "FALSE" ]]; then
if [[ "@NUWRO_BUILT_FROM_FILE@" == "FALSE" ]]; then
echo "[INFO]: Adding NuWro library paths to the environment."
export NUWRO="@NUWRO@"
if ! [[ ":$LD_LIBRARY_PATH:" == *":@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib:"* ]]; then
export LD_LIBRARY_PATH=@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib:$LD_LIBRARY_PATH
fi
+
+ if [[ "@NUWRO_INC@" ]]; then
+ export NUWRO_INC=@NUWRO_INC@
+ fi
else
echo "[INFO]: NuWro support included from input event file."
fi
fi
if [[ "@NEED_PYTHIA6@" != "FALSE" ]]; then
echo "[INFO]: Adding PYTHIA6 library paths to the environment."
export PYTHIA6="@PYTHIA6@"
if ! [[ ":$LD_LIBRARY_PATH:" == *":@PYTHIA6@:"* ]]; then
export LD_LIBRARY_PATH=@PYTHIA6@:$LD_LIBRARY_PATH
fi
fi
if [[ "@USE_GENIE@" != "FALSE" ]]; then
echo "[INFO]: Adding GENIE paths to the environment."
export GENIE="@GENIE@"
export LHAPDF_LIB="@LHAPDF_LIB@"
export LHAPDF_INC="@LHAPDF_INC@"
export LIBXML2_LIB="@LIBXML2_LIB@"
export LIBXML2_INC="@LIBXML2_INC@"
export LOG4CPP_LIB="@LOG4CPP_LIB@"
export LOG4CPP_INC="@LOG4CPP_INC@"
if [[ "@LHAPATH@" ]]; then
export LHAPATH="@LHAPATH@"
fi
if ! [[ ":$PATH:" == *":@GENIE@/bin:"* ]]; then
export PATH=@GENIE@/bin:$PATH
fi
if ! [[ ":$LD_LIBRARY_PATH:" == *":@GENIE@/lib:"* ]]; then
export LD_LIBRARY_PATH=@GENIE@/lib:$LD_LIBRARY_PATH
fi
if ! [[ ":$LD_LIBRARY_PATH:" == *":@LHAPDF_LIB@:"* ]]; then
export LD_LIBRARY_PATH=@LHAPDF_LIB@:$LD_LIBRARY_PATH
fi
if ! [[ ":$LD_LIBRARY_PATH:" == *":@LIBXML2_LIB@:"* ]]; then
export LD_LIBRARY_PATH=@LIBXML2_LIB@:$LD_LIBRARY_PATH
fi
if ! [[ ":$LD_LIBRARY_PATH:" == *":@LOG4CPP_LIB@:"* ]]; then
export LD_LIBRARY_PATH=@LOG4CPP_LIB@:$LD_LIBRARY_PATH
fi
fi
if [[ "@USE_NIWG@" != "FALSE" ]]; then
echo "[INFO]: Adding NIWG paths to the environment."
export NIWG=@NIWG_ROOT@
export NIWGREWEIGHT_INPUTS=@NIWG_ROOT@/inputs
if ! [[ ":$LD_LIBRARY_PATH:" == *":@NIWG_ROOT@:"* ]]; then
export LD_LIBRARY_PATH=${NIWG}:${LD_LIBRARY_PATH}
fi
fi
if [[ "@USE_T2K@" != "FALSE" ]]; then
echo "[INFO]: Adding T2K paths to the environment."
export T2KREWEIGHT=@T2KREWEIGHT@
if ! [[ ":$LD_LIBRARY_PATH:" == *":@T2KREWEIGHT@/lib:"* ]]; then
export LD_LIBRARY_PATH=${T2KREWEIGHT}/lib:${LD_LIBRARY_PATH}
fi
fi
if [[ "@BUILD_GiBUU@" != "FALSE" ]]; then
echo "[INFO]: Sourcing GiBUU tools."
source @CMAKE_BINARY_DIR@/GiBUUTools/src/GiBUUTools-build/Linux/setup.sh
fi
export NUISANCE="@CMAKE_SOURCE_DIR@"
diff --git a/src/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx
index 31023b2..54593b9 100755
--- a/src/FCN/JointFCN.cxx
+++ b/src/FCN/JointFCN.cxx
@@ -1,1010 +1,1014 @@
#include "JointFCN.h"
#include <stdio.h>
#include "FitUtils.h"
//***************************************************
JointFCN::JointFCN(TFile* outfile) {
//***************************************************
fOutputDir = gDirectory;
if (outfile) FitPar::Config().out = outfile;
std::vector<nuiskey> samplekeys = Config::QueryKeys("sample");
LoadSamples(samplekeys);
std::vector<nuiskey> covarkeys = Config::QueryKeys("covar");
LoadPulls(covarkeys);
fCurIter = 0;
fMCFilled = false;
fIterationTree = false;
fDialVals = NULL;
fNDials = 0;
fUsingEventManager = FitPar::Config().GetParB("EventManager");
fOutputDir->cd();
}
//***************************************************
JointFCN::JointFCN(std::vector<nuiskey> samplekeys, TFile* outfile) {
//***************************************************
fOutputDir = gDirectory;
if (outfile) FitPar::Config().out = outfile;
LoadSamples(samplekeys);
fCurIter = 0;
fMCFilled = false;
fOutputDir->cd();
fIterationTree = false;
fDialVals = NULL;
fNDials = 0;
fUsingEventManager = FitPar::Config().GetParB("EventManager");
fOutputDir->cd();
}
//***************************************************
JointFCN::~JointFCN() {
//***************************************************
// Delete Samples
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
delete exp;
}
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
delete pull;
}
// Sort Tree
if (fIterationTree) DestroyIterationTree();
if (fDialVals) delete fDialVals;
if (fSampleLikes) delete fSampleLikes;
};
//***************************************************
void JointFCN::CreateIterationTree(std::string name, FitWeight* rw) {
//***************************************************
LOG(FIT) << " Creating new iteration container! " << std::endl;
DestroyIterationTree();
fIterationTreeName = name;
// Add sample likelihoods and ndof
for (MeasListConstIter iter = fSamples.begin();
iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
std::string name = exp->GetName();
std::string liketag = name + "_likelihood";
fNameValues.push_back(liketag);
fCurrentValues.push_back(0.0);
std::string ndoftag = name + "_ndof";
fNameValues.push_back(ndoftag);
fCurrentValues.push_back(0.0);
}
// Add Pull terms
for (PullListConstIter iter = fPulls.begin();
iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
std::string name = pull->GetName();
std::string liketag = name + "_likelihood";
fNameValues.push_back(liketag);
fCurrentValues.push_back(0.0);
std::string ndoftag = name + "_ndof";
fNameValues.push_back(ndoftag);
fCurrentValues.push_back(0.0);
}
// Add Likelihoods
fNameValues.push_back("total_likelihood");
fCurrentValues.push_back(0.0);
fNameValues.push_back("total_ndof");
fCurrentValues.push_back(0.0);
// Setup Containers
fSampleN = fSamples.size() + fPulls.size();
fSampleLikes = new double[fSampleN];
fSampleNDOF = new int[fSampleN];
// Add Dials
std::vector<std::string> dials = rw->GetDialNames();
for (size_t i = 0; i < dials.size(); i++){
fNameValues.push_back( dials[i] );
fCurrentValues.push_back( 0.0 );
}
fNDials = dials.size();
fDialVals = new double[fNDials];
// Set IterationTree Flag
fIterationTree = true;
}
//***************************************************
void JointFCN::DestroyIterationTree() {
//***************************************************
fIterationCount.clear();
fCurrentValues.clear();
fNameValues.clear();
fIterationValues.clear();
}
//***************************************************
void JointFCN::WriteIterationTree() {
//***************************************************
LOG(FIT) << "Writing iteration tree" << std::endl;
// Make a new TTree
TTree* itree = new TTree(fIterationTreeName.c_str(),
fIterationTreeName.c_str());
double* vals = new double[fNameValues.size()];
int count = 0;
itree->Branch("iteration",&count,"Iteration/I");
for (int i = 0; i < fNameValues.size(); i++) {
itree->Branch( fNameValues[i].c_str(),
&vals[i],
(fNameValues[i] + "/D").c_str() );
}
// Fill Iterations
for (size_t i = 0; i < fIterationValues.size(); i++){
std::vector<double> itervals = fIterationValues[i];
// Fill iteration state
count = fIterationCount[i];
for (size_t j = 0; j < itervals.size(); j++){
vals[j] = itervals[j];
}
// Save to TTree
itree->Fill();
}
// Write to file
itree->Write();
}
//***************************************************
void JointFCN::FillIterationTree(FitWeight* rw) {
//***************************************************
// Loop over samples count
int count = 0;
for (int i = 0; i < fSampleN; i++){
fCurrentValues[count++] = fSampleLikes[i];
fCurrentValues[count++] = double(fSampleNDOF[i]);
}
// Fill Totals
fCurrentValues[count++] = fLikelihood;
fCurrentValues[count++] = double(fNDOF);
// Loop Over Parameter Counts
rw->GetAllDials(fDialVals, fNDials);
for (int i = 0; i < fNDials; i++){
fCurrentValues[count++] = double(fDialVals[i]);
}
// Push Back Into Container
fIterationCount.push_back( fCurIter );
fIterationValues.push_back(fCurrentValues);
}
//***************************************************
double JointFCN::DoEval(const double* x) {
//***************************************************
// WEIGHT ENGINE
fDialChanged = FitBase::GetRW()->HasRWDialChanged(x);
FitBase::GetRW()->UpdateWeightEngine(x);
if (fDialChanged) {
FitBase::GetRW()->Reconfigure();
FitBase::EvtManager().ResetWeightFlags();
}
if (LOG_LEVEL(REC)) {
FitBase::GetRW()->Print();
}
// SORT SAMPLES
ReconfigureSamples();
// GET TEST STAT
fLikelihood = GetLikelihood();
fNDOF = GetNDOF();
// PRINT PROGRESS
LOG(FIT) << "Current Stat (iter. " << this->fCurIter << ") = " << fLikelihood
<< std::endl;
// UPDATE TREE
if (fIterationTree) FillIterationTree(FitBase::GetRW());
return fLikelihood;
}
//***************************************************
int JointFCN::GetNDOF() {
//***************************************************
int totaldof = 0;
int count = 0;
// Total number of Free bins in each MC prediction
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
int dof = exp->GetNDOF();
// Save Seperate DOF
if (fIterationTree) {
fSampleNDOF[count] = dof;
}
// Add to total
totaldof += dof;
count++;
}
// Loop over pulls
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
double dof = pull->GetLikelihood();
// Save seperate DOF
if (fIterationTree) {
fSampleNDOF[count] = dof;
}
// Add to total
totaldof += dof;
count++;
}
// Set Data Variable
+ if (fIterationTree){
fSampleNDOF[count] = totaldof;
-
+ }
return totaldof;
}
//***************************************************
double JointFCN::GetLikelihood() {
//***************************************************
LOG(MIN) << std::left << std::setw(43) << "Getting likelihoods..."
<< " : "
<< "-2logL" << std::endl;
// Loop and add up likelihoods in an uncorrelated way
double like = 0.0;
int count = 0;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
double newlike = exp->GetLikelihood();
int ndof = exp->GetNDOF();
// Save seperate likelihoods
if (fIterationTree) {
fSampleLikes[count] = newlike;
}
LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : "
<< newlike << "/" << ndof << std::endl;
// Add Weight Scaling
// like *= FitBase::GetRW()->GetSampleLikelihoodWeight(exp->GetName());
// Add to total
like += newlike;
count++;
}
// Loop over pulls
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
double newlike = pull->GetLikelihood();
// Save seperate likelihoods
if (fIterationTree) {
fSampleLikes[count] = newlike;
}
// Add to total
like += newlike;
count++;
}
// Set Data Variable
fLikelihood = like;
+ if (fIterationTree){
+ fSampleLikes[count] = fLikelihood;
+ }
return like;
};
void JointFCN::LoadSamples(std::vector<nuiskey> samplekeys) {
LOG(MIN) << "Loading Samples : " << samplekeys.size() << std::endl;
for (size_t i = 0; i < samplekeys.size(); i++) {
nuiskey key = samplekeys[i];
// Get Sample Options
std::string samplename = key.GetS("name");
std::string samplefile = key.GetS("input");
std::string sampletype = key.GetS("type");
std::string fakeData = "";
LOG(MIN) << "Loading Sample : " << samplename << std::endl;
fOutputDir->cd();
MeasurementBase* NewLoadedSample = SampleUtils::CreateSample(key);
if (!NewLoadedSample) {
ERR(FTL) << "Could not load sample provided: " << samplename << std::endl;
ERR(FTL) << "Check spelling with that in src/FCN/SampleList.cxx"
<< std::endl;
throw;
} else {
fSamples.push_back(NewLoadedSample);
}
}
}
//***************************************************
void JointFCN::LoadPulls(std::vector<nuiskey> pullkeys) {
//***************************************************
for (size_t i = 0; i < pullkeys.size(); i++) {
nuiskey key = pullkeys[i];
std::string pullname = key.GetS("name");
std::string pullfile = key.GetS("input");
std::string pulltype = key.GetS("type");
fOutputDir->cd();
fPulls.push_back(new ParamPull(pullname, pullfile, pulltype));
}
}
//***************************************************
void JointFCN::ReconfigureSamples(bool fullconfig) {
//***************************************************
int starttime = time(NULL);
LOG(REC) << "Starting Reconfigure iter. " << this->fCurIter << std::endl;
// std::cout << fUsingEventManager << " " << fullconfig << " " << fMCFilled <<
// std::endl;
// Event Manager Reconf
if (fUsingEventManager) {
if (!fullconfig and fMCFilled)
ReconfigureFastUsingManager();
else
ReconfigureUsingManager();
} else {
// Loop over all Measurement Classes
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
// If RW Either do signal or full reconfigure.
if (fDialChanged or !fMCFilled or fullconfig) {
if (!fullconfig and fMCFilled)
exp->ReconfigureFast();
else
exp->Reconfigure();
// If RW Not needed just do normalisation
} else {
exp->Renormalise();
}
}
}
// Loop over pulls and update
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
pull->Reconfigure();
}
fMCFilled = true;
LOG(MIN) << "Finished Reconfigure iter. " << fCurIter << " in "
<< time(NULL) - starttime << "s" << std::endl;
fCurIter++;
}
//***************************************************
void JointFCN::ReconfigureSignal() {
//***************************************************
ReconfigureSamples(false);
}
//***************************************************
void JointFCN::ReconfigureAllEvents() {
//***************************************************
FitBase::GetRW()->Reconfigure();
FitBase::EvtManager().ResetWeightFlags();
ReconfigureSamples(true);
}
std::vector<InputHandlerBase*> JointFCN::GetInputList() {
std::vector<InputHandlerBase*> InputList;
fIsAllSplines = true;
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
std::vector<MeasurementBase*> subsamples = exp->GetSubSamples();
for (size_t i = 0; i < subsamples.size(); i++) {
InputHandlerBase* inp = subsamples[i]->GetInput();
if (std::find(InputList.begin(), InputList.end(), inp) ==
InputList.end()) {
if (subsamples[i]->GetInput()->GetType() != kSPLINEPARAMETER)
fIsAllSplines = false;
InputList.push_back(subsamples[i]->GetInput());
}
}
}
return InputList;
}
std::vector<MeasurementBase*> JointFCN::GetSubSampleList() {
std::vector<MeasurementBase*> SampleList;
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
std::vector<MeasurementBase*> subsamples = exp->GetSubSamples();
for (size_t i = 0; i < subsamples.size(); i++) {
SampleList.push_back(subsamples[i]);
}
}
return SampleList;
}
//***************************************************
void JointFCN::ReconfigureUsingManager() {
//***************************************************
// 'Slow' Event Manager Reconfigure
LOG(REC) << "Event Manager Reconfigure" << std::endl;
int timestart = time(NULL);
// Reset all samples
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ResetAll();
}
// If we are siving signal, reset all containers.
bool savesignal = (FitPar::Config().GetParB("SignalReconfigures"));
if (savesignal) {
// Reset all of our event signal vectors
fSignalEventBoxes.clear();
fSignalEventFlags.clear();
fSampleSignalFlags.clear();
fSignalEventSplines.clear();
}
// Make sure we have a list of inputs
if (fInputList.empty()) {
fInputList = GetInputList();
fSubSampleList = GetSubSampleList();
}
// If all inputs are splines make sure the readers are told
// they need to be reconfigured.
std::vector<InputHandlerBase*>::iterator inp_iter = fInputList.begin();
if (fIsAllSplines) {
for (; inp_iter != fInputList.end(); inp_iter++) {
InputHandlerBase* curinput = (*inp_iter);
// Tell reader in each BaseEvent it needs a Reconfigure next weight calc.
BaseFitEvt* curevent = curinput->FirstBaseEvent();
if (curevent->fSplineRead) {
curevent->fSplineRead->SetNeedsReconfigure(true);
}
}
}
// MAIN INPUT LOOP ====================
int fillcount = 0;
int inputcount = 0;
inp_iter = fInputList.begin();
// Loop over each input in manager
for (; inp_iter != fInputList.end(); inp_iter++) {
InputHandlerBase* curinput = (*inp_iter);
// Get event information
FitEvent* curevent = curinput->FirstNuisanceEvent();
curinput->CreateCache();
int i = 0;
int nevents = curinput->GetNEvents();
int countwidth = nevents / 5;
// Start event loop iterating until we get a NULL pointer.
while (curevent) {
// Get Event Weight
curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent);
curevent->Weight = curevent->RWWeight * curevent->InputWeight;
double rwweight = curevent->Weight;
// std::cout << "RWWeight = " << curevent->RWWeight << " " <<
// curevent->InputWeight << std::endl;
// Logging
// std::cout << CHECKLOG(1) << std::endl;
if (LOGGING(REC)) {
if (i % countwidth == 0) {
QLOG(REC, curinput->GetName()
<< " : Processed " << i << " events. [M, W] = ["
<< curevent->Mode << ", " << rwweight << "]");
}
}
// Setup flag for if signal found in at least one sample
bool foundsignal = false;
// Create a new signal bitset for this event
std::vector<bool> signalbitset(fSubSampleList.size());
// Create a new signal box vector for this event
std::vector<MeasurementVariableBox*> signalboxes;
// Start measurement iterator
size_t measitercount = 0;
std::vector<MeasurementBase*>::iterator meas_iter =
fSubSampleList.begin();
// Loop over all subsamples (sub in JointMeas)
for (; meas_iter != fSubSampleList.end(); meas_iter++) {
MeasurementBase* curmeas = (*meas_iter);
// Compare input pointers, to current input, skip if not.
// Pointer tells us if it matches without doing ID checks.
if (curinput != curmeas->GetInput()) {
if (savesignal) {
// Set bit to 0 as definitely not signal
signalbitset[measitercount] = 0;
}
// Count up what measurement we are on.
measitercount++;
// Skip sample as input not signal.
continue;
}
// Fill events for matching inputs.
MeasurementVariableBox* box = curmeas->FillVariableBox(curevent);
bool signal = curmeas->isSignal(curevent);
curmeas->SetSignal(signal);
curmeas->FillHistograms(curevent->Weight);
// If its Signal tally up fills
if (signal) {
fillcount++;
}
// If we are saving signal/splines fill the bitset
if (savesignal) {
signalbitset[measitercount] = signal;
}
// If signal save a clone of the event box for use later.
if (savesignal and signal) {
foundsignal = true;
signalboxes.push_back(box->CloneSignalBox());
}
// Keep track of Measurement we are on.
measitercount++;
}
// Once we've filled the measurements, if saving signal
// push back if any sample flagged this event as signal
if (savesignal) {
fSignalEventFlags.push_back(foundsignal);
}
// Save the vector of signal boxes for this event
if (savesignal and foundsignal) {
fSignalEventBoxes.push_back(signalboxes);
fSampleSignalFlags.push_back(signalbitset);
}
// If all inputs are splines we can save the spline coefficients
// for fast in memory reconfigures later.
if (fIsAllSplines and savesignal and foundsignal) {
// Make temp vector to push back with
std::vector<float> coeff;
for (size_t l = 0; l < (UInt_t)curevent->fSplineRead->GetNPar(); l++) {
coeff.push_back(curevent->fSplineCoeff[l]);
}
// Push back to signal event splines. Kept in sync with
// fSignalEventBoxes size.
// int splinecount = fSignalEventSplines.size();
fSignalEventSplines.push_back(coeff);
// if (splinecount % 1000 == 0) {
// std::cout << "Pushed Back Coeff " << splinecount << " : ";
// for (size_t l = 0; l < fSignalEventSplines[splinecount].size(); l++)
// {
// std::cout << " " << fSignalEventSplines[splinecount][l];
// }
// std::cout << std::endl;
// }
}
// Clean up vectors once done with this event
signalboxes.clear();
signalbitset.clear();
// Iterate to the next event.
curevent = curinput->NextNuisanceEvent();
i++;
}
curinput->RemoveCache();
// Keep track of what input we are on.
inputcount++;
}
// End of Event Loop ===============================
// Now event loop is finished loop over all Measurements
// Converting Binned events to XSec Distributions
iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ConvertEventRates();
}
// Print out statements on approximate memory usage for profiling.
LOG(REC) << "Filled " << fillcount << " signal events." << std::endl;
if (savesignal) {
int mem =
( // sizeof(fSignalEventBoxes) +
// fSignalEventBoxes.size() * sizeof(fSignalEventBoxes.at(0)) +
sizeof(MeasurementVariableBox1D) * fillcount) *
1E-6;
LOG(REC) << " -> Saved " << fillcount
<< " signal boxes for faster access. (~" << mem << " MB)"
<< std::endl;
if (fIsAllSplines and !fSignalEventSplines.empty()) {
int splmem = sizeof(float) * fSignalEventSplines.size() *
fSignalEventSplines[0].size() * 1E-6;
LOG(REC) << " -> Saved " << fillcount << " " << fSignalEventSplines.size()
<< " spline sets into memory. (~" << splmem << " MB)"
<< std::endl;
}
}
LOG(REC) << "Time taken ReconfigureUsingManager() : "
<< time(NULL) - timestart << std::endl;
// Check SignalReconfigures works for all samples
if (savesignal) {
double likefull = GetLikelihood();
ReconfigureFastUsingManager();
double likefast = GetLikelihood();
if (fabs(likefull - likefast) > 0.0001)
{
ERROR(FTL, "Fast and Full Likelihoods DIFFER! : " << likefull << " : " << likefast);
ERROR(FTL, "This means some samples you are using are not setup to use SignalReconfigures=1");
ERROR(FTL, "Please turn OFF signal reconfigures.");
throw;
} else {
LOG(FIT) << "Likelihoods for FULL and FAST match. Will use FAST next time." << std::endl;
}
}
// End of reconfigure
return;
};
//***************************************************
void JointFCN::ReconfigureFastUsingManager() {
//***************************************************
LOG(FIT) << " -> Doing FAST using manager" << std::endl;
// Get Start time for profilling
int timestart = time(NULL);
// Reset all samples
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ResetAll();
}
// Check for saved variables if not do a full reconfigure.
if (fSignalEventFlags.empty()) {
ERR(WRN) << "Signal Flags Empty! Using normal manager." << std::endl;
ReconfigureUsingManager();
return;
}
bool fFillNuisanceEvent =
FitPar::Config().GetParB("FullEventOnSignalReconfigure");
// Setup fast vector iterators.
std::vector<bool>::iterator inpsig_iter = fSignalEventFlags.begin();
std::vector<std::vector<MeasurementVariableBox*> >::iterator box_iter =
fSignalEventBoxes.begin();
std::vector<std::vector<float> >::iterator spline_iter =
fSignalEventSplines.begin();
std::vector<std::vector<bool> >::iterator samsig_iter =
fSampleSignalFlags.begin();
int splinecount = 0;
// Setup stuff for logging
int fillcount = 0;
int nevents = fSignalEventFlags.size();
int countwidth = nevents / 20;
// If All Splines tell splines they need a reconfigure.
std::vector<InputHandlerBase*>::iterator inp_iter = fInputList.begin();
if (fIsAllSplines) {
LOG(REC) << "All Spline Inputs so using fast spline loop." << std::endl;
for (; inp_iter != fInputList.end(); inp_iter++) {
InputHandlerBase* curinput = (*inp_iter);
// Tell each fSplineRead in BaseFitEvent to reconf next weight calc
BaseFitEvt* curevent = curinput->FirstBaseEvent();
if (curevent->fSplineRead)
curevent->fSplineRead->SetNeedsReconfigure(true);
}
}
// Loop over all possible spline inputs
double* coreeventweights = new double[fSignalEventBoxes.size()];
splinecount = 0;
inp_iter = fInputList.begin();
inpsig_iter = fSignalEventFlags.begin();
spline_iter = fSignalEventSplines.begin();
// Loop over all signal flags
// For each valid signal flag add one to splinecount
// Get Splines from that count and add to weight
// Add splinecount
int sigcount = 0;
splinecount = 0;
// #pragma omp parallel for shared(splinecount,sigcount)
for (uint iinput = 0; iinput < fInputList.size(); iinput++) {
InputHandlerBase* curinput = fInputList[iinput];
BaseFitEvt* curevent = curinput->FirstBaseEvent();
for (int i = 0; i < curinput->GetNEvents(); i++) {
double rwweight = 0.0;
if (fSignalEventFlags[sigcount]) {
// Get Event Info
if (!fIsAllSplines) {
if (fFillNuisanceEvent)
curinput->GetNuisanceEvent(i);
else
curevent = curinput->GetBaseEvent(i);
} else {
curevent->fSplineCoeff = &fSignalEventSplines[splinecount][0];
}
curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent);
curevent->Weight = curevent->RWWeight * curevent->InputWeight;
rwweight = curevent->Weight;
coreeventweights[splinecount] = rwweight;
if (splinecount % countwidth == 0) {
LOG(REC) << "Processed " << splinecount
<< " event weights. W = " << rwweight << std::endl;
}
// #pragma omp atomic
splinecount++;
}
// #pragma omp atomic
sigcount++;
}
}
LOG(SAM) << "Processed event weights." << std::endl;
// #pragma omp barrier
// Reset Iterators
inpsig_iter = fSignalEventFlags.begin();
spline_iter = fSignalEventSplines.begin();
box_iter = fSignalEventBoxes.begin();
samsig_iter = fSampleSignalFlags.begin();
int nsplineweights = splinecount;
splinecount = 0;
// Start of Fast Event Loop ============================
// Start input iterators
// Loop over number of inputs
for (int ispline = 0; ispline < nsplineweights; ispline++) {
double rwweight = coreeventweights[ispline];
// Get iterators for this event
std::vector<bool>::iterator subsamsig_iter = (*samsig_iter).begin();
std::vector<MeasurementVariableBox*>::iterator subbox_iter =
(*box_iter).begin();
// Loop over all sub measurements.
std::vector<MeasurementBase*>::iterator meas_iter = fSubSampleList.begin();
for (; meas_iter != fSubSampleList.end(); meas_iter++, subsamsig_iter++) {
MeasurementBase* curmeas = (*meas_iter);
// If event flagged as signal for this sample fill from the box.
if (*subsamsig_iter) {
curmeas->SetSignal(true);
curmeas->FillHistogramsFromBox((*subbox_iter), rwweight);
// Move onto next box if there is one.
subbox_iter++;
fillcount++;
}
}
if (ispline % countwidth == 0) {
LOG(REC) << "Filled " << ispline << " sample weights." << std::endl;
}
// Iterate over the main signal event containers.
samsig_iter++;
box_iter++;
spline_iter++;
splinecount++;
}
// End of Fast Event Loop ===================
LOG(SAM) << "Filled sample distributions." << std::endl;
// Now loop over all Measurements
// Convert Binned events
iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ConvertEventRates();
}
// Cleanup coreeventweights
if (fIsAllSplines) {
delete coreeventweights;
}
// Print some reconfigure profiling.
LOG(REC) << "Filled " << fillcount << " signal events." << std::endl;
LOG(REC) << "Time taken ReconfigureFastUsingManager() : "
<< time(NULL) - timestart << std::endl;
}
//***************************************************
void JointFCN::Write() {
//***************************************************
// Save a likelihood/ndof plot
LOG(MIN) << "Writing likelihood plot.." << std::endl;
std::vector<double> likes;
std::vector<double> ndofs;
std::vector<std::string> names;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
double like = exp->GetLikelihood();
double ndof = exp->GetNDOF();
std::string name = exp->GetName();
likes.push_back(like);
ndofs.push_back(ndof);
names.push_back(name);
}
TH1D likehist = TH1D("likelihood_hist", "likelihood_hist",
likes.size(), 0.0, double(likes.size()));
TH1D ndofhist = TH1D("ndof_hist", "ndof_hist",
ndofs.size(), 0.0, double(ndofs.size()));
TH1D divhist = TH1D("likedivndof_hist", "likedivndof_hist",
likes.size(), 0.0, double(likes.size()));
for (size_t i = 0; i < likehist.GetNbinsX(); i++) {
likehist.SetBinContent(i + 1, likes[i]);
ndofhist.SetBinContent(i + 1, ndofs[i]);
if (ndofs[i] != 0.0) {
divhist.SetBinContent(i + 1, likes[i] / ndofs[i]);
}
likehist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
ndofhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
divhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
}
likehist.Write();
ndofhist.Write();
divhist.Write();
// Loop over individual experiments and call Write
LOG(MIN) << "Writing each of the data classes..." << std::endl;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
exp->Write();
}
// Save Pull Terms
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
pull->Write();
}
if (FitPar::Config().GetParB("EventManager")) {
// Get list of inputs
std::map<int, InputHandlerBase*> fInputs =
FitBase::EvtManager().GetInputs();
std::map<int, InputHandlerBase*>::const_iterator iterInp;
for (iterInp = fInputs.begin(); iterInp != fInputs.end(); iterInp++) {
InputHandlerBase* input = (iterInp->second);
input->GetFluxHistogram()->Write();
input->GetXSecHistogram()->Write();
input->GetEventHistogram()->Write();
}
}
};
//***************************************************
void JointFCN::SetFakeData(std::string fakeinput) {
//***************************************************
LOG(MIN) << "Setting fake data from " << fakeinput << std::endl;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
exp->SetFakeDataValues(fakeinput);
}
return;
}
//***************************************************
void JointFCN::ThrowDataToy() {
//***************************************************
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
exp->ThrowDataToy();
}
return;
}
diff --git a/src/FitBase/JointMeas1D.cxx b/src/FitBase/JointMeas1D.cxx
index 8374aa4..6700a10 100644
--- a/src/FitBase/JointMeas1D.cxx
+++ b/src/FitBase/JointMeas1D.cxx
@@ -1,2290 +1,2303 @@
// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This ile 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "JointMeas1D.h"
//********************************************************************
JointMeas1D::JointMeas1D(void) {
//********************************************************************
// XSec Scalings
fScaleFactor = -1.0;
fCurrentNorm = 1.0;
// Histograms
fDataHist = NULL;
fDataTrue = NULL;
fMCHist = NULL;
fMCFine = NULL;
fMCWeighted = NULL;
fMaskHist = NULL;
// Covar
covar = NULL;
fFullCovar = NULL;
fCovar = NULL;
fInvert = NULL;
fDecomp = NULL;
// Fake Data
fFakeDataInput = "";
fFakeDataFile = NULL;
// Options
fDefaultTypes = "FIX/FULL/CHI2";
fAllowedTypes =
"FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK";
fIsFix = false;
fIsShape = false;
fIsFree = false;
fIsDiag = false;
fIsFull = false;
fAddNormPen = false;
fIsMask = false;
fIsChi2SVD = false;
fIsRawEvents = false;
fIsDifXSec = false;
fIsEnu1D = false;
// Inputs
fInput = NULL;
fRW = NULL;
// Extra Histograms
fMCHist_Modes = NULL;
for (std::vector<MeasurementBase*>::const_iterator iter = fSubChain.begin();
iter != fSubChain.end(); iter++) {
MeasurementBase* exp = *iter;
if (exp) delete exp;
}
fSubChain.clear();
// Flags for Joint Measurements
fIsRatio = false;
fIsSummed = false;
fSaveSubMeas = false;
fIsJoint = true;
}
//********************************************************************
void JointMeas1D::SetupDefaultHist() {
//********************************************************************
// Setup fMCHist
fMCHist = (TH1D*)fDataHist->Clone();
fMCHist->SetNameTitle((fName + "_MC").c_str(),
(fName + "_MC" + fPlotTitles).c_str());
// Setup fMCFine
Int_t nBins = fMCHist->GetNbinsX();
fMCFine = new TH1D(
(fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(),
nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1));
fMCStat = (TH1D*)fMCHist->Clone();
fMCStat->Reset();
fMCHist->Reset();
fMCFine->Reset();
// Setup the NEUT Mode Array
PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG);
PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG);
// Setup bin masks using sample name
if (fIsMask) {
std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask");
if (maskloc.empty()) {
maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask";
}
SetBinMask(maskloc);
}
fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist);
SetAutoProcessTH1(fMCHist_Modes);
return;
}
//********************************************************************
JointMeas1D::~JointMeas1D(void) {
//********************************************************************
if (fDataHist) delete fDataHist;
if (fDataTrue) delete fDataTrue;
if (fMCHist) delete fMCHist;
if (fMCFine) delete fMCFine;
if (fMCWeighted) delete fMCWeighted;
if (fMaskHist) delete fMaskHist;
if (covar) delete covar;
if (fFullCovar) delete fFullCovar;
if (fCovar) delete fCovar;
if (fInvert) delete fInvert;
if (fDecomp) delete fDecomp;
for (std::vector<MeasurementBase*>::const_iterator iter = fSubChain.begin();
iter != fSubChain.end(); iter++) {
MeasurementBase* exp = *iter;
if (exp) delete exp;
}
fSubChain.clear();
}
//********************************************************************
SampleSettings JointMeas1D::LoadSampleSettings(nuiskey samplekey){
//********************************************************************
SampleSettings s = MeasurementBase::LoadSampleSettings(samplekey);
// Parse Inputs
fSubInFiles.clear();
std::vector<std::string> entries = GeneralUtils::ParseToStr(s.GetS("input"), ";");
if (entries.size() < 2) {
ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon "
"separated input files, but recieved: \""
<< s.GetS("input") << "\"" << std::endl;
throw;
}
std::vector<std::string> first_file_descriptor =
GeneralUtils::ParseToStr(entries.front(), ":");
if (first_file_descriptor.size() != 2) {
ERR(FTL) << "Found Joint measurement where the input file had no type: \""
<< s.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"."
<< std::endl;
throw;
}
std::string inpType = first_file_descriptor[0];
for (std::vector<std::string>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) {
std::stringstream ss("");
ss << inpType << ":" << (*iter);
fSubInFiles.push_back(ss.str());
} else {
fSubInFiles.push_back(*iter);
}
}
return s;
}
//********************************************************************
void JointMeas1D::FinaliseSampleSettings() {
//********************************************************************
// Setup naming + renaming
fName = fSettings.GetName();
fSettings.SetS("originalname", fName);
if (fSettings.Has("rename")) {
fName = fSettings.GetS("rename");
fSettings.SetS("name", fName);
}
// Setup all other options
LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl;
if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) {
fIsRawEvents = true;
LOG(SAM) << "Found event rate measurement but using poisson likelihoods."
<< std::endl;
}
if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) {
fIsEnu1D = true;
LOG(SAM) << "::" << fName << "::" << std::endl;
LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
<< "not flux averaged!" << std::endl;
}
if (fIsEnu1D && fIsRawEvents) {
LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
"really correct?!"
<< std::endl;
LOG(SAM) << "Check experiment constructor for " << fName
<< " and correct this!" << std::endl;
LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
exit(-1);
}
// Parse Inputs
fSubInFiles.clear();
std::vector<std::string> entries = GeneralUtils::ParseToStr(fSettings.GetS("input"), ";");
if (entries.size() < 2) {
ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon "
"separated input files, but recieved: \""
<< fSettings.GetS("input") << "\"" << std::endl;
throw;
}
std::vector<std::string> first_file_descriptor =
GeneralUtils::ParseToStr(entries.front(), ":");
if (first_file_descriptor.size() != 2) {
ERR(FTL) << "Found Joint measurement where the input file had no type: \""
<< fSettings.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"."
<< std::endl;
throw;
}
std::string inpType = first_file_descriptor[0];
for (std::vector<std::string>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) {
std::stringstream ss("");
ss << inpType << ":" << (*iter);
fSubInFiles.push_back(ss.str());
} else {
fSubInFiles.push_back(*iter);
}
}
// Setup options
SetFitOptions(fDefaultTypes); // defaults
SetFitOptions(fSettings.GetS("type")); // user specified
EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min"));
EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max"));
if (fAddNormPen) {
if (fNormError <= 0.0) {
ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl;
ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl;
throw;
}
}
if (!fRW) fRW = FitBase::GetRW();
LOG(SAM) << "Finalised Sample Settings" << std::endl;
}
//********************************************************************
void JointMeas1D::SetDataFromTextFile(std::string datafile) {
//********************************************************************
LOG(SAM) << "Reading data from text file: " << datafile << std::endl;
fDataHist = PlotUtils::GetTH1DFromFile(datafile,
fSettings.GetName() + "_data",
fSettings.GetFullTitles());
}
//********************************************************************
void JointMeas1D::SetDataFromRootFile(std::string datafile,
std::string histname) {
//********************************************************************
LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl;
fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname);
fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(),
(fSettings.GetFullTitles()).c_str());
return;
};
//********************************************************************
void JointMeas1D::SetPoissonErrors() {
//********************************************************************
if (!fDataHist) {
ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl;
ERR(FTL) << "Setup Data First!" << std::endl;
throw;
}
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1)));
}
}
//********************************************************************
void JointMeas1D::SetCovarFromDiagonal(TH1D* data) {
//********************************************************************
if (!data and fDataHist) {
data = fDataHist;
}
if (data) {
LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl;
fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
} else {
ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl;
}
if (!fIsDiag) {
ERR(FTL) << "SetCovarMatrixFromDiag called for measurement "
<< "that is not set as diagonal." << std::endl;
throw;
}
}
//********************************************************************
void JointMeas1D::SetCovarFromTextFile(std::string covfile, int dim) {
//********************************************************************
LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl;
fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void JointMeas1D::SetCovarFromMultipleTextFiles(std::string covfiles, int dim) {
//********************************************************************
if (dim == -1) {
dim = fDataHist->GetNbinsX();
}
std::vector<std::string> covList = GeneralUtils::ParseToStr(covfiles, ";");
fFullCovar = new TMatrixDSym(dim);
for (uint i = 0; i < covList.size(); ++i){
LOG(SAM) << "Reading covariance from text file: " << covList[i] << std::endl;
TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(covList[i], dim);
(*fFullCovar) += (*temp_cov);
delete temp_cov;
}
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void JointMeas1D::SetCovarFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl;
fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void JointMeas1D::SetCovarInvertFromTextFile(std::string covfile, int dim) {
//********************************************************************
LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl;
covar = StatUtils::GetCovarFromTextFile(covfile, dim);
fFullCovar = StatUtils::GetInvert(covar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void JointMeas1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl;
covar = StatUtils::GetCovarFromRootFile(covfile, histname);
fFullCovar = StatUtils::GetInvert(covar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void JointMeas1D::SetCorrelationFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) dim = fDataHist->GetNbinsX();
LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl;
TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim);
if (!fDataHist) {
ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
<< "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
throw;
}
// Fill covar from data errors and correlations
fFullCovar = new TMatrixDSym(dim);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
(*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
}
}
// Fill other covars.
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete correlation;
}
//********************************************************************
void JointMeas1D::SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim) {
//********************************************************************
if (dim == -1) {
dim = fDataHist->GetNbinsX();
}
std::vector<std::string> corrList = GeneralUtils::ParseToStr(corrfiles, ";");
fFullCovar = new TMatrixDSym(dim);
for (uint i = 0; i < corrList.size(); ++i){
LOG(SAM) << "Reading covariance from text file: " << corrList[i] << std::endl;
TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(corrList[i], dim);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
// Note that there is a factor of 1E76 here. It is very silly indeed.
// However, if you remove it, you also need to fix the factors of 1E38 added to the chi2 calculations!
(*temp_cov)(i, j) = (*temp_cov)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1E76;
}
}
(*fFullCovar) += (*temp_cov);
delete temp_cov;
}
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void JointMeas1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl;
TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname);
if (!fDataHist) {
ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
<< "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
throw;
}
// Fill covar from data errors and correlations
fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX());
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
(*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
}
}
// Fill other covars.
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete correlation;
}
+void JointMeas1D::SetShapeCovar(){
+
+ // Return if this is missing any pre-requisites
+ if (!fFullCovar) return;
+ if (!fDataHist) return;
+
+ // Also return if it's bloody stupid under the circumstances
+ if (fIsDiag) return;
+
+ fShapeCovar = StatUtils::ExtractShapeOnlyCovar(fFullCovar, fDataHist);
+ return;
+}
+
//********************************************************************
void JointMeas1D::SetCholDecompFromTextFile(std::string covfile, int dim) {
//********************************************************************
LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl;
TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim);
TMatrixD* trans = (TMatrixD*)temp->Clone();
trans->T();
(*trans) *= (*temp);
fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), "");
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete temp;
delete trans;
}
//********************************************************************
void JointMeas1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl;
TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname);
TMatrixD* trans = (TMatrixD*)temp->Clone();
trans->T();
(*trans) *= (*temp);
fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), "");
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete temp;
delete trans;
}
//********************************************************************
void JointMeas1D::ScaleData(double scale) {
//********************************************************************
fDataHist->Scale(scale);
}
//********************************************************************
void JointMeas1D::ScaleCovar(double scale) {
//********************************************************************
(*fFullCovar) *= scale;
(*covar) *= 1.0 / scale;
(*fDecomp) *= sqrt(scale);
}
//********************************************************************
void JointMeas1D::SetBinMask(std::string maskfile) {
//********************************************************************
if (!fIsMask) return;
LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl;
// Create a mask histogram with dim of data
int nbins = fDataHist->GetNbinsX();
fMaskHist =
new TH1I((fSettings.GetName() + "_BINMASK").c_str(),
(fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins);
std::string line;
std::ifstream mask(maskfile.c_str(), ifstream::in);
if (!mask.is_open()) {
LOG(FTL) << " Cannot find mask file." << std::endl;
throw;
}
while (std::getline(mask >> std::ws, line, '\n')) {
std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
// Skip lines with poorly formatted lines
if (entries.size() < 2) {
LOG(WRN) << "JointMeas1D::SetBinMask(), couldn't parse line: " << line
<< std::endl;
continue;
}
// The first index should be the bin number, the second should be the mask
// value.
int val = 0;
if (entries[1] > 0) val = 1;
fMaskHist->SetBinContent(entries[0], val);
}
// Apply masking by setting masked data bins to zero
PlotUtils::MaskBins(fDataHist, fMaskHist);
return;
}
//********************************************************************
void JointMeas1D::FinaliseMeasurement() {
//********************************************************************
LOG(SAM) << "Finalising Measurement: " << fName << std::endl;
// Make sure data is setup
if (!fDataHist) {
ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl;
throw;
}
// Make sure covariances are setup
if (!fFullCovar) {
fIsDiag = true;
SetCovarFromDiagonal(fDataHist);
}
if (!covar) {
covar = StatUtils::GetInvert(fFullCovar);
}
if (!fDecomp) {
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
// Push the diagonals of fFullCovar onto the data histogram
// Comment out until scaling is used consistently...
- // StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar);
+ StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38);
// Setup fMCHist from data
fMCHist = (TH1D*)fDataHist->Clone();
fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(),
(fSettings.GetFullTitles()).c_str());
fMCHist->Reset();
// Setup fMCFine
fMCFine = new TH1D("mcfine", "mcfine", fDataHist->GetNbinsX(),
fMCHist->GetBinLowEdge(1),
fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1));
fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(),
(fSettings.GetFullTitles()).c_str());
fMCFine->Reset();
// Setup MC Stat
fMCStat = (TH1D*)fMCHist->Clone();
fMCStat->Reset();
// Search drawopts for possible types to include by default
std::string drawopts = FitPar::Config().GetParS("drawopts");
if (drawopts.find("MODES") != std::string::npos) {
fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(),
("True Channels"), fMCHist);
SetAutoProcessTH1(fMCHist_Modes);
}
// Setup bin masks using sample name
if (fIsMask) {
std::string curname = fName;
std::string origname = fSettings.GetS("originalname");
// Check rename.mask
std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask");
// Check origname.mask
if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask");
// Check database
if (maskloc.empty()) {
maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask";
}
// Setup Bin Mask
SetBinMask(maskloc);
}
/*
if (fScaleFactor < 0) {
ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl;
ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl;
ERR(FTL) << "EXITING" << std::endl;
throw;
}
*/
// Create and fill Weighted Histogram
if (!fMCWeighted) {
fMCWeighted = (TH1D*)fMCHist->Clone();
fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(),
(fName + "_MCWGHTS" + fPlotTitles).c_str());
fMCWeighted->GetYaxis()->SetTitle("Weighted Events");
}
}
//********************************************************************
void JointMeas1D::SetFitOptions(std::string opt) {
//********************************************************************
// Do nothing if default given
if (opt == "DEFAULT") return;
// CHECK Conflicting Fit Options
std::vector<std::string> fit_option_allow =
GeneralUtils::ParseToStr(fAllowedTypes, "/");
for (UInt_t i = 0; i < fit_option_allow.size(); i++) {
std::vector<std::string> fit_option_section =
GeneralUtils::ParseToStr(fit_option_allow.at(i), ",");
bool found_option = false;
for (UInt_t j = 0; j < fit_option_section.size(); j++) {
std::string av_opt = fit_option_section.at(j);
if (!found_option and opt.find(av_opt) != std::string::npos) {
found_option = true;
} else if (found_option and opt.find(av_opt) != std::string::npos) {
ERR(FTL) << "ERROR: Conflicting fit options provided: "
<< opt << std::endl
<< "Conflicting group = " << fit_option_section.at(i) << std::endl
<< "You should only supply one of these options in card file." << std::endl;
throw;
}
}
}
// Check all options are allowed
std::vector<std::string> fit_options_input =
GeneralUtils::ParseToStr(opt, "/");
for (UInt_t i = 0; i < fit_options_input.size(); i++) {
if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) {
ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i)
<< "' Provided is not allowed for this measurement."
<< std::endl;
ERR(FTL) << "Fit Options should be provided as a '/' seperated list "
"(e.g. FREE/DIAG/NORM)"
<< std::endl;
ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes
<< "'" << std::endl;
throw;
}
}
// Set TYPE
fFitType = opt;
// FIX,SHAPE,FREE
if (opt.find("FIX") != std::string::npos) {
fIsFree = fIsShape = false;
fIsFix = true;
} else if (opt.find("SHAPE") != std::string::npos) {
fIsFree = fIsFix = false;
fIsShape = true;
} else if (opt.find("FREE") != std::string::npos) {
fIsFix = fIsShape = false;
fIsFree = true;
}
// DIAG,FULL (or default to full)
if (opt.find("DIAG") != std::string::npos) {
fIsDiag = true;
fIsFull = false;
} else if (opt.find("FULL") != std::string::npos) {
fIsDiag = false;
fIsFull = true;
}
// CHI2/LL (OTHERS?)
if (opt.find("LOG") != std::string::npos) {
fIsChi2 = false;
ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl;
ERR(FTL) << "Try to use a chi2!" << std::endl;
throw;
} else {
fIsChi2 = true;
}
// EXTRAS
if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
if (opt.find("DIF") != std::string::npos) fIsDifXSec = true;
if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true;
if (opt.find("NORM") != std::string::npos) fAddNormPen = true;
if (opt.find("MASK") != std::string::npos) fIsMask = true;
return;
};
//********************************************************************
void JointMeas1D::SetSmearingMatrix(std::string smearfile, int truedim,
int recodim) {
//********************************************************************
// The smearing matrix describes the migration from true bins (rows) to reco
// bins (columns)
// Counter over the true bins!
int row = 0;
std::string line;
std::ifstream smear(smearfile.c_str(), ifstream::in);
// Note that the smearing matrix may be rectangular.
fSmearMatrix = new TMatrixD(truedim, recodim);
if (smear.is_open())
LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl;
else
ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile
<< std::endl;
while (std::getline(smear >> std::ws, line, '\n')) {
int column = 0;
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
(*fSmearMatrix)(row, column) =
(*iter) / 100.; // Convert to fraction from
// percentage (this may not be
// general enough)
column++;
}
row++;
}
return;
}
//********************************************************************
void JointMeas1D::ApplySmearingMatrix() {
//********************************************************************
if (!fSmearMatrix) {
ERR(WRN) << fName
<< ": attempted to apply smearing matrix, but none was set"
<< std::endl;
return;
}
TH1D* unsmeared = (TH1D*)fMCHist->Clone();
TH1D* smeared = (TH1D*)fMCHist->Clone();
smeared->Reset();
// Loop over reconstructed bins
// true = row; reco = column
for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) {
// Sum up the constributions from all true bins
double rBinVal = 0;
// Loop over true bins
for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) {
rBinVal +=
(*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1);
}
smeared->SetBinContent(rbin + 1, rBinVal);
}
fMCHist = (TH1D*)smeared->Clone();
return;
}
/*
Reconfigure LOOP
*/
//********************************************************************
void JointMeas1D::ResetAll() {
//********************************************************************
fMCHist->Reset();
fMCFine->Reset();
fMCStat->Reset();
return;
};
//********************************************************************
void JointMeas1D::FillHistograms() {
//********************************************************************
if (Signal) {
fMCHist->Fill(fXVar, Weight);
fMCFine->Fill(fXVar, Weight);
fMCStat->Fill(fXVar, 1.0);
if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight);
}
return;
};
//********************************************************************
void JointMeas1D::ScaleEvents() {
//********************************************************************
LOG(FIT) << "Scaling JointMeas1D" << std::endl;
// Fill MCWeighted;
for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1));
fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1));
}
// Setup Stat ratios for MC and MC Fine
double* statratio = new double[fMCHist->GetNbinsX()];
for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
if (fMCHist->GetBinContent(i + 1) != 0) {
statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1);
} else {
statratio[i] = 0.0;
}
}
double* statratiofine = new double[fMCFine->GetNbinsX()];
for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
if (fMCFine->GetBinContent(i + 1) != 0) {
statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1);
} else {
statratiofine[i] = 0.0;
}
}
// Scaling for raw event rates
if (fIsRawEvents) {
double datamcratio = fDataHist->Integral() / fMCHist->Integral();
fMCHist->Scale(datamcratio);
fMCFine->Scale(datamcratio);
if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio);
// Scaling for XSec as function of Enu
} else if (fIsEnu1D) {
PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(),
GetEventHistogram(), fScaleFactor,
fNEvents);
PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(),
GetEventHistogram(), fScaleFactor,
fNEvents);
// if (fMCHist_Modes) {
// PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(),
// GetEventHistogram(), fScaleFactor,
// fNEvents);
// }
// Any other differential scaling
} else {
fMCHist->Scale(fScaleFactor, "width");
fMCFine->Scale(fScaleFactor, "width");
if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width");
}
// Proper error scaling - ROOT Freaks out with xsec weights sometimes
for (int i = 0; i < fMCStat->GetNbinsX(); i++) {
fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]);
}
for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]);
}
// Clean up
delete statratio;
delete statratiofine;
return;
};
//********************************************************************
void JointMeas1D::ApplyNormScale(double norm) {
//********************************************************************
fCurrentNorm = norm;
fMCHist->Scale(1.0 / norm);
fMCFine->Scale(1.0 / norm);
return;
};
/*
Statistic Functions - Outsources to StatUtils
*/
//********************************************************************
int JointMeas1D::GetNDOF() {
//********************************************************************
int ndof = fDataHist->GetNbinsX();
if (fMaskHist) ndof -= fMaskHist->Integral();
return ndof;
}
//********************************************************************
double JointMeas1D::GetLikelihood() {
//********************************************************************
// If this is for a ratio, there is no data histogram to compare to!
if (fNoData || !fDataHist) return 0.;
// Apply Masking to MC if Required.
if (fIsMask and fMaskHist) {
PlotUtils::MaskBins(fMCHist, fMaskHist);
}
// Sort Shape Scaling
double scaleF = 0.0;
if (fIsShape) {
if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) {
scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") /
fMCHist->Integral(1, fMCHist->GetNbinsX(), "width");
fMCHist->Scale(scaleF);
fMCFine->Scale(scaleF);
}
}
// Likelihood Calculation
double stat = 0.;
if (fIsChi2) {
if (fIsRawEvents) {
stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist);
} else if (fIsDiag) {
stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist);
} else if (!fIsDiag and !fIsRawEvents) {
stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist);
}
}
// Sort Penalty Terms
if (fAddNormPen) {
double penalty =
(1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError);
stat += penalty;
}
// Return to normal scaling
if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) {
fMCHist->Scale(1. / scaleF);
fMCFine->Scale(1. / scaleF);
}
fLikelihood = stat;
return stat;
}
/*
Fake Data Functions
*/
//********************************************************************
void JointMeas1D::SetFakeDataValues(std::string fakeOption) {
//********************************************************************
// Setup original/datatrue
TH1D* tempdata = (TH1D*) fDataHist->Clone();
if (!fIsFakeData) {
fIsFakeData = true;
// Make a copy of the original data histogram.
if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str());
} else {
ResetFakeData();
}
// Setup Inputs
fFakeDataInput = fakeOption;
LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl;
// From MC
if (fFakeDataInput.compare("MC") == 0) {
fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str());
// Fake File
} else {
if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ");
fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str());
}
// Setup Data Hist
fDataHist->SetNameTitle((fName + "_FAKE").c_str(),
(fName + fPlotTitles).c_str());
// Replace Data True
if (fDataTrue) delete fDataTrue;
fDataTrue = (TH1D*)fDataHist->Clone();
fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(),
(fName + fPlotTitles).c_str());
// Make a new covariance for fake data hist.
int nbins = fDataHist->GetNbinsX();
double alpha_i = 0.0;
double alpha_j = 0.0;
for (int i = 0; i < nbins; i++) {
for (int j = 0; j < nbins; j++) {
alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1);
alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1);
(*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j);
}
}
// Setup Covariances
if (covar) delete covar;
covar = StatUtils::GetInvert(fFullCovar);
if (fDecomp) delete fDecomp;
fDecomp = StatUtils::GetInvert(fFullCovar);
delete tempdata;
return;
};
//********************************************************************
void JointMeas1D::ResetFakeData() {
//********************************************************************
if (fIsFakeData) {
if (fDataHist) delete fDataHist;
fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str());
}
}
//********************************************************************
void JointMeas1D::ResetData() {
//********************************************************************
if (fIsFakeData) {
if (fDataHist) delete fDataHist;
fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str());
}
fIsFakeData = false;
}
//********************************************************************
void JointMeas1D::ThrowCovariance() {
//********************************************************************
// Take a fDecomposition and use it to throw the current dataset.
// Requires fDataTrue also be set incase used repeatedly.
if (fDataHist) delete fDataHist;
fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
return;
};
//********************************************************************
void JointMeas1D::ThrowDataToy(){
//********************************************************************
if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone();
if (fMCHist) delete fMCHist;
fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
}
/*
Access Functions
*/
//********************************************************************
TH1D* JointMeas1D::GetMCHistogram() {
//********************************************************************
if (!fMCHist) return fMCHist;
std::ostringstream chi2;
chi2 << std::setprecision(5) << this->GetLikelihood();
int linecolor = kRed;
int linestyle = 1;
int linewidth = 1;
int fillcolor = 0;
int fillstyle = 1001;
if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor");
if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle");
if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth");
if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor");
if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle");
fMCHist->SetTitle(chi2.str().c_str());
fMCHist->SetLineColor(linecolor);
fMCHist->SetLineStyle(linestyle);
fMCHist->SetLineWidth(linewidth);
fMCHist->SetFillColor(fillcolor);
fMCHist->SetFillStyle(fillstyle);
return fMCHist;
};
//********************************************************************
TH1D* JointMeas1D::GetDataHistogram() {
//********************************************************************
if (!fDataHist) return fDataHist;
int datacolor = kBlack;
int datastyle = 1;
int datawidth = 1;
if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor");
if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle");
if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth");
fDataHist->SetLineColor(datacolor);
fDataHist->SetLineWidth(datawidth);
fDataHist->SetMarkerStyle(datastyle);
return fDataHist;
};
/*
Write Functions
*/
// Save all the histograms at once
//********************************************************************
void JointMeas1D::Write(std::string drawOpt) {
//********************************************************************
// Get Draw Options
drawOpt = FitPar::Config().GetParS("drawopts");
// Write Settigns
if (drawOpt.find("SETTINGS") != std::string::npos){
fSettings.Set("#chi^{2}",fLikelihood);
fSettings.Set("NDOF", this->GetNDOF() );
fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() );
fSettings.Write();
}
// Write Data/MC
GetDataHistogram()->Write();
GetMCHistogram()->Write();
// Write Fine Histogram
if (drawOpt.find("FINE") != std::string::npos)
GetFineList().at(0)->Write();
// Write Weighted Histogram
if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted)
fMCWeighted->Write();
// Save Flux/Evt if no event manager
if (!FitPar::Config().GetParB("EventManager")) {
if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram())
GetFluxHistogram()->Write();
if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram())
GetEventHistogram()->Write();
if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram())
GetEventHistogram()->Write();
}
// Write Mask
if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) {
fMaskHist->Write();
}
// Write Covariances
if (drawOpt.find("COV") != std::string::npos && fFullCovar) {
PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName());
}
if (drawOpt.find("INVCOV") != std::string::npos && covar) {
PlotUtils::GetInvCovarPlot(covar, fSettings.GetName());
}
if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) {
PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName());
}
// // Likelihood residual plots
// if (drawOpt.find("RESIDUAL") != std::string::npos) {
// WriteResidualPlots();
// }
// Ratio and Shape Plots
if (drawOpt.find("RATIO") != std::string::npos) {
WriteRatioPlot();
}
if (drawOpt.find("SHAPE") != std::string::npos) {
WriteShapePlot();
if (drawOpt.find("RATIO") != std::string::npos)
WriteShapeRatioPlot();
}
// // RATIO
// if (drawOpt.find("CANVMC") != std::string::npos) {
// TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist);
// c1->Write();
// delete c1;
// }
// // PDG
// if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) {
// TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes);
// c2->Write();
// delete c2;
// }
// Write Extra Histograms
AutoWriteExtraTH1();
WriteExtraHistograms();
if (fSaveSubMeas) {
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
exp->Write(drawOpt);
}
}
// Returning
LOG(SAM) << "Written Histograms: " << fName << std::endl;
return;
}
//********************************************************************
void JointMeas1D::WriteRatioPlot() {
//********************************************************************
// Setup mc data ratios
TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str());
TH1D* mcRatio = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str());
// Extra MC Data Ratios
for (int i = 0; i < mcRatio->GetNbinsX(); i++) {
dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1));
dataRatio->SetBinError(i + 1, fDataHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1));
mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1));
mcRatio->SetBinError(i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1));
}
// Write ratios
mcRatio->Write();
dataRatio->Write();
delete mcRatio;
delete dataRatio;
}
//********************************************************************
void JointMeas1D::WriteShapePlot() {
//********************************************************************
TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
double shapeScale = 1.0;
if (fIsRawEvents) {
shapeScale = fDataHist->Integral() / fMCHist->Integral();
} else {
shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
}
mcShape->Scale(shapeScale);
std::stringstream ss;
ss << shapeScale;
mcShape->SetTitle(ss.str().c_str());
mcShape->SetLineWidth(3);
mcShape->SetLineStyle(7);
mcShape->Write();
delete mcShape;
}
//********************************************************************
void JointMeas1D::WriteShapeRatioPlot() {
//********************************************************************
// Get a mcshape histogram
TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
double shapeScale = 1.0;
if (fIsRawEvents) {
shapeScale = fDataHist->Integral() / fMCHist->Integral();
} else {
shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
}
mcShape->Scale(shapeScale);
// Create shape ratio histograms
TH1D* mcShapeRatio = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str());
TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str());
// Divide the histograms
mcShapeRatio->Divide(mcShape);
dataShapeRatio->Divide(mcShape);
// Colour the shape ratio plots
mcShapeRatio->SetLineWidth(3);
mcShapeRatio->SetLineStyle(7);
mcShapeRatio->Write();
dataShapeRatio->Write();
delete mcShapeRatio;
delete dataShapeRatio;
}
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "JointMeas1D.h"
/*
Constructor/Deconstuctor
*/
/*
Setup Functions
*/
//********************************************************************
void JointMeas1D::SetupMeasurement(std::string input, std::string type,
FitWeight* rw, std::string fkdt) {
//********************************************************************
// For joint samples, input files are given as a semi-colon seperated list.
// Parse this list and save it for later, and set up the types etc.
if (FitPar::Config().GetParB("EventManager")) {
ERR(FTL) << "Event Manager does not yet work with JointMeas1D Samples" << std::endl;
ERR(FTL) << "If you want good predictions for " << fName << " then run with it turned off! (-q EventManager=0)" << std::endl;
}
fSubInFiles.clear();
std::vector<std::string> entries = GeneralUtils::ParseToStr(input, ";");
if (entries.size() < 2) {
ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon "
"separated input files, but recieved: \""
<< input << "\"" << std::endl;
throw;
}
std::vector<std::string> first_file_descriptor =
GeneralUtils::ParseToStr(entries.front(), ":");
if (first_file_descriptor.size() != 2) {
ERR(FTL) << "Found Joint measurement where the input file had no type: \""
<< input << "\", expected \"INPUTTYPE:File.root;File2.root\"."
<< std::endl;
throw;
}
std::string inpType = first_file_descriptor[0];
for (std::vector<std::string>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) {
std::stringstream ss("");
ss << inpType << ":" << (*iter);
fSubInFiles.push_back(ss.str());
} else {
fSubInFiles.push_back(*iter);
}
}
// Set Engine and Fake Data
fRW = rw;
fFakeDataInput = fkdt;
// Set Fit Options
SetFitOptions(type);
return;
}
/*
XSec Functions
*/
//********************************************************************
double JointMeas1D::TotalIntegratedFlux(std::string intOpt, double low,
double high) {
//********************************************************************
double totalflux = 0.0;
// Destroy the job for sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
double expflux = exp->TotalIntegratedFlux(intOpt, low, high);
// Fill flux options
if (fIsRatio) {
totalflux = expflux;
break;
}
if (fIsSummed) {
totalflux += expflux;
}
}
return totalflux;
}
/*
Reconfigure Functions
*/
//********************************************************************
void JointMeas1D::Reconfigure() {
//********************************************************************
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
exp->Reconfigure();
}
ConvertEventRates();
return;
}
//********************************************************************
void JointMeas1D::ConvertEventRates() {
//********************************************************************
// Apply Event Scaling
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = static_cast<MeasurementBase*>(*expIter);
exp->ScaleEvents();
}
// Joint function called by top level class
MakePlots();
// Do Final Normalisation
ApplyNormScale(fRW->GetSampleNorm(this->fName));
}
//********************************************************************
void JointMeas1D::MakePlots() {
//********************************************************************
// Reset the 1D histograms but not the subClasses
ResetAll();
// If Summed
if (fIsSummed) {
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = static_cast<MeasurementBase*>(*expIter);
this->fMCHist->Add(exp->GetMCList().at(0));
this->fMCFine->Add(exp->GetFineList().at(0));
}
return;
}
// If Ratio
if (fIsRatio) {
int sample = 0;
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
if (sample == 0) {
this->fMCHist->Add(exp->GetMCList().at(0));
this->fMCFine->Add(exp->GetFineList().at(0));
} else if (sample == 1) {
this->fMCHist->Divide(exp->GetMCList().at(0));
this->fMCFine->Divide(exp->GetFineList().at(0));
} else {
break;
}
sample++;
}
return;
}
return;
}
/*
Access Functions
*/
//********************************************************************
std::vector<TH1*> JointMeas1D::GetMCList() {
//********************************************************************
// Make Default Vector
std::vector<TH1*> tempVect;
tempVect.push_back(this->fMCHist);
// Return vector from all sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
std::vector<TH1*> subTempVect = exp->GetMCList();
for (UInt_t i = 0; i < subTempVect.size(); i++) {
tempVect.push_back(subTempVect.at(i));
}
}
return tempVect;
}
//********************************************************************
std::vector<TH1*> JointMeas1D::GetDataList() {
//********************************************************************
// Make Default Vector
std::vector<TH1*> tempVect;
tempVect.push_back(this->fDataHist);
// Return vector from all sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
std::vector<TH1*> subTempVect = exp->GetDataList();
for (UInt_t i = 0; i < subTempVect.size(); i++) {
tempVect.push_back(subTempVect.at(i));
}
}
return tempVect;
}
//********************************************************************
std::vector<TH1*> JointMeas1D::GetFineList() {
//********************************************************************
// Make Default Vector
std::vector<TH1*> tempVect;
tempVect.push_back(this->fMCFine);
// Return vector from all sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
std::vector<TH1*> subTempVect = exp->GetFineList();
for (UInt_t i = 0; i < subTempVect.size(); i++) {
tempVect.push_back(subTempVect.at(i));
}
}
return tempVect;
}
//********************************************************************
std::vector<TH1*> JointMeas1D::GetMaskList() {
//********************************************************************
// Make Default Vector
std::vector<TH1*> tempVect;
tempVect.push_back(this->fMaskHist);
// Return vector from all sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
std::vector<TH1*> subTempVect = exp->GetMaskList();
for (UInt_t i = 0; i < subTempVect.size(); i++) {
tempVect.push_back(subTempVect.at(i));
}
}
return tempVect;
}
//********************************************************************
std::vector<TH1*> JointMeas1D::GetFluxList() {
//********************************************************************
// Make Default Vector
std::vector<TH1*> tempVect;
tempVect.push_back(MeasurementBase::GetFluxHistogram());
// Return vector from all sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
std::vector<TH1*> subTempVect = exp->GetFluxList();
for (UInt_t i = 0; i < subTempVect.size(); i++) {
tempVect.push_back(subTempVect.at(i));
}
}
return tempVect;
}
//********************************************************************
std::vector<TH1*> JointMeas1D::GetEventRateList() {
//********************************************************************
// Make Default Vector
std::vector<TH1*> tempVect;
tempVect.push_back(MeasurementBase::GetEventHistogram());
// Return vector from all sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
std::vector<TH1*> subTempVect = exp->GetEventRateList();
for (UInt_t i = 0; i < subTempVect.size(); i++) {
tempVect.push_back(subTempVect.at(i));
}
}
return tempVect;
}
//********************************************************************
std::vector<TH1*> JointMeas1D::GetXSecList() {
//********************************************************************
// Make Default Vector
std::vector<TH1*> tempVect;
tempVect.push_back(MeasurementBase::GetXSecHistogram());
// Return vector from all sub samples
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
std::vector<TH1*> subTempVect = exp->GetXSecList();
for (UInt_t i = 0; i < subTempVect.size(); i++) {
tempVect.push_back(subTempVect.at(i));
}
}
return tempVect;
}
//********************************************************************
TH1D* JointMeas1D::GetCombinedFlux() {
//********************************************************************
TH1D* newflux = NULL;
int sample = 0;
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
// Get flux from experiment
std::vector<TH1*> fluxVect = exp->GetFluxList();
// Setup newflux
if (sample == 0) {
newflux = (TH1D*)fluxVect.at(0);
newflux->Reset();
}
// Add all fluxes
for (UInt_t i = 0; i < fluxVect.size(); i++) {
newflux->Add((TH1D*)fluxVect.at(i));
sample++;
}
}
if (!newflux){
ERR(FTL) << "No combined flux setup in JointMeas1D" << std::endl;
}
return newflux;
}
//********************************************************************
TH1D* JointMeas1D::GetCombinedEventRate() {
//********************************************************************
TH1D* newflux = NULL;
int sample = 0;
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
MeasurementBase* exp = *expIter;
// Get flux from experiment
std::vector<TH1*> fluxVect = exp->GetFluxList();
// Setup newflux
if (sample == 0) {
newflux = (TH1D*)fluxVect.at(0);
newflux->Reset();
}
// Add all fluxes
for (UInt_t i = 0; i < fluxVect.size(); i++) {
newflux->Add(fluxVect.at(i));
sample++;
}
}
if (!newflux){
ERR(FTL) << "No combined event rate setup in JointMeas1D" << std::endl;
}
return newflux;
}
//********************************************************************
std::vector<MeasurementBase*> JointMeas1D::GetSubSamples() {
//********************************************************************
std::vector<MeasurementBase*> exps;
for (std::vector<MeasurementBase*>::const_iterator expIter =
fSubChain.begin();
expIter != fSubChain.end(); expIter++) {
exps.push_back(*expIter);
}
return exps;
}
//// CRAP TO BE REMOVED
//********************************************************************
void JointMeas1D::SetDataValues(std::string dataFile) {
//********************************************************************
// Override this function if the input file isn't in a suitable format
LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl;
fDataHist =
PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles);
fDataTrue = (TH1D*)fDataHist->Clone();
// Number of data points is number of bins
fNDataPointsX = fDataHist->GetXaxis()->GetNbins();
return;
};
//********************************************************************
void JointMeas1D::SetDataFromDatabase(std::string inhistfile,
std::string histname) {
//********************************************************************
LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
<< std::endl;
fDataHist = PlotUtils::GetTH1DFromRootFile(
(GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname);
fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
return;
};
//********************************************************************
void JointMeas1D::SetDataFromFile(std::string inhistfile,
std::string histname) {
//********************************************************************
LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
<< std::endl;
fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname);
fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
return;
};
//********************************************************************
void JointMeas1D::SetCovarMatrix(std::string covarFile) {
//********************************************************************
// Covariance function, only really used when reading in the MB Covariances.
TFile* tempFile = new TFile(covarFile.c_str(), "READ");
TH2D* covarPlot = new TH2D();
// TH2D* decmpPlot = new TH2D();
TH2D* covarInvPlot = new TH2D();
TH2D* fFullCovarPlot = new TH2D();
std::string covName = "";
std::string covOption = FitPar::Config().GetParS("thrown_covariance");
if (fIsShape || fIsFree) covName = "shp_";
if (fIsDiag)
covName += "diag";
else
covName += "full";
covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str());
if (!covOption.compare("SUB"))
fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
else if (!covOption.compare("FULL"))
fFullCovarPlot = (TH2D*)tempFile->Get("fullcov");
else
ERR(WRN) << "Incorrect thrown_covariance option in parameters."
<< std::endl;
int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral());
int covdim = int(fDataHist->GetNbinsX());
this->covar = new TMatrixDSym(dim);
fFullCovar = new TMatrixDSym(dim);
fDecomp = new TMatrixDSym(dim);
int row, column = 0;
row = 0;
column = 0;
for (Int_t i = 0; i < covdim; i++) {
// if (this->masked->GetBinContent(i+1) > 0) continue;
for (Int_t j = 0; j < covdim; j++) {
// if (this->masked->GetBinContent(j+1) > 0) continue;
(*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1);
(*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1);
column++;
}
column = 0;
row++;
}
// Set bin errors on data
if (!fIsDiag) {
StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar);
}
// Get Deteriminant and inverse matrix
// fCovDet = this->covar->Determinant();
TDecompSVD LU = TDecompSVD(*this->covar);
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
return;
};
//********************************************************************
// Sets the covariance matrix from a provided file in a text format
// scale is a multiplicative pre-factor to apply in the case where the
// covariance is given in some unit (e.g. 1E-38)
void JointMeas1D::SetCovarMatrixFromText(std::string covarFile, int dim,
double scale) {
//********************************************************************
// Make a counter to track the line number
int row = 0;
std::string line;
std::ifstream covarread(covarFile.c_str(), ifstream::in);
this->covar = new TMatrixDSym(dim);
fFullCovar = new TMatrixDSym(dim);
if (covarread.is_open())
LOG(SAM) << "Reading covariance matrix from file: " << covarFile
<< std::endl;
else
ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile
<< std::endl;
// Loop over the lines in the file
while (std::getline(covarread >> std::ws, line, '\n')) {
int column = 0;
// Loop over entries and insert them into matrix
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
if (entries.size() <= 1) {
ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 "
"entries on this line: "
<< row << std::endl;
}
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
(*covar)(row, column) = *iter;
(*fFullCovar)(row, column) = *iter;
column++;
}
row++;
}
covarread.close();
// Scale the actualy covariance matrix by some multiplicative factor
(*fFullCovar) *= scale;
// Robust matrix inversion method
TDecompSVD LU = TDecompSVD(*this->covar);
// THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH
delete this->covar;
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
// Now need to multiply by the scaling factor
// If the covariance
(*this->covar) *= 1. / (scale);
return;
};
//********************************************************************
void JointMeas1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) {
//********************************************************************
// Make a counter to track the line number
int row = 0;
std::string line;
std::ifstream corr(corrFile.c_str(), ifstream::in);
this->covar = new TMatrixDSym(dim);
this->fFullCovar = new TMatrixDSym(dim);
if (corr.is_open())
LOG(SAM) << "Reading and converting correlation matrix from file: "
<< corrFile << std::endl;
else {
ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile
<< std::endl;
exit(-1);
}
while (std::getline(corr >> std::ws, line, '\n')) {
int column = 0;
// Loop over entries and insert them into matrix
// Multiply by the errors to get the covariance, rather than the correlation
// matrix
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 *
this->fDataHist->GetBinError(column + 1) * 1E38;
if (val == 0) {
ERR(FTL) << "Found a zero value in the covariance matrix, assuming "
"this is an error!"
<< std::endl;
exit(-1);
}
(*this->covar)(row, column) = val;
(*this->fFullCovar)(row, column) = val;
column++;
}
row++;
}
// Robust matrix inversion method
TDecompSVD LU = TDecompSVD(*this->covar);
delete this->covar;
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
return;
};
//********************************************************************
// FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76.
// If this is the case we need to scale it so that the chi2 contribution is correct
// NUISANCE internally assumes the covariance matrix has units of 1E76
void JointMeas1D::SetCovarFromDataFile(std::string covarFile,
std::string covName, bool FullUnits) {
//********************************************************************
LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName
<< std::endl;
TFile* tempFile = new TFile(covarFile.c_str(), "READ");
TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str());
covPlot->SetDirectory(0);
// Scale the covariance matrix if it comes in normal units
if (FullUnits) {
covPlot->Scale(1.E76);
}
int dim = covPlot->GetNbinsX();
fFullCovar = new TMatrixDSym(dim);
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++) {
(*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1);
}
}
this->covar = (TMatrixDSym*)fFullCovar->Clone();
fDecomp = (TMatrixDSym*)fFullCovar->Clone();
TDecompSVD LU = TDecompSVD(*this->covar);
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
TDecompChol LUChol = TDecompChol(*fDecomp);
LUChol.Decompose();
fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), "");
return;
};
// std::vector<TH1*> JointMeas1D::GetMCList(void){
// std::vector<TH1*> temp;
// return temp;
// }
// std::vector<TH1*> JointMeas1D::GetDataList(void){
// std::vector<TH1*> temp;
// return temp;
// }
// std::vector<TH1*> JointMeas1D::GetMaskList(void){
// std::vector<TH1*> temp;
// return temp;
// }
// std::vector<TH1*> JointMeas1D::GetFineList(void){
// std::vector<TH1*> temp;
// return temp;
// }
diff --git a/src/FitBase/JointMeas1D.h b/src/FitBase/JointMeas1D.h
index a82dab3..cada32a 100644
--- a/src/FitBase/JointMeas1D.h
+++ b/src/FitBase/JointMeas1D.h
@@ -1,685 +1,688 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#ifndef JOINTMEASUREMENT_1D_H_SEEN
#define JOINTMEASUREMENT_1D_H_SEEN
/*!
* \addtogroup FitBase
* @{
*/
#include <math.h>
#include <stdlib.h>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <numeric>
#include <sstream>
#include <string>
// ROOT includes
#include <TArrayF.h>
#include <TCanvas.h>
#include <TCut.h>
#include <TDecompChol.h>
#include <TDecompSVD.h>
#include <TGraph.h>
#include <TGraphErrors.h>
#include <TH1D.h>
#include <TH2D.h>
#include <TMatrixDSym.h>
#include <TROOT.h>
#include <TSystem.h>
#include "Measurement1D.h"
// External data fit includes
#include "FitEvent.h"
#include "FitParameters.h"
#include "FitUtils.h"
#include "MeasurementBase.h"
#include "PlotUtils.h"
#include "StatUtils.h"
//********************************************************************
/// 1D Measurement base class. Histogram handling is done in this base layer.
class JointMeas1D : public MeasurementBase {
//********************************************************************
public:
/*
Constructor/Deconstuctor
*/
JointMeas1D(void);
virtual ~JointMeas1D(void);
/*
Setup Functions
*/
SampleSettings LoadSampleSettings(nuiskey samplekey);
/// \brief Setup all configs once initialised
///
/// Should be called after all configs have been setup inside fSettings container.
/// Handles the processing of inputs and setting up of types.
/// Replaces the old 'SetupMeasurement' function.
void FinaliseSampleSettings();
/// \brief Read 1D data inputs from a text file.
///
/// Inputfile should have the format: \n
/// low_binedge_1 bin_content_1 bin_error_1 \n
/// low_binedge_2 bin_content_2 bin_error_2 \n
/// .... .... .... \n
/// high_bin_edge_N 0.0 0.0
virtual void SetDataFromTextFile(std::string datafile);
/// \brief Read 1D data inputs from a root file.
///
/// inhistfile specifies the path to the root file
/// histname specifies the name of the histogram.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ';' so that: \n
/// 'myhistfile.root;myhistname' \n
/// will also work.
virtual void SetDataFromRootFile(std::string inhistfile, std::string histname = "");
/// \brief Set data bin errors to sqrt(entries)
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Sets the data errors as the sqrt of the bin contents
/// Should be use for counting experiments
virtual void SetPoissonErrors();
/// \brief Make diagonal covariance from data
///
/// \warning If no histogram passed, data must be setup first!
/// Setup the covariance inputs by taking the data histogram
/// errors and setting up a diagonal covariance matrix.
///
/// If no data is supplied, fDataHist is used if already set.
virtual void SetCovarFromDiagonal(TH1D* data = NULL);
/// \brief Read the data covariance from a text file.
///
/// Inputfile should have the format: \n
/// covariance_11 covariance_12 covariance_13 ... \n
/// covariance_21 covariance_22 covariance_23 ... \n
/// ... ... ... ... \n
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCovarFromTextFile(std::string covfile, int dim = -1);
virtual void SetCovarFromMultipleTextFiles(std::string covfiles, int dim = -1);
/// \brief Read the data covariance from a ROOT file.
///
/// - covfile specifies the full path to the file
/// - histname specifies the name of the covariance object. Both TMatrixDSym and TH2D are supported.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCovarFromRootFile(std::string covfile, std::string histname);
/// \brief Read the inverted data covariance from a text file.
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCovarInvertFromTextFile(std::string covfile, int dim = -1);
/// \brief Read the inverted data covariance from a ROOT file.
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromRootFile.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCovarInvertFromRootFile(std::string covfile, std::string histname);
/// \brief Read the data correlations from a text file.
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCorrelationFromTextFile(std::string covfile, int dim = -1);
/// \brief Read the data correlations from multiple text files.
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of first covfile.
virtual void SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim = -1);
/// \brief Read the data correlations from a ROOT file.
///
/// \warning REQUIRES DATA TO BE SET FIRST
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromRootFile.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCorrelationFromRootFile(std::string covfile, std::string histname);
+ /// \brief Try to extract a shape-only matrix from the existing covariance
+ virtual void SetShapeCovar();
/// \brief Read the cholesky decomposed covariance from a text file and turn it into a covariance
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCholDecompFromTextFile(std::string covfile, int dim = -1);
/// \brief Read the cholesky decomposed covariance from a ROOT file and turn it into a covariance
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromRootFile.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCholDecompFromRootFile(std::string covfile, std::string histname);
/// \brief Scale the data by some scale factor
virtual void ScaleData(double scale);
/// \brief Scale the covariaince and its invert/decomp by some scale factor.
virtual void ScaleCovar(double scale);
/// \brief Setup a bin masking histogram and apply masking to data
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Reads in a list of bins in a text file to be masked. Format is: \n
/// bin_index_1 1 \n
/// bin_index_2 1 \n
/// bin_index_3 1 \n
///
/// If 0 is given then a bin entry will NOT be masked. So for example: \n\n
/// 1 1 \n
/// 2 1 \n
/// 3 0 \n
/// 4 1 \n\n
/// Will mask only the 1st, 2nd, and 4th bins.
///
/// Masking can be turned on by specifiying the MASK option when creating a sample.
/// When this is passed NUISANCE will look in the following locations for the mask file:
/// - FitPar::Config().GetParS(fName + ".mask")
/// - "data/masks/" + fName + ".mask";
virtual void SetBinMask(std::string maskfile);
/// \brief Final constructor setup
/// \warning Should be called right at the end of the constructor.
///
/// Contains a series of checks to ensure the data and inputs have been setup.
/// Also creates the MC histograms needed for fitting.
virtual void FinaliseMeasurement();
/// \brief Set the current fit options from a string.
///
/// This is called twice for each sample, once to set the default
/// and once to set the current setting (if anything other than default given)
///
/// For this to work properly it requires the default and allowed types to be
/// set correctly. These should be specified as a string listing options.
///
/// To split up options so that NUISANCE can automatically detect ones that
/// are conflicting. Any options seperated with the '/' symbol are non conflicting
/// and can be given together, whereas any seperated with the ',' symbol cannot
/// be specified by the end user at the same time.
///
/// Default Type Examples:
/// - DIAG/FIX = Default option will be a diagonal covariance, with FIXED norm.
/// - MASK/SHAPE = Default option will be a masked hist, with SHAPE always on.
///
/// Allowed Type examples:
/// - 'FULL/DIAG/NORM/MASK' = Any of these options can be specified.
/// - 'FULL,FREE,SHAPE/MASK/NORM' = User can give either FULL, FREE, or SHAPE as on option.
/// MASK and NORM can also be included as options.
virtual void SetFitOptions(std::string opt);
/*
Smearing
*/
/// \brief Read in smearing matrix from file
///
/// Set the smearing matrix from a text file given the size of the matrix
virtual void SetSmearingMatrix(std::string smearfile, int truedim,
int recodim);
/// \brief Apply smearing to MC true to get MC reco
///
/// Apply smearing matrix to fMCHist using fSmearingMatrix
virtual void ApplySmearingMatrix(void);
/*
Reconfigure Functions
*/
/// \brief Create a Measurement1D box
///
/// Creates a new 1D variable box containing just fXVar.
///
/// This box is the bare minimum required by the JointFCN when
/// running fast reconfigures during a routine.
/// If for some reason a sample needs extra variables to be saved then
/// it should override this function creating its own MeasurementVariableBox
/// that contains the extra variables.
virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox1D();};
/// \brief Reset all MC histograms
///
/// Resets all standard histograms and those registered to auto
/// process to zero.
///
/// If extra histograms are not included in auto processing, then they must be reset
/// by overriding this function and doing it manually if required.
virtual void ResetAll(void);
/// \brief Fill MC Histograms from XVar
///
/// Fill standard histograms using fXVar, Weight read from the variable box.
///
/// WARNING : Any extra MC histograms need to be filled by overriding this function,
/// even if they have been set to auto process.
virtual void FillHistograms(void);
// \brief Convert event rates to final histogram
///
/// Apply standard scaling procedure to standard mc histograms to convert from
/// raw events to xsec prediction.
///
/// If any distributions have been set to auto process
/// that is done during this function call, and a differential xsec is assumed.
/// If that is not the case this function must be overriden.
virtual void ScaleEvents(void);
/// \brief Scale MC by a factor=1/norm
///
/// Apply a simple normalisation scaling if the option FREE or a norm_parameter
/// has been specified in the NUISANCE routine.
virtual void ApplyNormScale(double norm);
/*
Statistical Functions
*/
/// \brief Get Number of degrees of freedom
///
/// Returns the number bins inside the data histogram accounting for
/// any bin masking applied.
virtual int GetNDOF(void);
/// \brief Return Data/MC Likelihood at current state
///
/// Returns the likelihood of the data given the current MC prediction.
/// Diferent likelihoods definitions are used depending on the FitOptions.
virtual double GetLikelihood(void);
/*
Fake Data
*/
/// \brief Set the fake data values from either a file, or MC
///
/// - Setting from a file "path": \n
/// When reading from a file the full path must be given to a standard
/// nuisance output. The standard MC histogram should have a name that matches
/// this sample for it to be read in.
/// \n\n
/// - Setting from "MC": \n
/// If the MC option is given the current MC prediction is used as fake data.
virtual void SetFakeDataValues(std::string fakeOption);
/// \brief Reset fake data back to starting fake data
///
/// Reset the fake data back to original fake data (Reset back to before
/// ThrowCovariance was first called)
virtual void ResetFakeData(void);
/// \brief Reset fake data back to original data
///
/// Reset the data histogram back to the true original dataset for this sample
/// before any fake data was defined.
virtual void ResetData(void);
/// \brief Generate fake data by throwing the covariance.
///
/// Can be used on fake MC data or just the original dataset.
/// Call ResetFakeData or ResetData to return to values before the throw.
virtual void ThrowCovariance(void);
/// \brief Throw the data by its assigned errors and assign this to MC
///
/// Used when creating data toys by assign the MC to this thrown data
/// so that the likelihood is calculated between data and thrown data
virtual void ThrowDataToy(void);
/*
Access Functions
*/
/// \brief Returns nicely formatted MC Histogram
///
/// Format options can also be given in the samplesettings:
/// - linecolor
/// - linestyle
/// - linewidth
/// - fillcolor
/// - fillstyle
///
/// So to have a sample line colored differently in the xml cardfile put: \n
/// <sample name="MiniBooNE_CCQE_XSec_1DQ2_nu" input="NEUT:input.root"
/// linecolor="2" linestyle="7" linewidth="2" />
virtual TH1D* GetMCHistogram(void);
/// \brief Returns nicely formatted data Histogram
///
/// Format options can also be given in the samplesettings:
/// - datacolor
/// - datastyle
/// - datawidth
///
/// So to have a sample data colored differently in the xml cardfile put: \n
/// <sample name="MiniBooNE_CCQE_XSec_1DQ2_nu" input="NEUT:input.root"
/// datacolor="2" datastyle="7" datawidth="2" />
virtual TH1D* GetDataHistogram(void);
/// \brief Returns a list of all MC histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
virtual std::vector<TH1*> GetMCList(void);
/// \brief Returns a list of all Data histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
virtual std::vector<TH1*> GetDataList(void);
/// \brief Returns a list of all Mask histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
virtual std::vector<TH1*> GetMaskList(void);
/// \brief Returns a list of all Fine histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
virtual std::vector<TH1*> GetFineList(void);
/*
Write Functions
*/
/// \brief Save the current state to the current TFile directory \n
///
/// Data/MC are both saved by default.
/// A range of other histograms can be saved by setting the
/// config option 'drawopts'.
///
/// Possible options: \n
/// - FINE = Write Fine Histogram \n
/// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n
/// - FLUX = Write Flux Histogram from MC Input \n
/// - EVT = Write Event Histogram from MC Input \n
/// - XSEC = Write XSec Histogram from MC Input \n
/// - MASK = Write Mask Histogram \n
/// - COV = Write Covariance Histogram \n
/// - INVCOV = Write Inverted Covariance Histogram \n
/// - DECMOP = Write Decomp. Covariance Histogram \n
/// - RESIDUAL= Write Resudial Histograms \n
/// - RATIO = Write Data/MC Ratio Histograms \n
/// - SHAPE = Write MC Shape Histograms norm. to Data \n
/// - CANVMC = Build MC Canvas Showing Data, MC, Shape \n
/// - MODES = Write PDG Stack \n
/// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n
///
/// So to save a range of these in parameters/config.xml set: \n
/// <config drawopts='FINE/COV/SHAPE/RATIO' />
virtual void Write(std::string drawOpt);
virtual void WriteRatioPlot();
virtual void WriteShapePlot();
virtual void WriteShapeRatioPlot();
double TotalIntegratedFlux(std::string intOpt, double low,
double high);
//*
// OLD DEFUNCTIONS
//
/// OLD FUNCTION
virtual void SetupMeasurement(std::string input, std::string type,
FitWeight* rw, std::string fkdt);
/// OLD FUNCTION
virtual void SetupDefaultHist(void);
/// OLD FUNCTION
virtual void SetDataValues(std::string dataFile);
/// OLD FUNCTION
virtual void SetDataFromFile(std::string inhistfile, std::string histname);
/// OLD FUNCTION
virtual void SetDataFromDatabase(std::string inhistfile,
std::string histname);
/// OLD FUNCTION
virtual void SetCovarMatrix(std::string covarFile);
/// OLD FUNCTION
virtual void SetCovarMatrixFromText(std::string covarFile, int dim,
double scale = 1.0);
/// OLD FUNCTION
virtual void SetCovarMatrixFromCorrText(std::string covarFile, int dim);
/// OLD FUNCTION
virtual void SetCovarFromDataFile(std::string covarFile, std::string covName,
bool FullUnits = false);
////// JOINT MEAS1D Functions //////
/*
Reconfigure Functions
*/
/// Call reconfigure on every sub sample
virtual void Reconfigure();
/// Stitch the sub sample plots together to make a final fMCHist after
/// reconfigure has been called
virtual void MakePlots();
virtual std::vector<MeasurementBase*> GetSubSamples();
virtual void ConvertEventRates();
/*
Access Functions
*/
virtual std::vector<TH1*> GetFluxList();
virtual std::vector<TH1*> GetEventRateList();
virtual std::vector<TH1*> GetXSecList();
//! Return a flux integrated across all sub samples
virtual TH1D* GetCombinedFlux();
//! Return an event rate integrated across all sub samples
virtual TH1D* GetCombinedEventRate();
virtual TH1D* GetEventHistogram() { return GetCombinedEventRate(); };
virtual TH1D* GetXSecHistogram() {
ERR(WRN)
<< "XSec histogram not properly implemented for joint measurements.";
return MeasurementBase::GetXSecHistogram();
};
virtual TH1D* GetFluxHistogram() { return GetCombinedFlux(); };
protected:
// Data
TH1D* fDataHist; ///< default data histogram
TH1D* fDataOrig; ///< histogram to store original data before throws.
TH1D* fDataTrue; ///< histogram to store true dataset
std::string fPlotTitles; ///< Plot title x and y for the histograms
// MC
TH1D* fMCHist; ///< default MC Histogram used in the chi2 fits
TH1D* fMCFine; ///< finely binned MC histogram
TH1D* fMCStat; ///< histogram with unweighted events to properly calculate
TH1D* fMCWeighted; ///< Weighted histogram before xsec scaling
TH1I* fMaskHist; ///< Mask histogram for neglecting specific bins
TMatrixD* fSmearMatrix; ///< Smearing matrix (note, this is not symmetric)
TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack
// Statistical
TMatrixDSym* covar; ///< Inverted Covariance
TMatrixDSym* fFullCovar; ///< Full Covariance
TMatrixDSym* fDecomp; ///< Decomposed Covariance
TMatrixDSym* fCorrel; ///< Correlation Matrix
+ TMatrixDSym* fShapeCovar; ///< Shape-only covariance
TMatrixDSym* fCovar; ///< New FullCovar
TMatrixDSym* fInvert; ///< New covar
double fNormError; ///< Sample norm error
// Fake Data
bool fIsFakeData; ///< Flag: is the current data fake from MC
std::string fFakeDataInput; ///< Input fake data file path
TFile* fFakeDataFile; ///< Input fake data file
// Fit specific flags
std::string fFitType; ///< Current fit type
std::string fAllowedTypes; ///< Fit Types Possible
std::string fDefaultTypes; ///< Starting Default Fit Types
bool fIsShape; ///< Flag : Perform Shape-only fit
bool fIsFree; ///< Flag : Perform normalisation free fit
bool fIsDiag; ///< Flag : only include uncorrelated diagonal errors
bool fIsMask; ///< Flag : Apply bin masking
bool fIsRawEvents; ///< Flag : Are bin contents just event rates
bool fIsEnu1D; ///< Flag : Perform Flux Unfolded Scaling
bool fIsChi2SVD; ///< Flag : Use alternative Chi2 SVD Method (Do not use)
bool fAddNormPen; ///< Flag : Add a normalisation penalty term to the chi2.
bool fIsFix; ///< Flag : keeping norm fixed
bool fIsFull; ///< Flag : using full covariaince
bool fIsDifXSec; ///< Flag : creating a dif xsec
bool fIsChi2; ///< Flag : using Chi2 over LL methods
bool fIsSmeared; ///< Flag : Apply smearing?
/// OLD STUFF TO REMOVE
TH1D* fMCHist_PDG[61]; ///< REMOVE OLD MC PDG Plot
// Arrays for data entries
Double_t* fXBins; ///< REMOVE xBin edges
Double_t* fDataValues; ///< REMOVE data bin contents
Double_t* fDataErrors; ///< REMOVE data bin errors
Int_t fNDataPointsX; ///< REMOVE number of data points
//// JOINT MEAS1D OBJECTS ////
std::vector<MeasurementBase*> fSubChain; //!< Vector of experimental classes
//! that are the sub measurements
std::vector<std::string>
fSubInFiles; //!< vector of input files for each of the sub measurements.
bool fIsRatio; //!< Flag: is this sample a hist1/hist2 ratio sample
bool fIsSummed; //!< Flag: is this sample a combination hist1 + hist2
bool fSaveSubMeas; //!< Flag: Save each of the histograms from the sub
//! samples as well as this joint samples plots
double fLikelihood;
};
/*! @} */
#endif
diff --git a/src/FitBase/Measurement1D.cxx b/src/FitBase/Measurement1D.cxx
index 2b0a123..70a03a5 100644
--- a/src/FitBase/Measurement1D.cxx
+++ b/src/FitBase/Measurement1D.cxx
@@ -1,1870 +1,1896 @@
// Copyright 2016 L. Pickering, P. Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This ile 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "Measurement1D.h"
//********************************************************************
Measurement1D::Measurement1D(void) {
//********************************************************************
// XSec Scalings
fScaleFactor = -1.0;
fCurrentNorm = 1.0;
// Histograms
fDataHist = NULL;
fDataTrue = NULL;
fMCHist = NULL;
fMCFine = NULL;
fMCWeighted = NULL;
fMaskHist = NULL;
// Covar
covar = NULL;
fFullCovar = NULL;
-
+ fShapeCovar = NULL;
+
fCovar = NULL;
fInvert = NULL;
fDecomp = NULL;
-
+
// Fake Data
fFakeDataInput = "";
fFakeDataFile = NULL;
// Options
fDefaultTypes = "FIX/FULL/CHI2";
fAllowedTypes =
"FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK/NOWIDTH";
fIsFix = false;
fIsShape = false;
fIsFree = false;
fIsDiag = false;
fIsFull = false;
fAddNormPen = false;
fIsMask = false;
fIsChi2SVD = false;
fIsRawEvents = false;
fIsNoWidth = false;
fIsDifXSec = false;
fIsEnu1D = false;
// Inputs
fInput = NULL;
fRW = NULL;
// Extra Histograms
fMCHist_Modes = NULL;
}
//********************************************************************
Measurement1D::~Measurement1D(void) {
//********************************************************************
if (fDataHist) delete fDataHist;
if (fDataTrue) delete fDataTrue;
if (fMCHist) delete fMCHist;
if (fMCFine) delete fMCFine;
if (fMCWeighted) delete fMCWeighted;
if (fMaskHist) delete fMaskHist;
if (covar) delete covar;
if (fFullCovar) delete fFullCovar;
+ if (fShapeCovar) delete fShapeCovar;
if (fCovar) delete fCovar;
if (fInvert) delete fInvert;
if (fDecomp) delete fDecomp;
}
//********************************************************************
void Measurement1D::FinaliseSampleSettings() {
//********************************************************************
MeasurementBase::FinaliseSampleSettings();
// Setup naming + renaming
fName = fSettings.GetName();
fSettings.SetS("originalname", fName);
if (fSettings.Has("rename")) {
fName = fSettings.GetS("rename");
fSettings.SetS("name", fName);
}
// Setup all other options
LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl;
if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) {
fIsRawEvents = true;
LOG(SAM) << "Found event rate measurement but using poisson likelihoods."
<< std::endl;
}
if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) {
fIsEnu1D = true;
LOG(SAM) << "::" << fName << "::" << std::endl;
LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
<< "not flux averaged!" << std::endl;
}
if (fIsEnu1D && fIsRawEvents) {
LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
"really correct?!"
<< std::endl;
LOG(SAM) << "Check experiment constructor for " << fName
<< " and correct this!" << std::endl;
LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
exit(-1);
}
if (!fRW) fRW = FitBase::GetRW();
if (!fInput and !fIsJoint) SetupInputs(fSettings.GetS("input"));
// Setup options
SetFitOptions(fDefaultTypes); // defaults
SetFitOptions(fSettings.GetS("type")); // user specified
EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min"));
EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max"));
if (fAddNormPen) {
if (fNormError <= 0.0) {
ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl;
ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl;
throw;
}
}
}
//********************************************************************
void Measurement1D::CreateDataHistogram(int dimx, double* binx) {
//********************************************************************
if (fDataHist) delete fDataHist;
fDataHist = new TH1D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(),
dimx, binx) ;
}
//********************************************************************
void Measurement1D::SetDataFromTextFile(std::string datafile) {
//********************************************************************
LOG(SAM) << "Reading data from text file: " << datafile << std::endl;
fDataHist = PlotUtils::GetTH1DFromFile(datafile,
fSettings.GetName() + "_data",
fSettings.GetFullTitles());
}
//********************************************************************
void Measurement1D::SetDataFromRootFile(std::string datafile,
std::string histname) {
//********************************************************************
LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl;
fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname);
fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(),
(fSettings.GetFullTitles()).c_str());
return;
};
//********************************************************************
void Measurement1D::SetEmptyData(){
//********************************************************************
fDataHist = new TH1D("EMPTY_DATA","EMPTY_DATA",1,0.0,1.0);
}
//********************************************************************
void Measurement1D::SetPoissonErrors() {
//********************************************************************
if (!fDataHist) {
ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl;
ERR(FTL) << "Setup Data First!" << std::endl;
throw;
}
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1)));
}
}
//********************************************************************
void Measurement1D::SetCovarFromDiagonal(TH1D* data) {
//********************************************************************
if (!data and fDataHist) {
data = fDataHist;
}
if (data) {
LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl;
fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
} else {
ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl;
}
// if (!fIsDiag) {
// ERR(FTL) << "SetCovarMatrixFromDiag called for measurement "
// << "that is not set as diagonal." << std::endl;
// throw;
// }
}
//********************************************************************
void Measurement1D::SetCovarFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) {
dim = fDataHist->GetNbinsX();
}
LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl;
fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement1D::SetCovarFromMultipleTextFiles(std::string covfiles, int dim) {
//********************************************************************
if (dim == -1) {
dim = fDataHist->GetNbinsX();
}
std::vector<std::string> covList = GeneralUtils::ParseToStr(covfiles, ";");
fFullCovar = new TMatrixDSym(dim);
for (uint i = 0; i < covList.size(); ++i){
LOG(SAM) << "Reading covariance from text file: " << covList[i] << std::endl;
TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(covList[i], dim);
(*fFullCovar) += (*temp_cov);
delete temp_cov;
}
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement1D::SetCovarFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl;
fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement1D::SetCovarInvertFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) {
dim = fDataHist->GetNbinsX();
}
LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl;
covar = StatUtils::GetCovarFromTextFile(covfile, dim);
fFullCovar = StatUtils::GetInvert(covar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl;
covar = StatUtils::GetCovarFromRootFile(covfile, histname);
fFullCovar = StatUtils::GetInvert(covar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement1D::SetCorrelationFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) dim = fDataHist->GetNbinsX();
LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl;
TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim);
if (!fDataHist) {
ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
<< "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
throw;
}
// Fill covar from data errors and correlations
fFullCovar = new TMatrixDSym(dim);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
(*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
}
}
// Fill other covars.
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete correlation;
}
//********************************************************************
void Measurement1D::SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim) {
//********************************************************************
if (dim == -1) {
dim = fDataHist->GetNbinsX();
}
std::vector<std::string> corrList = GeneralUtils::ParseToStr(corrfiles, ";");
fFullCovar = new TMatrixDSym(dim);
for (uint i = 0; i < corrList.size(); ++i){
LOG(SAM) << "Reading covariance from text file: " << corrList[i] << std::endl;
TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(corrList[i], dim);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
(*temp_cov)(i, j) = (*temp_cov)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
}
}
(*fFullCovar) += (*temp_cov);
delete temp_cov;
}
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl;
TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname);
if (!fDataHist) {
ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
<< "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
throw;
}
// Fill covar from data errors and correlations
fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX());
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
(*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
}
}
// Fill other covars.
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete correlation;
}
//********************************************************************
void Measurement1D::SetCholDecompFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) {
dim = fDataHist->GetNbinsX();
}
LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl;
TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim);
TMatrixD* trans = (TMatrixD*)temp->Clone();
trans->T();
(*trans) *= (*temp);
fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), "");
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete temp;
delete trans;
}
//********************************************************************
void Measurement1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl;
TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname);
TMatrixD* trans = (TMatrixD*)temp->Clone();
trans->T();
(*trans) *= (*temp);
fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), "");
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete temp;
delete trans;
}
+void Measurement1D::SetShapeCovar(){
+
+ // Return if this is missing any pre-requisites
+ if (!fFullCovar) return;
+ if (!fDataHist) return;
+
+ // Also return if it's bloody stupid under the circumstances
+ if (fIsDiag) return;
+
+ fShapeCovar = StatUtils::ExtractShapeOnlyCovar(fFullCovar, fDataHist);
+ return;
+}
//********************************************************************
void Measurement1D::ScaleData(double scale) {
//********************************************************************
fDataHist->Scale(scale);
}
//********************************************************************
void Measurement1D::ScaleDataErrors(double scale) {
//********************************************************************
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinError(i + 1, fDataHist->GetBinError(i + 1) * scale);
}
}
//********************************************************************
void Measurement1D::ScaleCovar(double scale) {
//********************************************************************
(*fFullCovar) *= scale;
(*covar) *= 1.0 / scale;
(*fDecomp) *= sqrt(scale);
}
//********************************************************************
void Measurement1D::SetBinMask(std::string maskfile) {
//********************************************************************
if (!fIsMask) return;
LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl;
// Create a mask histogram with dim of data
int nbins = fDataHist->GetNbinsX();
fMaskHist =
new TH1I((fSettings.GetName() + "_BINMASK").c_str(),
(fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins);
std::string line;
std::ifstream mask(maskfile.c_str(), ifstream::in);
if (!mask.is_open()) {
LOG(FTL) << " Cannot find mask file." << std::endl;
throw;
}
while (std::getline(mask >> std::ws, line, '\n')) {
std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
// Skip lines with poorly formatted lines
if (entries.size() < 2) {
LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line
<< std::endl;
continue;
}
// The first index should be the bin number, the second should be the mask
// value.
int val = 0;
if (entries[1] > 0) val = 1;
fMaskHist->SetBinContent(entries[0], val);
}
// Apply masking by setting masked data bins to zero
PlotUtils::MaskBins(fDataHist, fMaskHist);
return;
}
//********************************************************************
void Measurement1D::FinaliseMeasurement() {
//********************************************************************
LOG(SAM) << "Finalising Measurement: " << fName << std::endl;
if (fSettings.GetB("onlymc")){
if (fDataHist) delete fDataHist;
fDataHist = new TH1D("empty_data","empty_data",1,0.0,1.0);
}
// Make sure data is setup
if (!fDataHist) {
ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl;
throw;
}
// Make sure covariances are setup
if (!fFullCovar) {
fIsDiag = true;
SetCovarFromDiagonal(fDataHist);
}
if (!covar) {
covar = StatUtils::GetInvert(fFullCovar);
}
if (!fDecomp) {
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
// Push the diagonals of fFullCovar onto the data histogram
// Comment this out until the covariance/data scaling is consistent!
- // StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar);
+ StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38);
+
+ // If shape only, set covar and fDecomp using the shape-only matrix (if set)
+ if (fIsShape && fShapeCovar){
+ if (covar) delete covar;
+ covar = StatUtils::GetInvert(fShapeCovar);
+ if (fDecomp) delete fDecomp;
+ fDecomp = StatUtils::GetDecomp(fFullCovar);
+ }
// Setup fMCHist from data
fMCHist = (TH1D*)fDataHist->Clone();
fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(),
(fSettings.GetFullTitles()).c_str());
fMCHist->Reset();
// Setup fMCFine
fMCFine = new TH1D("mcfine", "mcfine", fDataHist->GetNbinsX() * 8,
fMCHist->GetBinLowEdge(1),
fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1));
fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(),
(fSettings.GetFullTitles()).c_str());
fMCFine->Reset();
// Setup MC Stat
fMCStat = (TH1D*)fMCHist->Clone();
fMCStat->Reset();
// Search drawopts for possible types to include by default
std::string drawopts = FitPar::Config().GetParS("drawopts");
if (drawopts.find("MODES") != std::string::npos) {
fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(),
("True Channels"), fMCHist);
SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write);
}
// Setup bin masks using sample name
if (fIsMask) {
std::string curname = fName;
std::string origname = fSettings.GetS("originalname");
// Check rename.mask
std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask");
// Check origname.mask
if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask");
// Check database
if (maskloc.empty()) {
maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask";
}
// Setup Bin Mask
SetBinMask(maskloc);
}
if (fScaleFactor < 0) {
ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl;
ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl;
ERR(FTL) << "EXITING" << std::endl;
throw;
}
// Create and fill Weighted Histogram
if (!fMCWeighted) {
fMCWeighted = (TH1D*)fMCHist->Clone();
fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(),
(fName + "_MCWGHTS" + fPlotTitles).c_str());
fMCWeighted->GetYaxis()->SetTitle("Weighted Events");
}
}
//********************************************************************
void Measurement1D::SetFitOptions(std::string opt) {
//********************************************************************
// Do nothing if default given
if (opt == "DEFAULT") return;
// CHECK Conflicting Fit Options
std::vector<std::string> fit_option_allow =
GeneralUtils::ParseToStr(fAllowedTypes, "/");
for (UInt_t i = 0; i < fit_option_allow.size(); i++) {
std::vector<std::string> fit_option_section =
GeneralUtils::ParseToStr(fit_option_allow.at(i), ",");
bool found_option = false;
for (UInt_t j = 0; j < fit_option_section.size(); j++) {
std::string av_opt = fit_option_section.at(j);
if (!found_option and opt.find(av_opt) != std::string::npos) {
found_option = true;
} else if (found_option and opt.find(av_opt) != std::string::npos) {
ERR(FTL) << "ERROR: Conflicting fit options provided: "
<< opt << std::endl
<< "Conflicting group = " << fit_option_section.at(i) << std::endl
<< "You should only supply one of these options in card file." << std::endl;
throw;
}
}
}
// Check all options are allowed
std::vector<std::string> fit_options_input =
GeneralUtils::ParseToStr(opt, "/");
for (UInt_t i = 0; i < fit_options_input.size(); i++) {
if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) {
ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i)
<< "' Provided is not allowed for this measurement."
<< std::endl;
ERR(FTL) << "Fit Options should be provided as a '/' seperated list "
"(e.g. FREE/DIAG/NORM)"
<< std::endl;
ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes
<< "'" << std::endl;
throw;
}
}
// Set TYPE
fFitType = opt;
// FIX,SHAPE,FREE
if (opt.find("FIX") != std::string::npos) {
fIsFree = fIsShape = false;
fIsFix = true;
} else if (opt.find("SHAPE") != std::string::npos) {
fIsFree = fIsFix = false;
fIsShape = true;
} else if (opt.find("FREE") != std::string::npos) {
fIsFix = fIsShape = false;
fIsFree = true;
}
// DIAG,FULL (or default to full)
if (opt.find("DIAG") != std::string::npos) {
fIsDiag = true;
fIsFull = false;
} else if (opt.find("FULL") != std::string::npos) {
fIsDiag = false;
fIsFull = true;
}
// CHI2/LL (OTHERS?)
if (opt.find("LOG") != std::string::npos) {
fIsChi2 = false;
ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl;
ERR(FTL) << "Try to use a chi2!" << std::endl;
throw;
} else {
fIsChi2 = true;
}
// EXTRAS
if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
if (opt.find("NOWIDTH") != std::string::npos) fIsNoWidth = true;
if (opt.find("DIF") != std::string::npos) fIsDifXSec = true;
if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true;
if (opt.find("NORM") != std::string::npos) fAddNormPen = true;
if (opt.find("MASK") != std::string::npos) fIsMask = true;
return;
};
//********************************************************************
void Measurement1D::SetSmearingMatrix(std::string smearfile, int truedim,
int recodim) {
//********************************************************************
// The smearing matrix describes the migration from true bins (rows) to reco
// bins (columns)
// Counter over the true bins!
int row = 0;
std::string line;
std::ifstream smear(smearfile.c_str(), ifstream::in);
// Note that the smearing matrix may be rectangular.
fSmearMatrix = new TMatrixD(truedim, recodim);
if (smear.is_open())
LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl;
else
ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile
<< std::endl;
while (std::getline(smear >> std::ws, line, '\n')) {
int column = 0;
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
(*fSmearMatrix)(row, column) =
(*iter) / 100.; // Convert to fraction from
// percentage (this may not be
// general enough)
column++;
}
row++;
}
return;
}
//********************************************************************
void Measurement1D::ApplySmearingMatrix() {
//********************************************************************
if (!fSmearMatrix) {
ERR(WRN) << fName
<< ": attempted to apply smearing matrix, but none was set"
<< std::endl;
return;
}
TH1D* unsmeared = (TH1D*)fMCHist->Clone();
TH1D* smeared = (TH1D*)fMCHist->Clone();
smeared->Reset();
// Loop over reconstructed bins
// true = row; reco = column
for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) {
// Sum up the constributions from all true bins
double rBinVal = 0;
// Loop over true bins
for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) {
rBinVal +=
(*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1);
}
smeared->SetBinContent(rbin + 1, rBinVal);
}
fMCHist = (TH1D*)smeared->Clone();
return;
}
/*
Reconfigure LOOP
*/
//********************************************************************
void Measurement1D::ResetAll() {
//********************************************************************
fMCHist->Reset();
fMCFine->Reset();
fMCStat->Reset();
return;
};
//********************************************************************
void Measurement1D::FillHistograms() {
//********************************************************************
if (Signal) {
fMCHist->Fill(fXVar, Weight);
fMCFine->Fill(fXVar, Weight);
fMCStat->Fill(fXVar, 1.0);
if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight);
}
return;
};
//********************************************************************
void Measurement1D::ScaleEvents() {
//********************************************************************
// Fill MCWeighted;
// for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
// fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1));
// fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1));
// }
// Setup Stat ratios for MC and MC Fine
double* statratio = new double[fMCHist->GetNbinsX()];
for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
if (fMCHist->GetBinContent(i + 1) != 0) {
statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1);
} else {
statratio[i] = 0.0;
}
}
double* statratiofine = new double[fMCFine->GetNbinsX()];
for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
if (fMCFine->GetBinContent(i + 1) != 0) {
statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1);
} else {
statratiofine[i] = 0.0;
}
}
// Scaling for raw event rates
if (fIsRawEvents) {
double datamcratio = fDataHist->Integral() / fMCHist->Integral();
fMCHist->Scale(datamcratio);
fMCFine->Scale(datamcratio);
if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio);
// Scaling for XSec as function of Enu
} else if (fIsEnu1D) {
PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(),
GetEventHistogram(), fScaleFactor,
fNEvents);
PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(),
GetEventHistogram(), fScaleFactor,
fNEvents);
// if (fMCHist_Modes) {
// PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(),
// GetEventHistogram(), fScaleFactor,
// fNEvents);
// }
} else if (fIsNoWidth) {
fMCHist->Scale(fScaleFactor);
fMCFine->Scale(fScaleFactor);
if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor);
// Any other differential scaling
} else {
fMCHist->Scale(fScaleFactor, "width");
fMCFine->Scale(fScaleFactor, "width");
if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width");
}
// Proper error scaling - ROOT Freaks out with xsec weights sometimes
for (int i = 0; i < fMCStat->GetNbinsX(); i++) {
fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]);
}
for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]);
}
// Clean up
delete statratio;
delete statratiofine;
return;
};
//********************************************************************
void Measurement1D::ApplyNormScale(double norm) {
//********************************************************************
fCurrentNorm = norm;
fMCHist->Scale(1.0 / norm);
fMCFine->Scale(1.0 / norm);
return;
};
/*
Statistic Functions - Outsources to StatUtils
*/
//********************************************************************
int Measurement1D::GetNDOF() {
//********************************************************************
int ndof = fDataHist->GetNbinsX();
if (fMaskHist and fIsMask) ndof -= fMaskHist->Integral();
return ndof;
}
//********************************************************************
double Measurement1D::GetLikelihood() {
//********************************************************************
// If this is for a ratio, there is no data histogram to compare to!
if (fNoData || !fDataHist) return 0.;
// Apply Masking to MC if Required.
if (fIsMask and fMaskHist) {
PlotUtils::MaskBins(fMCHist, fMaskHist);
}
// Sort Shape Scaling
double scaleF = 0.0;
// TODO Include !fIsRawEvents
if (fIsShape) {
if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) {
scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") /
fMCHist->Integral(1, fMCHist->GetNbinsX(), "width");
fMCHist->Scale(scaleF);
fMCFine->Scale(scaleF);
}
}
// Likelihood Calculation
double stat = 0.;
if (fIsChi2) {
if (fIsRawEvents) {
stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist);
} else if (fIsDiag) {
stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist);
} else if (!fIsDiag and !fIsRawEvents) {
stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist);
}
}
// Sort Penalty Terms
if (fAddNormPen) {
double penalty =
(1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError);
stat += penalty;
}
// Return to normal scaling
if (fIsShape) { // and !FitPar::Config().GetParB("saveshapescaling")) {
fMCHist->Scale(1. / scaleF);
fMCFine->Scale(1. / scaleF);
}
fLikelihood = stat;
return stat;
}
/*
Fake Data Functions
*/
//********************************************************************
void Measurement1D::SetFakeDataValues(std::string fakeOption) {
//********************************************************************
// Setup original/datatrue
TH1D* tempdata = (TH1D*) fDataHist->Clone();
if (!fIsFakeData) {
fIsFakeData = true;
// Make a copy of the original data histogram.
if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str());
} else {
ResetFakeData();
}
// Setup Inputs
fFakeDataInput = fakeOption;
LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl;
// From MC
if (fFakeDataInput.compare("MC") == 0) {
fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str());
// Fake File
} else {
if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ");
fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str());
}
// Setup Data Hist
fDataHist->SetNameTitle((fName + "_FAKE").c_str(),
(fName + fPlotTitles).c_str());
// Replace Data True
if (fDataTrue) delete fDataTrue;
fDataTrue = (TH1D*)fDataHist->Clone();
fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(),
(fName + fPlotTitles).c_str());
// Make a new covariance for fake data hist.
int nbins = fDataHist->GetNbinsX();
double alpha_i = 0.0;
double alpha_j = 0.0;
for (int i = 0; i < nbins; i++) {
for (int j = 0; j < nbins; j++) {
alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1);
alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1);
(*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j);
}
}
// Setup Covariances
if (covar) delete covar;
covar = StatUtils::GetInvert(fFullCovar);
if (fDecomp) delete fDecomp;
fDecomp = StatUtils::GetInvert(fFullCovar);
delete tempdata;
return;
};
//********************************************************************
void Measurement1D::ResetFakeData() {
//********************************************************************
if (fIsFakeData) {
if (fDataHist) delete fDataHist;
fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str());
}
}
//********************************************************************
void Measurement1D::ResetData() {
//********************************************************************
if (fIsFakeData) {
if (fDataHist) delete fDataHist;
fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str());
}
fIsFakeData = false;
}
//********************************************************************
void Measurement1D::ThrowCovariance() {
//********************************************************************
// Take a fDecomposition and use it to throw the current dataset.
// Requires fDataTrue also be set incase used repeatedly.
if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone();
if (fDataHist) delete fDataHist;
fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
return;
};
//********************************************************************
void Measurement1D::ThrowDataToy(){
//********************************************************************
if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone();
if (fMCHist) delete fMCHist;
fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
}
/*
Access Functions
*/
//********************************************************************
TH1D* Measurement1D::GetMCHistogram() {
//********************************************************************
if (!fMCHist) return fMCHist;
std::ostringstream chi2;
chi2 << std::setprecision(5) << this->GetLikelihood();
int linecolor = kRed;
int linestyle = 1;
int linewidth = 1;
int fillcolor = 0;
int fillstyle = 1001;
// if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor");
// if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle");
// if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth");
// if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor");
// if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle");
fMCHist->SetTitle(chi2.str().c_str());
fMCHist->SetLineColor(linecolor);
fMCHist->SetLineStyle(linestyle);
fMCHist->SetLineWidth(linewidth);
fMCHist->SetFillColor(fillcolor);
fMCHist->SetFillStyle(fillstyle);
return fMCHist;
};
//********************************************************************
TH1D* Measurement1D::GetDataHistogram() {
//********************************************************************
if (!fDataHist) return fDataHist;
int datacolor = kBlack;
int datastyle = 1;
int datawidth = 1;
// if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor");
// if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle");
// if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth");
fDataHist->SetLineColor(datacolor);
fDataHist->SetLineWidth(datawidth);
fDataHist->SetMarkerStyle(datastyle);
return fDataHist;
};
/*
Write Functions
*/
// Save all the histograms at once
//********************************************************************
void Measurement1D::Write(std::string drawOpt) {
//********************************************************************
// Get Draw Options
drawOpt = FitPar::Config().GetParS("drawopts");
// Write Settigns
if (drawOpt.find("SETTINGS") != std::string::npos){
fSettings.Set("#chi^{2}",fLikelihood);
fSettings.Set("NDOF", this->GetNDOF() );
fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() );
fSettings.Write();
}
// Write Data/MC
GetDataList().at(0)->Write();
GetMCList().at(0)->Write();
// Write Fine Histogram
if (drawOpt.find("FINE") != std::string::npos)
GetFineList().at(0)->Write();
// Write Weighted Histogram
if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted)
fMCWeighted->Write();
// Save Flux/Evt if no event manager
if (!FitPar::Config().GetParB("EventManager")) {
if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram())
GetFluxHistogram()->Write();
if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram())
GetEventHistogram()->Write();
if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram())
GetXSecHistogram()->Write();
}
// Write Mask
if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) {
fMaskHist->Write();
}
// Write Covariances
if (drawOpt.find("COV") != std::string::npos && fFullCovar) {
PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName());
}
if (drawOpt.find("INVCOV") != std::string::npos && covar) {
PlotUtils::GetInvCovarPlot(covar, fSettings.GetName());
}
if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) {
PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName());
}
// // Likelihood residual plots
// if (drawOpt.find("RESIDUAL") != std::string::npos) {
// WriteResidualPlots();
// }
// Ratio and Shape Plots
if (drawOpt.find("RATIO") != std::string::npos) {
WriteRatioPlot();
}
if (drawOpt.find("SHAPE") != std::string::npos) {
WriteShapePlot();
if (drawOpt.find("RATIO") != std::string::npos)
WriteShapeRatioPlot();
}
// // RATIO
// if (drawOpt.find("CANVMC") != std::string::npos) {
// TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist);
// c1->Write();
// delete c1;
// }
// // PDG
// if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) {
// TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes);
// c2->Write();
// delete c2;
// }
// Write Extra Histograms
AutoWriteExtraTH1();
WriteExtraHistograms();
// Returning
LOG(SAM) << "Written Histograms: " << fName << std::endl;
return;
}
//********************************************************************
void Measurement1D::WriteRatioPlot() {
//********************************************************************
// Setup mc data ratios
TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str());
TH1D* mcRatio = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str());
// Extra MC Data Ratios
for (int i = 0; i < mcRatio->GetNbinsX(); i++) {
dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1));
dataRatio->SetBinError(i + 1, fDataHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1));
mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1));
mcRatio->SetBinError(i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1));
}
// Write ratios
mcRatio->Write();
dataRatio->Write();
delete mcRatio;
delete dataRatio;
}
//********************************************************************
void Measurement1D::WriteShapePlot() {
//********************************************************************
TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
+ TH1D* dataShape = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE").c_str());
+ if (fShapeCovar) StatUtils::SetDataErrorFromCov(dataShape, fShapeCovar, 1E-38);
+
double shapeScale = 1.0;
if (fIsRawEvents) {
shapeScale = fDataHist->Integral() / fMCHist->Integral();
} else {
shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
}
mcShape->Scale(shapeScale);
std::stringstream ss;
ss << shapeScale;
mcShape->SetTitle(ss.str().c_str());
mcShape->SetLineWidth(3);
mcShape->SetLineStyle(7);
mcShape->Write();
+ dataShape->Write();
delete mcShape;
}
//********************************************************************
void Measurement1D::WriteShapeRatioPlot() {
//********************************************************************
// Get a mcshape histogram
TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
double shapeScale = 1.0;
if (fIsRawEvents) {
shapeScale = fDataHist->Integral() / fMCHist->Integral();
} else {
shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
}
mcShape->Scale(shapeScale);
// Create shape ratio histograms
TH1D* mcShapeRatio = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str());
TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str());
// Divide the histograms
mcShapeRatio->Divide(mcShape);
dataShapeRatio->Divide(mcShape);
// Colour the shape ratio plots
mcShapeRatio->SetLineWidth(3);
mcShapeRatio->SetLineStyle(7);
mcShapeRatio->Write();
dataShapeRatio->Write();
delete mcShapeRatio;
delete dataShapeRatio;
}
//// CRAP TO BE REMOVED
//********************************************************************
void Measurement1D::SetupMeasurement(std::string inputfile, std::string type,
FitWeight * rw, std::string fkdt) {
//********************************************************************
- //nuiskey samplekey = Config::CreateKey("sample");
-// samplekey.AddS("name", fName);
-// samplekey.AddS("type",type);
-// samplekey.AddS("input",inputfile);
-// fSettings = LoadSampleSettings(samplekey);
-
+ nuiskey samplekey = Config::CreateKey("sample");
+ samplekey.AddS("name", fName);
+ samplekey.AddS("type",type);
+ samplekey.AddS("input",inputfile);
+ fSettings = LoadSampleSettings(samplekey);
+
// Reset everything to NULL
// Init();
// Check if name contains Evt, indicating that it is a raw number of events
// measurements and should thus be treated as once
fIsRawEvents = false;
if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) {
fIsRawEvents = true;
LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!"
<< std::endl;
LOG(SAM) << "Overriding this and setting fIsRawEvents == true!"
<< std::endl;
}
fIsEnu1D = false;
if (fName.find("XSec_1DEnu") != std::string::npos) {
fIsEnu1D = true;
LOG(SAM) << "::" << fName << "::" << std::endl;
LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
"not flux averaged!"
<< std::endl;
}
if (fIsEnu1D && fIsRawEvents) {
LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
"really correct?!"
<< std::endl;
LOG(SAM) << "Check experiment constructor for " << fName
<< " and correct this!" << std::endl;
LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
exit(-1);
}
fRW = rw;
if (!fInput and !fIsJoint) SetupInputs(inputfile);
// Set Default Options
SetFitOptions(fDefaultTypes);
// Set Passed Options
SetFitOptions(type);
// Still adding support for flat flux inputs
// // Set Enu Flux Scaling
// if (isFlatFluxFolding) this->Input()->ApplyFluxFolding(
// this->defaultFluxHist );
// FinaliseMeasurement();
}
//********************************************************************
void Measurement1D::SetupDefaultHist() {
//********************************************************************
// Setup fMCHist
fMCHist = (TH1D*)fDataHist->Clone();
fMCHist->SetNameTitle((fName + "_MC").c_str(),
(fName + "_MC" + fPlotTitles).c_str());
// Setup fMCFine
Int_t nBins = fMCHist->GetNbinsX();
fMCFine = new TH1D(
(fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(),
nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1));
fMCStat = (TH1D*)fMCHist->Clone();
fMCStat->Reset();
fMCHist->Reset();
fMCFine->Reset();
// Setup the NEUT Mode Array
PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG);
PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG);
// Setup bin masks using sample name
if (fIsMask) {
std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask");
if (maskloc.empty()) {
maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask";
}
SetBinMask(maskloc);
}
fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist);
SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write);
return;
}
//********************************************************************
void Measurement1D::SetDataValues(std::string dataFile) {
//********************************************************************
// Override this function if the input file isn't in a suitable format
LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl;
fDataHist =
PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles);
fDataTrue = (TH1D*)fDataHist->Clone();
// Number of data points is number of bins
fNDataPointsX = fDataHist->GetXaxis()->GetNbins();
return;
};
//********************************************************************
void Measurement1D::SetDataFromDatabase(std::string inhistfile,
std::string histname) {
//********************************************************************
LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
<< std::endl;
fDataHist = PlotUtils::GetTH1DFromRootFile(
(GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname);
fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
return;
};
//********************************************************************
void Measurement1D::SetDataFromFile(std::string inhistfile,
std::string histname) {
//********************************************************************
LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
<< std::endl;
fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname);
fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
return;
};
//********************************************************************
void Measurement1D::SetCovarMatrix(std::string covarFile) {
//********************************************************************
// Covariance function, only really used when reading in the MB Covariances.
TFile* tempFile = new TFile(covarFile.c_str(), "READ");
TH2D* covarPlot = new TH2D();
// TH2D* decmpPlot = new TH2D();
TH2D* covarInvPlot = new TH2D();
TH2D* fFullCovarPlot = new TH2D();
std::string covName = "";
std::string covOption = FitPar::Config().GetParS("thrown_covariance");
if (fIsShape || fIsFree) covName = "shp_";
if (fIsDiag)
covName += "diag";
else
covName += "full";
covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str());
if (!covOption.compare("SUB"))
fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
else if (!covOption.compare("FULL"))
fFullCovarPlot = (TH2D*)tempFile->Get("fullcov");
else
ERR(WRN) << "Incorrect thrown_covariance option in parameters."
<< std::endl;
int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral());
int covdim = int(fDataHist->GetNbinsX());
this->covar = new TMatrixDSym(dim);
fFullCovar = new TMatrixDSym(dim);
fDecomp = new TMatrixDSym(dim);
int row, column = 0;
row = 0;
column = 0;
for (Int_t i = 0; i < covdim; i++) {
// if (this->masked->GetBinContent(i+1) > 0) continue;
for (Int_t j = 0; j < covdim; j++) {
// if (this->masked->GetBinContent(j+1) > 0) continue;
(*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1);
(*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1);
column++;
}
column = 0;
row++;
}
// Set bin errors on data
if (!fIsDiag) {
StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar);
}
// Get Deteriminant and inverse matrix
// fCovDet = this->covar->Determinant();
TDecompSVD LU = TDecompSVD(*this->covar);
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
return;
};
//********************************************************************
// Sets the covariance matrix from a provided file in a text format
// scale is a multiplicative pre-factor to apply in the case where the
// covariance is given in some unit (e.g. 1E-38)
void Measurement1D::SetCovarMatrixFromText(std::string covarFile, int dim,
double scale) {
//********************************************************************
// Make a counter to track the line number
int row = 0;
std::string line;
std::ifstream covarread(covarFile.c_str(), ifstream::in);
this->covar = new TMatrixDSym(dim);
fFullCovar = new TMatrixDSym(dim);
if (covarread.is_open())
LOG(SAM) << "Reading covariance matrix from file: " << covarFile
<< std::endl;
else
ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile
<< std::endl;
// Loop over the lines in the file
while (std::getline(covarread >> std::ws, line, '\n')) {
int column = 0;
// Loop over entries and insert them into matrix
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
if (entries.size() <= 1) {
ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 "
"entries on this line: "
<< row << std::endl;
}
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
(*covar)(row, column) = *iter;
(*fFullCovar)(row, column) = *iter;
column++;
}
row++;
}
covarread.close();
// Scale the actualy covariance matrix by some multiplicative factor
(*fFullCovar) *= scale;
// Robust matrix inversion method
TDecompSVD LU = TDecompSVD(*this->covar);
// THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH
delete this->covar;
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
// Now need to multiply by the scaling factor
// If the covariance
(*this->covar) *= 1. / (scale);
return;
};
//********************************************************************
void Measurement1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) {
//********************************************************************
// Make a counter to track the line number
int row = 0;
std::string line;
std::ifstream corr(corrFile.c_str(), ifstream::in);
this->covar = new TMatrixDSym(dim);
this->fFullCovar = new TMatrixDSym(dim);
if (corr.is_open())
LOG(SAM) << "Reading and converting correlation matrix from file: "
<< corrFile << std::endl;
else {
ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile
<< std::endl;
exit(-1);
}
while (std::getline(corr >> std::ws, line, '\n')) {
int column = 0;
// Loop over entries and insert them into matrix
// Multiply by the errors to get the covariance, rather than the correlation
// matrix
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 *
this->fDataHist->GetBinError(column + 1) * 1E38;
if (val == 0) {
ERR(FTL) << "Found a zero value in the covariance matrix, assuming "
"this is an error!"
<< std::endl;
exit(-1);
}
(*this->covar)(row, column) = val;
(*this->fFullCovar)(row, column) = val;
column++;
}
row++;
}
// Robust matrix inversion method
TDecompSVD LU = TDecompSVD(*this->covar);
delete this->covar;
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
return;
};
//********************************************************************
// FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76.
// If this is the case we need to scale it so that the chi2 contribution is correct
// NUISANCE internally assumes the covariance matrix has units of 1E76
void Measurement1D::SetCovarFromDataFile(std::string covarFile,
std::string covName, bool FullUnits) {
//********************************************************************
LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName
<< std::endl;
TFile* tempFile = new TFile(covarFile.c_str(), "READ");
TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str());
covPlot->SetDirectory(0);
// Scale the covariance matrix if it comes in normal units
if (FullUnits) {
covPlot->Scale(1.E76);
}
int dim = covPlot->GetNbinsX();
fFullCovar = new TMatrixDSym(dim);
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++) {
(*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1);
}
}
this->covar = (TMatrixDSym*)fFullCovar->Clone();
fDecomp = (TMatrixDSym*)fFullCovar->Clone();
TDecompSVD LU = TDecompSVD(*this->covar);
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
TDecompChol LUChol = TDecompChol(*fDecomp);
LUChol.Decompose();
fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), "");
return;
};
// //********************************************************************
// void Measurement1D::SetBinMask(std::string maskFile) {
// //********************************************************************
// // Create a mask histogram.
// int nbins = fDataHist->GetNbinsX();
// fMaskHist =
// new TH1I((fName + "_fMaskHist").c_str(),
// (fName + "_fMaskHist; Bin; Mask?").c_str(), nbins, 0, nbins);
// std::string line;
// std::ifstream mask(maskFile.c_str(), ifstream::in);
// if (mask.is_open())
// LOG(SAM) << "Reading bin mask from file: " << maskFile << std::endl;
// else
// LOG(FTL) << " Cannot find mask file." << std::endl;
// while (std::getline(mask >> std::ws, line, '\n')) {
// std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
// // Skip lines with poorly formatted lines
// if (entries.size() < 2) {
// LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line
// << std::endl;
// continue;
// }
// // The first index should be the bin number, the second should be the mask
// // value.
// fMaskHist->SetBinContent(entries[0], entries[1]);
// }
// // Set masked data bins to zero
// PlotUtils::MaskBins(fDataHist, fMaskHist);
// return;
// }
// //********************************************************************
// void Measurement1D::GetBinContents(std::vector<double>& cont,
// std::vector<double>& err) {
// //********************************************************************
// // Return a vector of the main bin contents
// for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
// cont.push_back(fMCHist->GetBinContent(i + 1));
// err.push_back(fMCHist->GetBinError(i + 1));
// }
// return;
// };
/*
XSec Functions
*/
// //********************************************************************
// void Measurement1D::SetFluxHistogram(std::string fluxFile, int minE, int
// maxE,
// double fluxNorm) {
// //********************************************************************
// // Note this expects the flux bins to be given in terms of MeV
// LOG(SAM) << "Reading flux from file: " << fluxFile << std::endl;
// TGraph f(fluxFile.c_str(), "%lg %lg");
// fFluxHist =
// new TH1D((fName + "_flux").c_str(), (fName + "; E_{#nu} (GeV)").c_str(),
// f.GetN() - 1, minE, maxE);
// Double_t* yVal = f.GetY();
// for (int i = 0; i < fFluxHist->GetNbinsX(); ++i)
// fFluxHist->SetBinContent(i + 1, yVal[i] * fluxNorm);
// };
// //********************************************************************
// double Measurement1D::TotalIntegratedFlux(std::string intOpt, double low,
// double high) {
// //********************************************************************
// if (fInput->GetType() == kGiBUU) {
// return 1.0;
// }
// // The default case of low = -9999.9 and high = -9999.9
// if (low == -9999.9) low = this->EnuMin;
// if (high == -9999.9) high = this->EnuMax;
// int minBin = fFluxHist->GetXaxis()->FindBin(low);
// int maxBin = fFluxHist->GetXaxis()->FindBin(high);
// // Get integral over custom range
// double integral = fFluxHist->Integral(minBin, maxBin + 1, intOpt.c_str());
// return integral;
// };
diff --git a/src/FitBase/Measurement1D.h b/src/FitBase/Measurement1D.h
index b3c14a9..e373dfe 100644
--- a/src/FitBase/Measurement1D.h
+++ b/src/FitBase/Measurement1D.h
@@ -1,650 +1,655 @@
// Copyright 2016 L. Pickering, P towell, 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#ifndef MEASUREMENT_1D_H_SEEN
#define MEASUREMENT_1D_H_SEEN
/*!
* \addtogroup FitBase
* @{
*/
#include <math.h>
#include <stdlib.h>
#include <deque>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <sstream>
#include <string>
// ROOT includes
#include <TArrayF.h>
#include <TCanvas.h>
#include <TCut.h>
#include <TDecompChol.h>
#include <TDecompSVD.h>
#include <TGraph.h>
#include <TGraphErrors.h>
#include <TH1D.h>
#include <TH2D.h>
#include <TMatrixDSym.h>
#include <TROOT.h>
#include <TSystem.h>
// External data fit includes
#include "FitEvent.h"
#include "FitParameters.h"
#include "FitUtils.h"
#include "MeasurementBase.h"
#include "PlotUtils.h"
#include "StatUtils.h"
#include "SignalDef.h"
#include "MeasurementVariableBox.h"
#include "MeasurementVariableBox1D.h"
namespace NUISANCE {
namespace FitBase {
}
}
//********************************************************************
/// 1D Measurement base class. Histogram handling is done in this base layer.
class Measurement1D : public MeasurementBase {
//********************************************************************
public:
/*
Constructor/Deconstuctor
*/
Measurement1D(void);
virtual ~Measurement1D(void);
/*
Setup Functions
*/
/// \brief Setup all configs once initialised
///
/// Should be called after all configs have been setup inside fSettings container.
/// Handles the processing of inputs and setting up of types.
/// Replaces the old 'SetupMeasurement' function.
void FinaliseSampleSettings();
/// \brief Creates the 1D data distribution given the binning provided.
virtual void CreateDataHistogram(int dimx, double* binx);
/// \brief Read 1D data inputs from a text file.
///
/// Inputfile should have the format: \n
/// low_binedge_1 bin_content_1 bin_error_1 \n
/// low_binedge_2 bin_content_2 bin_error_2 \n
/// .... .... .... \n
/// high_bin_edge_N 0.0 0.0
virtual void SetDataFromTextFile(std::string datafile);
/// \brief Read 1D data inputs from a root file.
///
/// inhistfile specifies the path to the root file
/// histname specifies the name of the histogram.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ';' so that: \n
/// 'myhistfile.root;myhistname' \n
/// will also work.
virtual void SetDataFromRootFile(std::string inhistfile, std::string histname = "");
/// \brief Setup a default empty data histogram
///
/// Only used for flattree creators.
virtual void SetEmptyData();
/// \brief Set data bin errors to sqrt(entries)
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Sets the data errors as the sqrt of the bin contents
/// Should be use for counting experiments
virtual void SetPoissonErrors();
/// \brief Make diagonal covariance from data
///
/// \warning If no histogram passed, data must be setup first!
/// Setup the covariance inputs by taking the data histogram
/// errors and setting up a diagonal covariance matrix.
///
/// If no data is supplied, fDataHist is used if already set.
virtual void SetCovarFromDiagonal(TH1D* data = NULL);
/// \brief Read the data covariance from a text file.
///
/// Inputfile should have the format: \n
/// covariance_11 covariance_12 covariance_13 ... \n
/// covariance_21 covariance_22 covariance_23 ... \n
/// ... ... ... ... \n
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCovarFromTextFile(std::string covfile, int dim = -1);
virtual void SetCovarFromMultipleTextFiles(std::string covfiles, int dim = -1);
/// \brief Read the data covariance from a ROOT file.
///
/// - covfile specifies the full path to the file
/// - histname specifies the name of the covariance object. Both TMatrixDSym and TH2D are supported.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCovarFromRootFile(std::string covfile, std::string histname="");
/// \brief Read the inverted data covariance from a text file.
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCovarInvertFromTextFile(std::string covfile, int dim = -1);
/// \brief Read the inverted data covariance from a ROOT file.
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromRootFile.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCovarInvertFromRootFile(std::string covfile, std::string histname="");
/// \brief Read the data correlations from a text file.
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCorrelationFromTextFile(std::string covfile, int dim = -1);
/// \brief Read the data correlations from multiple text files.
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of the first corrfile.
virtual void SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim = -1);
/// \brief Read the data correlations from a ROOT file.
///
/// \warning REQUIRES DATA TO BE SET FIRST
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromRootFile.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCorrelationFromRootFile(std::string covfile, std::string histname="");
/// \brief Read the cholesky decomposed covariance from a text file and turn it into a covariance
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromTextFile.
///
/// If no dimensions are given, it is assumed from the number
/// entries in the first line of covfile.
virtual void SetCholDecompFromTextFile(std::string covfile, int dim = -1);
/// \brief Read the cholesky decomposed covariance from a ROOT file and turn it into a covariance
///
/// Inputfile should have similar format to that shown
/// in SetCovarFromRootFile.
///
/// If no histogram name is given the inhistfile value
/// is automatically parsed with ; so that: \n
/// mycovfile.root;myhistname \n
/// will also work.
virtual void SetCholDecompFromRootFile(std::string covfile, std::string histname="");
+ /// \brief Try to extract a shape-only matrix from the existing covariance
+ virtual void SetShapeCovar();
/// \brief Scale the data by some scale factor
virtual void ScaleData(double scale);
/// \brief Scale the data error bars by some scale factor
virtual void ScaleDataErrors(double scale);
/// \brief Scale the covariaince and its invert/decomp by some scale factor.
virtual void ScaleCovar(double scale);
/// \brief Setup a bin masking histogram and apply masking to data
///
/// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
///
/// Reads in a list of bins in a text file to be masked. Format is: \n
/// bin_index_1 1 \n
/// bin_index_2 1 \n
/// bin_index_3 1 \n
///
/// If 0 is given then a bin entry will NOT be masked. So for example: \n\n
/// 1 1 \n
/// 2 1 \n
/// 3 0 \n
/// 4 1 \n\n
/// Will mask only the 1st, 2nd, and 4th bins.
///
/// Masking can be turned on by specifiying the MASK option when creating a sample.
/// When this is passed NUISANCE will look in the following locations for the mask file:
/// - FitPar::Config().GetParS(fName + ".mask")
/// - "data/masks/" + fName + ".mask";
virtual void SetBinMask(std::string maskfile);
/// \brief Set the current fit options from a string.
///
/// This is called twice for each sample, once to set the default
/// and once to set the current setting (if anything other than default given)
///
/// For this to work properly it requires the default and allowed types to be
/// set correctly. These should be specified as a string listing options.
///
/// To split up options so that NUISANCE can automatically detect ones that
/// are conflicting. Any options seperated with the '/' symbol are non conflicting
/// and can be given together, whereas any seperated with the ',' symbol cannot
/// be specified by the end user at the same time.
///
/// Default Type Examples:
/// - DIAG/FIX = Default option will be a diagonal covariance, with FIXED norm.
/// - MASK/SHAPE = Default option will be a masked hist, with SHAPE always on.
///
/// Allowed Type examples:
/// - 'FULL/DIAG/NORM/MASK' = Any of these options can be specified.
/// - 'FULL,FREE,SHAPE/MASK/NORM' = User can give either FULL, FREE, or SHAPE as on option.
/// MASK and NORM can also be included as options.
virtual void SetFitOptions(std::string opt);
/// \brief Final constructor setup
/// \warning Should be called right at the end of the constructor.
///
/// Contains a series of checks to ensure the data and inputs have been setup.
/// Also creates the MC histograms needed for fitting.
void FinaliseMeasurement();
/*
Smearing
*/
/// \brief Read in smearing matrix from file
///
/// Set the smearing matrix from a text file given the size of the matrix
virtual void SetSmearingMatrix(std::string smearfile, int truedim,
int recodim);
/// \brief Apply smearing to MC true to get MC reco
///
/// Apply smearing matrix to fMCHist using fSmearingMatrix
virtual void ApplySmearingMatrix(void);
/*
Reconfigure Functions
*/
/// \brief Create a Measurement1D box
///
/// Creates a new 1D variable box containing just fXVar.
///
/// This box is the bare minimum required by the JointFCN when
/// running fast reconfigures during a routine.
/// If for some reason a sample needs extra variables to be saved then
/// it should override this function creating its own MeasurementVariableBox
/// that contains the extra variables.
virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox1D();};
/// \brief Reset all MC histograms
///
/// Resets all standard histograms and those registered to auto
/// process to zero.
///
/// If extra histograms are not included in auto processing, then they must be reset
/// by overriding this function and doing it manually if required.
virtual void ResetAll(void);
/// \brief Fill MC Histograms from XVar
///
/// Fill standard histograms using fXVar, Weight read from the variable box.
///
/// WARNING : Any extra MC histograms need to be filled by overriding this function,
/// even if they have been set to auto process.
virtual void FillHistograms(void);
// \brief Convert event rates to final histogram
///
/// Apply standard scaling procedure to standard mc histograms to convert from
/// raw events to xsec prediction.
///
/// If any distributions have been set to auto process
/// that is done during this function call, and a differential xsec is assumed.
/// If that is not the case this function must be overriden.
virtual void ScaleEvents(void);
/// \brief Scale MC by a factor=1/norm
///
/// Apply a simple normalisation scaling if the option FREE or a norm_parameter
/// has been specified in the NUISANCE routine.
virtual void ApplyNormScale(double norm);
/*
Statistical Functions
*/
/// \brief Get Number of degrees of freedom
///
/// Returns the number bins inside the data histogram accounting for
/// any bin masking applied.
virtual int GetNDOF(void);
/// \brief Return Data/MC Likelihood at current state
///
/// Returns the likelihood of the data given the current MC prediction.
/// Diferent likelihoods definitions are used depending on the FitOptions.
virtual double GetLikelihood(void);
/*
Fake Data
*/
/// \brief Set the fake data values from either a file, or MC
///
/// - Setting from a file "path": \n
/// When reading from a file the full path must be given to a standard
/// nuisance output. The standard MC histogram should have a name that matches
/// this sample for it to be read in.
/// \n\n
/// - Setting from "MC": \n
/// If the MC option is given the current MC prediction is used as fake data.
virtual void SetFakeDataValues(std::string fakeOption);
/// \brief Reset fake data back to starting fake data
///
/// Reset the fake data back to original fake data (Reset back to before
/// ThrowCovariance was first called)
virtual void ResetFakeData(void);
/// \brief Reset fake data back to original data
///
/// Reset the data histogram back to the true original dataset for this sample
/// before any fake data was defined.
virtual void ResetData(void);
/// \brief Generate fake data by throwing the covariance.
///
/// Can be used on fake MC data or just the original dataset.
/// Call ResetFakeData or ResetData to return to values before the throw.
virtual void ThrowCovariance(void);
/// \brief Throw the data by its assigned errors and assign this to MC
///
/// Used when creating data toys by assign the MC to this thrown data
/// so that the likelihood is calculated between data and thrown data
virtual void ThrowDataToy(void);
/*
Access Functions
*/
/// \brief Returns nicely formatted MC Histogram
///
/// Format options can also be given in the samplesettings:
/// - linecolor
/// - linestyle
/// - linewidth
/// - fillcolor
/// - fillstyle
///
/// So to have a sample line colored differently in the xml cardfile put: \n
/// <sample name="MiniBooNE_CCQE_XSec_1DQ2_nu" input="NEUT:input.root"
/// linecolor="2" linestyle="7" linewidth="2" />
virtual TH1D* GetMCHistogram(void);
/// \brief Returns nicely formatted data Histogram
///
/// Format options can also be given in the samplesettings:
/// - datacolor
/// - datastyle
/// - datawidth
///
/// So to have a sample data colored differently in the xml cardfile put: \n
/// <sample name="MiniBooNE_CCQE_XSec_1DQ2_nu" input="NEUT:input.root"
/// datacolor="2" datastyle="7" datawidth="2" />
virtual TH1D* GetDataHistogram(void);
/// \brief Returns a list of all MC histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
inline virtual std::vector<TH1*> GetMCList(void) {
return std::vector<TH1*>(1, GetMCHistogram());
}
/// \brief Returns a list of all Data histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
inline virtual std::vector<TH1*> GetDataList(void) {
return std::vector<TH1*>(1, GetDataHistogram());
}
/// \brief Returns a list of all Mask histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
inline virtual std::vector<TH1*> GetMaskList(void) {
return std::vector<TH1*>(1, fMaskHist);
};
/// \brief Returns a list of all Fine histograms.
///
/// Override this if you have extra histograms that need to be
/// accessed outside of the Measurement1D class.
inline virtual std::vector<TH1*> GetFineList(void) {
return std::vector<TH1*>(1, fMCFine);
};
/*
Write Functions
*/
/// \brief Save the current state to the current TFile directory \n
///
/// Data/MC are both saved by default.
/// A range of other histograms can be saved by setting the
/// config option 'drawopts'.
///
/// Possible options: \n
/// - FINE = Write Fine Histogram \n
/// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n
/// - FLUX = Write Flux Histogram from MC Input \n
/// - EVT = Write Event Histogram from MC Input \n
/// - XSEC = Write XSec Histogram from MC Input \n
/// - MASK = Write Mask Histogram \n
/// - COV = Write Covariance Histogram \n
/// - INVCOV = Write Inverted Covariance Histogram \n
/// - DECMOP = Write Decomp. Covariance Histogram \n
/// - RESIDUAL= Write Resudial Histograms \n
/// - RATIO = Write Data/MC Ratio Histograms \n
/// - SHAPE = Write MC Shape Histograms norm. to Data \n
/// - CANVMC = Build MC Canvas Showing Data, MC, Shape \n
/// - MODES = Write PDG Stack \n
/// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n
///
/// So to save a range of these in parameters/config.xml set: \n
/// <config drawopts='FINE/COV/SHAPE/RATIO' />
virtual void Write(std::string drawOpt);
virtual void WriteRatioPlot();
virtual void WriteShapePlot();
virtual void WriteShapeRatioPlot();
//*
// OLD DEFUNCTIONS
//
/// OLD FUNCTION
virtual void SetupMeasurement(std::string input, std::string type,
FitWeight* rw, std::string fkdt);
/// OLD FUNCTION
virtual void SetupDefaultHist(void);
/// OLD FUNCTION
virtual void SetDataValues(std::string dataFile);
/// OLD FUNCTION
virtual void SetDataFromFile(std::string inhistfile, std::string histname);
/// OLD FUNCTION
virtual void SetDataFromDatabase(std::string inhistfile,
std::string histname);
/// OLD FUNCTION
virtual void SetCovarMatrix(std::string covarFile);
/// OLD FUNCTION
virtual void SetCovarMatrixFromText(std::string covarFile, int dim,
double scale = 1.0);
/// OLD FUNCTION
virtual void SetCovarMatrixFromCorrText(std::string covarFile, int dim);
/// OLD FUNCTION
virtual void SetCovarFromDataFile(std::string covarFile, std::string covName,
bool FullUnits = false);
/// OLD FUNCTION
// virtual THStack GetModeStack(void);
protected:
// Data
TH1D* fDataHist; ///< default data histogram
TH1D* fDataOrig; ///< histogram to store original data before throws.
TH1D* fDataTrue; ///< histogram to store true dataset
std::string fPlotTitles; ///< Plot title x and y for the histograms
// MC
TH1D* fMCHist; ///< default MC Histogram used in the chi2 fits
TH1D* fMCFine; ///< finely binned MC histogram
TH1D* fMCStat; ///< histogram with unweighted events to properly calculate
TH1D* fMCWeighted; ///< Weighted histogram before xsec scaling
TH1I* fMaskHist; ///< Mask histogram for neglecting specific bins
TMatrixD* fSmearMatrix; ///< Smearing matrix (note, this is not symmetric)
TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack
// Statistical
TMatrixDSym* covar; ///< Inverted Covariance
TMatrixDSym* fFullCovar; ///< Full Covariance
TMatrixDSym* fDecomp; ///< Decomposed Covariance
TMatrixDSym* fCorrel; ///< Correlation Matrix
+ TMatrixDSym* fShapeCovar; ///< Shape-only covariance
+ TMatrixDSym* fShapeDecomp; ///< Decomposed shape-only covariance
+
TMatrixDSym* fCovar; ///< New FullCovar
TMatrixDSym* fInvert; ///< New covar
double fNormError; ///< Sample norm error
double fLikelihood; ///< Likelihood value
// Fake Data
bool fIsFakeData; ///< Flag: is the current data fake from MC
std::string fFakeDataInput; ///< Input fake data file path
TFile* fFakeDataFile; ///< Input fake data file
// Fit specific flags
std::string fFitType; ///< Current fit type
std::string fAllowedTypes; ///< Fit Types Possible
std::string fDefaultTypes; ///< Starting Default Fit Types
bool fIsShape; ///< Flag : Perform Shape-only fit
bool fIsFree; ///< Flag : Perform normalisation free fit
bool fIsDiag; ///< Flag : only include uncorrelated diagonal errors
bool fIsMask; ///< Flag : Apply bin masking
bool fIsRawEvents; ///< Flag : Are bin contents just event rates
bool fIsEnu1D; ///< Flag : Perform Flux Unfolded Scaling
bool fIsChi2SVD; ///< Flag : Use alternative Chi2 SVD Method (Do not use)
bool fAddNormPen; ///< Flag : Add a normalisation penalty term to the chi2.
bool fIsFix; ///< Flag : keeping norm fixed
bool fIsFull; ///< Flag : using full covariaince
bool fIsDifXSec; ///< Flag : creating a dif xsec
bool fIsChi2; ///< Flag : using Chi2 over LL methods
bool fIsSmeared; ///< Flag : Apply smearing?
/// OLD STUFF TO REMOVE
TH1D* fMCHist_PDG[61]; ///< REMOVE OLD MC PDG Plot
// Arrays for data entries
Double_t* fXBins; ///< REMOVE xBin edges
Double_t* fDataValues; ///< REMOVE data bin contents
Double_t* fDataErrors; ///< REMOVE data bin errors
Int_t fNDataPointsX; ///< REMOVE number of data points
};
/*! @} */
#endif
diff --git a/src/FitBase/Measurement2D.cxx b/src/FitBase/Measurement2D.cxx
index 4c3a6df..33fdd0f 100644
--- a/src/FitBase/Measurement2D.cxx
+++ b/src/FitBase/Measurement2D.cxx
@@ -1,1961 +1,1961 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "Measurement2D.h"
#include "TDecompChol.h"
//********************************************************************
Measurement2D::Measurement2D(void) {
//********************************************************************
covar = NULL;
fDecomp = NULL;
fFullCovar = NULL;
fMCHist = NULL;
fMCFine = NULL;
fDataHist = NULL;
fMCHist_X = NULL;
fMCHist_Y = NULL;
fDataHist_X = NULL;
fDataHist_Y = NULL;
fMaskHist = NULL;
fMapHist = NULL;
fDataOrig = NULL;
fDataTrue = NULL;
fMCWeighted = NULL;
fDefaultTypes = "FIX/FULL/CHI2";
fAllowedTypes =
"FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/FITPROJX/"
"FITPROJY";
fIsFix = false;
fIsShape = false;
fIsFree = false;
fIsDiag = false;
fIsFull = false;
fAddNormPen = false;
fIsMask = false;
fIsChi2SVD = false;
fIsRawEvents = false;
fIsDifXSec = false;
fIsEnu = false;
// XSec Scalings
fScaleFactor = -1.0;
fCurrentNorm = 1.0;
// Histograms
fDataHist = NULL;
fDataTrue = NULL;
fMCHist = NULL;
fMCFine = NULL;
fMCWeighted = NULL;
fMaskHist = NULL;
// Covar
covar = NULL;
fFullCovar = NULL;
fCovar = NULL;
fInvert = NULL;
fDecomp = NULL;
// Fake Data
fFakeDataInput = "";
fFakeDataFile = NULL;
// Options
fDefaultTypes = "FIX/FULL/CHI2";
fAllowedTypes =
"FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK";
fIsFix = false;
fIsShape = false;
fIsFree = false;
fIsDiag = false;
fIsFull = false;
fAddNormPen = false;
fIsMask = false;
fIsChi2SVD = false;
fIsRawEvents = false;
fIsDifXSec = false;
fIsEnu1D = false;
// Inputs
fInput = NULL;
fRW = NULL;
// Extra Histograms
fMCHist_Modes = NULL;
}
//********************************************************************
Measurement2D::~Measurement2D(void) {
//********************************************************************
if (fDataHist) delete fDataHist;
if (fDataTrue) delete fDataTrue;
if (fMCHist) delete fMCHist;
if (fMCFine) delete fMCFine;
if (fMCWeighted) delete fMCWeighted;
if (fMaskHist) delete fMaskHist;
if (covar) delete covar;
if (fFullCovar) delete fFullCovar;
if (fCovar) delete fCovar;
if (fInvert) delete fInvert;
if (fDecomp) delete fDecomp;
}
//********************************************************************
void Measurement2D::FinaliseSampleSettings() {
//********************************************************************
MeasurementBase::FinaliseSampleSettings();
// Setup naming + renaming
fName = fSettings.GetName();
fSettings.SetS("originalname", fName);
if (fSettings.Has("rename")) {
fName = fSettings.GetS("rename");
fSettings.SetS("name", fName);
}
// Setup all other options
LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl;
if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) {
fIsRawEvents = true;
LOG(SAM) << "Found event rate measurement but using poisson likelihoods."
<< std::endl;
}
if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) {
fIsEnu1D = true;
LOG(SAM) << "::" << fName << "::" << std::endl;
LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
<< "not flux averaged!" << std::endl;
}
if (fIsEnu1D && fIsRawEvents) {
LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
"really correct?!"
<< std::endl;
LOG(SAM) << "Check experiment constructor for " << fName
<< " and correct this!" << std::endl;
LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
exit(-1);
}
if (!fRW) fRW = FitBase::GetRW();
if (!fInput) SetupInputs(fSettings.GetS("input"));
// Setup options
SetFitOptions(fDefaultTypes); // defaults
SetFitOptions(fSettings.GetS("type")); // user specified
EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min"));
EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max"));
if (fAddNormPen) {
fNormError = fSettings.GetNormError();
if (fNormError <= 0.0) {
ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl;
ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl;
throw;
}
}
}
void Measurement2D::CreateDataHistogram(int dimx, double* binx, int dimy, double* biny) {
if (fDataHist) delete fDataHist;
LOG(SAM) << "Creating Data Histogram dim : " << dimx << " " << dimy << std::endl;
fDataHist = new TH2D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(),
dimx - 1, binx, dimy - 1, biny );
}
void Measurement2D::SetDataFromTextFile(std::string datfile) {
// fDataHist = PlotUtils::GetTH2DFromTextFile(datfile,"");
}
void Measurement2D::SetDataFromRootFile(std::string datfile, std::string histname) {
fDataHist = PlotUtils::GetTH2DFromRootFile(datfile, histname);
}
void Measurement2D::SetDataValuesFromTextFile(std::string datfile, TH2D* hist) {
LOG(SAM) << "Setting data values from text file" << std::endl;
if (!hist) hist = fDataHist;
// Read TH2D From textfile
TH2D* valhist = (TH2D*) hist->Clone();
valhist->Reset();
PlotUtils::Set2DHistFromText(datfile, valhist, 1.0, true);
LOG(SAM) << " -> Filling values from read hist." << std::endl;
for (int i = 0; i < valhist->GetNbinsX(); i++) {
for (int j = 0; j < valhist->GetNbinsY(); j++) {
hist->SetBinContent(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1));
}
}
LOG(SAM) << " --> Done" << std::endl;
}
void Measurement2D::SetDataErrorsFromTextFile(std::string datfile, TH2D* hist) {
LOG(SAM) << "Setting data errors from text file" << std::endl;
if (!hist) hist = fDataHist;
// Read TH2D From textfile
TH2D* valhist = (TH2D*) hist->Clone();
valhist->Reset();
PlotUtils::Set2DHistFromText(datfile, valhist, 1.0);
// Fill Errors
LOG(SAM) << " -> Filling errors from read hist." << std::endl;
for (int i = 0; i < valhist->GetNbinsX(); i++) {
for (int j = 0; j < valhist->GetNbinsY(); j++) {
hist->SetBinError(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1));
}
}
LOG(SAM) << " --> Done" << std::endl;
}
void Measurement2D::SetMapValuesFromText(std::string dataFile) {
TH2D* hist = fDataHist;
std::vector<double> edgex;
std::vector<double> edgey;
for (int i = 0; i <= hist->GetNbinsX(); i++) edgex.push_back(hist->GetXaxis()->GetBinLowEdge(i + 1));
for (int i = 0; i <= hist->GetNbinsY(); i++) edgey.push_back(hist->GetYaxis()->GetBinLowEdge(i + 1));
fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(),
edgex.size() - 1, &edgex[0], edgey.size() - 1, &edgey[0]);
LOG(SAM) << "Reading map from: " << dataFile << std::endl;
PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0);
}
//********************************************************************
void Measurement2D::SetPoissonErrors() {
//********************************************************************
if (!fDataHist) {
ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl;
ERR(FTL) << "Setup Data First!" << std::endl;
throw;
}
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1)));
}
}
//********************************************************************
void Measurement2D::SetCovarFromDiagonal(TH2D* data) {
//********************************************************************
if (!data and fDataHist) {
data = fDataHist;
}
if (data) {
LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl;
fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
} else {
ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl;
}
// if (!fIsDiag) {
// ERR(FTL) << "SetCovarMatrixFromDiag called for measurement "
// << "that is not set as diagonal." << std::endl;
// throw;
// }
}
//********************************************************************
void Measurement2D::SetCovarFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) {
dim = this->GetNDOF();
}
LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl;
fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement2D::SetCovarFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl;
fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname);
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement2D::SetCovarInvertFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) {
dim = this->GetNDOF();
}
LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl;
covar = StatUtils::GetCovarFromTextFile(covfile, dim);
fFullCovar = StatUtils::GetInvert(covar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement2D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl;
covar = StatUtils::GetCovarFromRootFile(covfile, histname);
fFullCovar = StatUtils::GetInvert(covar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
//********************************************************************
void Measurement2D::SetCorrelationFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) dim = this->GetNDOF();
LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl;
TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim);
if (!fDataHist) {
ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
<< "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
throw;
}
// Fill covar from data errors and correlations
fFullCovar = new TMatrixDSym(dim);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
(*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
}
}
// Fill other covars.
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete correlation;
}
//********************************************************************
void Measurement2D::SetCorrelationFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl;
TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname);
if (!fDataHist) {
ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
<< "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
throw;
}
// Fill covar from data errors and correlations
fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX());
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
(*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
}
}
// Fill other covars.
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete correlation;
}
//********************************************************************
void Measurement2D::SetCholDecompFromTextFile(std::string covfile, int dim) {
//********************************************************************
if (dim == -1) {
dim = this->GetNDOF();
}
LOG(SAM) << "Reading cholesky from text file: " << covfile << " " << dim << std::endl;
TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim);
TMatrixD* trans = (TMatrixD*)temp->Clone();
trans->T();
(*trans) *= (*temp);
fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), "");
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete temp;
delete trans;
}
//********************************************************************
void Measurement2D::SetCholDecompFromRootFile(std::string covfile, std::string histname) {
//********************************************************************
LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl;
TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname);
TMatrixD* trans = (TMatrixD*)temp->Clone();
trans->T();
(*trans) *= (*temp);
fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), "");
covar = StatUtils::GetInvert(fFullCovar);
fDecomp = StatUtils::GetDecomp(fFullCovar);
delete temp;
delete trans;
}
//********************************************************************
void Measurement2D::ScaleData(double scale) {
//********************************************************************
fDataHist->Scale(scale);
}
//********************************************************************
void Measurement2D::ScaleDataErrors(double scale) {
//********************************************************************
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
for (int j = 0; j < fDataHist->GetNbinsY(); j++) {
fDataHist->SetBinError(i + 1, j + 1, fDataHist->GetBinError(i + 1, j + 1) * scale);
}
}
}
//********************************************************************
void Measurement2D::ScaleCovar(double scale) {
//********************************************************************
(*fFullCovar) *= scale;
(*covar) *= 1.0 / scale;
(*fDecomp) *= sqrt(scale);
}
//********************************************************************
void Measurement2D::SetBinMask(std::string maskfile) {
//********************************************************************
if (!fIsMask) return;
LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl;
// Create a mask histogram with dim of data
int nbinsx = fDataHist->GetNbinsX();
int nbinxy = fDataHist->GetNbinsY();
fMaskHist =
new TH2I((fSettings.GetName() + "_BINMASK").c_str(),
(fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbinsx, 0, nbinsx, nbinxy, 0, nbinxy);
std::string line;
std::ifstream mask(maskfile.c_str(), ifstream::in);
if (!mask.is_open()) {
LOG(FTL) << " Cannot find mask file." << std::endl;
throw;
}
while (std::getline(mask >> std::ws, line, '\n')) {
std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
// Skip lines with poorly formatted lines
if (entries.size() < 2) {
LOG(WRN) << "Measurement2D::SetBinMask(), couldn't parse line: " << line
<< std::endl;
continue;
}
// The first index should be the bin number, the second should be the mask
// value.
int val = 0;
if (entries[2] > 0) val = 1;
fMaskHist->SetBinContent(entries[0], entries[1], val);
}
// Apply masking by setting masked data bins to zero
PlotUtils::MaskBins(fDataHist, fMaskHist);
return;
}
//********************************************************************
void Measurement2D::FinaliseMeasurement() {
//********************************************************************
LOG(SAM) << "Finalising Measurement: " << fName << std::endl;
if (fSettings.GetB("onlymc")) {
if (fDataHist) delete fDataHist;
fDataHist = new TH2D("empty_data", "empty_data", 1, 0.0, 1.0,1,0.0,1.0);
}
// Make sure data is setup
if (!fDataHist) {
ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl;
throw;
}
// Make sure covariances are setup
if (!fFullCovar) {
fIsDiag = true;
SetCovarFromDiagonal(fDataHist);
}
if (!covar) {
covar = StatUtils::GetInvert(fFullCovar);
}
if (!fDecomp) {
fDecomp = StatUtils::GetDecomp(fFullCovar);
}
// Setup fMCHist from data
fMCHist = (TH2D*)fDataHist->Clone();
fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(),
(fSettings.GetFullTitles()).c_str());
fMCHist->Reset();
// Setup fMCFine
fMCFine = new TH2D("mcfine", "mcfine", fDataHist->GetNbinsX() * 6,
fMCHist->GetXaxis()->GetBinLowEdge(1),
fMCHist->GetXaxis()->GetBinLowEdge(fDataHist->GetNbinsX() + 1),
fDataHist->GetNbinsY() * 6,
fMCHist->GetYaxis()->GetBinLowEdge(1),
fMCHist->GetYaxis()->GetBinLowEdge(fDataHist->GetNbinsY() + 1));
fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(),
(fSettings.GetFullTitles()).c_str());
fMCFine->Reset();
// Setup MC Stat
fMCStat = (TH2D*)fMCHist->Clone();
fMCStat->Reset();
// Search drawopts for possible types to include by default
std::string drawopts = FitPar::Config().GetParS("drawopts");
if (drawopts.find("MODES") != std::string::npos) {
fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(),
("True Channels"), fMCHist);
SetAutoProcessTH1(fMCHist_Modes);
}
// Setup bin masks using sample name
if (fIsMask) {
std::string curname = fName;
std::string origname = fSettings.GetS("originalname");
// Check rename.mask
std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask");
// Check origname.mask
if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask");
// Check database
if (maskloc.empty()) {
maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask";
}
// Setup Bin Mask
SetBinMask(maskloc);
}
if (fScaleFactor < 0) {
ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl;
ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl;
ERR(FTL) << "EXITING" << std::endl;
throw;
}
// Create and fill Weighted Histogram
if (!fMCWeighted) {
fMCWeighted = (TH2D*)fMCHist->Clone();
fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(),
(fName + "_MCWGHTS" + fPlotTitles).c_str());
fMCWeighted->GetYaxis()->SetTitle("Weighted Events");
}
}
//********************************************************************
void Measurement2D::SetFitOptions(std::string opt) {
//********************************************************************
// Do nothing if default given
if (opt == "DEFAULT") return;
// CHECK Conflicting Fit Options
std::vector<std::string> fit_option_allow =
GeneralUtils::ParseToStr(fAllowedTypes, "/");
for (UInt_t i = 0; i < fit_option_allow.size(); i++) {
std::vector<std::string> fit_option_section =
GeneralUtils::ParseToStr(fit_option_allow.at(i), ",");
bool found_option = false;
for (UInt_t j = 0; j < fit_option_section.size(); j++) {
std::string av_opt = fit_option_section.at(j);
if (!found_option and opt.find(av_opt) != std::string::npos) {
found_option = true;
} else if (found_option and opt.find(av_opt) != std::string::npos) {
ERR(FTL) << "ERROR: Conflicting fit options provided: "
<< opt << std::endl
<< "Conflicting group = " << fit_option_section.at(i) << std::endl
<< "You should only supply one of these options in card file." << std::endl;
throw;
}
}
}
// Check all options are allowed
std::vector<std::string> fit_options_input =
GeneralUtils::ParseToStr(opt, "/");
for (UInt_t i = 0; i < fit_options_input.size(); i++) {
if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) {
ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i)
<< "' Provided is not allowed for this measurement."
<< std::endl;
ERR(FTL) << "Fit Options should be provided as a '/' seperated list "
"(e.g. FREE/DIAG/NORM)"
<< std::endl;
ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes
<< "'" << std::endl;
throw;
}
}
// Set TYPE
fFitType = opt;
// FIX,SHAPE,FREE
if (opt.find("FIX") != std::string::npos) {
fIsFree = fIsShape = false;
fIsFix = true;
} else if (opt.find("SHAPE") != std::string::npos) {
fIsFree = fIsFix = false;
fIsShape = true;
} else if (opt.find("FREE") != std::string::npos) {
fIsFix = fIsShape = false;
fIsFree = true;
}
// DIAG,FULL (or default to full)
if (opt.find("DIAG") != std::string::npos) {
fIsDiag = true;
fIsFull = false;
} else if (opt.find("FULL") != std::string::npos) {
fIsDiag = false;
fIsFull = true;
}
// CHI2/LL (OTHERS?)
if (opt.find("LOG") != std::string::npos) {
fIsChi2 = false;
ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl;
ERR(FTL) << "Try to use a chi2!" << std::endl;
throw;
} else {
fIsChi2 = true;
}
// EXTRAS
if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
if (opt.find("DIF") != std::string::npos) fIsDifXSec = true;
if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true;
if (opt.find("NORM") != std::string::npos) fAddNormPen = true;
if (opt.find("MASK") != std::string::npos) fIsMask = true;
// Set TYPE
fFitType = opt;
// FIX,SHAPE,FREE
if (opt.find("FIX") != std::string::npos) {
fIsFree = fIsShape = false;
fIsFix = true;
} else if (opt.find("SHAPE") != std::string::npos) {
fIsFree = fIsFix = false;
fIsShape = true;
} else if (opt.find("FREE") != std::string::npos) {
fIsFix = fIsShape = false;
fIsFree = true;
}
// DIAG,FULL (or default to full)
if (opt.find("DIAG") != std::string::npos) {
fIsDiag = true;
fIsFull = false;
} else if (opt.find("FULL") != std::string::npos) {
fIsDiag = false;
fIsFull = true;
}
// CHI2/LL (OTHERS?)
if (opt.find("LOG") != std::string::npos)
fIsChi2 = false;
else
fIsChi2 = true;
// EXTRAS
if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
if (opt.find("DIF") != std::string::npos) fIsDifXSec = true;
if (opt.find("ENU1D") != std::string::npos) fIsEnu = true;
if (opt.find("NORM") != std::string::npos) fAddNormPen = true;
if (opt.find("MASK") != std::string::npos) fIsMask = true;
fIsProjFitX = (opt.find("FITPROJX") != std::string::npos);
fIsProjFitY = (opt.find("FITPROJY") != std::string::npos);
return;
};
/*
Reconfigure LOOP
*/
//********************************************************************
void Measurement2D::ResetAll() {
//********************************************************************
fMCHist->Reset();
fMCFine->Reset();
fMCStat->Reset();
return;
};
//********************************************************************
void Measurement2D::FillHistograms() {
//********************************************************************
if (Signal) {
fMCHist->Fill(fXVar, fYVar, Weight);
fMCFine->Fill(fXVar, fYVar, Weight);
fMCStat->Fill(fXVar, fYVar, 1.0);
if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, fYVar, Weight);
}
return;
};
//********************************************************************
void Measurement2D::ScaleEvents() {
//********************************************************************
// Fill MCWeighted;
// for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
// fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1));
// fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1));
// }
// Setup Stat ratios for MC and MC Fine
double* statratio = new double[fMCHist->GetNbinsX()];
for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
if (fMCHist->GetBinContent(i + 1) != 0) {
statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1);
} else {
statratio[i] = 0.0;
}
}
double* statratiofine = new double[fMCFine->GetNbinsX()];
for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
if (fMCFine->GetBinContent(i + 1) != 0) {
statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1);
} else {
statratiofine[i] = 0.0;
}
}
// Scaling for raw event rates
if (fIsRawEvents) {
double datamcratio = fDataHist->Integral() / fMCHist->Integral();
fMCHist->Scale(datamcratio);
fMCFine->Scale(datamcratio);
if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio);
// Scaling for XSec as function of Enu
} else if (fIsEnu1D) {
PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(),
GetEventHistogram(), fScaleFactor);
PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(),
GetEventHistogram(), fScaleFactor);
// if (fMCHist_Modes) {
// PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(),
// GetEventHistogram(), fScaleFactor,
// fNEvents);
// }
// Any other differential scaling
} else {
fMCHist->Scale(fScaleFactor, "width");
fMCFine->Scale(fScaleFactor, "width");
// if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width");
}
// Proper error scaling - ROOT Freaks out with xsec weights sometimes
for (int i = 0; i < fMCStat->GetNbinsX(); i++) {
fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]);
}
for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]);
}
// Clean up
delete statratio;
delete statratiofine;
return;
};
//********************************************************************
void Measurement2D::ApplyNormScale(double norm) {
//********************************************************************
fCurrentNorm = norm;
fMCHist->Scale(1.0 / norm);
fMCFine->Scale(1.0 / norm);
return;
};
/*
Statistic Functions - Outsources to StatUtils
*/
//********************************************************************
int Measurement2D::GetNDOF() {
//********************************************************************
// Just incase it has gone...
if (!fDataHist) return -1;
int nDOF = 0;
// If datahist has no errors make sure we don't include those bins as they are
// not data points
for (int xBin = 0; xBin < fDataHist->GetNbinsX() + 1; ++xBin) {
for (int yBin = 0; yBin < fDataHist->GetNbinsY() + 1; ++yBin) {
if (fDataHist->GetBinError(xBin, yBin) != 0)
++nDOF;
}
}
// Account for possible bin masking
int nMasked = 0;
if (fMaskHist and fIsMask)
if (fMaskHist->Integral() > 0)
for (int xBin = 0; xBin < fMaskHist->GetNbinsX() + 1; ++xBin)
for (int yBin = 0; yBin < fMaskHist->GetNbinsY() + 1; ++yBin)
if (fMaskHist->GetBinContent(xBin, yBin) > 0.5) ++nMasked;
// Take away those masked DOF
if (fIsMask) {
nDOF -= nMasked;
}
return nDOF;
}
//********************************************************************
double Measurement2D::GetLikelihood() {
//********************************************************************
// If this is for a ratio, there is no data histogram to compare to!
if (fNoData || !fDataHist) return 0.;
// Fix weird masking bug
if (!fIsMask) {
if (fMaskHist) {
fMaskHist = NULL;
}
} else {
if (fMaskHist) {
PlotUtils::MaskBins(fMCHist, fMaskHist);
}
}
// if (fIsProjFitX or fIsProjFitY) return GetProjectedChi2();
// Scale up the results to match each other (Not using width might be
// inconsistent with Meas1D)
double scaleF = fDataHist->Integral() / fMCHist->Integral();
if (fIsShape) {
fMCHist->Scale(scaleF);
fMCFine->Scale(scaleF);
- PlotUtils::ScaleNeutModeArray((TH1**)fMCHist_PDG, scaleF);
+ //PlotUtils::ScaleNeutModeArray((TH1**)fMCHist_PDG, scaleF);
}
if (!fMapHist) {
fMapHist = StatUtils::GenerateMap(fDataHist);
}
// Get the chi2 from either covar or diagonals
double chi2 = 0.0;
if (fIsChi2) {
if (fIsDiag) {
chi2 =
StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMapHist, fMaskHist);
} else {
chi2 = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMapHist,
fMaskHist);
}
}
// Add a normal penalty term
if (fAddNormPen) {
chi2 +=
(1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError);
LOG(REC) << "Norm penalty = "
<< (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) /
(fNormError * fNormError)
<< std::endl;
}
// Adjust the shape back to where it was.
if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) {
fMCHist->Scale(1. / scaleF);
fMCFine->Scale(1. / scaleF);
}
fLikelihood = chi2;
return chi2;
}
/*
Fake Data Functions
*/
//********************************************************************
void Measurement2D::SetFakeDataValues(std::string fakeOption) {
//********************************************************************
// Setup original/datatrue
TH2D* tempdata = (TH2D*) fDataHist->Clone();
if (!fIsFakeData) {
fIsFakeData = true;
// Make a copy of the original data histogram.
if (!fDataOrig) fDataOrig = (TH2D*)fDataHist->Clone((fName + "_data_original").c_str());
} else {
ResetFakeData();
}
// Setup Inputs
fFakeDataInput = fakeOption;
LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl;
// From MC
if (fFakeDataInput.compare("MC") == 0) {
fDataHist = (TH2D*)fMCHist->Clone((fName + "_MC").c_str());
// Fake File
} else {
if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ");
fDataHist = (TH2D*)fFakeDataFile->Get((fName + "_MC").c_str());
}
// Setup Data Hist
fDataHist->SetNameTitle((fName + "_FAKE").c_str(),
(fName + fPlotTitles).c_str());
// Replace Data True
if (fDataTrue) delete fDataTrue;
fDataTrue = (TH2D*)fDataHist->Clone();
fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(),
(fName + fPlotTitles).c_str());
// Make a new covariance for fake data hist.
int nbins = fDataHist->GetNbinsX() * fDataHist->GetNbinsY();
double alpha_i = 0.0;
double alpha_j = 0.0;
for (int i = 0; i < nbins; i++) {
for (int j = 0; j < nbins; j++) {
if (tempdata->GetBinContent(i + 1) && tempdata->GetBinContent(j + 1)) {
alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1);
alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1);
} else {
alpha_i = 0.0;
alpha_j = 0.0;
}
(*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j);
}
}
// Setup Covariances
if (covar) delete covar;
covar = StatUtils::GetInvert(fFullCovar);
if (fDecomp) delete fDecomp;
fDecomp = StatUtils::GetInvert(fFullCovar);
delete tempdata;
return;
};
//********************************************************************
void Measurement2D::ResetFakeData() {
//********************************************************************
if (fIsFakeData) {
if (fDataHist) delete fDataHist;
fDataHist = (TH2D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str());
}
}
//********************************************************************
void Measurement2D::ResetData() {
//********************************************************************
if (fIsFakeData) {
if (fDataHist) delete fDataHist;
fDataHist = (TH2D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str());
}
fIsFakeData = false;
}
//********************************************************************
void Measurement2D::ThrowCovariance() {
//********************************************************************
// Take a fDecomposition and use it to throw the current dataset.
// Requires fDataTrue also be set incase used repeatedly.
if (fDataHist) delete fDataHist;
fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
return;
};
//********************************************************************
void Measurement2D::ThrowDataToy() {
//********************************************************************
if (!fDataTrue) fDataTrue = (TH2D*) fDataHist->Clone();
if (fMCHist) delete fMCHist;
fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
}
/*
Access Functions
*/
//********************************************************************
TH2D* Measurement2D::GetMCHistogram() {
//********************************************************************
if (!fMCHist) return fMCHist;
std::ostringstream chi2;
chi2 << std::setprecision(5) << this->GetLikelihood();
int linecolor = kRed;
int linestyle = 1;
int linewidth = 1;
int fillcolor = 0;
int fillstyle = 1001;
if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor");
if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle");
if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth");
if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor");
if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle");
fMCHist->SetTitle(chi2.str().c_str());
fMCHist->SetLineColor(linecolor);
fMCHist->SetLineStyle(linestyle);
fMCHist->SetLineWidth(linewidth);
fMCHist->SetFillColor(fillcolor);
fMCHist->SetFillStyle(fillstyle);
return fMCHist;
};
//********************************************************************
TH2D* Measurement2D::GetDataHistogram() {
//********************************************************************
if (!fDataHist) return fDataHist;
int datacolor = kBlack;
int datastyle = 1;
int datawidth = 1;
if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor");
if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle");
if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth");
fDataHist->SetLineColor(datacolor);
fDataHist->SetLineWidth(datawidth);
fDataHist->SetMarkerStyle(datastyle);
return fDataHist;
};
/*
Write Functions
*/
// Save all the histograms at once
//********************************************************************
void Measurement2D::Write(std::string drawOpt) {
//********************************************************************
// Get Draw Options
drawOpt = FitPar::Config().GetParS("drawopts");
// Write Settigns
if (drawOpt.find("SETTINGS") != std::string::npos) {
fSettings.Set("#chi^{2}", fLikelihood);
fSettings.Set("NDOF", this->GetNDOF() );
fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() );
fSettings.Write();
}
// Write Data/MC
GetDataList().at(0)->Write();
GetMCList().at(0)->Write();
// Write Fine Histogram
if (drawOpt.find("FINE") != std::string::npos)
GetFineList().at(0)->Write();
// Write Weighted Histogram
if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted)
fMCWeighted->Write();
// Save Flux/Evt if no event manager
if (!FitPar::Config().GetParB("EventManager")) {
if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram())
GetFluxHistogram()->Write();
if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram())
GetEventHistogram()->Write();
if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram())
GetEventHistogram()->Write();
}
// Write Mask
if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) {
fMaskHist->Write();
}
// Write Covariances
if (drawOpt.find("COV") != std::string::npos && fFullCovar) {
PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName());
}
if (drawOpt.find("INVCOV") != std::string::npos && covar) {
PlotUtils::GetInvCovarPlot(covar, fSettings.GetName());
}
if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) {
PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName());
}
// // Likelihood residual plots
// if (drawOpt.find("RESIDUAL") != std::string::npos) {
// WriteResidualPlots();
// }
// // RATIO
// if (drawOpt.find("CANVMC") != std::string::npos) {
// TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist);
// c1->Write();
// delete c1;
// }
// // PDG
// if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) {
// TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes);
// c2->Write();
// delete c2;
// }
// Write Extra Histograms
AutoWriteExtraTH1();
WriteExtraHistograms();
/// 2D VERSION
// If null pointer return
if (!fMCHist and !fDataHist) {
LOG(SAM) << fName << "Incomplete histogram set!" << std::endl;
return;
}
// FitPar::Config().out->cd();
// Get Draw Options
drawOpt = FitPar::Config().GetParS("drawopts");
bool drawData = (drawOpt.find("DATA") != std::string::npos);
bool drawNormal = (drawOpt.find("MC") != std::string::npos);
bool drawEvents = (drawOpt.find("EVT") != std::string::npos);
bool drawXSec = (drawOpt.find("XSEC") != std::string::npos);
bool drawFine = (drawOpt.find("FINE") != std::string::npos);
bool drawRatio = (drawOpt.find("RATIO") != std::string::npos);
// bool drawModes = (drawOpt.find("MODES") != std::string::npos);
bool drawShape = (drawOpt.find("SHAPE") != std::string::npos);
bool residual = (drawOpt.find("RESIDUAL") != std::string::npos);
bool drawMatrix = (drawOpt.find("MATRIX") != std::string::npos);
bool drawFlux = (drawOpt.find("FLUX") != std::string::npos);
bool drawMask = (drawOpt.find("MASK") != std::string::npos);
bool drawMap = (drawOpt.find("MAP") != std::string::npos);
bool drawProj = (drawOpt.find("PROJ") != std::string::npos);
// bool drawCanvPDG = (drawOpt.find("CANVPDG") != std::string::npos);
bool drawCov = (drawOpt.find("COV") != std::string::npos);
bool drawSliceCanvYMC = (drawOpt.find("CANVYMC") != std::string::npos);
bool drawWeighted = (drawOpt.find("WGHT") != std::string::npos);
if (FitPar::Config().GetParB("EventManager")) {
drawFlux = false;
drawXSec = false;
drawEvents = false;
}
if (fMaskHist) fMaskHist->Write();
// Save standard plots
if (drawData) this->GetDataList().at(0)->Write();
if (drawNormal) this->GetMCList().at(0)->Write();
if (drawCov) {
TH2D(*fFullCovar).Write((fName + "_COV").c_str());
}
if (drawOpt.find("INVCOV") != std::string::npos) {
TH2D(*covar).Write((fName + "_INVCOV").c_str());
}
// Generate a simple map
if (!fMapHist) fMapHist = StatUtils::GenerateMap(fDataHist);
// Convert to 1D Lists
TH1D* data_1D = StatUtils::MapToTH1D(fDataHist, fMapHist);
TH1D* mc_1D = StatUtils::MapToTH1D(fMCHist, fMapHist);
TH1I* mask_1D = StatUtils::MapToMask(fMaskHist, fMapHist);
data_1D->Write();
mc_1D->Write();
if (mask_1D) {
mask_1D->Write();
TMatrixDSym* calc_cov =
StatUtils::ApplyInvertedMatrixMasking(covar, mask_1D);
TH1D* calc_data = StatUtils::ApplyHistogramMasking(data_1D, mask_1D);
TH1D* calc_mc = StatUtils::ApplyHistogramMasking(mc_1D, mask_1D);
TH2D* bin_cov = new TH2D(*calc_cov);
bin_cov->Write();
calc_data->Write();
calc_mc->Write();
delete mask_1D;
delete calc_cov;
delete calc_data;
delete calc_mc;
delete bin_cov;
}
delete data_1D;
delete mc_1D;
// Save only mc and data if splines
if (fEventType == 4 or fEventType == 3) {
return;
}
// Draw Extra plots
if (drawFine) this->GetFineList().at(0)->Write();
if (drawFlux and GetFluxHistogram()) {
GetFluxHistogram()->Write();
}
if (drawEvents and GetEventHistogram()) {
GetEventHistogram()->Write();
}
if (fIsMask and drawMask) {
fMaskHist->Write((fName + "_MSK").c_str()); //< save mask
}
if (drawMap) fMapHist->Write((fName + "_MAP").c_str()); //< save map
// // Save neut stack
// if (drawModes) {
// THStack combo_fMCHist_PDG = PlotUtils::GetNeutModeStack(
// (fName + "_MC_PDG").c_str(), (TH1**)fMCHist_PDG, 0);
// combo_fMCHist_PDG.Write();
// }
// Save Matrix plots
if (drawMatrix and fFullCovar and covar and fDecomp) {
TH2D cov = TH2D((*fFullCovar));
cov.SetNameTitle((fName + "_cov").c_str(),
(fName + "_cov;Bins; Bins;").c_str());
cov.Write();
TH2D covinv = TH2D((*this->covar));
covinv.SetNameTitle((fName + "_covinv").c_str(),
(fName + "_cov;Bins; Bins;").c_str());
covinv.Write();
TH2D covdec = TH2D((*fDecomp));
covdec.SetNameTitle((fName + "_covdec").c_str(),
(fName + "_cov;Bins; Bins;").c_str());
covdec.Write();
}
// Save ratio plots if required
if (drawRatio) {
// Needed for error bars
for (int i = 0; i < fMCHist->GetNbinsX() * fMCHist->GetNbinsY(); i++)
fMCHist->SetBinError(i + 1, 0.0);
fDataHist->GetSumw2();
fMCHist->GetSumw2();
// Create Ratio Histograms
TH2D* dataRatio = (TH2D*)fDataHist->Clone((fName + "_data_RATIO").c_str());
TH2D* mcRatio = (TH2D*)fMCHist->Clone((fName + "_MC_RATIO").c_str());
mcRatio->Divide(fMCHist);
dataRatio->Divide(fMCHist);
// Cancel bin errors on MC
for (int i = 0; i < mcRatio->GetNbinsX() * mcRatio->GetNbinsY(); i++) {
mcRatio->SetBinError(
i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1));
}
mcRatio->SetMinimum(0);
mcRatio->SetMaximum(2);
dataRatio->SetMinimum(0);
dataRatio->SetMaximum(2);
mcRatio->Write();
dataRatio->Write();
delete mcRatio;
delete dataRatio;
}
// Save Shape Plots if required
if (drawShape) {
// Create Shape Histogram
TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
double shapeScale = 1.0;
if (fIsRawEvents) {
shapeScale = fDataHist->Integral() / fMCHist->Integral();
} else {
shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
}
mcShape->Scale(shapeScale);
mcShape->SetLineWidth(3);
mcShape->SetLineStyle(7); // dashes
mcShape->Write();
// Save shape ratios
if (drawRatio) {
// Needed for error bars
mcShape->GetSumw2();
// Create shape ratio histograms
TH2D* mcShapeRatio =
(TH2D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str());
TH2D* dataShapeRatio =
(TH2D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str());
// Divide the histograms
mcShapeRatio->Divide(mcShape);
dataShapeRatio->Divide(mcShape);
// Colour the shape ratio plots
mcShapeRatio->SetLineWidth(3);
mcShapeRatio->SetLineStyle(7); // dashes
mcShapeRatio->Write();
dataShapeRatio->Write();
delete mcShapeRatio;
delete dataShapeRatio;
}
delete mcShape;
}
// Save residual calculations of what contributed to the chi2 values.
if (residual) {
}
if (fIsProjFitX or fIsProjFitY or drawProj) {
// If not already made, make the projections
if (!fMCHist_X) {
PlotUtils::MatchEmptyBins(fDataHist, fMCHist);
fMCHist_X = PlotUtils::GetProjectionX(fMCHist, fMaskHist);
fMCHist_Y = PlotUtils::GetProjectionY(fMCHist, fMaskHist);
fDataHist_X = PlotUtils::GetProjectionX(fDataHist, fMaskHist);
fDataHist_Y = PlotUtils::GetProjectionY(fDataHist, fMaskHist);
double chi2X = StatUtils::GetChi2FromDiag(fDataHist_X, fMCHist_X);
double chi2Y = StatUtils::GetChi2FromDiag(fDataHist_Y, fMCHist_Y);
fMCHist_X->SetTitle(Form("%f", chi2X));
fMCHist_Y->SetTitle(Form("%f", chi2Y));
}
// Save the histograms
fDataHist_X->Write();
fMCHist_X->Write();
fDataHist_Y->Write();
fMCHist_Y->Write();
}
if (drawSliceCanvYMC or true) {
TCanvas* c1 = new TCanvas((fName + "_MC_CANV_Y").c_str(),
(fName + "_MC_CANV_Y").c_str(), 800, 600);
c1->Divide(int(sqrt(fDataHist->GetNbinsY() + 1)),
int(sqrt(fDataHist->GetNbinsY() + 1)));
TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
double shapeScale =
fDataHist->Integral("width") / fMCHist->Integral("width");
mcShape->Scale(shapeScale);
mcShape->SetLineStyle(7);
c1->cd(1);
TLegend* leg = new TLegend(0.6, 0.6, 0.9, 0.9);
leg->AddEntry(fDataHist, (fName + " Data").c_str(), "ep");
leg->AddEntry(fMCHist, (fName + " MC").c_str(), "l");
leg->AddEntry(mcShape, (fName + " Shape").c_str(), "l");
leg->Draw("SAME");
/*
// Make Y slices
for (int i = 0; i < fDataHist->GetNbinY(); i++){
c1->cd(i+2);
TH1D* fDataHist_SliceY = PlotUtils::GetSliceY(fDataHist, i);
fDataHist_SliceY->Draw("E1");
TH1D* fMCHist_SliceY = PlotUtils::GetSliceY(fMCHist, i);
fMCHist_SliceY->Draw("SAME HIST C");
TH1D* mcShape_SliceY = PlotUtils::GetSliceY(mcShape, i);
mcShape_SliceY->Draw("SAME HIST C");
}
*/
c1->Write();
}
if (drawWeighted) {
fMCWeighted->Write();
}
// Returning
LOG(SAM) << "Written Histograms: " << fName << std::endl;
return;
// Returning
LOG(SAM) << "Written Histograms: " << fName << std::endl;
return;
}
/*
Setup Functions
*/
//********************************************************************
void Measurement2D::SetupMeasurement(std::string inputfile, std::string type,
FitWeight* rw, std::string fkdt) {
//********************************************************************
// Check if name contains Evt, indicating that it is a raw number of events
// measurements and should thus be treated as once
fIsRawEvents = false;
if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) {
fIsRawEvents = true;
LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!"
<< std::endl;
LOG(SAM) << "Overriding this and setting fIsRawEvents == true!"
<< std::endl;
}
fIsEnu = false;
if ((fName.find("XSec") != std::string::npos) &&
(fName.find("Enu") != std::string::npos)) {
fIsEnu = true;
LOG(SAM) << "::" << fName << "::" << std::endl;
LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
"not flux averaged!"
<< std::endl;
if (FitPar::Config().GetParB("EventManager")) {
ERR(FTL) << "Enu Measurements do not yet work with the Event Manager!"
<< std::endl;
ERR(FTL) << "If you want decent flux unfolded results please run in "
"series mode (-q EventManager=0)"
<< std::endl;
sleep(2);
}
}
if (fIsEnu && fIsRawEvents) {
LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
"really correct?!"
<< std::endl;
LOG(SAM) << "Check experiment constructor for " << fName
<< " and correct this!" << std::endl;
LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
exit(-1);
}
// Reset everything to NULL
fRW = rw;
// Setting up 2D Inputs
this->SetupInputs(inputfile);
// Set Default Options
SetFitOptions(fDefaultTypes);
// Set Passed Options
SetFitOptions(type);
}
//********************************************************************
void Measurement2D::SetupDefaultHist() {
//********************************************************************
// Setup fMCHist
fMCHist = (TH2D*)fDataHist->Clone();
fMCHist->SetNameTitle((fName + "_MC").c_str(),
(fName + "_MC" + fPlotTitles).c_str());
// Setup fMCFine
Int_t nBinsX = fMCHist->GetNbinsX();
Int_t nBinsY = fMCHist->GetNbinsY();
fMCFine = new TH2D((fName + "_MC_FINE").c_str(),
(fName + "_MC_FINE" + fPlotTitles).c_str(), nBinsX * 3,
fMCHist->GetXaxis()->GetBinLowEdge(1),
fMCHist->GetXaxis()->GetBinLowEdge(nBinsX + 1), nBinsY * 3,
fMCHist->GetYaxis()->GetBinLowEdge(1),
fMCHist->GetYaxis()->GetBinLowEdge(nBinsY + 1));
// Setup MC Stat
fMCStat = (TH2D*)fMCHist->Clone();
fMCStat->Reset();
// Setup the NEUT Mode Array
- PlotUtils::CreateNeutModeArray(fMCHist, (TH1**)fMCHist_PDG);
+ //PlotUtils::CreateNeutModeArray(fMCHist, (TH1**)fMCHist_PDG);
// Setup bin masks using sample name
if (fIsMask) {
std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask");
if (maskloc.empty()) {
maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask";
}
SetBinMask(maskloc);
}
return;
}
//********************************************************************
void Measurement2D::SetDataValues(std::string dataFile, std::string TH2Dname) {
//********************************************************************
if (dataFile.find(".root") == std::string::npos) {
ERR(FTL) << "Error! " << dataFile << " is not a .root file" << std::endl;
ERR(FTL) << "Currently only .root file reading is supported (MiniBooNE "
"CC1pi+ 2D), but implementing .txt should be dirt easy"
<< std::endl;
ERR(FTL) << "See me at " << __FILE__ << ":" << __LINE__ << std::endl;
exit(-1);
} else {
TFile* inFile = new TFile(dataFile.c_str(), "READ");
fDataHist = (TH2D*)(inFile->Get(TH2Dname.c_str())->Clone());
fDataHist->SetDirectory(0);
fDataHist->SetNameTitle((fName + "_data").c_str(),
(fName + "_MC" + fPlotTitles).c_str());
delete inFile;
}
return;
}
//********************************************************************
void Measurement2D::SetDataValues(std::string dataFile, double dataNorm,
std::string errorFile, double errorNorm) {
//********************************************************************
// Make a counter to track the line number
int yBin = 0;
std::string line;
std::ifstream data(dataFile.c_str(), ifstream::in);
fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(),
fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins);
if (data.is_open())
LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl;
while (std::getline(data >> std::ws, line, '\n')) {
int xBin = 0;
// Loop over entries and insert them into the histogram
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
fDataHist->SetBinContent(xBin + 1, yBin + 1, (*iter) * dataNorm);
xBin++;
}
yBin++;
}
yBin = 0;
std::ifstream error(errorFile.c_str(), ifstream::in);
if (error.is_open())
LOG(SAM) << "Reading errors from: " << errorFile.c_str() << std::endl;
while (std::getline(error >> std::ws, line, '\n')) {
int xBin = 0;
// Loop over entries and insert them into the histogram
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
fDataHist->SetBinError(xBin + 1, yBin + 1, (*iter) * errorNorm);
xBin++;
}
yBin++;
}
return;
};
//********************************************************************
void Measurement2D::SetDataValuesFromText(std::string dataFile,
double dataNorm) {
//********************************************************************
fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(),
fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins);
LOG(SAM) << "Reading data from: " << dataFile << std::endl;
PlotUtils::Set2DHistFromText(dataFile, fDataHist, dataNorm, true);
return;
};
//********************************************************************
void Measurement2D::SetCovarMatrix(std::string covarFile) {
//********************************************************************
// Used to read a covariance matrix from a root file
TFile* tempFile = new TFile(covarFile.c_str(), "READ");
// Make plots that we want
TH2D* covarPlot = new TH2D();
// TH2D* decmpPlot = new TH2D();
TH2D* covarInvPlot = new TH2D();
TH2D* fFullCovarPlot = new TH2D();
// Get covariance options for fake data studies
std::string covName = "";
std::string covOption = FitPar::Config().GetParS("throw_covariance");
// Which matrix to get?
if (fIsShape || fIsFree) covName = "shp_";
if (fIsDiag)
covName += "diag";
else
covName += "full";
covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str());
// Throw either the sub matrix or the full matrix
if (!covOption.compare("SUB"))
fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
else if (!covOption.compare("FULL"))
fFullCovarPlot = (TH2D*)tempFile->Get("fullcov");
else
ERR(WRN) << " Incorrect thrown_covariance option in parameters."
<< std::endl;
// Bin masking?
int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral());
int covdim = int(fDataHist->GetNbinsX());
// Make new covars
this->covar = new TMatrixDSym(dim);
fFullCovar = new TMatrixDSym(dim);
fDecomp = new TMatrixDSym(dim);
// Full covariance values
int row, column = 0;
row = 0;
column = 0;
for (Int_t i = 0; i < covdim; i++) {
// masking can be dodgy
// if (this->masked->GetBinContent(i+1) > 0) continue;
for (Int_t j = 0; j < covdim; j++) {
// if (this->masked->GetBinContent(j+1) > 0) continue;
(*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1);
(*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1);
column++;
}
column = 0;
row++;
}
// Set bin errors on data
if (!fIsDiag) {
for (Int_t i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinError(
i + 1, sqrt((covarPlot->GetBinContent(i + 1, i + 1))) * 1E-38);
}
}
TDecompSVD LU = TDecompSVD(*this->covar);
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
tempFile->Close();
delete tempFile;
return;
};
//********************************************************************
void Measurement2D::SetCovarMatrixFromText(std::string covarFile, int dim) {
//********************************************************************
// Make a counter to track the line number
int row = 0;
std::string line;
std::ifstream covar(covarFile.c_str(), ifstream::in);
this->covar = new TMatrixDSym(dim);
fFullCovar = new TMatrixDSym(dim);
if (covar.is_open())
LOG(SAM) << "Reading covariance matrix from file: " << covarFile
<< std::endl;
while (std::getline(covar >> std::ws, line, '\n')) {
int column = 0;
// Loop over entries and insert them into matrix
// Multiply by the errors to get the covariance, rather than the correlation
// matrix
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
double val = (*iter) * fDataHist->GetBinError(row + 1) * 1E38 *
fDataHist->GetBinError(column + 1) * 1E38;
(*this->covar)(row, column) = val;
(*fFullCovar)(row, column) = val;
column++;
}
row++;
}
// Robust matrix inversion method
TDecompSVD LU = TDecompSVD(*this->covar);
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
return;
};
//********************************************************************
void Measurement2D::SetCovarMatrixFromChol(std::string covarFile, int dim) {
//********************************************************************
// Make a counter to track the line number
int row = 0;
std::string line;
std::ifstream covarread(covarFile.c_str(), ifstream::in);
TMatrixD* newcov = new TMatrixD(dim, dim);
if (covarread.is_open())
LOG(SAM) << "Reading covariance matrix from file: " << covarFile
<< std::endl;
while (std::getline(covarread >> std::ws, line, '\n')) {
int column = 0;
// Loop over entries and insert them into matrix
// Multiply by the errors to get the covariance, rather than the correlation
// matrix
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
(*newcov)(row, column) = *iter;
column++;
}
row++;
}
covarread.close();
// Form full covariance
TMatrixD* trans = (TMatrixD*)(newcov)->Clone();
trans->T();
(*trans) *= (*newcov);
fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), "");
delete newcov;
delete trans;
// Robust matrix inversion method
TDecompChol LU = TDecompChol(*this->fFullCovar);
this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
return;
};
// //********************************************************************
// void Measurement2D::SetMapValuesFromText(std::string dataFile) {
// //********************************************************************
// fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(),
// fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins);
// LOG(SAM) << "Reading map from: " << dataFile << std::endl;
// PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0);
// return;
// };
diff --git a/src/FitBase/MeasurementBase.cxx b/src/FitBase/MeasurementBase.cxx
index a77597e..235b470 100644
--- a/src/FitBase/MeasurementBase.cxx
+++ b/src/FitBase/MeasurementBase.cxx
@@ -1,561 +1,562 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MeasurementBase.h"
/*
Constructor/Destructors
*/
//********************************************************************
// 2nd Level Constructor (Inherits From MeasurementBase.h)
MeasurementBase::MeasurementBase(void) {
//********************************************************************
fScaleFactor = 1.0;
fMCFilled = false;
fNoData = false;
fInput = NULL;
// Set the default values
// After-wards this gets set in SetupMeasurement
EnuMin = 0.;
EnuMax = 1.E5;
fMeasurementSpeciesType = kSingleSpeciesMeasurement;
fEventVariables = NULL;
fIsJoint = false;
};
void MeasurementBase::FinaliseMeasurement() {
// Used to setup default data hists, covars, etc.
}
//********************************************************************
// 2nd Level Destructor (Inherits From MeasurementBase.h)
MeasurementBase::~MeasurementBase() {
//********************************************************************
};
//********************************************************************
double MeasurementBase::TotalIntegratedFlux(std::string intOpt, double low,
double high) {
//********************************************************************
// Set Energy Limits
if (low == -9999.9) low = this->EnuMin;
if (high == -9999.9) high = this->EnuMax;
return GetInput()->TotalIntegratedFlux(low, high, intOpt);
};
//********************************************************************
double MeasurementBase::PredictedEventRate(std::string intOpt, double low,
double high) {
//********************************************************************
// Set Energy Limits
if (low == -9999.9) low = this->EnuMin;
if (high == -9999.9) high = this->EnuMax;
return GetInput()->PredictedEventRate(low, high, intOpt) * 1E-38;
};
//********************************************************************
void MeasurementBase::SetupInputs(std::string inputfile) {
//********************************************************************
// Add this infile to the global manager
if (FitPar::Config().GetParB("EventManager")) {
fInput = FitBase::AddInput(fName, inputfile);
} else {
std::vector<std::string> file_descriptor =
GeneralUtils::ParseToStr(inputfile, ":");
if (file_descriptor.size() != 2) {
ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile
<< "\". expected \"FILETYPE:file.root\"" << std::endl;
throw;
}
InputUtils::InputType inpType =
InputUtils::ParseInputType(file_descriptor[0]);
fInput = InputUtils::CreateInputHandler(fName, inpType, file_descriptor[1]);
}
fNEvents = fInput->GetNEvents();
// Expect INPUTTYPE:FileLocation(s)
std::vector<std::string> file_descriptor =
GeneralUtils::ParseToStr(inputfile, ":");
if (file_descriptor.size() != 2) {
ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile
<< "\". expected \"FILETYPE:file.root\"" << std::endl;
throw;
}
fInputType = InputUtils::ParseInputType(file_descriptor[0]);
fInputFileName = file_descriptor[1];
if (EnuMin == 0 && EnuMax == 1.E5) {
EnuMin = fInput->GetFluxHistogram()->GetBinLowEdge(1);
EnuMax = fInput->GetFluxHistogram()->GetBinLowEdge(
fInput->GetFluxHistogram()->GetNbinsX() + 1);
}
fFluxHist = fInput->GetFluxHistogram();
fEventHist = fInput->GetEventHistogram();
}
//***********************************************
int MeasurementBase::GetInputID() {
//***********************************************
return FitBase::GetInputID(fInputFileName);
}
//***********************************************
SampleSettings MeasurementBase::LoadSampleSettings(nuiskey samplekey) {
//***********************************************
SampleSettings setting = SampleSettings(samplekey);
fName = setting.GetS("name");
// Used as an initial setup function incase we need to do anything here.
LOG(SAM) << "Loading Sample : " << setting.GetName() << std::endl;
if (!fIsJoint) SetupInputs( setting.GetS("input") );
return setting;
}
//***********************************************
SampleSettings MeasurementBase::LoadSampleSettings(std::string name, std::string input, std::string type) {
//***********************************************
nuiskey samplekey = Config::CreateKey("sample");
samplekey.SetS("name",name);
samplekey.SetS("input",input);
samplekey.SetS("type",type);
return LoadSampleSettings(samplekey);
}
void MeasurementBase::FinaliseSampleSettings() {
EnuMin = fSettings.GetD("enu_min");
EnuMax = fSettings.GetD("enu_max");
}
//***********************************************
void MeasurementBase::Reconfigure() {
//***********************************************
LOG(REC) << " Reconfiguring sample " << fName << std::endl;
// Reset Histograms
ResetExtraHistograms();
AutoResetExtraTH1();
this->ResetAll();
// FitEvent* cust_event = fInput->GetEventPointer();
int fNEvents = fInput->GetNEvents();
int countwidth = (fNEvents / 5);
// MAIN EVENT LOOP
FitEvent* cust_event = fInput->FirstNuisanceEvent();
int i = 0;
int npassed = 0;
while(cust_event){
cust_event->RWWeight = fRW->CalcWeight(cust_event);
cust_event->Weight = cust_event->RWWeight * cust_event->InputWeight;
Weight = cust_event->Weight;
// Initialize
fXVar = -999.9;
fYVar = -999.9;
fZVar = -999.9;
Signal = false;
Mode = cust_event->Mode;
// Extract Measurement Variables
this->FillEventVariables(cust_event);
Signal = this->isSignal(cust_event);
if (Signal) npassed++;
GetBox()->SetX(fXVar);
GetBox()->SetY(fYVar);
GetBox()->SetZ(fZVar);
GetBox()->SetMode(Mode);
// GetBox()->fSignal = Signal;
// Fill Histogram Values
GetBox()->FillBoxFromEvent(cust_event);
// this->FillExtraHistograms(GetBox(), Weight);
this->FillHistogramsFromBox(GetBox(), Weight);
// Print Out
if (LOG_LEVEL(REC) && countwidth > 0 && !(i % countwidth)) {
std::stringstream ss("");
ss.unsetf(std::ios_base::fixed);
ss << std::setw(7) << std::right << i << "/" << fNEvents << " events ("
<< std::setw(2) << double(i) / double(fNEvents) * 100. << std::left
<< std::setw(5) << "%) "
<< "[S,X,Y,Z,M,W] = [" << std::fixed << std::setprecision(2)
<< std::right << Signal << ", " << std::setw(5) << fXVar << ", "
<< std::setw(5) << fYVar << ", " << std::setw(5) << fYVar << ", "
<< std::setw(3) << (int)Mode << ", " << std::setw(5) << Weight << "] "
<< std::endl;
LOG(SAM) << ss.str();
}
// iterate
cust_event = fInput->NextNuisanceEvent();
i++;
}
LOG(SAM) << npassed << "/" << fNEvents << " passed selection " << std::endl;
if (npassed == 0) {
LOG(SAM) << "WARNING: NO EVENTS PASSED SELECTION!" << std::endl;
}
LOG(REC) << std::setw(10) << std::right << NSignal << "/"
<< fNEvents << " events passed selection + binning after reweight"
<< std::endl;
// Finalise Histograms
fMCFilled = true;
this->ConvertEventRates();
}
void MeasurementBase::FillHistogramsFromBox(MeasurementVariableBox* var, double weight) {
fXVar = var->GetX();
fYVar = var->GetY();
fZVar = var->GetZ();
// Signal = var->fSignal;
// Mode = var->fMode;
Weight = weight;
+ fEventVariables = var;
FillHistograms();
FillExtraHistograms(var, weight);
}
void MeasurementBase::FillHistograms(double weight){
Weight = weight * GetBox()->GetSampleWeight();
FillHistograms();
FillExtraHistograms(GetBox(), Weight);
}
MeasurementVariableBox* MeasurementBase::FillVariableBox(FitEvent* event) {
GetBox()->Reset();
Mode = event->Mode;
Weight = 1.0; //event->Weight;
this->FillEventVariables(event);
Signal = this->isSignal(event);
GetBox()->FillBoxFromEvent(event);
GetBox()->SetX(fXVar);
GetBox()->SetY(fYVar);
GetBox()->SetZ(fZVar);
GetBox()->SetMode(event->Mode);
GetBox()->SetSampleWeight(Weight);
// GetBox()->fSignal = Signal;
return GetBox();
}
MeasurementVariableBox* MeasurementBase::GetBox() {
if (!fEventVariables) fEventVariables = CreateBox();
return fEventVariables;
}
//***********************************************
void MeasurementBase::ReconfigureFast() {
//***********************************************
this->Reconfigure();
}
//***********************************************
void MeasurementBase::ConvertEventRates() {
//***********************************************
AutoScaleExtraTH1();
ScaleExtraHistograms(GetBox());
this->ScaleEvents();
double normval = fRW->GetSampleNorm(this->fName);
if (normval < 0.01 or normval > 10.0){
ERR(WRN) << "Norm Value inside MeasurementBase::ConvertEventRates() looks off!" << std::endl;
ERR(WRN) << "It could have become out of sync with the minimizer norm list." << std::endl;
ERR(WRN) << "Setting it to 1.0" << std::endl;
normval = 1.0;
}
AutoNormExtraTH1(normval);
NormExtraHistograms(GetBox(), normval);
this->ApplyNormScale(normval);
}
//***********************************************
InputHandlerBase* MeasurementBase::GetInput() {
//***********************************************
if (!fInput) {
ERR(FTL) << "MeasurementBase::fInput not set. Please submit your command "
"line options and input cardfile with a bug report to: "
"nuisance@projects.hepforge.org"
<< std::endl;
throw;
}
return fInput;
};
//***********************************************
void MeasurementBase::Renormalise() {
//***********************************************
// Called when the fitter has changed a measurements normalisation but not any
// reweight dials
// Means we don't have to call the time consuming reconfigure when this
// happens.
double norm = fRW->GetDialValue(this->fName + "_norm");
if ((this->fCurrentNorm == 0.0 and norm != 0.0) or not fMCFilled) {
this->ReconfigureFast();
return;
}
if (this->fCurrentNorm == norm) return;
this->ApplyNormScale(1.0 / this->fCurrentNorm);
this->ApplyNormScale(norm);
return;
};
//***********************************************
void MeasurementBase::SetSignal(bool sig) {
//***********************************************
Signal = sig;
}
//***********************************************
void MeasurementBase::SetSignal(FitEvent* evt) {
//***********************************************
Signal = this->isSignal(evt);
}
//***********************************************
void MeasurementBase::SetWeight(double wght) {
//***********************************************
Weight = wght;
}
//***********************************************
void MeasurementBase::SetMode(int md) {
//***********************************************
Mode = md;
}
//***********************************************
std::vector<TH1*> MeasurementBase::GetFluxList() {
//***********************************************
return GetInput()->GetFluxList();
}
//***********************************************
std::vector<TH1*> MeasurementBase::GetEventRateList() {
//***********************************************
return GetInput()->GetEventList();
}
//***********************************************
std::vector<TH1*> MeasurementBase::GetXSecList() {
//***********************************************
return GetInput()->GetXSecList();
}
void MeasurementBase::ProcessExtraHistograms(int cmd,
MeasurementVariableBox* vars,
double weight) {
// This should be overriden if we have extra histograms!!!
// Add a flag to tell user this...
return;
}
void MeasurementBase::FillExtraHistograms(MeasurementVariableBox* vars,
double weight) {
ProcessExtraHistograms(kCMD_Fill, vars, weight);
}
void MeasurementBase::ScaleExtraHistograms(MeasurementVariableBox* vars) {
ProcessExtraHistograms(kCMD_Scale, vars, 1.0);
}
void MeasurementBase::ResetExtraHistograms() {
ProcessExtraHistograms(kCMD_Reset, NULL, 1.0);
}
void MeasurementBase::NormExtraHistograms(MeasurementVariableBox* vars,
double norm) {
ProcessExtraHistograms(kCMD_Norm, vars, norm);
}
void MeasurementBase::WriteExtraHistograms() {
ProcessExtraHistograms(kCMD_Write, NULL, 1.00);
}
void MeasurementBase::SetAutoProcessTH1(TH1* hist, int c1, int c2, int c3, int c4, int c5) {
FakeStack* fake = new FakeStack(hist);
SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command!
}
void MeasurementBase::SetAutoProcess(TH1* hist, int c1, int c2, int c3, int c4, int c5) {
FakeStack* fake = new FakeStack(hist);
SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command!
}
void MeasurementBase::SetAutoProcess(TGraph* g, int c1, int c2, int c3, int c4, int c5) {
FakeStack* fake = new FakeStack(g);
SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command!
}
void MeasurementBase::SetAutoProcess(TF1* f, int c1, int c2, int c3, int c4, int c5) {
FakeStack* fake = new FakeStack(f);
SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command!
}
void MeasurementBase::SetAutoProcess(StackBase* hist, int c1, int c2, int c3, int c4, int c5){
SetAutoProcessTH1(hist, c1, c2, c3, c4, c5);
}
void MeasurementBase::SetAutoProcessTH1(StackBase* hist, int c1, int c2, int c3, int c4, int c5) {
// Set Defaults
// int ncommands = kCMD_extraplotflags;
bool autoflags[5];
autoflags[0] = false;
autoflags[1] = false;
autoflags[2] = false;
autoflags[3] = false;
autoflags[4] = false;
int givenflags[5];
givenflags[0] = c1;
givenflags[1] = c2;
givenflags[2] = c3;
givenflags[3] = c4;
givenflags[4] = c5;
fExtraTH1s[hist] = std::vector<int>(5,0);
// Setup a default one.
if (c1 == -1 && c2 == -1 && c3 == -1 && c4 == -1 && c5 == -1){
fExtraTH1s[hist][kCMD_Reset] = 1;
fExtraTH1s[hist][kCMD_Scale] = 1;
fExtraTH1s[hist][kCMD_Norm] = 1;
fExtraTH1s[hist][kCMD_Write] = 1;
}
for (int i = 0; i < 5; i++) {
switch (givenflags[i]) {
// Skip over...
case -1:
break;
case kCMD_Reset:
case kCMD_Scale:
case kCMD_Norm:
case kCMD_Write:
fExtraTH1s[hist][givenflags[i]] = 1;
break;
case kCMD_Fill:
ERR(FTL) << "Can't auto fill yet!" << std::endl;
autoflags[givenflags[i]] = 1;
break;
default:
break;
}
}
// LOG(SAM) << "AutoProcessing " << hist->GetName() << std::endl;
};
void MeasurementBase::AutoFillExtraTH1() {
ERR(FTL) << "Can't auto fill yet! it's too inefficent!" << std::endl;
return;
}
void MeasurementBase::AutoResetExtraTH1() {
for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
iter != fExtraTH1s.end(); iter++) {
if (!((*iter).second)[kCMD_Reset]) continue;
(*iter).first->Reset();
}
};
void MeasurementBase::AutoScaleExtraTH1() {
for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
iter != fExtraTH1s.end(); iter++) {
if (!((*iter).second)[kCMD_Scale]) continue;
if (fIsNoWidth){
(*iter).first->Scale(fScaleFactor);
} else {
(*iter).first->Scale(fScaleFactor, "width");
}
}
};
void MeasurementBase::AutoNormExtraTH1(double norm) {
double sfactor = 0.0;
if (norm != 0.0) sfactor = 1.0 / norm;
for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
iter != fExtraTH1s.end(); iter++) {
if (!((*iter).second)[kCMD_Norm]) continue;
(*iter).first->Scale(sfactor);
}
};
void MeasurementBase::AutoWriteExtraTH1() {
for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
iter != fExtraTH1s.end(); iter++) {
if (!(((*iter).second)[kCMD_Write])) continue;
(*iter).first->Write();
}
};
diff --git a/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx b/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx
index e93aee9..523a194 100644
--- a/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx
+++ b/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx
@@ -1,73 +1,72 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "K2K_NC1pi0_Evt_1Dppi0_nu.h"
// The constructor
K2K_NC1pi0_Evt_1Dppi0_nu::K2K_NC1pi0_Evt_1Dppi0_nu(nuiskey samplekey){
// Sample overview ---------------------------------------------------
std::string descrip = "K2K_NC1pi0_Evt_1Dppi0_nu sample. \n" \
"Target: D2 \n" \
"Flux: \n" \
"Signal: \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("p_{#pi^{0}} (MeV/c)");
fSettings.SetYTitle("Number of events");
fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG/Q2CORR/MASK");
fSettings.SetEnuRange(0.0, 5.0);
fSettings.DefineAllowedTargets("H,O");
// plot information
fSettings.SetTitle("K2K_NC1pi0_Evt_1Dppi0_nu");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput( FitPar::GetDataBase() + "K2K/nc1pi0/ppi0.csv");
FinaliseSampleSettings();
- // Scaling Setup ---------------------------------------------------
- // ScaleFactor for shape
- fScaleFactor = (fDataHist->Integral() / (fNEvents + 0.));
-
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCovarFromDiagonal();
+ // Scale for shape
+ fScaleFactor = fDataHist->Integral()/double(fNEvents);
+
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void K2K_NC1pi0_Evt_1Dppi0_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0)
return;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
double ppi0 = FitUtils::p(Ppi0)*1000.;
fXVar = ppi0;
return;
};
bool K2K_NC1pi0_Evt_1Dppi0_nu::isSignal(FitEvent *event) {
return SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax); // Check this signal definition
}
diff --git a/src/MINERvA/MINERvAVariableBoxes.h b/src/MINERvA/MINERvAVariableBoxes.h
index 56288f8..06ed9ed 100644
--- a/src/MINERvA/MINERvAVariableBoxes.h
+++ b/src/MINERvA/MINERvAVariableBoxes.h
@@ -1,30 +1,57 @@
#ifndef MINERvA_VARIABLES_BOX_H
#define MINERvA_VARIABLES_BOX_H
#include "MeasurementVariableBox.h"
#include "MeasurementVariableBox1D.h"
#include "MeasurementVariableBox2D.h"
/*!
* \addtogroup FitBase
* @{
*/
/// Custom box used to also save All Pion Tpi for each event.
class NTpiVariableBox1D : public MeasurementVariableBox1D {
public:
- inline NTpiVariableBox1D() { Reset(); };
+ inline NTpiVariableBox1D() { };
inline void Reset() { fTpiVect.clear(); }
+
+ inline MeasurementVariableBox* CloneSignalBox(){
+ NTpiVariableBox1D* box = new NTpiVariableBox1D();
+ box->fX = this->fX;
+ box->fSampleWeight = this->fSampleWeight;
+
+ box->fTpiVect.clear();
+ for (int i = 0; i < this->fTpiVect.size(); i++){
+ box->fTpiVect.push_back( this->fTpiVect[i] );
+ }
+ return box;
+ }
+ inline void Print(){
+ std::cout << "Box Print Size : " << this->fTpiVect.size() << std::endl;
+ }
+
std::vector<double> fTpiVect;
};
/// Custom box used to also save All Pion Tpi for each event.
class NthpiVariableBox1D : public MeasurementVariableBox1D {
public:
- inline NthpiVariableBox1D() { Reset(); };
+ inline NthpiVariableBox1D() { };
inline void Reset() { fthpiVect.clear(); }
+ inline MeasurementVariableBox* CloneSignalBox(){
+ NthpiVariableBox1D* box = new NthpiVariableBox1D();
+ box->fX = this->fX;
+ box->fSampleWeight = this->fSampleWeight;
+
+ box->fthpiVect.clear();
+ for (int i = 0; i < this->fthpiVect.size(); i++){
+ box->fthpiVect.push_back( this->fthpiVect[i] );
+ }
+ return box;
+ }
std::vector<double> fthpiVect;
};
#endif
diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx
index cbee9ae..f5a2fa7 100644
--- a/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx
+++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx
@@ -1,108 +1,109 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CC1pi0_XSec_1DEnu_antinu.h"
//********************************************************************
MINERvA_CC1pi0_XSec_1DEnu_antinu::MINERvA_CC1pi0_XSec_1DEnu_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MINERvA_CC1pi0_XSec_1DEnu_antinu sample. \n" \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current numubar \n" \
"Signal: Any event with 1 muon, 1 pion, no other tracks \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("E_{#nu} (GeV)");
fSettings.SetYTitle("#sigma(E_{#nu} (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MINERvA_CC1pi0_XSec_1DEnu_antinu");
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents);
// Plot Setup -------------------------------------------------------
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-enu.csv");
for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) {
fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.);
}
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-enu.csv");
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MINERvA_CC1pi0_XSec_1DEnu_antinu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(-13) == 0) return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP;
double hadMass = FitUtils::Wrec(Pnu, Pmu);
double Enu = -999;
if (hadMass < 1800)
Enu = Pnu.E()/1000.;
fXVar = Enu;
return;
};
// **************************************
// MINERvA CC1pi0 in anti-neutrino mode
// Unfortunately there's no information on the neutrino component which is
// subtracted off
//
// 2014 analysis:
// Exactly one positive muon
// Exactly one observed pi0
// No pi+/pi allowed
// No information on what is done with mesons, oops?
// No information on what is done with nucleons, oops?
//
// 2016 analysis:
// Exactly one positive muon
// Exactly one observed pi0
// No other mesons
// No other charged tracks (means no protons)
//
//********************************************************************
bool MINERvA_CC1pi0_XSec_1DEnu_antinu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax);
}
diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx
index 8b3eb7b..f5fc03a 100644
--- a/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx
+++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx
@@ -1,91 +1,92 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CC1pi0_XSec_1DQ2_antinu.h"
//********************************************************************
MINERvA_CC1pi0_XSec_1DQ2_antinu::MINERvA_CC1pi0_XSec_1DQ2_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MINERvA_CC1pi0_XSec_1DQ2_antinu sample. \n" \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current numubar \n" \
"Signal: Any event with 1 muon, 1 pion, no other tracks \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("Q^{2} (GeV^{2})");
fSettings.SetYTitle("d#sigma/dQ^{2} (cm^{2}/(GeV^{2})/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MINERvA_CC1pi0_XSec_1DQ2_antinu");
fSettings.DefineAllowedSpecies("numu");
// fFluxCorrected = fSettings.Found("name", "fluxcorr");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-q2.csv");
for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) {
fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.);
}
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-q2.csv");
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MINERvA_CC1pi0_XSec_1DQ2_antinu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(-13) == 0) return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP;
double hadMass = FitUtils::Wrec(Pnu, Pmu);
double Q2 = -999;
if (hadMass < 1800) {
Q2 = -1*(Pnu-Pmu).Mag2()/1.E6;
}
fXVar = Q2;
return;
};
//********************************************************************
bool MINERvA_CC1pi0_XSec_1DQ2_antinu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax);
}
diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx
index 67d9729..cfab2c3 100644
--- a/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx
+++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx
@@ -1,97 +1,98 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CC1pi0_XSec_1DTpi0_antinu.h"
// The 2016 MINERvA measurement is in Tpi
// The 2016 MINERvA measurement is in ppi
//********************************************************************
MINERvA_CC1pi0_XSec_1DTpi0_antinu::MINERvA_CC1pi0_XSec_1DTpi0_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MINERvA_CC1pi0_XSec_1DTpi0_antinu sample. \n" \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current numubar \n" \
"Signal: Any event with 1 muon, 1 pion, no other tracks \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("T_{#pi} (GeV)");
fSettings.SetYTitle("d#sigma/dT_{#pi} (cm^{2}/GeV/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MINERvA_CC1pi0_XSec_1DTpi0_antinu");
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-pion-kinetic-energy.csv");
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinError(i + 1, fDataHist->GetBinContent(i + 1)*fDataHist->GetBinError(i + 1) / 100.);
}
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-pion-kinetic-energy.csv");
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MINERvA_CC1pi0_XSec_1DTpi0_antinu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0 ||
event->NumFSParticle(-13) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP;
double hadMass = FitUtils::Wrec(Pnu, Pmu);
double Tpi0 = -999;
if (hadMass < 1800)
Tpi0 = FitUtils::T(Ppi0);
fXVar = Tpi0;
};
//********************************************************************
bool MINERvA_CC1pi0_XSec_1DTpi0_antinu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax);
}
diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx
index 71ac265..19dfe99 100644
--- a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx
+++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx
@@ -1,89 +1,90 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CC1pi0_XSec_1Dpmu_antinu.h"
//********************************************************************
MINERvA_CC1pi0_XSec_1Dpmu_antinu::MINERvA_CC1pi0_XSec_1Dpmu_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MINERvA_CC1pi0_XSec_1Dpmu_antinu sample. \n" \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current numubarr \n" \
"Signal: Any event with 1 muon, 1 pion, no other tracks \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("p_{#mu} (GeV)");
fSettings.SetYTitle("d#sigma/dp_{#mu} (cm^{2}/GeV/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MINERvA_CC1pi0_XSec_1Dpmu_antinu");
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-muon-momentum.csv");
for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) {
fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.);
}
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-muon-momentum.csv");
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MINERvA_CC1pi0_XSec_1Dpmu_antinu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(-13) == 0) return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP;
double hadMass = FitUtils::Wrec(Pnu, Pmu);
double pmu = -999;
if (hadMass < 1800)
pmu = FitUtils::p(Pmu);
fXVar = pmu;
return;
};
//********************************************************************
bool MINERvA_CC1pi0_XSec_1Dpmu_antinu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax);
}
diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx
index d8a8313..5d56b9d 100644
--- a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx
+++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx
@@ -1,131 +1,132 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CC1pi0_XSec_1Dth_antinu.h"
//********************************************************************
MINERvA_CC1pi0_XSec_1Dth_antinu::MINERvA_CC1pi0_XSec_1Dth_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MINERvA_CC1pi0_XSec_1Dth_antinu sample. \n" \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current numubar \n" \
"Signal: Any event with 1 muon, 1 pion, no other tracks \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("#theta_{#pi} (degrees)");
fSettings.SetYTitle("d#sigma/d#theta_{#pi}) (cm^{2}/nucleon/degree)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
fUpdatedData = !fSettings.Found("name", "2015");
fFluxCorrection = fSettings.Found("name","fluxcorr");
// CCQELike plot information
fSettings.SetTitle("MINERvA_CC1pi0_XSec_1Dth_antinu");
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
if (fUpdatedData) {
hadMassCut = 1800;
fIsDiag = false;
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-pion-angle.csv");
// Error is given as percentage of cross-section
// Need to scale the bin error properly before we do correlation -> covariance conversion
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinError(i + 1, fDataHist->GetBinContent(i + 1)*fDataHist->GetBinError(i + 1) / 100.);
}
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-pion-angle.csv");
+ SetShapeCovar();
} else {
// Although the covariance is given for MINERvA CC1pi0 nubar from 2015, it doesn't Cholesky decompose, hinting at something bad
// I've tried adding small numbers to the diagonal but it still didn't work and the chi2s are crazy
fIsDiag = true;
fNormError = 0.15;
// No hadronic mass cut on old publication
hadMassCut = 99999;
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2015/ccpi0_th.csv");
SetCovarFromDiagonal();
} // end special treatment depending on release year
if (fFluxCorrection) {
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) * 1.11);
}
}
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MINERvA_CC1pi0_XSec_1Dth_antinu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0 ||
event->NumFSParticle(-13) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP;
double hadMass = FitUtils::Wrec(Pnu, Pmu);
double th = -999;
if (hadMass < hadMassCut)
th = (180. / M_PI) * FitUtils::th(Pnu, Ppi0);
fXVar = th;
return;
};
//********************************************************************
bool MINERvA_CC1pi0_XSec_1Dth_antinu::isSignal(FitEvent *event) {
//********************************************************************
if (fUpdatedData) {
return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax);
} else {
return SignalDef::isCC1pi0_MINERvA_2015(event, EnuMin, EnuMax);
}
}
diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx
index cfde6e4..e5d212d 100644
--- a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx
+++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx
@@ -1,90 +1,91 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CC1pi0_XSec_1Dthmu_antinu.h"
//********************************************************************
MINERvA_CC1pi0_XSec_1Dthmu_antinu::MINERvA_CC1pi0_XSec_1Dthmu_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MINERvA_CC1pi0_XSec_1Dthmu_antinu sample. \n" \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current numubar \n" \
"Signal: Any event with 1 muon, 1 pion, no other tracks \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("#theta_{#mu}");
fSettings.SetYTitle("d#sigma/d#theta_{#mu} (cm^{2}/degrees/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MINERvA_CC1pi0_XSec_1Dthmu_antinu");
fSettings.DefineAllowedSpecies("numu");
fFluxCorrected = fSettings.Found("name", "fluxcorr");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-muon-angle.csv");
for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) {
fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.);
}
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-muon-angle.csv");
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MINERvA_CC1pi0_XSec_1Dthmu_antinu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(-13) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP;
double hadMass = FitUtils::Wrec(Pnu, Pmu);
double thmu = -999;
if (hadMass < 1800)
thmu = (180./M_PI)*FitUtils::th(Pnu, Pmu);
fXVar = thmu;
return;
};
//********************************************************************
bool MINERvA_CC1pi0_XSec_1Dthmu_antinu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax);
}
diff --git a/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx b/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx
index ed7ca53..aad2bd9 100644
--- a/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx
+++ b/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx
@@ -1,169 +1,170 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CC1pip_XSec_1D_2017Update.h"
//********************************************************************
void MINERvA_CC1pip_XSec_1D_2017Update::SetupDataSettings(){
//********************************************************************
// Set Distribution
std::string name = fSettings.GetS("name");
if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_2017")) fDist = kTpi;
else if (!name.compare("MINERvA_CC1pip_XSec_1Dth_nu_2017")) fDist= kth;
else if (!name.compare("MINERvA_CC1pip_XSec_1Dpmu_nu_2017")) fDist= kpmu;
else if (!name.compare("MINERvA_CC1pip_XSec_1Dthmu_nu_2017")) fDist= kthmu;
else if (!name.compare("MINERvA_CC1pip_XSec_1DQ2_nu_2017")) fDist= kQ2;
else if (!name.compare("MINERvA_CC1pip_XSec_1DEnu_nu_2017")) fDist= kEnu;
// Define what files to use from the dist
std::string datafile = "";
std::string covarfile = "";
std::string titles = "";
std::string distdescript = "";
switch(fDist){
case (kTpi):
datafile = "cc1pip_updated_1DTpi";
covarfile = "cc1pip_updated_1DTpi";
titles = "CC1#pi Updated;T_{#pi} (MeV);d#sigma/dT_{#pi} (cm^{2}/nucleon/MeV)";
break;
case (kth):
datafile = "cc1pip_updated_1Dth";
covarfile = "cc1pip_updated_1Dth";
titles = "CC1#pi Updated;#theta_{#pi};d#sigma/d#theta_{#pi} (cm^{2}/nucleon)";
break;
case (kpmu):
datafile = "cc1pip_updated_1Dpmu";
covarfile = "cc1pip_updated_1Dpmu";
titles = "CC1#pi Updated;p_{#mu} (GeV);d#sigma/dp_{#mu} (cm^{2}/nucleon/GeV)";
break;
case (kthmu):
datafile = "cc1pip_updated_1Dthmu";
covarfile = "cc1pip_updated_1Dthmu";
titles ="CC1#pi Updated;#theta_{#mu};d#sigma/d#theta_{#mu} (cm^{2}/nucleon)";
break;
case (kQ2):
datafile = "cc1pip_updated_1DQ2";
covarfile = "cc1pip_updated_1DQ2";
titles ="CC1#pi Updated;Q^{2} (GeV^{2});d#sigma/dQ^{2} (cm^{2}/nucleon/GeV^{2})";
break;
case (kEnu):
datafile = "cc1pip_updated_1DEnu";
covarfile = "cc1pip_updated_1DEnu";
titles ="CC1#pi Updated;E_{#nu} (GeV);#sigma(E_#nu) (cm^{2}/nucleon)";
break;
default:
THROW("Unknown Analysis Distribution : " << fDist);
}
// Choose shape or rate covariance
fIsShape = fSettings.Found("type","SHAPE");
std::string covid = fIsShape ? "_shapecov.txt" : "_ratecov.txt";
// Now setup each data distribution and description.
std::string descrip = distdescript + \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current numu ONLY \n" \
"Signal: Any event with 1 muon, and 1pi+ or 1pi- in FS. W < 1.4";
fSettings.SetDescription(descrip);
fSettings.SetDataInput( GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pip/070717/" + datafile + "_data.txt" );
fSettings.SetCovarInput( GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pip/070717/" + covarfile + covid );
fSettings.SetTitle( GeneralUtils::ParseToStr(titles,";")[0] );
fSettings.SetXTitle( GeneralUtils::ParseToStr(titles,";")[1] );
fSettings.SetYTitle( GeneralUtils::ParseToStr(titles,";")[2] );
return;
}
//********************************************************************
MINERvA_CC1pip_XSec_1D_2017Update::MINERvA_CC1pip_XSec_1D_2017Update(nuiskey samplekey) {
//********************************************************************
// Define Sample Settings common to all data distributions
fSettings = LoadSampleSettings(samplekey);
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
SetupDataSettings();
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// If Enu setup scale factor for Enu Unfolded, otherwise use differential
if (fDist == kEnu) fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents);
else fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCorrelationFromTextFile( fSettings.GetCovarInput() );
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
void MINERvA_CC1pip_XSec_1D_2017Update::FillEventVariables(FitEvent *event) {
//********************************************************************
fXVar = -999.9;
if (event->NumFSParticle(PhysConst::pdg_charged_pions) == 0 ||
event->NumFSParticle(13) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(PhysConst::pdg_charged_pions)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double Tpi = Ppip.E() - Ppip.Mag();
double th = (180./M_PI)*FitUtils::th(Pnu, Ppip);
double pmu = Pmu.Vect().Mag()/1.E3; // GeV
double thmu = (180.0/M_PI)*FitUtils::th(Pnu, Pmu);
double Q2 = fabs((Pmu - Pnu).Mag2()) / 1.E6; // Using true here?
double Enu = Pnu.E() / 1.E3;
switch(fDist){
case kTpi: fXVar = Tpi; break;
case kth: fXVar = th; break;
case kpmu: fXVar = pmu; break;
case kthmu: fXVar = thmu; break;
case kQ2: fXVar = Q2; break;
case kEnu: fXVar = Enu; break;
default:
THROW("DIST NOT FOUND : " << fDist);
}
return;
};
//********************************************************************
bool MINERvA_CC1pip_XSec_1D_2017Update::isSignal(FitEvent *event) {
//********************************************************************
// Only seem to release full phase space
return SignalDef::isCC1pip_MINERvA_2017(event, EnuMin, EnuMax);
}
diff --git a/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx b/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx
index 51fa133..74f9d9a 100644
--- a/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx
+++ b/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx
@@ -1,267 +1,267 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MINERvA_SignalDef.h"
#include "MINERvA_CCNpip_XSec_1DTpi_nu.h"
//********************************************************************
MINERvA_CCNpip_XSec_1DTpi_nu::MINERvA_CCNpip_XSec_1DTpi_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MINERvA_CCNpip_XSec_1DTpi_nu sample. \n" \
"Target: CH \n" \
"Flux: MINERvA Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("T_{#pi} (MeV)");
fSettings.SetYTitle("(1/T#Phi) dN_{#pi}/dT_{#pi} (cm^{2}/MeV/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(1.5, 10.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fFullPhaseSpace = !fSettings.Found("name", "_20deg");
fFluxCorrection = fSettings.Found("name", "fluxcorr");
fUpdatedData = !fSettings.Found("name", "2015");
fSettings.SetTitle("MINERvA_CCNpip_XSec_1DTpi_nu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
// Full Phase Space
if (fFullPhaseSpace) {
// 2016 release
if (fUpdatedData) {
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2016/nu-ccNpi+-xsec-pion-kinetic-energy.csv");
// MINERvA has the error quoted as a percentage of the cross-section
// Need to make this into an absolute error before we go from correlation
// matrix -> covariance matrix since it depends on the error in the ith
// bin
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinError(i + 1, fDataHist->GetBinContent(i + 1) * (fDataHist->GetBinError(i + 1) / 100.));
}
// This is a correlation matrix, not covariance matrix, so needs to be
// converted
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2016/nu-ccNpi+-correlation-pion-kinetic-energy.csv");
// 2015 release
} else {
// If we're doing shape only
if (fIsShape) {
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_shape.txt");
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_shape_cov.txt");
// If we're doing full cross-section
} else {
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi.txt");
SetCorrelationFromTextFile( GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_cov.txt");
}
}
// Restricted Phase Space
} else {
// Only 2015 data released restricted muon phase space cross-section
// unfortunately
if (fUpdatedData) {
ERR(FTL) << fName << " has no updated 2016 data for restricted phase space! Using 2015 data." << std::endl;
throw;
}
// If we're using the shape only data
if (fIsShape) {
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg_shape.txt");
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg_shape_cov.txt");
// Or total cross-section
} else {
SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg.txt");
SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg_cov.txt");
}
}
// Scale the MINERvA data to account for the flux difference
// Adjust MINERvA data to flux correction; roughly a 11% normalisation increase in data
// Please change when MINERvA releases new data!
if (fFluxCorrection) {
for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
fDataHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) * 1.11);
}
}
// Make some auxillary helper plots
onePions = (TH1D*)(fDataHist->Clone());
onePions->SetNameTitle((fName + "_1pions").c_str(), (fName + "_1pions" + fPlotTitles).c_str());
SetAutoProcessTH1(onePions, kCMD_Reset, kCMD_Scale, kCMD_Norm);
twoPions = (TH1D*)(fDataHist->Clone());
twoPions->SetNameTitle((fName + "_2pions").c_str(), (fName + "_2pions;" + fPlotTitles).c_str());
SetAutoProcessTH1(twoPions, kCMD_Reset, kCMD_Scale, kCMD_Norm);
threePions = (TH1D*)(fDataHist->Clone());
threePions->SetNameTitle((fName + "_3pions").c_str(), (fName + "_3pions" + fPlotTitles).c_str());
SetAutoProcessTH1(threePions, kCMD_Reset, kCMD_Scale, kCMD_Norm);
morePions = (TH1D*)(fDataHist->Clone());
morePions->SetNameTitle((fName + "_4pions").c_str(), (fName + "_4pions" + fPlotTitles).c_str());
SetAutoProcessTH1(morePions, kCMD_Reset, kCMD_Scale, kCMD_Norm);
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Here we have to fill for every pion we find in the event
void MINERvA_CCNpip_XSec_1DTpi_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
if (event->NumFSParticle(211) == 0 && event->NumFSParticle(-211) == 0) return;
if (event->NumFSParticle(13) == 0) return;
// Need to make this use event boxes
// Clear out the vectors
GetPionBox()->Reset();
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
// Loop over the particle stack
for (unsigned int j = 2; j < event->Npart(); ++j) {
// Only include alive particles
if (event->GetParticleState(j) != kFinalState) continue;
int PID = (event->PartInfo(j))->fPID;
// Pick up the charged pions in the event
if (abs(PID) == 211) {
double ppi = FitUtils::T(event->PartInfo(j)->fP) * 1000.;
GetPionBox()->fTpiVect.push_back(ppi);
}
}
fXVar = 0;
return;
};
//********************************************************************
// The last bool refers to if we're using restricted phase space or not
bool MINERvA_CCNpip_XSec_1DTpi_nu::isSignal(FitEvent *event) {
//********************************************************************
// Last false refers to that this is NOT the restricted MINERvA phase space,
// in which only forward-going muons are accepted
return SignalDef::isCCNpip_MINERvA(event, EnuMin, EnuMax, !fFullPhaseSpace, !fUpdatedData);
}
//********************************************************************
// Need to override FillHistograms() here because we fill the histogram N_pion
// times
void MINERvA_CCNpip_XSec_1DTpi_nu::FillHistograms() {
//********************************************************************
if (Signal) {
- unsigned int nPions = GetPionBox()->fTpiVect.size();
+ unsigned int nPions = GetPionBox()->fTpiVect.size();
// Need to loop over all the pions in the sample
for (size_t k = 0; k < nPions; ++k) {
double tpi = GetPionBox()->fTpiVect[k];
this->fMCHist->Fill(tpi, Weight);
this->fMCFine->Fill(tpi, Weight);
this->fMCStat->Fill(tpi, 1.0);
if (nPions == 1) {
onePions->Fill(tpi, Weight);
} else if (nPions == 2) {
twoPions->Fill(tpi, Weight);
} else if (nPions == 3) {
threePions->Fill(tpi, Weight);
} else if (nPions > 3) {
morePions->Fill(tpi, Weight);
}
if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, tpi, Weight);
}
}
}
//********************************************************************
void MINERvA_CCNpip_XSec_1DTpi_nu::ScaleEvents() {
//********************************************************************
Measurement1D::ScaleEvents();
onePions->Scale(this->fScaleFactor, "width");
twoPions->Scale(this->fScaleFactor, "width");
threePions->Scale(this->fScaleFactor, "width");
morePions->Scale(this->fScaleFactor, "width");
return;
}
//********************************************************************
void MINERvA_CCNpip_XSec_1DTpi_nu::Write(std::string drawOpts) {
//********************************************************************
Measurement1D::Write(drawOpts);
// Make an auto processed pion stack
// Draw the npions stack
onePions->SetTitle("1#pi");
onePions->SetLineColor(kBlack);
// onePions->SetFillStyle(0);
onePions->SetFillColor(onePions->GetLineColor());
twoPions->SetTitle("2#pi");
twoPions->SetLineColor(kRed);
// twoPions->SetFillStyle(0);
twoPions->SetFillColor(twoPions->GetLineColor());
threePions->SetTitle("3#pi");
threePions->SetLineColor(kGreen);
// threePions->SetFillStyle(0);
threePions->SetFillColor(threePions->GetLineColor());
morePions->SetTitle(">3#pi");
morePions->SetLineColor(kBlue);
// morePions->SetFillStyle(0);
morePions->SetFillColor(morePions->GetLineColor());
THStack pionStack =
THStack((fName + "_pionStack").c_str(), (fName + "_pionStack").c_str());
pionStack.Add(onePions);
pionStack.Add(twoPions);
pionStack.Add(threePions);
pionStack.Add(morePions);
pionStack.Write();
return;
}
diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx
index dfdd241..5c61d66 100644
--- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx
@@ -1,94 +1,95 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_CC1pi0_XSec_1DEnu_nu.h"
//********************************************************************
MiniBooNE_CC1pi0_XSec_1DEnu_nu::MiniBooNE_CC1pi0_XSec_1DEnu_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_CC1pi0_XSec_1DEnu_nu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("E_{#nu} (GeV)");
fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/CH_{2})");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.5, 2.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1DEnu_nu");
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/totalxsec_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/totalxsec_covar.txt" );
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08);
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCorrelationFromTextFile( fSettings.GetCovarInput() );
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_CC1pi0_XSec_1DEnu_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0 ||
event->NumFSParticle(13) == 0)
return;
TLorentzVector Pnu =event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double Enu = FitUtils::EnuCC1pi0rec(Pnu, Pmu, Ppi0);
fXVar = Enu;
return;
};
// **************************************************
// MiniBooNE CC1pi0 signal definition
//
// The signal definition is:
// Exactly one negative muon
// Exactly one pi0
// No additional mesons
// Any number of nucleons
//
// Does a few clever cuts on the likelihood to reduce CCQE contamination by
// looking at "fuzziness" of the ring; CCQE events are sharp, CC1pi0 are fuzzy
// (because of the pi0->2 gamma collinearity)
bool MiniBooNE_CC1pi0_XSec_1DEnu_nu::isSignal(FitEvent *event) {
return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax);
}
diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx
index 3c15ca2..4316e32 100644
--- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx
@@ -1,81 +1,82 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_CC1pi0_XSec_1DQ2_nu.h"
//********************************************************************
MiniBooNE_CC1pi0_XSec_1DQ2_nu::MiniBooNE_CC1pi0_XSec_1DQ2_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_CC1pi0_XSec_1DQ2_nu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("Q^{2}_{CC#pi} (GeV^{2})");
fSettings.SetYTitle("d#sigma/dQ_{CC#pi}^{2} (cm^{2}/GeV^{2})");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.5, 2.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1DQ2_nu");
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdq2_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdq2_covar.txt" );
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCorrelationFromTextFile( fSettings.GetCovarInput() );
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_CC1pi0_XSec_1DQ2_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0) return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double q2 = -1*(Pnu-Pmu).Mag2()/(1.E6);
fXVar = q2;
return;
};
//********************************************************************
bool MiniBooNE_CC1pi0_XSec_1DQ2_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax);
}
diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx
index 3245928..07df183 100644
--- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx
@@ -1,83 +1,84 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_CC1pi0_XSec_1DTu_nu.h"
//********************************************************************
MiniBooNE_CC1pi0_XSec_1DTu_nu::MiniBooNE_CC1pi0_XSec_1DTu_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_CC1pi0_XSec_1DTu_nu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("T_{#mu} (GeV)");
fSettings.SetYTitle("d#sigma/dE_{#mu} (cm^{2}/GeV^{2}/CH_{2})");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.5, 2.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1DTu_nu");
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdemu_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdemu_covar.txt" );
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCorrelationFromTextFile( fSettings.GetCovarInput() );
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_CC1pi0_XSec_1DTu_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0 ||
event->NumFSParticle(13) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double TuCCpi0 = FitUtils::T(Pmu);
fXVar = TuCCpi0;
return;
};
//********************************************************************
bool MiniBooNE_CC1pi0_XSec_1DTu_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax);
}
diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx
index 7ed184e..757046a 100644
--- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx
@@ -1,85 +1,86 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.h"
//********************************************************************
MiniBooNE_CC1pi0_XSec_1Dcosmu_nu::MiniBooNE_CC1pi0_XSec_1Dcosmu_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_CC1pi0_XSec_1Dcosmu_nu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("cos#theta_{#mu}");
fSettings.SetYTitle("d#sigma/dcos#theta_{#mu} (cm^{2}/CH_{2})");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.5, 2.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1Dcosmu_nu");
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcosmu_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcosmu_covar.txt" );
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCorrelationFromTextFile( fSettings.GetCovarInput() );
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_CC1pi0_XSec_1Dcosmu_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0 ||
event->NumFSParticle(13) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
// No W cut on MiniBooNE CC1pi+
double CosMu = cos(FitUtils::th(Pnu, Pmu));
fXVar = CosMu;
return;
};
//********************************************************************
bool MiniBooNE_CC1pi0_XSec_1Dcosmu_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax);
}
diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx
index 0758791..a0ad302 100644
--- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx
@@ -1,84 +1,85 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.h"
//********************************************************************
MiniBooNE_CC1pi0_XSec_1Dcospi0_nu::MiniBooNE_CC1pi0_XSec_1Dcospi0_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_CC1pi0_XSec_1Dcospi0_nu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("cos#theta_{#pi^{0}}");
fSettings.SetYTitle("d#sigma/dcos#theta_{#pi^{0}} (cm^{2}/CH_{2})");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.5, 2.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1Dcospi0_nu");
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcospi_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcospi_covar.txt" );
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCorrelationFromTextFile( fSettings.GetCovarInput() );
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_CC1pi0_XSec_1Dcospi0_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0 ||
event->NumFSParticle(13) == 0)
return;
TLorentzVector Pnu =event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double CosPi0 = cos(FitUtils::th(Pnu, Ppi0));
fXVar = CosPi0;
return;
};
//********************************************************************
bool MiniBooNE_CC1pi0_XSec_1Dcospi0_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax);
}
diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx
index 0b258df..09919a9 100644
--- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx
@@ -1,90 +1,91 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_CC1pi0_XSec_1Dppi0_nu.h"
MiniBooNE_CC1pi0_XSec_1Dppi0_nu::MiniBooNE_CC1pi0_XSec_1Dppi0_nu(nuiskey confkey) {
// 1. Initalise sample Settings (all overrideable in cardfile) --------------
fSettings = LoadSampleSettings(confkey); // Must go first
fSettings.SetDescription("");
fSettings.SetXTitle("p_{#pi^{0}} (GeV/c)");
fSettings.SetYTitle("d#sigma/dp_{#pi^{0}} (cm^{2}/GeV/CH_{2})");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.5, 2.0);
fSettings.SetSuggestedFlux( FitPar::GetDataBase() + "/MiniBooNE/ccqe/mb_fhc_flux.root");
fSettings.SetTitle("MiniBooNE #nu_#mu CC1#pi^{0} on CH");
fSettings.SetDataInput( FitPar::GetDataBase() + "/MiniBooNE/CC1pi0/dxsecdppi_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "/MiniBooNE/CC1pi0/dxsecdppi_covar.txt" );
fSettings.DefineAllowedSpecies("numu");
fSettings.DefineAllowedTargets("C,H");
FinaliseSampleSettings(); // Must go after all settings
// 2. Set Scale Factor -------------------------------------------------------
fScaleFactor = GetEventHistogram()->Integral("width")
* double(1E-38) / double(fNEvents)
* (14.08) / TotalIntegratedFlux("width");
// 3. Plot Setup -------------------------------------------------------
SetDataValues( fSettings.GetDataInput() );
SetCovarMatrixFromCorrText( fSettings.GetCovarInput(), fDataHist->GetNbinsX() );
+ SetShapeCovar();
// Create a Target Species Stack copying data
fTargetStack = new TargetTypeStack( fSettings.Name() + "_TGT",
"Target Contributions" + fSettings.PlotTitles(),
fDataHist);
SetAutoProcessTH1(fTargetStack);
// Final MC Setup
// Must go last
FinaliseMeasurement();
};
void MiniBooNE_CC1pi0_XSec_1Dppi0_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(111) == 0 ||
event->NumFSParticle(13) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double p_pi0 = FitUtils::p(Ppi0);
fXVar = p_pi0;
fTargetPDG = event->fTargetPDG;
return;
};
//********************************************************************
bool MiniBooNE_CC1pi0_XSec_1Dppi0_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax);
}
//********************************************************************
void MiniBooNE_CC1pi0_XSec_1Dppi0_nu::FillExtraHistograms(MeasurementVariableBox* box, double weight){
//********************************************************************
if (!Signal) return;
fTargetStack->Fill( fTargetPDG, fXVar, weight );
}
diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx
index 5013411..48a3f35 100644
--- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx
+++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx
@@ -1,102 +1,103 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.h"
//********************************************************************
MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu::MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("cos#theta_{#pi^{0}}");
fSettings.SetYTitle("d#sigma/dcos#theta_{#pi^{0}} (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.0, 5.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu");
nunubar_mode = fSettings.Found("name", "combined");
if (!nunubar_mode) {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarcosthetapi0xsec_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarcosthetapi0xsecerrormatrix.txt" );
fSettings.DefineAllowedSpecies("numub");
} else {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodecosthetapi0xsec_edit.txt");
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodecosthetapi0xsecerrormatrix.txt");
fSettings.DefineAllowedSpecies("numu,numub");
}
-
+
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCovarFromTextFile( fSettings.GetCovarInput() );
ScaleCovar(1.E-5);
StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38);
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu::FillEventVariables(FitEvent *event) {
// (CP) require pi0 in final state (this makes some assumptions about how the
// generator treats the pi0 after it is produced in the nucleus.
// MB required 2 photons to make a pion signal, so check for those later
if (event->NumFSParticle(111) == 0 ) {
return;
}
if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
double CosPi0 = cos(FitUtils::th(Pnu, Ppi0));
fXVar = CosPi0;
return;
};
//********************************************************************
bool MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu::isSignal(FitEvent *event) {
//********************************************************************
if (nunubar_mode) {
return (SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) ||
SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax));
} else {
return SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax);
}
}
diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx
index e413b2c..fcc28a0 100644
--- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx
@@ -1,104 +1,105 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.h"
//********************************************************************
MiniBooNE_NC1pi0_XSec_1Dcospi0_nu::MiniBooNE_NC1pi0_XSec_1Dcospi0_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dcospi0_nu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("cos#theta_{#pi^{0}}");
fSettings.SetYTitle("d#sigma/dcos#theta_{#pi^{0}} (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.0, 5.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dcospi0_nu");
nunubarmode = fSettings.Found("name", "combined");
if (!nunubarmode) {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nucosthetapi0xsec_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nucosthetapi0xsecerrormatrix.txt" );
fSettings.DefineAllowedSpecies("numu");
} else {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodecosthetapi0xsec_edit.txt");
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodecosthetapi0xsecerrormatrix.txt");
fSettings.DefineAllowedSpecies("numu,numub");
}
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCovarFromTextFile( fSettings.GetCovarInput() );
ScaleCovar(1.E-5);
StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38);
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_NC1pi0_XSec_1Dcospi0_nu::FillEventVariables(FitEvent *event) {
// (CP) require pi0 in final state (this makes some assumptions about how the
// generator treats the pi0 after it is produced in the nucleus.
// MB required 2 photons to make a pion signal, so check for those later
if (event->NumFSParticle(111) == 0 ) {
return;
}
if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
double CosPi0 = cos(FitUtils::th(Pnu, Ppi0));
fXVar = CosPi0;
return;
};
//********************************************************************
bool MiniBooNE_NC1pi0_XSec_1Dcospi0_nu::isSignal(FitEvent *event) {
//********************************************************************
if (nunubarmode){
return (SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) ||
SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax));
} else {
return SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax);
}
}
diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx
index de94f25..3f13396 100644
--- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx
+++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx
@@ -1,103 +1,104 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.h"
//********************************************************************
MiniBooNE_NC1pi0_XSec_1Dppi0_antinu::MiniBooNE_NC1pi0_XSec_1Dppi0_antinu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dppi0_antinu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("p_{#pi^{0}} (GeV/c)");
fSettings.SetYTitle("d#sigma/dp_{#pi^{0}} (cm^{2}/(GeV/c)/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.0, 5.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dppi0_antinu");
nunubarmode = fSettings.Found("name", "combined");
if (!nunubarmode) {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarppi0xsec_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarppi0xsecerrormatrix.txt" );
fSettings.DefineAllowedSpecies("numu");
} else {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodeppi0xsec_edit.txt");
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodeppi0xsecerrormatrix.txt");
fSettings.DefineAllowedSpecies("numu,numub");
}
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCovarFromTextFile( fSettings.GetCovarInput() );
ScaleCovar(1.E-5);
StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38);
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_NC1pi0_XSec_1Dppi0_antinu::FillEventVariables(FitEvent *event) {
// (CP) require pi0 in final state (this makes some assumptions about how the
// generator treats the pi0 after it is produced in the nucleus.
// MB required 2 photons to make a pion signal, so check for those later
if (event->NumFSParticle(111) == 0) {
return;
}
if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
double p_pi0 = FitUtils::p(Ppi0);
fXVar = p_pi0;
return;
};
//********************************************************************
bool MiniBooNE_NC1pi0_XSec_1Dppi0_antinu::isSignal(FitEvent *event) {
//********************************************************************
if (nunubarmode){
return (SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax) ||
SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) );
} else {
return SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax);
}
}
diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx
index 1dc1119..ea0fea1 100644
--- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx
+++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx
@@ -1,103 +1,104 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "MiniBooNE_NC1pi0_XSec_1Dppi0_nu.h"
//********************************************************************
MiniBooNE_NC1pi0_XSec_1Dppi0_nu::MiniBooNE_NC1pi0_XSec_1Dppi0_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dppi0_nu sample. \n" \
"Target: CH \n" \
"Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 muon, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("p_{#pi^{0}} (GeV/c)");
fSettings.SetYTitle("d#sigma/dp_{#pi^{0}} (cm^{2}/(GeV/c)/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.0, 5.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dppi0_nu");
nunubar_mode_nu = fSettings.Found("name", "combined");
if (!nunubar_mode_nu) {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nuppi0xsec_edit.txt" );
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nuppi0xsecerrormatrix.txt" );
fSettings.DefineAllowedSpecies("numu");
} else {
fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodeppi0xsec_edit.txt");
fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodeppi0xsecerrormatrix.txt");
fSettings.DefineAllowedSpecies("numu,numub");
}
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromTextFile( fSettings.GetDataInput() );
SetCovarFromTextFile( fSettings.GetCovarInput() );
ScaleCovar(1.E-5);
StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38);
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
void MiniBooNE_NC1pi0_XSec_1Dppi0_nu::FillEventVariables(FitEvent *event) {
// (CP) require pi0 in final state (this makes some assumptions about how the
// generator treats the pi0 after it is produced in the nucleus.
// MB required 2 photons to make a pion signal, so check for those later
if (event->NumFSParticle(111) == 0) {
return;
}
if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
double p_pi0 = FitUtils::p(Ppi0);
fXVar = p_pi0;
return;
};
//********************************************************************
bool MiniBooNE_NC1pi0_XSec_1Dppi0_nu::isSignal(FitEvent *event) {
//********************************************************************
if (nunubar_mode_nu){
return (SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) ||
SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax));
} else {
return SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax);
}
}
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx
index 2764225..ee52182 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx
@@ -1,204 +1,201 @@
#include <iomanip>
#include "T2K_SignalDef.h"
#include "T2K_CC1pip_CH_XSec_1DQ2_nu.h"
// The constructor
T2K_CC1pip_CH_XSec_1DQ2_nu::T2K_CC1pip_CH_XSec_1DQ2_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
EnuMin = 0.;
EnuMax = 100.;
fIsDiag = false;
// Here we can give either MB (kMB), extended MB (keMB) or Delta (kDelta)
if (type.find("eMB") != std::string::npos) {
fT2KSampleType = keMB;
fName = "T2K_CC1pip_CH_XSec_1DQ2eMB_nu";
fPlotTitles = "; Q^{2}_{eMB} (GeV^{2}); d#sigma/dQ^{2}_{eMB} (cm^{2}/GeV^{2}/nucleon)";
} else if (type.find("MB") != std::string::npos) {
fT2KSampleType = kMB;
fName = "T2K_CC1pip_CH_XSec_1DQ2MB_nu";
fPlotTitles = "; Q^{2}_{MB} (GeV^{2}); d#sigma/dQ^{2}_{MB} (cm^{2}/GeV^{2}/nucleon)";
} else if (type.find("Delta") != std::string::npos) {
fT2KSampleType = kDelta;
fName = "T2K_CC1pip_CH_XSec_1DQ2delta_nu";
fPlotTitles = "; Q^{2}_{#Delta} (GeV^{2}); d#sigma/dQ^{2}_{#Delta} (cm^{2}/GeV^{2}/nucleon)";
} else {
LOG(SAM) << "Found no specified type, using MiniBooNE E_nu/Q2 definition" << std::endl;
fT2KSampleType = kMB;
fName = "T2K_CC1pip_CH_XSec_1DQ2MB_nu";
fPlotTitles = "; Q^{2}_{MB} (GeV^{2}); d#sigma/dQ^{2}_{MB} (cm^{2}/GeV^{2}/nucleon)";
}
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
//type = keMB;
//type = kDelta;
if (fT2KSampleType == kMB) {
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_MB.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_MB.root");
} else if (fT2KSampleType == keMB) {
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_extendedMB.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_extendedMB.root");
} else if (fT2KSampleType == kDelta) {
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_Delta.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_Delta.root");
} else {
ERR(FTL) << "No data type set for " << fName << std::endl;
ERR(FTL) << __FILE__ << ":" << __LINE__ << std::endl;
exit(-1);
}
+ SetShapeCovar();
this->SetupDefaultHist();
-
+
this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1DQ2_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
const int nPoints = dataCopy->GetNbinsX()-6;
LOG(DEB) << nPoints << std::endl;
double *binEdges = new double[nPoints+1];
for (int i = 0; i < nPoints+1; i++) {
binEdges[i] = dataCopy->GetBinLowEdge(i+1);
}
for (int i = 0; i < nPoints+1; i++) {
LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl;
}
fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), nPoints, binEdges);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38);
fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str());
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1DQ2_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
int nBinsX = covarMatrix->GetXaxis()->GetNbins();
int nBinsY = covarMatrix->GetYaxis()->GetNbins();
LOG(DEB) << nBinsX << std::endl;
LOG(DEB) << fDataHist->GetNbinsX() << std::endl;
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
- this->covar = new TMatrixDSym(nBinsX-7);
this->fFullCovar = new TMatrixDSym(nBinsX-7);
// First two entries are BS
// Last entry is BS
for (int i = 0; i < nBinsX-7; i++) {
for (int j = 0; j < nBinsY-7; j++) {
- (*this->covar)(i, j) = covarMatrix->GetBinContent(i+3, j+3); //adds syst+stat covariances
(*this->fFullCovar)(i, j) = covarMatrix->GetBinContent(i+3, j+3); //adds syst+stat covariances
- LOG(DEB) << "covar(" << i << ", " << j << ") = " << (*this->covar)(i,j) << std::endl;
+ LOG(DEB) << "fFullCovar(" << i << ", " << j << ") = " << (*this->fFullCovar)(i,j) << std::endl;
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
-
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
return;
};
void T2K_CC1pip_CH_XSec_1DQ2_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double q2 = -999;
switch(fT2KSampleType) {
// First int refers to how we reconstruct Enu
// 0 uses true neutrino energy (not used here but common for other analyses when they unfold to true Enu from reconstructed Enu)
// 1 uses "extended MiniBooNE" method
// 2 uses "MiniBooNE reconstructed" method
// 3 uses Delta resonance mass for reconstruction
//
// The last bool refers to if pion directional information was used
//
// Use MiniBooNE reconstructed Enu; uses Michel tag so no pion direction information
case kMB:
q2 = FitUtils::Q2CC1piprec(Pnu, Pmu, Ppip, 2, false);
break;
// Use Extended MiniBooNE reconstructed Enu
// Needs pion information to reconstruct so bool is true (did not include Michel e tag)
case keMB:
q2 = FitUtils::Q2CC1piprec(Pnu, Pmu, Ppip, 1, true);
break;
// Use Delta resonance reconstructed Enu
// Uses Michel electron so don't have pion directional information
case kDelta:
q2 = FitUtils::Q2CC1piprec(Pnu, Pmu, Ppip, 3, false);
break;
}
fXVar = q2;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1DQ2_nu::isSignal(FitEvent *event) {
//********************************************************************
// Warning: The CH analysis has different signal definition to the H2O analysis!
// Often to do with the Michel tag
switch(fT2KSampleType) {
// Using MiniBooNE formula for Enu reconstruction on the Q2 variable
// Does have Michel e tag, set bool to true!
case kMB:
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true);
break;
// Using extended MiniBooNE formula for Enu reconstruction on the Q2 variable
// Does not have Michel e tag because we need directional information to reconstruct Q2
case keMB:
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false);
break;
// Using Delta resonance for Enu reconstruction on the Q2 variable
// Does have Michel e tag, bool to true
case kDelta:
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true);
break;
}
// Default to return false
return false;
}
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx
index 0961a84..c31b6aa 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx
@@ -1,118 +1,116 @@
#include <iomanip>
#include "T2K_SignalDef.h"
#include "T2K_CC1pip_CH_XSec_1DWrec_nu.h"
// The constructor
T2K_CC1pip_CH_XSec_1DWrec_nu::T2K_CC1pip_CH_XSec_1DWrec_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
fName = "T2K_CC1pip_CH_XSec_1DWrec_nu";
fPlotTitles = "; W_{rec} (GeV/c); d#sigma/dW_{rec} (cm^{2}/(GeV/c^{2})/nucleon)";
EnuMin = 0.;
EnuMax = 100.;
fIsDiag = false;
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/W.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/W.root");
-
+ SetShapeCovar();
this->SetupDefaultHist();
this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1DWrec_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the first and last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
LOG(DEB) << dataCopy->GetNbinsX() << std::endl;
const int dataPoints = dataCopy->GetNbinsX()-2;
double *binEdges = new double[dataPoints+1];
// Want to skip the first bin here
for (int i = 0; i < dataPoints+1; i++) {
binEdges[i] = dataCopy->GetBinLowEdge(i+2);
}
for (int i = 0; i < dataPoints+1; i++) {
LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl;
}
fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataPoints, binEdges);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+2)*1E-38);
fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+2)*1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
//fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str());
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1DWrec_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
const int nBinsX = covarMatrix->GetXaxis()->GetNbins();
const int nBinsY = covarMatrix->GetYaxis()->GetNbins();
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
LOG(DEB) << nBinsX << std::endl;
LOG(DEB) << fDataHist->GetNbinsX() << std::endl;
- this->covar = new TMatrixDSym(nBinsX-3);
this->fFullCovar = new TMatrixDSym(nBinsX-3);
for (int i = 0; i < nBinsX-3; i++) {
for (int j = 0; j < nBinsY-3; j++) {
- (*this->covar)(i, j) = covarMatrix->GetBinContent(i+4, j+4); //adds syst+stat covariances
- LOG(DEB) << "covar(" << i << ", " << j << ") = " << (*this->covar)(i,j) << std::endl;
+ (*this->fFullCovar)(i, j) = covarMatrix->GetBinContent(i+4, j+4); //adds syst+stat covariances
+ LOG(DEB) << "fFullCovar(" << i << ", " << j << ") = " << (*this->fFullCovar)(i,j) << std::endl;
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
return;
};
void T2K_CC1pip_CH_XSec_1DWrec_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double Wrec = FitUtils::WrecCC1pip_T2K_MB(Pnu, Pmu, Ppip);
fXVar = Wrec;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1DWrec_nu::isSignal(FitEvent *event) {
//********************************************************************
// This sample includes the Michel e tag so do not have to cut into the pion phase space
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true);
}
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx
index b56e2b7..702a16d 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx
@@ -1,156 +1,154 @@
#include "T2K_CC1pip_CH_XSec_1Dpmu_nu.h"
#include <iomanip>
//********************************************************************
T2K_CC1pip_CH_XSec_1Dpmu_nu::T2K_CC1pip_CH_XSec_1Dpmu_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_CH_XSec_1Dpmu_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.SetXTitle("p_{#mu} (GeV/c)");
fSettings.SetYTitle("d#sigma/dp_{#mu} (cm^{2}/(GeV/c)/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
// CCQELike plot information
fSettings.SetTitle("T2K_CC1pip_CH_XSec_1Dpmu_nu");
fSettings.SetDataInput( GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Pmu.root" );
fSettings.SetCovarInput( GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Pmu.root" );
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataValues( fSettings.GetDataInput() );
SetCovarMatrix( fSettings.GetCovarInput() );
+ SetShapeCovar();
+
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dpmu_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
LOG(DEB) << "nbins = " << dataCopy->GetNbinsX() << std::endl;
double *binEdges = new double[dataCopy->GetNbinsX()-1];
for (int i = 0; i < dataCopy->GetNbinsX()-1; i++) {
binEdges[i] = dataCopy->GetBinLowEdge(i+1);
}
binEdges[dataCopy->GetNbinsX()-1] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX());
for (int i = 0; i < dataCopy->GetNbinsX()+5; i++) {
LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl;
}
fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-1, binEdges);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38);
fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str());
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dpmu_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
int nBinsX = covarMatrix->GetXaxis()->GetNbins();
int nBinsY = covarMatrix->GetYaxis()->GetNbins();
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
- this->covar = new TMatrixDSym(nBinsX-2);
this->fFullCovar = new TMatrixDSym(nBinsX-2);
// First two entries are BS
// Last entry is BS
for (int i = 1; i < nBinsX-1; i++) {
for (int j = 1; j < nBinsY-1; j++) {
- (*this->covar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances
(*this->fFullCovar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances
- LOG(DEB) << "covar(" << i-1 << ", " << j-1 << ") = " << (*this->covar)(i-1,j-1) << std::endl;
+ LOG(DEB) << "fFullCovar(" << i-1 << ", " << j-1 << ") = " << (*this->fFullCovar)(i-1,j-1) << std::endl;
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
-
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
return;
};
void T2K_CC1pip_CH_XSec_1Dpmu_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double pmu = FitUtils::p(Pmu);
fXVar = pmu;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1Dpmu_nu::isSignal(FitEvent *event) {
//********************************************************************
// Warning: The CH analysis has different signal definition to the H2O analysis!
//
// If Michel e- is used for pion PID we don't have directional info on pion; set the bool to true
// The bool is if we use Michel e- or not
// Also, for events binned in muon momentum/angle there's no cut on the pion kinematics
//
// Additionally, the 2D distribution uses 0.8 > cos th mu > 0 and no pion phase space reduction applied
// Also no muon momentum reduction applied
//
// This uses a slightly custom signal definition where a cut is only placed on the muon angle, not the momentum
if (!SignalDef::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 (cos_th_mu >= 0.2) return true;
return false;
};
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx
index 423d9c1..f787b76 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx
@@ -1,179 +1,177 @@
#include <iomanip>
#include "T2K_SignalDef.h"
#include "T2K_CC1pip_CH_XSec_1Dppi_nu.h"
//********************************************************************
T2K_CC1pip_CH_XSec_1Dppi_nu::T2K_CC1pip_CH_XSec_1Dppi_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_CH_XSec_1Dppi_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_CH_XSec_1Dppi_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("p_{#pi} (GeV/c)");
fSettings.SetYTitle("d#sigma/dW_{rec} (cm^{2}/(GeV/c)/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
if (fSettings.GetS("type").find("Michel") != std::string::npos) {
useMichel = true;
fName += "_Michel";
SetDataValues(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi.root");
SetCovarMatrix(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi.root");
} else {
useMichel = false;
- fName += "_kin";
+ // fName += "_kin";
SetDataValues(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi_noME.root");
SetCovarMatrix(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi_noME.root");
}
+
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dppi_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
LOG(DEB) << dataCopy->GetNbinsX() << std::endl;
double *binEdges = new double[dataCopy->GetNbinsX() - 1];
for (int i = 0; i < dataCopy->GetNbinsX() - 1; i++) {
binEdges[i] = dataCopy->GetBinLowEdge(i + 1);
}
binEdges[dataCopy->GetNbinsX() - 1] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX());
fDataHist = new TH1D((fName + "_data").c_str(), (fName + "_data" + fPlotTitles).c_str(), dataCopy->GetNbinsX() - 2, binEdges);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinContent(i + 1, dataCopy->GetBinContent(i + 1) * 1E-38);
fDataHist->SetBinError(i + 1, dataCopy->GetBinError(i + 1) * 1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i + 1) << " " << fDataHist->GetBinContent(i + 1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_MC" + fPlotTitles).c_str());
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dppi_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
int nBinsX = covarMatrix->GetXaxis()->GetNbins();
int nBinsY = covarMatrix->GetYaxis()->GetNbins();
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
- this->covar = new TMatrixDSym(nBinsX - 2);
- this->fFullCovar = new TMatrixDSym(nBinsX - 2);
+ this->fFullCovar = new TMatrixDSym(nBinsX - 3);
// First two entries are BS
// Last entry is BS
- for (int i = 1; i < nBinsX - 1; i++) {
- for (int j = 1; j < nBinsY - 1; j++) {
+ for (int i = 2; i < nBinsX-1; i++) {
+ for (int j = 2; j < nBinsY-1; j++) {
LOG(DEB) << "(" << i << ", " << j << ") = " << covarMatrix->GetBinContent(i + 1, j + 1) << std::endl;
- (*this->covar)(i - 1, j - 1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances
- (*this->fFullCovar)(i - 1, j - 1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances
+ (*this->fFullCovar)(i - 2, j - 2) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
-
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
return;
};
void T2K_CC1pip_CH_XSec_1Dppi_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double ppip = FitUtils::p(Ppip);
fXVar = ppip;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1Dppi_nu::isSignal(FitEvent *event) {
//********************************************************************
// This distribution uses a somewhat different signal definition so might as well implement it separately here
// If we use Michel tag sample we don't cut into the pion phase space, only the muon phase space
// The last bool refers to if we have Michel e or not
if (useMichel) {
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true);
} else { // Custom signal definition if we aren't using Michel tag; cut on muon and cut only on pion angle
// does the event pass the muon cut?
bool muonPass = SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true);
// If the event doesn't pass the muon cut return false
if (!muonPass) {
return false;
}
// does the event pass the pion angle cut?
// we already know there's just one muon in the event if it passes muonPass so don't need to make an event loop rejection
// Need the neutrino four-vector to get the angle between pion and neutrino
TLorentzVector Pnu = event->PartInfo(0)->fP;
TLorentzVector Ppip;
for (unsigned int j = 2; j < event->Npart(); j++) {
if (!((event->PartInfo(j))->fIsAlive) && (event->PartInfo(j))->fNEUTStatusCode != 0) continue; //move on if NOT ALIVE and NOT NORMAL
int PID = (event->PartInfo(j))->fPID;
if (PID == 211) {
Ppip = event->PartInfo(j)->fP; // Once the pion is found we can break
break;
}
}
double cos_th_pi = cos(FitUtils::th(Pnu, Ppip));
// Now check the angle of the pion
if (cos_th_pi <= 0.2) {
return false;
} else {
return true;
}
}
// Unnecessary default to false
return false;
}
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx
index 28f6e7b..6a34455 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx
@@ -1,113 +1,109 @@
#include <iomanip>
#include "T2K_SignalDef.h"
#include "T2K_CC1pip_CH_XSec_1Dq3_nu.h"
// The constructor
T2K_CC1pip_CH_XSec_1Dq3_nu::T2K_CC1pip_CH_XSec_1Dq3_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
fName = "T2K_CC1pip_CH_XSec_1Dq3_nu";
fPlotTitles = "; q_{3} (GeV/c); d#sigma/dq_{3} (cm^{2}/(GeV/c)/nucleon)";
EnuMin = 0.;
EnuMax = 100.;
fIsDiag = false;
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q3.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q3.root");
-
+ SetShapeCovar();
this->SetupDefaultHist();
this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dq3_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
- double *binEdges = new double[dataCopy->GetNbinsX()-1];
+ double *binEdges = new double[dataCopy->GetNbinsX()-2];
LOG(DEB) << dataCopy->GetNbinsX() << std::endl;
- for (int i = 1; i < dataCopy->GetNbinsX(); i++) {
+ for (int i = 1; i < dataCopy->GetNbinsX()-1; i++) {
binEdges[i-1] = dataCopy->GetBinLowEdge(i+1);
LOG(DEB) << i-1 << " " << binEdges[i-1] << " from binLowEdge " << i+1 << std::endl;
}
fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-2, binEdges);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+2)*1E-38);
fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+2)*1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str());
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dq3_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
int nBinsX = covarMatrix->GetXaxis()->GetNbins();
int nBinsY = covarMatrix->GetYaxis()->GetNbins();
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
- this->covar = new TMatrixDSym(nBinsX-2);
- this->fFullCovar = new TMatrixDSym(nBinsX-2);
+ this->fFullCovar = new TMatrixDSym(nBinsX-3);
// First two entries are BS
// Last entry is BS
for (int i = 2; i < nBinsX-1; i++) {
for (int j = 2; j < nBinsY-1; j++) {
- (*this->covar)(i-2, j-2) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances
(*this->fFullCovar)(i-2, j-2) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances
- LOG(DEB) << "covar(" << i-2 << ", " << j-2 << ") = " << (*this->covar)(i-2,j-2) << std::endl;
+ LOG(DEB) << "fFullCovar(" << i-2 << ", " << j-2 << ") = " << (*this->fFullCovar)(i-2,j-2) << std::endl;
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
-
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
return;
};
void T2K_CC1pip_CH_XSec_1Dq3_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double q3 = FitUtils::q3_CC1pip_T2K(Pnu, Pmu, Ppip);
fXVar = q3;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1Dq3_nu::isSignal(FitEvent *event) {
//********************************************************************
// Has a Michel e sample in so no phase space cut on pion required
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true);
}
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx
index b191482..da6cc55 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx
@@ -1,113 +1,109 @@
#include <iomanip>
#include "T2K_SignalDef.h"
#include "T2K_CC1pip_CH_XSec_1Dthmupi_nu.h"
// The constructor
T2K_CC1pip_CH_XSec_1Dthmupi_nu::T2K_CC1pip_CH_XSec_1Dthmupi_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
fName = "T2K_CC1pip_CH_XSec_1Dthmupi_nu";
fPlotTitles = "; #theta_{#pi,#mu} (radians); d#sigma/d#theta_{#pi} (cm^{2}/nucleon)";
EnuMin = 0.;
EnuMax = 100.;
fIsDiag = false;
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapimu.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapimu.root");
-
+ SetShapeCovar();
this->SetupDefaultHist();
this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dthmupi_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the first and last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
LOG(DEB) << "dataCopy->GetNbinsX() = " << dataCopy->GetNbinsX() << std::endl;
double *binEdges = new double[dataCopy->GetNbinsX()];
for (int i = 0; i < dataCopy->GetNbinsX(); i++) {
binEdges[i] = dataCopy->GetBinLowEdge(i+1);
}
binEdges[dataCopy->GetNbinsX()] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX()+1);
for (int i = 0; i < dataCopy->GetNbinsX()+5; i++) {
LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl;
}
fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX(), binEdges);
for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) {
fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38);
fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dthmupi_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
int nBinsX = covarMatrix->GetXaxis()->GetNbins();
int nBinsY = covarMatrix->GetYaxis()->GetNbins();
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
- this->covar = new TMatrixDSym(nBinsX-1);
this->fFullCovar = new TMatrixDSym(nBinsX-1);
for (int i = 1; i < nBinsX; i++) {
for (int j = 1; j < nBinsY; j++) {
- (*this->covar)(i-1, j-1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances
(*this->fFullCovar)(i-1, j-1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances
- LOG(DEB) << "covar(" << i-1 << ", " << j-1 << ") = " << (*this->covar)(i-1,j-1) << std::endl;
+ LOG(DEB) << "fFullCovar(" << i-1 << ", " << j-1 << ") = " << (*this->fFullCovar)(i-1,j-1) << std::endl;
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
-
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
dataFile->Close();
};
void T2K_CC1pip_CH_XSec_1Dthmupi_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double thmupi = FitUtils::th(Pmu, Ppip);
fXVar = thmupi;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1Dthmupi_nu::isSignal(FitEvent *event) {
//********************************************************************
// This sample requires directional information on the pion so can't use Michel tag sample
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false);
}
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx
index 4324fe6..b8be6c5 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx
@@ -1,114 +1,110 @@
#include <iomanip>
#include "T2K_SignalDef.h"
#include "T2K_CC1pip_CH_XSec_1Dthpi_nu.h"
// The constructor
T2K_CC1pip_CH_XSec_1Dthpi_nu::T2K_CC1pip_CH_XSec_1Dthpi_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
fName = "T2K_CC1pip_CH_XSec_1Dthpi_nu";
fPlotTitles = "; #theta_{#pi} (radians); d#sigma/d#theta_{#pi} (cm^{2}/nucleon)";
EnuMin = 0.;
EnuMax = 100.;
fIsDiag = false;
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapi.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapi.root");
-
+ SetShapeCovar();
this->SetupDefaultHist();
this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dthpi_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the first and last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
LOG(DEB) << "dataCopy->GetNbinsX() = " << dataCopy->GetNbinsX() << std::endl;
double *binEdges = new double[dataCopy->GetNbinsX()-4];
for (int i = 0; i < dataCopy->GetNbinsX()-4; i++) {
binEdges[i] = dataCopy->GetBinLowEdge(i+1);
}
binEdges[dataCopy->GetNbinsX()-4] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX()-3);
for (int i = 0; i < dataCopy->GetNbinsX(); i++) {
LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl;
}
fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-4, binEdges);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38);
fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dthpi_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
int nBinsX = covarMatrix->GetXaxis()->GetNbins();
int nBinsY = covarMatrix->GetYaxis()->GetNbins();
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
- this->covar = new TMatrixDSym(nBinsX-5);
this->fFullCovar = new TMatrixDSym(nBinsX-5);
for (int i = 2; i < nBinsX-3; i++) {
for (int j = 2; j < nBinsY-3; j++) {
- (*this->covar)(i-2, j-2) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances
(*this->fFullCovar)(i-2, j-2) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances
- LOG(DEB) << "covar(" << i-2 << ", " << j-2 << ") = " << (*this->covar)(i-2,j-2) << std::endl;
+ LOG(DEB) << "fFullCovar(" << i-2 << ", " << j-2 << ") = " << (*this->fFullCovar)(i-2,j-2) << std::endl;
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
-
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
dataFile->Close();
};
void T2K_CC1pip_CH_XSec_1Dthpi_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double thpi = FitUtils::th(Pnu, Ppip);
fXVar = thpi;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1Dthpi_nu::isSignal(FitEvent *event) {
//********************************************************************
// This sample uses directional info on the pion so Michel e tag sample can not be included
// i.e. we need reduce the pion variable phase space
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false);
}
diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx
index e3a1cbb..1426e80 100644
--- a/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx
+++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx
@@ -1,119 +1,115 @@
#include <iomanip>
#include "T2K_SignalDef.h"
#include "T2K_CC1pip_CH_XSec_1Dthq3pi_nu.h"
// The constructor
T2K_CC1pip_CH_XSec_1Dthq3pi_nu::T2K_CC1pip_CH_XSec_1Dthq3pi_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
fName = "T2K_CC1pip_CH_XSec_1Dthq3pi_nu";
fPlotTitles = "; #theta_{q_{3},#pi} (radians); d#sigma/d#theta_{q_{3},#pi} (cm^{2}/(radian)/nucleon)";
EnuMin = 0.;
EnuMax = 100.;
fIsDiag = false;
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/ThetaQ3Pi.root");
this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/ThetaQ3Pi.root");
-
+ SetShapeCovar();
this->SetupDefaultHist();
this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dthq3pi_nu::SetDataValues(std::string fileLocation) {
LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
// Don't want the last bin of dataCopy
TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone();
double *binEdges = new double[dataCopy->GetNbinsX()-1];
LOG(DEB) << dataCopy->GetNbinsX() << std::endl;
for (int i = 1; i < dataCopy->GetNbinsX()+1; i++) {
binEdges[i-1] = dataCopy->GetBinLowEdge(i);
LOG(DEB) << i-1 << " " << binEdges[i-1] << std::endl;
}
for (int i = 0; i < dataCopy->GetNbinsX()+5; i++) {
LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl;
}
fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-1, binEdges);
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38);
fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38);
LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl;
}
fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile
fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str());
dataFile->Close();
};
// Override this for now
// Should really have Measurement1D do this properly though
void T2K_CC1pip_CH_XSec_1Dthq3pi_nu::SetCovarMatrix(std::string fileLocation) {
LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl;
TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file!
TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone();
int nBinsX = covarMatrix->GetXaxis()->GetNbins();
int nBinsY = covarMatrix->GetYaxis()->GetNbins();
if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl;
// First bin is underflow, last bin is overflow
- this->covar = new TMatrixDSym(nBinsX-2);
this->fFullCovar = new TMatrixDSym(nBinsX-2);
// First two entries are BS
// Last entry is BS
for (int i = 1; i < nBinsX-1; i++) {
for (int j = 1; j < nBinsY-1; j++) {
- (*this->covar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances
(*this->fFullCovar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances
- LOG(DEB) << "covar(" << i-1 << ", " << j-1 << ") = " << (*this->covar)(i-1,j-1) << std::endl;
+ LOG(DEB) << "fFullCovar(" << i-1 << ", " << j-1 << ") = " << (*this->fFullCovar)(i-1,j-1) << std::endl;
}
} //should now have set covariance, I hope
- TDecompChol tempMat = TDecompChol(*this->covar);
- this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), "");
- // *this->covar *= 1E-38*1E-38;
-
+ this->fDecomp = StatUtils::GetDecomp(this->fFullCovar);
+ this->covar = StatUtils::GetInvert(this->fFullCovar);
return;
};
void T2K_CC1pip_CH_XSec_1Dthq3pi_nu::FillEventVariables(FitEvent *event) {
if (event->NumFSParticle(13) == 0 ||
event->NumFSParticle(211) == 0)
return;
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double th_q3_pi = FitUtils::thq3pi_CC1pip_T2K(Pnu, Pmu, Ppip);
fXVar = th_q3_pi;
return;
};
//********************************************************************
bool T2K_CC1pip_CH_XSec_1Dthq3pi_nu::isSignal(FitEvent *event) {
//********************************************************************
// This sample requires pion directional information so can not include Michel tag sample
// i.e. will need to cut the pion phase space
return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false);
}
diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx
index 6e04801..45c4bf1 100644
--- a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx
+++ b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx
@@ -1,74 +1,75 @@
#include "T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.h"
// The derived neutrino energy assuming a Delta resonance and a nucleon at rest; so only requires the outgoing muon to derive (and information on the angle between the muon and the neutrino)
// Please beware that this is NOT THE "TRUE" NEUTRINO ENERGY; IT'S A PROXY FOR THE TRUE NEUTRINO ENERGY
// Also, this is flux-integrated cross-section, not flux averaged
//********************************************************************
T2K_CC1pip_H2O_XSec_1DEnuDelta_nu::T2K_CC1pip_H2O_XSec_1DEnuDelta_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_H2O_XSec_1DEnuDelta_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1DEnuDelta_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("E_{#nu} (GeV)");
fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_Delta/hResultTot");
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_Delta/TotalCovariance");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents);
// Plot Setup -------------------------------------------------------
SetDataFromRootFile( fSettings.GetDataInput() );
SetCovarFromRootFile( fSettings.GetCovarInput() );
ScaleCovar(1E76);
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Find the muon whows kinematics we use to derive the "neutrino energy"
void T2K_CC1pip_H2O_XSec_1DEnuDelta_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
// Need to make sure there's a muon
if (event->NumFSParticle(13) == 0) return;
// Get the incoming neutrino
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
// Get the muon
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double Enu = FitUtils::EnuCC1piprecDelta(Pnu, Pmu);
fXVar = Enu;
return;
};
//********************************************************************
// Beware: The H2O analysis has different signal definition to the CH analysis!
bool T2K_CC1pip_H2O_XSec_1DEnuDelta_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax);
}
diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx
index 6779ad4..1f1e902 100644
--- a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx
+++ b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx
@@ -1,80 +1,80 @@
#include "T2K_CC1pip_H2O_XSec_1DEnuMB_nu.h"
// The derived neutrino energy using the "MiniBooNE formula" (see paper)
// Essentially this is a proxy for the neutrino energy, using the outgoing pion and muon to get the reconstructed neutrino energy, assuming the struck nucleon was at rest
// Again, THIS IS NOT A "TRUE" NEUTRINO ENERGY!
//********************************************************************
T2K_CC1pip_H2O_XSec_1DEnuMB_nu::T2K_CC1pip_H2O_XSec_1DEnuMB_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_H2O_XSec_1DEnuMB_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1DEnuMB_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("E_{#nu} (GeV)");
fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_MB/hResultTot");
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_MB/TotalCovariance");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents);
// Plot Setup -------------------------------------------------------
SetDataFromRootFile( fSettings.GetDataInput() );
SetCovarFromRootFile( fSettings.GetCovarInput() );
ScaleCovar(1E76);
-
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Find the derived neutrino energy using the "MiniBooNE formula" (see paper)
// Essentially uses the pion and muon kinematics to derive a pseudo-neutrino energy, assuming the struck nucleon is at rest
// We also need the incoming neutrino to get the muon/neutrino and pion/neutrino angles
void T2K_CC1pip_H2O_XSec_1DEnuMB_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
// Need to make sure there's a muon
if (event->NumFSParticle(13) == 0) return;
// Need to make sure there's a pion
if (event->NumFSParticle(211) == 0) return;
// Get the incoming neutrino
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
// Get the muon
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
// Get the pion
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
double Enu = FitUtils::EnuCC1piprec(Pnu, Pmu, Ppip);
fXVar = Enu;
return;
};
//********************************************************************
// Beware: The H2O analysis has different signal definition to the CH analysis!
bool T2K_CC1pip_H2O_XSec_1DEnuMB_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax);
}
diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx
index a92a430..8abe3e3 100644
--- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx
+++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx
@@ -1,73 +1,74 @@
#include "T2K_CC1pip_H2O_XSec_1Dcosmu_nu.h"
// The cos of the angle between the neutrino and the muon
//********************************************************************
T2K_CC1pip_H2O_XSec_1Dcosmu_nu::T2K_CC1pip_H2O_XSec_1Dcosmu_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_H2O_XSec_1Dcosmu_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dcosmu_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("cos#theta_{#pi,#mu}");
fSettings.SetYTitle("d#sigma/dcos#theta_{#pi#mu} (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuCos/hResultTot");
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuCos/TotalCovariance");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromRootFile( fSettings.GetDataInput() );
SetCovarFromRootFile( fSettings.GetCovarInput() );
ScaleCovar(1E76);
+ SetShapeCovar();
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Find the cos theta of the angle between muon and neutrino
void T2K_CC1pip_H2O_XSec_1Dcosmu_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
// Need to make sure there's a muon
if (event->NumFSParticle(13) == 0) return;
// Get the incoming neutrino
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
// Get the muon
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
// Do the cos of the angle between the two
double cos_th = cos(FitUtils::th(Pnu, Pmu));
fXVar = cos_th;
return;
};
//********************************************************************
// Beware: The H2O analysis has different signal definition to the CH analysis!
bool T2K_CC1pip_H2O_XSec_1Dcosmu_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax);
}
diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx
index a56f805..1a50ac3 100644
--- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx
+++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx
@@ -1,71 +1,72 @@
#include "T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.h"
//********************************************************************
T2K_CC1pip_H2O_XSec_1Dcosmupi_nu::T2K_CC1pip_H2O_XSec_1Dcosmupi_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_H2O_XSec_1Dcosmupi_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dcosmupi_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("cos#theta_{#pi,#mu}");
fSettings.SetYTitle("d#sigma/dcos#theta_{#pi#mu} (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuPiCos/hResultTot");
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuPiCos/TotalCovariance");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = GetEventHistogram()->Integral("width")*1E-38/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromRootFile( fSettings.GetDataInput() );
SetCovarFromRootFile( fSettings.GetCovarInput() );
ScaleCovar(1E76);
-
+ SetShapeCovar();
+
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Find the cos theta of the angle between muon and pion
void T2K_CC1pip_H2O_XSec_1Dcosmupi_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
// Need to make sure there's a muon
if (event->NumFSParticle(13) == 0) return;
// Need to make sure there's a pion
if (event->NumFSParticle(211) == 0) return;
// Get the muon
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
// Get the pion
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
double cos_th = cos(FitUtils::th(Pmu, Ppip));
fXVar = cos_th;
return;
};
//********************************************************************
// Beware: The H2O analysis has different signal definition to the CH analysis!
bool T2K_CC1pip_H2O_XSec_1Dcosmupi_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax);
}
diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx
index 3ba843d..fd022ff 100644
--- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx
+++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx
@@ -1,68 +1,69 @@
#include "T2K_CC1pip_H2O_XSec_1Dcospi_nu.h"
//********************************************************************
T2K_CC1pip_H2O_XSec_1Dcospi_nu::T2K_CC1pip_H2O_XSec_1Dcospi_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_H2O_XSec_1Dcospi_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dcospi_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("cos#theta_{#pi}");
fSettings.SetYTitle("d#sigma/dcos#theta_{#pi} (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionCos/hResultTot");
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionCos/TotalCovariance");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromRootFile( fSettings.GetDataInput() );
SetCovarFromRootFile( fSettings.GetCovarInput() );
ScaleCovar(1E76);
-
+ SetShapeCovar();
+
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Find the cos theta of the angle between pion and neutrino
void T2K_CC1pip_H2O_XSec_1Dcospi_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
// Need to make sure there's a pion
if (event->NumFSParticle(211) == 0) return;
// Get the incoming neutrino
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
// Get the pion
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
double cos_th = cos(FitUtils::th(Pnu, Ppip));
fXVar = cos_th;
return;
};
//********************************************************************
// Beware: The H2O analysis has different signal definition to the CH analysis!
bool T2K_CC1pip_H2O_XSec_1Dcospi_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax);
}
diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx
index 5f482f0..9d6d983 100644
--- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx
+++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx
@@ -1,70 +1,71 @@
#include "T2K_CC1pip_H2O_XSec_1Dpmu_nu.h"
// The muon momentum
//********************************************************************
T2K_CC1pip_H2O_XSec_1Dpmu_nu::T2K_CC1pip_H2O_XSec_1Dpmu_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_H2O_XSec_1Dpmu_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dpmu_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("E_{#nu} (GeV)");
fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuMom/hResultTot");
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuMom/TotalCovariance");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromRootFile( fSettings.GetDataInput() );
SetCovarFromRootFile( fSettings.GetCovarInput() );
ScaleCovar(1E76);
-
+ SetShapeCovar();
+
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Find the momentum of the muon
void T2K_CC1pip_H2O_XSec_1Dpmu_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
// Need to make sure there's a muon
if (event->NumFSParticle(13) == 0) return;
// Get the muon
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
double p_mu = FitUtils::p(Pmu);
fXVar = p_mu;
return;
};
//********************************************************************
// Beware: The H2O analysis has different signal definition to the CH analysis!
bool T2K_CC1pip_H2O_XSec_1Dpmu_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax);
}
diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx
index 594c1be..7b33785 100644
--- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx
+++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx
@@ -1,69 +1,70 @@
#include "T2K_CC1pip_H2O_XSec_1Dppi_nu.h"
// The momentum of the (positive) pion
//********************************************************************
T2K_CC1pip_H2O_XSec_1Dppi_nu::T2K_CC1pip_H2O_XSec_1Dppi_nu(nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip = "T2K_CC1pip_H2O_XSec_1Dppi_nu sample. \n" \
"Target: CH \n" \
"Flux: T2k Forward Horn Current nue + nuebar \n" \
"Signal: Any event with 1 electron, any nucleons, and no other FS particles \n";
// Setup common settings
fSettings = LoadSampleSettings(samplekey);
fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dppi_nu");
fSettings.SetDescription(descrip);
fSettings.SetXTitle("p_{#pi^{+}} (GeV/c)");
fSettings.SetYTitle("d#sigma/dp_{#pi^{+}} (cm^{2}/(GeV/c)/nucleon)");
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL");
fSettings.SetEnuRange(0.0, 100.0);
fSettings.DefineAllowedTargets("C,H");
fSettings.DefineAllowedSpecies("numu");
fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionMom/hResultTot");
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionMom/TotalCovariance");
FinaliseSampleSettings();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width");
// Plot Setup -------------------------------------------------------
SetDataFromRootFile( fSettings.GetDataInput() );
SetCovarFromRootFile( fSettings.GetCovarInput() );
ScaleCovar(1E76);
-
+ SetShapeCovar();
+
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
// Find the momentum of the (positively charged) pion
void T2K_CC1pip_H2O_XSec_1Dppi_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
// Need to make sure there's a muon
if (event->NumFSParticle(211) == 0) return;
// Get the pion
TLorentzVector Ppip = event->GetHMFSParticle(211)->fP;
double p_pi = FitUtils::p(Ppip);
fXVar = p_pi;
return;
};
//********************************************************************
// Beware: The H2O analysis has different signal definition to the CH analysis!
bool T2K_CC1pip_H2O_XSec_1Dppi_nu::isSignal(FitEvent *event) {
//********************************************************************
return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax);
}
diff --git a/src/Utils/StatUtils.cxx b/src/Utils/StatUtils.cxx
index 276054c..24a458a 100644
--- a/src/Utils/StatUtils.cxx
+++ b/src/Utils/StatUtils.cxx
@@ -1,1239 +1,1300 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "TH1D.h"
#include "StatUtils.h"
//*******************************************************************
Double_t StatUtils::GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask) {
//*******************************************************************
Double_t Chi2 = 0.0;
TH1D* calc_data = (TH1D*)data->Clone();
TH1D* calc_mc = (TH1D*)mc->Clone();
// Add MC Error to data if required
if (FitPar::Config().GetParB("statutils.addmcerror")) {
for (int i = 0; i < calc_data->GetNbinsX(); i++) {
double dterr = calc_data->GetBinError(i + 1);
double mcerr = calc_mc->GetBinError(i + 1);
if (dterr > 0.0) {
calc_data->SetBinError(i + 1, sqrt(dterr * dterr + mcerr * mcerr));
}
}
}
// Apply masking if required
if (mask) {
calc_data = ApplyHistogramMasking(data, mask);
calc_mc = ApplyHistogramMasking(mc, mask);
}
// Iterate over bins in X
for (int i = 0; i < calc_data->GetNbinsX(); i++) {
// Ignore bins with zero data or zero bin error
if (calc_data->GetBinError(i + 1) <= 0.0 ||
calc_data->GetBinContent(i + 1) == 0.0) continue;
// Take mc data difference
double diff = calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1);
double err = calc_data->GetBinError(i + 1);
Chi2 += (diff * diff) / (err * err);
}
// cleanup
delete calc_data;
delete calc_mc;
return Chi2;
};
//*******************************************************************
Double_t StatUtils::GetChi2FromDiag(TH2D* data, TH2D* mc,
TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map) map = GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate 1D chi2 from 1D Plots
Double_t Chi2 = StatUtils:: GetChi2FromDiag(data_1D, mc_1D, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return Chi2;
};
//*******************************************************************
Double_t StatUtils::GetChi2FromCov(TH1D* data, TH1D* mc,
TMatrixDSym* invcov, TH1I* mask,
double data_scale, double covar_scale) {
//*******************************************************************
Double_t Chi2 = 0.0;
TMatrixDSym* calc_cov = (TMatrixDSym*) invcov->Clone();
TH1D* calc_data = (TH1D*) data->Clone();
TH1D* calc_mc = (TH1D*) mc->Clone();
calc_data->Scale(data_scale);
calc_mc ->Scale(data_scale);
(*calc_cov) *= covar_scale;
// If a mask if applied we need to apply it before the matrix is inverted
if (mask) {
calc_cov = ApplyInvertedMatrixMasking(invcov, mask);
calc_data = ApplyHistogramMasking(data, mask);
calc_mc = ApplyHistogramMasking(mc, mask);
}
// Add MC Error to data if required
if (FitPar::Config().GetParB("statutils.addmcerror")) {
// Make temp cov
TMatrixDSym* newcov = StatUtils::GetInvert(calc_cov);
// Add MC err to diag
for (int i = 0; i < calc_data->GetNbinsX(); i++) {
double mcerr = calc_mc->GetBinError(i + 1) * sqrt(covar_scale);
double oldval = (*newcov)(i, i);
(*newcov)(i, i) = oldval + mcerr * mcerr;
}
// Reset the calc_cov to new invert
delete calc_cov;
calc_cov = GetInvert(newcov);
// Delete the tempcov
delete newcov;
}
// iterate over bins in X (i,j)
for (int i = 0; i < calc_data->GetNbinsX(); i++) {
for (int j = 0; j < calc_data->GetNbinsX(); j++) {
if (calc_data->GetBinContent(i + 1) != 0 || calc_mc->GetBinContent(i + 1) != 0) {
LOG(DEB) << "i j = " << i << " " << j << std::endl;
LOG(DEB) << "Calc_data mc i = " << calc_data->GetBinContent(i + 1)
<< " " << calc_mc->GetBinContent(i + 1)
<< " Dif = "
<< ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) )
<< std::endl;
LOG(DEB) << "Calc_data mc i = " << calc_data->GetBinContent(j + 1)
<< " " << calc_mc->GetBinContent(j + 1)
<< " Dif = "
<< ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1) )
<< std::endl;
LOG(DEB) << "Covar = " << (*calc_cov)(i, j) << std::endl;
LOG(DEB) << "Cont chi2 = " \
<< ( ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) \
* (*calc_cov)(i, j) \
* ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1)))
<< " " << Chi2 << std::endl;
Chi2 += ( ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) \
* (*calc_cov)(i, j) \
* ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1) ) );
} else {
LOG(DEB) << "Error on bin (i,j) = (" << i << "," << j << ")" << std::endl;
LOG(DEB) << "data->GetBinContent(i+1) = " << calc_data->GetBinContent(i + 1) << std::endl;
LOG(DEB) << "mc->GetBinContent(i+1) = " << calc_mc->GetBinContent(i + 1) << std::endl;
LOG(DEB) << "Adding zero to chi2 instead of dying horrifically " << std::endl;
Chi2 += 0.;
}
}
}
// Cleanup
delete calc_cov;
delete calc_data;
delete calc_mc;
return Chi2;
}
//*******************************************************************
Double_t StatUtils::GetChi2FromCov( TH2D* data, TH2D* mc,
TMatrixDSym* invcov, TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map) {
map = StatUtils::GenerateMap(data);
}
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate 1D chi2 from 1D Plots
Double_t Chi2 = StatUtils::GetChi2FromCov(data_1D, mc_1D, invcov, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return Chi2;
}
//*******************************************************************
Double_t StatUtils::GetChi2FromSVD( TH1D* data, TH1D* mc,
TMatrixDSym* cov, TH1I* mask) {
//*******************************************************************
Double_t Chi2 = 0.0;
TMatrixDSym* calc_cov = (TMatrixDSym*) cov->Clone();
TH1D* calc_data = (TH1D*) data->Clone();
TH1D* calc_mc = (TH1D*) mc->Clone();
// If a mask if applied we need to apply it before the matrix is inverted
if (mask) {
calc_cov = StatUtils::ApplyMatrixMasking(cov, mask);
calc_data = StatUtils::ApplyHistogramMasking(data, mask);
calc_mc = StatUtils::ApplyHistogramMasking(mc, mask);
}
// Decompose matrix
TDecompSVD LU = TDecompSVD((*calc_cov));
LU.Decompose();
TMatrixDSym* cov_U = new TMatrixDSym(calc_data->GetNbinsX(), LU .GetU().GetMatrixArray(), "");
TVectorD* cov_S = new TVectorD( LU.GetSig() );
// Apply basis rotation before adding up chi2
Double_t rotated_difference = 0.0;
for (int i = 0; i < calc_data->GetNbinsX(); i++) {
rotated_difference = 0.0;
// Rotate basis of Data - MC
for (int j = 0; j < calc_data->GetNbinsY(); j++)
rotated_difference += ( calc_data->GetBinContent(j + 1) - calc_mc ->GetBinContent(j + 1) ) * (*cov_U)(j, i) ;
// Divide by rotated error cov_S
Chi2 += rotated_difference * rotated_difference * 1E76 / (*cov_S)(i);
}
// Cleanup
delete calc_cov;
delete calc_data;
delete calc_mc;
delete cov_U;
delete cov_S;
return Chi2;
}
//*******************************************************************
Double_t StatUtils::GetChi2FromSVD( TH2D* data, TH2D* mc,
TMatrixDSym* cov, TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map)
map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate from 1D
Double_t Chi2 = StatUtils::GetChi2FromSVD(data_1D, mc_1D, cov, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return Chi2;
}
//*******************************************************************
double StatUtils::GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask) {
//*******************************************************************
// If just an event rate, for chi2 just use Poission Likelihood to calculate the chi2 component
double chi2 = 0.0;
TH1D* calc_data = (TH1D*)data->Clone();
TH1D* calc_mc = (TH1D*)mc->Clone();
// Apply masking if required
if (mask) {
calc_data = ApplyHistogramMasking(data, mask);
calc_mc = ApplyHistogramMasking(mc, mask);
}
// Iterate over bins in X
for (int i = 0; i < calc_data->GetNbinsX(); i++) {
double dt = calc_data->GetBinContent(i + 1);
double mc = calc_mc->GetBinContent(i + 1);
if (mc <= 0) continue;
if (dt <= 0) {
// Only add difference
chi2 += 2 * (mc - dt);
} else {
// Do the chi2 for Poisson distributions
chi2 += 2 * (mc - dt + (dt * log(dt / mc)));
}
/*
LOG(REC)<<"Evt Chi2 cont = "<<i<<" "
<<mc<<" "<<dt<<" "
<<2 * (mc - dt + (dt+0.) * log((dt+0.) / (mc+0.)))
<<" "<<Chi2<<std::endl;
*/
}
// cleanup
delete calc_data;
delete calc_mc;
return chi2;
}
//*******************************************************************
Double_t StatUtils::GetChi2FromEventRate(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map)
map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate from 1D
Double_t Chi2 = StatUtils::GetChi2FromEventRate(data_1D, mc_1D, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return Chi2;
}
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromDiag(TH1D* data, TH1D* mc, TH1I* mask) {
//*******************************************************************
// Currently just a placeholder!
(void) data;
(void) mc;
(void) mask;
return 0.0;
};
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromDiag(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map)
map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate from 1D
Double_t MLE = StatUtils::GetLikelihoodFromDiag(data_1D, mc_1D, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return MLE;
};
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask) {
//*******************************************************************
// Currently just a placeholder !
(void) data;
(void) mc;
(void) invcov;
(void) mask;
return 0.0;
};
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map)
map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate from 1D
Double_t MLE = StatUtils::GetLikelihoodFromCov(data_1D, mc_1D, invcov, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return MLE;
};
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask) {
//*******************************************************************
// Currently just a placeholder!
(void) data;
(void) mc;
(void) cov;
(void) mask;
return 0.0;
};
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map)
map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate from 1D
Double_t MLE = StatUtils::GetLikelihoodFromSVD(data_1D, mc_1D, cov, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return MLE;
};
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromEventRate(TH1D* data, TH1D* mc, TH1I* mask) {
//*******************************************************************
// Currently just a placeholder!
(void) data;
(void) mc;
(void) mask;
return 0.0;
};
//*******************************************************************
Double_t StatUtils::GetLikelihoodFromEventRate(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) {
//*******************************************************************
// Generate a simple map
if (!map)
map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
TH1D* mc_1D = MapToTH1D(mc, map);
TH1I* mask_1D = MapToMask(mask, map);
// Calculate from 1D
Double_t MLE = StatUtils::GetChi2FromEventRate(data_1D, mc_1D, mask_1D);
// CleanUp
delete data_1D;
delete mc_1D;
delete mask_1D;
return MLE;
};
//*******************************************************************
Int_t StatUtils::GetNDOF(TH1D* hist, TH1I* mask) {
//*******************************************************************
TH1D* calc_hist = (TH1D*)hist->Clone();
// If a mask is provided we need to apply it before getting NDOF
if (mask) {
calc_hist = StatUtils::ApplyHistogramMasking(hist, mask);
}
// NDOF is defined as total number of bins with non-zero errors
Int_t NDOF = 0;
for (int i = 0; i < calc_hist->GetNbinsX(); i++) {
if (calc_hist->GetBinError(i + 1) > 0.0) NDOF++;
}
delete calc_hist;
return NDOF;
};
//*******************************************************************
Int_t StatUtils::GetNDOF(TH2D* hist, TH2I* map, TH2I* mask) {
//*******************************************************************
Int_t NDOF = 0;
if (!map) map = StatUtils::GenerateMap(hist);
for (int i = 0; i < hist->GetNbinsX(); i++) {
for (int j = 0; j < hist->GetNbinsY(); j++) {
if (mask->GetBinContent(i + 1, j + 1)) continue;
if (map->GetBinContent(i + 1, j + 1) <= 0) continue;
NDOF++;
}
}
return NDOF;
};
//*******************************************************************
TH1D* StatUtils::ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag, TH1I* mask) {
//*******************************************************************
TH1D* calc_hist = (TH1D*) hist->Clone( (std::string(hist->GetName()) + "_THROW" ).c_str() );
TMatrixDSym* calc_cov = (TMatrixDSym*) cov->Clone();
Double_t correl_val = 0.0;
// If a mask if applied we need to apply it before the matrix is decomposed
if (mask) {
calc_cov = ApplyMatrixMasking(cov, mask);
calc_hist = ApplyHistogramMasking(calc_hist, mask);
}
// If a covariance is provided we need a preset random vector and a decomp
std::vector<Double_t> rand_val;
TMatrixDSym* decomp_cov;
if (cov) {
for (int i = 0; i < hist->GetNbinsX(); i++) {
rand_val.push_back(gRandom->Gaus(0.0, 1.0));
}
// Decomp the matrix
decomp_cov = StatUtils::GetDecomp(calc_cov);
}
// iterate over bins
for (int i = 0; i < hist->GetNbinsX(); i++) {
// By Default the errors on the histogram are thrown uncorrelated to the other errors
// if (throwdiag) {
// calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + \
// gRandom->Gaus(0.0, 1.0) * calc_hist->GetBinError(i + 1)) );
// }
// If a covariance is provided that is also thrown
if (cov) {
correl_val = 0.0;
for (int j = 0; j < hist->GetNbinsX(); j++) {
correl_val += rand_val[j] * (*decomp_cov)(j, i) ;
}
calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + correl_val * 1E-38));
}
}
delete calc_cov;
delete decomp_cov;
// return this new thrown data
return calc_hist;
};
//*******************************************************************
TH2D* StatUtils::ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map, bool throwdiag, TH2I* mask) {
//*******************************************************************
// PLACEHOLDER!!!!!!!!!
// Currently no support for throwing 2D Histograms from a covariance
(void) hist;
(void) cov;
(void) map;
(void) throwdiag;
(void) mask;
// /todo
// Sort maps if required
// Throw the covariance for a 1D plot
// Unmap back to 2D Histogram
return hist;
}
//*******************************************************************
TH1D* StatUtils::ApplyHistogramMasking(TH1D* hist, TH1I* mask) {
//*******************************************************************
if (!mask) return ( (TH1D*)hist->Clone() );
// This masking is only sufficient for chi2 calculations, and will have dodgy bin edges.
// Get New Bin Count
Int_t NBins = 0;
for (int i = 0; i < hist->GetNbinsX(); i++) {
if (mask->GetBinContent(i + 1)) continue;
NBins++;
}
// Make new hist
std::string newmaskname = std::string(hist->GetName()) + "_MSKD";
TH1D* calc_hist = new TH1D( newmaskname.c_str(), newmaskname.c_str(), NBins, 0, NBins);
// fill new hist
int binindex = 0;
for (int i = 0; i < hist->GetNbinsX(); i++) {
if (mask->GetBinContent(i + 1)) {
LOG(REC) << "Applying mask to bin " << i + 1 << " " << hist->GetName() << std::endl;
continue;
}
calc_hist->SetBinContent(binindex + 1, hist->GetBinContent(i + 1));
calc_hist->SetBinError(binindex + 1, hist->GetBinError(i + 1));
binindex++;
}
return calc_hist;
};
//*******************************************************************
TH2D* StatUtils::ApplyHistogramMasking(TH2D* hist, TH2I* mask) {
//*******************************************************************
TH2D* newhist = (TH2D*) hist->Clone();
if (!mask) return newhist;
for (int i = 0; i < hist->GetNbinsX(); i++) {
for (int j = 0; j < hist->GetNbinsY(); j++) {
if (mask->GetBinContent(i + 1, j + 1) > 0) {
newhist->SetBinContent(i + 1, j + 1, 0.0);
newhist->SetBinContent(i + 1, j + 1, 0.0);
}
}
}
return newhist;
}
//*******************************************************************
TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask) {
//*******************************************************************
if (!mask) return (TMatrixDSym*)(mat->Clone());
// Get New Bin Count
Int_t NBins = 0;
for (int i = 0; i < mask->GetNbinsX(); i++) {
if (mask->GetBinContent(i + 1)) continue;
NBins++;
}
// make new matrix
TMatrixDSym* calc_mat = new TMatrixDSym(NBins);
int col, row;
// Need to mask out bins in the current matrix
row = 0;
for (int i = 0; i < mask->GetNbinsX(); i++) {
col = 0;
// skip if masked
if (mask->GetBinContent(i + 1) > 0.5) continue;
for (int j = 0; j < mask->GetNbinsX(); j++) {
// skip if masked
if (mask->GetBinContent(j + 1) > 0.5) continue;
(*calc_mat)(row, col) = (*mat)(i, j);
col++;
}
row++;
}
return calc_mat;
};
//*******************************************************************
TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) {
//*******************************************************************
if (!map) map = StatUtils::GenerateMap(data);
TH1I* mask_1D = StatUtils::MapToMask(mask, map);
TMatrixDSym* newmat = StatUtils::ApplyMatrixMasking(mat, mask_1D);
delete mask_1D;
return newmat;
}
//*******************************************************************
TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask) {
//*******************************************************************
TMatrixDSym* new_mat = GetInvert(mat);
TMatrixDSym* masked_mat = ApplyMatrixMasking(new_mat, mask);
TMatrixDSym* inverted_mat = GetInvert(masked_mat);
delete masked_mat;
delete new_mat;
return inverted_mat;
};
//*******************************************************************
TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) {
//*******************************************************************
if (!map) map = StatUtils::GenerateMap(data);
TH1I* mask_1D = StatUtils::MapToMask(mask, map);
TMatrixDSym* newmat = ApplyInvertedMatrixMasking(mat, mask_1D);
delete mask_1D;
return newmat;
}
//*******************************************************************
TMatrixDSym* StatUtils::GetInvert(TMatrixDSym* mat) {
//*******************************************************************
TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone();
// Check for diagonal
bool non_diagonal = false;
for (int i = 0; i < new_mat->GetNrows(); i++) {
for (int j = 0; j < new_mat->GetNrows(); j++) {
if (i == j) continue;
if ((*new_mat)(i, j) != 0.0) {
non_diagonal = true;
break;
}
}
}
// If diag, just flip the diag
if (!non_diagonal or new_mat->GetNrows() == 1) {
for (int i = 0; i < new_mat->GetNrows(); i++) {
if ((*new_mat)(i, i) != 0.0)
(*new_mat)(i, i) = 1.0 / (*new_mat)(i, i);
else
(*new_mat)(i, i) = 0.0;
}
return new_mat;
}
// Invert full matrix
TDecompSVD LU = TDecompSVD((*new_mat));
new_mat = new TMatrixDSym(new_mat->GetNrows(), LU.Invert().GetMatrixArray(), "");
return new_mat;
}
//*******************************************************************
TMatrixDSym* StatUtils::GetDecomp(TMatrixDSym* mat) {
//*******************************************************************
TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone();
int nrows = new_mat->GetNrows();
// Check for diagonal
bool diagonal = true;
for (int i = 0; i < nrows; i++) {
for (int j = 0; j < nrows; j++) {
if (i == j) continue;
if ((*new_mat)(i, j) != 0.0) {
diagonal = false;
break;
}
}
}
// If diag, just flip the diag
if (diagonal or nrows == 1) {
for (int i = 0; i < nrows; i++) {
if ((*new_mat)(i, i) > 0.0)
(*new_mat)(i, i) = sqrt((*new_mat)(i, i));
else
(*new_mat)(i, i) = 0.0;
}
return new_mat;
}
TDecompChol LU = TDecompChol(*new_mat);
LU.Decompose();
delete new_mat;
TMatrixDSym* dec_mat = new TMatrixDSym(nrows, LU.GetU().GetMatrixArray(), "");
return dec_mat;
}
//*******************************************************************
void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH1D* hist, double norm) {
//*******************************************************************
if (!mat) mat = MakeDiagonalCovarMatrix(hist);
int nbins = mat->GetNrows();
TMatrixDSym* new_mat = new TMatrixDSym(nbins);
for (int i = 0; i < nbins; i++) {
for (int j = 0; j < nbins; j++) {
double valx = hist->GetBinContent(i + 1) * 1E38;
double valy = hist->GetBinContent(j + 1) * 1E38;
(*new_mat)(i, j) = (*mat)(i, j) + norm * norm * valx * valy;
}
}
// Swap the two
delete mat;
mat = new_mat;
return;
};
//*******************************************************************
void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map ) {
//*******************************************************************
if (!map) map = StatUtils::GenerateMap(data);
TH1D* data_1D = MapToTH1D(data, map);
StatUtils::ForceNormIntoCovar(mat, data_1D, norm);
delete data_1D;
return;
}
//*******************************************************************
TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH1D* data, double scaleF) {
//*******************************************************************
TMatrixDSym* newmat = new TMatrixDSym(data->GetNbinsX());
for (int i = 0; i < data->GetNbinsX(); i++) {
(*newmat)(i, i) = data->GetBinError(i + 1) * data->GetBinError(i + 1) * scaleF * scaleF;
}
return newmat;
}
//*******************************************************************
TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH2D* data, TH2I* map, double scaleF) {
//*******************************************************************
if (!map) map = StatUtils::GenerateMap(data);
TH1D* data_1D = MapToTH1D(data, map);
return StatUtils::MakeDiagonalCovarMatrix(data_1D, scaleF);
};
//*******************************************************************
void StatUtils::SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale) {
//*******************************************************************
// Check
if (cov->GetNrows() != data->GetNbinsX()) {
ERR(WRN) << "Nrows in cov don't match nbins in data for SetDataErrorFromCov" << std::endl;
}
// Set bin errors form cov diag
for (int i = 0; i < data->GetNbinsX(); i++) {
data->SetBinError(i + 1, sqrt((*cov)(i, i)) * scale );
}
return;
}
//*******************************************************************
void StatUtils::SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map, double scale) {
//*******************************************************************
// Create map if required
if (!map) map = StatUtils::GenerateMap(data);
- std::cout << data << " " << cov << " " << map << " " << scale << std::endl;
// Set Bin Errors from cov diag
int count = 0;
for (int i = 0; i < data->GetNbinsX(); i++) {
for (int j = 0; j < data->GetNbinsY(); j++) {
if (data->GetBinContent(i + 1, j + 1) == 0.0) continue;
count = map->GetBinContent(i + 1, j + 1) - 1;
data->SetBinError(i + 1, j + 1, sqrt((*cov)(count, count)) * scale );
}
}
return;
}
+
+TMatrixDSym* StatUtils::ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale){
+
+ int nbins = full_covar->GetNrows();
+ TMatrixDSym* shape_covar = new TMatrixDSym(nbins);
+
+ // Check nobody is being silly
+ if (data_hist->GetNbinsX() != nbins){
+ ERR(WRN) << "Inconsistent matrix and data histogram passed to StatUtils::ExtractShapeOnlyCovar!" << std::endl;
+ ERR(WRN) << "data_hist has " << data_hist->GetNbinsX() << " matrix has " << nbins << std::endl;
+ int err_bins = data_hist->GetNbinsX();
+ if (nbins > err_bins) err_bins = nbins;
+ for (int i = 0; i < err_bins; ++i){
+ ERR(WRN) << "Matrix diag. = " << (*full_covar)(i, i) << " data = " << data_hist->GetBinContent(i+1) << std::endl;
+ }
+ return NULL;
+ }
+
+ double total_data = 0;
+ double total_covar = 0;
+
+ // Initial loop to calculate some constants
+ for (int i = 0; i < nbins; ++i) {
+ total_data += data_hist->GetBinContent(i+1)*data_scale;
+ for (int j = 0; j < nbins; ++j) {
+ total_covar += (*full_covar)(i,j);
+ }
+ }
+
+ if (total_data == 0 || total_covar == 0){
+ ERR(WRN) << "Stupid matrix or data histogram passed to StatUtils::ExtractShapeOnlyCovar! Ignoring..." << std::endl;
+ return NULL;
+ }
+
+ LOG(SAM) << "Norm error = " << sqrt(total_covar)/total_data << std::endl;
+
+ // Now loop over and calculate the shape-only matrix
+ for (int i = 0; i < nbins; ++i) {
+ double data_i = data_hist->GetBinContent(i+1)*data_scale;
+
+ for (int j = 0; j < nbins; ++j) {
+ double data_j = data_hist->GetBinContent(j+1)*data_scale;
+
+ double norm_term = data_i*data_j*total_covar/total_data/total_data;
+ double mix_sum1 = 0;
+ double mix_sum2 = 0;
+
+ for (int k = 0; k < nbins; ++k){
+ mix_sum1 += (*full_covar)(k,j);
+ mix_sum2 += (*full_covar)(i,k);
+ }
+
+ double mix_term1 = data_i*(mix_sum1/total_data - total_covar*data_j/total_data/total_data);
+ double mix_term2 = data_j*(mix_sum2/total_data - total_covar*data_i/total_data/total_data);
+
+ (*shape_covar)(i, j) = (*full_covar)(i, j) - mix_term1 - mix_term2 - norm_term;
+ }
+ }
+ return shape_covar;
+}
+
+
//*******************************************************************
TH2I* StatUtils::GenerateMap(TH2D* hist) {
//*******************************************************************
std::string maptitle = std::string(hist->GetName()) + "_MAP";
TH2I* map = new TH2I( maptitle.c_str(), maptitle.c_str(),
hist->GetNbinsX(), 0, hist->GetNbinsX(),
hist->GetNbinsY(), 0, hist->GetNbinsY());
Int_t index = 1;
for (int i = 0; i < hist->GetNbinsX(); i++) {
for (int j = 0; j < hist->GetNbinsY(); j++) {
if (hist->GetBinContent(i + 1, j + 1) > 0 && hist->GetBinError(i + 1, j + 1) > 0) {
map->SetBinContent(i + 1, j + 1, index);
index++;
} else {
map->SetBinContent(i + 1, j + 1, 0);
}
}
}
return map;
}
//*******************************************************************
TH1D* StatUtils::MapToTH1D(TH2D* hist, TH2I* map) {
//*******************************************************************
if (!hist) return NULL;
// Get N bins for 1D plot
Int_t Nbins = map->GetMaximum();
std::string name1D = std::string(hist->GetName()) + "_1D";
// Make new 1D Hist
TH1D* newhist = new TH1D(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins);
// map bin contents
for (int i = 0; i < map->GetNbinsX(); i++) {
for (int j = 0; j < map->GetNbinsY(); j++) {
if (map->GetBinContent(i + 1, j + 1) == 0) continue;
newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1));
newhist->SetBinError(map->GetBinContent(i + 1, j + 1), hist->GetBinError(i + 1, j + 1));
}
}
// return
return newhist;
}
//*******************************************************************
TH1I* StatUtils::MapToMask(TH2I* hist, TH2I* map) {
//*******************************************************************
TH1I* newhist = NULL;
if (!hist) return newhist;
// Get N bins for 1D plot
Int_t Nbins = map->GetMaximum();
std::string name1D = std::string(hist->GetName()) + "_1D";
// Make new 1D Hist
newhist = new TH1I(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins);
// map bin contents
for (int i = 0; i < map->GetNbinsX(); i++) {
for (int j = 0; j < map->GetNbinsY(); j++) {
if (map->GetBinContent(i + 1, j + 1) == 0) continue;
newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1));
}
}
// return
return newhist;
}
TMatrixDSym* StatUtils::GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data) {
int nbins = correl->GetNrows();
TMatrixDSym* covar = new TMatrixDSym(nbins);
for (int i = 0; i < nbins; i++) {
for (int j = 0; j < nbins; j++) {
(*covar)(i, j) = (*correl)(i, j) * data->GetBinError(i + 1) * data->GetBinError(j + 1);
}
}
return covar;
}
//*******************************************************************
TMatrixD* StatUtils::GetMatrixFromTextFile(std::string covfile, int dimx, int dimy) {
//*******************************************************************
// Determine dim
if (dimx == -1 and dimy == -1) {
std::string line;
std::ifstream covar(covfile.c_str(), std::ifstream::in);
int row = 0;
while (std::getline(covar >> std::ws, line, '\n')) {
int column = 0;
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
if (entries.size() <= 1) {
ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 "
"entries on this line: " << row << std::endl;
}
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
column++;
if (column > dimx) dimx = column;
}
row++;
if (row > dimy) dimy = row;
}
}
// Or assume symmetric
if (dimx != -1 and dimy == -1) {
dimy = dimx;
}
assert(dimy != -1 && " matrix dimy not set.");
// Make new matrix
TMatrixD* mat = new TMatrixD(dimx, dimy);
std::string line;
std::ifstream covar(covfile.c_str(), std::ifstream::in);
int row = 0;
while (std::getline(covar >> std::ws, line, '\n')) {
int column = 0;
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
if (entries.size() <= 1) {
ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 "
"entries on this line: " << row << std::endl;
}
for (std::vector<double>::iterator iter = entries.begin();
iter != entries.end(); iter++) {
// Check Rows
//assert(row > mat->GetNrows() && " covar rows doesn't match matrix rows.");
//assert(column > mat->GetNcols() && " covar cols doesn't match matrix cols.");
// Fill Matrix
(*mat)(row, column) = (*iter);
column++;
}
row++;
}
return mat;
}
//*******************************************************************
TMatrixD* StatUtils::GetMatrixFromRootFile(std::string covfile, std::string histname) {
//*******************************************************************
std::string inputfile = covfile + ";" + histname;
std::vector<std::string> splitfile = GeneralUtils::ParseToStr(inputfile, ";");
if (splitfile.size() < 2) {
ERR(FTL) << "No object name given!" << std::endl;
throw;
}
// Get file
TFile* tempfile = new TFile(splitfile[0].c_str(), "READ");
// Get Object
TObject* obj = tempfile->Get(splitfile[1].c_str());
if (!obj) {
ERR(FTL) << "Object " << splitfile[1] << " doesn't exist!" << std::endl;
throw;
}
// Try casting
TMatrixD* mat = dynamic_cast<TMatrixD*>(obj);
if (mat) {
TMatrixD* newmat = (TMatrixD*)mat->Clone();
delete mat;
tempfile->Close();
return newmat;
}
TMatrixDSym* matsym = dynamic_cast<TMatrixDSym*>(obj);
if (matsym) {
TMatrixD* newmat = new TMatrixD(matsym->GetNrows(), matsym->GetNrows());
for (int i = 0; i < matsym->GetNrows(); i++) {
for (int j = 0; j < matsym->GetNrows(); j++) {
(*newmat)(i, j) = (*matsym)(i, j);
}
}
delete matsym;
tempfile->Close();
return newmat;
}
TH2D* mathist = dynamic_cast<TH2D*>(obj);
if (mathist) {
TMatrixD* newmat = new TMatrixD(mathist->GetNbinsX(), mathist->GetNbinsX());
for (int i = 0; i < mathist->GetNbinsX(); i++) {
for (int j = 0; j < mathist->GetNbinsX(); j++) {
(*newmat)(i, j) = mathist->GetBinContent(i + 1, j + 1);
}
}
delete mathist;
tempfile->Close();
return newmat;
}
return NULL;
}
//*******************************************************************
TMatrixDSym* StatUtils::GetCovarFromTextFile(std::string covfile, int dim){
//*******************************************************************
// Delete TempMat
TMatrixD* tempmat = GetMatrixFromTextFile(covfile, dim, dim);
// Make a symmetric covariance
TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows());
for (int i = 0; i < tempmat->GetNrows(); i++){
for (int j = 0; j < tempmat->GetNrows(); j++){
(*newmat)(i,j) = (*tempmat)(i,j);
}
}
delete tempmat;
return newmat;
}
//*******************************************************************
TMatrixDSym* StatUtils::GetCovarFromRootFile(std::string covfile, std::string histname){
//*******************************************************************
TMatrixD* tempmat = GetMatrixFromRootFile(covfile, histname);
TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows());
for (int i = 0; i < tempmat->GetNrows(); i++){
for (int j = 0; j < tempmat->GetNrows(); j++){
(*newmat)(i,j) = (*tempmat)(i,j);
}
}
delete tempmat;
return newmat;
}
diff --git a/src/Utils/StatUtils.h b/src/Utils/StatUtils.h
index a44c5c2..bf26e90 100644
--- a/src/Utils/StatUtils.h
+++ b/src/Utils/StatUtils.h
@@ -1,253 +1,255 @@
// 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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
#ifndef STATUTILS_H
#define STATUTILS_H
// C Includes
#include <stdlib.h>
#include <numeric>
#include <math.h>
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <deque>
#include "assert.h"
// Root Includes
#include "TH1D.h"
#include "TH2I.h"
#include "TH2D.h"
#include "TFile.h"
#include "TMatrixDSym.h"
#include "TDecompSVD.h"
#include "TMath.h"
#include "TRandom3.h"
#include "TDecompChol.h"
#include "TGraphErrors.h"
// Fit Includes
#include "FitParameters.h"
#include "FitLogger.h"
/*!
* \addtogroup Utils
* @{
*/
//! Functions for handling statistics calculations
namespace StatUtils{
/*
Chi2 Functions
*/
//! Get Chi2 using diagonal bin errors from the histogram. Masking applied before calculation if mask provided.
Double_t GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL);
//! Get Chi2 using diagonal bin errors from the histogram.
//! Plots converted to 1D histograms before using 1D calculation.
Double_t GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL);
//! Get Chi2 using an inverted covariance for the data
Double_t GetChi2FromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL, double data_scale=1, double covar_scale=1E76);
//! Get Chi2 using an inverted covariance for the data
//! Plots converted to 1D histograms before using 1D calculation.
Double_t GetChi2FromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL);
//! Get Chi2 using an SVD method on the covariance before calculation.
//! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work.
Double_t GetChi2FromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL);
//! Get Chi2 using an SVD method on the covariance before calculation.
//! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work.
//! Plots converted to 1D histograms before using 1D calculation.
Double_t GetChi2FromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL);
//! Get Chi2 using only the raw event rates given in each bin using a -2LL method.
Double_t GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL);
//! Get Chi2 using only the raw event rates given in each bin using a -2LL method.
//! Plots converted to 1D histograms before using 1D calculation.
Double_t GetChi2FromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL);
// Likelihood Functions
//! Placeholder for 1D binned likelihood method
Double_t GetLikelihoodFromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL);
//! Placeholder for 2D binned likelihood method
Double_t GetLikelihoodFromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL);
//! Placeholder for 1D binned likelihood method
Double_t GetLikelihoodFromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL);
//! Placeholder for 2D binned likelihood method
Double_t GetLikelihoodFromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL);
//! Placeholder for 1D binned likelihood method
Double_t GetLikelihoodFromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL);
//! Placeholder for 2D binned likelihood method
Double_t GetLikelihoodFromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL);
//! Placeholder for 1D binned likelihood method
Double_t GetLikelihoodFromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL);
//! Placeholder for 2D binned likelihood method
Double_t GetLikelihoodFromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL);
/*
NDOF Functions
*/
//! Return 1D Histogram NDOF considering masking and empty bins
Int_t GetNDOF(TH1D* hist, TH1I* mask=NULL);
//! Return 2D Histogram NDOF considering masking and empty bins
Int_t GetNDOF(TH2D* hist, TH2I* map=NULL, TH2I* mask=NULL);
/*
Fake Data Functions
*/
//! Given a full covariance for a 1D data set throw the decomposition to generate fake data.
//! throwdiag determines whether diagonal statistical errors are thrown.
//! If no covariance is provided only statistical errors are thrown.
TH1D* ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag=true, TH1I* mask=NULL);
//! Given a full covariance for a 2D data set throw the decomposition to generate fake data.
//! Plots are converted to 1D histograms and the 1D ThrowHistogram is used, before being converted back to 2D histograms.
TH2D* ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map=NULL, bool throwdiag=true, TH2I* mask=NULL);
/*
Masking Functions
*/
//! Given a mask histogram, mask out any bins in hist with non zero entries in mask.
TH1D* ApplyHistogramMasking(TH1D* hist, TH1I* mask);
//! Given a mask histogram, mask out any bins in hist with non zero entries in mask.
TH2D* ApplyHistogramMasking(TH2D* hist, TH2I* mask);
//! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse.
TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask);
//! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse.
//! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D.
TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL);
//! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance
TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask);
//! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance
//! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D.
TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL);
/*
Covariance Handling Functions
*/
//! Return inverted matrix of TMatrixDSym
TMatrixDSym* GetInvert(TMatrixDSym* mat);
//! Return Cholesky Decomposed matrix of TMatrixDSym
TMatrixDSym* GetDecomp(TMatrixDSym* mat);
//! Return full covariances
TMatrixDSym* GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data);
//! Given a normalisation factor for a dataset add in a new normalisation term to the covariance.
void ForceNormIntoCovar(TMatrixDSym* mat, TH1D* data, double norm);
//! Given a normalisation factor for a dataset add in a new normalisation term to the covariance.
//! Convertes 2D to 1D, before using 1D ForceNormIntoCovar
void ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map=NULL);
//! Given a dataset generate an uncorrelated covariance matrix using the bin errors.
TMatrixDSym* MakeDiagonalCovarMatrix(TH1D* data, double scaleF=1E38);
//! Given a dataset generate an uncorrelated covariance matrix using the bin errors.
TMatrixDSym* MakeDiagonalCovarMatrix(TH2D* data, TH2I* map=NULL, double scaleF=1E38);
//! Given a covariance set the errors in each bin on the data from the covariance diagonals.
void SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale=1.0);
//! Given a covariance set the errors in each bin on the data from the covariance diagonals.
void SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map=NULL, double scale=1.0);
+ //! Given a covariance, extracts the shape-only matrix using the method from the MiniBooNE TN
+ TMatrixDSym* ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale=1E38);
/*
Mapping Functions
*/
//! If no map is provided for the 2D histogram, generate one by counting up through the bins along x and y.
TH2I* GenerateMap(TH2D* hist);
//! Apply a map to a 2D histogram converting it into a 1D histogram.
TH1D* MapToTH1D(TH2D* hist, TH2I* map);
//! Apply a map to a 2D mask convering it into a 1D mask.
TH1I* MapToMask(TH2I* hist, TH2I* map);
/// \brief Read TMatrixD from a text file
///
/// - covfile = full path to text file
/// - dimx = x dimensions of matrix
/// - dimy = y dimensions of matrix
///
/// Format of textfile should be: \n
/// cov_11 cov_12 ... cov_1N \n
/// cov_21 cov_22 ... cov_2N \n
/// ... ... ... ... \n
/// cov_N1 ... ... cov_NN \n
///
/// If no dimensions are given, dimx and dimy are determined from rows/columns
/// inside textfile.
///
/// If only dimx is given a symmetric matrix is assumed.
TMatrixD* GetMatrixFromTextFile(std::string covfile, int dimx=-1, int dimy=-1);
/// \brief Read TMatrixD from a ROOT file
///
/// - covfile = full path to root file (+';histogram')
/// - histname = histogram name
///
/// If no histogram name is given function assumes it has been appended
/// covfile path as: \n
/// 'covfile.root;histname'
///
/// histname can point to a TMatrixD object, a TMatrixDSym object, or
/// a TH2D object.
TMatrixD* GetMatrixFromRootFile(std::string covfile, std::string histname="");
/// \brief Calls GetMatrixFromTextFile and turns it into a TMatrixDSym
TMatrixDSym* GetCovarFromTextFile(std::string covfile, int dim);
/// \brief Calls GetMatrixFromRootFile and turns it into a TMatrixDSym
TMatrixDSym* GetCovarFromRootFile(std::string covfile, std::string histname);
};
/*! @} */
#endif

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 19, 7:01 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3805024
Default Alt Text
(502 KB)

Event Timeline